Getting CodeFilter to work in WYSIWYG

CodeFilter is a Drupal module that highlights source around the text.

The problem is that in its default state, you can’t use it in the WYSIWYG without having to turn off the feature and play with raw HTML.

For example;

function codefilter_process_php($text) {
    $text = html_entity_decode($text);
    // Note, pay attention to odd preg_replace-with-/e behaviour on slashes
    // Undo possible linebreak filter conversion
    $text = preg_replace('@@', "\n", str_replace('\"', '"', $text));
    // Undo the escaping in the prepare step
    $text = decode_entities($text);
    // Trim leading and trailing linebreaks
    $text = trim($text, "\r\n");
    // Highlight as PHP
    $text = '
' . highlight_string("\n$text\n?>", 1) . '
'
; // Remove newlines to avoid clashing with the linebreak filter $text = str_replace("\n", '', $text); return codefilter_fix_spaces($text); }

The solution has several parts, all require hacking the code

1. Replace HTML Entities

Edit codefilter.module, find the function codefilter_process_php, and add this line at the very start

$text = html_entity_decode($text);

and change the following line by adding the /n

$text = preg_replace('@@', "\n", str_replace('\"', '"', $text));

2. Enable ( in HTML)

In reality, I don’t have to do this as I can just use the [% and %] commands around the code and these are not translated into HTML Entities - so it works.

But just incase, we want to modify this function

function _codefilter_prepare($text, $format) {
    $text = preg_replace_callback('@(.+?)@s', '_codefilter_escape_code_tag_callback', $text);
    $text = preg_replace_callback('@[\[<](\?php|%)(.+?)(\?|%)[\]>]@s', '_codefilter_escape_php_tag_callback', $text);
    return $text;
}

to this

function _codefilter_prepare($text, $format) {
    /* Note: we replace < code> , < ?php  ?>, [ ?php ? ], < % % >, and [ %  % ] to prevent other filters from acting on them. */
    $text = preg_replace_callback('@(.+?)@s', '_codefilter_escape_code_tag_callback', $text);
    $text = preg_replace_callback('@\(.+?)\@s', '_codefilter_escape_code_tag_callback', $text);
    $text = preg_replace_callback('@[\[<](\?php|%)(.+?)(\?|%)[\]>]@s', '_codefilter_escape_php_tag_callback', $text);
    $text = preg_replace_callback('@(\[|\<)(\?php|%)(.+?)(\?|%)(\]|\>)@s', '_codefilter_escape_php_tag_callback3', $text);
    return $text;
}

and adding a new function

function _codefilter_escape_php_tag_callback3($matches) {
    return codefilter_escape($matches[3], 'php');
}

3. Remove the and ?> wrapper

I don’t want to have the and wrapper around the code that is required by the highlight_string function. So lets split that line up as follows.

$text = highlight_string("\n$text\n?>", 1);
$a = explode("
"
, $text); $n = array_slice($a, 1, -1); $text = implode("
"
, $n); $text = '
' . $text . '
'
;

Basically break the result into an array based on lines (
) and remove the first and last entries.

End Result

function codefilter_process_php($text) {
    $text = html_entity_decode($text);

    // Note, pay attention to odd preg_replace-with-/e behaviour on slashes
    // Undo possible linebreak filter conversion
    $text = preg_replace('@@', "\n", str_replace('\"', '"', $text));

    // Undo the escaping in the prepare step
    $text = decode_entities($text);

    // Trim leading and trailing linebreaks
    $text = trim($text, "\r\n");

    // Highlight as PHP
    $text = highlight_string("\n$text\n?>", 1);

    // remove the < ?php  ? >
    $a = explode("
"
, $text); $n = array_slice($a, 1, -1); $text = implode("
"
, $n); // add the envelope $text = '
' . $text . '
'
; // Remove newlines to avoid clashing with the linebreak filter $text = str_replace("\n", '', $text); return codefilter_fix_spaces($text); }

Other Codes

You can actually use a series of different codes to indicate source code.

  • ?>
  • [?php?]
  • <%%>
  • [%%]

Note, that the < code> option does NOT format PHP - it just puts the text into a CODE block

Leave a Reply

Your email address will not be published. Required fields are marked *