docpensieve 0.1.0 → 0.1.2
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/README.md +5 -2
- package/bin/docpensieve.js +1 -0
- package/package.json +8 -6
- package/src/commands/dev.js +1 -1
- package/src/commands/init.js +214 -39
- package/starter/01-guide/01-installation.md +79 -0
- package/starter/01-guide/02-first-site.md +97 -0
- package/starter/01-guide/03-writing-pages.md +138 -0
- package/starter/01-guide/04-versions.md +179 -0
- package/starter/01-guide/05-themes.md +116 -0
- package/starter/01-guide/06-deployment.md +124 -0
- package/starter/01-guide/index.md +38 -0
- package/starter/02-components/01-card.mdx +195 -0
- package/starter/02-components/02-columns.mdx +193 -0
- package/starter/02-components/03-time-timer.mdx +120 -0
- package/starter/02-components/04-tooltip.mdx +100 -0
- package/starter/02-components/05-tree.mdx +163 -0
- package/starter/02-components/06-scroll-to-top.mdx +103 -0
- package/starter/02-components/07-skill.mdx +214 -0
- package/starter/02-components/08-logo-icon.mdx +122 -0
- package/starter/02-components/icons/banner.svg +15 -0
- package/starter/02-components/icons/book.svg +4 -0
- package/starter/02-components/icons/lightning.svg +3 -0
- package/starter/02-components/icons/shield.svg +4 -0
- package/starter/02-components/icons/star.svg +3 -0
- package/starter/02-components/index.md +41 -0
- package/starter/03-reference/01-cli.md +134 -0
- package/starter/03-reference/02-configuration.md +132 -0
- package/starter/03-reference/03-frontmatter.md +110 -0
- package/starter/03-reference/04-theme.md +149 -0
- package/starter/03-reference/index.md +32 -0
- package/starter/04-architecture.md +106 -0
- package/starter/icons/blocks.svg +6 -0
- package/starter/icons/book.svg +4 -0
- package/starter/icons/branch.svg +6 -0
- package/starter/icons/compass.svg +4 -0
- package/starter/icons/lightning.svg +3 -0
- package/starter/icons/list.svg +4 -0
- package/starter/icons/shield.svg +4 -0
- package/starter/icons/star.svg +3 -0
- package/starter/index.mdx +244 -0
- package/types/commands/init.d.ts +7 -4
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Commands
|
|
3
|
+
description: init, build, check, dev and serve, with their arguments and options.
|
|
4
|
+
tags: [reference, cli]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx docpensieve <command> [arguments] [options]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## `init`
|
|
18
|
+
|
|
19
|
+
Sets up a documentation project.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx docpensieve init [dir]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Option | Effect |
|
|
26
|
+
| -------------------------- | --------------------------------------- |
|
|
27
|
+
| `[dir]` | Target folder. Default: `.` |
|
|
28
|
+
| `-n, --name <name>` | Project name |
|
|
29
|
+
| `-t, --theme <framework>` | `tailwind` or `custom` |
|
|
30
|
+
| `-u, --site-url <url>` | Public URL of the site |
|
|
31
|
+
| `--version-name <version>` | First version, `1.0` for instance |
|
|
32
|
+
| `-y, --yes` | Accepts the defaults without a dialogue |
|
|
33
|
+
| `-f, --force` | Overwrites an existing configuration |
|
|
34
|
+
| `--minimal` | Leaves DocPensieve's documentation out |
|
|
35
|
+
|
|
36
|
+
Without `--force`, the command refuses to overwrite an existing configuration.
|
|
37
|
+
|
|
38
|
+
Unless `--minimal` is given, the command installs DocPensieve's documentation
|
|
39
|
+
in the new site, in `docs/<version>/99-docpensieve/`: a **DocPensieve** section
|
|
40
|
+
at the end of the menu, matching the installed version. Delete that folder when
|
|
41
|
+
you no longer need it.
|
|
42
|
+
|
|
43
|
+
## `build`
|
|
44
|
+
|
|
45
|
+
Generates the site.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx docpensieve build [version]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Option | Effect |
|
|
52
|
+
| ----------------- | ---------------------------------------------------- |
|
|
53
|
+
| `[version]` | Version slug. When omitted, every version is built |
|
|
54
|
+
| `-o, --out <dir>` | Output folder. Default: the one in the configuration |
|
|
55
|
+
|
|
56
|
+
With a slug, only that version is written, in `versions/<slug>/`. That form
|
|
57
|
+
writes **neither the manifest nor the root redirect**: after adding or
|
|
58
|
+
removing a version, run a full build.
|
|
59
|
+
|
|
60
|
+
## `check`
|
|
61
|
+
|
|
62
|
+
Reads the produced site back: internal links and markup.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx docpensieve check
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Option | Effect |
|
|
69
|
+
| ----------------- | ------------------------------------------------------ |
|
|
70
|
+
| `-d, --dir <dir>` | Folder to check. Default: the one in the configuration |
|
|
71
|
+
|
|
72
|
+
### Links
|
|
73
|
+
|
|
74
|
+
- a target that **ignores the deployment prefix** — the file exists, but the
|
|
75
|
+
link will lead nowhere once online. It is the symptom of a URL that escaped
|
|
76
|
+
resolution;
|
|
77
|
+
- a target that **matches no produced file**.
|
|
78
|
+
|
|
79
|
+
External targets, anchors and `mailto:` are left alone. A target that comes
|
|
80
|
+
back several times in a page is reported only once.
|
|
81
|
+
|
|
82
|
+
### Markup
|
|
83
|
+
|
|
84
|
+
- a **paragraph nested** in another one;
|
|
85
|
+
- a **paragraph inside an element that only accepts text**, a `span` for
|
|
86
|
+
instance;
|
|
87
|
+
- a **block element inside a paragraph**, a heading for instance.
|
|
88
|
+
|
|
89
|
+
They usually come from the same source, described in
|
|
90
|
+
[Writing pages](../guide/writing-pages/): the content of a JSX tag left alone on
|
|
91
|
+
its line becomes a paragraph. The browser then silently undoes the nesting, the
|
|
92
|
+
wrapper disappears, and the intended layout with it.
|
|
93
|
+
|
|
94
|
+
If anything is left to fix, the command exits with code 1: it therefore fails a
|
|
95
|
+
continuous integration run without any particular setting.
|
|
96
|
+
|
|
97
|
+
## `dev`
|
|
98
|
+
|
|
99
|
+
Development server, which rebuilds on every save.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx docpensieve dev
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Option | Effect |
|
|
106
|
+
| --------------------- | ------------------------------- |
|
|
107
|
+
| `-p, --port <number>` | Listening port. Default: `3000` |
|
|
108
|
+
|
|
109
|
+
## `serve`
|
|
110
|
+
|
|
111
|
+
Serves the output folder statically, without rebuilding anything.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx docpensieve serve
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
| Option | Effect |
|
|
118
|
+
| --------------------- | ------------------------------- |
|
|
119
|
+
| `-p, --port <number>` | Listening port. Default: `4000` |
|
|
120
|
+
| `-d, --dir <dir>` | Folder to serve |
|
|
121
|
+
|
|
122
|
+
It is the command that faithfully reproduces what a host will do: to check what
|
|
123
|
+
will be published, chain `build` then `serve`.
|
|
124
|
+
|
|
125
|
+
## Exit codes
|
|
126
|
+
|
|
127
|
+
| Code | Meaning |
|
|
128
|
+
| ---- | -------------------------------------------------------------- |
|
|
129
|
+
| `0` | Everything went well |
|
|
130
|
+
| `1` | Expected error — message and hint shown, without a stack trace |
|
|
131
|
+
| `2` | Feature not written yet |
|
|
132
|
+
|
|
133
|
+
An unexpected error comes out with its full stack trace: it is a defect of the
|
|
134
|
+
generator, not of the documentation it is given.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Configuration
|
|
3
|
+
description: Every field of docpensieve.config.mjs, its default value and its effect.
|
|
4
|
+
tags: [reference, configuration]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Configuration
|
|
12
|
+
|
|
13
|
+
The `docpensieve.config.mjs` file, at the root of the project.
|
|
14
|
+
|
|
15
|
+
It is an ES module — hence `.mjs`, which Node reads as one whatever the
|
|
16
|
+
project's `package.json` says. `docpensieve.config.js` works too, in a project
|
|
17
|
+
whose `package.json` declares `"type": "module"`; with both files present, the
|
|
18
|
+
build stops rather than pick one.
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
/** @type {import('@docpensieve/core').DocPensieveConfig} */
|
|
22
|
+
export default {
|
|
23
|
+
projectName: 'My documentation',
|
|
24
|
+
siteUrl: 'https://example.com/my-project',
|
|
25
|
+
|
|
26
|
+
versions: [{ slug: 'v1.0', name: '1.0', folder: 'docs/v1.0', current: true }],
|
|
27
|
+
|
|
28
|
+
outDir: 'dist',
|
|
29
|
+
|
|
30
|
+
theme: {
|
|
31
|
+
framework: 'tailwind',
|
|
32
|
+
darkMode: 'class',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
sidebar: 'auto',
|
|
36
|
+
globalComponents: true,
|
|
37
|
+
jsonld: { enabled: true },
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `@type` comment gives autocompletion and type checking in the editor
|
|
42
|
+
without importing anything: the file stays readable even where DocPensieve
|
|
43
|
+
only runs through `npx`. In a project that installs it as a dependency,
|
|
44
|
+
`defineConfig` from `@docpensieve/core` does the same.
|
|
45
|
+
|
|
46
|
+
`docpensieve init` writes this file with **every field** in it — set to its
|
|
47
|
+
default, or commented out with an example — so that it also tells you what you
|
|
48
|
+
can change.
|
|
49
|
+
|
|
50
|
+
## The fields
|
|
51
|
+
|
|
52
|
+
| Field | Default | Effect |
|
|
53
|
+
| ------------------ | ------------------- | --------------------------------------------------------------------------- |
|
|
54
|
+
| `projectName` | `'Documentation'` | Name shown in the header and in the JSON-LD |
|
|
55
|
+
| `siteUrl` | `''` | Public URL. Used for the `canonical` and the JSON-LD |
|
|
56
|
+
| `baseUrl` | `'/'` | Deployment prefix. Derived from `siteUrl` when omitted |
|
|
57
|
+
| `outDir` | `'dist'` | Output folder, relative to the root |
|
|
58
|
+
| `versions` | `[]` | At least one entry |
|
|
59
|
+
| `theme` | see below | Styling |
|
|
60
|
+
| `sidebar` | `'auto'` | `'auto'`: the sidebar follows the file tree. The only value written so far |
|
|
61
|
+
| `globalComponents` | `true` | Shipped components available without an import |
|
|
62
|
+
| `scrollToTop` | `true` | Back-to-top button on every page |
|
|
63
|
+
| `jsonld` | `{ enabled: true }` | Structured data |
|
|
64
|
+
| `lang` | `'en'` | Language of the document, in `<html lang>`. The shell's labels stay English |
|
|
65
|
+
|
|
66
|
+
## `versions`
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
versions: [
|
|
70
|
+
{ slug: 'v2.0', name: '2.0', folder: 'docs/v2.0', current: true },
|
|
71
|
+
{ slug: 'v1.0', name: '1.0', folder: 'docs/v1.0', archived: true },
|
|
72
|
+
],
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| Field | Role |
|
|
76
|
+
| ------------ | ---------------------------------------------------------------- |
|
|
77
|
+
| `slug` | URL and branch identifier |
|
|
78
|
+
| `name` | Label shown in the switcher |
|
|
79
|
+
| `folder` | Source folder, relative to the root |
|
|
80
|
+
| `current` | Version served by default. At most one |
|
|
81
|
+
| `archived` | Version kept but no longer maintained. Banner, but stays indexed |
|
|
82
|
+
| `prerelease` | Version in preparation. Banner **and** `noindex` |
|
|
83
|
+
|
|
84
|
+
## `theme`
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
theme: {
|
|
88
|
+
framework: 'tailwind',
|
|
89
|
+
darkMode: 'class',
|
|
90
|
+
tokens: { '--dp-accent': 'oklch(55% 0.2 250)' },
|
|
91
|
+
css: '.dp-article h2 { letter-spacing: -0.01em; }',
|
|
92
|
+
source: '@import "tailwindcss";',
|
|
93
|
+
},
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
| Field | Effect |
|
|
97
|
+
| ----------- | ----------------------------------------- |
|
|
98
|
+
| `framework` | `'tailwind'` or `'custom'` |
|
|
99
|
+
| `darkMode` | Dark theme strategy |
|
|
100
|
+
| `tokens` | Redefined `--dp-*` tokens |
|
|
101
|
+
| `css` | CSS appended to the produced stylesheet |
|
|
102
|
+
| `source` | Stylesheet handed to the utility compiler |
|
|
103
|
+
|
|
104
|
+
The available tokens are listed in [Themes](../guide/themes/).
|
|
105
|
+
|
|
106
|
+
## `baseUrl`, and why you rarely write it
|
|
107
|
+
|
|
108
|
+
A `siteUrl` with a sub-path already gives it: `https://example.com/my-project`
|
|
109
|
+
produces `baseUrl: '/my-project/'`. Writing it is only useful to depart from
|
|
110
|
+
it.
|
|
111
|
+
|
|
112
|
+
The prefix is normalised with both its slashes. It is what prefixes every
|
|
113
|
+
internal link: if it is wrong, every link is.
|
|
114
|
+
|
|
115
|
+
## What is refused
|
|
116
|
+
|
|
117
|
+
| Case | Message |
|
|
118
|
+
| ---------------------------------- | --------------------------------- |
|
|
119
|
+
| The configuration is not an object | An example of the expected export |
|
|
120
|
+
| No version declared | An example of a complete entry |
|
|
121
|
+
| Two versions with the same slug | The offending slug |
|
|
122
|
+
| Several `current` versions | The list of those found |
|
|
123
|
+
| Unknown `framework` | The accepted values |
|
|
124
|
+
| Requested slug not found | The available slugs |
|
|
125
|
+
|
|
126
|
+
Each one stops the build with a message and a hint, without a stack trace.
|
|
127
|
+
|
|
128
|
+
## What is filled in automatically
|
|
129
|
+
|
|
130
|
+
If **no** version carries `current`, the first in the list becomes current. A
|
|
131
|
+
single-version configuration therefore has nothing to specify — this field only
|
|
132
|
+
starts to matter from the second version on.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Frontmatter
|
|
3
|
+
description: The fields recognised at the top of a page, and what they produce.
|
|
4
|
+
tags: [reference, frontmatter]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
faq:
|
|
10
|
+
- question: Is the frontmatter mandatory?
|
|
11
|
+
answer: No. Without a title, the project name stands in; without a date, no date is published.
|
|
12
|
+
- question: How do I keep a page offline?
|
|
13
|
+
answer: 'Set draft: true in its frontmatter. It stays in the repository, absent from the output.'
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Frontmatter
|
|
17
|
+
|
|
18
|
+
A YAML block at the top of the file, between two lines of three dashes.
|
|
19
|
+
Everything in it is optional.
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
---
|
|
23
|
+
title: Installation
|
|
24
|
+
description: What you need, and how to set up a project.
|
|
25
|
+
date: 2026-09-09
|
|
26
|
+
modified: 2026-09-14
|
|
27
|
+
authors: [Valentin Chevoleau]
|
|
28
|
+
tags: [guide, installation]
|
|
29
|
+
preview: ./screenshot.png
|
|
30
|
+
draft: false
|
|
31
|
+
layout: doc
|
|
32
|
+
|
|
33
|
+
jsonld:
|
|
34
|
+
type: TechArticle
|
|
35
|
+
breadcrumbs: true
|
|
36
|
+
---
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## The fields
|
|
40
|
+
|
|
41
|
+
| Field | Effect |
|
|
42
|
+
| ------------- | --------------------------------------------------------- |
|
|
43
|
+
| `title` | `<title>` tag, menu entry, breadcrumb, JSON-LD `headline` |
|
|
44
|
+
| `description` | `description` metadata and JSON-LD `description` |
|
|
45
|
+
| `date` | Publication date |
|
|
46
|
+
| `modified` | Last modification date. Default: the publication date |
|
|
47
|
+
| `authors` | List of authors |
|
|
48
|
+
| `tags` | Keywords, carried over as `keywords` |
|
|
49
|
+
| `preview` | Image of the page. The path is resolved like a link |
|
|
50
|
+
| `draft` | `true` keeps the page out of the output |
|
|
51
|
+
| `layout` | `doc` (default) or `home` |
|
|
52
|
+
| `jsonld` | Structured data settings |
|
|
53
|
+
|
|
54
|
+
## `layout`
|
|
55
|
+
|
|
56
|
+
`doc` is the documentation layout: menu on the left, table of contents on the
|
|
57
|
+
right, content held to reading width.
|
|
58
|
+
|
|
59
|
+
`home` removes all three. It is what a home page expects, where columns and
|
|
60
|
+
cards take the whole surface.
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
layout: home
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
An unknown value stops the build. A typo would otherwise render the page in a
|
|
67
|
+
layout other than the intended one, without a word.
|
|
68
|
+
|
|
69
|
+
## `jsonld`
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
jsonld:
|
|
73
|
+
type: TechArticle
|
|
74
|
+
breadcrumbs: true
|
|
75
|
+
faq:
|
|
76
|
+
- question: Do I need a frontmatter?
|
|
77
|
+
answer: No, everything in it is optional.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Field | Effect |
|
|
81
|
+
| ------------- | --------------------------------------------- |
|
|
82
|
+
| `type` | `Article`, `TechArticle` or `BlogPosting` |
|
|
83
|
+
| `breadcrumbs` | `false` removes the breadcrumb |
|
|
84
|
+
| `faq` | Questions and answers, published as `FAQPage` |
|
|
85
|
+
|
|
86
|
+
Every `faq` entry must carry `question` **and** `answer`: if one of them is
|
|
87
|
+
missing, the build stops and says so.
|
|
88
|
+
|
|
89
|
+
The questions must **also appear in the text of the page**. Search engines
|
|
90
|
+
reject markup that describes invisible content: a FAQ present only in the
|
|
91
|
+
frontmatter exposes the page to losing its structured data.
|
|
92
|
+
|
|
93
|
+
A `type` outside the list is refused the same way. This very page carries a
|
|
94
|
+
`faq`: its JSON-LD contains the block.
|
|
95
|
+
|
|
96
|
+
## What does not need to be written
|
|
97
|
+
|
|
98
|
+
The URL, the place in the menu, the breadcrumb and the `canonical` link are
|
|
99
|
+
derived from the file path and the configuration. Nothing to repeat in the
|
|
100
|
+
frontmatter, and nothing to keep up to date when a file is moved.
|
|
101
|
+
|
|
102
|
+
## Frequently asked questions
|
|
103
|
+
|
|
104
|
+
### Is the frontmatter mandatory?
|
|
105
|
+
|
|
106
|
+
No. Without a title, the project name stands in; without a date, no date is published.
|
|
107
|
+
|
|
108
|
+
### How do I keep a page offline?
|
|
109
|
+
|
|
110
|
+
Set `draft: true` in its frontmatter. It stays in the repository, absent from the output.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Theme
|
|
3
|
+
description: Slots, tokens and styling options, one by one.
|
|
4
|
+
tags: [reference, theme]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Theme
|
|
12
|
+
|
|
13
|
+
To learn how to use it, see [Themes](../guide/themes/). This page lists what
|
|
14
|
+
exists.
|
|
15
|
+
|
|
16
|
+
## The options
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
theme: {
|
|
20
|
+
framework: 'tailwind',
|
|
21
|
+
darkMode: 'class',
|
|
22
|
+
tokens: { '--dp-accent': 'oklch(55% 0.2 250)' },
|
|
23
|
+
css: '.dp-article h2 { letter-spacing: -0.01em; }',
|
|
24
|
+
source: '@import "tailwindcss";',
|
|
25
|
+
},
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Field | Default | Effect |
|
|
29
|
+
| ----------- | ------------------------ | ----------------------------------------------------- |
|
|
30
|
+
| `framework` | `'tailwind'` | `'tailwind'` or `'custom'` |
|
|
31
|
+
| `darkMode` | `'class'` | Dark theme strategy |
|
|
32
|
+
| `tokens` | — | Redefined `--dp-*` tokens, merged with the provider's |
|
|
33
|
+
| `css` | `''` | CSS appended to the produced stylesheet |
|
|
34
|
+
| `source` | `@import "tailwindcss";` | Stylesheet handed to the utility compiler |
|
|
35
|
+
|
|
36
|
+
`source` only concerns the `tailwind` provider: it is the entry stylesheet it
|
|
37
|
+
compiles. Replacing it lets you add directives — a `@theme` block, for
|
|
38
|
+
instance — without leaving the mechanism. `@plugin` directives are not
|
|
39
|
+
supported yet and stop the build.
|
|
40
|
+
|
|
41
|
+
## The tokens
|
|
42
|
+
|
|
43
|
+
Fifteen tokens, which both providers define and the components read. A
|
|
44
|
+
redefined token propagates everywhere, without any component having to know.
|
|
45
|
+
|
|
46
|
+
| Token | Role |
|
|
47
|
+
| -------------------- | --------------------------------------------------- |
|
|
48
|
+
| `--dp-bg` | Page background |
|
|
49
|
+
| `--dp-bg-soft` | Background of recessed areas — gauge tracks, hovers |
|
|
50
|
+
| `--dp-text` | Body text |
|
|
51
|
+
| `--dp-text-soft` | Secondary text — captions, card footers |
|
|
52
|
+
| `--dp-border` | Visible borders |
|
|
53
|
+
| `--dp-rule` | Discreet rules — tree separators |
|
|
54
|
+
| `--dp-accent` | Accent colour — links, fills |
|
|
55
|
+
| `--dp-accent-soft` | Accent background — banners |
|
|
56
|
+
| `--dp-shadow` | Colour of drop shadows |
|
|
57
|
+
| `--dp-radius` | Corner rounding |
|
|
58
|
+
| `--dp-font` | Font family of the text |
|
|
59
|
+
| `--dp-font-mono` | Monospaced family — code, trees |
|
|
60
|
+
| `--dp-content-width` | Reading width. `none` by default |
|
|
61
|
+
| `--dp-sidebar-width` | Menu column |
|
|
62
|
+
| `--dp-toc-width` | Table of contents column |
|
|
63
|
+
|
|
64
|
+
Some components add their own, documented on their page: `--dp-skill-size` for
|
|
65
|
+
a circle gauge, `--dp-skill-color` for the tint of a gauge,
|
|
66
|
+
`--dp-logo-icon-size` for an icon.
|
|
67
|
+
|
|
68
|
+
## The slots
|
|
69
|
+
|
|
70
|
+
The templates write no class. They ask for the class of each slot, and the
|
|
71
|
+
theme answers. A provider only redefines what it changes; everything else keeps
|
|
72
|
+
the `dp-*` class below.
|
|
73
|
+
|
|
74
|
+
| Slot | Default class | Where |
|
|
75
|
+
| --------------- | ------------------------- | ----------------------------------------------- |
|
|
76
|
+
| `skip` | `dp-skip` | Skip link to the content |
|
|
77
|
+
| `header` | `dp-header` | Site header |
|
|
78
|
+
| `brand` | `dp-brand` | Project name, in the header |
|
|
79
|
+
| `versions` | `dp-versions` | Version switcher |
|
|
80
|
+
| `versionsList` | `dp-versions-list` | Open list of the switcher |
|
|
81
|
+
| `shell` | `dp-shell` | Menu / content / table of contents grid |
|
|
82
|
+
| `shellWide` | `dp-shell dp-shell--wide` | The same, without menu or table of contents |
|
|
83
|
+
| `sidebar` | `dp-sidebar` | Menu column |
|
|
84
|
+
| `nav` | `dp-nav` | Navigation list |
|
|
85
|
+
| `navItem` | `dp-nav-item` | Navigation entry |
|
|
86
|
+
| `navItemParent` | `dp-nav-item--parent` | Entry that holds a section |
|
|
87
|
+
| `navLink` | `dp-nav-link` | Navigation link |
|
|
88
|
+
| `navLabel` | `dp-nav-label` | Section label, not clickable |
|
|
89
|
+
| `notice` | `dp-notice` | Banner of the versions that are not the current |
|
|
90
|
+
| `skillIcon` | `dp-skill-icon` | Icon before the name of a gauge |
|
|
91
|
+
| `main` | `dp-main` | Main area |
|
|
92
|
+
| `article` | `dp-article` | Page content |
|
|
93
|
+
| `toc` | `dp-toc` | Table of contents column |
|
|
94
|
+
| `tocTitle` | `dp-toc-title` | Title of the table of contents |
|
|
95
|
+
| `tocList` | `dp-toc-list` | List of the table of contents |
|
|
96
|
+
| `tocItem` | `dp-toc-item` | Entry of the table of contents |
|
|
97
|
+
| `footer` | `dp-footer` | Page footer |
|
|
98
|
+
| `scrollTop` | `dp-scroll-top` | Back-to-top button |
|
|
99
|
+
| `scrollTopIcon` | `dp-scroll-top-icon` | Arrow of that button |
|
|
100
|
+
|
|
101
|
+
A slot can carry **variants**, suffixed `--variant`: `column` gives
|
|
102
|
+
`dp-column--span-8`, `skill` gives `dp-skill--circle`.
|
|
103
|
+
|
|
104
|
+
## How a slot is rendered
|
|
105
|
+
|
|
106
|
+
Always in **triple braces**, in the templates:
|
|
107
|
+
|
|
108
|
+
```hbs
|
|
109
|
+
<nav class="{{{cls.sidebar}}}">
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Double braces would escape the content, and a utility class such as
|
|
113
|
+
`aria-[current=page]` would become `aria-[current=page]` — a silent
|
|
114
|
+
selector, without the slightest error.
|
|
115
|
+
|
|
116
|
+
## The stylesheets
|
|
117
|
+
|
|
118
|
+
The delivered stylesheet is assembled from four pieces, in this order:
|
|
119
|
+
|
|
120
|
+
| Stylesheet | Content |
|
|
121
|
+
| ------------------- | -------------------------------------------------- |
|
|
122
|
+
| `structure.css` | Grid, sticky columns, accessibility. Shared by all |
|
|
123
|
+
| `prose.css` | Typography of the content |
|
|
124
|
+
| a skin or a bridge | `custom.css`, or `tailwind-bridge.css` |
|
|
125
|
+
| the components' one | The `dp-*` rules of the shipped components |
|
|
126
|
+
|
|
127
|
+
Then comes what the project adds through `theme.css`.
|
|
128
|
+
|
|
129
|
+
The layout is **never** duplicated in a provider: it lives in `structure.css`,
|
|
130
|
+
which both share. A provider only takes care of the styling.
|
|
131
|
+
|
|
132
|
+
## Layer order
|
|
133
|
+
|
|
134
|
+
Under the `tailwind` theme, the stylesheet declares its layers in this order:
|
|
135
|
+
|
|
136
|
+
```css
|
|
137
|
+
@layer theme, base, components, utilities;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Component rules live in `components`, **below** the utilities. A `className`
|
|
141
|
+
set at use therefore always wins, whatever the place of the rule in the file.
|
|
142
|
+
|
|
143
|
+
The `custom` theme has no utility layer: its stylesheets are in no layer, and
|
|
144
|
+
therefore come before the component rules, which stay in the `components`
|
|
145
|
+
layer.
|
|
146
|
+
|
|
147
|
+
What `theme.css` adds is in no layer: without a layer, a rule wins over all
|
|
148
|
+
those that have one. That is what lets you write a fix there without worrying
|
|
149
|
+
about specificity.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Reference
|
|
3
|
+
description: Commands, configuration and frontmatter, field by field.
|
|
4
|
+
tags: [reference]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Reference
|
|
12
|
+
|
|
13
|
+
- **[Commands](./cli/)** — `init`, `build`, `check`, `dev`, `serve`
|
|
14
|
+
and their options.
|
|
15
|
+
- **[Configuration](./configuration/)** — every field of
|
|
16
|
+
`docpensieve.config.mjs`, its default value and its effect.
|
|
17
|
+
- **[Frontmatter](./frontmatter/)** — the fields recognised at the top
|
|
18
|
+
of a page.
|
|
19
|
+
- **[Theme](./theme/)** — slots, tokens and styling options.
|
|
20
|
+
|
|
21
|
+
To learn how to use them rather than look them up, the [guide](../guide/) is the
|
|
22
|
+
right starting point.
|
|
23
|
+
|
|
24
|
+
## Errors
|
|
25
|
+
|
|
26
|
+
Every expected error carries a message and an **actionable hint**. An invalid
|
|
27
|
+
configuration, an unknown version slug, a value out of range: each one says
|
|
28
|
+
what is wrong and what is expected instead.
|
|
29
|
+
|
|
30
|
+
Nothing fails silently. A component that cannot render what it is asked for
|
|
31
|
+
stops the build rather than produce an inert element — a tag that does nothing
|
|
32
|
+
goes unnoticed on review, an error does not.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
description: How a page becomes HTML, and why it works that way.
|
|
4
|
+
tags: [architecture]
|
|
5
|
+
|
|
6
|
+
jsonld:
|
|
7
|
+
type: TechArticle
|
|
8
|
+
breadcrumbs: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Architecture
|
|
12
|
+
|
|
13
|
+
## The journey of a page
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
.md / .mdx file
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
loading frontmatter detached, slug derived from the path
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
compilation MDX → React component
|
|
23
|
+
│
|
|
24
|
+
▼
|
|
25
|
+
rendering React → HTML string, once and for all
|
|
26
|
+
│
|
|
27
|
+
▼
|
|
28
|
+
shell header, menu, table of contents, footer
|
|
29
|
+
│
|
|
30
|
+
▼
|
|
31
|
+
page written a folder, an index.html
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Once every page is written, and **only then**, the stylesheet is compiled: a
|
|
35
|
+
utility theme needs to know which classes were actually used.
|
|
36
|
+
|
|
37
|
+
## React does not leave the build
|
|
38
|
+
|
|
39
|
+
Components are rendered to HTML during the build. The delivered site loads no
|
|
40
|
+
runtime: what reaches the reader is markup and a stylesheet.
|
|
41
|
+
|
|
42
|
+
That explains the shape of the shipped components. None of them has state or
|
|
43
|
+
an event listener, because there would be nothing to bring them to life.
|
|
44
|
+
Whatever needs interaction goes through a native element — `details` for
|
|
45
|
+
expanding, a link for moving — or through CSS.
|
|
46
|
+
|
|
47
|
+
This constraint is also what guarantees that a page stays readable in ten
|
|
48
|
+
years: there is nothing that can stop working.
|
|
49
|
+
|
|
50
|
+
## Templates do not render content
|
|
51
|
+
|
|
52
|
+
A template engine builds the shell: header, menu, table of contents, version
|
|
53
|
+
switcher, footer. The content comes from the MDX compilation.
|
|
54
|
+
|
|
55
|
+
The two do not mix, and that is deliberate. The content is written by the
|
|
56
|
+
author and can contain anything; the shell is written once and must never
|
|
57
|
+
depend on what a page contains.
|
|
58
|
+
|
|
59
|
+
## The packages
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
shared constants, errors, slugs — depends on nothing
|
|
63
|
+
core configuration, loading, compilation, JSON-LD, generation
|
|
64
|
+
theme stylings, each answering the same contract
|
|
65
|
+
components components available in pages
|
|
66
|
+
cli the commands
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**The graph never goes up.** The engine imports neither the stylings nor the
|
|
70
|
+
components: the commands hand them over. That is what lets it be tested
|
|
71
|
+
without React or CSS, and what keeps a circular dependency from settling in
|
|
72
|
+
unnoticed.
|
|
73
|
+
|
|
74
|
+
## Theme slots
|
|
75
|
+
|
|
76
|
+
The templates contain no class. They ask the theme for the class of each slot,
|
|
77
|
+
and the theme answers — a simple class, or a handful of utilities.
|
|
78
|
+
|
|
79
|
+
Two practical consequences:
|
|
80
|
+
|
|
81
|
+
- changing styling requires touching no template;
|
|
82
|
+
- a styling only needs to redefine what it changes.
|
|
83
|
+
|
|
84
|
+
Components follow the same rule, with a fallback: when there is no answer, they
|
|
85
|
+
take a `dp-*` class that their own stylesheet styles from the theme tokens.
|
|
86
|
+
They therefore follow the active palette without knowing anything about it.
|
|
87
|
+
|
|
88
|
+
## URLs
|
|
89
|
+
|
|
90
|
+
A relative target resolves against the folder of the page's file. An absolute
|
|
91
|
+
target starts from the **version root**, not from the domain: a documentation
|
|
92
|
+
does not know it may be served under a sub-path.
|
|
93
|
+
|
|
94
|
+
That rewrite happens on the tree built from the Markdown — hence **before** the
|
|
95
|
+
components are rendered. A component that produces a URL must therefore resolve
|
|
96
|
+
it itself, following the same rules. That is why every rendered page is
|
|
97
|
+
announced to the components, just as the class table is announced to them.
|
|
98
|
+
|
|
99
|
+
## Nothing fails silently
|
|
100
|
+
|
|
101
|
+
It is the rule that runs through everything else. An unknown value, a missing
|
|
102
|
+
parent, a file not found: each one stops the build with a message and a hint.
|
|
103
|
+
|
|
104
|
+
The alternative — rendering an empty element, ignoring a prop, falling back on
|
|
105
|
+
a default value — produces pages that look right and are not. Those faults are
|
|
106
|
+
only discovered in production, long afterwards.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<rect x="3" y="3" width="7.5" height="7.5" rx="1.5" />
|
|
3
|
+
<rect x="13.5" y="3" width="7.5" height="7.5" rx="1.5" />
|
|
4
|
+
<rect x="3" y="13.5" width="7.5" height="7.5" rx="1.5" />
|
|
5
|
+
<rect x="13.5" y="13.5" width="7.5" height="7.5" rx="1.5" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" />
|
|
3
|
+
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<circle cx="6" cy="5" r="2.5" />
|
|
3
|
+
<circle cx="6" cy="19" r="2.5" />
|
|
4
|
+
<circle cx="18" cy="12" r="2.5" />
|
|
5
|
+
<path d="M6 7.5v9M8.5 5h5a4 4 0 0 1 4 4v.5" />
|
|
6
|
+
</svg>
|