Skip to content

Instantly share code, notes, and snippets.

@cgrand
Created October 19, 2009 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgrand/213649 to your computer and use it in GitHub Desktop.
Save cgrand/213649 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Pygments Support
Plugin URI: http://lucumr.pocoo.org/
Description: Adds support for pygments to wordpress
Version: 1.0
Author: Armin Ronacher
Author URI: http://lucumr.pocoo.org/
Modified by Christophe Grand to support wordpress 2.8
*/
define('PYGMENTS_STYLE', 'pastie');
define('PYGMENTS_PATH', '/usr/bin/pygmentize');
/**
* function that highlights code in a pygments
* subprocess and returns the highlighted HTML.
*
* return NULL if something went wrong.
*/
function pygments_highlight_code($tag, $code, $lexer)
{
if (!preg_match('/^[a-zA-Z_+]+$/', $lexer))
return NULL;
$pipes = NULL;
$process = proc_open(PYGMENTS_PATH . ' -l' . $lexer . ' -fhtml -Onowrap,style=' .
PYGMENTS_STYLE, array(
array('pipe', 'r'),
array('pipe', 'w'),
array('pipe', 'w')
), $pipes);
fwrite($pipes[0], $code);
fclose($pipes[0]);
$highlighted = rtrim(stream_get_contents($pipes[1]));
fclose($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[2]);
if (trim($errors))
return NULL;
proc_close($process);
return '<' . $tag . ' class="highlight">' . addcslashes($highlighted, '\\') . '</' . $tag . '>';
}
/**
* this function is called to remove the cached stuff from the post
* if the post was edited. This ensures that the cached output is not
* visible in the editor and that you can edit the post after posting.
*/
function pygments_cleanup_code($text)
{
// Step 1: remove the cached stuff
$regex = '/&lt;!-- PYGMENTS_CACHE&gt;.*?&lt;PYGMENTS_CACHE --&gt;/sm';
$text = preg_replace($regex, '', $text);
// Step 2: remove the comments around the raw stuff
// and recreate the <pre lang=""></pre> stuff.
$regex = '/&lt;!-- PYGMENTS_RAW\\(([^,)]+),?\\s*([^)]*)\\)&gt;(.*?)&lt;PYGMENTS_RAW --&gt;/sm';
return preg_replace_callback($regex, '_pygments_perform_cleanup', $text);
}
function _pygments_perform_cleanup($match)
{
$tag = $match[2] == "" ? "pre" : $match[2];
return '<' . $tag . ' lang="' . $match[1] . '">' . $match[3] . '</' . $tag . '>';
}
/**
* the opposite of the pygments_cleanup_code. It's executed when
* rendering the blog post and just removes the raw stuff because we
* don't want a bloated page.
*/
function pygments_finish_code($text)
{
// Step 1: uncomment the cache
$regex = '/<!-- PYGMENTS_CACHE>(.*?)<PYGMENTS_CACHE -->/sm';
$text = preg_replace($regex, '\\1', $text);
// Step 2: remove all the raw stuff
$regex = '/<!-- PYGMENTS_RAW\\(.*?<PYGMENTS_RAW -->/sm';
return preg_replace($regex, '', $text);
}
/**
* highlight the code inline. All the pre tags with a language tag
* are processed by pygments then.
*/
function pygments_highlight_code_inline($text)
{
// Find all the pre or code blocks with a lang attribute
$regex = '/<(pre|code)\\s+lang=\\\\(["\'])([^\\\\]+)\\\\\\2>(.*?)<\\/\\1>/ism';
return preg_replace_callback($regex, '_pygments_perform_replace', $text);
}
/**
* helper function (callback) for pygments_highlight_code_inline
*/
function _pygments_perform_replace($match)
{
$lang = strtolower($match[3]);
$code = $match[4];
$highlighted = pygments_highlight_code($match[1], stripslashes($code), $lang);
if (!$highlighted)
$highlighted = '<' . $match[1] . '>' . htmlspecialchars($code) . '</' . $match[1] . '>';
return '<!-- PYGMENTS_CACHE>' . $highlighted . '<PYGMENTS_CACHE -->' .
'<!-- PYGMENTS_RAW(' . $lang . ', ' . $match[1] . ')>' . $code . '<PYGMENTS_RAW -->';
}
// register filters in wordpress
add_filter('the_editor_content', 'pygments_cleanup_code', 100);
add_filter('content_save_pre', 'pygments_highlight_code_inline', 1);
add_filter('the_content', 'pygments_finish_code', 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment