@primeui-devkit/markdown-core 0.1.0-rc.3 → 0.1.0-rc.5
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/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/llms.d.ts +5 -9
- package/dist/plugins/highlight.d.ts +8 -53
- package/dist/plugins/highlight.js +1 -1
- package/dist/plugins/sanitize.d.ts +43 -0
- package/dist/plugins/sanitize.js +1 -0
- package/dist/preset.d.ts +6 -13
- package/dist/preset.js +1 -1
- package/dist/search.d.ts +4 -13
- package/dist/tree.d.ts +14 -22
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ElementNode as MarkdownElement, Node as MarkdownNode, ParserOptions as MarkdownParseOptions, ComarkParseFn as MarkdownParser, ComarkPlugin as MarkdownPlugin, NodeRenderData as MarkdownRenderData, MarkdownDocument as MarkdownTree, autoCloseMarkdown, createMarkdownParser, defineComarkPlugin as defineMarkdownPlugin, parseFrontmatter, parseMarkdown } from 'comark';
|
|
2
2
|
export { pascalCase, resolveAttributes } from 'comark/utils';
|
|
3
3
|
export { HeadingSection, TocItem, childrenOf, descriptionFromTree, headingSections, isElement, propsOf, tagOf, textOf, titleFromTree, tocFromTree, walkTree } from './tree.js';
|
|
4
|
+
export { SanitizeOptions, componentMap, defaultAllowedProtocols, defaultBlockedTags, isPrototypeKey, isSafeAttribute, sanitizeOptions, sanitizeTree } from './plugins/sanitize.js';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{childrenOf as e,descriptionFromTree as t,headingSections as n,isElement as r,propsOf as i,tagOf as a,textOf as o,titleFromTree as s,tocFromTree as c,walkTree as l}from"./tree.js";import{
|
|
1
|
+
import{childrenOf as e,descriptionFromTree as t,headingSections as n,isElement as r,propsOf as i,tagOf as a,textOf as o,titleFromTree as s,tocFromTree as c,walkTree as l}from"./tree.js";import{componentMap as u,defaultAllowedProtocols as d,defaultBlockedTags as f,isPrototypeKey as p,isSafeAttribute as m,sanitizeOptions as h,sanitizeTree as g}from"./plugins/sanitize.js";import{autoCloseMarkdown as _,createMarkdownParser as v,defineComarkPlugin as y,parseFrontmatter as b,parseMarkdown as x}from"comark";import{pascalCase as S,resolveAttributes as C}from"comark/utils";export{_ as autoCloseMarkdown,e as childrenOf,u as componentMap,v as createMarkdownParser,d as defaultAllowedProtocols,f as defaultBlockedTags,y as defineMarkdownPlugin,t as descriptionFromTree,n as headingSections,r as isElement,p as isPrototypeKey,m as isSafeAttribute,b as parseFrontmatter,x as parseMarkdown,S as pascalCase,i as propsOf,C as resolveAttributes,h as sanitizeOptions,g as sanitizeTree,a as tagOf,o as textOf,s as titleFromTree,c as tocFromTree,l as walkTree};
|
package/dist/llms.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ interface LlmsPage {
|
|
|
3
3
|
route: string;
|
|
4
4
|
/** Raw markdown source of the page. */
|
|
5
5
|
markdown: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Explicit title; defaults to the first `# ` heading. */
|
|
7
7
|
title?: string;
|
|
8
|
-
/**
|
|
8
|
+
/** One-line description, appended to index links and full sections. */
|
|
9
9
|
description?: string;
|
|
10
10
|
}
|
|
11
11
|
interface LlmsIndexOptions {
|
|
@@ -15,11 +15,7 @@ interface LlmsIndexOptions {
|
|
|
15
15
|
description?: string;
|
|
16
16
|
/** Absolute origin used in links, e.g. 'https://vue.example.dev'. */
|
|
17
17
|
siteUrl: string;
|
|
18
|
-
/**
|
|
19
|
-
* How each link points at a page, given its route:
|
|
20
|
-
* - 'page' (default): `${siteUrl}/${route}`
|
|
21
|
-
* - 'raw': `${siteUrl}/raw/${route}.md`
|
|
22
|
-
*/
|
|
18
|
+
/** Link target: 'page' (default) is `${siteUrl}/${route}`, 'raw' is `${siteUrl}/raw/${route}.md`. */
|
|
23
19
|
linkTarget?: 'page' | 'raw';
|
|
24
20
|
/** Heading above the link list. @default 'Documentation' */
|
|
25
21
|
heading?: string;
|
|
@@ -33,9 +29,9 @@ interface LlmsFullOptions {
|
|
|
33
29
|
transform?: (page: LlmsPage) => string;
|
|
34
30
|
}
|
|
35
31
|
declare function pageTitle(page: LlmsPage): string;
|
|
36
|
-
/** llms.txt
|
|
32
|
+
/** Renders llms.txt: site summary plus one link per page. */
|
|
37
33
|
declare function renderLlmsIndex(pages: LlmsPage[], options: LlmsIndexOptions): string;
|
|
38
|
-
/** llms-full.txt
|
|
34
|
+
/** Renders llms-full.txt: every page's markdown in one document. */
|
|
39
35
|
declare function renderLlmsFull(pages: LlmsPage[], options: LlmsFullOptions): string;
|
|
40
36
|
/** File plan for the raw markdown mirror: [route, content]. */
|
|
41
37
|
declare function rawMarkdownFiles(pages: LlmsPage[], options?: {
|
|
@@ -1,30 +1,6 @@
|
|
|
1
|
-
import { ComarkPlugin,
|
|
1
|
+
import { ComarkPlugin, MarkdownDocument } from 'comark';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* NOTE ON THE OPTIONAL PEER — importing this subpath without `shiki` installed fails at
|
|
5
|
-
* module load with `Cannot find package 'shiki'`, thrown from inside the backend rather
|
|
6
|
-
* than from here. That cannot be caught: the failing import is the static one above, which
|
|
7
|
-
* runs before any code in this file. Making it dynamic would push the cost onto every
|
|
8
|
-
* caller and would still not help {@link default}, which is synchronous by contract.
|
|
9
|
-
*
|
|
10
|
-
* So the message stays as it is, and the requirement is documented instead: the README and
|
|
11
|
-
* the package's `peerDependenciesMeta` both state that highlighting needs `shiki`.
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Syntax highlighting for code blocks.
|
|
15
|
-
*
|
|
16
|
-
* The options below are this package's own. The backend exposes the highlighting engine's
|
|
17
|
-
* types directly — themes, language registrations, transformers — and re-exporting those
|
|
18
|
-
* would tie every caller to that engine through a package whose whole purpose is to keep
|
|
19
|
-
* it out of sight.
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* A theme, either by name or as a full definition.
|
|
23
|
-
*
|
|
24
|
-
* The definition form is deliberately opaque: describing it would pull the highlighting
|
|
25
|
-
* engine's types into this package's public surface, which is what it exists to avoid.
|
|
26
|
-
* Pass the value a `shiki/themes/*` module default-exports.
|
|
27
|
-
*/
|
|
3
|
+
/** A theme name, or a definition as a `shiki/themes/*` module default-exports. */
|
|
28
4
|
type HighlightTheme = string | (object & {
|
|
29
5
|
name?: string;
|
|
30
6
|
});
|
|
@@ -33,27 +9,14 @@ type HighlightLanguage = object;
|
|
|
33
9
|
/** A code-block transformer, as `@shikijs/transformers` returns. */
|
|
34
10
|
type HighlightTransformer = object;
|
|
35
11
|
interface HighlightOptions {
|
|
36
|
-
/**
|
|
37
|
-
* Themes to render with. Both are emitted, so a page can switch between light and dark
|
|
38
|
-
* without highlighting anything again.
|
|
39
|
-
*
|
|
40
|
-
* A registered name works, as does a theme definition — pass the latter to use a theme
|
|
41
|
-
* the backend does not ship. Names are checked first, because a name the backend does
|
|
42
|
-
* not know leaves every block unhighlighted without reporting anything.
|
|
43
|
-
*/
|
|
12
|
+
/** Light and dark themes, both emitted. Unknown theme names throw. */
|
|
44
13
|
themes?: {
|
|
45
14
|
light: HighlightTheme;
|
|
46
15
|
dark: HighlightTheme;
|
|
47
16
|
};
|
|
48
|
-
/**
|
|
49
|
-
* Languages to preload. Left unset, languages load on demand, which needs the backend's
|
|
50
|
-
* full bundle; preloading keeps a build to the grammars it actually uses.
|
|
51
|
-
*/
|
|
17
|
+
/** Languages to preload. Unset loads them on demand from the full bundle. */
|
|
52
18
|
languages?: HighlightLanguage[];
|
|
53
|
-
/**
|
|
54
|
-
* Transformers applied to every block — line markers such as `[!code highlight]` come
|
|
55
|
-
* from these.
|
|
56
|
-
*/
|
|
19
|
+
/** Transformers applied to every block, e.g. for `[!code highlight]` markers. */
|
|
57
20
|
transformers?: HighlightTransformer[];
|
|
58
21
|
/** Whether to inline the theme's background and colour on the block. Defaults to `false`. */
|
|
59
22
|
inlineStyles?: boolean;
|
|
@@ -66,9 +29,7 @@ declare const defaultThemes: {
|
|
|
66
29
|
/** Themes available without registering any of your own. */
|
|
67
30
|
declare function availableThemes(): Promise<string[]>;
|
|
68
31
|
/**
|
|
69
|
-
* Highlight every code block in a parsed tree.
|
|
70
|
-
*
|
|
71
|
-
* Highlighting is asynchronous and happens after parsing, so it runs as its own step:
|
|
32
|
+
* Highlight every code block in a parsed tree, as an async step after parsing.
|
|
72
33
|
*
|
|
73
34
|
* @example
|
|
74
35
|
* ```ts
|
|
@@ -79,14 +40,8 @@ declare function availableThemes(): Promise<string[]>;
|
|
|
79
40
|
* const tree = await highlightTree(await parse(source));
|
|
80
41
|
* ```
|
|
81
42
|
*/
|
|
82
|
-
declare function highlightTree(tree:
|
|
83
|
-
/**
|
|
84
|
-
* The same highlighting as a parser plugin.
|
|
85
|
-
*
|
|
86
|
-
* Kept for parsers that drive the plugin pipeline themselves. Prefer {@link highlightTree}:
|
|
87
|
-
* the plugin form marks blocks as highlighted without tokenising them, because tokenising
|
|
88
|
-
* is asynchronous and the plugin hook is not.
|
|
89
|
-
*/
|
|
43
|
+
declare function highlightTree(tree: MarkdownDocument, options?: HighlightOptions): Promise<MarkdownDocument>;
|
|
44
|
+
/** Parser plugin form: tokenises every block while parsing. {@link highlightTree} does the same for a tree parsed earlier or cached. */
|
|
90
45
|
declare function highlight(options?: HighlightOptions): ComarkPlugin<any, any>;
|
|
91
46
|
|
|
92
47
|
export { availableThemes, highlight as default, defaultThemes, highlightTree };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e,{getHighlighter as t,highlightCodeBlocks as n}from"comark/plugins/
|
|
1
|
+
import e,{getHighlighter as t,highlightCodeBlocks as n}from"comark/plugins/shiki";import{bundledThemes as r}from"shiki";const i=e=>e?[e.light,e.dark].filter(e=>typeof e==`string`):[],a={light:`material-theme-lighter`,dark:`material-theme-palenight`};async function o(){let e=await t();return[.../* @__PURE__ */ new Set([...Object.keys(r),...e.getLoadedThemes?.()??[]])]}async function s(e,t={}){let{themes:r,languages:a,transformers:s,inlineStyles:c=!1}=t,l=i(r);if(l.length>0){let e=await o(),t=l.filter(t=>!e.includes(t));if(t.length>0)throw Error(`Unknown theme${t.length>1?`s`:``}: ${t.join(`, `)}. Available: ${e.join(`, `)}.`)}return await n(e,{...r?{themes:r}:{},...a?{languages:a}:{},...s?{transformers:s}:{},preStyles:c})}function c(t={}){let{themes:n,languages:r,transformers:i,inlineStyles:a=!1}=t;return e({...n?{themes:n}:{},...r?{languages:r}:{},...i?{transformers:i}:{},preStyles:a})}export{o as availableThemes,c as default,a as defaultThemes,s as highlightTree};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as comark from 'comark';
|
|
2
|
+
import { Node } from 'comark';
|
|
3
|
+
|
|
4
|
+
interface SanitizeOptions {
|
|
5
|
+
/** Tags removed with everything inside them, added to the default list. */
|
|
6
|
+
blockedTags?: string[];
|
|
7
|
+
/** Tags taken off the blocked list, e.g. `['iframe']` for embeds you trust or `['form', 'input', 'button']` for a form. */
|
|
8
|
+
allowedTags?: string[];
|
|
9
|
+
/**
|
|
10
|
+
* URL schemes allowed in links and sources. Relative URLs and `data:image/` image sources always pass.
|
|
11
|
+
* @default ['http', 'https', 'mailto', 'tel']
|
|
12
|
+
*/
|
|
13
|
+
allowedProtocols?: string[];
|
|
14
|
+
/** Keeps every inline style. Off, a style keeps only colour and font declarations, which cannot move content or lay it over the page. @default false */
|
|
15
|
+
allowStyle?: boolean;
|
|
16
|
+
/** Components the `as` attribute may switch an element to; any other `as` is removed. @default [] */
|
|
17
|
+
allowedComponents?: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Elements that run code, load another document, change how the page resolves URLs, or submit or capture input. */
|
|
20
|
+
declare const defaultBlockedTags: string[];
|
|
21
|
+
declare const defaultAllowedProtocols: string[];
|
|
22
|
+
/** Whether a name would read Object.prototype from a plain object, `constructor` and `toString` among them. */
|
|
23
|
+
declare function isPrototypeKey(name: string): boolean;
|
|
24
|
+
/** Whether an attribute is safe to write: a plain name, not an event handler, not HTML, not a style unless allowed, not a URL outside `allowedProtocols`. A binding counts only when it is a literal. */
|
|
25
|
+
declare function isSafeAttribute(tag: string, key: string, value: unknown, options?: SanitizeOptions): boolean;
|
|
26
|
+
/** A copy of the tree with what would run script, submit a form, restyle the page or swap in another component removed; for a tree that did not come through the plugin. */
|
|
27
|
+
declare function sanitizeTree<T extends {
|
|
28
|
+
nodes: Node[];
|
|
29
|
+
}>(tree: T, options?: SanitizeOptions): T;
|
|
30
|
+
/** The `sanitize` option every renderer takes, as options to pass on, or `false` when it is off. Unset means on. */
|
|
31
|
+
declare function sanitizeOptions(setting: boolean | SanitizeOptions | undefined): SanitizeOptions | false;
|
|
32
|
+
/** A component map whose lookups never reach Object.prototype, so a `::constructor` node renders as an element, not as `Object`. */
|
|
33
|
+
/**
|
|
34
|
+
* Whether a component registered app-wide may render a markdown tag. `Prose*` components restyle the elements sanitizing
|
|
35
|
+
* already allowed, so they always may; any other one only when sanitizing is off or `allowedComponents` names it.
|
|
36
|
+
*/
|
|
37
|
+
declare function allowsGlobalComponent(setting: boolean | SanitizeOptions | undefined, name: string): boolean;
|
|
38
|
+
declare function componentMap<T>(components: Record<string, T> | null | undefined): Record<string, T>;
|
|
39
|
+
/** Removes blocked elements, event handler, HTML and style attributes, unlisted `as` targets and disallowed URL schemes. Use for untrusted markdown; add it last so it sees what other plugins add. */
|
|
40
|
+
declare const _default: comark.ComarkPluginFactory<SanitizeOptions, {}, {}>;
|
|
41
|
+
|
|
42
|
+
export { allowsGlobalComponent, componentMap, _default as default, defaultAllowedProtocols, defaultBlockedTags, isPrototypeKey, isSafeAttribute, sanitizeOptions, sanitizeTree };
|
|
43
|
+
export type { SanitizeOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineComarkPlugin as e}from"comark";const t=[`script`,`style`,`iframe`,`frame`,`frameset`,`object`,`embed`,`applet`,`portal`,`base`,`meta`,`link`,`animate`,`animatemotion`,`animatetransform`,`animatecolor`,`set`,`handler`,`listener`,`form`,`input`,`button`,`textarea`,`select`],n=[`http`,`https`,`mailto`,`tel`],r=/^[a-z_][a-z0-9_.:-]*$/i,i=/^[a-z][a-z0-9_.:-]*$/i,a=/* @__PURE__ */ new Set([`innerhtml`,`outerhtml`,`dangerouslysetinnerhtml`,`srcdoc`]),o=/* @__PURE__ */ new Set([`href`,`src`,`action`,`formaction`,`xlink:href`,`xlinkhref`,`poster`,`background`,`cite`,`data`,`ping`,`lowsrc`,`dynsrc`,`longdesc`,`to`,`url`]),s=/^(?:color|background-color|font-style|font-weight|text-align|text-decoration(?:-line|-color|-style)?|--shiki-[a-z0-9-]+)$/,c=/^[\w\s#%.,()+-]+$/,l=/* @__PURE__ */ new Set([`__proto__`,`constructor`,`prototype`]);function u(e){return Object.prototype.hasOwnProperty.call(Object.prototype,e)}function d(e){return/^on[a-z]+$/.test(e.toLowerCase())||/^on[^a-z]/.test(e)}function f(e){return Number.isInteger(e)&&e>0&&e<=1114111&&(e<55296||e>57343)?String.fromCodePoint(e):`�`}function p(e){return e.replace(/&#x([0-9a-f]+);?/gi,(e,t)=>f(Number.parseInt(t,16))).replace(/&#(\d+);?/g,(e,t)=>f(Number(t))).replace(/:?/gi,`:`).replace(/&tab;?|&newline;?/gi,``).replace(/[\u0000- \u007f-\u009f]/g,``).toLowerCase()}function m(e,t,n,r){let i=p(e),a=/^([a-z][a-z0-9+.-]*):/.exec(i)?.[1];return!a||r.has(a)?!0:a===`data`&&t===`src`&&n===`img`&&i.startsWith(`data:image/`)}const h=e=>e.replace(/[-_]/g,``).toLowerCase();function g(e={}){let r=new Set((e.allowedTags??[]).map(e=>e.toLowerCase()));return{blocked:new Set([...t,...e.blockedTags??[]].map(e=>e.toLowerCase()).filter(e=>!r.has(e))),allowedProtocols:new Set((e.allowedProtocols??n).map(e=>e.toLowerCase().replace(/:$/,``))),allowStyle:e.allowStyle===!0,allowedComponents:new Set((e.allowedComponents??[]).map(h))}}const _=(e,t)=>s.test(e.toLowerCase())&&c.test(t)&&!/url\(|expression|image/i.test(t);function v(e){if(typeof e==`string`){let t=e.split(`;`).map(e=>/^([-a-z0-9]+)\s*:([\s\S]*)$/i.exec(e.trim())).filter(e=>e!==null&&_(e[1],e[2].trim())).map(([,e,t])=>`${e}:${t.trim()}`);return t.length?t.join(`;`):void 0}if(e&&typeof e==`object`&&!Array.isArray(e)){let t=Object.entries(e).filter(([e,t])=>(typeof t==`string`||typeof t==`number`)&&_(e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),String(t)));return t.length?Object.fromEntries(t):void 0}}const y=Symbol(`unknown`);function b(e,t){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{}let[n,...r]=e.split(`.`);if(!t||n!==`frontmatter`&&n!==`meta`||r.some(e=>l.has(e)))return y;let i=t[n];for(let e of r){if(!i||typeof i!=`object`||!Object.hasOwn(i,e))return;i=i[e]}return i}function x(e,t){return typeof e==`string`&&!u(e)&&t.allowedComponents.has(h(e))}function S(e,t,n,i,s){let c=t.startsWith(`:`),u=c?t.slice(1):t,f=u.toLowerCase();if(!r.test(u)||d(u)||a.has(f))return;if(f===`style`&&!i.allowStyle){let e=v(c?b(n,s):n);return e===void 0?void 0:c?[t,JSON.stringify(e)]:[t,e]}if((!o.has(f)||f===`data`&&e!==`object`)&&f!==`as`)return c&&typeof n==`string`&&n.split(`.`).some(e=>l.has(e))?void 0:[t,n];let p=c?b(n,s):n;if(p!==y&&typeof p==`string`&&!(f===`as`?!x(p,i):!m(p,f,e,i.allowedProtocols)))return c?[t,JSON.stringify(p)]:[t,n]}function C(e,t,n,r={}){return t===`$`||S(e.toLowerCase(),t,n,g(r))!==void 0}function w(e){let t=`:disabled`in e?e[`:disabled`]===`true`||e[`:disabled`]===!0:e.disabled===``||e.disabled===!0||e.disabled===`disabled`||e.disabled===`true`;return e.type===`checkbox`&&!(`:type`in e)&&t}function T(e,t,n,r){let i={};for(let[a,o]of Object.entries(t)){let t=a===`$`?[a,o]:S(e,a,o,n,r);t&&(i[t[0]]=t[1])}return i}function E(e,t,n){if(!Array.isArray(e))return typeof e==`string`?e:void 0;let[r,a,...o]=e;if(r===null)return e;if(typeof r!=`string`||!i.test(r)||u(r))return;let s=r.toLowerCase(),c=a&&typeof a==`object`?a:{};if(t.blocked.has(s)&&!(s===`input`&&w(c)))return;let l=o.map(e=>E(e,t,n)).filter(e=>e!==void 0);return[r,T(s,c,t,n),...l]}function D(e,t={}){let n=g(t),r=e,i={frontmatter:r.frontmatter??r.data??{},meta:r.meta??{}};return{...e,nodes:(e.nodes??[]).map(e=>E(e,n,i)).filter(e=>e!==void 0)}}function O(e){return e===!1?!1:typeof e==`object`&&e?e:{}}function k(e,t){let n=O(e);return n===!1||/^prose[-_]?/i.test(t)?!0:!u(t)&&g(n).allowedComponents.has(h(t))}function A(e){let t=Object.create(null);for(let e of Object.getOwnPropertyNames(Object.prototype))t[e]=void 0;return Object.assign(t,e??{})}var j=e((e={})=>({name:`primeui:sanitize`,post(t){t.tree.nodes=D(t.tree,e).nodes}}));export{k as allowsGlobalComponent,A as componentMap,j as default,n as defaultAllowedProtocols,t as defaultBlockedTags,u as isPrototypeKey,C as isSafeAttribute,O as sanitizeOptions,D as sanitizeTree};
|
package/dist/preset.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { ComarkPlugin, ComarkParseFn } from 'comark';
|
|
2
|
+
import { SanitizeOptions } from './plugins/sanitize.js';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* Options handed to the parser underneath.
|
|
5
|
-
*
|
|
6
|
-
* Deliberately loose: the parsing backend accepts more than this preset models, and
|
|
7
|
-
* naming its option type here would put its full schema — and its name — into a public
|
|
8
|
-
* signature. Anything valid for the backend passes through.
|
|
9
|
-
*/
|
|
4
|
+
/** Options passed through to the underlying parser, kept loose so the backend type stays private. */
|
|
10
5
|
type ParserPassthrough = Record<string, unknown>;
|
|
11
6
|
interface DocsParserOptions {
|
|
12
7
|
/** Heading ids for anchors. @default true */
|
|
@@ -17,16 +12,14 @@ interface DocsParserOptions {
|
|
|
17
12
|
alert?: boolean;
|
|
18
13
|
/** {{ binding }} interpolation. @default true */
|
|
19
14
|
binding?: boolean;
|
|
20
|
-
/** Extra plugins
|
|
15
|
+
/** Extra plugins, e.g. a configured highlight plugin from ./plugins/highlight. */
|
|
21
16
|
plugins?: ComarkPlugin<any, any>[];
|
|
17
|
+
/** Strips script, event handlers, styles, form controls and unsafe URLs after every other plugin. Disable only for trusted markdown. @default true */
|
|
18
|
+
sanitize?: boolean | SanitizeOptions;
|
|
22
19
|
/** Options forwarded to the underlying parser. Plugins are set by this preset. */
|
|
23
20
|
parse?: ParserPassthrough;
|
|
24
21
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Docs-flavored parser preset: the plugin set every showcase/docs app needs,
|
|
27
|
-
* assembled once. Syntax highlighting is intentionally NOT bundled — shiki is
|
|
28
|
-
* heavy and optional; pass a configured highlight plugin via `plugins`.
|
|
29
|
-
*/
|
|
22
|
+
/** Docs parser preset. Highlighting is not bundled; pass a configured highlight plugin via `plugins`. */
|
|
30
23
|
declare function createDocsParser(options?: DocsParserOptions): ComarkParseFn<any, any>;
|
|
31
24
|
|
|
32
25
|
export { createDocsParser };
|
package/dist/preset.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import e,{sanitizeOptions as t}from"./plugins/sanitize.js";import{createMarkdownParser as n}from"comark";import r from"comark/plugins/alert";import i from"comark/plugins/binding";import a from"comark/plugins/headings";import o from"comark/plugins/toc";function s(s={}){let c=[];s.headings!==!1&&c.push(a()),s.toc!==!1&&c.push(o()),s.alert!==!1&&c.push(r()),s.binding!==!1&&c.push(i()),s.plugins&&c.push(...s.plugins);let l=t(s.sanitize);return l&&c.push(e(l)),n({...s.parse,plugins:c})}export{s as createDocsParser};
|
package/dist/search.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MarkdownDocument } from 'comark';
|
|
2
2
|
|
|
3
3
|
interface SearchPage {
|
|
4
4
|
/** Route of the page, e.g. '/charts/animation'. */
|
|
5
5
|
route: string;
|
|
6
|
-
tree:
|
|
6
|
+
tree: MarkdownDocument;
|
|
7
7
|
}
|
|
8
8
|
interface SearchDocument {
|
|
9
9
|
/** Route plus anchor, e.g. '/charts/animation#easing'. */
|
|
@@ -13,18 +13,9 @@ interface SearchDocument {
|
|
|
13
13
|
heading: string;
|
|
14
14
|
text: string;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Flattens parsed pages into heading-level search documents. The output is
|
|
18
|
-
* plain JSON: ship it to the client for local search, hand it to Algolia, or
|
|
19
|
-
* serve it to agents — same records everywhere.
|
|
20
|
-
*/
|
|
16
|
+
/** Flattens parsed pages into heading-level search documents as plain JSON. */
|
|
21
17
|
declare function buildSearchIndex(pages: SearchPage[]): SearchDocument[];
|
|
22
|
-
/**
|
|
23
|
-
* Dependency-free local search over an index: case-insensitive, every term
|
|
24
|
-
* must match, heading/title hits outrank body hits. Good enough for docs-size
|
|
25
|
-
* indexes; swap in Algolia or MiniSearch behind the same SearchDocument shape
|
|
26
|
-
* when the corpus outgrows it.
|
|
27
|
-
*/
|
|
18
|
+
/** Case-insensitive local search; every term must match, heading hits rank above body hits. */
|
|
28
19
|
declare function searchDocuments(index: SearchDocument[], query: string, limit?: number): SearchDocument[];
|
|
29
20
|
|
|
30
21
|
export { buildSearchIndex, searchDocuments };
|
package/dist/tree.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import 'comark/utils';
|
|
1
|
+
import { ElementNode, Node, MarkdownDocument } from 'comark';
|
|
3
2
|
|
|
4
3
|
interface TocItem {
|
|
5
4
|
id: string;
|
|
@@ -8,22 +7,19 @@ interface TocItem {
|
|
|
8
7
|
children?: TocItem[];
|
|
9
8
|
}
|
|
10
9
|
/** Table of contents produced by the toc plugin, normalized to a plain array. */
|
|
11
|
-
declare function tocFromTree(tree:
|
|
10
|
+
declare function tocFromTree(tree: MarkdownDocument | null | undefined): TocItem[];
|
|
12
11
|
/** Page title: frontmatter wins, then the title the parser derived from the first heading. */
|
|
13
|
-
declare function titleFromTree(tree:
|
|
12
|
+
declare function titleFromTree(tree: MarkdownDocument | null | undefined): string;
|
|
14
13
|
/** Page description from frontmatter, when present. */
|
|
15
|
-
declare function descriptionFromTree(tree:
|
|
16
|
-
declare function isElement(node:
|
|
17
|
-
declare function tagOf(node:
|
|
18
|
-
declare function propsOf(node:
|
|
19
|
-
declare function childrenOf(node:
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
declare function walkTree(tree: ComarkTree, visit: (node: ComarkNode, parent: ComarkElement | null) => void | boolean): void;
|
|
25
|
-
/** Plain-text content of a node (or node list) — markup and components stripped. */
|
|
26
|
-
declare function textOf(node: ComarkNode | ComarkNode[]): string;
|
|
14
|
+
declare function descriptionFromTree(tree: MarkdownDocument | null | undefined): string;
|
|
15
|
+
declare function isElement(node: Node): node is ElementNode;
|
|
16
|
+
declare function tagOf(node: ElementNode): string;
|
|
17
|
+
declare function propsOf(node: ElementNode): Record<string, unknown>;
|
|
18
|
+
declare function childrenOf(node: ElementNode): Node[];
|
|
19
|
+
/** Depth-first walk; return `false` from the visitor to skip a node's children. */
|
|
20
|
+
declare function walkTree(tree: MarkdownDocument, visit: (node: Node, parent: ElementNode | null) => void | boolean): void;
|
|
21
|
+
/** Plain-text content of a node or node list, markup stripped. */
|
|
22
|
+
declare function textOf(node: Node | Node[]): string;
|
|
27
23
|
interface HeadingSection {
|
|
28
24
|
/** Heading id (anchor target); empty for content before the first heading. */
|
|
29
25
|
id: string;
|
|
@@ -34,12 +30,8 @@ interface HeadingSection {
|
|
|
34
30
|
/** Plain text of everything under this heading, code blocks excluded. */
|
|
35
31
|
text: string;
|
|
36
32
|
}
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
* unit for search indexing and llms excerpts. Code blocks are excluded so
|
|
40
|
-
* indexes stay prose-focused.
|
|
41
|
-
*/
|
|
42
|
-
declare function headingSections(tree: ComarkTree): HeadingSection[];
|
|
33
|
+
/** Splits a page into heading-anchored plain-text sections, code blocks excluded. */
|
|
34
|
+
declare function headingSections(tree: MarkdownDocument): HeadingSection[];
|
|
43
35
|
|
|
44
36
|
export { childrenOf, descriptionFromTree, headingSections, isElement, propsOf, tagOf, textOf, titleFromTree, tocFromTree, walkTree };
|
|
45
37
|
export type { HeadingSection, TocItem };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primeui-devkit/markdown-core",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.5",
|
|
4
4
|
"author": "PrimeTek Informatics",
|
|
5
5
|
"description": "Framework-agnostic markdown engine. Parses markdown with component directives into a serializable tree consumed by the framework renderers. The parsing backend is an internal implementation detail.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"README.md"
|
|
88
88
|
],
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"comark": "
|
|
90
|
+
"comark": "0.7.0"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
93
|
"shiki": "^4.4.2"
|
|
@@ -102,10 +102,10 @@
|
|
|
102
102
|
"cross-env": "^10.1.0",
|
|
103
103
|
"typescript": "~6.0.0",
|
|
104
104
|
"vitest": "4.1.11",
|
|
105
|
-
"@primeui-devkit/bundle": "0.1.0-rc.
|
|
106
|
-
"@primeui-devkit/cli": "0.1.0-rc.
|
|
107
|
-
"@primeui-devkit/test-config": "0.1.0-rc.
|
|
108
|
-
"@primeui-devkit/ts-config": "0.1.0-rc.
|
|
105
|
+
"@primeui-devkit/bundle": "0.1.0-rc.2",
|
|
106
|
+
"@primeui-devkit/cli": "0.1.0-rc.2",
|
|
107
|
+
"@primeui-devkit/test-config": "0.1.0-rc.2",
|
|
108
|
+
"@primeui-devkit/ts-config": "0.1.0-rc.2"
|
|
109
109
|
},
|
|
110
110
|
"engines": {
|
|
111
111
|
"node": ">=22.18.0"
|