docpensieve 0.5.0-beta.2 → 0.5.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/docpensieve.js +2 -0
- package/package.json +5 -5
- package/src/commands/build.js +2 -0
- package/src/commands/dev.js +14 -3
- package/src/commands/init.js +10 -0
- package/src/commands/serve.js +5 -3
- package/src/server.js +33 -3
- package/starter/01-guide/02-first-site.md +4 -0
- package/starter/01-guide/06-deployment.md +26 -0
- package/starter/01-guide/07-migrate-to-beta.md +17 -2
- package/starter/02-components/01-card.mdx +3 -0
- package/starter/02-components/13-snippet.mdx +230 -0
- package/starter/02-components/14-hero.mdx +230 -0
- package/starter/02-components/15-calendar.mdx +130 -0
- package/starter/02-components/index.mdx +9 -3
- package/starter/02-components/snippet-example.js +32 -0
- package/starter/02-components/snippet-example.py +19 -0
- package/starter/03-reference/01-cli.md +13 -7
- package/starter/03-reference/02-configuration.md +19 -0
- package/starter/03-reference/05-api.md +266 -3
- package/starter/05-whats-new.md +47 -0
- package/types/commands/dev.d.ts +2 -1
- package/types/commands/serve.d.ts +2 -1
- package/types/server.d.ts +24 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hero
|
|
3
|
+
description: The banner at the head of a page — a name, a sentence, and the way in.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Hero
|
|
7
|
+
|
|
8
|
+
A landing page opens on three things: what this is, what it does, and where to
|
|
9
|
+
start. `Hero` is the block that holds them, so that the head of a page is a
|
|
10
|
+
component rather than a `div` and a pile of classes.
|
|
11
|
+
|
|
12
|
+
It is **not a card**: no border, no panel. What a banner is made of is space, a
|
|
13
|
+
title large enough to be the first thing read, and one way in that stands out
|
|
14
|
+
from the rest. A frame exists for the page that asks for one, and it is not
|
|
15
|
+
what you get by default.
|
|
16
|
+
|
|
17
|
+
## A banner
|
|
18
|
+
|
|
19
|
+
<Hero>
|
|
20
|
+
|
|
21
|
+
## DocPensieve
|
|
22
|
+
|
|
23
|
+
Your Markdown and MDX files become a static site. No runtime to load, one
|
|
24
|
+
version per branch.
|
|
25
|
+
|
|
26
|
+
<HeroActions>[Get started](../guide/installation/) [See the components](./)</HeroActions>
|
|
27
|
+
|
|
28
|
+
</Hero>
|
|
29
|
+
|
|
30
|
+
```mdx
|
|
31
|
+
<Hero>
|
|
32
|
+
|
|
33
|
+
# My project
|
|
34
|
+
|
|
35
|
+
What it does, in one sentence.
|
|
36
|
+
|
|
37
|
+
<HeroActions>[Get started](../guide/installation/) [Components](./)</HeroActions>
|
|
38
|
+
|
|
39
|
+
</Hero>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Everything inside is ordinary Markdown: a heading, a paragraph, a row of
|
|
43
|
+
links. The component sets the width of the sentence, the spacing, and turns
|
|
44
|
+
the links into something to press — **the first one carries the accent**,
|
|
45
|
+
because a reader should see one way in rather than three.
|
|
46
|
+
|
|
47
|
+
## Aligned to the start
|
|
48
|
+
|
|
49
|
+
`align="start"` leaves the banner where the text of the page is, which suits a
|
|
50
|
+
section that opens a chapter rather than a site.
|
|
51
|
+
|
|
52
|
+
<Hero align="start">
|
|
53
|
+
|
|
54
|
+
### A section, not a site
|
|
55
|
+
|
|
56
|
+
The same block, reading from the left.
|
|
57
|
+
|
|
58
|
+
<HeroActions>[Read on](../guide/writing-pages/)</HeroActions>
|
|
59
|
+
|
|
60
|
+
</Hero>
|
|
61
|
+
|
|
62
|
+
```mdx
|
|
63
|
+
<Hero align="start">
|
|
64
|
+
|
|
65
|
+
## A section, not a site
|
|
66
|
+
|
|
67
|
+
The same block, reading from the left.
|
|
68
|
+
|
|
69
|
+
</Hero>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Accepted values are `center`, the default, and `start`. Anything else stops the
|
|
73
|
+
build and lists the two — a banner silently ignoring its alignment would look
|
|
74
|
+
like a stylesheet that failed.
|
|
75
|
+
|
|
76
|
+
## With something to show
|
|
77
|
+
|
|
78
|
+
Put a `HeroVisual` among the children and the banner becomes two columns — the
|
|
79
|
+
words on one side, the picture on the other. Nothing to declare: having a
|
|
80
|
+
visual is what makes it a split, which is the commonest shape of a landing
|
|
81
|
+
page and the reason a project puts a screenshot there.
|
|
82
|
+
|
|
83
|
+
<Hero>
|
|
84
|
+
<HeroText>
|
|
85
|
+
|
|
86
|
+
### My project
|
|
87
|
+
|
|
88
|
+
What it does, in one sentence, with room to breathe.
|
|
89
|
+
|
|
90
|
+
<HeroActions>[Get started](../guide/installation/) [Components](./)</HeroActions>
|
|
91
|
+
|
|
92
|
+
</HeroText>
|
|
93
|
+
<HeroVisual>
|
|
94
|
+
|
|
95
|
+

|
|
96
|
+
|
|
97
|
+
</HeroVisual>
|
|
98
|
+
</Hero>
|
|
99
|
+
|
|
100
|
+
```mdx
|
|
101
|
+
<Hero>
|
|
102
|
+
<HeroText>
|
|
103
|
+
|
|
104
|
+
# My project
|
|
105
|
+
|
|
106
|
+
What it does, in one sentence, with room to breathe.
|
|
107
|
+
|
|
108
|
+
<HeroActions>[Get started](/guide/installation/) [Components](/components/)</HeroActions>
|
|
109
|
+
|
|
110
|
+
</HeroText>
|
|
111
|
+
<HeroVisual>
|
|
112
|
+
|
|
113
|
+

|
|
114
|
+
|
|
115
|
+
</HeroVisual>
|
|
116
|
+
</Hero>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`HeroText` holds the words, `HeroVisual` the picture. Below 48rem the two
|
|
120
|
+
columns become one, the picture following the words it illustrates.
|
|
121
|
+
|
|
122
|
+
## A frame, if you want one
|
|
123
|
+
|
|
124
|
+
`frame` draws the panel a banner does not have by default — a border, and a
|
|
125
|
+
wash of its tone.
|
|
126
|
+
|
|
127
|
+
<Hero frame size="small">
|
|
128
|
+
|
|
129
|
+
### Framed
|
|
130
|
+
|
|
131
|
+
For a banner that has to be told apart from the page around it.
|
|
132
|
+
|
|
133
|
+
</Hero>
|
|
134
|
+
|
|
135
|
+
```mdx
|
|
136
|
+
<Hero frame>...</Hero>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## How much room it takes
|
|
140
|
+
|
|
141
|
+
`size` decides the air around the words, not the look: `small`, `medium` —
|
|
142
|
+
the default — `large`, and `full`, which takes the height of the screen and
|
|
143
|
+
centres its content in it.
|
|
144
|
+
|
|
145
|
+
<Hero size="small">
|
|
146
|
+
|
|
147
|
+
### A small one
|
|
148
|
+
|
|
149
|
+
For a section that only needs announcing.
|
|
150
|
+
|
|
151
|
+
</Hero>
|
|
152
|
+
|
|
153
|
+
```mdx
|
|
154
|
+
<Hero size="small">...</Hero>
|
|
155
|
+
<Hero size="large">...</Hero>
|
|
156
|
+
<Hero size="full">...</Hero>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`full` measures the screen as the browser really shows it, so a phone whose
|
|
160
|
+
address bar comes and goes does not push the banner under it.
|
|
161
|
+
|
|
162
|
+
## The tone it is lit with
|
|
163
|
+
|
|
164
|
+
`tone` names a colour the theme already carries — the same tones an admonition
|
|
165
|
+
takes, because a theme defines a colour per tone, not a colour per component.
|
|
166
|
+
A project that gives `attention` its own colour gives it to both at once.
|
|
167
|
+
|
|
168
|
+
<Hero tone="tip" align="start" size="small">
|
|
169
|
+
|
|
170
|
+
### Lit by a tone
|
|
171
|
+
|
|
172
|
+
The wash behind the words, and the first way in, follow it.
|
|
173
|
+
|
|
174
|
+
<HeroActions>[Read on](../guide/writing-pages/)</HeroActions>
|
|
175
|
+
|
|
176
|
+
</Hero>
|
|
177
|
+
|
|
178
|
+
```mdx
|
|
179
|
+
<Hero tone="tip">...</Hero>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Accepted: `note` — the default, which is the accent of the theme — `info`,
|
|
183
|
+
`tip`, `attention` and `danger`. Anything else stops the build and lists them,
|
|
184
|
+
as an unknown size or alignment does: a banner silently ignoring what it was
|
|
185
|
+
asked would look like a stylesheet that failed.
|
|
186
|
+
|
|
187
|
+
## On a page of your own
|
|
188
|
+
|
|
189
|
+
A banner belongs on a page that opens something: the home page of a version, a
|
|
190
|
+
landing page for a section. The `home` layout of the frontmatter is its usual
|
|
191
|
+
companion, since it drops the menu and the table of contents:
|
|
192
|
+
|
|
193
|
+
```mdx
|
|
194
|
+
---
|
|
195
|
+
title: My project
|
|
196
|
+
layout: home
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
<Hero>
|
|
200
|
+
|
|
201
|
+
# My project
|
|
202
|
+
|
|
203
|
+
...
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Properties
|
|
207
|
+
|
|
208
|
+
| Property | Type | Effect |
|
|
209
|
+
| ----------- | -------- | ---------------------------------- |
|
|
210
|
+
| `align` | `string` | `center` (the default) or `start`. |
|
|
211
|
+
| `className` | `string` | Classes added to the banner. |
|
|
212
|
+
| `style` | `object` | Inline styles on the banner. |
|
|
213
|
+
|
|
214
|
+
Its companions, each taking `className` and `style` as well:
|
|
215
|
+
|
|
216
|
+
| Component | What it holds |
|
|
217
|
+
| ------------- | -------------------------------------------------------------------- |
|
|
218
|
+
| `HeroActions` | The row of ways in. Its children are links, as Markdown writes them. |
|
|
219
|
+
| `HeroText` | The words, in a split. Not needed in a single column. |
|
|
220
|
+
| `HeroVisual` | The picture. Its presence is what makes the banner a split. |
|
|
221
|
+
|
|
222
|
+
**One primary action and one alternative** is the shape that reads — a row of
|
|
223
|
+
five buttons is a row of none.
|
|
224
|
+
|
|
225
|
+
The classes are `dp-banner*`, after what the element is rather than after the
|
|
226
|
+
component: a page that already writes a class of its own around a title keeps
|
|
227
|
+
whatever that class did, and adopting the component stays a decision.
|
|
228
|
+
|
|
229
|
+
A row of ways in is a row of choices — [Columns](./columns/) shows how to keep
|
|
230
|
+
several blocks the same height when the banner is followed by cards.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Calendar
|
|
3
|
+
description: A month of dates and what happens on them — built at generation, navigable once the page has loaded its script.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Calendar
|
|
7
|
+
|
|
8
|
+
Dates read badly as a list. A release plan, a course schedule, the weeks of a
|
|
9
|
+
migration: what matters is where they fall, and how far apart. `Calendar`
|
|
10
|
+
draws the months, and puts each event on its day.
|
|
11
|
+
|
|
12
|
+
## Days and what is on them
|
|
13
|
+
|
|
14
|
+
<Calendar>
|
|
15
|
+
<Event date="2026-10-14" label="Release 0.5" href="../whats-new/" />
|
|
16
|
+
<Event date="2026-10-14" label="Blog post" />
|
|
17
|
+
<Event date="2026-10-28" label="Workshop" />
|
|
18
|
+
</Calendar>
|
|
19
|
+
|
|
20
|
+
```mdx
|
|
21
|
+
<Calendar>
|
|
22
|
+
<Event date="2026-10-14" label="Release 0.5" href="/whats-new/" />
|
|
23
|
+
<Event date="2026-10-14" label="Blog post" />
|
|
24
|
+
<Event date="2026-10-28" label="Workshop" />
|
|
25
|
+
</Calendar>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A day is written `2026-10-14` — four digits, two, two. Several events may fall
|
|
29
|
+
on the same day, and they are drawn in the order they are written. `href` is
|
|
30
|
+
resolved like any other link of a page: relative to the page, or from the
|
|
31
|
+
version root.
|
|
32
|
+
|
|
33
|
+
The events are written in the page. Nothing is read from the frontmatter of
|
|
34
|
+
other pages: a calendar says what its author put in it, and says it where it
|
|
35
|
+
is read.
|
|
36
|
+
|
|
37
|
+
## Several months
|
|
38
|
+
|
|
39
|
+
Every month between the first event and the last is drawn — including the ones
|
|
40
|
+
with nothing in them, because a gap is something a reader should see.
|
|
41
|
+
|
|
42
|
+
<Calendar>
|
|
43
|
+
<Event date="2026-11-18" label="Beta" />
|
|
44
|
+
<Event date="2027-01-06" label="Release" />
|
|
45
|
+
</Calendar>
|
|
46
|
+
|
|
47
|
+
```mdx
|
|
48
|
+
<Calendar>
|
|
49
|
+
<Event date="2026-11-18" label="Beta" />
|
|
50
|
+
<Event date="2027-01-06" label="Release" />
|
|
51
|
+
</Calendar>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Without JavaScript, the months are stacked one after the other and the whole
|
|
55
|
+
calendar is readable. With it, they fold into one, two arrows move between
|
|
56
|
+
them, and today is outlined. The arrows are **written hidden** and revealed by
|
|
57
|
+
the script, so they never appear without the code that makes them work.
|
|
58
|
+
|
|
59
|
+
That script is the client file of the version: a couple of kilobytes, loaded
|
|
60
|
+
only by the pages that hold a calendar, and shared with any other behaviour
|
|
61
|
+
the version uses. See [copyCode](../reference/configuration/) for what that
|
|
62
|
+
file is.
|
|
63
|
+
|
|
64
|
+
## The small model
|
|
65
|
+
|
|
66
|
+
`compact` draws the grid small and writes the events out under it, at every
|
|
67
|
+
width — beside a paragraph, or in a column of its own.
|
|
68
|
+
|
|
69
|
+
**A narrow screen takes this model whatever the page asked for.** Seven columns
|
|
70
|
+
of full cells on a phone give each day a few millimetres, and a label written
|
|
71
|
+
in one is a word per line. Both forms are in the page and the stylesheet shows
|
|
72
|
+
one, as the menu of the header is written twice: no script decides it, and
|
|
73
|
+
nothing is read twice by a screen reader.
|
|
74
|
+
|
|
75
|
+
<Calendar compact>
|
|
76
|
+
<Event date="2026-10-14" label="Release 0.5" href="../whats-new/" />
|
|
77
|
+
<Event date="2026-10-14" label="Blog post" />
|
|
78
|
+
<Event date="2026-10-28" label="Workshop" />
|
|
79
|
+
</Calendar>
|
|
80
|
+
|
|
81
|
+
```mdx
|
|
82
|
+
<Calendar compact>
|
|
83
|
+
<Event date="2026-10-14" label="Release 0.5" />
|
|
84
|
+
<Event date="2026-10-28" label="Workshop" />
|
|
85
|
+
</Calendar>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A day that holds something carries a dot, or the number of things it holds —
|
|
89
|
+
a day with three should say three rather than look like a day with one. The
|
|
90
|
+
list underneath is what says what they are: **nothing is only a colour**,
|
|
91
|
+
which no screen reader reads and no colour-blind reader sees.
|
|
92
|
+
|
|
93
|
+
## The language of the page
|
|
94
|
+
|
|
95
|
+
Month and weekday names come from the language of the page, and so does the
|
|
96
|
+
name a screen reader announces. A French page says `octobre`, an English one
|
|
97
|
+
`October` — nothing to declare.
|
|
98
|
+
|
|
99
|
+
## What it refuses
|
|
100
|
+
|
|
101
|
+
| Written | What happens |
|
|
102
|
+
| ----------------------------- | ------------------------------------------------------------------ |
|
|
103
|
+
| a calendar with no event | The build stops: an empty calendar shows nothing. |
|
|
104
|
+
| `2026-10` or `14/10/2026` | The build stops, saying how a day is written. |
|
|
105
|
+
| `2026-09-31` | Refused: September has thirty days, so this is a typo, not a date. |
|
|
106
|
+
| an event without a label | The build stops, naming its day. |
|
|
107
|
+
| an `Event` outside a calendar | The build stops: nothing would know which month to draw it in. |
|
|
108
|
+
| anything else inside | The build stops: a calendar holds events. |
|
|
109
|
+
|
|
110
|
+
## Properties
|
|
111
|
+
|
|
112
|
+
`Calendar`:
|
|
113
|
+
|
|
114
|
+
| Property | Type | Effect |
|
|
115
|
+
| ----------- | --------- | ---------------------------------------------------------------- |
|
|
116
|
+
| `label` | `string` | Name announced to a screen reader. Default: `Calendar`. |
|
|
117
|
+
| `compact` | `boolean` | The small model at every width. A narrow screen takes it anyway. |
|
|
118
|
+
| `className` | `string` | Classes added to the calendar. |
|
|
119
|
+
| `style` | `object` | Inline styles on the calendar. |
|
|
120
|
+
|
|
121
|
+
`Event`:
|
|
122
|
+
|
|
123
|
+
| Property | Type | Effect |
|
|
124
|
+
| -------- | -------- | ---------------------------------------------- |
|
|
125
|
+
| `date` | `string` | The day, `2026-10-14`. Required. |
|
|
126
|
+
| `label` | `string` | What happens that day. Required. |
|
|
127
|
+
| `href` | `string` | Where the event leads. Resolved like any link. |
|
|
128
|
+
|
|
129
|
+
Writing a block twice and showing one is how this site handles a narrow screen
|
|
130
|
+
throughout — [Columns](./columns/) makes the same choice.
|
|
@@ -67,9 +67,15 @@ changes the examples too.
|
|
|
67
67
|
|
|
68
68
|
## Without JavaScript
|
|
69
69
|
|
|
70
|
-
No component loads a script
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
No component loads a script but one: `Calendar`, whose arrows between months
|
|
71
|
+
come from the client file of the version — and only on the pages that hold a
|
|
72
|
+
calendar. Whatever else needs interaction goes through native elements or
|
|
73
|
+
through CSS: `details` for expanding, a link for moving, `animation-timeline`
|
|
74
|
+
for appearing on scroll.
|
|
75
|
+
|
|
76
|
+
The site itself can add a behaviour to a page — `copyCode` puts a copy button
|
|
77
|
+
on each block of code — but that is a field you turn on, it lands in one file
|
|
78
|
+
shared by the version, and only pages that use it load it.
|
|
73
79
|
|
|
74
80
|
When the browser does not know one of these properties yet, the component stays
|
|
75
81
|
usable in its simplest state — visible, full, expanded. None of them waits for
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A file the Snippet page reads, rather than quoting.
|
|
3
|
+
*
|
|
4
|
+
* It is installed along with the documentation, so the examples on that page
|
|
5
|
+
* work in your project exactly as they do on this site. Change a line here
|
|
6
|
+
* and the page changes with it — which is the whole point of the component.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Words a slug drops, so that titles do not all begin alike. */
|
|
10
|
+
const SKIPPED = new Set(['a', 'an', 'the', 'of', 'to']);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Turns the title of a page into the last segment of its address.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} title Title, as the frontmatter gives it.
|
|
16
|
+
* @returns {string} A slug: lower case, accents dropped, words joined by a dash.
|
|
17
|
+
*/
|
|
18
|
+
export function slugOf(title) {
|
|
19
|
+
// #region guard
|
|
20
|
+
if (typeof title !== 'string' || title.trim() === '') {
|
|
21
|
+
throw new TypeError('slugOf needs a title');
|
|
22
|
+
}
|
|
23
|
+
// #endregion
|
|
24
|
+
|
|
25
|
+
return title
|
|
26
|
+
.normalize('NFD')
|
|
27
|
+
.replace(/\p{M}/gu, '')
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.split(/[^a-z0-9]+/)
|
|
30
|
+
.filter((word) => word && !SKIPPED.has(word))
|
|
31
|
+
.join('-');
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""A second file, in another language, so the page can show what changes.
|
|
2
|
+
|
|
3
|
+
Nothing here is read by the tool: it is only the source of an example. The
|
|
4
|
+
extension is what tells the block which language it holds, and therefore
|
|
5
|
+
which mark and which colour it carries.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
SKIPPED = {"a", "an", "the", "of", "to"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def slug_of(title: str) -> str:
|
|
12
|
+
"""Turn the title of a page into the last segment of its address."""
|
|
13
|
+
# #region guard
|
|
14
|
+
if not isinstance(title, str) or not title.strip():
|
|
15
|
+
raise TypeError("slug_of needs a title")
|
|
16
|
+
# #endregion
|
|
17
|
+
|
|
18
|
+
words = "".join(c if c.isalnum() else " " for c in title.lower()).split()
|
|
19
|
+
return "-".join(w for w in words if w not in SKIPPED)
|
|
@@ -113,9 +113,14 @@ Development server, which rebuilds on every save.
|
|
|
113
113
|
npx docpensieve dev
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
| Option | Effect
|
|
117
|
-
| --------------------- |
|
|
118
|
-
| `-p, --port <number>` | Listening port. Default: `3000`
|
|
116
|
+
| Option | Effect |
|
|
117
|
+
| --------------------- | ------------------------------------------------------------- |
|
|
118
|
+
| `-p, --port <number>` | Listening port. Default: `3000` |
|
|
119
|
+
| `--host <address>` | Address to listen on. Default: `127.0.0.1`, this machine only |
|
|
120
|
+
|
|
121
|
+
`0.0.0.0` opens the server to the network — to look at the site from a phone on
|
|
122
|
+
the same wifi. Anyone on that network can then read it, drafts included, and
|
|
123
|
+
the command says so when it starts.
|
|
119
124
|
|
|
120
125
|
## `serve`
|
|
121
126
|
|
|
@@ -125,10 +130,11 @@ Serves the output folder statically, without rebuilding anything.
|
|
|
125
130
|
npx docpensieve serve
|
|
126
131
|
```
|
|
127
132
|
|
|
128
|
-
| Option | Effect
|
|
129
|
-
| --------------------- |
|
|
130
|
-
| `-p, --port <number>` | Listening port. Default: `4000`
|
|
131
|
-
|
|
|
133
|
+
| Option | Effect |
|
|
134
|
+
| --------------------- | ------------------------------------------------------------- |
|
|
135
|
+
| `-p, --port <number>` | Listening port. Default: `4000` |
|
|
136
|
+
| `--host <address>` | Address to listen on. Default: `127.0.0.1`, this machine only |
|
|
137
|
+
| `-d, --dir <dir>` | Folder to serve |
|
|
132
138
|
|
|
133
139
|
It is the command that faithfully reproduces what a host will do: to check what
|
|
134
140
|
will be published, chain `build` then `serve`.
|
|
@@ -65,6 +65,8 @@ can change.
|
|
|
65
65
|
| `stickyHeader` | `true` | The header stays at the top of the screen; `false` lets it scroll away |
|
|
66
66
|
| `globalComponents` | `true` | Shipped components available without an import |
|
|
67
67
|
| `scrollToTop` | `true` | Back-to-top button on every page |
|
|
68
|
+
| `copyCode` | `false` | A button copying each block of code — the one field that makes a content page load a script |
|
|
69
|
+
| `snippetIcons` | `''` | Icon collection a code block takes the mark of its language from, `'simple-icons'` |
|
|
68
70
|
| `jsonld` | `{ enabled: true }` | Structured data |
|
|
69
71
|
| `lang` | `'en'` | Language of the site: `<html lang>`, and the wording of the shell |
|
|
70
72
|
| `ui` | `{}` | Wording of the shell, by language — corrects a word, or adds a language |
|
|
@@ -135,6 +137,23 @@ The search page is kept out of search engines (`noindex`) and out of the
|
|
|
135
137
|
sitemap. A page of your own at `/search/` would take its place: the build
|
|
136
138
|
refuses it, and `search: false` frees the address.
|
|
137
139
|
|
|
140
|
+
## `copyCode`
|
|
141
|
+
|
|
142
|
+
`copyCode: true` puts a button on every block of code, which copies it.
|
|
143
|
+
|
|
144
|
+
It is off by default, because it is the one field that makes an ordinary page
|
|
145
|
+
load a script. Turned on, the behaviour is written **once per version**, in
|
|
146
|
+
`assets/client.js` beside the stylesheet, and shared by every page and every
|
|
147
|
+
language — a reader who has it in cache pays for it once. Only the pages that
|
|
148
|
+
hold a block of code load it; the others go on loading nothing.
|
|
149
|
+
|
|
150
|
+
About two kilobytes, compressed. No framework, no hydration: the code is plain
|
|
151
|
+
DOM, and the button is drawn by the script itself. Without JavaScript the
|
|
152
|
+
block is exactly what it was, text you can select — nothing is missing but
|
|
153
|
+
the button.
|
|
154
|
+
|
|
155
|
+
The label follows the language of the page, in English and in French.
|
|
156
|
+
|
|
138
157
|
## `versions`
|
|
139
158
|
|
|
140
159
|
```js
|