mdrefine 0.2.0-rc.2 → 0.2.0
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/CHANGELOG.md +577 -0
- package/CODE_OF_CONDUCT.md +30 -0
- package/CONTRIBUTING.md +189 -16
- package/README.md +100 -154
- package/SECURITY.md +15 -13
- package/config.schema.json +91 -0
- package/dist/cli/diff.d.ts +10 -0
- package/dist/cli/diff.js +247 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/main.js +270 -150
- package/dist/cli/main.js.map +1 -1
- package/dist/config/load.js +67 -6
- package/dist/config/load.js.map +1 -1
- package/dist/config/problems.d.ts +7 -0
- package/dist/config/problems.js +208 -0
- package/dist/config/problems.js.map +1 -0
- package/dist/config/resolve.d.ts +42 -109
- package/dist/config/resolve.js +193 -52
- package/dist/config/resolve.js.map +1 -1
- package/dist/core/directives.d.ts +7 -0
- package/dist/core/directives.js +25 -13
- package/dist/core/directives.js.map +1 -1
- package/dist/core/engine.d.ts +42 -4
- package/dist/core/engine.js +518 -79
- package/dist/core/engine.js.map +1 -1
- package/dist/core/frozen.d.ts +6 -0
- package/dist/core/frozen.js +15 -0
- package/dist/core/frozen.js.map +1 -0
- package/dist/core/scope.d.ts +30 -0
- package/dist/core/scope.js +122 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/types.d.ts +202 -23
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +3 -0
- package/dist/node.js +4 -0
- package/dist/node.js.map +1 -0
- package/dist/rules/blocks.d.ts +34 -0
- package/dist/rules/blocks.js +550 -0
- package/dist/rules/blocks.js.map +1 -0
- package/dist/rules/content.d.ts +2 -0
- package/dist/rules/content.js +85 -0
- package/dist/rules/content.js.map +1 -0
- package/dist/rules/dialects.js +10 -6
- package/dist/rules/dialects.js.map +1 -1
- package/dist/rules/links.js +302 -6
- package/dist/rules/links.js.map +1 -1
- package/dist/rules/lists.d.ts +2 -0
- package/dist/rules/lists.js +924 -0
- package/dist/rules/lists.js.map +1 -0
- package/dist/rules/structure.js +127 -1
- package/dist/rules/structure.js.map +1 -1
- package/dist/rules/style.d.ts +8 -2
- package/dist/rules/style.js +1137 -165
- package/dist/rules/style.js.map +1 -1
- package/dist/syntax/block-identifier.d.ts +18 -0
- package/dist/syntax/block-identifier.js +24 -0
- package/dist/syntax/block-identifier.js.map +1 -0
- package/dist/syntax/obsidian.d.ts +29 -11
- package/dist/syntax/obsidian.js +9 -10
- package/dist/syntax/obsidian.js.map +1 -1
- package/dist/syntax/parse.d.ts +87 -3
- package/dist/syntax/parse.js +247 -19
- package/dist/syntax/parse.js.map +1 -1
- package/dist/workspace/access.d.ts +12 -3
- package/dist/workspace/access.js +33 -5
- package/dist/workspace/access.js.map +1 -1
- package/dist/workspace/discovery.d.ts +85 -0
- package/dist/workspace/discovery.js +155 -0
- package/dist/workspace/discovery.js.map +1 -0
- package/dist/workspace/encoding.d.ts +24 -0
- package/dist/workspace/encoding.js +113 -0
- package/dist/workspace/encoding.js.map +1 -0
- package/dist/workspace/files.d.ts +92 -6
- package/dist/workspace/files.js +715 -59
- package/dist/workspace/files.js.map +1 -1
- package/dist/workspace/git.d.ts +54 -0
- package/dist/workspace/git.js +198 -0
- package/dist/workspace/git.js.map +1 -0
- package/dist/workspace/index.d.ts +58 -3
- package/dist/workspace/index.js +136 -37
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/selection.d.ts +2 -2
- package/dist/workspace/selection.js +3 -3
- package/dist/workspace/selection.js.map +1 -1
- package/dist/workspace/slug.js +8 -1
- package/dist/workspace/slug.js.map +1 -1
- package/dist/workspace/vault.js +3 -1
- package/dist/workspace/vault.js.map +1 -1
- package/docs/api.md +239 -0
- package/docs/benchmarks.md +140 -200
- package/docs/changelog.md +1 -0
- package/docs/cli.md +281 -89
- package/docs/configuration.md +193 -480
- package/docs/design.md +163 -284
- package/docs/dialects.md +169 -0
- package/docs/examples.md +151 -109
- package/docs/index.md +21 -37
- package/docs/integrations.md +144 -0
- package/docs/obsidian.md +91 -115
- package/docs/plugins.md +147 -212
- package/docs/quick-start.md +68 -74
- package/docs/rules.md +1237 -0
- package/docs/versions.md +56 -0
- package/examples/README.md +17 -14
- package/examples/automation/summarize-report.mjs +5 -2
- package/examples/library/lint-folder.mjs +5 -4
- package/examples/library/lint-workspace.mjs +32 -0
- package/examples/plugin/notes/release-checklist.md +2 -2
- package/examples/plugin/rules.mjs +17 -23
- package/examples/workspaces/obsidian-vault/after/mdtools.config.jsonc +2 -2
- package/examples/workspaces/obsidian-vault/before/mdtools.config.jsonc +2 -2
- package/examples/workspaces/repository-docs/after/README.md +2 -2
- package/examples/workspaces/repository-docs/after/mdtools.config.jsonc +0 -2
- package/examples/workspaces/repository-docs/before/README.md +2 -2
- package/examples/workspaces/repository-docs/before/docs/guide.md +7 -7
- package/examples/workspaces/repository-docs/before/docs/reference.md +3 -1
- package/examples/workspaces/repository-docs/before/mdtools.config.jsonc +0 -2
- package/package.json +38 -12
- package/docs/contributing.md +0 -218
- package/docs/releases/0.1.0-beta.1.md +0 -39
- package/docs/releases/0.1.0-beta.2.md +0 -83
- package/docs/releases/0.1.0-beta.3.md +0 -61
- package/docs/releases/0.1.0-beta.4.md +0 -50
- package/docs/releases/0.1.0-rc.1.md +0 -99
- package/docs/releases/0.2.0-rc.1.md +0 -141
- package/docs/releases/0.2.0-rc.2.md +0 -225
- package/docs/releases.md +0 -144
- package/docs/testing.md +0 -93
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport GithubSlugger from \"github-slugger\";\nimport { decodeNamedCharacterReference } from \"decode-named-character-reference\";\nimport { walk } from \"../syntax/walk.js\";\nimport type { Heading, Nodes } from \"mdast\";\nimport type { Dialect, Document, LinkResolution, Workspace } from \"../core/types.js\";\nimport { fallbackDialect } from \"../config/resolve.js\";\nimport { parse, range, textContent } from \"../syntax/parse.js\";\nimport { headingAttributes, lastLineSource } from \"./heading-attributes.js\";\nimport { createForgejoSlugger, createGiteaSlugger, giteaAnchor } from \"./slug.js\";\nimport { refusal } from \"./access.js\";\n\n/**\n * A Markdown file's text, null for a file that is not Markdown, or a loader\n * that returns the text when a fragment check needs it. A loader that throws an\n * error whose `code` is `EACCES` or `EPERM` marks the file as unreadable; any\n * other error propagates.\n */\nexport type WorkspaceSource = string | null | (() => string);\n\n/** How a renderer shows a heading's inline content when it builds the anchor from the rendered text. */\ninterface Rendering {\n /** Tags shown as text rather than as HTML, and so part of the anchor. */\n shownTags: RegExp;\n /** What a hard line break contributes. */\n lineBreak: string;\n}\n/** GFM's tagfilter makes GitHub show these tags as text; a hard break adds nothing. */\nconst github: Rendering = {\n shownTags:\n /^<\\/?(?:iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\\t\\n\\f\\r />])/i,\n lineBreak: \"\",\n};\n/**\n * Gitea 1.26 and later show these tags as text, drop other disallowed tags\n * while keeping their text, and read a hard break as a line break. Rendered on\n * Gitea 1.27.3 and 28.0.0: `## X <script>a</script> Y` is `#x-scriptascript-y`\n * and `## X <iframe>a</iframe> Y` is `#x-a-y`.\n */\nconst gitea: Rendering = {\n shownTags: /^<\\/?(?:script|style|html|head)(?=[\\t\\n\\f\\r />])/i,\n lineBreak: \"\\n\",\n};\n/**\n * Heading text as rendered, which GitHub and Gitea 1.26 and later build anchors\n * from: inline HTML tags and comments are left out and the text between tags\n * stays, so `## A <span>B</span>` reads `A B`, except for the tags that the\n * renderer shows as text.\n */\nfunction renderedText(node: Nodes, rendering: Rendering): string {\n if (node.type === \"html\") return rendering.shownTags.test(node.value) ? node.value : \"\";\n if (node.type === \"break\") return rendering.lineBreak;\n if (\"children\" in node)\n return node.children.map((child) => renderedText(child, rendering)).join(\"\");\n return textContent(node);\n}\n/**\n * Heading text with `_` emphasis delimiters kept, as Gitea 1.26 and later show\n * them near `_.py` (`## __init__.py` reads `__init__.py`, not `init.py`).\n * Everything else is as in Gitea's rendered text.\n */\nfunction literalUnderscoreText(node: Nodes, source: string): string {\n if (node.type === \"emphasis\" || node.type === \"strong\") {\n const [start, end] = range(node);\n if (source[start] === \"_\") {\n const size = node.type === \"strong\" ? 2 : 1;\n const inner = node.children.map((child) => literalUnderscoreText(child, source)).join(\"\");\n return source.slice(start, start + size) + inner + source.slice(end - size, end);\n }\n }\n if (\"children\" in node)\n return node.children.map((child) => literalUnderscoreText(child, source)).join(\"\");\n return renderedText(node, gitea);\n}\n/** An HTML open tag with its attributes, by CommonMark's grammar for raw HTML. */\nconst openTag =\n /<([A-Za-z][A-Za-z0-9-]*)((?:[ \\t\\r\\n]+[A-Za-z_:][\\w.:-]*(?:[ \\t\\r\\n]*=[ \\t\\r\\n]*(?:\"[^\"]*\"|'[^']*'|[^ \\t\\r\\n\"'=<>`]+))?)*)[ \\t\\r\\n]*\\/?>/y;\nconst closeTag = /<\\/([A-Za-z][A-Za-z0-9-]*)[ \\t\\r\\n]*>/y;\nconst attribute =\n /([A-Za-z_:][\\w.:-]*)(?:[ \\t\\r\\n]*=[ \\t\\r\\n]*(?:\"([^\"]*)\"|'([^']*)'|([^ \\t\\r\\n\"'=<>`]+)))?/g;\n/**\n * Elements whose content HTML reads as text and that no renderer shows as an\n * element: GitHub's tagfilter shows these tags as text, Forgejo removes them,\n * and Gitea shows them as text or removes them. `<plaintext>` has no end.\n */\nconst rawText = new Set([\n \"iframe\",\n \"noembed\",\n \"noframes\",\n \"plaintext\",\n \"script\",\n \"style\",\n \"textarea\",\n \"title\",\n \"xmp\",\n]);\n/** A tag that becomes an element, or the text between tags. */\ntype HtmlToken =\n { name: string; attributes: string; close: boolean } | { name?: undefined; text: string };\n/**\n * HTML as a browser tokenizes it, in one forward pass: comments, which run to\n * the end when unterminated, declarations, and raw-text elements with their\n * content are left out, and a tag is read whole, so a `<!--` or `<h2>` inside\n * a quoted attribute value is part of the value.\n */\nfunction htmlTokens(html: string): HtmlToken[] {\n const tokens: HtmlToken[] = [];\n const lower = html.toLowerCase();\n let copied = 0;\n const text = (end: number) => {\n if (end > copied) tokens.push({ text: html.slice(copied, end) });\n };\n for (let at = html.indexOf(\"<\"); at >= 0; at = html.indexOf(\"<\", at)) {\n let end: number;\n if (html.startsWith(\"<!--\", at)) {\n const close = html.indexOf(\"-->\", at + 4);\n end = close < 0 ? html.length : close + 3;\n text(at);\n } else if (html[at + 1] === \"!\" || html[at + 1] === \"?\") {\n const close = html.indexOf(\">\", at);\n end = close < 0 ? html.length : close + 1;\n text(at);\n } else {\n openTag.lastIndex = closeTag.lastIndex = at;\n const open = openTag.exec(html);\n const tag = open ?? closeTag.exec(html);\n if (!tag) {\n // A `<` that starts no tag is text.\n at++;\n continue;\n }\n const name = tag[1]!.toLowerCase();\n end = at + tag[0].length;\n text(at);\n if (!open) tokens.push({ name, attributes: \"\", close: true });\n else if (!rawText.has(name)) tokens.push({ name, attributes: tag[2]!, close: false });\n else {\n const close = name === \"plaintext\" ? -1 : lower.indexOf(`</${name}`, end);\n const after = close < 0 ? -1 : html.indexOf(\">\", close);\n end = after < 0 ? html.length : after + 1;\n }\n }\n copied = at = end;\n }\n text(html.length);\n return tokens;\n}\n/**\n * The anchors that HTML in a document adds: the `id` of any element and the\n * `name` of an `<a>`, as written. GitHub, Forgejo, and Gitea keep both on the\n * elements they allow and add their `user-content-` prefix to them unless it is\n * already there, as they do to a link's fragment, so an `id` written with the\n * prefix is recorded without it. Every value of a repeated attribute counts:\n * Forgejo 16 and Gitea 1.26 keep the first, Gitea 1.25 the last.\n */\nfunction htmlAnchors(tokens: HtmlToken[]): string[] {\n const anchors: string[] = [];\n for (const token of tokens) {\n if (token.name === undefined || token.close) continue;\n for (const match of token.attributes.matchAll(attribute)) {\n const attributeName = match[1]!.toLowerCase();\n if (attributeName !== \"id\" && !(token.name === \"a\" && attributeName === \"name\")) continue;\n const value = (match[2] ?? match[3] ?? match[4] ?? \"\").replace(/^user-content-/, \"\");\n if (value) anchors.push(value);\n }\n }\n return anchors;\n}\n\n/**\n * A character reference, which HTML decodes in an element's text. A numeric one\n * needs no semicolon, and one that names no character becomes U+FFFD.\n */\nconst characterReference = /&(?:#(\\d+);?|#[xX]([0-9a-fA-F]+);?|([A-Za-z][A-Za-z\\d]*);)/g;\nfunction decodeReferences(text: string): string {\n return text.replace(characterReference, (reference, decimal, hex, name) => {\n if (name) return decodeNamedCharacterReference(name) || reference;\n const code = Number.parseInt(decimal ?? hex, decimal ? 10 : 16);\n const valid = code > 0 && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff);\n return valid ? String.fromCodePoint(code) : \"�\";\n });\n}\nconst headingTag = /^h[1-6]$/;\n/**\n * Headings written as HTML, as GitHub and Gitea 1.26 and later see them when\n * they generate anchors: the text content with inner tags removed and character\n * references decoded, and whether the tag sets its own `id`. As in HTML, a\n * heading's start tag also ends an open heading, and any heading's end tag\n * closes it. A heading left open at the end is not reported: the renderers\n * continue it through the Markdown that follows, which is not modeled.\n */\nfunction htmlHeadings(tokens: HtmlToken[]): { text: string; hasId: boolean }[] {\n const headings: { text: string; hasId: boolean }[] = [];\n let open: { text: string; hasId: boolean } | undefined;\n const close = () => {\n if (open) headings.push({ text: decodeReferences(open.text), hasId: open.hasId });\n open = undefined;\n };\n for (const token of tokens) {\n if (token.name === undefined) {\n if (open) open.text += token.text;\n } else if (headingTag.test(token.name)) {\n close();\n if (!token.close)\n open = {\n text: \"\",\n hasId: [...token.attributes.matchAll(attribute)].some(\n (item) => item[1]!.toLowerCase() === \"id\",\n ),\n };\n }\n }\n return headings;\n}\n/**\n * A paragraph as HTML, for headings that are written inline: the HTML tags as\n * written around the text that the renderers put between them, with the text's\n * own `<` and `&` escaped so that only real tags are read.\n */\nfunction htmlView(node: Nodes): string {\n if (node.type === \"html\") return node.value;\n if (node.type === \"break\") return \"\\n\";\n if (\"children\" in node) return node.children.map(htmlView).join(\"\");\n return textContent(node).replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\");\n}\n\n/** What Obsidian links to: exact heading text, matched case-insensitively, and block identifiers. */\ninterface ObsidianAnchors {\n headings: Set<string>;\n foldedHeadings: Set<string>;\n blocks: Set<string>;\n}\n/** What GitHub links to, and CommonMark in its stead. */\ninterface GithubAnchors {\n /** GitHub's numbered heading anchors. */\n slugs: Set<string>;\n /** `id` and `<a name>` values from the document's HTML, lowercased, as GitHub stores and matches them. */\n explicit: Set<string>;\n}\n/** What Forgejo and Gitea link to; each reads attribute blocks and its own anchor rules. */\ninterface ForgeAnchors {\n /** Forgejo heading anchors; punctuation runs collapse differently. */\n forgejoSlugs: Set<string>;\n /** Gitea heading anchors; GitHub-like, but combining marks are dropped. */\n giteaSlugs: Set<string>;\n /** `id` and `<a name>` values from the document's HTML, as written, which is how both match them. */\n explicit: Set<string>;\n}\n/** What one HTML node, or one paragraph holding an inline heading, adds to the page. */\ninterface HtmlPart {\n anchors: string[];\n headings: { text: string; hasId: boolean }[];\n}\n/**\n * What link checks read from a target: its anchors, in one group per set of\n * dialects that share them. A group is computed the first time a link is\n * checked against one of its dialects, so a GitHub or Obsidian workspace never\n * reads attribute blocks, which need a second parse, or the Forgejo and Gitea\n * anchors, and the forges never number anchors GitHub's way.\n *\n * Nothing else is kept. A parsed document takes many times the memory of its\n * source, and a workspace held one for every target until the run ended, so\n * each group is computed from a document that is parsed for it and released\n * with it. A workspace's links are almost always checked against one group, and\n * a check against another one parses the target once more.\n */\ninterface Target {\n /** Whether the system refused to let the target's source be read. */\n unreadable?: true;\n obsidian?: ObsidianAnchors;\n github?: GithubAnchors;\n forge?: ForgeAnchors;\n}\n/**\n * A copy of a string that shares no memory with the text it was cut from. An\n * engine may store a substring, such as a regular expression's match or a slice\n * of the source, as a reference into the whole string, so a kept heading name\n * or `id` would keep its document's text alive after the parsed document is\n * gone. Joining the string's code units builds a new string of the same\n * content. `text + \"\"`, a template literal, `String()`, and `substring()` return\n * the same string and detach nothing; measured on Node.js 22 and 24.\n */\nfunction detach(text: string): string {\n return text.split(\"\").join(\"\");\n}\n/** Replace every string of the sets, which are all a target keeps, by a detached copy. */\nfunction detachAll(...sets: Set<string>[]): void {\n for (const set of sets) {\n const copies = Array.from(set, detach);\n set.clear();\n for (const copy of copies) set.add(copy);\n }\n}\n/** The document's HTML, tokenized once for the headings and the explicit anchors of a group. */\nfunction htmlParts(document: Document): Map<Nodes, HtmlPart> {\n const parts = new Map<Nodes, HtmlPart>();\n const { source, tree } = document;\n walk(tree, (node) => {\n if (node.type === \"html\") {\n const tokens = htmlTokens(node.value);\n parts.set(node, { anchors: htmlAnchors(tokens), headings: htmlHeadings(tokens) });\n } else if (node.type === \"paragraph\" && /<h[1-6]/i.test(source.slice(...range(node))))\n // An inline heading's tags and text are separate nodes, at any depth;\n // their explicit anchors come from the tags' own nodes.\n parts.set(node, { anchors: [], headings: htmlHeadings(htmlTokens(htmlView(node))) });\n });\n return parts;\n}\n/** A target's anchors for Obsidian; none for a target that is not Markdown source. */\nfunction obsidianAnchors(document: Document | null): ObsidianAnchors {\n const anchors: ObsidianAnchors = {\n headings: new Set(),\n foldedHeadings: new Set(),\n blocks: new Set(),\n };\n if (!document) return anchors;\n walk(document.tree, \"heading\", (node) => {\n const text = textContent(node);\n anchors.headings.add(text);\n anchors.foldedHeadings.add(text.toLowerCase());\n });\n walk(document.tree, \"text\", (node) => {\n const match = /(?:^|\\s)\\^([A-Za-z0-9-]+)\\s*$/.exec(node.value);\n if (match) anchors.blocks.add(match[1]!);\n });\n detachAll(anchors.headings, anchors.foldedHeadings, anchors.blocks);\n return anchors;\n}\n/** A target's anchors for GitHub and CommonMark; none for a target that is not Markdown source. */\nfunction githubAnchors(document: Document | null): GithubAnchors {\n const anchors: GithubAnchors = { slugs: new Set(), explicit: new Set() };\n if (!document) return anchors;\n const slugger = new GithubSlugger();\n const parts = htmlParts(document);\n // GitHub numbers the anchors of Markdown and HTML headings together, in\n // document order, and prefixes an id only when it does not already start\n // with the prefix.\n const add = (text: string) => anchors.slugs.add(slugger.slug(text).replace(/^user-content-/, \"\"));\n walk(document.tree, (node) => {\n const part = parts.get(node);\n if (part) for (const heading of part.headings) add(heading.text);\n else if (node.type === \"heading\") add(renderedText(node, github));\n });\n // Explicit anchors, inline or in HTML blocks, do not affect heading numbering.\n for (const part of parts.values())\n for (const anchor of part.anchors) anchors.explicit.add(anchor.toLowerCase());\n detachAll(anchors.slugs, anchors.explicit);\n return anchors;\n}\n/** A target's anchors for Forgejo and Gitea; none for a target that is not Markdown source. */\nfunction forgeAnchors(document: Document | null): ForgeAnchors {\n const anchors: ForgeAnchors = {\n forgejoSlugs: new Set(),\n giteaSlugs: new Set(),\n explicit: new Set(),\n };\n if (!document) return anchors;\n const { source } = document;\n const forgejoSlugger = createForgejoSlugger();\n const giteaSlugger = createGiteaSlugger();\n const attributes = headingAttributes(document);\n const parts = htmlParts(document);\n // How many block quotes each heading is in, for the markers of its last line.\n const quotes = new Map<Heading, number>();\n const count = (node: Nodes, depth: number) => {\n if (node.type === \"heading\") quotes.set(node, depth);\n if (\"children\" in node)\n for (const child of node.children) count(child, depth + (node.type === \"blockquote\" ? 1 : 0));\n };\n count(document.tree, 0);\n walk(document.tree, (node) => {\n // Gitea 1.26 and later give HTML headings without an `id` an anchor from\n // their text, and number nothing. Forgejo gives them none.\n for (const heading of parts.get(node)?.headings ?? []) {\n const anchor = heading.hasId ? \"\" : giteaAnchor(heading.text);\n if (anchor) anchors.giteaSlugs.add(anchor);\n }\n if (node.type !== \"heading\") return;\n // Forgejo and Gitea take a trailing `{#id .class}` as attributes, not text.\n const block = attributes.get(node);\n if (block?.id !== undefined) {\n // A non-string id is empty on Gitea 1.26 and later and unrenderable before.\n const anchor = forgejoSlugger.custom(block.id ?? \"\");\n if (anchor) anchors.forgejoSlugs.add(anchor);\n if (giteaSlugger.custom(block.id ?? \"\")) anchors.giteaSlugs.add(anchor);\n return;\n }\n // Forgejo, like Gitea before 1.26, builds anchors from the source of\n // the heading's last line: markup, destinations, and tags are part of it.\n const line = lastLineSource(source, node, quotes.get(node) ?? 0, block?.start);\n anchors.forgejoSlugs.add(forgejoSlugger.slug(line));\n anchors.giteaSlugs.add(giteaSlugger.slug(line));\n // Gitea 1.26 and later number no anchors, build them from the rendered\n // text, and keep underscores near `_.py` literal.\n const shown = block?.heading ?? node;\n const [start, end] = range(shown);\n const anchor = giteaAnchor(\n source.slice(start, block ? Math.min(end, block.start) : end).includes(\"_.py\")\n ? literalUnderscoreText(shown, source)\n : renderedText(shown, gitea),\n );\n if (anchor) anchors.giteaSlugs.add(anchor);\n });\n // Explicit anchors, inline or in HTML blocks, do not affect heading numbering.\n for (const part of parts.values())\n for (const anchor of part.anchors) anchors.explicit.add(anchor);\n detachAll(anchors.forgejoSlugs, anchors.giteaSlugs, anchors.explicit);\n return anchors;\n}\nexport interface WorkspaceOptions {\n /** The dialect that link targets are parsed in; `github` when omitted. */\n dialect?: Dialect;\n strictLineBreaks?: boolean;\n /** Existing directories, including empty ones; never treated as note targets. */\n directories?: string[];\n /**\n * Existing directories whose contents could not be read. A link that leads\n * into one, or that an Obsidian name search finds nowhere else, resolves as\n * `unreadable` instead of `missing`.\n */\n unreadable?: string[];\n /**\n * Folders below the workspace root that are Obsidian vaults of their own. An\n * Obsidian link in a note of such a vault reaches only the vault's files: a\n * path is counted from the vault's folder, and a search by name looks inside\n * it. Other dialects, and notes outside these folders, resolve as without it.\n */\n vaults?: string[];\n /**\n * The workspace root's own path inside an Obsidian vault, such as\n * `Projects/Notes`, when the root is a folder of that vault and not the vault\n * itself. The rest of the vault is then out of sight: an Obsidian link whose\n * target could lie there, or be outdone by a note there, resolves as\n * `unreadable` or as `resolved` with `unreadable` set, never as `missing`.\n */\n rootInVault?: string;\n}\nexport function splitDestination(destination: string): { path: string; fragment: string } {\n const hash = destination.indexOf(\"#\");\n const decode = (value: string) => {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n };\n return {\n path: decode(hash < 0 ? destination : destination.slice(0, hash)),\n fragment: decode(hash < 0 ? \"\" : destination.slice(hash + 1)),\n };\n}\nexport function createWorkspace(\n files: Record<string, WorkspaceSource>,\n options: WorkspaceOptions = {},\n): Workspace {\n const sources = new Map(\n Object.entries(files).map(([name, source]) => [\n name.replaceAll(\"\\\\\", \"/\").replace(/^\\.\\//, \"\"),\n source,\n ]),\n );\n const directories = new Set(\n (options.directories ?? []).map((name) => name.replaceAll(\"\\\\\", \"/\")),\n );\n directories.add(\".\");\n /** The directories above a path, nearest first, up to the workspace root. */\n function* parents(name: string): Generator<string> {\n let directory = path.posix.dirname(name);\n while (directory !== \".\" && directory !== path.posix.dirname(directory)) {\n yield directory;\n directory = path.posix.dirname(directory);\n }\n }\n for (const name of sources.keys())\n for (const directory of parents(name)) directories.add(directory);\n const unreadable = [\n ...new Set(\n (options.unreadable ?? []).map((name) =>\n path.posix.normalize(name.replaceAll(\"\\\\\", \"/\")).replace(/\\/$/, \"\"),\n ),\n ),\n ].sort();\n for (const name of unreadable) {\n directories.add(name);\n for (const directory of parents(name)) directories.add(directory);\n }\n const unreadableNames = new Set(unreadable);\n // Obsidian matches paths without regard to case.\n const unreadableFolded = new Map(unreadable.map((name) => [name.toLowerCase(), name]));\n /** The unreadable directory that a path lies in, if any. */\n function unreadableAbove(name: string, folded: boolean): string | undefined {\n if (unreadable.length)\n for (const directory of parents(name)) {\n const found = folded\n ? unreadableFolded.get(directory.toLowerCase())\n : unreadableNames.has(directory)\n ? directory\n : undefined;\n if (found !== undefined) return found;\n }\n return undefined;\n }\n // Obsidian resolves note names case-insensitively; these indexes are built on first use.\n // Every file is filed once, under its file name in lowercase. A table of every\n // path, or of every ending of every path, costs hundreds of bytes for each\n // file, which a vault with many attachments pays whether or not they are linked.\n let fileNames: Map<string, string | string[]> | undefined;\n let foldedDirectories: Set<string> | undefined;\n /** The files whose file name, the last part of the path, is `key` in lowercase. */\n function filesNamed(key: string): readonly string[] {\n if (!fileNames) {\n fileNames = new Map();\n for (const actual of sources.keys()) {\n const name = actual.slice(actual.lastIndexOf(\"/\") + 1).toLowerCase();\n const held = fileNames.get(name);\n if (held === undefined) fileNames.set(name, actual);\n else if (typeof held === \"string\") fileNames.set(name, [held, actual]);\n else held.push(actual);\n }\n }\n const held = fileNames.get(key);\n return held === undefined ? [] : typeof held === \"string\" ? [held] : held;\n }\n // A file name that very many files share, such as an index note in every folder,\n // gets a table of its paths, so that a link to one of them does not compare all.\n const manySharing = 32;\n const sharedNames = new Map<string, Map<string, string[]>>();\n /** The files whose whole path is `name` without regard to case. */\n function namesMatching(name: string): string[] {\n const folded = name.toLowerCase();\n const key = folded.slice(folded.lastIndexOf(\"/\") + 1);\n const sharing = filesNamed(key);\n if (sharing.length <= manySharing)\n return sharing.filter((actual) => actual.toLowerCase() === folded);\n let paths = sharedNames.get(key);\n if (!paths) {\n paths = new Map();\n for (const actual of sharing) {\n const path = actual.toLowerCase();\n const held = paths.get(path);\n if (held) held.push(actual);\n else paths.set(path, [actual]);\n }\n sharedNames.set(key, paths);\n }\n return paths.get(folded) ?? [];\n }\n function isDirectory(name: string, folded: boolean): boolean {\n if (!folded) return directories.has(name);\n foldedDirectories ??= new Set([...directories].map((directory) => directory.toLowerCase()));\n return foldedDirectories.has(name.toLowerCase());\n }\n const targets = new Map<string, Target>();\n /**\n * One group of a target's anchors, from the target read and parsed for it;\n * nothing keeps the parsed document. A target that is not Markdown source has\n * no anchors. Undefined for a target that the system refuses to let be read,\n * which is marked and not read again.\n */\n function compute<Anchors>(\n target: Target,\n name: string,\n anchors: (document: Document | null) => Anchors,\n ): Anchors | undefined {\n if (target.unreadable) return undefined;\n const value = sources.get(name);\n if (value === null || value === undefined || !/\\.md$/i.test(name)) return anchors(null);\n let source: string;\n try {\n source = typeof value === \"function\" ? value() : value;\n } catch (error) {\n // The file exists, but its anchors are unknown; any other error is a fault.\n if (!refusal(error)) throw error;\n target.unreadable = true;\n return undefined;\n }\n return anchors(parse(source, options.dialect ?? fallbackDialect, name));\n }\n /**\n * Whether the target has the anchor a fragment names, or undefined when the\n * target's source could not be read. GitHub, Forgejo, and Gitea store anchors\n * with a `user-content-` prefix and add it to a link's fragment unless it is\n * already there, so `anchor` is the fragment with one prefix removed. Gitea\n * 1.26 and later prefix a generated anchor that already has the prefix again,\n * and a browser reaches that element with the fragment as written. GitHub's\n * page script also retries a fragment lowercased, and its anchors are.\n */\n function hasAnchor(\n name: string,\n dialect: Dialect,\n fragment: string,\n anchor: string,\n ): boolean | undefined {\n let target = targets.get(name);\n if (!target) targets.set(name, (target = {}));\n if (dialect === \"obsidian\") {\n const anchors = target.obsidian ?? compute(target, name, obsidianAnchors);\n if (!anchors) return undefined;\n target.obsidian = anchors;\n return fragment.startsWith(\"^\")\n ? anchors.blocks.has(fragment.slice(1))\n : anchors.headings.has(fragment) || anchors.foldedHeadings.has(fragment.toLowerCase());\n }\n if (dialect === \"forgejo\" || dialect === \"gitea\") {\n const forge = target.forge ?? compute(target, name, forgeAnchors);\n if (!forge) return undefined;\n target.forge = forge;\n const slugs = dialect === \"forgejo\" ? forge.forgejoSlugs : forge.giteaSlugs;\n if (slugs.has(anchor) || slugs.has(fragment)) return true;\n return forge.explicit.has(anchor) || forge.explicit.has(fragment);\n }\n const anchors = target.github ?? compute(target, name, githubAnchors);\n if (!anchors) return undefined;\n target.github = anchors;\n const folded = anchor.toLowerCase();\n return anchors.slugs.has(folded) || anchors.explicit.has(folded);\n }\n // Vaults of their own, deepest first, so that a note belongs to the nearest one.\n const vaults = [\n ...new Set(\n (options.vaults ?? [])\n .map((name) => path.posix.normalize(name.replaceAll(\"\\\\\", \"/\")).replace(/\\/$/, \"\"))\n .filter((name) => name !== \".\" && name !== \"\"),\n ),\n ].sort((a, b) => b.length - a.length);\n /** The vault below the root that holds a note, or \"\" when none does. */\n function vaultOf(name: string): string {\n return vaults.find((vault) => name.startsWith(`${vault}/`)) ?? \"\";\n }\n // The folders from the vault that the root is a part of, down to the root.\n const rootFolders = path.posix\n .normalize((options.rootInVault ?? \"\").replaceAll(\"\\\\\", \"/\"))\n .split(\"/\")\n .filter((part) => part !== \"\" && part !== \".\");\n const rootFolded = rootFolders.map((part) => part.toLowerCase());\n /** Where the rest of that vault is, seen from the root. */\n const beyondRoot = rootFolders.map(() => \"..\").join(\"/\");\n /**\n * The path from the root that a path from that vault's folder names, or\n * undefined when it names something of the vault outside the root.\n */\n function belowRoot(rooted: string): string | undefined {\n const parts = rooted.split(\"/\").filter((part) => part !== \"\" && part !== \".\");\n if (parts.length < rootFolders.length) return undefined;\n for (const [index, part] of rootFolded.entries())\n if (parts[index]!.toLowerCase() !== part) return undefined;\n return parts.slice(rootFolders.length).join(\"/\") || \".\";\n }\n /**\n * Files that a search finds when the searched path starts in the folders above\n * the root: with the root at `A/B`, the path `B/Note` names `Note` at the root.\n */\n function overlapCandidates(target: string): string[] {\n const parts = target.split(\"/\").filter((part) => part !== \"\");\n const found: string[] = [];\n for (let count = 1; count <= rootFolders.length && count < parts.length; count++) {\n const tail = rootFolded.slice(-count);\n if (!tail.every((part, index) => parts[index]!.toLowerCase() === part)) continue;\n const rest = parts.slice(count).join(\"/\");\n found.push(...namesMatching(rest));\n if (!path.posix.extname(rest)) found.push(...namesMatching(`${rest}.md`));\n }\n return found;\n }\n /**\n * The files that an Obsidian search for `target` finds in `vault`: those whose\n * path from the vault's folder ends with it.\n */\n function searchCandidates(target: string, vault: string): string[] {\n const found = suffixCandidates(target);\n if (!vault) return found;\n const wanted = target.toLowerCase();\n const ends = (name: string) => name === wanted || name.endsWith(`/${wanted}`);\n return found.filter((name) => {\n if (!name.startsWith(`${vault}/`)) return false;\n // The index matched a suffix of the path from the root, which may be longer.\n const inside = name.slice(vault.length + 1).toLowerCase();\n return ends(inside) || (inside.endsWith(\".md\") && ends(inside.slice(0, -3)));\n });\n }\n /**\n * The files whose path ends with `target` at a folder boundary, without regard\n * to case; a Markdown file is also found without its `.md`.\n */\n function suffixCandidates(target: string): string[] {\n const wanted = target.toLowerCase();\n const slash = wanted.lastIndexOf(\"/\");\n const found: string[] = [];\n for (const extension of [\"\", \".md\"]) {\n const sharing = filesNamed(wanted.slice(slash + 1) + extension);\n // A bare file name is decided by the table alone.\n if (slash < 0) found.push(...sharing);\n else {\n const ending = `/${wanted}${extension}`;\n for (const actual of sharing) {\n const path = actual.toLowerCase();\n if (path.length + 1 === ending.length ? ending.endsWith(path) : path.endsWith(ending))\n found.push(actual);\n }\n }\n }\n return found;\n }\n return {\n ...(options.strictLineBreaks !== undefined\n ? { strictLineBreaks: options.strictLineBreaks }\n : {}),\n resolve(source, destination, dialect): LinkResolution {\n if (/^[a-z][a-z\\d+.-]*:/i.test(destination) || destination.startsWith(\"//\"))\n return { status: \"external\" };\n source = source.replaceAll(\"\\\\\", \"/\");\n const parts = splitDestination(destination);\n const targetPath = parts.path;\n if (dialect !== \"obsidian\" && (targetPath.startsWith(\"/\") || targetPath.includes(\"?\")))\n return { status: \"unavailable\" };\n const candidates = new Set<string>();\n // Unreadable directories that the link's path leads into.\n const blocking = new Set<string>();\n let directory = false;\n // Whether Obsidian's search by name was used, which looks in every directory.\n let searched = false;\n // Whether a place that Obsidian tries first could not be looked in.\n let obstructed = false;\n const folded = dialect === \"obsidian\";\n // The vault below the root that an Obsidian link is confined to, if any.\n const vault = folded ? vaultOf(source) : \"\";\n // Something that the link's path names outside that vault.\n let outside: string | undefined;\n // Whether the workspace is only a part of the note's vault.\n const partial = folded && !vault && rootFolders.length > 0;\n // Whether Obsidian would look in a place of that vault outside the workspace.\n let beyond = false;\n const add = (candidate: string) => {\n const normalized = path.posix.normalize(candidate);\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n // As far up as the vault's folder, the path stays inside the vault.\n const climbed = normalized.split(\"/\").filter((part) => part === \"..\").length;\n if (partial && climbed <= rootFolders.length) beyond = true;\n return;\n }\n if (path.posix.isAbsolute(normalized)) return;\n const bare = normalized.replace(/\\/$/, \"\");\n if (vault && bare !== vault && !bare.startsWith(`${vault}/`)) {\n // Obsidian does not look there; remember it to say so instead of \"missing\".\n outside ??=\n namesMatching(bare)[0] ??\n (path.posix.extname(bare) ? undefined : namesMatching(`${bare}.md`)[0]) ??\n (isDirectory(bare, true) ? bare : undefined);\n return;\n }\n if (isDirectory(bare, folded)) directory = true;\n const above = unreadableAbove(bare, folded);\n if (above !== undefined) blocking.add(above);\n if (!folded) {\n if (sources.has(normalized)) candidates.add(normalized);\n return;\n }\n // Names differing only by case all count, so such vaults report ambiguity.\n for (const name of namesMatching(normalized)) candidates.add(name);\n if (!path.posix.extname(normalized))\n for (const name of namesMatching(`${normalized}.md`)) candidates.add(name);\n };\n if (!targetPath) add(source);\n else if (dialect === \"obsidian\") {\n if (/^\\.{1,2}\\//.test(targetPath))\n add(path.posix.join(path.posix.dirname(source), targetPath));\n else {\n const rooted = targetPath.replace(/^\\//, \"\");\n if (partial) {\n // The path is counted from the vault's folder, above the root: only\n // one through the root's own folder names something in the workspace.\n const below = belowRoot(rooted);\n if (below === undefined) beyond = true;\n else add(below);\n } else add(path.posix.join(vault, rooted));\n if (candidates.size === 0 && !directory && !targetPath.startsWith(\"/\")) {\n // The vault root comes first: a note there, unseen, would be the target.\n obstructed = blocking.size > 0;\n add(path.posix.join(path.posix.dirname(source), targetPath));\n }\n if (candidates.size === 0 && !directory && !targetPath.startsWith(\"/\")) {\n searched = true;\n for (const name of searchCandidates(targetPath, vault)) candidates.add(name);\n if (partial) for (const name of overlapCandidates(targetPath)) candidates.add(name);\n }\n }\n } else add(path.posix.join(path.posix.dirname(source), targetPath));\n if (candidates.size === 0 && directory) return { status: \"directory\" };\n // The search looks in the note's own vault only, and so do the directories\n // that could hide a match from it.\n const hidden = vault ? unreadable.filter((name) => name.startsWith(`${vault}/`)) : unreadable;\n // A search by name covers the readable files only: an unreadable directory\n // may hold the note that is missing, or a second one of a name found once.\n const unsearched = searched && hidden.length > 0;\n // The rest of a vault that the workspace is a part of may hold the target of\n // a link that led there, and a note that a search would find as well or first.\n const unseen = partial && (beyond || searched) ? [beyondRoot] : [];\n // A match is uncertain when a place that could not be looked in may hold a\n // note that Obsidian would choose instead, or as well.\n const uncertain = [...(unsearched ? hidden : obstructed ? blocking : []), ...unseen];\n if (candidates.size === 0 && (blocking.size > 0 || unsearched || unseen.length > 0))\n return {\n status: \"unreadable\",\n unreadable: [...(blocking.size ? blocking : unsearched ? hidden : []), ...unseen],\n ...(vault ? { vault } : {}),\n };\n if (candidates.size !== 1)\n return {\n status: candidates.size ? \"ambiguous\" : \"missing\",\n ...(vault ? { vault } : {}),\n ...(candidates.size === 0 && outside !== undefined ? { outside } : {}),\n };\n const resolved = [...candidates][0]!;\n const fragment = parts.fragment;\n let fragmentExists = true;\n if (fragment) {\n const found = hasAnchor(\n resolved,\n dialect,\n fragment,\n fragment.replace(/^user-content-/, \"\"),\n );\n // The file is there, but what it contains could not be read.\n if (found === undefined)\n return {\n status: \"unreadable\",\n target: resolved,\n fragment,\n unreadable: [resolved],\n ...(vault ? { vault } : {}),\n };\n fragmentExists = found;\n }\n return {\n status: \"resolved\",\n target: resolved,\n fragment,\n fragmentExists,\n ...(uncertain.length ? { unreadable: uncertain } : {}),\n ...(vault ? { vault, rooted: resolved.slice(vault.length + 1) } : {}),\n ...(partial ? { rooted: `${rootFolders.join(\"/\")}/${resolved}` } : {}),\n };\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport GithubSlugger from \"github-slugger\";\nimport { decodeNamedCharacterReference } from \"decode-named-character-reference\";\nimport { walk } from \"../syntax/walk.js\";\nimport type { Heading, Nodes } from \"mdast\";\nimport type { Dialect, Document, LinkResolution, Workspace } from \"../core/types.js\";\nimport { fallbackDialect } from \"../config/resolve.js\";\nimport { blockIdentifier } from \"../syntax/block-identifier.js\";\nimport { parse, range, textContent } from \"../syntax/parse.js\";\nimport { headingAttributes, lastLineSource } from \"./heading-attributes.js\";\nimport { createForgejoSlugger, createGiteaSlugger, giteaAnchor } from \"./slug.js\";\nimport { refusal } from \"./access.js\";\nimport { isNotUtf8 } from \"./encoding.js\";\n\n/**\n * A Markdown file's text, null for a file that is not Markdown, or a loader\n * that returns the text when a fragment check needs it. Only a file that\n * `isMarkdownName` accepts for the link's dialect is read for anchors. A\n * loader that throws an error whose `code` is `EACCES`, `EPERM`, or `EBUSY`,\n * or `ERR_ENCODING_INVALID_ENCODED_DATA` for a file that is not UTF-8 text,\n * marks the file as unreadable; any other error propagates.\n */\nexport type WorkspaceSource = string | null | (() => string);\n\n/** What `WorkspaceOptions.lookup` found at a path. */\nexport type LookupResult =\n /** A file, with its path as found from the root and its source as in `files`. */\n | { type: \"file\"; path: string; source: WorkspaceSource }\n | { type: \"directory\" }\n /**\n * Something whose real location lies outside the workspace root, reached\n * through the symbolic link or junction `through`, which the host does not\n * follow: the root bounds what is read.\n */\n | { type: \"outside\"; through: string }\n /** Something that the system does not let the host examine; `at` names it. */\n | { type: \"unreadable\"; at: string };\n\n/**\n * Whether a file is Markdown by its name: one ending in `.md` or `.markdown`,\n * in any letter case, both of which GitHub, Forgejo, and Gitea render.\n * Discovery selects such files in folders, and their headings are link\n * targets. For the Obsidian dialect only `.md` counts: Obsidian opens no\n * other file as a note.\n */\nexport function isMarkdownName(name: string, dialect?: Dialect): boolean {\n return (dialect === \"obsidian\" ? /\\.md$/i : /\\.(?:md|markdown)$/i).test(name);\n}\n\n/** How a renderer shows a heading's inline content when it builds the anchor from the rendered text. */\ninterface Rendering {\n /** Tags shown as text rather than as HTML, and so part of the anchor. */\n shownTags: RegExp;\n /** What a hard line break contributes. */\n lineBreak: string;\n}\n/** GFM's tagfilter makes GitHub show these tags as text; a hard break adds nothing. */\nconst github: Rendering = {\n shownTags:\n /^<\\/?(?:iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\\t\\n\\f\\r />])/i,\n lineBreak: \"\",\n};\n/**\n * Gitea 1.26 and later show these tags as text, drop other disallowed tags\n * while keeping their text, and read a hard break as a line break. Rendered on\n * Gitea 1.27.3 and 28.0.0: `## X <script>a</script> Y` is `#x-scriptascript-y`\n * and `## X <iframe>a</iframe> Y` is `#x-a-y`.\n */\nconst gitea: Rendering = {\n shownTags: /^<\\/?(?:script|style|html|head)(?=[\\t\\n\\f\\r />])/i,\n lineBreak: \"\\n\",\n};\n/**\n * Heading text as rendered, which GitHub and Gitea 1.26 and later build anchors\n * from: inline HTML tags and comments are left out and the text between tags\n * stays, so `## A <span>B</span>` reads `A B`, except for the tags that the\n * renderer shows as text.\n */\nfunction renderedText(node: Nodes, rendering: Rendering): string {\n if (node.type === \"html\") return rendering.shownTags.test(node.value) ? node.value : \"\";\n if (node.type === \"break\") return rendering.lineBreak;\n if (\"children\" in node)\n return node.children.map((child) => renderedText(child, rendering)).join(\"\");\n return textContent(node);\n}\n/**\n * Heading text with `_` emphasis delimiters kept, as Gitea 1.26 and later show\n * them near `_.py` (`## __init__.py` reads `__init__.py`, not `init.py`).\n * Everything else is as in Gitea's rendered text.\n */\nfunction literalUnderscoreText(node: Nodes, source: string): string {\n if (node.type === \"emphasis\" || node.type === \"strong\") {\n const [start, end] = range(node);\n if (source[start] === \"_\") {\n const size = node.type === \"strong\" ? 2 : 1;\n const inner = node.children.map((child) => literalUnderscoreText(child, source)).join(\"\");\n return source.slice(start, start + size) + inner + source.slice(end - size, end);\n }\n }\n if (\"children\" in node)\n return node.children.map((child) => literalUnderscoreText(child, source)).join(\"\");\n return renderedText(node, gitea);\n}\n/** An HTML open tag with its attributes, by CommonMark's grammar for raw HTML. */\nconst openTag =\n /<([A-Za-z][A-Za-z0-9-]*)((?:[ \\t\\r\\n]+[A-Za-z_:][\\w.:-]*(?:[ \\t\\r\\n]*=[ \\t\\r\\n]*(?:\"[^\"]*\"|'[^']*'|[^ \\t\\r\\n\"'=<>`]+))?)*)[ \\t\\r\\n]*\\/?>/y;\nconst closeTag = /<\\/([A-Za-z][A-Za-z0-9-]*)[ \\t\\r\\n]*>/y;\nconst attribute =\n /([A-Za-z_:][\\w.:-]*)(?:[ \\t\\r\\n]*=[ \\t\\r\\n]*(?:\"([^\"]*)\"|'([^']*)'|([^ \\t\\r\\n\"'=<>`]+)))?/g;\n/**\n * Elements whose content HTML reads as text and that no renderer shows as an\n * element: GitHub's tagfilter shows these tags as text, Forgejo removes them,\n * and Gitea shows them as text or removes them. `<plaintext>` has no end.\n */\nconst rawText = new Set([\n \"iframe\",\n \"noembed\",\n \"noframes\",\n \"plaintext\",\n \"script\",\n \"style\",\n \"textarea\",\n \"title\",\n \"xmp\",\n]);\n/** A tag that becomes an element, or the text between tags. */\ntype HtmlToken =\n { name: string; attributes: string; close: boolean } | { name?: undefined; text: string };\n/**\n * HTML as a browser tokenizes it, in one forward pass: comments, which run to\n * the end when unterminated, declarations, and raw-text elements with their\n * content are left out, and a tag is read whole, so a `<!--` or `<h2>` inside\n * a quoted attribute value is part of the value.\n */\nfunction htmlTokens(html: string): HtmlToken[] {\n const tokens: HtmlToken[] = [];\n const lower = html.toLowerCase();\n let copied = 0;\n const text = (end: number) => {\n if (end > copied) tokens.push({ text: html.slice(copied, end) });\n };\n for (let at = html.indexOf(\"<\"); at >= 0; at = html.indexOf(\"<\", at)) {\n let end: number;\n if (html.startsWith(\"<!--\", at)) {\n const close = html.indexOf(\"-->\", at + 4);\n end = close < 0 ? html.length : close + 3;\n text(at);\n } else if (html[at + 1] === \"!\" || html[at + 1] === \"?\") {\n const close = html.indexOf(\">\", at);\n end = close < 0 ? html.length : close + 1;\n text(at);\n } else {\n openTag.lastIndex = closeTag.lastIndex = at;\n const open = openTag.exec(html);\n const tag = open ?? closeTag.exec(html);\n if (!tag) {\n // A `<` that starts no tag is text.\n at++;\n continue;\n }\n const name = tag[1]!.toLowerCase();\n end = at + tag[0].length;\n text(at);\n if (!open) tokens.push({ name, attributes: \"\", close: true });\n else if (!rawText.has(name)) tokens.push({ name, attributes: tag[2]!, close: false });\n else {\n const close = name === \"plaintext\" ? -1 : lower.indexOf(`</${name}`, end);\n const after = close < 0 ? -1 : html.indexOf(\">\", close);\n end = after < 0 ? html.length : after + 1;\n }\n }\n copied = at = end;\n }\n text(html.length);\n return tokens;\n}\n/**\n * The anchors that HTML in a document adds: the `id` of any element and the\n * `name` of an `<a>`, as written. GitHub, Forgejo, and Gitea keep both on the\n * elements they allow and add their `user-content-` prefix to them unless it is\n * already there, as they do to a link's fragment, so an `id` written with the\n * prefix is recorded without it. Every value of a repeated attribute counts:\n * Forgejo 16 and Gitea 1.26 keep the first, Gitea 1.25 the last.\n */\nfunction htmlAnchors(tokens: HtmlToken[]): string[] {\n const anchors: string[] = [];\n for (const token of tokens) {\n if (token.name === undefined || token.close) continue;\n for (const match of token.attributes.matchAll(attribute)) {\n const attributeName = match[1]!.toLowerCase();\n if (attributeName !== \"id\" && !(token.name === \"a\" && attributeName === \"name\")) continue;\n const value = (match[2] ?? match[3] ?? match[4] ?? \"\").replace(/^user-content-/, \"\");\n if (value) anchors.push(value);\n }\n }\n return anchors;\n}\n\n/**\n * A character reference, which HTML decodes in an element's text. A numeric one\n * needs no semicolon, and one that names no character becomes U+FFFD.\n */\nconst characterReference = /&(?:#(\\d+);?|#[xX]([0-9a-fA-F]+);?|([A-Za-z][A-Za-z\\d]*);)/g;\nfunction decodeReferences(text: string): string {\n return text.replace(characterReference, (reference, decimal, hex, name) => {\n if (name) return decodeNamedCharacterReference(name) || reference;\n const code = Number.parseInt(decimal ?? hex, decimal ? 10 : 16);\n const valid = code > 0 && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff);\n return valid ? String.fromCodePoint(code) : \"�\";\n });\n}\nconst headingTag = /^h[1-6]$/;\n/**\n * Headings written as HTML, as GitHub and Gitea 1.26 and later see them when\n * they generate anchors: the text content with inner tags removed and character\n * references decoded, and whether the tag sets its own `id`. As in HTML, a\n * heading's start tag also ends an open heading, and any heading's end tag\n * closes it. A heading left open at the end is not reported: the renderers\n * continue it through the Markdown that follows, which is not modeled.\n */\nfunction htmlHeadings(tokens: HtmlToken[]): { text: string; hasId: boolean }[] {\n const headings: { text: string; hasId: boolean }[] = [];\n let open: { text: string; hasId: boolean } | undefined;\n const close = () => {\n if (open) headings.push({ text: decodeReferences(open.text), hasId: open.hasId });\n open = undefined;\n };\n for (const token of tokens) {\n if (token.name === undefined) {\n if (open) open.text += token.text;\n } else if (headingTag.test(token.name)) {\n close();\n if (!token.close)\n open = {\n text: \"\",\n hasId: [...token.attributes.matchAll(attribute)].some(\n (item) => item[1]!.toLowerCase() === \"id\",\n ),\n };\n }\n }\n return headings;\n}\n/**\n * A paragraph as HTML, for headings that are written inline: the HTML tags as\n * written around the text that the renderers put between them, with the text's\n * own `<` and `&` escaped so that only real tags are read.\n */\nfunction htmlView(node: Nodes): string {\n if (node.type === \"html\") return node.value;\n if (node.type === \"break\") return \"\\n\";\n if (\"children\" in node) return node.children.map(htmlView).join(\"\");\n return textContent(node).replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\");\n}\n\n/**\n * What Obsidian links to: headings, by the text they show or by their source\n * text, as written or without regard to case, and block identifiers.\n */\ninterface ObsidianAnchors {\n headings: Set<string>;\n foldedHeadings: Set<string>;\n /**\n * The headings in document order, with their levels and names, for a link to\n * a heading below another one, such as `[[Note#Setup#Mobile]]`.\n */\n outline: { depth: number; names: string[] }[];\n blocks: Set<string>;\n}\n/** What GitHub links to, and CommonMark in its stead. */\ninterface GithubAnchors {\n /** GitHub's numbered heading anchors. */\n slugs: Set<string>;\n /** `id` and `<a name>` values from the document's HTML, lowercased, as GitHub stores and matches them. */\n explicit: Set<string>;\n}\n/** What Forgejo and Gitea link to; each reads attribute blocks and its own anchor rules. */\ninterface ForgeAnchors {\n /** Forgejo heading anchors; punctuation runs collapse differently. */\n forgejoSlugs: Set<string>;\n /** Gitea heading anchors; GitHub-like, but combining marks are dropped. */\n giteaSlugs: Set<string>;\n /** `id` and `<a name>` values from the document's HTML, as written, which is how both match them. */\n explicit: Set<string>;\n}\n/** What one HTML node, or one paragraph holding an inline heading, adds to the page. */\ninterface HtmlPart {\n anchors: string[];\n headings: { text: string; hasId: boolean }[];\n}\n/**\n * What link checks read from a target: its anchors, in one group per set of\n * dialects that share them. A group is computed the first time a link is\n * checked against one of its dialects, so a GitHub or Obsidian workspace never\n * reads attribute blocks, which need a second parse, or the Forgejo and Gitea\n * anchors, and the forges never number anchors GitHub's way.\n *\n * Nothing else is kept. A parsed document takes many times the memory of its\n * source, and a workspace held one for every target until the run ended, so\n * each group is computed from a document that is parsed for it and released\n * with it. A workspace's links are almost always checked against one group, and\n * a check against another one parses the target once more.\n */\ninterface Target {\n /** Whether the system refused to let the target's source be read, or it is not UTF-8 text. */\n unreadable?: true;\n obsidian?: ObsidianAnchors;\n github?: GithubAnchors;\n forge?: ForgeAnchors;\n}\n/**\n * A copy of a string that shares no memory with the text it was cut from. An\n * engine may store a substring, such as a regular expression's match or a slice\n * of the source, as a reference into the whole string, so a kept heading name\n * or `id` would keep its document's text alive after the parsed document is\n * gone. Joining the string's code units builds a new string of the same\n * content. `text + \"\"`, a template literal, `String()`, and `substring()` return\n * the same string and detach nothing; measured on Node.js 22 and 24.\n */\nfunction detach(text: string): string {\n return text.split(\"\").join(\"\");\n}\n/** Replace every string of the sets, which are all a target keeps, by a detached copy. */\nfunction detachAll(...sets: Set<string>[]): void {\n for (const set of sets) {\n const copies = Array.from(set, detach);\n set.clear();\n for (const copy of copies) set.add(copy);\n }\n}\n/** The document's HTML, tokenized once for the headings and the explicit anchors of a group. */\nfunction htmlParts(document: Document): Map<Nodes, HtmlPart> {\n const parts = new Map<Nodes, HtmlPart>();\n const { source, tree } = document;\n walk(tree, (node) => {\n if (node.type === \"html\") {\n const tokens = htmlTokens(node.value);\n parts.set(node, { anchors: htmlAnchors(tokens), headings: htmlHeadings(tokens) });\n } else if (node.type === \"paragraph\" && /<h[1-6]/i.test(source.slice(...range(node))))\n // An inline heading's tags and text are separate nodes, at any depth;\n // their explicit anchors come from the tags' own nodes.\n parts.set(node, { anchors: [], headings: htmlHeadings(htmlTokens(htmlView(node))) });\n });\n return parts;\n}\n/**\n * Whether the outline holds a chain of headings that `parts` name, each one\n * below the one before, within its section: `Setup#Mobile` is a heading\n * `Mobile` of any lower level after a heading `Setup` and before the next\n * heading of `Setup`'s level or higher. Every heading that a part names is\n * tried, so the link is missing only when no such chain exists.\n */\nfunction hasHeadingPath(outline: ObsidianAnchors[\"outline\"], parts: string[]): boolean {\n const named = (names: string[], part: string) =>\n names.some((name) => name === part || name.toLowerCase() === part.toLowerCase());\n const below = (part: number, from: number, depth: number): boolean => {\n for (let at = from; at < outline.length && outline[at]!.depth > depth; at++)\n if (\n named(outline[at]!.names, parts[part]!) &&\n (part === parts.length - 1 || below(part + 1, at + 1, outline[at]!.depth))\n )\n return true;\n return false;\n };\n return below(0, 0, 0);\n}\n/** A target's anchors for Obsidian. */\nfunction obsidianAnchors(document: Document): ObsidianAnchors {\n const anchors: ObsidianAnchors = {\n headings: new Set(),\n foldedHeadings: new Set(),\n outline: [],\n blocks: new Set(),\n };\n const { source } = document;\n walk(document.tree, (node) => {\n const block = blockIdentifier(source, node);\n if (block) anchors.blocks.add(block.id);\n if (node.type !== \"heading\") return;\n // A link may name a heading by the text it shows or as its source writes\n // it: the heading `` `move` `` is both `move` and `` `move` ``.\n const first = node.children[0];\n const written = first ? source.slice(range(first)[0], range(node.children.at(-1)!)[1]) : \"\";\n const names = [...new Set([textContent(node), written])].map(detach);\n for (const name of names) {\n anchors.headings.add(name);\n anchors.foldedHeadings.add(name.toLowerCase());\n }\n anchors.outline.push({ depth: node.depth, names });\n });\n // The names are detached already, and so is their lowercase form.\n detachAll(anchors.blocks);\n return anchors;\n}\n/** A target's anchors for GitHub and CommonMark. */\nfunction githubAnchors(document: Document): GithubAnchors {\n const anchors: GithubAnchors = { slugs: new Set(), explicit: new Set() };\n const slugger = new GithubSlugger();\n const parts = htmlParts(document);\n // GitHub numbers the anchors of Markdown and HTML headings together, in\n // document order, and prefixes an id only when it does not already start\n // with the prefix.\n const add = (text: string) => anchors.slugs.add(slugger.slug(text).replace(/^user-content-/, \"\"));\n walk(document.tree, (node) => {\n const part = parts.get(node);\n if (part) for (const heading of part.headings) add(heading.text);\n else if (node.type === \"heading\") add(renderedText(node, github));\n });\n // Explicit anchors, inline or in HTML blocks, do not affect heading numbering.\n for (const part of parts.values())\n for (const anchor of part.anchors) anchors.explicit.add(anchor.toLowerCase());\n detachAll(anchors.slugs, anchors.explicit);\n return anchors;\n}\n/** A target's anchors for Forgejo and Gitea. */\nfunction forgeAnchors(document: Document): ForgeAnchors {\n const anchors: ForgeAnchors = {\n forgejoSlugs: new Set(),\n giteaSlugs: new Set(),\n explicit: new Set(),\n };\n const { source } = document;\n const forgejoSlugger = createForgejoSlugger();\n const giteaSlugger = createGiteaSlugger();\n const attributes = headingAttributes(document);\n const parts = htmlParts(document);\n // How many block quotes each heading is in, for the markers of its last line.\n const quotes = new Map<Heading, number>();\n const count = (node: Nodes, depth: number) => {\n if (node.type === \"heading\") quotes.set(node, depth);\n if (\"children\" in node)\n for (const child of node.children) count(child, depth + (node.type === \"blockquote\" ? 1 : 0));\n };\n count(document.tree, 0);\n walk(document.tree, (node) => {\n // Gitea 1.26 and later give HTML headings without an `id` an anchor from\n // their text, and number nothing. Forgejo gives them none.\n for (const heading of parts.get(node)?.headings ?? []) {\n const anchor = heading.hasId ? \"\" : giteaAnchor(heading.text);\n if (anchor) anchors.giteaSlugs.add(anchor);\n }\n if (node.type !== \"heading\") return;\n // Forgejo and Gitea take a trailing `{#id .class}` as attributes, not text.\n const block = attributes.get(node);\n if (block?.id !== undefined) {\n // A non-string id is empty on Gitea 1.26 and later and unrenderable before.\n const anchor = forgejoSlugger.custom(block.id ?? \"\");\n if (anchor) anchors.forgejoSlugs.add(anchor);\n if (giteaSlugger.custom(block.id ?? \"\")) anchors.giteaSlugs.add(anchor);\n return;\n }\n // Forgejo, like Gitea before 1.26, builds anchors from the source of\n // the heading's last line: markup, destinations, and tags are part of it.\n const line = lastLineSource(source, node, quotes.get(node) ?? 0, block?.start);\n anchors.forgejoSlugs.add(forgejoSlugger.slug(line));\n anchors.giteaSlugs.add(giteaSlugger.slug(line));\n // Gitea 1.26 and later number no anchors, build them from the rendered\n // text, and keep underscores near `_.py` literal.\n const shown = block?.heading ?? node;\n const [start, end] = range(shown);\n const anchor = giteaAnchor(\n source.slice(start, block ? Math.min(end, block.start) : end).includes(\"_.py\")\n ? literalUnderscoreText(shown, source)\n : renderedText(shown, gitea),\n );\n if (anchor) anchors.giteaSlugs.add(anchor);\n });\n // Explicit anchors, inline or in HTML blocks, do not affect heading numbering.\n for (const part of parts.values())\n for (const anchor of part.anchors) anchors.explicit.add(anchor);\n detachAll(anchors.forgejoSlugs, anchors.giteaSlugs, anchors.explicit);\n return anchors;\n}\n/** The options of `createWorkspace`. */\nexport interface WorkspaceOptions {\n /** The dialect that link targets are parsed in; `github` when omitted. */\n dialect?: Dialect;\n /**\n * `true` when the vault's \"Strict line breaks\" setting is verified on, which\n * the workspace then reports as `Workspace.strictLineBreaks`. Obsidian notes\n * are wrapped only then.\n */\n strictLineBreaks?: boolean;\n /** Existing directories, including empty ones; never treated as note targets. */\n directories?: string[];\n /**\n * Existing directories whose contents could not be read. A link that leads\n * into one, or that an Obsidian name search finds nowhere else, resolves as\n * `unreadable` instead of `missing`.\n */\n unreadable?: string[];\n /**\n * Looks for a path that `files` and `directories` do not hold, when a link\n * names it: a host that leaves some folders or links out of the index, such\n * as the CLI, finds there what a link names. It returns what is at the path,\n * or undefined when nothing is. `folded` asks for Obsidian's matching,\n * without regard to letter case. A search by note name does not use it.\n */\n lookup?: (path: string, folded: boolean) => LookupResult | undefined;\n /**\n * Folders below the workspace root that are Obsidian vaults of their own. An\n * Obsidian link in a note of such a vault reaches only the vault's files: a\n * path is counted from the vault's folder, and a search by name looks inside\n * it. Other dialects, and notes outside these folders, resolve as without it.\n */\n vaults?: string[];\n /**\n * The workspace root's own path inside an Obsidian vault, such as\n * `Projects/Notes`, when the root is a folder of that vault and not the vault\n * itself. The rest of the vault is then out of sight: an Obsidian link whose\n * target could lie there, or be outdone by a note there, resolves as\n * `unreadable` or as `resolved` with `unreadable` set, never as `missing`.\n */\n rootInVault?: string;\n}\nexport function splitDestination(destination: string): { path: string; fragment: string } {\n const hash = destination.indexOf(\"#\");\n const decode = (value: string) => {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n };\n return {\n path: decode(hash < 0 ? destination : destination.slice(0, hash)),\n fragment: decode(hash < 0 ? \"\" : destination.slice(hash + 1)),\n };\n}\n/**\n * The workspace of `files`, which maps each path, relative to the workspace\n * root with forward slashes, to a `WorkspaceSource`. Link checks, link\n * rewriting, and Obsidian wrapping need one. A Markdown target is parsed in\n * `options.dialect` when a link's fragment needs its anchors, which are kept\n * and its text is not.\n */\nexport function createWorkspace(\n files: Record<string, WorkspaceSource>,\n options: WorkspaceOptions = {},\n): Workspace {\n const sources = new Map(\n Object.entries(files).map(([name, source]) => [\n name.replaceAll(\"\\\\\", \"/\").replace(/^\\.\\//, \"\"),\n source,\n ]),\n );\n const directories = new Set(\n (options.directories ?? []).map((name) => name.replaceAll(\"\\\\\", \"/\")),\n );\n directories.add(\".\");\n /** The directories above a path, nearest first, up to the workspace root. */\n function* parents(name: string): Generator<string> {\n let directory = path.posix.dirname(name);\n while (directory !== \".\" && directory !== path.posix.dirname(directory)) {\n yield directory;\n directory = path.posix.dirname(directory);\n }\n }\n for (const name of sources.keys())\n for (const directory of parents(name)) directories.add(directory);\n const unreadable = [\n ...new Set(\n (options.unreadable ?? []).map((name) =>\n path.posix.normalize(name.replaceAll(\"\\\\\", \"/\")).replace(/\\/$/, \"\"),\n ),\n ),\n ].sort();\n for (const name of unreadable) {\n directories.add(name);\n for (const directory of parents(name)) directories.add(directory);\n }\n const unreadableNames = new Set(unreadable);\n // Obsidian matches paths without regard to case.\n const unreadableFolded = new Map(unreadable.map((name) => [name.toLowerCase(), name]));\n /** The unreadable directory that a path lies in, if any. */\n function unreadableAbove(name: string, folded: boolean): string | undefined {\n if (unreadable.length)\n for (const directory of parents(name)) {\n const found = folded\n ? unreadableFolded.get(directory.toLowerCase())\n : unreadableNames.has(directory)\n ? directory\n : undefined;\n if (found !== undefined) return found;\n }\n return undefined;\n }\n // Obsidian resolves note names case-insensitively; these indexes are built on first use.\n // Every file is filed once, under its file name in lowercase. A table of every\n // path, or of every ending of every path, costs hundreds of bytes for each\n // file, which a vault with many attachments pays whether or not they are linked.\n let fileNames: Map<string, string | string[]> | undefined;\n let foldedDirectories: Set<string> | undefined;\n /** The files whose file name, the last part of the path, is `key` in lowercase. */\n function filesNamed(key: string): readonly string[] {\n if (!fileNames) {\n fileNames = new Map();\n for (const actual of sources.keys()) {\n const name = actual.slice(actual.lastIndexOf(\"/\") + 1).toLowerCase();\n const held = fileNames.get(name);\n if (held === undefined) fileNames.set(name, actual);\n else if (typeof held === \"string\") fileNames.set(name, [held, actual]);\n else held.push(actual);\n }\n }\n const held = fileNames.get(key);\n return held === undefined ? [] : typeof held === \"string\" ? [held] : held;\n }\n // A file name that very many files share, such as an index note in every folder,\n // gets a table of its paths, so that a link to one of them does not compare all.\n const manySharing = 32;\n const sharedNames = new Map<string, Map<string, string[]>>();\n /** The files whose whole path is `name` without regard to case. */\n function namesMatching(name: string): string[] {\n const folded = name.toLowerCase();\n const key = folded.slice(folded.lastIndexOf(\"/\") + 1);\n const sharing = filesNamed(key);\n if (sharing.length <= manySharing)\n return sharing.filter((actual) => actual.toLowerCase() === folded);\n let paths = sharedNames.get(key);\n if (!paths) {\n paths = new Map();\n for (const actual of sharing) {\n const path = actual.toLowerCase();\n const held = paths.get(path);\n if (held) held.push(actual);\n else paths.set(path, [actual]);\n }\n sharedNames.set(key, paths);\n }\n return paths.get(folded) ?? [];\n }\n function isDirectory(name: string, folded: boolean): boolean {\n if (!folded) return directories.has(name);\n foldedDirectories ??= new Set([...directories].map((directory) => directory.toLowerCase()));\n return foldedDirectories.has(name.toLowerCase());\n }\n const targets = new Map<string, Target>();\n /** What the host's lookup found, by the matching asked for and the path. */\n const lookedUp = new Map<string, LookupResult | undefined>();\n /** The sources of the files that the lookup found, by path. */\n const foundSources = new Map<string, WorkspaceSource>();\n /** What the host finds at a path that the index does not hold, asked once per path. */\n function lookup(name: string, folded: boolean): LookupResult | undefined {\n if (!options.lookup) return undefined;\n const key = `${folded ? \"i\" : \"s\"}:${name}`;\n if (lookedUp.has(key)) return lookedUp.get(key);\n const result = options.lookup(name, folded);\n lookedUp.set(key, result);\n if (result?.type === \"file\") foundSources.set(result.path, result.source);\n return result;\n }\n /**\n * One group of a Markdown target's anchors, from the target read and parsed\n * for it; nothing keeps the parsed document. Undefined for a target that the\n * system refuses to let be read, or whose text is not UTF-8, which is marked\n * and not read again.\n */\n function compute<Anchors>(\n target: Target,\n value: string | (() => string),\n name: string,\n anchors: (document: Document) => Anchors,\n ): Anchors | undefined {\n if (target.unreadable) return undefined;\n let source: string;\n try {\n source = typeof value === \"function\" ? value() : value;\n } catch (error) {\n // The file exists, but its anchors are unknown; any other error is a fault.\n if (!refusal(error) && !isNotUtf8(error)) throw error;\n target.unreadable = true;\n return undefined;\n }\n return anchors(parse(source, options.dialect ?? fallbackDialect, name));\n }\n /**\n * Whether the target has the anchor a fragment names, or undefined when the\n * target's source could not be read. GitHub, Forgejo, and Gitea store anchors\n * with a `user-content-` prefix and add it to a link's fragment unless it is\n * already there, so `anchor` is the fragment with one prefix removed. Gitea\n * 1.26 and later prefix a generated anchor that already has the prefix again,\n * and a browser reaches that element with the fragment as written. GitHub's\n * page script also retries a fragment lowercased, and its anchors are.\n */\n function hasAnchor(\n name: string,\n dialect: Dialect,\n fragment: string,\n anchor: string,\n ): boolean | undefined {\n const value = sources.has(name) ? sources.get(name) : foundSources.get(name);\n // Only a Markdown file's anchors are known. Other files take fragments of\n // their own, such as an image's `#gh-dark-mode-only`, a PDF's `#page=2`, or\n // a forge's line range `#L10-L20` in source code, which are not checked; so\n // is a file that is linted as Markdown only because it was named.\n if (value === null || value === undefined || !isMarkdownName(name, dialect)) return true;\n let target = targets.get(name);\n if (!target) targets.set(name, (target = {}));\n if (dialect === \"obsidian\") {\n const anchors = target.obsidian ?? compute(target, value, name, obsidianAnchors);\n if (!anchors) return undefined;\n target.obsidian = anchors;\n if (fragment.startsWith(\"^\")) return anchors.blocks.has(fragment.slice(1));\n if (anchors.headings.has(fragment) || anchors.foldedHeadings.has(fragment.toLowerCase()))\n return true;\n // A path of headings, each below the one before, such as `Setup#Mobile`.\n return fragment.includes(\"#\") && hasHeadingPath(anchors.outline, fragment.split(\"#\"));\n }\n if (dialect === \"forgejo\" || dialect === \"gitea\") {\n const forge = target.forge ?? compute(target, value, name, forgeAnchors);\n if (!forge) return undefined;\n target.forge = forge;\n const slugs = dialect === \"forgejo\" ? forge.forgejoSlugs : forge.giteaSlugs;\n if (slugs.has(anchor) || slugs.has(fragment)) return true;\n return forge.explicit.has(anchor) || forge.explicit.has(fragment);\n }\n const anchors = target.github ?? compute(target, value, name, githubAnchors);\n if (!anchors) return undefined;\n target.github = anchors;\n const folded = anchor.toLowerCase();\n return anchors.slugs.has(folded) || anchors.explicit.has(folded);\n }\n // Vaults of their own, deepest first, so that a note belongs to the nearest one.\n const vaults = [\n ...new Set(\n (options.vaults ?? [])\n .map((name) => path.posix.normalize(name.replaceAll(\"\\\\\", \"/\")).replace(/\\/$/, \"\"))\n .filter((name) => name !== \".\" && name !== \"\"),\n ),\n ].sort((a, b) => b.length - a.length);\n /** The vault below the root that holds a note, or \"\" when none does. */\n function vaultOf(name: string): string {\n return vaults.find((vault) => name.startsWith(`${vault}/`)) ?? \"\";\n }\n // The folders from the vault that the root is a part of, down to the root.\n const rootFolders = path.posix\n .normalize((options.rootInVault ?? \"\").replaceAll(\"\\\\\", \"/\"))\n .split(\"/\")\n .filter((part) => part !== \"\" && part !== \".\");\n const rootFolded = rootFolders.map((part) => part.toLowerCase());\n /** Where the rest of that vault is, seen from the root. */\n const beyondRoot = rootFolders.map(() => \"..\").join(\"/\");\n /**\n * The path from the root that a path from that vault's folder names, or\n * undefined when it names something of the vault outside the root.\n */\n function belowRoot(rooted: string): string | undefined {\n const parts = rooted.split(\"/\").filter((part) => part !== \"\" && part !== \".\");\n if (parts.length < rootFolders.length) return undefined;\n for (const [index, part] of rootFolded.entries())\n if (parts[index]!.toLowerCase() !== part) return undefined;\n return parts.slice(rootFolders.length).join(\"/\") || \".\";\n }\n /**\n * Files that a search finds when the searched path starts in the folders above\n * the root: with the root at `A/B`, the path `B/Note` names `Note` at the root.\n */\n function overlapCandidates(target: string): string[] {\n const parts = target.split(\"/\").filter((part) => part !== \"\");\n const found: string[] = [];\n for (let count = 1; count <= rootFolders.length && count < parts.length; count++) {\n const tail = rootFolded.slice(-count);\n if (!tail.every((part, index) => parts[index]!.toLowerCase() === part)) continue;\n const rest = parts.slice(count).join(\"/\");\n found.push(...namesMatching(rest));\n if (!path.posix.extname(rest)) found.push(...namesMatching(`${rest}.md`));\n }\n return found;\n }\n /**\n * The files that an Obsidian search for `target` finds in `vault`: those whose\n * path from the vault's folder ends with it.\n */\n function searchCandidates(target: string, vault: string): string[] {\n const found = suffixCandidates(target);\n if (!vault) return found;\n const wanted = target.toLowerCase();\n const ends = (name: string) => name === wanted || name.endsWith(`/${wanted}`);\n return found.filter((name) => {\n if (!name.startsWith(`${vault}/`)) return false;\n // The index matched a suffix of the path from the root, which may be longer.\n const inside = name.slice(vault.length + 1).toLowerCase();\n return ends(inside) || (inside.endsWith(\".md\") && ends(inside.slice(0, -3)));\n });\n }\n /**\n * The files whose path ends with `target` at a folder boundary, without regard\n * to case; a Markdown file is also found without its `.md`.\n */\n function suffixCandidates(target: string): string[] {\n const wanted = target.toLowerCase();\n const slash = wanted.lastIndexOf(\"/\");\n const found: string[] = [];\n for (const extension of [\"\", \".md\"]) {\n const sharing = filesNamed(wanted.slice(slash + 1) + extension);\n // A bare file name is decided by the table alone.\n if (slash < 0) found.push(...sharing);\n else {\n const ending = `/${wanted}${extension}`;\n for (const actual of sharing) {\n const path = actual.toLowerCase();\n if (path.length + 1 === ending.length ? ending.endsWith(path) : path.endsWith(ending))\n found.push(actual);\n }\n }\n }\n return found;\n }\n return {\n ...(options.strictLineBreaks !== undefined\n ? { strictLineBreaks: options.strictLineBreaks }\n : {}),\n resolve(source, destination, dialect, wiki = false): LinkResolution {\n if (/^[a-z][a-z\\d+.-]*:/i.test(destination) || destination.startsWith(\"//\"))\n return { status: \"external\" };\n source = source.replaceAll(\"\\\\\", \"/\");\n const parts = splitDestination(destination);\n const targetPath = parts.path;\n if (dialect !== \"obsidian\" && (targetPath.startsWith(\"/\") || targetPath.includes(\"?\")))\n return { status: \"unavailable\" };\n const candidates = new Set<string>();\n // Unreadable directories that the link's path leads into.\n const blocking = new Set<string>();\n let directory = false;\n // Whether Obsidian's search by name was used, which looks in every directory.\n let searched = false;\n // Whether a place that Obsidian tries first could not be looked in.\n let obstructed = false;\n const folded = dialect === \"obsidian\";\n // The vault below the root that an Obsidian link is confined to, if any.\n const vault = folded ? vaultOf(source) : \"\";\n // Something that the link's path names outside that vault.\n let outside: string | undefined;\n // Whether the workspace is only a part of the note's vault.\n const partial = folded && !vault && rootFolders.length > 0;\n // Whether Obsidian would look in a place of that vault outside the workspace.\n let beyond = false;\n // A link on the disk that the path leads through to outside the workspace root.\n let leaves: string | undefined;\n /** What the host finds at a path that the index does not hold. */\n const look = (name: string, file = true) => {\n const found = lookup(name, folded);\n if (found?.type === \"file\") {\n if (file) candidates.add(found.path);\n } else if (found?.type === \"directory\") directory ||= !wiki;\n else if (found?.type === \"outside\") leaves ??= found.through;\n else if (found?.type === \"unreadable\") blocking.add(found.at);\n };\n const add = (candidate: string) => {\n const normalized = path.posix.normalize(candidate);\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n // As far up as the vault's folder, the path stays inside the vault.\n const climbed = normalized.split(\"/\").filter((part) => part === \"..\").length;\n if (partial && climbed <= rootFolders.length) beyond = true;\n return;\n }\n if (path.posix.isAbsolute(normalized)) return;\n const bare = normalized.replace(/\\/$/, \"\");\n if (vault && bare !== vault && !bare.startsWith(`${vault}/`)) {\n // Obsidian does not look there; remember it to say so instead of \"missing\".\n outside ??=\n namesMatching(bare)[0] ??\n (path.posix.extname(bare) ? undefined : namesMatching(`${bare}.md`)[0]) ??\n (!wiki && isDirectory(bare, true) ? bare : undefined);\n return;\n }\n // Obsidian links a wikilink to a note or a file, never to a folder.\n if (!wiki && isDirectory(bare, folded)) directory = true;\n const above = unreadableAbove(bare, folded);\n if (above !== undefined) blocking.add(above);\n if (!folded) {\n if (sources.has(normalized)) candidates.add(normalized);\n // A path that ends with a slash names a folder only.\n else if (!directory) look(bare, bare === normalized);\n return;\n }\n // Names differing only by case all count, so such vaults report ambiguity.\n const before = candidates.size;\n for (const name of namesMatching(normalized)) candidates.add(name);\n if (!path.posix.extname(normalized))\n for (const name of namesMatching(`${normalized}.md`)) candidates.add(name);\n if (candidates.size === before && !directory) {\n look(bare);\n if (!path.posix.extname(bare)) look(`${bare}.md`);\n }\n };\n if (!targetPath) add(source);\n else if (dialect === \"obsidian\") {\n if (/^\\.{1,2}\\//.test(targetPath))\n add(path.posix.join(path.posix.dirname(source), targetPath));\n else {\n const rooted = targetPath.replace(/^\\//, \"\");\n if (partial) {\n // The path is counted from the vault's folder, above the root: only\n // one through the root's own folder names something in the workspace.\n const below = belowRoot(rooted);\n if (below === undefined) beyond = true;\n else add(below);\n } else add(path.posix.join(vault, rooted));\n if (candidates.size === 0 && !directory && !targetPath.startsWith(\"/\")) {\n // The vault root comes first: a note there, unseen, would be the target.\n obstructed = blocking.size > 0;\n add(path.posix.join(path.posix.dirname(source), targetPath));\n }\n if (candidates.size === 0 && !directory && !targetPath.startsWith(\"/\")) {\n searched = true;\n for (const name of searchCandidates(targetPath, vault)) candidates.add(name);\n if (partial) for (const name of overlapCandidates(targetPath)) candidates.add(name);\n }\n }\n } else add(path.posix.join(path.posix.dirname(source), targetPath));\n if (candidates.size === 0 && directory) return { status: \"directory\" };\n // The search looks in the note's own vault only, and so do the directories\n // that could hide a match from it.\n const hidden = vault ? unreadable.filter((name) => name.startsWith(`${vault}/`)) : unreadable;\n // A search by name covers the readable files only: an unreadable directory\n // may hold the note that is missing, or a second one of a name found once.\n const unsearched = searched && hidden.length > 0;\n // The rest of a vault that the workspace is a part of may hold the target of\n // a link that led there, and a note that a search would find as well or first.\n const unseen = partial && (beyond || searched) ? [beyondRoot] : [];\n // A match is uncertain when a place that could not be looked in may hold a\n // note that Obsidian would choose instead, or as well.\n const uncertain = [...(unsearched ? hidden : obstructed ? blocking : []), ...unseen];\n // The tool reads nothing outside the workspace root, where the link leads.\n if (candidates.size === 0 && leaves !== undefined)\n return {\n status: \"unreadable\",\n unreadable: [leaves],\n leavesRoot: leaves,\n ...(vault ? { vault } : {}),\n };\n if (candidates.size === 0 && (blocking.size > 0 || unsearched || unseen.length > 0))\n return {\n status: \"unreadable\",\n unreadable: [...(blocking.size ? blocking : unsearched ? hidden : []), ...unseen],\n ...(vault ? { vault } : {}),\n };\n if (candidates.size !== 1)\n return {\n status: candidates.size ? \"ambiguous\" : \"missing\",\n ...(vault ? { vault } : {}),\n ...(candidates.size === 0 && outside !== undefined ? { outside } : {}),\n };\n const resolved = [...candidates][0]!;\n const fragment = parts.fragment;\n let fragmentExists = true;\n if (fragment) {\n const found = hasAnchor(\n resolved,\n dialect,\n fragment,\n fragment.replace(/^user-content-/, \"\"),\n );\n // The file is there, but what it contains could not be read.\n if (found === undefined)\n return {\n status: \"unreadable\",\n target: resolved,\n fragment,\n unreadable: [resolved],\n ...(vault ? { vault } : {}),\n };\n fragmentExists = found;\n }\n return {\n status: \"resolved\",\n target: resolved,\n fragment,\n fragmentExists,\n ...(uncertain.length ? { unreadable: uncertain } : {}),\n ...(vault ? { vault, rooted: resolved.slice(vault.length + 1) } : {}),\n ...(partial ? { rooted: `${rootFolders.join(\"/\")}/${resolved}` } : {}),\n };\n },\n };\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/** Exclusions are literal paths relative to
|
|
2
|
-
export declare function excludeSelection(root: string, selected: string[], exclusions: string[]): Promise<string[]>;
|
|
1
|
+
/** Exclusions are literal paths, relative to `base`, never glob patterns. */
|
|
2
|
+
export declare function excludeSelection(root: string, selected: string[], exclusions: string[], base?: string): Promise<string[]>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { realpath } from "node:fs/promises";
|
|
3
3
|
import { pathError, refusal } from "./access.js";
|
|
4
|
-
/** Exclusions are literal paths relative to
|
|
5
|
-
export async function excludeSelection(root, selected, exclusions) {
|
|
4
|
+
/** Exclusions are literal paths, relative to `base`, never glob patterns. */
|
|
5
|
+
export async function excludeSelection(root, selected, exclusions, base = process.cwd()) {
|
|
6
6
|
// Resolve filesystem aliases (including Windows short names) consistently
|
|
7
7
|
// with discovery, while allowing exclusions for paths that do not exist yet.
|
|
8
8
|
async function canonical(file) {
|
|
@@ -22,7 +22,7 @@ export async function excludeSelection(root, selected, exclusions) {
|
|
|
22
22
|
const relative = await Promise.all(exclusions.map(async (input) => {
|
|
23
23
|
let actual;
|
|
24
24
|
try {
|
|
25
|
-
actual = await canonical(path.resolve(input));
|
|
25
|
+
actual = await canonical(path.resolve(base, input));
|
|
26
26
|
}
|
|
27
27
|
catch (error) {
|
|
28
28
|
// Without the real path nothing tells which file the exclusion stands for,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/workspace/selection.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEjD,
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/workspace/selection.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEjD,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,QAAkB,EAClB,UAAoB,EACpB,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE;IAEpB,0EAA0E;IAC1E,6EAA6E;IAC7E,KAAK,UAAU,SAAS,CAAC,IAAY;QACnC,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAI,KAA+B,CAAC,IAAI,CAAC;YACnD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,KAAK,CAAC;YACzD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,MAAM,KAAK,IAAI;gBAAE,MAAM,KAAK,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7B,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,2EAA2E;YAC3E,+CAA+C;YAC/C,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1E,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnE,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,2CAA2C,KAAK,EAAE,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CACH,CAAC;IACF,OAAO,QAAQ,CAAC,MAAM,CACpB,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,QAAQ,CAAC,IAAI,CACZ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,CAChF,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import path from \"node:path\";\nimport { realpath } from \"node:fs/promises\";\nimport { pathError, refusal } from \"./access.js\";\n\n/** Exclusions are literal paths, relative to `base`, never glob patterns. */\nexport async function excludeSelection(\n root: string,\n selected: string[],\n exclusions: string[],\n base = process.cwd(),\n): Promise<string[]> {\n // Resolve filesystem aliases (including Windows short names) consistently\n // with discovery, while allowing exclusions for paths that do not exist yet.\n async function canonical(file: string): Promise<string> {\n try {\n return await realpath(file);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\" && code !== \"ENOTDIR\") throw error;\n const parent = path.dirname(file);\n if (parent === file) throw error;\n return path.join(await canonical(parent), path.basename(file));\n }\n }\n const relative = await Promise.all(\n exclusions.map(async (input) => {\n let actual: string;\n try {\n actual = await canonical(path.resolve(base, input));\n } catch (error) {\n // Without the real path nothing tells which file the exclusion stands for,\n // so the run must not carry on and process it.\n throw refusal(error) ? pathError(\"Excluded path\", input, error) : error;\n }\n const name = path.relative(root, actual).split(path.sep).join(\"/\");\n if (name === \"..\" || name.startsWith(\"../\") || path.isAbsolute(name))\n throw new Error(`Excluded path is outside the workspace: ${input}`);\n return name;\n }),\n );\n return selected.filter(\n (name) =>\n !relative.some(\n (excluded) => !excluded || name === excluded || name.startsWith(`${excluded}/`),\n ),\n );\n}\n"]}
|
package/dist/workspace/slug.js
CHANGED
|
@@ -9,9 +9,15 @@ function lower(character) {
|
|
|
9
9
|
* authors, so links use the bare anchor. A generated anchor that already starts
|
|
10
10
|
* with the prefix is not prefixed again: `## user-content-setup` is reached as
|
|
11
11
|
* `#setup`, and a later `## Setup` becomes `#setup-1`.
|
|
12
|
+
*
|
|
13
|
+
* The renderers try `-1`, `-2`, ... from the start for each repeat, which takes
|
|
14
|
+
* time that grows with the square of the repeats. Each anchor here keeps the
|
|
15
|
+
* number to try next, as GitHub's anchor library does: every number below it
|
|
16
|
+
* is taken, and stays taken, so the search from there finds the same one.
|
|
12
17
|
*/
|
|
13
18
|
function createSlugger(clean) {
|
|
14
19
|
const seen = new Set();
|
|
20
|
+
const next = new Map();
|
|
15
21
|
return {
|
|
16
22
|
custom(id) {
|
|
17
23
|
const anchor = id.replace(/^user-content-/, "");
|
|
@@ -25,10 +31,11 @@ function createSlugger(clean) {
|
|
|
25
31
|
seen.add(result);
|
|
26
32
|
return result;
|
|
27
33
|
}
|
|
28
|
-
for (let i = 1;; i++) {
|
|
34
|
+
for (let i = next.get(result) ?? 1;; i++) {
|
|
29
35
|
const candidate = `${result}-${i}`;
|
|
30
36
|
if (!seen.has(candidate)) {
|
|
31
37
|
seen.add(candidate);
|
|
38
|
+
next.set(result, i + 1);
|
|
32
39
|
return candidate;
|
|
33
40
|
}
|
|
34
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/workspace/slug.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,SAAS,KAAK,CAAC,SAAiB;IAC9B,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;AAChE,CAAC;AAiBD
|
|
1
|
+
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/workspace/slug.ts"],"names":[],"mappings":"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","sourcesContent":["/** Lowercase one code point with Go's simple case mapping, which keeps `İ` one `i`. */\nfunction lower(character: string): string {\n return character === \"\\u0130\" ? \"i\" : character.toLowerCase();\n}\n\nexport interface Slugger {\n /** The anchor generated from heading text. */\n slug(text: string): string;\n /**\n * The anchor of a heading whose attributes set `id`, which replaces the\n * generated one. It is used as written, never numbered, and does not count as\n * issued: Forgejo 16 and Gitea before 1.26 record it without the\n * `user-content-` prefix that generated anchors are compared with, and Gitea\n * 1.26 and later number nothing. Only an id written with that prefix, which\n * the renderers do not add twice, takes the anchor after it. Links are\n * matched without the prefix, so that anchor is reachable with and without it.\n */\n custom(id: string): string;\n}\n\n/**\n * Number repeated anchors `-1`, `-2`, ... checked against every anchor already\n * issued, and give a heading without anchor characters the anchor `heading`.\n * The renderers prefix `user-content-`, which their page scripts hide from\n * authors, so links use the bare anchor. A generated anchor that already starts\n * with the prefix is not prefixed again: `## user-content-setup` is reached as\n * `#setup`, and a later `## Setup` becomes `#setup-1`.\n *\n * The renderers try `-1`, `-2`, ... from the start for each repeat, which takes\n * time that grows with the square of the repeats. Each anchor here keeps the\n * number to try next, as GitHub's anchor library does: every number below it\n * is taken, and stays taken, so the search from there finds the same one.\n */\nfunction createSlugger(clean: (text: string) => string): Slugger {\n const seen = new Set<string>();\n const next = new Map<string, number>();\n return {\n custom(id) {\n const anchor = id.replace(/^user-content-/, \"\");\n if (anchor !== id) seen.add(anchor);\n return anchor;\n },\n slug(text) {\n const result = (clean(text) || \"heading\").replace(/^user-content-/, \"\");\n if (!seen.has(result)) {\n seen.add(result);\n return result;\n }\n for (let i = next.get(result) ?? 1; ; i++) {\n const candidate = `${result}-${i}`;\n if (!seen.has(candidate)) {\n seen.add(candidate);\n next.set(result, i + 1);\n return candidate;\n }\n }\n },\n };\n}\n\n/**\n * Heading anchors as Forgejo, and therefore Codeberg, generates them. Unicode letters,\n * numbers, and underscores are kept and lowercased; every other run of\n * characters becomes a single hyphen, with none leading or trailing.\n */\nexport function createForgejoSlugger(): Slugger {\n return createSlugger(forgejoAnchor);\n}\n/** One Forgejo anchor without numbering. */\nexport function forgejoAnchor(text: string): string {\n let result = \"\";\n let pending = false;\n for (const character of text) {\n if (/[\\p{L}\\p{N}_]/u.test(character)) {\n if (pending && result) result += \"-\";\n pending = false;\n result += lower(character);\n } else pending = true;\n }\n return result;\n}\n\n/**\n * Heading anchors as Gitea 1.21 and later generates them. Surrounding\n * whitespace is trimmed; Unicode letters, numbers, `_`, and `-` are kept and\n * lowercased; each remaining whitespace character becomes a hyphen; everything\n * else, including combining marks, is dropped. Gitea 1.26 and later give\n * repeated headings the same anchor and punctuation-only headings none, so the\n * numbered and `heading` anchors that earlier versions generate are accepted\n * as well.\n */\nexport function createGiteaSlugger(): Slugger {\n return createSlugger(giteaAnchor);\n}\n/** One Gitea anchor without numbering, as Gitea 1.26 and later generate them. */\nexport function giteaAnchor(text: string): string {\n let result = \"\";\n for (const character of text.replace(/^\\p{White_Space}+|\\p{White_Space}+$/gu, \"\")) {\n if (/[\\p{L}\\p{N}_-]/u.test(character)) result += lower(character);\n else if (/\\p{White_Space}/u.test(character)) result += \"-\";\n }\n return result;\n}\n"]}
|
package/dist/workspace/vault.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { exists, refusal, refusalText } from "./access.js";
|
|
4
|
+
import { splitByteOrderMark } from "../syntax/parse.js";
|
|
4
5
|
/** Whether `directory` has a `.obsidian` folder; a refusal is thrown as it is. */
|
|
5
6
|
async function hasSettingsFolder(directory) {
|
|
6
7
|
try {
|
|
@@ -84,7 +85,8 @@ export async function lineBreakSetting(directory) {
|
|
|
84
85
|
}
|
|
85
86
|
let settings;
|
|
86
87
|
try {
|
|
87
|
-
|
|
88
|
+
// A byte order mark, which some Windows programs write, is no part of the JSON.
|
|
89
|
+
settings = JSON.parse(splitByteOrderMark(text)[1]);
|
|
88
90
|
}
|
|
89
91
|
catch {
|
|
90
92
|
return { problem: { code: "INVALID", reason: "not valid JSON" } };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/workspace/vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/workspace/vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AA2BxD,kFAAkF;AAClF,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IAChD,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAI,KAA+B,CAAC,IAAI,CAAC;QACnD,gEAAgE;QAChE,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAC1D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AACD;;;GAGG;AACH,SAAS,YAAY,CAAC,QAAgB,EAAE,KAAc;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,IAAI;QACT,CAAC,CAAC,IAAI,KAAK,CAAC,uBAAuB,QAAQ,KAAK,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACvF,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AACD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,CAAC,GAAG,SAAS,uBAAuB,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AACD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,SAAS,CAAC;YACR,IAAI,MAAM,iBAAiB,CAAC,OAAO,CAAC;gBAAE,OAAO,OAAO,CAAC;YACrD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;YACvF,OAAO,GAAG,MAAM,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,CAAC,GAAG,QAAQ,8BAA8B,EAAE,KAAK,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AACD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IAC1D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACpC,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,IAAI;YAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QAClE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YACpD,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;QAChE,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACH,gFAAgF;QAChF,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAC;IACpE,CAAC;IACD,OAAO;QACL,KAAK,EACH,OAAO,QAAQ,KAAK,QAAQ;YAC5B,QAAQ,KAAK,IAAI;YACjB,kBAAkB,IAAI,QAAQ;YAC9B,QAAQ,CAAC,gBAAgB,KAAK,IAAI;KACrC,CAAC;AACJ,CAAC;AACD,iFAAiF;AACjF,MAAM,UAAU,OAAO,CAAC,MAAe,EAAE,IAAY;IACnD,IAAI,KAAwB,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM;QACxB,IACE,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YAClD,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;YAEjD,KAAK,GAAG,KAAK,CAAC;IAClB,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { exists, refusal, refusalText } from \"./access.js\";\nimport type { RefusalCode } from \"./access.js\";\nimport { splitByteOrderMark } from \"../syntax/parse.js\";\n\n/** An Obsidian vault that holds documents of a workspace. */\nexport interface Vault {\n /**\n * The part of the workspace that the vault holds: its folder relative to the\n * workspace root, or \"\" when the vault is the root or a folder above it.\n */\n path: string;\n /**\n * The `strictLineBreaks` setting in the vault's `.obsidian/app.json`;\n * undefined when the file is absent or could not be used.\n */\n strictLineBreaks?: boolean;\n /**\n * For a vault whose folder lies above the workspace root: the root's path\n * from that folder, with forward slashes. The workspace is then only a part\n * of the vault.\n */\n rootInVault?: string;\n}\n/** Why a vault's settings file could not be used: the system's refusal, or its content. */\nexport interface SettingsProblem {\n code: RefusalCode | \"INVALID\";\n reason: string;\n}\n\n/** Whether `directory` has a `.obsidian` folder; a refusal is thrown as it is. */\nasync function hasSettingsFolder(directory: string): Promise<boolean> {\n try {\n return (await stat(path.join(directory, \".obsidian\"))).isDirectory();\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n // Nothing has that name, or `directory` is not a folder itself.\n if (code === \"ENOENT\" || code === \"ENOTDIR\") return false;\n throw error;\n }\n}\n/**\n * A refusal stays an error, in words: taking a folder for no vault could format\n * its notes as another dialect. Any other error is passed on.\n */\nfunction unknownVault(question: string, error: unknown): unknown {\n const code = refusal(error);\n return code\n ? new Error(`Cannot tell whether ${question} (${refusalText(code)})`, { cause: error })\n : error;\n}\n/**\n * Whether `directory` is the root of an Obsidian vault: Obsidian keeps a vault's\n * settings in a `.obsidian` folder there. A file of that name is not one.\n */\nexport async function isVault(directory: string): Promise<boolean> {\n try {\n return await hasSettingsFolder(directory);\n } catch (error) {\n throw unknownVault(`${directory} is an Obsidian vault`, error);\n }\n}\n/**\n * The folder of the vault that holds `location`, a file or a folder that need\n * not exist: the nearest folder at or above it that contains `.obsidian`. The\n * search ends at a repository boundary, a folder that contains `.git`, which is\n * the last one examined. Discovery leaves the documents of a repository inside\n * a workspace alone, so a repository checked out inside a vault is not read as\n * that vault's notes.\n */\nexport async function enclosingVault(location: string): Promise<string | undefined> {\n let current = path.resolve(location);\n try {\n for (;;) {\n if (await hasSettingsFolder(current)) return current;\n const parent = path.dirname(current);\n if (parent === current || (await exists(path.join(current, \".git\")))) return undefined;\n current = parent;\n }\n } catch (error) {\n throw unknownVault(`${location} is inside an Obsidian vault`, error);\n }\n}\n/**\n * The `strictLineBreaks` setting of the vault in `directory`: undefined without\n * a settings file, and a problem instead when the file is there but cannot be\n * used. Unverified settings are safe, because Obsidian reflow needs them\n * verified; any other read error is a fault.\n */\nexport async function lineBreakSetting(\n directory: string,\n): Promise<{ value?: boolean; problem?: SettingsProblem }> {\n const app = path.join(directory, \".obsidian\", \"app.json\");\n let text: string;\n try {\n if (!(await exists(app))) return {};\n text = await readFile(app, \"utf8\");\n } catch (error) {\n const code = refusal(error);\n if (code) return { problem: { code, reason: refusalText(code) } };\n if ((error as NodeJS.ErrnoException).code === \"EISDIR\")\n return { problem: { code: \"INVALID\", reason: \"not a file\" } };\n throw error;\n }\n let settings: unknown;\n try {\n // A byte order mark, which some Windows programs write, is no part of the JSON.\n settings = JSON.parse(splitByteOrderMark(text)[1]);\n } catch {\n return { problem: { code: \"INVALID\", reason: \"not valid JSON\" } };\n }\n return {\n value:\n typeof settings === \"object\" &&\n settings !== null &&\n \"strictLineBreaks\" in settings &&\n settings.strictLineBreaks === true,\n };\n}\n/** The vault that holds the workspace file `name`: the deepest one around it. */\nexport function vaultOf(vaults: Vault[], name: string): Vault | undefined {\n let found: Vault | undefined;\n for (const vault of vaults)\n if (\n (!vault.path || name.startsWith(`${vault.path}/`)) &&\n (!found || vault.path.length > found.path.length)\n )\n found = vault;\n return found;\n}\n"]}
|