Embedding GitHub Gists in XHTML

tags: , , , ,

If you’ve ever shared code snip­pets online, you’ve prob­a­bly heard of Pastie or Paste­bin. What you may not have heard about is GitHub’s Gist ser­vice. Basi­cally, take the fea­tures of exist­ing paste­bins, and add ver­sion­ing, SSL, and fork­ing. Very cool stuff.

Unfor­tu­nately, the method that is used to embed them in your pages (document.write) doesn’t work in pages that are served as real XHTML. This is a PHP func­tion that parses your con­tent for Gists, and then fetches them and replaces the script with the Gist’s CSS & HTML markup, avoid­ing the use of document.write().

<?php

/**
* Replaces Gist javascript instances with their actual content,
* avoiding the use of document.write().
*
* @param string $source (X)HTML source
*
* @return string (X)HTML with embedded Gists
*/
function embed_gists($source)
{
    $gists_regex = '/<script[^>]+src="(http:\/\/gist.github.com\/[^"]+)"[^>]*><\/script>/i';

    preg_match_all($gists_regex, $source, $gists);

    for ($i = 0, $n = count($gists[0]); $i < $n; $i++) {

        $embed = file_get_contents($gists[1][$i]);

        if ($embed != false) {

            // remove document.writes
            $embed = preg_replace('/document.write\(\'/i', '', $embed);
            $embed = preg_replace('/(*ANYCRLF)\'\)$/m', '', $embed);

            // remove javascript newlines
            $embed = preg_replace('%(?<!/)\\\%', '', $embed);

            // reverse javascript escaping
            $embed = stripslashes($embed);

            // remove line breaks
            $embed = preg_replace("/[\r]/", '',$embed);

            // replace the script tag
            $source = str_replace($gists[0][$i], $embed, $source);

        }

    }

    return $source;
}

?>

Feedback

Aaron Gough

I have actu­ally cre­ated a ser­vice that acts as a proxy and removes the document.write calls in favor of proper DOM manipulation.

The ser­vice is avail­able for free here: http://​ajax​-gist​.com/

I have also opened a sup­port ticket with GitHub to try to get them to updated their embed code so we won’t need to do this: http://​sup​port​.github​.com/​d​i​s​c​u​s​s​i​o​n​s​/​g​i​s​t​/​186​-​d​o​c​u​m​e​n​t​w​r​i​t​e​-​n​e​e​d​s​-​t​o​-​b​e​-​r​e​moved

Hope you find this use­ful! –Aaron