From b8b10b7e8f661ab3e6514e35aeba3b970b484ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gra=C3=9Fl?= Date: Thu, 29 Oct 2026 16:39:04 +0100 Subject: [PATCH 1/2] The pages call the file a templates file, not a chrome file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The library renamed the key that points at a file of template definitions: `chrome:` is `templates-file:` now, and the file it names is a templates file. The word "chrome" keeps its other meaning — the shapes a template draws — and the pages keep it there. The exceptions follow the library: `ChromeNotFound` and `ChromeTooLarge` are `TemplatesFileNotFound` and `TemplatesFileTooLarge`, and a templates file that holds a slide is now `MalformedTemplatesFile` rather than a case of `MalformedChrome`. --- content/presentation/directives.md | 10 +++++----- content/presentation/errors.md | 12 ++++++----- content/presentation/index.md | 2 +- content/presentation/themes.md | 4 ++-- src/Reference/Vocabularies.php | 6 +++--- tests/Claims/templates.php | 18 ++++++++--------- .../Support/{Chrome.php => TemplatesFile.php} | 20 +++++++++---------- 7 files changed, 37 insertions(+), 35 deletions(-) rename tests/Support/{Chrome.php => TemplatesFile.php} (51%) diff --git a/content/presentation/directives.md b/content/presentation/directives.md index 2d1a806..d7ec9da 100644 --- a/content/presentation/directives.md +++ b/content/presentation/directives.md @@ -260,14 +260,14 @@ Every key of every slide's frontmatter must be one of these nine: | `author` | string | the theme's, else `markdown-presentation` | **first only** | | `description` | string | `null` | **first only** | | `template` | string, or a list of them | none | any | -| `chrome` | string | none | **first only** | +| `templates-file` | string | none | **first only** | The layout roles are listed with the [themes](/presentation/themes/#layout-roles). Anything else — including Slidev's own `two-cols` — is refused with the list of what would have worked. A deck directive on a later slide is refused by name, because it is nearly always a slide that was meant to be the first one. The deck's own frontmatter **is the first slide's**, so `theme:`, -`author:`, `description:` and `chrome:` belong on the slide that opens the deck. +`author:`, `description:` and `templates-file:` belong on the slide that opens the deck. {% example %} ````md presentation "The four keys that describe a deck" @@ -374,18 +374,18 @@ drawn where the template puts it. The chrome is drawn **over** what the slide placed itself, so a full-bleed picture is behind the wordmark and not over it. -### The chrome file +### The templates file A deck may keep its templates in a file beside it and name it in the deck's frontmatter: ```markdown --- theme: ./theme.yml -chrome: ./chrome.md +templates-file: ./templates.md --- ``` -`chrome.md` is a Markdown file of template definitions in the same syntax as a deck, and it is +`templates.md` is a Markdown file of template definitions in the same syntax as a deck, and it is resolved against the deck's own directory — so a deck and the furniture it shares travel together. A file that is not there is a failure, and so is a file outside the directories the render may read: a path a deck wrote is held to the same scope as a picture in it. A file that holds a slide diff --git a/content/presentation/errors.md b/content/presentation/errors.md index 085019b..5d6fbb6 100644 --- a/content/presentation/errors.md +++ b/content/presentation/errors.md @@ -21,9 +21,10 @@ is about both libraries, is on [Errors in general](/errors/). | `UnknownMarker` | `::click=0`, backwards, over 500, unclosed, or a stray closer | | `UnknownLayoutRole` | `layout:` is not one of the layout roles | | `UnknownTemplate` | a slide names a template the deck does not have — the message names the templates | -| `MalformedChrome` | a template holds ordinary Markdown, or a chrome file holds a slide | -| `ChromeNotFound` | the chrome file a deck names is not there, or is outside the roots | -| `ChromeTooLarge` | the chrome file a deck names is over the ceiling | +| `MalformedChrome` | a template holds ordinary Markdown | +| `MalformedTemplatesFile` | the templates file a deck names holds a slide | +| `TemplatesFileNotFound` | the templates file a deck names is not there, or is outside the roots | +| `TemplatesFileTooLarge` | the templates file a deck names is over the ceiling | | `UnsupportedColumn` | more `::column` markers than the layout has columns | | `UnsupportedImageFormat` | not an image, no decoder, or over the ceiling | | `UnsupportedLink` | `javascript:`, `data:`, `phar://`, `file://`, a UNC share | @@ -51,5 +52,6 @@ Five sit beside `InvalidInput` rather than under it: nothing a deck names fixes be read, a target that cannot be written, a conversion with nothing to convert, or a dependency that was installed without the fixes the library needs. -The three that carry a template are about the deck rather than about a file on disk: a name -nothing is under, a body that holds the wrong thing, and a file that is not there. +The four that carry a template are about the deck rather than about a file on disk: a name +nothing is under, a body that holds the wrong thing, a file that holds a slide, and a file that is +not there. diff --git a/content/presentation/index.md b/content/presentation/index.md index 3ef602d..c173f74 100644 --- a/content/presentation/index.md +++ b/content/presentation/index.md @@ -280,7 +280,7 @@ PowerPoint open the deck as `[Repaired]`. | `MAX_SLIDES` | 1000 | | `MAX_STEP` | 500 | | `MAX_PIXELS` | 16,777,216 — 4096 × 4096, enforced on the file header | -| `MAX_BYTES` | 1,048,576 — the size of a chrome file | +| `MAX_BYTES` | 1,048,576 — the size of a templates file | | `MAX_SHAPES` | 100 — the shapes one slide may carry | | `MAX_PART_BYTES` | 4,194,304 — one part of a theme's template | diff --git a/content/presentation/themes.md b/content/presentation/themes.md index b74d8db..811e195 100644 --- a/content/presentation/themes.md +++ b/content/presentation/themes.md @@ -134,8 +134,8 @@ A **template** is not a theme, and it does not live beside one. A theme's own `template.pptx` is a **third thing** and shares only the name: it is the PowerPoint file that says where the theme's layouts put their boxes, and it says nothing about the furniture on a slide. A template that says where the furniture goes is written in Markdown, beside the deck -or in it — `chrome: ./chrome.md` resolves against the deck's own directory, so a deck and the -furniture it shares travel together. +or in it — `templates-file: ./templates.md` resolves against the deck's own directory, so a deck +and the furniture it shares travel together. The rules a template follows, and the four things that decide what one is, are on [Presentation directives](/presentation/directives/#slide-templates). diff --git a/src/Reference/Vocabularies.php b/src/Reference/Vocabularies.php index 57d8dd6..6b17272 100644 --- a/src/Reference/Vocabularies.php +++ b/src/Reference/Vocabularies.php @@ -11,7 +11,7 @@ use MarkdownPresentation\Render\ImageConverter; use MarkdownPresentation\Render\PresentationRenderer; use MarkdownPresentation\Render\TemplateGeometry; -use MarkdownPresentation\Template\ChromeFile; +use MarkdownPresentation\Template\TemplatesFile; use MarkdownPresentation\Theme\LayoutRole; use MarkdownPresentation\Theme\StyleMapping; use MarkdownPresentation\Theme\StyleSlots; @@ -79,7 +79,7 @@ public static function all(): array 'presentation.ceilings' => new Vocabulary( [ 'PresentationRenderer::MAX_SLIDES, BlockTranslator::MAX_STEP, ImageConverter::MAX_PIXELS, ' - . 'ChromeFile::MAX_BYTES, Furniture::MAX_SHAPES, TemplateGeometry::MAX_PART_BYTES' + . 'TemplatesFile::MAX_BYTES, Furniture::MAX_SHAPES, TemplateGeometry::MAX_PART_BYTES' => [ 'MAX_SLIDES', 'MAX_STEP', @@ -93,7 +93,7 @@ public static function all(): array 'MAX_SLIDES' => PresentationRenderer::MAX_SLIDES, 'MAX_STEP' => BlockTranslator::MAX_STEP, 'MAX_PIXELS' => ImageConverter::MAX_PIXELS, - 'MAX_BYTES' => ChromeFile::MAX_BYTES, + 'MAX_BYTES' => TemplatesFile::MAX_BYTES, 'MAX_SHAPES' => Furniture::MAX_SHAPES, 'MAX_PART_BYTES' => TemplateGeometry::MAX_PART_BYTES, ], diff --git a/tests/Claims/templates.php b/tests/Claims/templates.php index 4b8e27b..8200b39 100644 --- a/tests/Claims/templates.php +++ b/tests/Claims/templates.php @@ -2,9 +2,9 @@ declare(strict_types=1); -use MarkdownOffice\Documentation\Tests\Support\Chrome; use MarkdownOffice\Documentation\Tests\Support\Deck; use MarkdownOffice\Documentation\Tests\Support\Site; +use MarkdownOffice\Documentation\Tests\Support\TemplatesFile; /** * The claims the pages make about the slide templates. @@ -62,24 +62,24 @@ expect(\array_search('circle', $shapes, true))->toBeLessThan(\array_search('rectangle', $shapes, true)); }); -it('reads a chrome file from beside the deck', function () { - $shapes = Chrome::shapes( - "---\nchrome: ./chrome.md\n---\n# One\n\n---\nlayout: blank\ntemplate: brand\n---\n\nWords.\n", +it('reads a templates file from beside the deck', function () { + $shapes = TemplatesFile::shapes( + "---\ntemplates-file: ./templates.md\n---\n# One\n\n---\nlayout: blank\ntemplate: brand\n---\n\nWords.\n", "---\ntemplate: brand\n---\n::rectangle{left=0 top=0 width=10% height=10%}\n", ); expect($shapes[1])->toContain('rectangle'); }); -it('refuses a chrome file that is not there', function () { - $message = Deck::refusal("---\nchrome: ./nowhere.md\n---\n# One\n", \sys_get_temp_dir()); +it('refuses a templates file that is not there', function () { + $message = Deck::refusal("---\ntemplates-file: ./nowhere.md\n---\n# One\n", \sys_get_temp_dir()); - expect($message)->toContain('There is no chrome file at'); + expect($message)->toContain('There is no templates file at'); }); it('lets the deck\'s own template override an imported one of the same name', function () { - $shapes = Chrome::shapes( - "---\nchrome: ./chrome.md\n---\n# One\n\n---\ntemplate: brand\n---\n::circle{left=1% top=1% width=5% height=5%}\n\n---\nlayout: blank\ntemplate: brand\n---\n\nWords.\n", + $shapes = TemplatesFile::shapes( + "---\ntemplates-file: ./templates.md\n---\n# One\n\n---\ntemplate: brand\n---\n::circle{left=1% top=1% width=5% height=5%}\n\n---\nlayout: blank\ntemplate: brand\n---\n\nWords.\n", "---\ntemplate: brand\n---\n::rectangle{left=0 top=0 width=10% height=10%}\n", ); diff --git a/tests/Support/Chrome.php b/tests/Support/TemplatesFile.php similarity index 51% rename from tests/Support/Chrome.php rename to tests/Support/TemplatesFile.php index d051640..04a601e 100644 --- a/tests/Support/Chrome.php +++ b/tests/Support/TemplatesFile.php @@ -5,38 +5,38 @@ namespace MarkdownOffice\Documentation\Tests\Support; /** - * A deck's own directory, and the chrome file beside it. + * A deck's own directory, and the templates file beside it. * * A template may be imported from a file beside the deck, so a claim about one needs a * deck's directory to put the file in — and the deck has to be rendered from there, or the * path is resolved against somewhere else. */ -final class Chrome +final class TemplatesFile { /** - * A directory holding a chrome file, and the directory it is in. + * A directory holding a templates file, and the directory it is in. */ public static function beside(string $markdown): string { - $root = Directory::make('chrome'); + $root = Directory::make('templates'); - \file_put_contents($root . '/chrome.md', $markdown); + \file_put_contents($root . '/templates.md', $markdown); return $root; } /** - * The shapes of a deck drawn against a chrome file. + * The shapes of a deck drawn against a templates file. * - * The chrome is written beside the deck and taken away again, whatever the deck says: - * a file left behind is a file the next test draws against. + * The templates file is written beside the deck and taken away again, whatever the deck + * says: a file left behind is a file the next test draws against. * * @return list> */ - public static function shapes(string $markdown, string $chrome): array + public static function shapes(string $markdown, string $templates): array { return Directory::during( - self::beside($chrome), + self::beside($templates), static fn (string $root): array => Deck::shapes($markdown, $root), ); } From 52e1158f67a8e54b8e0cd8a6088a190a6920fa5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gra=C3=9Fl?= Date: Thu, 29 Oct 2026 16:43:48 +0100 Subject: [PATCH 2/2] The four template failures are the deck author's to fix --- content/presentation/errors.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/presentation/errors.md b/content/presentation/errors.md index 5d6fbb6..5a49f67 100644 --- a/content/presentation/errors.md +++ b/content/presentation/errors.md @@ -52,6 +52,5 @@ Five sit beside `InvalidInput` rather than under it: nothing a deck names fixes be read, a target that cannot be written, a conversion with nothing to convert, or a dependency that was installed without the fixes the library needs. -The four that carry a template are about the deck rather than about a file on disk: a name -nothing is under, a body that holds the wrong thing, a file that holds a slide, and a file that is -not there. +The four that carry a template are the deck author's to fix: a name nothing is under, a body +that holds the wrong thing, a file that holds a slide, and a file that is not there.