[PHP-WEBMASTER] [web-php] php-85-focus: Highlight focus comment

Author: Sergey Panteleev (saundefined)
Date: 2025-11-08T21:18:33+03:00

Commit: Highlight focus comment · php/web-php@374ba05 · GitHub
Raw diff: https://github.com/php/web-php/commit/374ba05ef6bac375be3896fc637734004eedc38a.diff

Highlight focus comment

Changed paths:
  M include/layout.inc
  M releases/8.5/release.inc
  M styles/theme-base.css

Diff:

diff --git a/include/layout.inc b/include/layout.inc
index 83efa1c6bb..9b0d3181b0 100644
--- a/include/layout.inc
+++ b/include/layout.inc
@@ -15,39 +15,86 @@ ini_set('highlight.string', 'string');
ini_set('highlight.html', 'html');

// Highlight PHP code
-function highlight_php($code, $return = false)
+function highlight_php(string $code, bool $return = false): ?string
{
- $highlighted = highlight_string($code, true);
+ $hasFocusTag = preg_match('!//.*\[focus]!', $code);
+
+ $highlighted = highlight_php_process_lines($code, $hasFocusTag);
+
+ if ($return) {
+ return $highlighted;
+ }
+
+ echo $highlighted;
+ return null;
+}
+
+function highlight_php_process_lines(string $code, bool $hasFocusTag): string
+{
+ $lines = explode(PHP_EOL, $code);
+ $processedLines = ;
+
+ foreach ($lines as $line) {
+ if ($line === '') {
+ $processedLines = '<br />';
+ continue;
+ }
+
+ $processedLines = highlight_php_process_single_line($line);
+ }
+
+ $highlighted = implode('', $processedLines);

- // Use this ugly hack for now to avoid code snippets with bad syntax screwing up the highlighter
     if (strstr($highlighted, "include/layout.inc</b>")) {
- $highlighted = '<span class="html">' . nl2br(htmlentities($code, ENT_HTML5), false) . "</span>";
+ return format_as_plain_code($code);
     }

- // Fix output to use CSS classes and wrap well
- $highlighted = '<div class="phpcode">' . strtr(
- $highlighted,
- [
- '&nbsp;' => ' ',
- "\n" => '',
+ return format_highlighted_output($highlighted, $hasFocusTag);
+}

- '<span style="color: ' => '<span class="',
- ],
- ) . '</div>';
+function highlight_php_process_single_line(string $line): string
+{
+ $highlighted = highlight_string('<?php ' . $line, true);
+ $highlighted = str_replace('&lt;?php&nbsp;', '', $highlighted);

- if ($return) { return $highlighted; }
- echo $highlighted;
- return null;
+ $isFocus = preg_match('!//.*\[focus]!', $line);
+
+ $highlighted = preg_replace('!//[^<]*\s*\[focus]!', '', $highlighted);
+
+ return '<span class="' . ($isFocus ? 'focus' : 'fade') . '">' . $highlighted . '</span>';
+}
+
+function format_as_plain_code(string $code): string
+{
+ return '<div class="phpcode"><span class="html">' .
+ nl2br(htmlentities($code, ENT_HTML5), false) .
+ '</span></div>';
}

-// Same as highlight_php() but does not require '<?php' in $code
-function highlight_php_trimmed($code, $return = false)
+function format_highlighted_output(string $highlighted, bool $hasFocus): string
+{
+ return '<div class="phpcode' . ($hasFocus ? ' phpcode--focused' : '') . '">' .
+ strtr(
+ $highlighted,
+ [
+ '&nbsp;' => ' ',
+ "\n" => '',
+ '<span style="color: ' => '<span class="',
+ ],
+ ) .
+ '</div>';
+}
+
+function highlight_php_trimmed(string $code, bool $return = false): ?string
{
     $code = "<?php\n" . $code;
     $highlighted_code = highlight_php($code, true);
     $highlighted_code = preg_replace("!&lt;\?php(<br />)+!", '', $highlighted_code, 1);

- if ($return) { return $highlighted_code; }
+ if ($return) {
+ return $highlighted_code;
+ }
+
     echo $highlighted_code;
     return null;
}
diff --git a/releases/8.5/release.inc b/releases/8.5/release.inc
index 246c654a33..e53b6cc279 100644
--- a/releases/8.5/release.inc
+++ b/releases/8.5/release.inc
@@ -267,9 +267,11 @@ final class Stopwatch
     public function stopLap()
     {
         $fromStart = hrtime(true) - $this->start;
- $lastLap = $this->laps !==
- ? $this->laps[array_key_last($this->laps)]
- : 0;
+
+ $lastLap = $this->laps !== // [focus]
+ ? $this->laps[array_key_last($this->laps)] // [focus]
+ : 0; // [focus]
+
         $lapDuration = $fromStart - $lastLap;

         $this->laps = $fromStart;
@@ -306,7 +308,9 @@ final class Stopwatch
     public function stopLap()
     {
         $fromStart = hrtime(true) - $this->start;
- $lastLap = array_last($this->laps) ?? 0;
+
+ $lastLap = array_last($this->laps) ?? 0; // [focus]
+
         $lapDuration = $fromStart - $lastLap;

         $this->laps = $fromStart;
diff --git a/styles/theme-base.css b/styles/theme-base.css
index 59b4ad6329..6674cb9545 100644
--- a/styles/theme-base.css
+++ b/styles/theme-base.css
@@ -501,6 +501,15 @@ dl dd {
     overflow-x: auto;
}

+.phpcode--focused .fade {
+ opacity: .5;
+ transition: .2s all;
+}
+
+.phpcode--focused:hover .fade {
+ opacity: 1;
+}
+
.phpcode, div.classsynopsis {
     text-align: left;
}