Page 1 of 1

alternative to highlight_string() and highlight_file();

Posted: Mon Dec 03, 2007 4:48 am
by s.dot
This function produces way fewer amount of characters by using a stylesheet to highlight syntax, rather than pulling hex values from php.ini and highlighting.

Stylesheet needed:

Code: Select all

<style type="text/css">
/* Variables */
.hsm_v
{
	color: blue;
}

/* Strings */
.hsm_s
{
	color: red;
}

/* Comments */
.hsm_c
{
	color: orange;
}

/* Functions */
.hsm_f
{
	color: purple;
}

/* HTML */
.hsm_h
{
	color: black;
}

/* Everything else */
.hsm_n
{
	color: green;
}
</style>
functions:

Code: Select all

function highlight_string_min($source, $return = false)
{
	//begin return string
	$ret = '<span class="hsm_n">';
	
	//get all the tokens
	$tokens = token_get_all($source);
	
	//loop through the tokens
	foreach ($tokens AS $token)
	{
		if (!is_string($token))
		{
			//get token id and text
			list($id, $text) = $token;
		
			switch ($id)
			{
				//variable
				case T_VARIABLE:
				$ret .= '<span class="hsm_v">' . $text . '</span>';
				break;
				
				//string
				case T_CONSTANT_ENCAPSED_STRING:
				case T_ENCAPSED_AND_WHITESPACE:
				$ret .= '<span class="hsm_s">' . $text . '</span>';
				break;
				
				//comments
				case T_COMMENT:
				$ret .= '<span class="hsm_c">' . trim($text) . '</span>';
				break;
				
				case T_DOC_COMMENT:
				$ret .= '<span class="hsm_c">' . $text . '</span>';
				break;
				
				//functions
				case T_STRING:
				$ret .= '<span class="hsm_f">' . $text . '</span>';
				break;

				case T_INLINE_HTML:
				$ret .= '<span class="hsm_h">' . $text . '</span>';
				break;
			
				default:
				$ret .= $text;
				break;
			}
		} else
		{
			$ret .= $token;
		}
	}
	
	//end return
	$ret .= '</span>';
	
	//prepare return
	$ret = nl2br(
		str_replace(
			array('</span>','<span','">', '&nbsp;'),
			array('</span>','<span','">','&nbsp;'),
			htmlentities(
				str_replace(
					array('  ', "\t", 'span&nbsp;'),
					array('&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;', 'span '),
					$ret
				), ENT_NOQUOTES
			)
		)
	);
	
	if ($return)
	{
		return $ret;
	}
	
	return print $ret;
}

function highlight_file_min($file, $return=false)
{
	$source = file_get_contents($file);
	return highlight_string_min($source, $return);
}
test:

Code: Select all

$str = '<?php

//say hi
echo \'hey, whats up?\';

//some functions
$strlen = strlen(basename($_SERVER[\'PHP_SELF\']));';


highlight_string($str);
output:

Code: Select all

<span class="hsm_n"><?php<br />
<br />
<span class="hsm_c">//say hi</span><br />
echo&nbsp;<span class="hsm_s">'hey, whats up?'</span>;<br />
<br />
<span class="hsm_c">//some functions</span><br />
<span class="hsm_v">$strlen</span> = <span class="hsm_f">strlen</span>(<span class="hsm_f">basename</span>(<span class="hsm_v">$_SERVER</span>[<span class="hsm_s">'PHP_SELF'</span>]));</span>
Compared to highlight_string() test:

Code: Select all

echo 'highlight_string_min() produces ' . strlen(highlight_string_min($str, true)) . ' characters<br />
highlight_string() produces ' . strlen(highlight_string($str, true)) . ' characters';
output:

Code: Select all

highlight_string_min() produces 392 characters
highlight_string() produces 808 characters
on larger files, the difference becomes more apparent
109, 003
164, 603

inline HTML still needs to be tweaked a bit, but it works pretty solid for pure php strings and files

Posted: Sat Dec 08, 2007 7:31 pm
by John Cartwright
You must have been bored :)

Posted: Sat Dec 08, 2007 9:44 pm
by superdezign
Yah... This is definitely the reason I decided to use GeSHi.

Posted: Sun Dec 09, 2007 11:14 am
by feyd
I just run a preg_replace_callback() on the return from highlight_string() to convert their coloring to CSS classes.