gutterpress 0.10.8 → 0.10.9
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 +93 -90
- package/dist/{README-aaqapam1.md → README-6c7fda1s.md} +9 -7
- package/dist/{README-mdq34cmb.md → README-jntqyj1z.md} +19 -10
- package/dist/api/index.d.ts +8 -8
- package/dist/api/index.js +46 -46
- package/dist/{audit-m3ce9pvq.js → audit-fq7s1gsz.js} +4 -4
- package/dist/{build-qnecb3a1.js → build-dyat3fqd.js} +5 -8
- package/dist/checks/source/dangling-links.d.ts +18 -0
- package/dist/checks/source/index.d.ts +1 -0
- package/dist/checks/source/local-ref-parser.d.ts +13 -0
- package/dist/{cli-1hx14cgk.js → cli-8pg731p5.js} +2941 -2927
- package/dist/{cli-4vtgt2ng.js → cli-bx950tb4.js} +7 -7
- package/dist/{cli-pfpb1t3h.js → cli-bzxqtvrk.js} +1 -2
- package/dist/{cli-vcv5ewqj.js → cli-rh05byck.js} +2 -9
- package/dist/{cli-vxf151ea.js → cli-ypfvnhag.js} +1 -1
- package/dist/cli.js +24 -53
- package/dist/{doctor-qvqye1wd.js → doctor-yr85n080.js} +2 -2
- package/dist/{engine-daad33qn.js → engine-19mshh07.js} +2 -2
- package/dist/{engine-db8632w6.js → engine-d46wgg99.js} +3 -3
- package/dist/ext-jrg8c48s.js +268 -0
- package/dist/{index-rpt4vtby.js → index-dhgzkhs7.js} +1 -1
- package/dist/{index-dfw8hn8q.js → index-mey5vraz.js} +5852 -5899
- package/dist/{index-9pbaznww.js → index-zwcv1njy.js} +7 -7
- package/dist/index.js +47 -47
- package/dist/lib/build-runner.d.ts +0 -7
- package/dist/lib/build-staging.d.ts +36 -0
- package/dist/lib/cli-args.d.ts +0 -7
- package/dist/lib/{theme-import.d.ts → extension-import.d.ts} +20 -11
- package/dist/lib/extension-manager.d.ts +170 -0
- package/dist/lib/extension-manifest.d.ts +25 -17
- package/dist/lib/extension-specifier.d.ts +31 -0
- package/dist/lib/manifest-doc.d.ts +3 -9
- package/dist/lib/markdown/markers.d.ts +2 -2
- package/dist/lib/markdown/plugins.d.ts +4 -4
- package/dist/lib/missing-asset-placeholder.d.ts +11 -0
- package/dist/lib/presets.d.ts +1 -1
- package/dist/lib/publish/providers/gdrive.d.ts +1 -1
- package/dist/lib/snippets.d.ts +11 -15
- package/dist/lib/style-resolver.d.ts +1 -1
- package/dist/{lint-3p1s8agk.js → lint-enasqbqx.js} +4 -4
- package/dist/{manifest.schema-1q35yxs9.json → manifest.schema-hsn8rsgr.json} +18 -53
- package/dist/{new-xffarp40.js → new-r9c99wsn.js} +11 -12
- package/dist/{plugin.test.js-mv0ghv5n.tpl → plugin.test.js-npnfhyca.tpl} +0 -1
- package/dist/{preflight-z6xpty9w.js → preflight-shk7vqbs.js} +4 -4
- package/dist/preview/file-watcher.d.ts +4 -4
- package/dist/preview/lifecycle.d.ts +1 -1
- package/dist/{preview-xa1n7why.js → preview-52918mxk.js} +6 -10
- package/dist/{publish-zgmr99kd.js → publish-8s60vhx7.js} +4 -4
- package/dist/schema/manifest.types.d.ts +28 -44
- package/dist/{theme-cd6efzjw.json → theme-etj4gxck.json} +4 -1
- package/dist/{theme-tqfypc1w.json → theme-s2rg7xe7.json} +4 -1
- package/dist/{theme-xt0hjb1b.json → theme-vktedy8q.json} +4 -1
- package/dist/types.d.ts +0 -7
- package/dist/{validate-43hqgzz5.js → validate-awccx32r.js} +4 -4
- package/package.json +1 -1
- package/dist/lib/plugin-manager.d.ts +0 -106
- package/dist/lib/theme-manager.d.ts +0 -242
- package/dist/plugin-b05ck7zd.js +0 -126
- package/dist/theme-m9dtxkhj.js +0 -323
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ See [User Guide: Chapter 1 — Getting Started](https://github.com/dimm-city/gut
|
|
|
108
108
|
|
|
109
109
|
## Manifest
|
|
110
110
|
|
|
111
|
-
`manifest.yaml` is where you control everything that isn't authored in markdown — book title, the page-size preset, custom styles,
|
|
111
|
+
`manifest.yaml` is where you control everything that isn't authored in markdown — book title, the page-size preset, custom styles, extensions (looks and plugins), validation rules, PDF/X configuration. It is the only recognized project manifest filename. The schema lives in [`docs/schema-autocomplete.md`](https://github.com/dimm-city/gutterpress/blob/main/docs/schema-autocomplete.md) for YAML autocomplete in editors.
|
|
112
112
|
|
|
113
113
|
Minimal example:
|
|
114
114
|
|
|
@@ -133,10 +133,10 @@ The full configuration cascade is `CLI flags > manifest.yaml > preset defaults`.
|
|
|
133
133
|
|
|
134
134
|
## Commands
|
|
135
135
|
|
|
136
|
-
Gutterpress has
|
|
136
|
+
Gutterpress has 10 subcommands. `new`, `preview`, `build`, and `publish` are the
|
|
137
137
|
primary author commands; `lint`, `validate`, `audit`, and `preflight` are
|
|
138
|
-
CI / advanced checks;
|
|
139
|
-
project plugins
|
|
138
|
+
CI / advanced checks; `doctor` reports system readiness; and `ext` manages the
|
|
139
|
+
project's extensions (plugins, looks, component libraries). Every
|
|
140
140
|
command also accepts `--help` for the authoritative, always-current flag list
|
|
141
141
|
(`gutterpress <command> --help`) — this section is regenerated from the same
|
|
142
142
|
source.
|
|
@@ -198,7 +198,6 @@ gutterpress preview [input-dir] [options]
|
|
|
198
198
|
--skip-pre-validate Skip pre-build validation (pdf|pdfx only)
|
|
199
199
|
--skip-post-validate Skip post-build PDF/X validation (pdfx only)
|
|
200
200
|
--allow-shrink Build anyway when content is wider than the page content box (pdf|pdfx only)
|
|
201
|
-
--engine <name> native (default) | paged (deprecated) [overrides the manifest's engine: field; applies to the live preview AND --format pdf|pdfx]
|
|
202
201
|
```
|
|
203
202
|
|
|
204
203
|
### `gutterpress build`
|
|
@@ -219,7 +218,6 @@ gutterpress build [input-dir] [options]
|
|
|
219
218
|
--skip-pre-validate Skip pre-build validation
|
|
220
219
|
--skip-post-validate Skip post-build PDF/X validation
|
|
221
220
|
--allow-shrink Build anyway when content is wider than the page content box. Chromium then scales the WHOLE book down to fit it — the build reports that whole-document scale (e.g. "about 0.72x its declared size") plus every offender, as warnings.
|
|
222
|
-
--engine <name> native (default) | paged (deprecated) [overrides the manifest's engine: field; native = the Gutterpress engine, native Chromium pagination]
|
|
223
221
|
```
|
|
224
222
|
|
|
225
223
|
### `gutterpress publish`
|
|
@@ -271,9 +269,11 @@ gutterpress lint [files] [options]
|
|
|
271
269
|
|
|
272
270
|
Common findings include remote `url(...)` references, effects that rasterize
|
|
273
271
|
print text, and declarations on core page wrappers that could clip or trap
|
|
274
|
-
out-of-flow art.
|
|
275
|
-
|
|
276
|
-
|
|
272
|
+
out-of-flow art. Each finding is listed with its file and `line:col`, so you
|
|
273
|
+
can see exactly which selectors rasterize text; a property at its initial value
|
|
274
|
+
(`filter: none`, `will-change: auto`) is not a finding. The source-level
|
|
275
|
+
containment check is an early signal; the build-time `engine.layer.trapped`
|
|
276
|
+
diagnostic inspects the authoritative live ancestor chain.
|
|
277
277
|
|
|
278
278
|
### `gutterpress validate`
|
|
279
279
|
|
|
@@ -334,94 +334,96 @@ Report the Gutterpress version, platform and config paths, and whether each exte
|
|
|
334
334
|
gutterpress doctor
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
-
### `gutterpress
|
|
337
|
+
### `gutterpress ext`
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
List, add, remove, enable, or disable the project's extensions. Markdown-it
|
|
340
|
+
plugins, looks (stylesheets) and component libraries are all extensions — one
|
|
341
|
+
`extensions:` list in `manifest.yaml`, in load order (see
|
|
342
|
+
[Extensions](#extensions) below). These are the same shared-lib functions the
|
|
343
|
+
desktop app's Look and Features views call, so an extension added from the
|
|
344
|
+
terminal is the same entry the GUI shows.
|
|
340
345
|
|
|
341
346
|
```sh
|
|
342
|
-
gutterpress
|
|
347
|
+
gutterpress ext
|
|
343
348
|
|
|
344
|
-
--help Show
|
|
349
|
+
--help Show ext subcommands (list, add, remove, enable, disable)
|
|
345
350
|
```
|
|
346
351
|
|
|
347
|
-
|
|
352
|
+
Every subcommand takes the project directory as an optional trailing
|
|
353
|
+
positional (default: the current directory).
|
|
348
354
|
|
|
349
|
-
|
|
350
|
-
verify their registry hashes, vendor the complete graph into the project, and
|
|
351
|
-
pin the exact root version. This does not invoke npm, Bun, Node.js tooling, or
|
|
352
|
-
package install scripts.
|
|
355
|
+
#### `gutterpress ext list`
|
|
353
356
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### `gutterpress theme`
|
|
361
|
-
|
|
362
|
-
List, apply, import, revert, or remove project themes — the same
|
|
363
|
-
`applyTheme`/`importThemeFrom*`/`revertTheme`/`removeProjectTheme` functions
|
|
364
|
-
the desktop app's Theme panel calls, so a theme applied from the terminal is
|
|
365
|
-
just as switchable/revertible as one applied from the GUI.
|
|
357
|
+
List the project's extensions in load (= cascade) order: each specifier as
|
|
358
|
+
written, whether it is bundled, a path, or an npm package, what it carries
|
|
359
|
+
(markdown, styles, snippets, components), and any warning — not installed,
|
|
360
|
+
not found, not pinned.
|
|
366
361
|
|
|
367
362
|
```sh
|
|
368
|
-
gutterpress
|
|
369
|
-
|
|
370
|
-
--help Show theme subcommands
|
|
363
|
+
gutterpress ext list ./my-book
|
|
371
364
|
```
|
|
372
365
|
|
|
373
|
-
#### `gutterpress
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
366
|
+
#### `gutterpress ext add`
|
|
367
|
+
|
|
368
|
+
Add an extension. What `SOURCE` is decides what happens:
|
|
369
|
+
|
|
370
|
+
- an **npm package** (`name` or `name@version`) is downloaded straight from
|
|
371
|
+
the registry along with its runtime dependencies, hash-verified, vendored
|
|
372
|
+
into the project under `plugins/npm/` with a receipt, load-tested, and
|
|
373
|
+
written back pinned as `name@<exact version>`. This does not invoke npm,
|
|
374
|
+
Bun, Node.js tooling, or package install scripts;
|
|
375
|
+
- a **bundled feature** (`markdown-it-mark`, `markdown-it-sub`,
|
|
376
|
+
`markdown-it-sup`, `markdown-it-abbr`, `gutterpress-gfm-alerts`) is simply
|
|
377
|
+
listed — nothing to install, works offline;
|
|
378
|
+
- a **folder or plugin-file path** is load-tested and listed as a
|
|
379
|
+
manifest-relative path, referenced in place — never copied;
|
|
380
|
+
- a **`.zip` or `.css` file**, or an **http(s) URL**, is validated (every
|
|
381
|
+
declared sheet must exist and parse; print-safety findings are warnings)
|
|
382
|
+
and landed in `extensions/<id>/`, then listed as `./extensions/<id>`;
|
|
383
|
+
- with `--look`, `SOURCE` is a built-in look id, copied into
|
|
384
|
+
`extensions/<id>/` as the author's own editable files and listed.
|
|
385
|
+
|
|
386
|
+
Adding something already listed re-pins or updates that entry instead of
|
|
387
|
+
adding a second one.
|
|
377
388
|
|
|
378
389
|
```sh
|
|
379
|
-
gutterpress
|
|
380
|
-
```
|
|
390
|
+
gutterpress ext add <source> [dir] [options]
|
|
381
391
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
Apply a theme: a built-in id (`clean-book`, `zine`, `technical-doc`) is copied
|
|
385
|
-
into `themes/<id>/` the first time, and the manifest's `styles:` entry is
|
|
386
|
-
wired so its `theme.css` is the active stylesheet, keeping its cascade
|
|
387
|
-
position. Re-running `apply` with an id that is already a project theme makes
|
|
388
|
-
it active again without forking a second copy — the same non-destructive
|
|
389
|
-
re-apply guarantee the desktop's Theme panel relies on.
|
|
390
|
-
|
|
391
|
-
```sh
|
|
392
|
-
gutterpress theme apply clean-book ./my-book
|
|
393
|
-
gutterpress theme apply zine ./my-book
|
|
392
|
+
--export <name> Named module export to use as the plugin function (npm and path extensions only)
|
|
393
|
+
--look Treat SOURCE as a built-in look id (clean-book, zine, technical-doc): copy it into extensions/ and add it
|
|
394
394
|
```
|
|
395
395
|
|
|
396
|
-
#### `gutterpress theme import`
|
|
397
|
-
|
|
398
|
-
Import a theme from a local folder, a `.zip` package, a `.css` file, or an
|
|
399
|
-
`http(s)` URL. Importing vendors the theme under `themes/<id>/` but does not
|
|
400
|
-
apply it — follow up with `gutterpress theme apply <id>`.
|
|
401
|
-
|
|
402
396
|
```sh
|
|
403
|
-
gutterpress
|
|
404
|
-
gutterpress
|
|
405
|
-
gutterpress
|
|
406
|
-
gutterpress
|
|
397
|
+
gutterpress ext add markdown-it-highlightjs ./my-book
|
|
398
|
+
gutterpress ext add markdown-it-highlightjs@4.3.0 ./my-book
|
|
399
|
+
gutterpress ext add markdown-it-emoji@3.0.0 ./my-book --export full
|
|
400
|
+
gutterpress ext add markdown-it-mark ./my-book
|
|
401
|
+
gutterpress ext add ./plugins/field-notes ./my-book
|
|
402
|
+
gutterpress ext add zine ./my-book --look
|
|
403
|
+
gutterpress ext add ./parchment.zip ./my-book
|
|
404
|
+
gutterpress ext add https://example.com/looks/cool/ ./my-book
|
|
407
405
|
```
|
|
408
406
|
|
|
409
|
-
#### `gutterpress
|
|
407
|
+
#### `gutterpress ext remove`
|
|
410
408
|
|
|
411
|
-
|
|
412
|
-
|
|
409
|
+
Remove an extension from the manifest, by the specifier as written there (for
|
|
410
|
+
an npm package the bare name is enough). An npm extension's vendored copy
|
|
411
|
+
under `plugins/npm/` is deleted too; a path extension's folder is yours and is
|
|
412
|
+
never touched.
|
|
413
413
|
|
|
414
414
|
```sh
|
|
415
|
-
gutterpress
|
|
415
|
+
gutterpress ext remove markdown-it-highlightjs ./my-book
|
|
416
|
+
gutterpress ext remove ./extensions/zine ./my-book
|
|
416
417
|
```
|
|
417
418
|
|
|
418
|
-
#### `gutterpress
|
|
419
|
+
#### `gutterpress ext enable` / `gutterpress ext disable`
|
|
419
420
|
|
|
420
|
-
|
|
421
|
-
|
|
421
|
+
Turn a configured extension off without removing it (`disable` writes
|
|
422
|
+
`enabled: false` on the entry, so the toggle is reversible), or back on.
|
|
422
423
|
|
|
423
424
|
```sh
|
|
424
|
-
gutterpress
|
|
425
|
+
gutterpress ext disable markdown-it-mark ./my-book
|
|
426
|
+
gutterpress ext enable markdown-it-mark ./my-book
|
|
425
427
|
```
|
|
426
428
|
|
|
427
429
|
## Exit codes
|
|
@@ -435,44 +437,45 @@ Every command follows the same exit-code contract, so CI can branch on the resul
|
|
|
435
437
|
| `2` | Usage — the invocation itself was wrong: a bad flag, positional argument, preset, or value. |
|
|
436
438
|
| `3` | Pipeline — the build/render/export pipeline itself failed for a reason unrelated to usage or findings (I/O error, missing tool, renderer crash). |
|
|
437
439
|
|
|
438
|
-
This applies uniformly across `build`, `preview`, `lint`, `validate`, `preflight`, `audit`, `publish`, `
|
|
440
|
+
This applies uniformly across `build`, `preview`, `lint`, `validate`, `preflight`, `audit`, `publish`, `ext`, `new`, and `doctor`.
|
|
439
441
|
|
|
440
|
-
##
|
|
442
|
+
## Extensions
|
|
441
443
|
|
|
442
|
-
Gutterpress uses [markdown-it](https://github.com/markdown-it/markdown-it) under the hood, so pure-JavaScript plugins that follow the `(md, options) => void` signature work without a Gutterpress-specific API.
|
|
444
|
+
Gutterpress uses [markdown-it](https://github.com/markdown-it/markdown-it) under the hood, so pure-JavaScript plugins that follow the `(md, options) => void` signature work without a Gutterpress-specific API. Plugins, looks (stylesheets) and component libraries are all **extensions**: one `extensions:` list in `manifest.yaml`, in load order. Every entry is a bare specifier, and its form says what it is:
|
|
443
445
|
|
|
444
446
|
```yaml
|
|
445
|
-
|
|
446
|
-
#
|
|
447
|
-
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
- name: markdown-it-emoji
|
|
451
|
-
version: 3.0.0
|
|
452
|
-
export: full
|
|
453
|
-
# local file
|
|
447
|
+
extensions:
|
|
448
|
+
# a feature bundled with Gutterpress — nothing to install, works offline
|
|
449
|
+
- markdown-it-mark
|
|
450
|
+
# a folder or plugin file, relative to manifest.yaml — referenced in place
|
|
451
|
+
- ./extensions/clean-book
|
|
454
452
|
- ./plugins/my-custom-plugin.js
|
|
455
|
-
#
|
|
456
|
-
-
|
|
453
|
+
# an npm package, pinned to the exact version `gutterpress ext add` installed
|
|
454
|
+
- markdown-it-highlightjs@4.3.0
|
|
455
|
+
# the object form, only when an entry needs more than its specifier
|
|
456
|
+
- use: markdown-it-emoji@3.0.0
|
|
457
|
+
export: full # the plugin function is a named export
|
|
458
|
+
- use: markdown-it-anchor@9.2.0
|
|
457
459
|
options:
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
priority: 10
|
|
460
|
+
level: 2
|
|
461
|
+
- use: ./plugins/drafts.js
|
|
462
|
+
enabled: false # keep the entry, skip loading it
|
|
462
463
|
```
|
|
463
464
|
|
|
465
|
+
Order is load order: a later entry's markdown runs after earlier entries' (and sees their output) and its CSS wins ties; the project's own `styles:` always load after every extension. There is no `priority` and no `path:`/`name:` wrapper — a manifest still carrying `plugins:` fails with a message that prints the same entries rewritten as `extensions:`. The `engine:` and `engineStyles:` keys are gone too (there is one engine; move any `engineStyles` entries to the end of `styles:`).
|
|
466
|
+
|
|
464
467
|
Pinned npm packages and their runtime dependencies live under `plugins/npm/`,
|
|
465
468
|
with a receipt that records the exact graph and hashes the complete tree. They
|
|
466
469
|
travel with the project and builds never fetch from the registry. Install/build
|
|
467
470
|
scripts, native addon compilation, bundled `node_modules`, and non-registry
|
|
468
471
|
dependency selectors are intentionally unsupported. Only install packages you
|
|
469
|
-
trust:
|
|
472
|
+
trust: extensions run unsandboxed with the process's full filesystem and network
|
|
470
473
|
privileges.
|
|
471
474
|
|
|
472
|
-
Use the
|
|
475
|
+
Use the entry's `export` field, or `ext add --export <name>`, for packages
|
|
473
476
|
that expose a named plugin function instead of a default export.
|
|
474
477
|
|
|
475
|
-
See [User Guide: Chapter 5 — Plugins](https://github.com/dimm-city/gutterpress/blob/main/examples/gutterpress-user-guide/05-plugins.md) for authoring custom plugins.
|
|
478
|
+
See [User Guide: Chapter 5 — Plugins](https://github.com/dimm-city/gutterpress/blob/main/examples/gutterpress-user-guide/05-plugins.md) for the full list contract and for authoring custom plugins, and [Chapter 4 — Styling & Theming](https://github.com/dimm-city/gutterpress/blob/main/examples/gutterpress-user-guide/04-styling-theming.md) for looks.
|
|
476
479
|
|
|
477
480
|
## CI / scripting
|
|
478
481
|
|
|
@@ -28,13 +28,15 @@ about to add a rule to the wrong sheet.
|
|
|
28
28
|
## Try it
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
|
-
gutterpress
|
|
32
|
-
gutterpress theme apply {{SLUG}} ../my-book
|
|
31
|
+
gutterpress ext add ./{{SLUG}} ../my-book
|
|
33
32
|
gutterpress preview ../my-book
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
`ext add` takes the book directory as its second POSITIONAL argument, not a
|
|
36
|
+
`--dir` flag. It lists the folder under the book's `extensions:` and references
|
|
37
|
+
it in place — nothing is copied, so keep editing here and the book follows.
|
|
38
|
+
The book's own `styles:` always load after every extension, so an author can
|
|
39
|
+
override any rule in this package from their `styles/book.css`.
|
|
38
40
|
|
|
39
41
|
Then in a chapter:
|
|
40
42
|
|
|
@@ -127,9 +129,9 @@ That asymmetry is the whole difference between the two kinds of package.
|
|
|
127
129
|
```
|
|
128
130
|
|
|
129
131
|
Each sheet then puts everything it owns inside its layer. The cascade is
|
|
130
|
-
settled by that one line rather than by which
|
|
131
|
-
splitting a sheet or reordering
|
|
132
|
-
wins.
|
|
132
|
+
settled by that one line rather than by which sheet `gutterpress.json`'s
|
|
133
|
+
`styles` lists last, so splitting a sheet or reordering that list can no
|
|
134
|
+
longer silently flip who wins.
|
|
133
135
|
|
|
134
136
|
The trap, and it catches everyone once: a rule left OUTSIDE all the layers is
|
|
135
137
|
fully unlayered, and unlayered CSS beats layered CSS at any specificity. So
|
|
@@ -25,14 +25,17 @@ bun test
|
|
|
25
25
|
Then wire it into a book. In the book's `manifest.yaml`:
|
|
26
26
|
|
|
27
27
|
```yaml
|
|
28
|
-
|
|
29
|
-
-
|
|
28
|
+
extensions:
|
|
29
|
+
- ./plugins/{{SLUG}}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`
|
|
32
|
+
`gutterpress ext add ./plugins/{{SLUG}} <book>` writes that line for you (the
|
|
33
|
+
book directory is the second positional argument). Either way the entry names
|
|
34
|
+
the FOLDER, not `plugin.js`. That is what makes Gutterpress read
|
|
33
35
|
`gutterpress.json` and pick up the stylesheet and snippets alongside the
|
|
34
36
|
markdown behaviour — point it at the `.js` file and you get the markdown and
|
|
35
|
-
nothing else.
|
|
37
|
+
nothing else. The folder is referenced in place, never copied: keep editing it
|
|
38
|
+
and the book follows.
|
|
36
39
|
|
|
37
40
|
Now `gutterpress preview` the book and write:
|
|
38
41
|
|
|
@@ -111,14 +114,20 @@ outcome, and another reason to prefix.
|
|
|
111
114
|
|
|
112
115
|
`styles/plugin.css` wraps everything in `@layer {{SLUG}}`.
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
unlayered rule beats a layered one at any
|
|
116
|
-
sheet outranks every rule in a book
|
|
117
|
+
Extension CSS lands in the book in `extensions:` list order, and always before
|
|
118
|
+
the book's own `styles:`. In CSS an unlayered rule beats a layered one at any
|
|
119
|
+
specificity. So an unlayered plugin sheet outranks every rule in a book whose
|
|
120
|
+
look uses the recommended
|
|
117
121
|
`@layer tokens, base, components, templates, pages, book;` convention — the
|
|
118
122
|
author edits their CSS and nothing happens.
|
|
119
123
|
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
Inside a layer, the book's own unlayered `styles:` always beat you, which is
|
|
125
|
+
right. Against the LOOK's layers, position decides: a layer sorts by where it
|
|
126
|
+
is first declared, so with this plugin listed above the look in `extensions:`
|
|
127
|
+
its layer sorts first and is the weakest thing in the book — the right place
|
|
128
|
+
for a plugin to sit. Listed below the look, its component rules win ties over
|
|
129
|
+
the look's layered rules instead. Either way the author moves one line to
|
|
130
|
+
change it; that is the whole point of the list.
|
|
122
131
|
|
|
123
132
|
Adopt it for the whole file: a rule left outside the layer is unlayered and
|
|
124
133
|
beats everything inside it, including your own.
|
|
@@ -152,4 +161,4 @@ Anything a book can reach works. Committing the folder into the book's
|
|
|
152
161
|
`plugins/` directory is the simplest and needs no registry at all.
|
|
153
162
|
|
|
154
163
|
To publish to npm, `npm publish` this folder and have readers install it with
|
|
155
|
-
`gutterpress
|
|
164
|
+
`gutterpress ext add {{SLUG}}`.
|
package/dist/api/index.d.ts
CHANGED
|
@@ -33,14 +33,14 @@ export { listBuiltInTemplates, listCustomTemplates, saveProjectAsTemplate, impor
|
|
|
33
33
|
export type { TemplateInfo, SaveProjectAsTemplateOptions, } from "../lib/project-templates.ts";
|
|
34
34
|
export { extractVariables, substituteVariables, listSnippets, readSnippet, saveSnippet, deleteSnippet, listMergedSnippets, readExtensionSnippet, SNIPPETS_DIR, } from "../lib/snippets.ts";
|
|
35
35
|
export type { SnippetEntry, SnippetSource } from "../lib/snippets.ts";
|
|
36
|
-
export {
|
|
37
|
-
export type {
|
|
38
|
-
export {
|
|
39
|
-
export type {
|
|
40
|
-
export {
|
|
41
|
-
export type {
|
|
42
|
-
export { EXTENSION_MANIFEST_FILENAME, LEGACY_THEME_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList,
|
|
43
|
-
export type { ExtensionMetadata, ResolvedExtension } from "../lib/extension-manifest.ts";
|
|
36
|
+
export { listProjectExtensions, describeExtension, addExtension, removeExtension, setExtensionEnabled, reorderExtensions, validateProjectExtensions, readExtensionCss, listBuiltInStyleSets, addBuiltInStyleSet, sameExtension, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, EXTENSIONS_DIR, PLUGINS_DIR, } from "../lib/extension-manager.ts";
|
|
37
|
+
export type { ProjectExtensionEntry, ExtensionValidationResult, RecommendedExtension, ExtensionSourceKind, BuiltInStyleSet, BuiltInStyleSetId, AddExtensionOptions, } from "../lib/extension-manager.ts";
|
|
38
|
+
export { BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, } from "../lib/extension-specifier.ts";
|
|
39
|
+
export type { ParsedExtensionSpecifier } from "../lib/extension-specifier.ts";
|
|
40
|
+
export { importExtensionFromFile, importExtensionFromUrl } from "../lib/extension-import.ts";
|
|
41
|
+
export type { ExtensionImportResult, ExtensionImportWarning } from "../lib/extension-import.ts";
|
|
42
|
+
export { EXTENSION_MANIFEST_FILENAME, LEGACY_THEME_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionStyleListWithDefault, extensionCarries, assertExtensionContained, pathEscapesFolder, resolveExtension, } from "../lib/extension-manifest.ts";
|
|
43
|
+
export type { ExtensionMetadata, ResolvedExtension, ExtensionCarries, } from "../lib/extension-manifest.ts";
|
|
44
44
|
export { listProjectStyles, resolveActiveStyles } from "../lib/style-resolver.ts";
|
|
45
45
|
export type { ProjectStyle } from "../lib/style-resolver.ts";
|
|
46
46
|
export { readManifestFields, setManifestFields, setActiveStyles, } from "../lib/manifest-config.ts";
|