Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   PHP (http://www.programmingforums.org/forum29.html)
-   -   PHP Syntax Highlighter (http://www.programmingforums.org/showthread.php?t=12836)

grimpirate Mar 17th, 2007 1:43 AM

PHP Syntax Highlighter
 
Well I created this simple script to help someone else on the site, figured I'd put it in its own thread. It basically uses the the PHP function highlight_file() to perform the standard PHP syntax highlighting. However, the limitation is that it didn't have line numbers. So I tweaked the output of that function a bit in order to also output line numbers.[PHP]<pre>
<?php
$filename = 'forum/admin.php';
ob_start();
highlight_file($filename);
$source = ob_get_contents();
ob_end_clean();
$source = explode(chr(13), $source);
$temp = substr($source[0], 0, 35);
$temp .= substr($source[0], 36);
$source[0] = substr($temp, 6);
$temp = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 8);
$source[count($source) - 1] = $temp;
for($i = 1; $i < count($source); $i++){
$source[$i] = substr($source[$i], 6);
}
for($i = 0; $i < count($source) - 1; $i++){
$source[$i] .= '<br />';
}
$spaces = strlen(count($source));
for($i = 0; $i < count($source); $i++){
$source[$i] = '<span style="color: #777777">' . ($i + 1) . '</span>&nbsp;' . $source[$i];
for($j = 0; $j < $spaces - strlen($i + 1); $j++){
$source[$i] = '&nbsp;' . $source[$i];
}
}
for($i = 0; $i < count($source); $i++){
echo $source[$i];
}
?>
</pre>[/PHP]

Styx Mar 17th, 2007 4:49 AM

Nice script, very useful =D

except when I run it as-is, the first line, <?php, is on the second line uncounted and line 1 is left blank

so I went ahead and made an attempt somewhat based on your script:
[php]<?php
$file = 'script.php';

ob_start();
highlight_file($file);
$source = ob_get_contents();
ob_end_clean();

echo '<pre>';
$blocks = explode("\n", $source);
$lines = str_replace('&nbsp;', ' ', explode(chr(13), $blocks[1]));
for ($i = 0; $i < count($lines); $i++)
{
for ($j = 0; $j < strlen(count($lines)) - strlen($i + 1); $j++)
{
echo '&nbsp;';
}
$lines[$i] = (($i == 0) ? '<br />' : '') . $lines[$i];
echo '<span style="color: #777777">' . ($i + 1) . '</span> ' . substr($lines[$i], 6) . "\n";
}
echo '</pre>';
?>[/php]
Notes:
replacing &nbsp; with a space reduces the file size :) also, there seems to be a difference between "\n" and chr(13) from highlight_file, so splitting it into blocks first with "\n" will let you get what you want (the content itself) to split it with chr(13), which removes that first extra new line.

grimpirate Mar 18th, 2007 10:44 PM

I don't quite understand what you mean about the output of my script Styx, could you possibly post the output so I can get a better idea?

Styx Mar 19th, 2007 3:16 AM

:

1
<pr>
 2 <?php
 3 $filename = 'highlighting.php';
 4 ob_start();
 5 highlight_file($filename);
 6 $source = ob_get_contents();
 7 ob_end_clean();
 8 $source = explode(chr(13), $source);
 9 $temp = substr($source[0], 0, 35);
10 $temp .= substr($source[0], 36);
11 $source[0] = substr($temp, 6);
12 $temp = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 8);
13 $source[count($source) - 1] = $temp;
14 for($i = 1; $i < count($source); $i++){
15    $source[$i] = substr($source[$i], 6);
16 }
17 for($i = 0; $i < count($source) - 1; $i++){
18    $source[$i] .= '<br />';
19 }
20 $spaces = strlen(count($source));
21 for($i = 0; $i < count($source); $i++){
22    $source[$i] = '<span style="color: #777777">' . ($i + 1) . '</span>&nbsp;' . $source[$i];
23    for($j = 0; $j < $spaces - strlen($i + 1); $j++){
24        $source[$i] = '&nbsp;' . $source[$i];
25    }
26 }
27 for($i = 0; $i < count($source); $i++){
28    echo $source[$i];
29 }
30 ?>
31 </pre>

That first line is what I mean. This is after copying and pasting from here.

grimpirate Mar 19th, 2007 1:13 PM

Here's what I get:
:

1 <pre>
 2 <?php
 3 $filename = 'syntax_h.php';
 4 ob_start();
 5 highlight_file($filename);
 6 $source = ob_get_contents();
 7 ob_end_clean();
 8 $source = explode(chr(13), $source);
 9 $temp = substr($source[0], 0, 35);
10 $temp .= substr($source[0], 36);
11 $source[0] = substr($temp, 6);
12 $temp = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 8);
13 $source[count($source) - 1] = $temp;
14 for($i = 1; $i < count($source); $i++){
15    $source[$i] = substr($source[$i], 6);
16 }
17 for($i = 0; $i < count($source) - 1; $i++){
18    $source[$i] .= '<br />';
19 }
20 $spaces = strlen(count($source));
21 for($i = 0; $i < count($source); $i++){
22    $source[$i] = '<span style="color: #777777">' . ($i + 1) . '</span>&nbsp;' . $source[$i];
23    for($j = 0; $j < $spaces - strlen($i + 1); $j++){
24        $source[$i] = '&nbsp;' . $source[$i];
25    }
26 }
27 for($i = 0; $i < count($source); $i++){
28    echo $source[$i];
29 }
30 ?>
31 </pre>

I'm not sure why yours isn't getting the same thing. But your code also produced proper output so whatever works ^_^. Also, the idea behind using &nbsp instead of the space character is so that rather than using the pre html tag the user can use a span with another monospaced font. For instance, something like this: <span style="font-family: Courier New; font-size: 10pt"> which produces the same results.

grimpirate Mar 19th, 2007 1:36 PM

I improved the code to be able to select only the source code without the line numbers getting selected:[PHP]<html>
<head>
<title>Grim PHP Syntax Highlighter</title>
<style>
div.lineNumbers {
float: left;
text-align: left;
border-right: 1px #999999 solid;
margin-right: 8px;
}
</style>
</head>
<body>
<span style="font-family: Courier New; font-size: 10pt">
<?php
$filename = 'syntax_h.php';
ob_start();
highlight_file($filename);
$source = ob_get_contents();
ob_end_clean();
$source = explode(chr(13), $source);
$temp = substr($source[0], 0, 35);
$temp .= substr($source[0], 36);
$source[0] = substr($temp, 6);
$temp = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 8);
$source[count($source) - 1] = $temp;
for($i = 1; $i < count($source); $i++){
$source[$i] = substr($source[$i], 6);
}
for($i = 0; $i < count($source) - 1; $i++){
$source[$i] .= '<br />';
}
$lineNum = array();
$spaces = strlen(count($source));
for($i = 0; $i < count($source); $i++){
array_push($lineNum, '<span style="color: #777777">' . ($i + 1) . '</span>&nbsp;');
for($j = 0; $j < $spaces - strlen($i + 1); $j++){
$lineNum[$i] = '&nbsp;' . $lineNum[$i];
}
$lineNum[$i] .= '<br />';
}
echo '<div class="lineNumbers">';
for($i = 0; $i < count($lineNum); $i++){
echo $lineNum[$i];
}
echo '</div>';
echo '<div class="sourceCode">';
for($i = 0; $i < count($source); $i++){
echo $source[$i];
}
echo '</div>';
?>
</span>
</body>
</html>[/PHP]

Styx Mar 19th, 2007 2:33 PM

ooo, nice improvement ^_^

The first line doesn't seem to highlight properly though. <?php tags are black if they're at line 1, and, when it scans your script, <html> turns into <htl>

grimpirate Mar 19th, 2007 3:34 PM

I remade the code and cut it down so it would be less memory intense by replacing some style codes with a main style sheet and also used css to control the spacing of the line numbers to decrease the number of &nbsp's that were necessary. The ones in the sourcecode still remain. Also, when there was a linewrap this would produce errors so I imposed a no linewrapping property in the style. However, this ONLY works in FIREFOX. For whatever reason Internet Explorer chooses to mess up the css as it sees fit.[PHP]<html>
<head>
<title>Grim PHP Syntax Highlighter</title>
<style type="text/css">
body {
font-family: Courier New;
font-size: 10pt;
white-space: nowrap;
}
div.lineNumbers {
float: left;
text-align: right;
margin-right: 8px;
padding-right: 8px;
border-right: 1px #999999 solid;
color: #777777;
}
span.v {
color: #0000BB;
}
span.k {
color: #007700;
}
span.s {
color: #DD0000;
}
span.c {
color: #FF8000;
}
</style>
</head>
<body>
<?php
$filename = 'forum/board_lib.php';
ob_start();
highlight_file($filename);
$source = ob_get_contents();
ob_end_clean();
$source = explode(chr(13), $source);
$source[0] = substr($source[0], 36);
$temp = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 15);
$source[count($source) - 1] = $temp;
for($i = 1; $i < count($source); $i++){
$source[$i] = substr($source[$i], 6);
}
for($i = 0; $i < count($source) - 1; $i++){
$source[$i] .= '<br />';
}
echo '<div class="lineNumbers">' . "\n";
for($i = 0; $i < count($source); $i++){
echo $i + 1 . '<br />' . "\n";
}
echo '</div>' . "\n";
echo '<div class="sourceCode">' . "\n";
$source = implode("\n", $source);
$source = str_replace('<span style="color: #0000BB">', '<span class="v">', $source);
$source = str_replace('<span style="color: #007700">', '<span class="k">', $source);
$source = str_replace('<span style="color: #DD0000">', '<span class="s">', $source);
$source = str_replace('<span style="color: #FF8000">', '<span class="c">', $source);
echo $source;
echo '</div>' . "\n";
?>
</body>
</html>[/PHP]Styx, I don't get the errors you mention, that's why I'm not sure how they're occurring on your end. It seems like you're always missing a letter somewhere.

DaWei Mar 19th, 2007 4:00 PM

Whether or not a line ending is 10, 13, or a combination of both depends on the platform. Windows files may, all by their li'l selves, have either a 10 or a 13+10. You might want to see if that's giving you a problem on the explode.

grimpirate Mar 19th, 2007 5:14 PM

2 Attachment(s)
I took into account what you suggested DaWei regarding the various combinations of the two characters and modified the code as follows:[PHP]<html>
<head>
<title>Grim PHP Syntax Highlighter</title>
<style type="text/css">
body {
font-family: Courier New;
font-size: 10pt;
white-space: nowrap;
}
div.lineNumbers {
float: left;
text-align: right;
margin-right: 8px;
padding-right: 8px;
border-right: 1px #999999 solid;
color: #777777;
}
span.v {
color: #0000BB;
}
span.k {
color: #007700;
}
span.s {
color: #DD0000;
}
span.c {
color: #FF8000;
}
</style>
</head>
<body>
<?php
$filename = 'syntax_h.php';
ob_start();
highlight_file($filename);
$source = ob_get_contents();
ob_end_clean();
$source = explode(chr(13), $source);
$source = implode('', $source);
$source = explode(chr(10), $source);
$source = implode('', $source);
$source = explode('<br />', $source);
$source[0] = substr($source[0], 35);
$source[count($source) - 1] = substr($source[count($source) - 1], 0, strlen($source[count($source) - 1]) - 14);
for($i = 0; $i < count($source) - 1; $i++){
$source[$i] .= '<br />';
}
echo '<div class="lineNumbers">' . "\n";
for($i = 0; $i < count($source); $i++){
echo $i + 1 . '<br />' . "\n";
}
echo '</div>' . "\n";
echo '<div class="sourceCode">' . "\n";
$source = implode("\n", $source);
$source = str_replace('<span style="color: #0000BB">', '<span class="v">', $source);
$source = str_replace('<span style="color: #007700">', '<span class="k">', $source);
$source = str_replace('<span style="color: #DD0000">', '<span class="s">', $source);
$source = str_replace('<span style="color: #FF8000">', '<span class="c">', $source);
echo $source;
echo '</div>' . "\n";
?>
</body>
</html>[/PHP]However, it still malfunctions in Internet Explorer. The attached pics show the problem that occurs in IE.


All times are GMT -5. The time now is 9:12 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC