satteri 0.11.1 → 0.11.4
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/compile-options.js +3 -1
- package/dist/compile-types.d.ts +13 -1
- package/dist/compile.js +7 -7
- package/dist/generated/parse-options.d.ts +1 -0
- package/dist/generated/parse-options.js +1 -0
- package/dist/generated/wire-constants.d.ts +1 -0
- package/dist/generated/wire-constants.js +1 -0
- package/dist/hast/hast-visitor.js +3 -0
- package/dist/mdast/mdast-visitor.js +1 -0
- package/dist/op-stream.d.ts +3 -0
- package/dist/op-stream.js +28 -1
- package/dist/plugin.d.ts +6 -1
- package/dist/plugin.js +2 -1
- package/package.json +4 -1
package/dist/compile-options.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ENABLE_DEFINITION_LIST, ENABLE_DIRECTIVE, ENABLE_FOOTNOTES, ENABLE_GFM, ENABLE_HEADING_ATTRIBUTES, ENABLE_MATH, ENABLE_MATH_MULTI_DOLLAR, ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS, ENABLE_SMART_DASHES, ENABLE_SMART_ELLIPSES, ENABLE_SMART_PUNCTUATION, ENABLE_SMART_QUOTES, ENABLE_STRIKETHROUGH, ENABLE_SUBSCRIPT, ENABLE_SUPERSCRIPT, ENABLE_TABLES, ENABLE_TASKLISTS, ENABLE_WIKILINKS, ENABLE_YAML_STYLE_METADATA_BLOCKS, } from "./generated/parse-options.js";
|
|
1
|
+
import { ENABLE_ATTRIBUTES, ENABLE_DEFINITION_LIST, ENABLE_DIRECTIVE, ENABLE_FOOTNOTES, ENABLE_GFM, ENABLE_HEADING_ATTRIBUTES, ENABLE_MATH, ENABLE_MATH_MULTI_DOLLAR, ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS, ENABLE_SMART_DASHES, ENABLE_SMART_ELLIPSES, ENABLE_SMART_PUNCTUATION, ENABLE_SMART_QUOTES, ENABLE_STRIKETHROUGH, ENABLE_SUBSCRIPT, ENABLE_SUPERSCRIPT, ENABLE_TABLES, ENABLE_TASKLISTS, ENABLE_WIKILINKS, ENABLE_YAML_STYLE_METADATA_BLOCKS, } from "./generated/parse-options.js";
|
|
2
2
|
const GFM_PARSE_OPTIONS = ENABLE_TABLES | ENABLE_STRIKETHROUGH | ENABLE_TASKLISTS | ENABLE_GFM;
|
|
3
3
|
const FRONTMATTER_PARSE_OPTIONS = ENABLE_YAML_STYLE_METADATA_BLOCKS | ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS;
|
|
4
4
|
export const DEFAULT_PARSE_OPTIONS = GFM_PARSE_OPTIONS | ENABLE_FOOTNOTES | FRONTMATTER_PARSE_OPTIONS;
|
|
@@ -24,6 +24,8 @@ function featuresToParseOptions(features) {
|
|
|
24
24
|
}
|
|
25
25
|
if (features.headingAttributes)
|
|
26
26
|
options |= ENABLE_HEADING_ATTRIBUTES;
|
|
27
|
+
if (features.attributes)
|
|
28
|
+
options |= ENABLE_ATTRIBUTES;
|
|
27
29
|
if (features.directive)
|
|
28
30
|
options |= ENABLE_DIRECTIVE;
|
|
29
31
|
if (features.superscript)
|
package/dist/compile-types.d.ts
CHANGED
|
@@ -102,8 +102,20 @@ export interface Features {
|
|
|
102
102
|
* ```
|
|
103
103
|
*/
|
|
104
104
|
math?: boolean | MathOptions;
|
|
105
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Heading attributes (`# text { #id .class }`). Default: false.
|
|
107
|
+
*
|
|
108
|
+
* @deprecated Use {@link Features.attributes}, which reads heading attributes
|
|
109
|
+
* as well as attributes on other elements.
|
|
110
|
+
*/
|
|
106
111
|
headingAttributes?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Curly-brace attributes (`{#id .class key=value}`) on fenced code blocks
|
|
114
|
+
* (` ```js {.class} `), inline elements (`*em*{.class}`), and paragraphs,
|
|
115
|
+
* list items, lists, blockquotes, tables, table cells and thematic breaks,
|
|
116
|
+
* as well as on headings. Default: false.
|
|
117
|
+
*/
|
|
118
|
+
attributes?: boolean;
|
|
107
119
|
/** Colon-delimited container directive blocks (`:::`). Default: false. */
|
|
108
120
|
directive?: boolean;
|
|
109
121
|
/** Superscript (`^super^`). Default: false. */
|
package/dist/compile.js
CHANGED
|
@@ -10,8 +10,8 @@ import { MdastReader } from "./mdast/mdast-reader.js";
|
|
|
10
10
|
import { normalizePlugins } from "./plugin.js";
|
|
11
11
|
export function markdownToHtml(source, options = {}) {
|
|
12
12
|
const { features, fileURL, data = {} } = options;
|
|
13
|
-
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, "markdown", data);
|
|
14
|
-
const hastPlugins = normalizePlugins(options.hastPlugins ?? [], "hastPlugins", source, fileURL, "markdown", data);
|
|
13
|
+
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, "markdown", data, features);
|
|
14
|
+
const hastPlugins = normalizePlugins(options.hastPlugins ?? [], "hastPlugins", source, fileURL, "markdown", data, features);
|
|
15
15
|
const hastMayHaveStubs = hastPlugins.length > 0;
|
|
16
16
|
const { parseOptions, convertOptions: nativeConvertOptions } = featuresToNative(features);
|
|
17
17
|
// Without plugins, one NAPI call avoids the handle lifecycle’s extra boundary crossings.
|
|
@@ -102,8 +102,8 @@ export function markdownToJs(source, options = {}) {
|
|
|
102
102
|
function toJsImpl(source, options, mdx) {
|
|
103
103
|
const { mdastPlugins: mdastInput = [], hastPlugins: hastInput = [], features, fileURL, data = {}, ...mdxFields } = options;
|
|
104
104
|
const sourceFormat = mdx ? "mdx" : "markdown";
|
|
105
|
-
const mdastPlugins = normalizePlugins(mdastInput, "mdastPlugins", source, fileURL, sourceFormat, data);
|
|
106
|
-
const hastPlugins = normalizePlugins(hastInput, "hastPlugins", source, fileURL, sourceFormat, data);
|
|
105
|
+
const mdastPlugins = normalizePlugins(mdastInput, "mdastPlugins", source, fileURL, sourceFormat, data, features);
|
|
106
|
+
const hastPlugins = normalizePlugins(hastInput, "hastPlugins", source, fileURL, sourceFormat, data, features);
|
|
107
107
|
const hastMayHaveStubs = hastPlugins.length > 0;
|
|
108
108
|
const mdxOptions = mdxOptionsToNative(mdxFields);
|
|
109
109
|
const { parseOptions, convertOptions: nativeConvertOptions } = featuresToNative(features);
|
|
@@ -239,7 +239,7 @@ function applyCollectedHastCommands(handle, collected, invalidateStubs) {
|
|
|
239
239
|
function toMdastImpl(source, options, mdx) {
|
|
240
240
|
const { features, fileURL, data = {} } = options;
|
|
241
241
|
const sourceFormat = mdx ? "mdx" : "markdown";
|
|
242
|
-
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, sourceFormat, data);
|
|
242
|
+
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, sourceFormat, data, features);
|
|
243
243
|
const { parseOptions } = featuresToNative(features);
|
|
244
244
|
if (mdastPlugins.length === 0) {
|
|
245
245
|
const wire = parseMdastWire(source, parseOptions, mdx, options.position);
|
|
@@ -268,8 +268,8 @@ function toMdastImpl(source, options, mdx) {
|
|
|
268
268
|
function toHastImpl(source, options, mdx) {
|
|
269
269
|
const { features, fileURL, data = {} } = options;
|
|
270
270
|
const sourceFormat = mdx ? "mdx" : "markdown";
|
|
271
|
-
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, sourceFormat, data);
|
|
272
|
-
const hastPlugins = normalizePlugins(options.hastPlugins ?? [], "hastPlugins", source, fileURL, sourceFormat, data);
|
|
271
|
+
const mdastPlugins = normalizePlugins(options.mdastPlugins ?? [], "mdastPlugins", source, fileURL, sourceFormat, data, features);
|
|
272
|
+
const hastPlugins = normalizePlugins(options.hastPlugins ?? [], "hastPlugins", source, fileURL, sourceFormat, data, features);
|
|
273
273
|
const { parseOptions, convertOptions } = featuresToNative(features);
|
|
274
274
|
if (mdastPlugins.length === 0 && hastPlugins.length === 0) {
|
|
275
275
|
const wire = parseHastWire(source, parseOptions, convertOptions, mdx, options.position);
|
|
@@ -9,6 +9,7 @@ export declare const OP_BOOL = 8;
|
|
|
9
9
|
export declare const OP_DATA = 9;
|
|
10
10
|
export declare const OP_PROP = 10;
|
|
11
11
|
export declare const OP_ALIGN = 11;
|
|
12
|
+
export declare const OP_POSITION = 12;
|
|
12
13
|
export declare const OF_VALUE = 0;
|
|
13
14
|
export declare const OF_URL = 1;
|
|
14
15
|
export declare const OF_TITLE = 2;
|
|
@@ -126,6 +126,9 @@ function emitHastOp(w, node, isRoot, refs, document = false, allowRootRef = fals
|
|
|
126
126
|
if (document && n.type.startsWith("mdx"))
|
|
127
127
|
return true;
|
|
128
128
|
w.open(type);
|
|
129
|
+
// A standalone document is only serialized, and has no source for a position to point into.
|
|
130
|
+
if (!document)
|
|
131
|
+
w.position(n.position);
|
|
129
132
|
if (type === HAST_ELEMENT) {
|
|
130
133
|
w.str(OF_TAGNAME, typeof n.tagName === "string" ? n.tagName : "div");
|
|
131
134
|
const props = n.properties;
|
package/dist/op-stream.d.ts
CHANGED
|
@@ -13,5 +13,8 @@ export declare class OpWriter extends ByteWriter {
|
|
|
13
13
|
ref(id: number): void;
|
|
14
14
|
align(codes: readonly number[]): void;
|
|
15
15
|
keepChildren(): void;
|
|
16
|
+
/** Write a node's `position` so the node keeps it. Only lines and columns are
|
|
17
|
+
* sent: Rust derives the byte offsets the arena stores from them. */
|
|
18
|
+
position(value: unknown): void;
|
|
16
19
|
}
|
|
17
20
|
export declare function emitMdxAttr(w: OpWriter, a: Record<string, unknown>): void;
|
package/dist/op-stream.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Writing directly into CommandBuffer avoids an intermediate op-stream allocation and copy.
|
|
2
2
|
import { ByteWriter } from "./byte-writer.js";
|
|
3
|
-
import { OP_OPEN, OP_CLOSE, OP_REF, OP_KEEP_CHILDREN, OP_STR, OP_U8, OP_U32, OP_BOOL, OP_DATA, OP_PROP, OP_ALIGN, MDX_ATTR_BOOLEAN_PROP, MDX_ATTR_LITERAL_PROP, MDX_ATTR_EXPRESSION_PROP, MDX_ATTR_SPREAD, } from "./generated/wire-constants.js";
|
|
3
|
+
import { OP_OPEN, OP_CLOSE, OP_REF, OP_KEEP_CHILDREN, OP_STR, OP_U8, OP_U32, OP_BOOL, OP_DATA, OP_PROP, OP_ALIGN, OP_POSITION, MDX_ATTR_BOOLEAN_PROP, MDX_ATTR_LITERAL_PROP, MDX_ATTR_EXPRESSION_PROP, MDX_ATTR_SPREAD, } from "./generated/wire-constants.js";
|
|
4
4
|
export { OF_VALUE, OF_URL, OF_TITLE, OF_ALT, OF_LANG, OF_META, OF_IDENTIFIER, OF_LABEL, OF_NAME, OF_REFERENCE_TYPE, OF_DEPTH, OF_CHECKED, OF_START, OF_ORDERED, OF_SPREAD, OF_TAGNAME, OF_EXPLICIT, PROP_STRING, PROP_BOOL_TRUE, PROP_BOOL_FALSE, PROP_SPACE_SEP, PROP_INT, PROP_NULL, PROP_TOKEN_LIST, } from "./generated/wire-constants.js";
|
|
5
5
|
export class OpWriter extends ByteWriter {
|
|
6
6
|
constructor(initialSize = 512) {
|
|
@@ -73,6 +73,33 @@ export class OpWriter extends ByteWriter {
|
|
|
73
73
|
this.ensure(1);
|
|
74
74
|
this.buf[this.n++] = OP_KEEP_CHILDREN;
|
|
75
75
|
}
|
|
76
|
+
/** Write a node's `position` so the node keeps it. Only lines and columns are
|
|
77
|
+
* sent: Rust derives the byte offsets the arena stores from them. */
|
|
78
|
+
position(value) {
|
|
79
|
+
// Most re-encoded nodes are built by plugins and have no position: return before any work.
|
|
80
|
+
if (value == null)
|
|
81
|
+
return;
|
|
82
|
+
const { start, end } = value;
|
|
83
|
+
if (start == null || end == null)
|
|
84
|
+
return;
|
|
85
|
+
const { line: startLine, column: startColumn } = start;
|
|
86
|
+
const { line: endLine, column: endColumn } = end;
|
|
87
|
+
if (!isLineOrColumn(startLine) ||
|
|
88
|
+
!isLineOrColumn(startColumn) ||
|
|
89
|
+
!isLineOrColumn(endLine) ||
|
|
90
|
+
!isLineOrColumn(endColumn)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.ensure(17);
|
|
94
|
+
this.buf[this.n++] = OP_POSITION;
|
|
95
|
+
this.writeU32(startLine);
|
|
96
|
+
this.writeU32(startColumn);
|
|
97
|
+
this.writeU32(endLine);
|
|
98
|
+
this.writeU32(endColumn);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function isLineOrColumn(value) {
|
|
102
|
+
return Number.isInteger(value) && value >= 1 && value <= 4294967295;
|
|
76
103
|
}
|
|
77
104
|
export function emitMdxAttr(w, a) {
|
|
78
105
|
if (a.type === "mdxJsxExpressionAttribute") {
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MdastPluginInstance } from "./mdast/mdast-visitor.js";
|
|
2
2
|
import type { HastVisitorInstance } from "./hast/hast-visitor.js";
|
|
3
|
+
import type { Features } from "./compile-types.js";
|
|
3
4
|
import type { Data, SourceFormat } from "./types.js";
|
|
4
5
|
/**
|
|
5
6
|
* What a plugin factory is told about the document, before it is parsed.
|
|
@@ -17,6 +18,10 @@ export interface PluginFactoryContext {
|
|
|
17
18
|
readonly source: string;
|
|
18
19
|
/** The document-level data bag, before any plugin has run. */
|
|
19
20
|
readonly data: Data;
|
|
21
|
+
/** The `features` compile option, or `{}` (the defaults) when none was
|
|
22
|
+
* given. Pass it on to compile a fragment with the same syntax as the
|
|
23
|
+
* document. */
|
|
24
|
+
readonly features: Features;
|
|
20
25
|
}
|
|
21
26
|
type RequireAtLeastOne<T, K extends keyof T> = Omit<T, K> & {
|
|
22
27
|
[P in K]-?: Required<Pick<T, P>> & Partial<Pick<T, Exclude<K, P>>>;
|
|
@@ -41,7 +46,7 @@ export type MdastPluginInput = MdastPluginEntry;
|
|
|
41
46
|
/** Alias for {@link HastPluginEntry}. */
|
|
42
47
|
export type HastPluginInput = HastPluginEntry;
|
|
43
48
|
/** Resolve nested entries and invoke each factory once per compile. */
|
|
44
|
-
export declare function normalizePlugins<D>(entries: readonly PluginEntry<D>[], option: string, source: string, fileURL: URL | undefined, sourceFormat: SourceFormat, data: Data): D[];
|
|
49
|
+
export declare function normalizePlugins<D>(entries: readonly PluginEntry<D>[], option: string, source: string, fileURL: URL | undefined, sourceFormat: SourceFormat, data: Data, features?: Features): D[];
|
|
45
50
|
export declare function defineMdastPlugin<P extends MdastPluginDefinition>(definition: P): P;
|
|
46
51
|
export declare function defineHastPlugin<P extends HastPluginDefinition>(definition: P): P;
|
|
47
52
|
export {};
|
package/dist/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Bound recursive factories so a self-referential preset cannot overflow the stack.
|
|
2
2
|
const MAX_FACTORY_DEPTH = 10;
|
|
3
3
|
/** Resolve nested entries and invoke each factory once per compile. */
|
|
4
|
-
export function normalizePlugins(entries, option, source, fileURL, sourceFormat, data) {
|
|
4
|
+
export function normalizePlugins(entries, option, source, fileURL, sourceFormat, data, features) {
|
|
5
5
|
const out = [];
|
|
6
6
|
// Built lazily so a list with no factories allocates no context.
|
|
7
7
|
let ctx;
|
|
@@ -25,6 +25,7 @@ export function normalizePlugins(entries, option, source, fileURL, sourceFormat,
|
|
|
25
25
|
// The parser drops a leading BOM, so `ctx.source` in a visitor lacks it too.
|
|
26
26
|
source: source.startsWith("\uFEFF") ? source.slice(1) : source,
|
|
27
27
|
data,
|
|
28
|
+
features: features ?? {},
|
|
28
29
|
});
|
|
29
30
|
walk(entry(ctx), factoryDepth - 1);
|
|
30
31
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "satteri",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.4",
|
|
4
4
|
"description": "High-performance Markdown and MDX processing",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -43,11 +43,14 @@
|
|
|
43
43
|
"@emnapi/runtime": "^1.11.1",
|
|
44
44
|
"@mdx-js/mdx": "^3.1.1",
|
|
45
45
|
"@napi-rs/wasm-runtime": "^1.1.5",
|
|
46
|
+
"@types/markdown-it": "^14.2.0",
|
|
46
47
|
"@types/node": "^26.2.0",
|
|
47
48
|
"@types/react": "^19.2.18",
|
|
48
49
|
"@types/react-dom": "^19.2.4",
|
|
49
50
|
"fast-check": "^4.7.0",
|
|
50
51
|
"hastscript": "^9.0.1",
|
|
52
|
+
"markdown-it": "^15.0.2",
|
|
53
|
+
"markdown-it-attrs": "^5.0.1",
|
|
51
54
|
"mdast-util-mdx": "^3.0.0",
|
|
52
55
|
"mdast-util-to-hast": "^13.2.1",
|
|
53
56
|
"react": "^19.2.5",
|