diff --git a/src/Tracy/BlueScreen/CodeHighlighter.php b/src/Tracy/BlueScreen/CodeHighlighter.php
index 4552c8269..fb5ae0f3d 100644
--- a/src/Tracy/BlueScreen/CodeHighlighter.php
+++ b/src/Tracy/BlueScreen/CodeHighlighter.php
@@ -71,25 +71,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 "
$html
";
+ }
+
- $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]; //
- $tmp = str_replace('
', "\n", $source[1]);
- $out .= self::highlightLine($tmp, $line, $column);
- $out = str_replace(' ', ' ', $out) . $source[2] . @$source[3];
- return "$out
";
+ 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);
+
+ $last = $out = '';
+ foreach (\PhpToken::tokenize($code) as $token) {
+ $next = match ($token->id) {
+ T_COMMENT, T_DOC_COMMENT, T_INLINE_HTML => 'tracy-code-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_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, T_NAME_RELATIVE => '',
+ T_LNUMBER, T_DNUMBER => 'tracy-dump-number',
+ T_VARIABLE => 'tracy-code-var',
+ T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING => 'tracy-dump-string',
+ T_WHITESPACE => $last,
+ default => 'tracy-code-keyword',
+ };
+
+ if ($last !== $next) {
+ if ($last !== '') {
+ $out .= '';
+ }
+ $last = $next;
+ if ($last !== '') {
+ $out .= "";
+ }
+ }
+
+ $out .= strtr($token->text, ['<' => '<', '>' => '>', '&' => '&', "\t" => ' ']);
+ }
+ if ($last !== '') {
+ $out .= '';
+ }
+ return $out;
}
@@ -101,13 +126,13 @@ public static function highlightPhpCli(string $code, int $line, int $column = 0)
return Helpers::htmlToAnsi(
self::highlightPhp($code, $line, $column),
[
- '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',
- 'tracy-line' => '1;30',
- 'tracy-line-highlight' => "1;37m\e[41",
+ 'string' => '1;32',
+ 'number' => '1;32',
+ 'code-comment' => '1;30',
+ 'code-keyword' => '1;37',
+ 'code-var' => '1;36',
+ 'line' => '1;30',
+ 'line-highlight' => "1;37m\e[41",
],
);
}
diff --git a/src/Tracy/BlueScreen/assets/bluescreen.css b/src/Tracy/BlueScreen/assets/bluescreen.css
index 13cceb324..abf309fa9 100644
--- a/src/Tracy/BlueScreen/assets/bluescreen.css
+++ b/src/Tracy/BlueScreen/assets/bluescreen.css
@@ -267,6 +267,20 @@ html.tracy-bs-visible body {
white-space: pre;
}
+#tracy-bs .tracy-code-comment {
+ color: rgba(0, 0, 0, 0.5);
+ font-style: italic;
+}
+
+#tracy-bs .tracy-code-keyword {
+ color: #D24;
+ font-weight: bold;
+}
+
+#tracy-bs .tracy-code-var {
+ font-weight: bold;
+}
+
#tracy-bs .tracy-line-highlight {
background: #CD1818;
color: white;
diff --git a/src/Tracy/Dumper/Renderer.php b/src/Tracy/Dumper/Renderer.php
index 3ff8867b8..edcff7498 100644
--- a/src/Tracy/Dumper/Renderer.php
+++ b/src/Tracy/Dumper/Renderer.php
@@ -101,7 +101,6 @@ public function renderAsText(\stdClass $model, array $colors = []): string
}
$s = $colors ? Helpers::htmlToAnsi($s, $colors) : Helpers::htmlToText($s);
- $s = preg_replace('/\e\[0m( *)(?=\e)/', '$1', $s);
$s = str_replace('…', '...', $s);
$s .= substr($s, -1) === "\n" ? '' : "\n";
diff --git a/src/Tracy/Helpers.php b/src/Tracy/Helpers.php
index 132858983..fad81e006 100644
--- a/src/Tracy/Helpers.php
+++ b/src/Tracy/Helpers.php
@@ -479,17 +479,18 @@ public static function htmlToAnsi(string $s, array $colors): string
{
$stack = ['0'];
$s = preg_replace_callback(
- '#<\w+(?: (?:style|class)=["\'](?:tracy-dump-)?(.*?)["\'])?[^>]*>|\w+>#',
+ '#<\w+(?: class=["\']tracy-(?:dump-)?([\w-]+)["\'])?[^>]*>|\w+>#',
function ($m) use ($colors, &$stack): string {
if ($m[0][1] === '/') {
array_pop($stack);
} else {
$stack[] = isset($m[1], $colors[$m[1]]) ? $colors[$m[1]] : '0';
}
- return "\e[0m\e[" . end($stack) . 'm';
+ return "\e[" . end($stack) . 'm';
},
$s,
);
+ $s = preg_replace('/\e\[0m( *)(?=\e)/', '$1', $s);
$s = self::htmlToText($s);
return $s;
}
diff --git a/tests/Tracy/expected/Debugger.exception.html.expect b/tests/Tracy/expected/Debugger.exception.html.expect
index 601a033ea..71f42d3c0 100644
--- a/tests/Tracy/expected/Debugger.exception.html.expect
+++ b/tests/Tracy/expected/Debugger.exception.html.expect
@@ -33,22 +33,22 @@
File: %a%
-
%d%:
+ %d%:
%d%:
-%d%: function second($arg1, $arg2)
+%d%: function second($arg1, $arg2)
%d%: {
-%d%: third([1, 2, 3]);
+%d%: third([1, 2, 3]);
%d%: }
%d%:
%d%:
-%d%: function third($arg1)
+%d%: function third($arg1)
%d%: {
%d%: throw new Exception('The my exception', 123);
-%d%: }
+%d%: }
%d%:
%d%:
-%d%: define('MY_CONST', 123);
-
+%d%: define('MY_CONST', 123);
+
@@ -67,22 +67,22 @@
-
%d%:
+ %d%:
%d%:
-%d%: function first($arg1, $arg2)
+%d%: function first($arg1, $arg2)
%d%: {
-%d%: second(true, false);
+%d%: second(true, false);
%d%: }
%d%:
%d%:
-%d%: function second($arg1, $arg2)
+%d%: function second($arg1, $arg2)
%d%: {
%d%: third([1, 2, 3]);
-%d%: }
+%d%: }
%d%:
%d%:
-%d%: function third($arg1)
-
+%d%: function third($arg1)
+
$arg1 |
@@ -99,22 +99,22 @@
- 19:
+ 19:
%d%:
-%d%: Debugger::$productionMode = false;
-%d%: setHtmlMode();
+%d%: Debugger::$productionMode = false;
+%d%: setHtmlMode();
%d%:
-%d%: Debugger::enable();
+%d%: Debugger::enable();
%d%:
%d%:
-%d%: function first($arg1, $arg2)
+%d%: function first($arg1, $arg2)
%d%: {
%d%: second(true, false);
-%d%: }
+%d%: }
%d%:
%d%:
-%d%: function second($arg1, $arg2)
-
+%d%: function second($arg1, $arg2)
+
$arg1 | true
@@ -133,19 +133,18 @@
- %d%:
+ %d%:
%d%:
-%d%: function third($arg1)
+%d%: function third($arg1)
%d%: {
-%d%: throw new Exception('The my exception', 123);
+%d%: throw new Exception('The my exception', 123);
%d%: }
%d%:
%d%:
-%d%: define('MY_CONST', 123);
-%d%: @hex2bin('a'); // E_WARNING
+%d%: define('MY_CONST', 123);
+%d%: @hex2bin('a'); %d%: first(10, 'any string');
-%d%:
-
+
|
---|
|
---|