@wizzlethorpe/vaults 0.6.1 → 0.7.1
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 +135 -17
- package/dist/build.js +501 -190
- package/dist/build.js.map +1 -1
- package/dist/commands/build.js +4 -4
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/init.js +13 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/password.js +3 -1
- package/dist/commands/password.js.map +1 -1
- package/dist/commands/patreon.js +30 -20
- package/dist/commands/patreon.js.map +1 -1
- package/dist/commands/preview.js +10 -8
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/push.js +11 -9
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/role.js +5 -0
- package/dist/commands/role.js.map +1 -1
- package/dist/config.js +30 -15
- package/dist/config.js.map +1 -1
- package/dist/escape.js +29 -0
- package/dist/escape.js.map +1 -0
- package/dist/favicon.js +3 -36
- package/dist/favicon.js.map +1 -1
- package/dist/foundry-importer.js +61 -0
- package/dist/foundry-importer.js.map +1 -0
- package/dist/images.js +0 -30
- package/dist/images.js.map +1 -1
- package/dist/index.js +37 -4
- package/dist/index.js.map +1 -1
- package/dist/migrate/0.6-legacy-auth-settings.js +96 -0
- package/dist/migrate/0.6-legacy-auth-settings.js.map +1 -0
- package/dist/migrate/0.7-vaults-dir.js +74 -0
- package/dist/migrate/0.7-vaults-dir.js.map +1 -0
- package/dist/migrate/registry.js +6 -0
- package/dist/migrate/registry.js.map +1 -0
- package/dist/migrate/run.js +38 -0
- package/dist/migrate/run.js.map +1 -0
- package/dist/migrate/types.js +8 -0
- package/dist/migrate/types.js.map +1 -0
- package/dist/paths.js +66 -0
- package/dist/paths.js.map +1 -0
- package/dist/render/auth-template.js +23 -141
- package/dist/render/auth-template.js.map +1 -1
- package/dist/render/bases.js +56 -44
- package/dist/render/bases.js.map +1 -1
- package/dist/render/callouts.js +29 -10
- package/dist/render/callouts.js.map +1 -1
- package/dist/render/embed.js +124 -26
- package/dist/render/embed.js.map +1 -1
- package/dist/render/extensions.js +68 -0
- package/dist/render/extensions.js.map +1 -0
- package/dist/render/external-links.js +32 -0
- package/dist/render/external-links.js.map +1 -0
- package/dist/render/footer.js +37 -0
- package/dist/render/footer.js.map +1 -0
- package/dist/render/frontmatter.js +17 -0
- package/dist/render/frontmatter.js.map +1 -0
- package/dist/render/handlers/assets.js +123 -0
- package/dist/render/handlers/assets.js.map +1 -0
- package/dist/render/handlers/builtin/battlemap.js +199 -0
- package/dist/render/handlers/builtin/battlemap.js.map +1 -0
- package/dist/render/handlers/builtin/dice.js +78 -0
- package/dist/render/handlers/builtin/dice.js.map +1 -0
- package/dist/render/handlers/builtin/fm-code.js +50 -0
- package/dist/render/handlers/builtin/fm-code.js.map +1 -0
- package/dist/render/handlers/builtin/fm.js +83 -0
- package/dist/render/handlers/builtin/fm.js.map +1 -0
- package/dist/render/handlers/builtin/index.js +13 -0
- package/dist/render/handlers/builtin/index.js.map +1 -0
- package/dist/render/handlers/builtin/inline-format.js +26 -0
- package/dist/render/handlers/builtin/inline-format.js.map +1 -0
- package/dist/render/handlers/builtin/statblock.js +491 -0
- package/dist/render/handlers/builtin/statblock.js.map +1 -0
- package/dist/render/handlers/dispatch.js +182 -0
- package/dist/render/handlers/dispatch.js.map +1 -0
- package/dist/render/handlers/loader.js +90 -0
- package/dist/render/handlers/loader.js.map +1 -0
- package/dist/render/handlers/types.js +60 -0
- package/dist/render/handlers/types.js.map +1 -0
- package/dist/render/image-srcs.js +42 -0
- package/dist/render/image-srcs.js.map +1 -0
- package/dist/render/layout.js +62 -9
- package/dist/render/layout.js.map +1 -1
- package/dist/render/pipeline.js +38 -9
- package/dist/render/pipeline.js.map +1 -1
- package/dist/render/preview.js +53 -18
- package/dist/render/preview.js.map +1 -1
- package/dist/render/slug.js +5 -0
- package/dist/render/slug.js.map +1 -1
- package/dist/render/styles.js +124 -15
- package/dist/render/styles.js.map +1 -1
- package/dist/render/wikilink.js +15 -4
- package/dist/render/wikilink.js.map +1 -1
- package/dist/scan.js +1 -1
- package/dist/scan.js.map +1 -1
- package/dist/settings.js +25 -4
- package/dist/settings.js.map +1 -1
- package/dist/version.js +36 -0
- package/dist/version.js.map +1 -0
- package/package.json +12 -12
- package/dist/api.js +0 -42
- package/dist/api.js.map +0 -1
- package/dist/render/mcp-template.js +0 -239
- package/dist/render/mcp-template.js.map +0 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// Unified plugin that runs registered handlers over the markdown AST.
|
|
2
|
+
// Inline-code `prefix: …` and fenced code ```lang … ``` blocks are
|
|
3
|
+
// dispatched to the matching InlineHandler / CodeBlockHandler. Handler
|
|
4
|
+
// output is re-parsed (or wrapped as raw HTML) so downstream wikilink /
|
|
5
|
+
// embed passes still see it. Handler-emitted markdown is recursively
|
|
6
|
+
// dispatched, bounded by MAX_DEPTH.
|
|
7
|
+
import { unified } from "unified";
|
|
8
|
+
import remarkParse from "remark-parse";
|
|
9
|
+
import remarkGfm from "remark-gfm";
|
|
10
|
+
/** Cap on handler-emits-handler recursion. Realistically nothing legitimate nests this deep. */
|
|
11
|
+
const MAX_DEPTH = 10;
|
|
12
|
+
/**
|
|
13
|
+
* Pattern for an inline-handler invocation inside arbitrary text:
|
|
14
|
+
* `` `prefix: content` ``. `prefix` matches the InlineHandler discriminator
|
|
15
|
+
* shape (lowercase letter then word chars / dashes). A fresh RegExp is
|
|
16
|
+
* built per call (rather than module-level) because /g + recursion +
|
|
17
|
+
* shared regex state is a hang waiting to happen.
|
|
18
|
+
*/
|
|
19
|
+
const INLINE_HANDLER_PATTERN = "`([a-z][\\w-]*):\\s*([^`]*)`";
|
|
20
|
+
/**
|
|
21
|
+
* Substitute inline-handler matches in a plain string with their HTML
|
|
22
|
+
* output. Bounded by MAX_DEPTH so a handler whose HTML output happens to
|
|
23
|
+
* contain another `` `prefix: …` `` pattern still terminates.
|
|
24
|
+
*/
|
|
25
|
+
async function applyInlineHandlersImpl(text, registry, ctx, depth) {
|
|
26
|
+
if (depth > MAX_DEPTH)
|
|
27
|
+
return text;
|
|
28
|
+
const re = new RegExp(INLINE_HANDLER_PATTERN, "g");
|
|
29
|
+
let out = "";
|
|
30
|
+
let last = 0;
|
|
31
|
+
let m;
|
|
32
|
+
while ((m = re.exec(text)) !== null) {
|
|
33
|
+
const prefix = m[1];
|
|
34
|
+
const content = (m[2] ?? "").trim();
|
|
35
|
+
const handler = registry.inline.get(prefix);
|
|
36
|
+
if (!handler)
|
|
37
|
+
continue;
|
|
38
|
+
const result = await handler.render(content, ctx);
|
|
39
|
+
if ("markdown" in result) {
|
|
40
|
+
// Markdown output can't be safely spliced into a non-markdown context
|
|
41
|
+
// without re-running the full pipeline. Skip; the original text stays.
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
out += text.slice(last, m.index);
|
|
45
|
+
out += await applyInlineHandlersImpl(result.html, registry, ctx, depth + 1);
|
|
46
|
+
last = m.index + m[0].length;
|
|
47
|
+
}
|
|
48
|
+
out += text.slice(last);
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Single sub-parser instance reused across every handler that returns
|
|
53
|
+
* markdown. Hoisted so the .use() chain isn't rebuilt per call.
|
|
54
|
+
*/
|
|
55
|
+
const SUB_PARSER = unified().use(remarkParse).use(remarkGfm);
|
|
56
|
+
function asHtmlNode(html) {
|
|
57
|
+
return { type: "html", value: html };
|
|
58
|
+
}
|
|
59
|
+
/** Parse a markdown string into a list of mdast block-level children. */
|
|
60
|
+
function parseMarkdownBlocks(source) {
|
|
61
|
+
return SUB_PARSER.parse(source).children;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Parse a markdown string and pull out its inline (phrasing) content. Drops
|
|
65
|
+
* the surrounding paragraph wrapper so the inline content can be spliced
|
|
66
|
+
* into a phrasing context.
|
|
67
|
+
*/
|
|
68
|
+
function parseMarkdownInline(source) {
|
|
69
|
+
const blocks = parseMarkdownBlocks(source);
|
|
70
|
+
const out = [];
|
|
71
|
+
for (const block of blocks) {
|
|
72
|
+
if (block.type === "paragraph") {
|
|
73
|
+
out.push(...block.children);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Block-level output in an inline context: drop. A handler author who
|
|
77
|
+
// needs block flow should use a code-block handler, not an inline one.
|
|
78
|
+
// Empty html node keeps the document well-formed.
|
|
79
|
+
out.push(asHtmlNode(""));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function outputToBlock(out) {
|
|
85
|
+
if ("markdown" in out)
|
|
86
|
+
return parseMarkdownBlocks(out.markdown);
|
|
87
|
+
return [asHtmlNode(out.html)];
|
|
88
|
+
}
|
|
89
|
+
function outputToInline(out) {
|
|
90
|
+
if ("markdown" in out)
|
|
91
|
+
return parseMarkdownInline(out.markdown);
|
|
92
|
+
return [asHtmlNode(out.html)];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Walk the AST forward, applying any matching handler to each inline-code
|
|
96
|
+
* and code node. After a substitution, the replacements get re-walked at
|
|
97
|
+
* depth+1 — this handles both:
|
|
98
|
+
* (a) **vertical** recursion: a paragraph the handler emitted contains
|
|
99
|
+
* further handler-eligible inline nodes (e.g., a `dice:` inside a
|
|
100
|
+
* custom code-block's emitted markdown).
|
|
101
|
+
* (b) **horizontal** recursion: the replacement is itself directly
|
|
102
|
+
* handler-eligible (e.g., a `loop:` handler emitting another
|
|
103
|
+
* `loop:`). Bounded by MAX_DEPTH so a self-emitting handler can't
|
|
104
|
+
* loop forever.
|
|
105
|
+
*/
|
|
106
|
+
async function walkAndSubstitute(parent, registry, context, depth) {
|
|
107
|
+
if (depth > MAX_DEPTH) {
|
|
108
|
+
console.warn(` handlers: recursion depth ${depth} exceeded; stopping`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
let i = 0;
|
|
112
|
+
while (i < parent.children.length) {
|
|
113
|
+
const node = parent.children[i];
|
|
114
|
+
const replacements = await dispatchOne(node, registry, context);
|
|
115
|
+
if (replacements !== null) {
|
|
116
|
+
parent.children.splice(i, 1, ...replacements);
|
|
117
|
+
// Wrap the replacement slice and re-walk it at depth+1. The nested
|
|
118
|
+
// walk handles both horizontal and vertical recursion for the new
|
|
119
|
+
// content. Splice back the (possibly further-substituted) result.
|
|
120
|
+
const synth = { children: parent.children.slice(i, i + replacements.length) };
|
|
121
|
+
await walkAndSubstitute(synth, registry, context, depth + 1);
|
|
122
|
+
parent.children.splice(i, replacements.length, ...synth.children);
|
|
123
|
+
i += synth.children.length;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(node.children)) {
|
|
127
|
+
await walkAndSubstitute(node, registry, context, depth + 1);
|
|
128
|
+
}
|
|
129
|
+
i += 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Returns the replacement nodes for `node` if a handler matched, else null.
|
|
134
|
+
* Inline-code nodes return PhrasingContent[]; code nodes return RootContent[].
|
|
135
|
+
* The caller is responsible for splicing into the right parent.
|
|
136
|
+
*/
|
|
137
|
+
async function dispatchOne(node, registry, context) {
|
|
138
|
+
if (node?.type === "inlineCode") {
|
|
139
|
+
const value = node.value;
|
|
140
|
+
const colon = value.indexOf(":");
|
|
141
|
+
if (colon < 1)
|
|
142
|
+
return null;
|
|
143
|
+
const prefix = value.slice(0, colon).trim();
|
|
144
|
+
const handler = registry.inline.get(prefix);
|
|
145
|
+
if (!handler)
|
|
146
|
+
return null;
|
|
147
|
+
const content = value.slice(colon + 1).trim();
|
|
148
|
+
// Inline handlers never see a code-block meta string. Spread to a fresh
|
|
149
|
+
// context so a handler that mutates ctx (it shouldn't, but) can't leak
|
|
150
|
+
// state across dispatches.
|
|
151
|
+
return outputToInline(await handler.render(content, { ...context, codeBlockMeta: "" }));
|
|
152
|
+
}
|
|
153
|
+
if (node?.type === "code") {
|
|
154
|
+
const lang = (node.lang ?? "").trim();
|
|
155
|
+
if (!lang)
|
|
156
|
+
return null;
|
|
157
|
+
const handler = registry.codeBlock.get(lang);
|
|
158
|
+
if (!handler)
|
|
159
|
+
return null;
|
|
160
|
+
// node.meta is whatever follows the lang on the fence — `lang foo bar`.
|
|
161
|
+
// Pass it through so handlers like `fm` can use it as a language hint
|
|
162
|
+
// for the rendered <pre><code class="language-…">.
|
|
163
|
+
const meta = (node.meta ?? "").trim();
|
|
164
|
+
return outputToBlock(await handler.render(node.value, { ...context, codeBlockMeta: meta }));
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
export function handlersPlugin(opts) {
|
|
169
|
+
const { registry, context: baseContext } = opts;
|
|
170
|
+
// Build the full HandlerContext once, with applyInlineHandlers closing
|
|
171
|
+
// over the registry. Self-reference goes through the resulting context
|
|
172
|
+
// so handler authors who chain calls see the same object.
|
|
173
|
+
const context = {
|
|
174
|
+
...baseContext,
|
|
175
|
+
applyInlineHandlers: (text) => applyInlineHandlersImpl(text, registry, context, 0),
|
|
176
|
+
codeBlockMeta: "",
|
|
177
|
+
};
|
|
178
|
+
return () => async (tree) => {
|
|
179
|
+
await walkAndSubstitute(tree, registry, context, 0);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../../src/render/handlers/dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Discover and load custom handlers from a vault's `.vaults/handlers/`
|
|
2
|
+
// directory. Each handler file is dynamically imported; it must export a
|
|
3
|
+
// `handler` (single Handler) or `handlers` (Handler[]) named export.
|
|
4
|
+
//
|
|
5
|
+
// Returns the absolute on-disk path each handler was loaded from. The path
|
|
6
|
+
// is the anchor for resolving asset paths declared on the handler (see
|
|
7
|
+
// HandlerAssets in types.ts).
|
|
8
|
+
//
|
|
9
|
+
// Trust model: handlers are loaded and executed verbatim. Anyone running
|
|
10
|
+
// `vaults push` is trusting the vault's contents. Same trust model as
|
|
11
|
+
// `npm install` for any project they choose to build.
|
|
12
|
+
import { readdir, stat } from "node:fs/promises";
|
|
13
|
+
import { join, resolve } from "node:path";
|
|
14
|
+
import { pathToFileURL } from "node:url";
|
|
15
|
+
const HANDLER_DIR = ".vaults/handlers";
|
|
16
|
+
// Handler modules are `.mjs` (Node ESM). `.js` files in the same directory
|
|
17
|
+
// are treated as browser-side runtime assets and skipped by the loader —
|
|
18
|
+
// they get picked up via the `assets.scripts` declaration on a handler.
|
|
19
|
+
const SUPPORTED_EXTENSIONS = [".mjs"];
|
|
20
|
+
/**
|
|
21
|
+
* Returns user-defined handlers discovered in `<vaultPath>/.vaults/handlers/`.
|
|
22
|
+
* Returns an empty array if the directory doesn't exist; this is the common
|
|
23
|
+
* case (most vaults won't ship handlers).
|
|
24
|
+
*
|
|
25
|
+
* Each handler module's named exports are inspected:
|
|
26
|
+
* - `handler` (single Handler) is registered as one handler.
|
|
27
|
+
* - `handlers` (Handler[]) is spread into the result.
|
|
28
|
+
*
|
|
29
|
+
* Modules that throw on import or that export neither name produce a
|
|
30
|
+
* warning but do not abort the build.
|
|
31
|
+
*/
|
|
32
|
+
export async function loadUserHandlers(vaultPath) {
|
|
33
|
+
const dir = join(vaultPath, HANDLER_DIR);
|
|
34
|
+
let entries;
|
|
35
|
+
try {
|
|
36
|
+
entries = await readdir(dir);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err.code === "ENOENT")
|
|
40
|
+
return [];
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
const results = [];
|
|
44
|
+
for (const name of entries.sort()) {
|
|
45
|
+
if (!SUPPORTED_EXTENSIONS.some((ext) => name.endsWith(ext)))
|
|
46
|
+
continue;
|
|
47
|
+
const path = resolve(dir, name);
|
|
48
|
+
let info;
|
|
49
|
+
try {
|
|
50
|
+
info = await stat(path);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (!info.isFile())
|
|
56
|
+
continue;
|
|
57
|
+
const url = pathToFileURL(path).href;
|
|
58
|
+
let mod;
|
|
59
|
+
try {
|
|
60
|
+
mod = await import(url);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.warn(` handlers: failed to import ${name}: ${err.message}`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const single = mod.handler;
|
|
67
|
+
const many = mod.handlers;
|
|
68
|
+
if (Array.isArray(many)) {
|
|
69
|
+
for (const h of many) {
|
|
70
|
+
if (isHandlerLike(h))
|
|
71
|
+
results.push({ handler: h, sourcePath: path });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (isHandlerLike(single))
|
|
75
|
+
results.push({ handler: single, sourcePath: path });
|
|
76
|
+
if (single == null && !Array.isArray(many)) {
|
|
77
|
+
console.warn(` handlers: ${name} exports neither 'handler' nor 'handlers'; skipped`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return results;
|
|
81
|
+
}
|
|
82
|
+
function isHandlerLike(v) {
|
|
83
|
+
if (!v || typeof v !== "object")
|
|
84
|
+
return false;
|
|
85
|
+
const o = v;
|
|
86
|
+
if (typeof o.render !== "function")
|
|
87
|
+
return false;
|
|
88
|
+
return typeof o.inline === "string" || typeof o.codeBlock === "string";
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/render/handlers/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Handler API for custom inline / code-block transforms.
|
|
2
|
+
//
|
|
3
|
+
// Vault authors drop `.vaults/handlers/<name>.{js,mjs}` files into their
|
|
4
|
+
// vault. Each file exports `handler` (or `handlers: Handler[]`) and the
|
|
5
|
+
// loader registers them alongside vaults-cli's built-in handlers.
|
|
6
|
+
//
|
|
7
|
+
// At render time, the dispatch plugin (handlers/dispatch.ts) walks the
|
|
8
|
+
// markdown AST. For each inline-code node `` `prefix: …` `` it looks up an
|
|
9
|
+
// InlineHandler keyed on `prefix`. For each fenced ``` ```lang ``` block it
|
|
10
|
+
// looks up a CodeBlockHandler keyed on `lang`. The handler's `render()` is
|
|
11
|
+
// called with the content and a HandlerContext, and the returned markdown
|
|
12
|
+
// or HTML replaces the matched node in the AST. Handlers may also ship
|
|
13
|
+
// `assets.{styles,scripts}` to opt their generated markup into runtime
|
|
14
|
+
// CSS / JS bundles.
|
|
15
|
+
/**
|
|
16
|
+
* Build the dispatch registry from built-in + user handlers. User handlers
|
|
17
|
+
* register after built-ins so they win on prefix/lang collision (documented
|
|
18
|
+
* "user override" semantics) — but a *silent* override is a footgun: the
|
|
19
|
+
* built-in's contract may change between CLI versions and the user's
|
|
20
|
+
* shadowing handler keeps an old shape, breaking quietly. Surface every
|
|
21
|
+
* shadow at registration time with a console.warn so the override is at
|
|
22
|
+
* least visible in build logs.
|
|
23
|
+
*
|
|
24
|
+
* Pass user handlers as `[]` if there are none — callers shouldn't need to
|
|
25
|
+
* gate on emptiness.
|
|
26
|
+
*/
|
|
27
|
+
export function buildRegistry(builtin, user = []) {
|
|
28
|
+
const inline = new Map();
|
|
29
|
+
const codeBlock = new Map();
|
|
30
|
+
const builtinInlineIds = new Set();
|
|
31
|
+
const builtinCodeBlockIds = new Set();
|
|
32
|
+
for (const h of builtin) {
|
|
33
|
+
if ("inline" in h) {
|
|
34
|
+
inline.set(h.inline, h);
|
|
35
|
+
builtinInlineIds.add(h.inline);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
codeBlock.set(h.codeBlock, h);
|
|
39
|
+
builtinCodeBlockIds.add(h.codeBlock);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
for (const h of user) {
|
|
43
|
+
if ("inline" in h) {
|
|
44
|
+
if (builtinInlineIds.has(h.inline)) {
|
|
45
|
+
console.warn(`handlers: user inline handler 'inline: "${h.inline}"' shadows the built-in `
|
|
46
|
+
+ `with the same prefix. Override is intentional? OK; otherwise rename the user handler.`);
|
|
47
|
+
}
|
|
48
|
+
inline.set(h.inline, h);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (builtinCodeBlockIds.has(h.codeBlock)) {
|
|
52
|
+
console.warn(`handlers: user code-block handler 'codeBlock: "${h.codeBlock}"' shadows the built-in `
|
|
53
|
+
+ `with the same lang tag. Override is intentional? OK; otherwise rename the user handler.`);
|
|
54
|
+
}
|
|
55
|
+
codeBlock.set(h.codeBlock, h);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { inline, codeBlock };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/render/handlers/types.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,uEAAuE;AACvE,oBAAoB;AA8FpB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,OAAkB,EAAE,OAAkB,EAAE;IACpE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;IACtD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE9C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACxB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAC9B,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CACV,2CAA2C,CAAC,CAAC,MAAM,0BAA0B;sBAC3E,uFAAuF,CAC1F,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,OAAO,CAAC,IAAI,CACV,kDAAkD,CAAC,CAAC,SAAS,0BAA0B;sBACrF,yFAAyF,CAC5F,CAAC;YACJ,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Normalise plain markdown image URLs (``) to the
|
|
2
|
+
// absolute, slugified URL the build emits for that image. Without this the
|
|
3
|
+
// `<img src>` keeps the author's relative path verbatim — fine in a browser
|
|
4
|
+
// loading the page from `/Features/Images.html` (which resolves
|
|
5
|
+
// `../attachments/foo.webp` correctly), but broken anywhere else that loads
|
|
6
|
+
// the rendered HTML out of context: most notably the Foundry module's
|
|
7
|
+
// journal-page sheet, which runs from `/game` and ends up pointing at
|
|
8
|
+
// `/attachments/foo.webp` as if it lived at the world root.
|
|
9
|
+
//
|
|
10
|
+
// Wikilink-style image embeds (`![[foo.webp]]`) already resolve through the
|
|
11
|
+
// embed plugin, which writes the absolute URL directly. This plugin is the
|
|
12
|
+
// matching pass for the standard markdown form.
|
|
13
|
+
//
|
|
14
|
+
// External URLs (`https://`, `data:`) and references to images we didn't
|
|
15
|
+
// build are left untouched so the author can still link out or surface
|
|
16
|
+
// missing-image cases through the normal warning flow downstream.
|
|
17
|
+
import { visit } from "unist-util-visit";
|
|
18
|
+
import { slugify } from "./slug.js";
|
|
19
|
+
import { IMAGE_EXT_RE } from "./extensions.js";
|
|
20
|
+
export function imageSrcsPlugin(opts) {
|
|
21
|
+
const { context } = opts;
|
|
22
|
+
return () => (tree) => {
|
|
23
|
+
visit(tree, "image", (node) => {
|
|
24
|
+
const url = node.url;
|
|
25
|
+
if (!url)
|
|
26
|
+
return;
|
|
27
|
+
if (/^(https?:|data:|blob:|mailto:|#)/i.test(url))
|
|
28
|
+
return;
|
|
29
|
+
if (url.startsWith("/"))
|
|
30
|
+
return;
|
|
31
|
+
const basename = url.split("/").pop().split("#")[0].split("?")[0];
|
|
32
|
+
if (!IMAGE_EXT_RE.test(basename))
|
|
33
|
+
return;
|
|
34
|
+
const slug = slugify(decodeURIComponent(basename));
|
|
35
|
+
const entry = context.images.get(slug);
|
|
36
|
+
if (!entry)
|
|
37
|
+
return;
|
|
38
|
+
node.url = "/" + entry.outputPath.split("/").map(encodeURIComponent).join("/");
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=image-srcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-srcs.js","sourceRoot":"","sources":["../../src/render/image-srcs.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,gEAAgE;AAChE,4EAA4E;AAC5E,sEAAsE;AACtE,sEAAsE;AACtE,4DAA4D;AAC5D,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,gDAAgD;AAChD,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,kEAAkE;AAIlE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,UAAU,eAAe,CAAC,IAAgC;IAC9D,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,OAAO,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;QACpB,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,IAAW,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;YACrB,IAAI,CAAC,GAAG;gBAAE,OAAO;YACjB,IAAI,mCAAmC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAO;YAC1D,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO;YAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YACrE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,OAAO;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/render/layout.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { htmlEscape as esc, htmlAttr as attr } from "../escape.js";
|
|
1
2
|
/**
|
|
2
3
|
* Standalone 404 page using the same shell as a regular article (sidebar,
|
|
3
4
|
* search, sitemap), so a missing page still leaves the reader inside the
|
|
@@ -19,7 +20,7 @@ export function renderLayout(input) {
|
|
|
19
20
|
const breadcrumbs = renderBreadcrumbs(input.pagePath, input.vaultName);
|
|
20
21
|
const sitemap = renderSitemap(input.pages, input.pagePath);
|
|
21
22
|
return `<!doctype html>
|
|
22
|
-
<html lang="en">
|
|
23
|
+
<html lang="en" data-theme="${attr(input.theme)}">
|
|
23
24
|
<head>
|
|
24
25
|
<meta charset="utf-8">
|
|
25
26
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
@@ -27,7 +28,9 @@ export function renderLayout(input) {
|
|
|
27
28
|
<link rel="icon" href="/favicon.ico">
|
|
28
29
|
<link rel="stylesheet" href="/styles.css">
|
|
29
30
|
<link rel="stylesheet" href="/user.css">
|
|
31
|
+
${input.hasHandlerCss ? `<link rel="stylesheet" href="/_handlers.css">` : ""}${input.hasHandlerJs ? `\n<script src="/_handlers.js" defer></script>` : ""}
|
|
30
32
|
${renderSocialMeta(input)}
|
|
33
|
+
${THEME_BOOT_SCRIPT}
|
|
31
34
|
</head>
|
|
32
35
|
<body${input.centerImages ? ` class="center-images"` : ""}${input.defaultImageWidth ? ` style="--default-img-width: ${attr(input.defaultImageWidth)}"` : ""}>
|
|
33
36
|
<div class="app-grid">
|
|
@@ -37,7 +40,12 @@ ${renderSocialMeta(input)}
|
|
|
37
40
|
<input id="vault-search" type="search" placeholder="Search…" aria-label="Search vault" autocomplete="off">
|
|
38
41
|
<div class="search-results" role="listbox"></div>
|
|
39
42
|
</div>
|
|
40
|
-
|
|
43
|
+
<div class="sidebar-row">
|
|
44
|
+
<button id="theme-toggle" type="button" class="theme-toggle" aria-label="Toggle dark mode" title="Toggle dark mode">
|
|
45
|
+
<span class="theme-toggle-icon" aria-hidden="true"></span>
|
|
46
|
+
</button>
|
|
47
|
+
${input.authConfigured ? '<div class="auth-box" id="vault-auth"></div>' : ''}
|
|
48
|
+
</div>
|
|
41
49
|
${sitemap}
|
|
42
50
|
</aside>
|
|
43
51
|
<main>
|
|
@@ -47,6 +55,7 @@ ${renderSocialMeta(input)}
|
|
|
47
55
|
${input.bodyHtml}
|
|
48
56
|
${renderMeta(input.mtime, input.birthtime)}
|
|
49
57
|
</article>
|
|
58
|
+
${input.footerHtml ? `<footer class="site-footer">${input.footerHtml}</footer>` : ""}
|
|
50
59
|
</main>
|
|
51
60
|
<aside class="rightbar">
|
|
52
61
|
<details class="toc" open>
|
|
@@ -62,6 +71,7 @@ ${TOC_SCRIPT}
|
|
|
62
71
|
${SEARCH_SCRIPT}
|
|
63
72
|
${LIGHTBOX_SCRIPT}
|
|
64
73
|
${AUTH_SCRIPT}
|
|
74
|
+
${THEME_TOGGLE_SCRIPT}
|
|
65
75
|
${BASES_SCRIPT}
|
|
66
76
|
${FRONTMATTER_SCRIPT}
|
|
67
77
|
</body>
|
|
@@ -239,12 +249,6 @@ function sitemapItem(p, currentPath) {
|
|
|
239
249
|
const cur = p.path === currentPath ? ' aria-current="page"' : "";
|
|
240
250
|
return `<li><a href="${attr(href)}"${cur} class="internal internal-link">${esc(p.title)}</a></li>`;
|
|
241
251
|
}
|
|
242
|
-
function esc(s) {
|
|
243
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
244
|
-
}
|
|
245
|
-
function attr(s) {
|
|
246
|
-
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
247
|
-
}
|
|
248
252
|
// Opens the Explorer <details> on desktop so its [open] state matches the
|
|
249
253
|
// CSS-forced visibility. On mobile we leave it closed so the user has a
|
|
250
254
|
// collapsed sitemap by default.
|
|
@@ -373,7 +377,7 @@ const AUTH_SCRIPT = `<script>
|
|
|
373
377
|
box.classList.remove('auth-signed-out');
|
|
374
378
|
box.classList.add('auth-signed-in');
|
|
375
379
|
box.innerHTML =
|
|
376
|
-
'<div class="auth-status"
|
|
380
|
+
'<div class="auth-status"><strong>' + esc(role) + '</strong></div>' +
|
|
377
381
|
'<a class="auth-action" href="/logout?next=' + next + '">Sign out</a>';
|
|
378
382
|
} else {
|
|
379
383
|
box.classList.remove('auth-signed-in');
|
|
@@ -390,6 +394,55 @@ const AUTH_SCRIPT = `<script>
|
|
|
390
394
|
function esc(s) { return String(s).replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])); }
|
|
391
395
|
})();
|
|
392
396
|
</script>`;
|
|
397
|
+
// Boot script: runs in <head> before any paint so the visitor's stored theme
|
|
398
|
+
// preference (or the OS preference for "auto") wins immediately, no
|
|
399
|
+
// flash-of-wrong-theme. Reads localStorage.vaultTheme; falls back to the
|
|
400
|
+
// data-theme value the server emitted on <html>. Sets an effective-theme
|
|
401
|
+
// data attribute the toggle uses to flip the icon without re-deriving.
|
|
402
|
+
const THEME_BOOT_SCRIPT = `<script>
|
|
403
|
+
(function () {
|
|
404
|
+
try {
|
|
405
|
+
const html = document.documentElement;
|
|
406
|
+
const stored = localStorage.getItem('vaultTheme');
|
|
407
|
+
if (stored === 'light' || stored === 'dark' || stored === 'auto') html.setAttribute('data-theme', stored);
|
|
408
|
+
} catch (e) { /* localStorage may be blocked; the SSR data-theme stays in effect */ }
|
|
409
|
+
})();
|
|
410
|
+
</script>`;
|
|
411
|
+
// Click handler: cycles through light → dark → auto, persisting to
|
|
412
|
+
// localStorage. The button icon swaps based on the effective theme so the
|
|
413
|
+
// affordance always shows what's currently active. Listens for OS-pref
|
|
414
|
+
// changes too so the icon updates live when the visitor flips their
|
|
415
|
+
// system theme while on the page.
|
|
416
|
+
const THEME_TOGGLE_SCRIPT = `<script>
|
|
417
|
+
(function () {
|
|
418
|
+
const btn = document.getElementById('theme-toggle');
|
|
419
|
+
if (!btn) return;
|
|
420
|
+
const html = document.documentElement;
|
|
421
|
+
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
|
422
|
+
const SUN = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>';
|
|
423
|
+
const MOON = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';
|
|
424
|
+
const icon = btn.querySelector('.theme-toggle-icon');
|
|
425
|
+
function effective() {
|
|
426
|
+
const t = html.getAttribute('data-theme') || 'auto';
|
|
427
|
+
if (t === 'light' || t === 'dark') return t;
|
|
428
|
+
return mql.matches ? 'dark' : 'light';
|
|
429
|
+
}
|
|
430
|
+
function paint() {
|
|
431
|
+
const eff = effective();
|
|
432
|
+
if (icon) icon.innerHTML = eff === 'dark' ? SUN : MOON;
|
|
433
|
+
btn.setAttribute('aria-pressed', eff === 'dark' ? 'true' : 'false');
|
|
434
|
+
btn.title = eff === 'dark' ? 'Switch to light mode' : 'Switch to dark mode';
|
|
435
|
+
}
|
|
436
|
+
paint();
|
|
437
|
+
mql.addEventListener('change', paint);
|
|
438
|
+
btn.addEventListener('click', function () {
|
|
439
|
+
const next = effective() === 'dark' ? 'light' : 'dark';
|
|
440
|
+
html.setAttribute('data-theme', next);
|
|
441
|
+
try { localStorage.setItem('vaultTheme', next); } catch (e) { /* blocked storage */ }
|
|
442
|
+
paint();
|
|
443
|
+
});
|
|
444
|
+
})();
|
|
445
|
+
</script>`;
|
|
393
446
|
const LIGHTBOX_SCRIPT = `<script>
|
|
394
447
|
(function () {
|
|
395
448
|
let onKey = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/render/layout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/render/layout.ts"],"names":[],"mappings":"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"}
|