Skip to content

Commit

Permalink
BlueScreen: implemented PHP syntax highlighter
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Sep 25, 2023
1 parent 193f8e5 commit 22c8d9c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 33 deletions.
80 changes: 57 additions & 23 deletions src/Tracy/BlueScreen/CodeHighlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ final class CodeHighlighter
{
private const DisplayLines = 15;

private const PhpColors = [
'comment' => '#998; font-style: italic',
'default' => '#000',
'html' => '#06B',
'keyword' => '#D24; font-weight: bold',
'string' => '#080',
];


/**
* Extract a snippet from the code, highlights the row and column, and adds line numbers.
*/
Expand Down Expand Up @@ -56,7 +65,7 @@ public static function highlightLine(string $html, int $line, int $column = 0):
1,
);
}
$out .= sprintf("<span class='tracy-line-highlight'>%{$numWidth}s: %s\n</span>%s", $n, $s, implode('', $openTags));
$out .= sprintf("<span class='tracy-line-highlight'>%{$numWidth}s: %s</span>\n%s", $n, $s, implode('', $openTags));
} else {
$out .= sprintf("<span class='tracy-line'>%{$numWidth}s:</span> %s\n", $n, $lines[$n]);
}
Expand All @@ -70,25 +79,50 @@ public static function highlightLine(string $html, int $line, int $column = 0):
/**
* Returns syntax highlighted source code.
*/
public static function highlightPhp(string $source, int $line, int $column = 0): string
public static function highlightPhp(string $code, int $line, int $column = 0): string
{
if (function_exists('ini_set')) {
ini_set('highlight.comment', '#998; font-style: italic');
ini_set('highlight.default', '#000');
ini_set('highlight.html', '#06B');
ini_set('highlight.keyword', '#D24; font-weight: bold');
ini_set('highlight.string', '#080');
}
$html = self::highlightPhpCode($code);
$html = self::highlightLine($html, $line, $column);
return "<pre class='tracy-code'><div><code>$html</code></div></pre>";
}

$source = preg_replace('#(__halt_compiler\s*\(\)\s*;).*#is', '$1', $source);
$source = str_replace(["\r\n", "\r"], "\n", $source);
$source = preg_replace('#/\*sensitive\{\*/.*?/\*\}\*/#s', Dumper\Describer::HiddenValue, $source);
$source = explode("\n", highlight_string($source, true));
$out = $source[0]; // <code><span color=highlight.html>
$tmp = str_replace('<br />', "\n", $source[1]);
$out .= self::highlightLine($tmp, $line, $column);
$out = str_replace('&nbsp;', ' ', $out) . $source[2] . @$source[3];
return "<pre class='tracy-code'><div>$out</div></pre>";

private static function highlightPhpCode(string $code): string
{
$code = str_replace("\r\n", "\n", $code);
$code = preg_replace('#(__halt_compiler\s*\(\)\s*;).*#is', '$1', $code);
$code = rtrim($code);
$code = preg_replace('#/\*sensitive\{\*/.*?/\*\}\*/#s', Dumper\Describer::HiddenValue, $code);

$lastColor = $baseColor = self::PhpColors['html'];
$out = "<span style=\"color: $lastColor\">";
foreach (\PhpToken::tokenize($code) as $token) {
$nextColor = match ($token->id) {
T_INLINE_HTML => $baseColor,
T_COMMENT, T_DOC_COMMENT => self::PhpColors['comment'],
T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, T_CLOSE_TAG, T_LINE, T_FILE, T_DIR, T_TRAIT_C, T_METHOD_C, T_FUNC_C, T_NS_C, T_CLASS_C,
T_STRING, T_VARIABLE, T_LNUMBER, T_DNUMBER => self::PhpColors['default'],
'"', T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING => self::PhpColors['string'],
T_WHITESPACE => $lastColor,
default => self::PhpColors['keyword'],
};

if ($lastColor !== $nextColor) {
if ($lastColor !== $baseColor) {
$out .= '</span>';
}
$lastColor = $nextColor;
if ($lastColor !== $baseColor) {
$out .= "<span style=\"color: $lastColor\">";
}
}

$out .= strtr($token->text, ['<' => '&lt;', '>' => '&gt;', '&' => '&amp;', "\t" => ' ', "\n" => "\n"]);
}
if ($lastColor !== $baseColor) {
$out .= '</span>';
}
return $out;
}


Expand All @@ -98,11 +132,11 @@ public static function highlightPhp(string $source, int $line, int $column = 0):
public static function highlightPhpCli(string $code, int $line, int $column = 0): string
{
$colors = [
'color: ' . ini_get('highlight.comment') => '1;30',
'color: ' . ini_get('highlight.default') => '1;36',
'color: ' . ini_get('highlight.html') => '1;35',
'color: ' . ini_get('highlight.keyword') => '1;37',
'color: ' . ini_get('highlight.string') => '1;32',
'color: ' . self::PhpColors['comment'] => '1;30',
'color: ' . self::PhpColors['default'] => '1;36',
'color: ' . self::PhpColors['html'] => '1;35',
'color: ' . self::PhpColors['keyword'] => '1;37',
'color: ' . self::PhpColors['string'] => '1;32',
'tracy-line' => '1;30',
'tracy-line-highlight' => "1;37m\e[41",
];
Expand Down
2 changes: 1 addition & 1 deletion src/Tracy/BlueScreen/assets/bluescreen.css
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ html.tracy-bs-visible body {
font-style: normal;
display: block;
padding: 0 1ch;
margin: 0 -1ch;
margin: 0 -1ch -1lh;
}

#tracy-bs .tracy-column-highlight {
Expand Down
17 changes: 8 additions & 9 deletions tests/Tracy/expected/Debugger.exception.html.expect
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> function </span><span style="color: #000">third</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #000">$arg1</span><span style="color: #D24; font-weight: bold">)
<span class='tracy-line'>%d%:</span> {
</span><span class='tracy-line-highlight'>%d%: throw new Exception('The my exception', 123);
</span><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
</span></span><span class='tracy-line-highlight'>%d%: throw new Exception('The my exception', 123);</span>
<span style="color: #06B"><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> </span><span style="color: #000">define</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #080">'MY_CONST'</span><span style="color: #D24; font-weight: bold">, </span><span style="color: #000">123</span><span style="color: #D24; font-weight: bold">);
Expand Down Expand Up @@ -77,8 +77,8 @@
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> function </span><span style="color: #000">second</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #000">$arg1</span><span style="color: #D24; font-weight: bold">, </span><span style="color: #000">$arg2</span><span style="color: #D24; font-weight: bold">)
<span class='tracy-line'>%d%:</span> {
</span><span class='tracy-line-highlight'>%d%: third([1, 2, 3]);
</span><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
</span></span><span class='tracy-line-highlight'>%d%: third([1, 2, 3]);</span>
<span style="color: #06B"><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> function </span><span style="color: #000">third</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #000">$arg1</span><span style="color: #D24; font-weight: bold">)
Expand Down Expand Up @@ -109,8 +109,8 @@
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> function </span><span style="color: #000">first</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #000">$arg1</span><span style="color: #D24; font-weight: bold">, </span><span style="color: #000">$arg2</span><span style="color: #D24; font-weight: bold">)
<span class='tracy-line'>%d%:</span> {
</span><span class='tracy-line-highlight'>%d%: second(true, false);
</span><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
</span></span><span class='tracy-line-highlight'>%d%: second(true, false);</span>
<span style="color: #06B"><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> }
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> function </span><span style="color: #000">second</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #000">$arg1</span><span style="color: #D24; font-weight: bold">, </span><span style="color: #000">$arg2</span><span style="color: #D24; font-weight: bold">)
Expand Down Expand Up @@ -143,9 +143,8 @@
<span class='tracy-line'>%d%:</span>
<span class='tracy-line'>%d%:</span> </span><span style="color: #000">define</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #080">'MY_CONST'</span><span style="color: #D24; font-weight: bold">, </span><span style="color: #000">123</span><span style="color: #D24; font-weight: bold">);
<span class='tracy-line'>%d%:</span> @</span><span style="color: #000">hex2bin</span><span style="color: #D24; font-weight: bold">(</span><span style="color: #080">'a'</span><span style="color: #D24; font-weight: bold">); </span><span style="color: #998; font-style: italic">// E_WARNING
</span><span class='tracy-line-highlight'>%d%: first(10, 'any string');
</span><span style="color: #D24; font-weight: bold"><span class='tracy-line'>%d%:</span> </span>
</span></code></div></pre>
</span></span><span class='tracy-line-highlight'>%d%: first(10, 'any string');</span>
<span style="color: #06B"></span></code></div></pre>

<table class="tracy-callstack-args">
<tr><th>$arg1</th><td><pre class="tracy-dump tracy-light"><span class="tracy-dump-number">10</span></pre>
Expand Down

0 comments on commit 22c8d9c

Please sign in to comment.