From 7b5d155f8ad56e718def76a9112df244cf62d8f9 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 24 Jun 2026 11:59:32 +0100 Subject: [PATCH 1/2] Fix invisible code blocks Torchlight returns un-highlighted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Torchlight returns some blocks un-highlighted (empty style, no token color spans) when its API can't tokenise a language — e.g. the Svelte snippets on some plugin pages. With `.prose pre` being transparent, these inherit prose's light text color and render invisible. Add a CSS fallback giving un-highlighted `code.torchlight` blocks the theme's dark surface and readable text (via new `--color-torchlight-*` theme vars), excluding highlighted blocks so they keep their inline colors. Co-Authored-By: Claude Opus 4.8 (1M context) --- resources/css/app.css | 17 +++++++++ tests/Feature/TorchlightCodeBlockTest.php | 42 +++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 tests/Feature/TorchlightCodeBlockTest.php diff --git a/resources/css/app.css b/resources/css/app.css index 2046d534..10bb7bda 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -26,6 +26,10 @@ --color-snow-flurry-200: #a2fd00; --color-snow-flurry-300: #97ed00; + /* Torchlight code surface (matches the material-theme-palenight theme) */ + --color-torchlight-surface: #292d3e; + --color-torchlight-text: #a6accd; + --font-poppins: 'Poppins', Verdana, sans-serif; } @@ -296,6 +300,19 @@ nav.docs-navigation li:has(.third-tier .exact-active) > .subsection-header { @apply block min-w-max py-4; } +/* + Fallback for blocks Torchlight returns un-highlighted (e.g. a language + its API can't tokenise, like the Svelte snippets on some plugin pages). + These come back with an empty `style` attribute and no per-token color + spans, so without this they have no background and inherit prose's light + text color, rendering the block invisible. Successfully highlighted + blocks set `background-color` inline, so they're excluded here and keep + their own theme colors. +*/ +.prose pre code.torchlight:not([style*='background-color']) { + @apply bg-torchlight-surface text-torchlight-text; +} + /* Horizontal line padding. */ diff --git a/tests/Feature/TorchlightCodeBlockTest.php b/tests/Feature/TorchlightCodeBlockTest.php new file mode 100644 index 00000000..7c386456 --- /dev/null +++ b/tests/Feature/TorchlightCodeBlockTest.php @@ -0,0 +1,42 @@ +assertStringContainsString("class='torchlight'", $html); + } + + public function test_unhighlighted_block_carries_torchlight_class_for_css_fallback(): void + { + // When Torchlight cannot highlight a block (no API token, as in the + // test environment, or a language its API can't tokenise such as the + // Svelte snippet below) it returns the block un-highlighted with an + // empty `style` attribute and no per-token color spans. The fallback + // CSS targets `code.torchlight:not([style*='background-color'])` to + // give these otherwise-invisible blocks a background and readable + // text, so the markup must still carry the `torchlight` class without + // an inline background color. + $svelte = <<<'MD' + ```svelte +
+ {#if status}

{status}

{/if} + +
+ ``` + MD; + + $html = CommonMark::convertToHtml($svelte); + + $this->assertStringContainsString("class='torchlight'", $html); + $this->assertStringContainsString("style=''", $html); + $this->assertStringNotContainsString('background-color', $html); + } +} From 331662edce2231b9b224569678925c60ae8cf38e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 24 Jun 2026 12:22:53 +0100 Subject: [PATCH 2/2] Make Torchlight code block test deterministic without a token CI has no TORCHLIGHT_TOKEN, and Torchlight throws outside production when rendering a block with no token. Set a fake token and Http::fake the API so Torchlight uses its un-highlighted fallback, reproducing the invisible block state offline and deterministically. Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/Feature/TorchlightCodeBlockTest.php | 32 +++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/Feature/TorchlightCodeBlockTest.php b/tests/Feature/TorchlightCodeBlockTest.php index 7c386456..5f60cb9d 100644 --- a/tests/Feature/TorchlightCodeBlockTest.php +++ b/tests/Feature/TorchlightCodeBlockTest.php @@ -3,10 +3,26 @@ namespace Tests\Feature; use App\Support\CommonMark\CommonMark; +use Illuminate\Support\Facades\Http; use Tests\TestCase; class TorchlightCodeBlockTest extends TestCase { + protected function setUp(): void + { + parent::setUp(); + + // A token is required for Torchlight to attempt highlighting (it throws + // outside production otherwise), and faking the API forces its built-in + // "un-highlighted" fallback — the same state produced in the wild when + // Torchlight cannot tokenise a block. This keeps the test deterministic + // and offline regardless of whether a real token is present locally. + config(['torchlight.token' => 'test-token']); + Http::fake([ + '*' => Http::response(['blocks' => []], 200), + ]); + } + public function test_fenced_code_renders_as_a_torchlight_block(): void { $html = CommonMark::convertToHtml("```php\necho 'hello';\n```"); @@ -16,14 +32,14 @@ public function test_fenced_code_renders_as_a_torchlight_block(): void public function test_unhighlighted_block_carries_torchlight_class_for_css_fallback(): void { - // When Torchlight cannot highlight a block (no API token, as in the - // test environment, or a language its API can't tokenise such as the - // Svelte snippet below) it returns the block un-highlighted with an - // empty `style` attribute and no per-token color spans. The fallback - // CSS targets `code.torchlight:not([style*='background-color'])` to - // give these otherwise-invisible blocks a background and readable - // text, so the markup must still carry the `torchlight` class without - // an inline background color. + // When Torchlight cannot highlight a block (e.g. a language its API + // can't tokenise, such as the Svelte snippet below) it returns the + // block un-highlighted with an empty `style` attribute and no per-token + // color spans. The fallback CSS targets + // `code.torchlight:not([style*='background-color'])` to give these + // otherwise-invisible blocks a background and readable text, so the + // markup must still carry the `torchlight` class without an inline + // background color. $svelte = <<<'MD' ```svelte