/** * HTMLize JavaScript source for colourizing * @example JavaScript/j_token_html.php * @category PLUG * @param string * @param bool whether to keep whitespace and comments, default is true * @param bool whether to fully support Unicode * @param string optionally specify HTML tag instead of "OL", e.g. "DIV" * @return string */ function j_token_html($src, $ws = true, $unicode = true, $ol = 'ol', $LexClass = 'JLex') { // instantiate Lex instance of appropriate type $Lex = Lex::get($LexClass); // convert non-unix line breaks // @todo replace Unicode breaks too? $src = str_replace(array("\r\n", "\r"), array("\n", "\n"), $src); $tokens = j_token_get_all($src, $ws, $unicode); switch (strtolower($ol)) { case 'ol': case 'ul': $li = 'li'; break; default: $li = 'div'; } $lines = array(''); $line =& $lines[0]; while (list(, $token) = each($tokens)) { list($t, $s, $l, $c) = $token; if ($s === 'true' || $s === 'false' || $s === 'null') { $class = 'J_LITERAL'; } else { if ($Lex->is_word($s)) { $class = 'J_KEYWORD'; } else { if (!is_int($t) && $s === $t) { $class = 'J_PUNCTUATOR'; } else { $class = $Lex->name($t); } } } while (isset($s[0])) { if (!preg_match('/^(.*)\\n/', $s, $r)) { $lines[0] .= '<span class="' . $class . '">' . _j_htmlentities($s) . '</span>'; break; } $lines[0] .= '<span class="' . $class . '">' . _j_htmlentities($r[1]) . '</span>'; array_unshift($lines, ''); $s = substr($s, strlen($r[0])); } } $src = "</{$ol}>"; foreach ($lines as $i => $s) { $class = $i & 1 ? 'odd' : 'even'; $src = "<{$li} class=\"{$class}\">{$s}</{$li}>\n{$src}"; } return "<{$ol} class=\"javascript\">\n{$src}"; }
/** * jTokenizer example * More complex - show how the tokenizer can be used for highlighting source code * * We don't need the full parser for this, we justinclude the tokenizer library */ require '../jparser-libs/jtokenizer.php'; /** * Get some juice source code from a *.js file */ $source = file_get_contents('complex.js'); /** * Get the tokens as an array, just like the php tokenizer token_get_all function */ $tokens = j_token_get_all($source); /** * Utility for printing out tokens as HTML */ function _j_htmlentities($s) { if ($s === '') { return ' '; } $s = htmlentities($s, ENT_COMPAT, 'utf-8'); $s = str_replace(array(' ', "\t"), array(' ', ' '), $s); return $s; } /** * We're going to need one extra utility to see if a token is a word. * This function accesses the JLex helper class directly.
function convertExample($js, $inApiBody = false) { @($tokens = j_token_get_all($js)); // Based on the token_highlight example code $lines = array(''); $line =& $lines[0]; $inFunction = false; $objectsOpenInFunction = 1; for ($i = 0; $i < count($tokens); ++$i) { $token = $tokens[$i]; list($t, $s, $l, $c) = $token; @($next = $tokens[$i + 1]); list($tn, $sn, $ln, $cn) = $next; @($prev = $tokens[$i - 1]); list($tp, $sp, $lp, $cp) = $prev; if (_j_token_is_word($token)) { // Token is a keyword if ($s == "function") { $inFunction = true; $objectsOpenInFunction = 0; // Only works as long as we don't have nested functions } } else { if (isPunctation($token)) { if ($s == ":") { $s = " =>"; } else { if ($s == ".") { if ($sp == "r") { $s = "\\"; } else { if ($sp == "." || $sn == ".") { // Probably part of a ... place holder } else { $s = "->"; } } } else { if (!$inApiBody && $s == "[") { $s = "array("; } else { if (!$inApiBody && $s == "]") { $s = ")"; } else { if ($s == "{") { if (!$inFunction || $objectsOpenInFunction != 0) { $s = "array("; } $objectsOpenInFunction += 1; } else { if ($s == "}") { $objectsOpenInFunction -= 1; if (!$inFunction || $objectsOpenInFunction != 0) { $s = ")"; } else { $inFunction = false; } } else { if ($s == "(" && isPunctation($prev) && $sp == ")") { // Two function calls next to each other are not supported in PHP. I assume we should use getField instead. $s = "->getField("; } } } } } } } } else { if ($t == 2) { // symbol if (isPunctation($next) && $sn == ":") { // We're probably inside an object. Make this symbol a string for PHP $s = "'{$s}'"; } else { if (!(isPunctation($next) && $sn == "(") && $s != "r") { // This is not a function call, so probably this is a variable. Add a dollar sign. if (!$inApiBody) { $s = '$' . $s; } } } } } } // style and push onto source code lines array while (isset($s[0])) { if (!preg_match('/^(.*)(\\n|\\r\\n|\\r)/', $s, $r)) { $lines[0] .= $s; break; } $lines[0] .= $r[1]; array_unshift($lines, ''); $s = substr($s, strlen($r[0])); } } $lines = array_reverse($lines); $output = ''; foreach ($lines as $l) { $output .= $l . "\n"; } $output = substr($output, 0, -1); // Post-processing filters: if ($inApiBody) { $output = str_replace(', ]callback', "]", $output); $output = str_replace(', callback', "", $output); $output = str_replace('callback', "", $output); } else { $output = str_replace(', $callback', "", $output); $output = str_replace('$callback', "", $output); } return $output; }