Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ All notable changes to this project are documented here. The format follows
not over it.

The templates may also live in a file beside the deck, named by the deck's frontmatter
and resolved against the deck's own directory, so that a deck and the furniture it
shares travel together. The deck's own templates override the imported ones of the same
name, the way a deck's own theme overrides the shipped one.
with `templates-file:` and resolved against the deck's own directory, so that a deck and
the furniture it shares travel together. The deck's own templates override the imported
ones of the same name, the way a deck's own theme overrides the shipped one.

`examples/markdown/16-templates.md` is the deck that shows it: a template defined in the
deck, slides that name one, two and three of them, a template imported from
`templates/chrome.md`, and a template of the deck's own of the same name as one the file
holds — the one that is drawn. The company is invented.
`templates/templates.md`, and a template of the deck's own of the same name as one the
file holds — the one that is drawn. The company is invented.

- **A whole corporate template, as the files a company has.** A theme, a brand mark and
the furniture of a deck are three separate things, and a company that has all three has
Expand All @@ -42,13 +42,13 @@ All notable changes to this project are documented here. The format follows
`examples/markdown/17-corporate-template.md` is a deck that has them: a theme of its own
in `examples/markdown/corporate/theme.yml`, a mark in two colours — one for a light page
and one for a dark one, with the crosshair knocked out of it rather than painted on it,
so the page shows through it either way — and a chrome file holding the wordmark, the
so the page shows through it either way — and a templates file holding the wordmark, the
rule and the footer.

**A dark slide and a light one are the same deck, and the furniture on them cannot be
the same furniture**: the name is ink on a light page and white on a dark one, so the
dark wordmark is the same named style with the colour laid over it. That is the one
thing a chrome file cannot decide for itself, and it is why there are two of them.
thing a templates file cannot decide for itself, and it is why there are two of them.

The company is invented, and so is every figure in the deck.

Expand Down Expand Up @@ -228,20 +228,22 @@ All notable changes to this project are documented here. The format follows
struck-through word rather than refused. The arms of the match are the vocabulary now, and
an attribute they do not know is refused by name.

- **A chrome file is read with a ceiling.** The chrome file is the one file this library
reads whole, and it is the one a deck names in its frontmatter: a picture is bounded by
the pixels of its raster and a part of a template by the bytes it inflates to, and the
chrome file was bounded by nothing at all. It is read with a ceiling of a megabyte now, and
a file over it is refused with its size and the ceiling in the message. The ceiling is an
argument of `ChromeFile`, so a caller can hold a deck to a smaller one.
- **A templates file is read with a ceiling.** The templates file is the one file this
library reads whole, and it is the one a deck names in its frontmatter: a picture is
bounded by the pixels of its raster and a part of a template by the bytes it inflates to,
and the templates file was bounded by nothing at all. It is read with a ceiling of a
megabyte now, and a file over it is refused with its size and the ceiling in the message.
The ceiling is an argument of `TemplatesFile`, so a caller can hold a deck to a smaller
one.

- **A slide carries at most a hundred shapes.** The chrome of a template is read once and
drawn on every slide that names it, so the shapes of a template are multiplied by the
slides that draw them: two hundred shapes in a chrome file named by sixty slides is twelve
thousand shapes and ten megabytes of slide XML, and neither factor was bounded. The slide
count is bounded by `PresentationRenderer::MAX_SLIDES`, and `Furniture::MAX_SHAPES` is the
other half of that bound — a slide that carries more than a hundred shapes, the chrome of
a template included, is refused with the number and the ceiling in the message.
slides that draw them: two hundred shapes in a templates file named by sixty slides is
twelve thousand shapes and ten megabytes of slide XML, and neither factor was bounded.
The slide count is bounded by `PresentationRenderer::MAX_SLIDES`, and
`Furniture::MAX_SHAPES` is the other half of that bound — a slide that carries more than
a hundred shapes, the chrome of a template included, is refused with the number and the
ceiling in the message.

- **A picture in a template is paid for once.** The chrome of a template is drawn on every
slide that names it, and each of those slides had a picture of its own in the package: a
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1549,19 +1549,19 @@ The page number is furniture, so it is written in a template and drawn on every
names it. A slide may write one itself as well, and the number it carries is the number of
the slide it is on.

#### 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
resolved against the deck's own directory — so a deck and the furniture it shares travel
`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.

Expand Down Expand Up @@ -1720,7 +1720,7 @@ slide that names it:
| Ceiling | Value | Bounds |
| --- | --- | --- |
| `Render\Furniture::MAX_SHAPES` | 100 | the shapes one slide may carry, the chrome of a template included |
| `Template\ChromeFile::MAX_BYTES` | one megabyte | the chrome file a deck may name in its frontmatter |
| `Template\TemplatesFile::MAX_BYTES` | one megabyte | the templates file a deck may name in its frontmatter |

Both are refused with the number and the ceiling in the message, and the shape count is the
other half of the slide count: a hundred shapes on a slide is a hundred shapes on each of the
Expand Down Expand Up @@ -1997,7 +1997,7 @@ try {
```

```text
The frontmatter of slide 1 names "transition", which is not a directive. The directives are: title, name, level, layout, theme, author, description, template, chrome.
The frontmatter of slide 1 names "transition", which is not a directive. The directives are: title, name, level, layout, theme, author, description, template, templates-file.
```

Slidev accepts dozens of directives this library does not read, so a deck written for it will
Expand Down
10 changes: 5 additions & 5 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ quietly. The profile and the scratch script go to the temporary directory, so
| `01-kitchen-sink.md` | `01-kitchen-sink.pptx` | Every construct at once: emphasis, `code`, strikethrough, links, nested lists, an ordered list starting at 7, an aligned table with markup in its cells, a two-line quote, code, a rule, and a `::note` becoming a speaker note |
| `02-layout-roles.md` | `02-layout-roles.pptx` | Every layout role, one per slide |
| `03-themes.md` | three files | The same deck in `default`, `corporate-dark` and `minimal`, changed by nothing but the `theme:` line — so the three can be put side by side and compared. They differ in type scale, margins, rule weight and heading treatment, not only in palette |
| `04-frontmatter.md` | `04-frontmatter.pptx` | Every frontmatter key and what each one does, and a slide drawn with two templates — one the deck defines and one `templates/chrome.md` holds |
| `04-frontmatter.md` | `04-frontmatter.pptx` | Every frontmatter key and what each one does, and a slide drawn with two templates — one the deck defines and one `templates/templates.md` holds |
| `05-steps.md` | `05-steps.pptx` | `::click` steps as click animations on one slide, a `:::click` region that is a step of its own, a build-up across two columns, a `::column` written inside a region, a picture held back for its own click, and a `::note` |
| `06-tables.md` | `06-tables.pptx` | Table alignment, a bold filled header, widths from content |
| `07-images.md` | `07-images.pptx` | A picture fitted to the room left in its column, a WebP converted to PNG, an SVG drawn to PNG, and the three layouts built around one: `image-text`, `image-title` and `image-slide` |
Expand All @@ -32,7 +32,7 @@ quietly. The profile and the scratch script go to the temporary directory, so
| `13-placed-deck.md` | `13-placed-deck.pptx` | A whole business pitch built out of free shapes and nothing else — a dark cover and a dark sign-off, an agenda of numbered circles, a card grid, a hand-built pricing table with zebra rows and a right-aligned column, a four-pillar comparison, a quarterly roadmap with arrows between phases, and translucent decoration over both dark slides. The company is invented |
| `14-shadows.md` | `14-shadows.pptx` | Five shadow types on five different kinds of object — a soft shadow straight down, a hard-edged one with no blur at all, a glow with no offset, one cast down and to the right, and one thrown upward at 40% — plus a shadow on a `:::content` block and on a `::image` |
| `15-inline-styles.md` | `15-inline-styles.pptx` | A word in a style of the theme inside a box with a colour of its own, the raw form that needs no style of the theme's, an attribute laid over a named style for one property only, the seven attributes this half draws, and the three it refuses — a name the theme does not have, a label holding Markdown, and the `highlight` it cannot write. The company is invented |
| `16-templates.md` | `16-templates.pptx` | The furniture of a deck, written once: a template defined in the deck, a slide that names one, a slide that names two, a slide that names three, a template imported from `templates/chrome.md`, and a template of the deck's own of the same name as one the file holds — the one that is drawn. The company is invented |
| `16-templates.md` | `16-templates.pptx` | The furniture of a deck, written once: a template defined in the deck, a slide that names one, a slide that names two, a slide that names three, a template imported from `templates/templates.md`, and a template of the deck's own of the same name as one the file holds — the one that is drawn. The company is invented |
| `17-corporate-template.md` | `17-corporate-template.pptx` | A whole corporate template: a theme of the company's own, a brand mark in two colours — one for a light page and one for a dark one — and the furniture of a deck written once and named by every slide that wants it. Eight slides of the kinds a company deck is made of: a cover, an agenda, a headline, two columns with a chart, a quote, a table, a divider and a closing. The company is invented |

## The deck that is not anybody's business
Expand All @@ -51,7 +51,7 @@ Rebuilding that deck from another tool is what turned up both defects in [PR #11
the failure it exists to demonstrate, so `build.php` leaves it alone and says
which file and why.

`templates/chrome.md` is not a deck either: it is a file of templates, and
`templates/templates.md` is not a deck either: it is a file of templates, and
`04-frontmatter.md` and `16-templates.md` are the decks that name it. It is in a
directory of its own because every `.md` file beside the decks is one.

Expand Down Expand Up @@ -152,7 +152,7 @@ A few of these are here because the render is the only honest evidence:
of five slides, and two definitions stand between the cover and this slide in
the file: a definition is not drawn, it has no number, and it does not count.
- **`16`, the third slide.** The band across the head came out of
`templates/chrome.md`, which the deck's frontmatter names, and the deck says
`templates/templates.md`, which the deck's frontmatter names, and the deck says
nothing about where it is or how thick it is. Three templates are named on this
slide and the chrome of each of them is drawn on it.
- **`16`, the fourth slide.** The number is `accent1` at twelve points and reads
Expand All @@ -163,7 +163,7 @@ A few of these are here because the render is the only honest evidence:
- **`17`, the second slide.** One box, three words and three colours is `15`; what is
new here is the furniture around them. The wordmark is the company's own mark beside
the company's own name, the rule is a hairline under the header, and the footer is the
confidential mark and the page number. All three are templates of `corporate/chrome.md`
confidential mark and the page number. All three are templates of `corporate/templates.md`
and every slide that names them is drawn with them.
- **`17`, the seventh slide.** The divider is a dark panel with a gold number on it, and
the wordmark on it is the light one: the same named style with the colour laid over it,
Expand Down
8 changes: 4 additions & 4 deletions examples/markdown/04-frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ title: Every frontmatter key
description: One slide per key, and what each one reaches.
theme: minimal
author: markdown-office
chrome: ./templates/chrome.md
templates-file: ./templates/templates.md
---

# Every frontmatter key

Nine keys: `title`, `name`, `level`, `layout`, `theme`, `author`, `description`,
`template` and `chrome`. A block naming a tenth is a failure that names these
nine, and this slide carries the first four.
`template` and `templates-file`. A block naming a tenth is a failure that names
these nine, and this slide carries the first four.

---
name: A title that is not a heading
Expand Down Expand Up @@ -61,7 +61,7 @@ template: [wordmark, page]
---

This slide names two templates. `wordmark` is the one this deck defines below,
and `page` is the one `templates/chrome.md` — the file this deck's frontmatter
and `page` is the one `templates/templates.md` — the file this deck's frontmatter
names — holds.

A template's frontmatter names the template and nothing else, which is what
Expand Down
8 changes: 4 additions & 4 deletions examples/markdown/16-templates.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Slide templates
theme: minimal
chrome: ./templates/chrome.md
templates-file: ./templates/templates.md
description: The furniture of a deck, written once, and the slides that draw it.
template: wordmark
---
Expand All @@ -18,7 +18,7 @@ A deck gets its templates three ways:

- a **definition** in the deck, a block whose frontmatter names a template
- a **slide** that names a template, or several of them
- a **chrome file** beside the deck, named in the deck's frontmatter
- a **templates file** beside the deck, named in the deck's frontmatter

---
template: wordmark
Expand Down Expand Up @@ -60,7 +60,7 @@ template: [wordmark, band, page]

# A template out of a file

The deck's frontmatter names `templates/chrome.md`.
The deck's frontmatter names `templates/templates.md`.
That file holds a template called `band`.
The band across the head of this slide came out of that file, and this deck says nothing
about where it is or how thick it is.
Expand All @@ -77,7 +77,7 @@ template: [wordmark, page]
# The deck's own template wins

:::content{left=6.7% top=20% width=86.7% height=70% font-size=17}
`templates/chrome.md` holds a template called `page` too, and it puts a bare number at
`templates/templates.md` holds a template called `page` too, and it puts a bare number at
the foot of the slide.
This deck defines its own `page` above, and the deck's own one is the one that is drawn:
the number is in the theme's `accent1` rather than its `subtle`, at twelve points rather
Expand Down
2 changes: 1 addition & 1 deletion examples/markdown/17-corporate-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Third-quarter review
description: A corporate deck built out of the house template.
theme: ./corporate/theme.yml
chrome: ./corporate/chrome.md
templates-file: ./corporate/templates.md
layout: title
template: wordmark
---
Expand Down
8 changes: 4 additions & 4 deletions examples/markdown/corporate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ decks have, and every part of it is a file you edit.
| `theme.yml` | the design — the twelve colour slots, the faces, the type scale and the rhythm |
| `layouts.yml` | which layout each of the eight roles gets |
| `text-styles.yml` | the named text styles a deck writes words in |
| `chrome.md` | the furniture of a deck: the wordmark, the rule, the footer |
| `templates.md` | the furniture of a deck: the wordmark, the rule, the footer |
| `logo.png`, `logo-light.png` | the mark, for a light page and for a dark one |
| `make-logo.php` | draws the two marks from the theme's colours |

Expand All @@ -22,7 +22,7 @@ The deck that uses all of it is `../17-corporate-template.md`.

Three things, and each is one file.

**The name.** `chrome.md` holds the wordmark, and the name is in it twice — once in the
**The name.** `templates.md` holds the wordmark, and the name is in it twice — once in the
light template and once in the dark one. The dark one is the same named style with the
colour laid over it:

Expand All @@ -45,7 +45,7 @@ the table uses it for the one row that went down.

## The furniture

The chrome file holds four templates, and a slide names the ones it wants:
The templates file holds four templates, and a slide names the ones it wants:

```markdown
---
Expand All @@ -63,7 +63,7 @@ template: [wordmark, rule, footer]

**A dark slide and a light one are the same deck, and the furniture on them cannot be the
same furniture** — the name is ink on a light page and white on a dark one. That is what
the second wordmark is for, and it is the one thing a single chrome file cannot decide for
the second wordmark is for, and it is the one thing a single templates file cannot decide for
you.

The cover and the two dark slides name `wordmark-light` and nothing else; the light slides
Expand Down
18 changes: 5 additions & 13 deletions src/Exception/MalformedChrome.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
namespace MarkdownPresentation\Exception;

/**
* A template that is not chrome, or a chrome file that is not templates.
* A template that holds the wrong thing.
*
* A template holds chrome — the free shapes it draws — and nothing else, so a body that
* holds ordinary Markdown, a column marker, or nothing at all is a mistake in the template
* rather than in the deck that draws it.
*
* Kept apart from {@see UnknownTemplate} because the two failures have opposite fixes: a
* name nobody has needs a different name, and a body that holds the wrong thing needs a
Expand Down Expand Up @@ -58,18 +62,6 @@ public static function empty(string $name): self
));
}

/**
* A chrome file that holds something other than template definitions.
*/
public static function slide(string $file): self
{
return new self(sprintf(
'The chrome file "%s" holds a slide that is not a template definition. A chrome file holds definitions: '
. 'slides whose frontmatter names a template and nothing else.',
$file,
));
}

/**
* A mistake in a template, told with the message the mistake came with.
*
Expand Down
23 changes: 23 additions & 0 deletions src/Exception/MalformedTemplatesFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace MarkdownPresentation\Exception;

/**
* A templates file that holds something other than template definitions.
*
* A slide in a templates file is a slide nobody asked for, drawn on a deck the file was
* not written for, so it is a failure rather than something to ignore.
*/
final class MalformedTemplatesFile extends InvalidInput
{
public static function slide(string $file): self
{
return new self(sprintf(
'The templates file "%s" holds a slide that is not a template definition. A templates file holds '
. 'definitions: slides whose frontmatter names a template and nothing else.',
$file,
));
}
}
Loading
Loading