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
|
@@ -8,8 +8,8 @@ export declare const LEGACY_THEME_MANIFEST_FILENAME = "theme.json";
|
|
|
8
8
|
/**
|
|
9
9
|
* Parsed extension metadata — a superset of the pre-#241 theme metadata
|
|
10
10
|
* shape. Every field is optional, and a folder declaring only the theme-era
|
|
11
|
-
* fields (`name`/`author`/`description`/`preview`/`styles`/`
|
|
12
|
-
*
|
|
11
|
+
* fields (`name`/`author`/`description`/`preview`/`styles`/`tokensFile`) IS
|
|
12
|
+
* a valid extension: "theme ≡ extension with only styles."
|
|
13
13
|
* Symmetrically, a bare `.js` plugin file (no metadata file at all) never
|
|
14
14
|
* constructs one of these — "plugin ≡ extension with only markdown" needs no
|
|
15
15
|
* metadata file until it wants more than a function (see `plugins.ts`'s
|
|
@@ -25,16 +25,11 @@ export interface ExtensionMetadata {
|
|
|
25
25
|
/**
|
|
26
26
|
* Ordered stylesheets, relative to the extension folder. Absent/empty means
|
|
27
27
|
* "no styles declared" here — {@link extensionStyleList} does NOT default
|
|
28
|
-
* to `["theme.css"]`; that default is
|
|
28
|
+
* to `["theme.css"]`; that default is {@link extensionStyleListWithDefault}'s, layered on
|
|
29
29
|
* top for its theme-shaped callers (a plain markdown-only extension folder
|
|
30
30
|
* has no reason to require a `theme.css` it never declared).
|
|
31
31
|
*/
|
|
32
32
|
styles?: string[];
|
|
33
|
-
/** Engine-conditional sheets, relative to the extension folder, appended
|
|
34
|
-
* after `styles` (mirrors the manifest's own `engineStyles.native`). */
|
|
35
|
-
engineStyles?: {
|
|
36
|
-
native?: string[];
|
|
37
|
-
};
|
|
38
33
|
/** Which declared sheet (a path from `styles`) carries the author-facing
|
|
39
34
|
* `:root` token surface for the Design panel's guided editor. Purely
|
|
40
35
|
* advisory — nothing in this module enforces or existence-checks it,
|
|
@@ -80,14 +75,26 @@ export interface ExtensionMetadata {
|
|
|
80
75
|
export declare function readExtensionMeta(dir: string): Promise<ExtensionMetadata>;
|
|
81
76
|
/**
|
|
82
77
|
* An extension's declared stylesheets, relative to its folder, in cascade
|
|
83
|
-
* order. UNLIKE
|
|
78
|
+
* order. UNLIKE {@link extensionStyleListWithDefault} (which layers a
|
|
84
79
|
* `["theme.css"]` default on top of this for its theme-shaped callers), an
|
|
85
80
|
* absent/empty `styles` here means exactly "none declared" — a markdown-only
|
|
86
81
|
* extension folder must not be forced to carry a `theme.css` it never wanted.
|
|
87
82
|
*/
|
|
88
83
|
export declare function extensionStyleList(meta: ExtensionMetadata): string[];
|
|
89
|
-
/**
|
|
90
|
-
|
|
84
|
+
/**
|
|
85
|
+
* `styles`, with the theme-era default (#265): a folder that declares none
|
|
86
|
+
* but holds a `theme.css` IS a one-sheet look — every theme published before
|
|
87
|
+
* `styles` existed. A folder with neither still declares nothing.
|
|
88
|
+
*/
|
|
89
|
+
export declare function extensionStyleListWithDefault(meta: ExtensionMetadata, dir: string): string[];
|
|
90
|
+
/** What an extension declares, by field — the desktop's one-list filter. */
|
|
91
|
+
export interface ExtensionCarries {
|
|
92
|
+
markdown: boolean;
|
|
93
|
+
styles: boolean;
|
|
94
|
+
snippets: boolean;
|
|
95
|
+
components: boolean;
|
|
96
|
+
}
|
|
97
|
+
export declare function extensionCarries(meta: ExtensionMetadata, dir: string): ExtensionCarries;
|
|
91
98
|
/**
|
|
92
99
|
* True when a declared relative path escapes its own folder (absolute, or a
|
|
93
100
|
* `..` segment) — the traversal shape every containment check in this
|
|
@@ -111,24 +118,27 @@ export declare function pathEscapesFolder(rel: string): boolean;
|
|
|
111
118
|
* absolute entry would make apply/load read a file from anywhere on disk.
|
|
112
119
|
*
|
|
113
120
|
* Generalizes the pre-#241 theme-only `assertThemeSheetsContained` (still
|
|
114
|
-
* exported under that name from
|
|
121
|
+
* once exported under that name from the theme manager, now this
|
|
115
122
|
* function) to the three new fields: a `gutterpress.json`-formatted theme
|
|
116
123
|
* folder can declare `markdown`/`components`/`snippets` too, so the SAME
|
|
117
|
-
* write-boundary guard must cover them, not just `styles
|
|
124
|
+
* write-boundary guard must cover them, not just `styles`.
|
|
118
125
|
* `tokensFile` is included even though it is advisory/unenforced elsewhere —
|
|
119
126
|
* defense in depth against a future consumer reading it unchecked.
|
|
120
127
|
*
|
|
121
128
|
* A WRITE-BOUNDARY guard, not a read-path check (mirrors the theme-only
|
|
122
129
|
* predecessor): callers invoke this before copying anything or wiring a
|
|
123
130
|
* manifest, never from a plain listing/read path, so one hand-edited
|
|
124
|
-
* metadata file cannot take down listing every extension.
|
|
131
|
+
* metadata file cannot take down listing every extension. The removed
|
|
132
|
+
* `engineStyles` field (#266) is rejected here for the same reason: the
|
|
133
|
+
* error names the replacement, and it fires only where something would be
|
|
134
|
+
* copied or wired, never while listing.
|
|
125
135
|
*/
|
|
126
136
|
export declare function assertExtensionContained(meta: ExtensionMetadata): void;
|
|
127
137
|
/**
|
|
128
138
|
* An extension's declared paths, resolved to absolute, existence-checked
|
|
129
139
|
* filesystem paths — every list/single-path field goes through the SAME
|
|
130
140
|
* {@link resolveDeclaredStyles} a plugin's `styles` export and a theme's
|
|
131
|
-
* `styles
|
|
141
|
+
* `styles` already resolve through, so a broken
|
|
132
142
|
* declaration (a missing file) throws HERE, at load/apply time, instead of
|
|
133
143
|
* failing silently deep in the render pipeline (or never, for `components`/
|
|
134
144
|
* `snippets`, which nothing yet reads — #240/#242).
|
|
@@ -142,8 +152,6 @@ export interface ResolvedExtension {
|
|
|
142
152
|
markdown?: string;
|
|
143
153
|
/** Absolute paths, in cascade order, when any are declared. */
|
|
144
154
|
styles?: string[];
|
|
145
|
-
/** Absolute paths, in cascade order, when any are declared. */
|
|
146
|
-
engineStyles?: string[];
|
|
147
155
|
/** Declared-relative path of the `:root` token surface — advisory. */
|
|
148
156
|
tokensFile?: string;
|
|
149
157
|
/** Absolute path to the component catalog file, when declared (#242). */
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The markdown features compiled into Gutterpress (`BUILTIN_OPTIONAL_PLUGINS`,
|
|
3
|
+
* `markdown/renderer.ts` — a test pins the two lists together). Writing one
|
|
4
|
+
* of these names installs nothing: the loader resolves it from the bundle.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BUNDLED_EXTENSIONS: readonly ["markdown-it-mark", "markdown-it-sub", "markdown-it-sup", "markdown-it-abbr", "gutterpress-gfm-alerts"];
|
|
7
|
+
export type BundledExtensionName = (typeof BUNDLED_EXTENSIONS)[number];
|
|
8
|
+
export declare function isBundledExtension(name: string): name is BundledExtensionName;
|
|
9
|
+
/** `./x`, `../x`, `/x`, or a Windows drive path (`C:\x`). Nothing else is a path. */
|
|
10
|
+
export declare function isPathSpecifier(use: string): boolean;
|
|
11
|
+
export type ParsedExtensionSpecifier = {
|
|
12
|
+
kind: "path";
|
|
13
|
+
path: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "bundled";
|
|
16
|
+
name: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "npm";
|
|
19
|
+
name: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Parse one specifier. Throws a plain `Error` whose message says what to
|
|
24
|
+
* write instead — callers wrap it with the entry's position.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseExtensionSpecifier(use: string): ParsedExtensionSpecifier;
|
|
27
|
+
/**
|
|
28
|
+
* The specifier an `ext add` writes back for an npm install: the exact
|
|
29
|
+
* version is part of the specifier, so the manifest reads `name@1.2.3`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function pinnedNpmSpecifier(name: string, version: string): string;
|
|
@@ -9,14 +9,8 @@ export declare function loadManifestDoc(projectDir: string): Promise<{
|
|
|
9
9
|
}>;
|
|
10
10
|
/** Atomically write the doc back, creating the project dir if needed. */
|
|
11
11
|
export declare function writeManifestDoc(file: string, doc: Document.Parsed): Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
* `key` is a single top-level key (the original, still-exact behavior) OR a
|
|
15
|
-
* path for a nested key (e.g. `["engineStyles", "native"]`, #239) — the
|
|
16
|
-
* `getIn`/`setIn` branch auto-vivifies any missing intermediate map, exactly
|
|
17
|
-
* like a hand-written `engineStyles: { native: [...] }` would parse.
|
|
18
|
-
*/
|
|
19
|
-
export declare function ensureSeq(doc: Document.Parsed, key: string | readonly string[]): YAMLSeq;
|
|
12
|
+
/** The named top-level sequence node, creating (and attaching) an empty one if missing. */
|
|
13
|
+
export declare function ensureSeq(doc: Document.Parsed, key: string): YAMLSeq;
|
|
20
14
|
/**
|
|
21
15
|
* Unwrap a yaml seq item (or `getIn`-style Pair) to its string value: `null`
|
|
22
16
|
* when the item isn't a string. Handles both a bare Scalar/Pair-shaped node
|
|
@@ -25,7 +19,7 @@ export declare function ensureSeq(doc: Document.Parsed, key: string | readonly s
|
|
|
25
19
|
* array entry would be).
|
|
26
20
|
*
|
|
27
21
|
* ARCH finding #25: this was two near-duplicate helpers — `unwrapScalar`
|
|
28
|
-
* (manifest-config.ts) and `styleHrefOf` (theme
|
|
22
|
+
* (manifest-config.ts) and `styleHrefOf` (the theme manager, since retired) — with the same
|
|
29
23
|
* shape-sniffing logic. One implementation here, consumed by both.
|
|
30
24
|
*/
|
|
31
25
|
export declare function scalarString(item: unknown): string | null;
|
|
@@ -27,8 +27,8 @@ export default function plugin(md: any, pluginOptions?: {}): void;
|
|
|
27
27
|
* opposite and was stale — 2026-09-01 CSS architecture review, C4):
|
|
28
28
|
* consumers inject this FIRST, wrapped in `@layer gp.marker` (assemble.ts
|
|
29
29
|
* declares `@layer gp.marker, gp.vocab;` before both core blocks). Author
|
|
30
|
-
* CSS — plugin CSS, every project stylesheet,
|
|
31
|
-
*
|
|
30
|
+
* CSS — plugin CSS, every project stylesheet — stays UNLAYERED, and per
|
|
31
|
+
* the CSS Cascade Layers
|
|
32
32
|
* spec unlayered CSS always wins over layered CSS regardless of selector
|
|
33
33
|
* specificity. That is what makes "author wins" true now, not injection
|
|
34
34
|
* order. The `:where()` wrapping on the break/orphan/sizing rules below is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ResolvedExtensionConfig } from "../../schema/manifest.types";
|
|
2
2
|
import type { LoadedPlugin } from "./renderer";
|
|
3
3
|
export type { GutterpressMarkerDeclaration, GutterpressMarkerLabel, GutterpressMarkerTable, GutterpressPlugin, GutterpressPluginMetadata, GutterpressPluginExport, LoadedPlugin, } from "./renderer";
|
|
4
4
|
export { applyPlugins, collectPluginCss, collectPluginStylePaths } from "./renderer";
|
|
@@ -7,7 +7,7 @@ export declare function __setVendorSnapshotHookForTests(hook?: (sourceRoot: stri
|
|
|
7
7
|
export declare function clearVendoredPluginResolver(baseDir: string, packageName: string, version: string): void;
|
|
8
8
|
/** Test-only: reset the path-plugin cache between test cases. */
|
|
9
9
|
export declare function __resetPathPluginCacheForTests(): void;
|
|
10
|
-
export declare function loadPlugin(config:
|
|
10
|
+
export declare function loadPlugin(config: ResolvedExtensionConfig, baseDir: string): Promise<LoadedPlugin>;
|
|
11
11
|
/**
|
|
12
12
|
* Load all plugins from the resolved configuration.
|
|
13
13
|
*
|
|
@@ -30,7 +30,7 @@ export declare function loadPlugin(config: ResolvedPluginConfig, baseDir: string
|
|
|
30
30
|
* unedited one is never re-imported, correct in both a one-shot CLI build and
|
|
31
31
|
* the long-lived Electron host.
|
|
32
32
|
*/
|
|
33
|
-
export declare function loadPlugins(configs:
|
|
33
|
+
export declare function loadPlugins(configs: ResolvedExtensionConfig[], baseDir: string, onError?: (pluginRef: string, error: Error) => void): Promise<LoadedPlugin[]>;
|
|
34
34
|
/** Result of {@link loadPluginsWithCss}: loaded plugins ready for `applyPlugins`
|
|
35
35
|
* plus their concatenated CSS ready for injection into the rendered document. */
|
|
36
36
|
export interface LoadedPluginsWithCss {
|
|
@@ -62,4 +62,4 @@ export interface LoadedPluginsWithCss {
|
|
|
62
62
|
* both call sites' prior behavior of never plugin-loading when the manifest
|
|
63
63
|
* declares no plugins.
|
|
64
64
|
*/
|
|
65
|
-
export declare function loadPluginsWithCss(configs:
|
|
65
|
+
export declare function loadPluginsWithCss(configs: ResolvedExtensionConfig[] | undefined | null, baseDir: string, onError?: (pluginRef: string, error: Error) => void): Promise<LoadedPluginsWithCss>;
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
* while hashing the original output path keeps repeat references deterministic.
|
|
33
33
|
*/
|
|
34
34
|
export declare function placeholderOutputPath(missingOutputPath: string): string;
|
|
35
|
+
/** Decode the small entity set that can occur inside an HTML URL attribute. */
|
|
36
|
+
export declare function decodeHtmlAttribute(value: string): string;
|
|
35
37
|
/**
|
|
36
38
|
* Rewrite missing local image URLs in rendered HTML to their real PNG paths.
|
|
37
39
|
*
|
|
@@ -43,6 +45,15 @@ export declare function placeholderOutputPath(missingOutputPath: string): string
|
|
|
43
45
|
* at the same staged PNG before `inlineShapeUrls()` reads and embeds it.
|
|
44
46
|
*/
|
|
45
47
|
export declare function rewriteMissingImageReferences(html: string, replacements: ReadonlyMap<string, string>): string;
|
|
48
|
+
/**
|
|
49
|
+
* Apply `rewriteTag` to every tag in the ACTIVE parts of rendered HTML.
|
|
50
|
+
* Comments and raw-text / literal-content elements (`<script>`, `<style>`,
|
|
51
|
+
* `<pre>`, `<code>`, `<textarea>`) are opaque to the tag pass — a prose
|
|
52
|
+
* example showing HTML must stay byte-for-byte authored. Each such region is
|
|
53
|
+
* handed whole to `rewriteProtected` with its element name (undefined for a
|
|
54
|
+
* comment), which keeps it unchanged unless the caller says otherwise.
|
|
55
|
+
*/
|
|
56
|
+
export declare function rewriteActiveHtml(html: string, rewriteTag: (tag: string) => string, rewriteProtected?: (region: string, element: string | undefined) => string): string;
|
|
46
57
|
/**
|
|
47
58
|
* Encode a checkerboard PNG of `width`×`height` at `cell` pixels per square.
|
|
48
59
|
* Truecolor (8-bit RGB, no alpha) with filter byte 0 per scanline — the
|
package/dist/lib/presets.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { ResolvedConfig } from "../schema/manifest.types";
|
|
|
8
8
|
* Every preset value is overridable from the manifest, leaf by leaf
|
|
9
9
|
* (resolveConfig's mergeShape; precedence cli > manifest > target > preset).
|
|
10
10
|
*/
|
|
11
|
-
export interface VendorPreset extends Omit<ResolvedConfig, "title" | "authors" | "targets" | "page"
|
|
11
|
+
export interface VendorPreset extends Omit<ResolvedConfig, "title" | "authors" | "targets" | "page"> {
|
|
12
12
|
/**
|
|
13
13
|
* Base page geometry in points, or `null` for `custom` — the one preset
|
|
14
14
|
* with no built-in trim, which therefore REQUIRES the manifest to supply
|
|
@@ -13,7 +13,7 @@ interface UploadSource {
|
|
|
13
13
|
* Package the HTML export directory into a single ZIP (D8: Drive is file
|
|
14
14
|
* delivery, not web hosting — no N-file folder mirroring). Built via
|
|
15
15
|
* `zipEntriesNonBlocking` (fflate is already a dependency, see
|
|
16
|
-
*
|
|
16
|
+
* extension-import.ts for the sibling unzip-side usage) so building the archive
|
|
17
17
|
* doesn't block the event loop, then written to a temp file so the existing
|
|
18
18
|
* file-based `resumableUpload` (google-drive.ts) can read it incrementally
|
|
19
19
|
* like any other artifact. Note this is true only of the UPLOAD step — the
|
package/dist/lib/snippets.d.ts
CHANGED
|
@@ -10,22 +10,19 @@ export declare const SNIPPETS_DIR = "snippets";
|
|
|
10
10
|
* gate those actions, so "can this be deleted" never drifts out of sync with
|
|
11
11
|
* "where did this come from" (one field, not two that could disagree).
|
|
12
12
|
*
|
|
13
|
-
* `{ kind: "
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* so that function can re-derive the extension's folder itself from a small,
|
|
22
|
-
* validated identifier instead of trusting a filesystem path a caller could
|
|
23
|
-
* construct.
|
|
13
|
+
* `{ kind: "extension", ref, name }` — a READ-ONLY snippet merged in from an
|
|
14
|
+
* installed, ENABLED extension (see {@link listInstalledExtensions}). `name`
|
|
15
|
+
* is the extension's display name — the picker's group label, so an author
|
|
16
|
+
* always sees WHICH extension a snippet came from, never just "not mine".
|
|
17
|
+
* `ref` is the extension's manifest specifier (`ProjectExtensionEntry.use`);
|
|
18
|
+
* it is round-tripped back into {@link readExtensionSnippet} so that function
|
|
19
|
+
* can re-derive the extension's folder itself from a small, validated
|
|
20
|
+
* identifier instead of trusting a filesystem path a caller could construct.
|
|
24
21
|
*/
|
|
25
22
|
export type SnippetSource = {
|
|
26
23
|
kind: "project";
|
|
27
24
|
} | {
|
|
28
|
-
kind: "
|
|
25
|
+
kind: "extension";
|
|
29
26
|
ref: string;
|
|
30
27
|
name: string;
|
|
31
28
|
};
|
|
@@ -144,12 +141,11 @@ export declare function listMergedSnippets(projectDir: string): Promise<SnippetE
|
|
|
144
141
|
* extended to a second, per-extension root instead of a single project one.
|
|
145
142
|
*
|
|
146
143
|
* Throws when `source` no longer resolves to an installed, active extension
|
|
147
|
-
* (it was disabled
|
|
148
|
-
* was fetched — the picker's existing `error` display already handles a
|
|
144
|
+
* (it was disabled or removed since the list was fetched — the picker's existing `error` display already handles a
|
|
149
145
|
* thrown read the same way a vanished project snippet would) or when
|
|
150
146
|
* `fileName` escapes that extension's snippets folder.
|
|
151
147
|
*/
|
|
152
148
|
export declare function readExtensionSnippet(projectDir: string, source: {
|
|
153
|
-
kind: "
|
|
149
|
+
kind: "extension";
|
|
154
150
|
ref: string;
|
|
155
151
|
}, fileName: string): Promise<string>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export interface ProjectStyle {
|
|
3
3
|
/** Absolute path to the `.css` file. */
|
|
4
4
|
path: string;
|
|
5
|
-
/** Project-relative, "/"-separated display name (e.g. `
|
|
5
|
+
/** Project-relative, "/"-separated display name (e.g. `styles/print.css`). */
|
|
6
6
|
displayName: string;
|
|
7
7
|
/** True when this stylesheet is in the manifest `styles:` list (the active set). */
|
|
8
8
|
active: boolean;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MANIFEST_FILENAMES,
|
|
3
3
|
runLint
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-8pg731p5.js";
|
|
5
5
|
import {
|
|
6
6
|
log
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-ypfvnhag.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError,
|
|
10
10
|
rejectExtraPositionals,
|
|
11
11
|
rejectUnknownFlags
|
|
12
|
-
} from "./cli-
|
|
13
|
-
import"./cli-
|
|
12
|
+
} from "./cli-rh05byck.js";
|
|
13
|
+
import"./cli-bx950tb4.js";
|
|
14
14
|
import"./cli-c41yr7he.js";
|
|
15
15
|
import {
|
|
16
16
|
EXIT_CODES
|
|
@@ -29,22 +29,6 @@
|
|
|
29
29
|
"enum": ["dtrpg", "book", "custom"],
|
|
30
30
|
"examples": ["dtrpg", "book", "custom"]
|
|
31
31
|
},
|
|
32
|
-
"engine": {
|
|
33
|
-
"type": "string",
|
|
34
|
-
"description": "Pagination engine. The Gutterpress engine (native Chromium pagination) is the only engine, and \"native\" is the only meaningful value. \"paged\" is accepted for backward-compatible manifest parsing only: it produces a one-line warning and the build proceeds natively regardless. `--engine` on the CLI is likewise an accepted-but-ignored no-op.",
|
|
35
|
-
"enum": ["paged", "native"],
|
|
36
|
-
"default": "native",
|
|
37
|
-
"examples": ["native"]
|
|
38
|
-
},
|
|
39
|
-
"engineStyles": {
|
|
40
|
-
"type": "object",
|
|
41
|
-
"description": "Engine-conditional stylesheets, appended AFTER `styles`. `.native` is the only list — the native engine is the only engine, so there is nothing else to condition on. A manifest from the dual-engine era may still carry `.paged`; it keeps loading (with a one-line warning) but is no longer part of this schema.",
|
|
42
|
-
"properties": {
|
|
43
|
-
"native": { "type": "array", "items": { "type": "string" } }
|
|
44
|
-
},
|
|
45
|
-
"additionalProperties": false,
|
|
46
|
-
"examples": [{ "native": ["css/native-furniture.css"] }]
|
|
47
|
-
},
|
|
48
32
|
"targets": {
|
|
49
33
|
"type": "array",
|
|
50
34
|
"description": "Where the book is published (ADR 0008): publish targets whose requirements `gutterpress validate` checks the built PDF against — each target is validated separately, so one book can target several destinations. Omitting it uses the preset's default (dtrpg -> [\"dtrpg\"]; book/custom -> []).",
|
|
@@ -65,42 +49,34 @@
|
|
|
65
49
|
["themes/parchment.css", "styles/override.css"]
|
|
66
50
|
]
|
|
67
51
|
},
|
|
68
|
-
"
|
|
52
|
+
"extensions": {
|
|
69
53
|
"type": "array",
|
|
70
|
-
"description": "markdown-it plugins
|
|
71
|
-
"default": [],
|
|
54
|
+
"description": "Extensions, in load order: markdown-it plugins, looks (stylesheets), component libraries — anything from npm or a folder. Each entry is a specifier: a bundled feature name (markdown-it-mark, markdown-it-sub, markdown-it-sup, markdown-it-abbr, gutterpress-gfm-alerts), a path starting with ./ or ../ (relative to this file), or an npm package name, optionally pinned as name@version. A later entry loads later: its markdown runs after earlier entries' and its CSS wins ties. The project's own `styles` always load after every extension.",
|
|
72
55
|
"items": {
|
|
73
56
|
"oneOf": [
|
|
74
57
|
{
|
|
75
58
|
"type": "string",
|
|
76
59
|
"minLength": 1,
|
|
77
|
-
"description": "
|
|
60
|
+
"description": "The specifier. Bundled names resolve to the copy compiled into Gutterpress; ./ and ../ are paths relative to this file; anything else is an npm package, name@version pins it.",
|
|
78
61
|
"examples": [
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
62
|
+
"markdown-it-footnote",
|
|
63
|
+
"@dimm-city/components@2.1.0",
|
|
64
|
+
"./extensions/house-style",
|
|
65
|
+
"../shared/dc-design-guide",
|
|
66
|
+
"markdown-it-mark"
|
|
82
67
|
]
|
|
83
68
|
},
|
|
84
69
|
{
|
|
85
70
|
"type": "object",
|
|
86
|
-
"description": "
|
|
71
|
+
"description": "The object form, for an entry that needs more than its specifier. `use` carries the same specifier the bare form would.",
|
|
72
|
+
"required": ["use"],
|
|
73
|
+
"additionalProperties": false,
|
|
87
74
|
"properties": {
|
|
88
|
-
"
|
|
75
|
+
"use": {
|
|
89
76
|
"type": "string",
|
|
90
77
|
"minLength": 1,
|
|
91
|
-
"description": "
|
|
92
|
-
"examples": ["
|
|
93
|
-
},
|
|
94
|
-
"name": {
|
|
95
|
-
"type": "string",
|
|
96
|
-
"minLength": 1,
|
|
97
|
-
"description": "npm package name of the plugin.",
|
|
98
|
-
"examples": ["gutterpress-plugin-callouts"]
|
|
99
|
-
},
|
|
100
|
-
"version": {
|
|
101
|
-
"type": "string",
|
|
102
|
-
"description": "Exact npm version installed under plugins/npm by Gutterpress. Legacy non-exact values remain informational and use legacy node_modules resolution.",
|
|
103
|
-
"examples": ["1.2.3", "2.1.0-beta.1"]
|
|
78
|
+
"description": "The specifier — exactly what the bare string form would be.",
|
|
79
|
+
"examples": ["markdown-it-attrs", "./extensions/house-style"]
|
|
104
80
|
},
|
|
105
81
|
"export": {
|
|
106
82
|
"type": "string",
|
|
@@ -108,15 +84,9 @@
|
|
|
108
84
|
"description": "Named module export to use as the markdown-it plugin function when the package has no default export.",
|
|
109
85
|
"examples": ["full"]
|
|
110
86
|
},
|
|
111
|
-
"priority": {
|
|
112
|
-
"type": "integer",
|
|
113
|
-
"description": "Advanced, rarely needed. Load order: higher loads first. If one of your plugins needs to see tokens another one of your plugins produces, give it the LOWER number of the two, so it loads (and runs) after.",
|
|
114
|
-
"default": 100,
|
|
115
|
-
"examples": [100, 200]
|
|
116
|
-
},
|
|
117
87
|
"options": {
|
|
118
88
|
"type": "object",
|
|
119
|
-
"description": "
|
|
89
|
+
"description": "Options passed straight through to the markdown-it plugin.",
|
|
120
90
|
"default": {},
|
|
121
91
|
"additionalProperties": true
|
|
122
92
|
},
|
|
@@ -130,11 +100,11 @@
|
|
|
130
100
|
]
|
|
131
101
|
},
|
|
132
102
|
"examples": [
|
|
133
|
-
["
|
|
103
|
+
["./extensions/house-style", "markdown-it-footnote"],
|
|
134
104
|
[
|
|
135
105
|
{
|
|
136
|
-
"
|
|
137
|
-
"
|
|
106
|
+
"use": "markdown-it-attrs",
|
|
107
|
+
"options": { "leftDelimiter": "[" }
|
|
138
108
|
}
|
|
139
109
|
]
|
|
140
110
|
]
|
|
@@ -554,11 +524,6 @@
|
|
|
554
524
|
}
|
|
555
525
|
}
|
|
556
526
|
}
|
|
557
|
-
},
|
|
558
|
-
"themePrevious": {
|
|
559
|
-
"type": "string",
|
|
560
|
-
"description": "Id of the theme active before the current one (the 'Revert to previous theme' target, #106). Managed automatically by Gutterpress; not authored by hand.",
|
|
561
|
-
"examples": ["clean-book", "zine"]
|
|
562
527
|
}
|
|
563
528
|
},
|
|
564
529
|
"examples": [
|
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
TARGET_IDS,
|
|
8
8
|
scaffoldExtension,
|
|
9
9
|
scaffoldProject
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-8pg731p5.js";
|
|
11
11
|
import {
|
|
12
12
|
resolveGhostscript
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-ypfvnhag.js";
|
|
14
14
|
import {
|
|
15
15
|
UsageError,
|
|
16
16
|
rejectExtraPositionals,
|
|
17
17
|
rejectUnknownFlags
|
|
18
|
-
} from "./cli-
|
|
19
|
-
import"./cli-
|
|
18
|
+
} from "./cli-rh05byck.js";
|
|
19
|
+
import"./cli-bx950tb4.js";
|
|
20
20
|
import {
|
|
21
21
|
isToolAvailable
|
|
22
22
|
} from "./cli-c41yr7he.js";
|
|
@@ -159,16 +159,15 @@ async function runExtensionScaffold(kind, name, parentDir, args) {
|
|
|
159
159
|
console.log("Next: check it still works —");
|
|
160
160
|
console.log(` cd ${result.slug} && bun install && bun test`);
|
|
161
161
|
console.log("");
|
|
162
|
-
console.log(" then
|
|
163
|
-
console.log(
|
|
164
|
-
console.log(` - path: plugins/${result.slug}`);
|
|
162
|
+
console.log(" then add it to a book:");
|
|
163
|
+
console.log(` gutterpress ext add ./${result.slug} <book>`);
|
|
165
164
|
console.log("");
|
|
166
|
-
console.log(" (
|
|
167
|
-
console.log("
|
|
165
|
+
console.log(" (that lists the FOLDER under `extensions:` in the book's manifest —");
|
|
166
|
+
console.log(" not plugin.js — which is what makes Gutterpress read gutterpress.json");
|
|
167
|
+
console.log(" and pick up the stylesheet too.)");
|
|
168
168
|
} else {
|
|
169
|
-
console.log("Next:
|
|
170
|
-
console.log(` gutterpress
|
|
171
|
-
console.log(` gutterpress theme apply ${result.slug} <book>`);
|
|
169
|
+
console.log("Next: add it to a book —");
|
|
170
|
+
console.log(` gutterpress ext add ${result.extensionDir} <book>`);
|
|
172
171
|
console.log("");
|
|
173
172
|
console.log(" Each stylesheet opens with the OWNS / MUST NOT CONTAIN header that");
|
|
174
173
|
console.log(" says which rules belong in it. Start with styles/tokens.css.");
|
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
executeValidation,
|
|
3
3
|
publishTargetFor,
|
|
4
4
|
reportMissingTools
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-8pg731p5.js";
|
|
6
6
|
import {
|
|
7
7
|
log
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-ypfvnhag.js";
|
|
9
9
|
import {
|
|
10
10
|
UsageError,
|
|
11
11
|
rejectExtraPositionals,
|
|
12
12
|
rejectUnknownFlags
|
|
13
|
-
} from "./cli-
|
|
14
|
-
import"./cli-
|
|
13
|
+
} from "./cli-rh05byck.js";
|
|
14
|
+
import"./cli-bx950tb4.js";
|
|
15
15
|
import"./cli-c41yr7he.js";
|
|
16
16
|
import {
|
|
17
17
|
EXIT_CODES
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type FSWatcher } from 'chokidar';
|
|
8
8
|
import type { ServerState } from './server-context';
|
|
9
|
-
import type {
|
|
9
|
+
import type { ResolvedExtensionConfig } from '../schema/manifest.types';
|
|
10
10
|
/**
|
|
11
11
|
* Whether the incremental preview shell is active. The historical env name is
|
|
12
12
|
* retained because users may already set it. A single Markdown edit paginates
|
|
@@ -50,7 +50,7 @@ export declare function generateAndWriteHtml(inputPath: string, tempDir: string,
|
|
|
50
50
|
source?: {
|
|
51
51
|
files?: string[] | null;
|
|
52
52
|
};
|
|
53
|
-
|
|
53
|
+
extensions?: ResolvedExtensionConfig[];
|
|
54
54
|
}, cssAssets: Map<string, string>): Promise<void>;
|
|
55
55
|
/**
|
|
56
56
|
* Render one source file with the same CSS, plugins, source metadata, and
|
|
@@ -60,7 +60,7 @@ export declare function generateAndWriteHtml(inputPath: string, tempDir: string,
|
|
|
60
60
|
export declare function renderChapterPreviewHtml(inputPath: string, file: string, config: {
|
|
61
61
|
title?: string;
|
|
62
62
|
styles?: string[];
|
|
63
|
-
|
|
63
|
+
extensions?: ResolvedExtensionConfig[];
|
|
64
64
|
}): Promise<string>;
|
|
65
65
|
/** One changed project file, named for the preview broadcast decision. */
|
|
66
66
|
export interface ChangedFile {
|
|
@@ -154,7 +154,7 @@ export declare function externalWatchRoots(targets: Iterable<string>): Promise<s
|
|
|
154
154
|
*/
|
|
155
155
|
export declare function externalWatchTargets(projectDir: string, config: {
|
|
156
156
|
styles?: string[];
|
|
157
|
-
|
|
157
|
+
extensions?: ResolvedExtensionConfig[];
|
|
158
158
|
}): Promise<string[]>;
|
|
159
159
|
/**
|
|
160
160
|
* Create and configure a file watcher for the project's input directory plus
|
|
@@ -42,7 +42,7 @@ export declare function validateInputPath(inputPath: string): Promise<void>;
|
|
|
42
42
|
* For empty input (no-input mode), skip manifest loading entirely and
|
|
43
43
|
* return a default resolved config.
|
|
44
44
|
*/
|
|
45
|
-
export declare function initializeConfiguration(inputPath: string
|
|
45
|
+
export declare function initializeConfiguration(inputPath: string): Promise<ResolvedConfig>;
|
|
46
46
|
/**
|
|
47
47
|
* Restart the preview server with a new input directory.
|
|
48
48
|
*
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
previewArgs
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-bzxqtvrk.js";
|
|
4
4
|
import {
|
|
5
5
|
openPath,
|
|
6
6
|
runBuild,
|
|
7
7
|
splitOutPath,
|
|
8
8
|
startPreviewServer
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-8pg731p5.js";
|
|
10
10
|
import {
|
|
11
11
|
log
|
|
12
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-ypfvnhag.js";
|
|
13
13
|
import {
|
|
14
14
|
UsageError,
|
|
15
|
-
parseEngine,
|
|
16
15
|
parseFormat,
|
|
17
16
|
parsePdfxFlavor,
|
|
18
17
|
rejectExtraPositionals,
|
|
19
18
|
rejectUnknownFlags,
|
|
20
19
|
resolvePort
|
|
21
|
-
} from "./cli-
|
|
22
|
-
import"./cli-
|
|
20
|
+
} from "./cli-rh05byck.js";
|
|
21
|
+
import"./cli-bx950tb4.js";
|
|
23
22
|
import"./cli-c41yr7he.js";
|
|
24
23
|
import {
|
|
25
24
|
BuildError
|
|
@@ -48,7 +47,6 @@ var preview_default = defineCommand({
|
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
const openFlag = args.open;
|
|
51
|
-
const engine = parseEngine(args.engine);
|
|
52
50
|
if (format === "html") {
|
|
53
51
|
if (typeof args.manifest === "string") {
|
|
54
52
|
throw new UsageError("--manifest is only supported by preview --format pdf or pdfx; live HTML preview discovers the project manifest from its input directory.");
|
|
@@ -60,8 +58,7 @@ var preview_default = defineCommand({
|
|
|
60
58
|
noWatch: args.watch === false,
|
|
61
59
|
verbose: !!args.verbose,
|
|
62
60
|
openBrowser: openFlag,
|
|
63
|
-
debug: !!args.debug
|
|
64
|
-
engine
|
|
61
|
+
debug: !!args.debug
|
|
65
62
|
});
|
|
66
63
|
return;
|
|
67
64
|
}
|
|
@@ -83,7 +80,6 @@ var preview_default = defineCommand({
|
|
|
83
80
|
skipPreValidate: !!args["skip-pre-validate"],
|
|
84
81
|
skipPostValidate: !!args["skip-post-validate"],
|
|
85
82
|
allowShrink: !!args["allow-shrink"],
|
|
86
|
-
engine,
|
|
87
83
|
rawArgs: args
|
|
88
84
|
});
|
|
89
85
|
if (openFlag && result.pdfPath) {
|