@simple-mark/model 0.1.0 → 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/index.d.ts +31 -2
- package/index.js +93 -1
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import { MarkdownExtension } from "@lezer/markdown";
|
|
2
|
-
import { Tree } from "@lezer/common";
|
|
2
|
+
import { SyntaxNode, Tree } from "@lezer/common";
|
|
3
3
|
//#region packages/model/src/parser.d.ts
|
|
4
4
|
/** The Markdown flavor every SimpleMark renderer parses: CommonMark + GFM + $math$. */
|
|
5
5
|
export declare const markdownExtensions: MarkdownExtension[];
|
|
6
6
|
/** A Lezer parser for that flavor, for hosts without CodeMirror (e.g. a canvas renderer). */
|
|
7
7
|
export declare const markdownParser: import("@lezer/markdown").MarkdownParser;
|
|
8
8
|
//#endregion
|
|
9
|
+
//#region packages/model/src/previews.d.ts
|
|
10
|
+
/** An image as written in the document. */
|
|
11
|
+
interface ImageSource {
|
|
12
|
+
alt: string;
|
|
13
|
+
/** The path as written, or null when a reference has no definition. */
|
|
14
|
+
src: string | null;
|
|
15
|
+
/** For messages: the path, or the reference label (`[logo]`) that has no definition. */
|
|
16
|
+
raw: string;
|
|
17
|
+
}
|
|
18
|
+
/** A preview drawn below the line that ends at `at` (an offset in the text). */
|
|
19
|
+
type PreviewBlock = {
|
|
20
|
+
at: number;
|
|
21
|
+
images: ImageSource[];
|
|
22
|
+
} | {
|
|
23
|
+
at: number;
|
|
24
|
+
tex: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The TeX of a math node (`InlineMath` or `BlockMath`), without delimiters or quote markers;
|
|
28
|
+
* null while it is not closed. `slice` reads the document.
|
|
29
|
+
*/
|
|
30
|
+
export declare function mathSource(node: SyntaxNode, slice: (from: number, to: number) => string): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* The previews of a document: the images of each line (one entry per line, in order) and
|
|
33
|
+
* closed, non-empty `$$` blocks. `text` must use one character per line break ("\n"), so
|
|
34
|
+
* offsets match the tree.
|
|
35
|
+
*/
|
|
36
|
+
export declare function previewBlocks(tree: Tree, text: string): PreviewBlock[];
|
|
37
|
+
//#endregion
|
|
9
38
|
//#region packages/model/src/styles.d.ts
|
|
10
39
|
/** Styles of whole lines, in precedence order (later wins when two set the same property). */
|
|
11
40
|
export declare const BLOCK_STYLES: readonly ['quote', 'codeblock', 'mathblock', 'table', 'tableHeader', 'tableRowAlt', 'hr', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
@@ -113,4 +142,4 @@ export declare function resolveLineLook(blocks: Iterable<BlockStyle>, theme?: Th
|
|
|
113
142
|
/** The look of text with these block and inline styles (any order). */
|
|
114
143
|
export declare function resolveLook(blocks: Iterable<BlockStyle>, inline: Iterable<InlineStyle>, theme?: Theme): Look;
|
|
115
144
|
//#endregion
|
|
116
|
-
export type { BlockRange, BlockStyle, ColumnAlign, InlineStyle, LineLook, Look, MarkdownStyles, RenderedTable, RowCell, Span, Table, Theme };
|
|
145
|
+
export type { BlockRange, BlockStyle, ColumnAlign, ImageSource, InlineStyle, LineLook, Look, MarkdownStyles, PreviewBlock, RenderedTable, RowCell, Span, Table, Theme };
|
package/index.js
CHANGED
|
@@ -103,6 +103,98 @@ const markdownExtensions = [GFM, {
|
|
|
103
103
|
/** A Lezer parser for that flavor, for hosts without CodeMirror (e.g. a canvas renderer). */
|
|
104
104
|
const markdownParser = parser.configure(markdownExtensions);
|
|
105
105
|
//#endregion
|
|
106
|
+
//#region packages/model/src/previews.ts
|
|
107
|
+
const normalizeLabel = (label) => label.slice(1, -1).trim().replace(/\s+/g, " ").toLowerCase();
|
|
108
|
+
/** A link destination as written, without the optional angle brackets (`<a b.png>`). */
|
|
109
|
+
const destination = (text, url) => text.slice(url.from, url.to).replace(/^<(.*)>$/, "$1");
|
|
110
|
+
/** Link reference definitions (`[label]: url`) of the document, by normalized label. */
|
|
111
|
+
function linkDefinitions(tree, text) {
|
|
112
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
113
|
+
for (let node = tree.topNode.firstChild; node; node = node.nextSibling) {
|
|
114
|
+
if (node.name !== "LinkReference") continue;
|
|
115
|
+
const label = node.getChild("LinkLabel");
|
|
116
|
+
const url = node.getChild("URL");
|
|
117
|
+
if (label && url) {
|
|
118
|
+
const key = normalizeLabel(text.slice(label.from, label.to));
|
|
119
|
+
if (!definitions.has(key)) definitions.set(key, destination(text, url));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return definitions;
|
|
123
|
+
}
|
|
124
|
+
function imageSource(node, text, definitions) {
|
|
125
|
+
const marks = node.getChildren("LinkMark");
|
|
126
|
+
const alt = marks.length >= 2 ? text.slice(marks[0].to, marks[1].from) : "";
|
|
127
|
+
const url = node.getChild("URL");
|
|
128
|
+
if (url) {
|
|
129
|
+
const src = destination(text, url);
|
|
130
|
+
return {
|
|
131
|
+
alt,
|
|
132
|
+
src,
|
|
133
|
+
raw: src
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const label = node.getChild("LinkLabel");
|
|
137
|
+
const labelText = label && label.to - label.from > 2 ? text.slice(label.from, label.to) : `[${alt}]`;
|
|
138
|
+
const src = definitions.get(normalizeLabel(labelText));
|
|
139
|
+
return src === void 0 ? {
|
|
140
|
+
alt,
|
|
141
|
+
src: null,
|
|
142
|
+
raw: labelText
|
|
143
|
+
} : {
|
|
144
|
+
alt,
|
|
145
|
+
src,
|
|
146
|
+
raw: src
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The TeX of a math node (`InlineMath` or `BlockMath`), without delimiters or quote markers;
|
|
151
|
+
* null while it is not closed. `slice` reads the document.
|
|
152
|
+
*/
|
|
153
|
+
function mathSource(node, slice) {
|
|
154
|
+
const marks = node.getChildren("MathMark");
|
|
155
|
+
if (marks.length < 2) return null;
|
|
156
|
+
if (node.name === "InlineMath") return slice(marks[0].to, marks[1].from);
|
|
157
|
+
return node.getChildren("MathText").map((part) => slice(part.from, part.to)).join("\n");
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The previews of a document: the images of each line (one entry per line, in order) and
|
|
161
|
+
* closed, non-empty `$$` blocks. `text` must use one character per line break ("\n"), so
|
|
162
|
+
* offsets match the tree.
|
|
163
|
+
*/
|
|
164
|
+
function previewBlocks(tree, text) {
|
|
165
|
+
const definitions = linkDefinitions(tree, text);
|
|
166
|
+
const lineEnd = (pos) => {
|
|
167
|
+
const end = text.indexOf("\n", pos);
|
|
168
|
+
return end === -1 ? text.length : end;
|
|
169
|
+
};
|
|
170
|
+
const imagesByLine = /* @__PURE__ */ new Map();
|
|
171
|
+
const blocks = [];
|
|
172
|
+
tree.iterate({ enter(node) {
|
|
173
|
+
if (node.name === "Image") {
|
|
174
|
+
const at = lineEnd(node.to);
|
|
175
|
+
let images = imagesByLine.get(at);
|
|
176
|
+
if (!images) {
|
|
177
|
+
imagesByLine.set(at, images = []);
|
|
178
|
+
blocks.push({
|
|
179
|
+
at,
|
|
180
|
+
images
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
images.push(imageSource(node.node, text, definitions));
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
if (node.name === "BlockMath") {
|
|
187
|
+
const tex = mathSource(node.node, (from, to) => text.slice(from, to));
|
|
188
|
+
if (tex !== null && tex.trim()) blocks.push({
|
|
189
|
+
at: lineEnd(node.to),
|
|
190
|
+
tex
|
|
191
|
+
});
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
} });
|
|
195
|
+
return blocks;
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
106
198
|
//#region packages/model/src/styles.ts
|
|
107
199
|
/** Styles of whole lines, in precedence order (later wins when two set the same property). */
|
|
108
200
|
const BLOCK_STYLES = [
|
|
@@ -505,4 +597,4 @@ function resolveLook(blocks, inline, theme = defaultTheme) {
|
|
|
505
597
|
return look;
|
|
506
598
|
}
|
|
507
599
|
//#endregion
|
|
508
|
-
export { BLOCK_STYLES, INLINE_STYLES, cellAt, charWidth, defaultTheme, displayWidth, flattenSpans, markdownExtensions, markdownParser, markdownStyles, parseTable, renderTable, resolveLineLook, resolveLook, rowLine, splitRow };
|
|
600
|
+
export { BLOCK_STYLES, INLINE_STYLES, cellAt, charWidth, defaultTheme, displayWidth, flattenSpans, markdownExtensions, markdownParser, markdownStyles, mathSource, parseTable, previewBlocks, renderTable, resolveLineLook, resolveLook, rowLine, splitRow };
|