@localix-ai/flowdown 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/core/blocks.js +3 -2
- package/dist/core/blocks.js.map +1 -1
- package/dist/core/continues.js +15 -0
- package/dist/core/continues.js.map +1 -0
- package/dist/core/fence-scan.js +10 -1
- package/dist/core/fence-scan.js.map +1 -1
- package/dist/core/file-tree-parse.js +1 -1
- package/dist/core/file-tree-parse.js.map +1 -1
- package/dist/core/heal.js +1 -1
- package/dist/core/heal.js.map +1 -1
- package/dist/document/fence.js +3 -2
- package/dist/document/fence.js.map +1 -1
- package/dist/dom/index.js +25 -7
- package/dist/dom/index.js.map +1 -1
- package/dist/element/index.d.ts +6 -0
- package/dist/element/index.js.map +1 -1
- package/dist/engine/blocks.js +11 -0
- package/dist/engine/blocks.js.map +1 -1
- package/dist/engine/inlines.js +40 -5
- package/dist/engine/inlines.js.map +1 -1
- package/dist/react/code-block.js +15 -2
- package/dist/react/code-block.js.map +1 -1
- package/dist/react/draw.js +1 -0
- package/dist/react/draw.js.map +1 -1
- package/dist/react/markdown.js +4 -2
- package/dist/react/markdown.js.map +1 -1
- package/dist/react/scrolls.js +62 -0
- package/dist/react/scrolls.js.map +1 -0
- package/dist/react/table.js +6 -20
- package/dist/react/table.js.map +1 -1
- package/dist/react/use-smooth-text.js +2 -1
- package/dist/react/use-smooth-text.js.map +1 -1
- package/dist/render/labels.d.ts +5 -0
- package/dist/render/labels.js +3 -0
- package/dist/render/labels.js.map +1 -1
- package/dist/render/tree.js +2 -0
- package/dist/render/tree.js.map +1 -1
- package/dist/render/view.d.ts +4 -1
- package/dist/render/view.js +6 -2
- package/dist/render/view.js.map +1 -1
- package/dist/render/views.js +2 -2
- package/dist/render/views.js.map +1 -1
- package/dist/styles.css +12 -1
- package/dist/tui/wrap.js +5 -4
- package/dist/tui/wrap.js.map +1 -1
- package/package.json +3 -2
package/dist/tui/wrap.js
CHANGED
|
@@ -92,9 +92,9 @@ function wrap(line, columns, first, rest) {
|
|
|
92
92
|
let word = list[at].text;
|
|
93
93
|
const run = kept[at];
|
|
94
94
|
if (!fresh && used + (pending ? 1 : 0) + run > room && indent + run <= room) next();
|
|
95
|
+
let own = width(word);
|
|
95
96
|
for (;;) {
|
|
96
97
|
const gap = pending && !fresh ? 1 : 0;
|
|
97
|
-
const own = width(word);
|
|
98
98
|
if (used + gap + own <= room) {
|
|
99
99
|
if (gap) row.push({
|
|
100
100
|
text: " ",
|
|
@@ -112,12 +112,13 @@ function wrap(line, columns, first, rest) {
|
|
|
112
112
|
next();
|
|
113
113
|
continue;
|
|
114
114
|
}
|
|
115
|
-
const
|
|
115
|
+
const head = word.slice(0, split(word, Math.max(1, room - used)));
|
|
116
116
|
row.push({
|
|
117
|
-
text:
|
|
117
|
+
text: head,
|
|
118
118
|
style
|
|
119
119
|
});
|
|
120
|
-
word = word.slice(
|
|
120
|
+
word = word.slice(head.length);
|
|
121
|
+
own -= width(head);
|
|
121
122
|
next();
|
|
122
123
|
if (!word) break;
|
|
123
124
|
}
|
package/dist/tui/wrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap.js","names":[],"sources":["../../src/tui/wrap.ts"],"sourcesContent":["/**\n * Styled lines wrapped to a width by display columns, at word boundaries, with a prefix for the\n * first row and another for the rest (a hanging indent): a paragraph never breaks mid-word and\n * its continuation sits under its own start. A word wider than the row is split; nothing is ever\n * wider than `width` while the prefix leaves a column to write in.\n */\nimport type { Line, Span, Style } from './style'\nimport { charWidth, width } from './width'\n\n/**\n * A space a row is not broken at while a row holds what it joins: the spaces of code. Drawn as a\n * space, so what is copied from the screen is what was written.\n */\nexport const NO_BREAK = String.fromCharCode(0xa0)\n\n/** What follows a word. */\nconst enum After {\n /** A space, where a row may end. */\n Space,\n /** A space that keeps its words on one row when a row holds them. */\n Joint,\n /** The next word, with nothing between: \"`code`,\" or \"a**b**\". */\n Nothing,\n}\n\ninterface Word {\n text: string\n style: Style\n after: After\n}\n\nexport const lineWidth = (line: Line): number => {\n let columns = 0\n for (const span of line) columns += width(span.text)\n return columns\n}\n\nconst SPACE = /\\s/\n\n/** The words of `line` with their style and what follows each. */\nfunction words(line: Line): Word[] {\n const out: Word[] = []\n for (const span of line) {\n let word = ''\n for (const char of span.text) {\n if (SPACE.test(char)) {\n const after = char === NO_BREAK ? After.Joint : After.Space\n if (word) {\n out.push({ text: word, style: span.style, after })\n word = ''\n } else if (out.length > 0) out.at(-1)!.after = after\n } else word += char\n }\n if (word) out.push({ text: word, style: span.style, after: After.Nothing })\n }\n return out\n}\n\n/**\n * For each word, the columns kept on one row from it on: the words that run into it, and where a\n * code span starts, the span. A span no row holds is then broken at its spaces, as words are.\n */\nfunction runs(list: Word[]): number[] {\n const out = list.map(() => 0)\n let glued = 0\n let whole = 0\n for (let at = list.length - 1; at >= 0; at--) {\n const { text, after } = list[at]!\n const own = width(text)\n if (after === After.Space) [glued, whole] = [own, own]\n else if (after === After.Joint) [glued, whole] = [own, own + 1 + whole]\n else [glued, whole] = [own + glued, own + whole]\n const before = at > 0 ? list[at - 1]!.after : After.Space\n out[at] = before === After.Space ? whole : before === After.Joint ? glued : 0\n }\n return out\n}\n\n/** Where `word` is cut to fit `columns`: its length when it fits. Always past its first character. */\nfunction split(word: string, columns: number): number {\n let used = 0\n let at = 0\n for (const char of word) {\n const own = charWidth(char)\n if (used + own > columns && at > 0) return at\n used += own\n at += char.length\n }\n return word.length\n}\n\n/**\n * How the space between two words is drawn: with what both are. Inside a link it is underlined\n * with its words; after the link it is not, and the line under the link ends where the link does.\n */\nfunction shared(before: Style, after: Style): Style {\n if (before === after) return before\n const out: Record<string, unknown> = {}\n for (const [field, value] of Object.entries(before))\n if ((after as Record<string, unknown>)[field] === value) out[field] = value\n return out as Style\n}\n\n/** `line` wrapped to `columns`: the first row starts with `first`, the others with `rest`. */\nexport function wrap(line: Line, columns: number, first: Line, rest: Line): Line[] {\n const rows: Line[] = []\n let row: Line = [...first]\n let used = lineWidth(first)\n const indent = lineWidth(rest)\n const room = Math.max(columns, indent + 1)\n let pending: Style | null = null\n let fresh = true\n const list = words(line)\n const kept = runs(list)\n const next = () => {\n rows.push(row)\n row = [...rest]\n used = indent\n fresh = true\n }\n for (let at = 0; at < list.length; at++) {\n const { style, after } = list[at]!\n let word = list[at]!.text\n const run = kept[at]!\n // A word and what runs into it (\"`code`,\" or \"(**b**)\"), and the words of a code span, go\n // to the next row together when a row holds them: no row starts with the comma.\n if (!fresh && used + (pending ? 1 : 0) + run > room && indent + run <= room) next()\n for (;;) {\n const gap = pending && !fresh ? 1 : 0\n const own = width(word)\n if (used + gap + own <= room) {\n if (gap) row.push({ text: ' ', style: shared(pending!, style) })\n row.push({ text: word, style })\n used += gap + own\n fresh = false\n break\n }\n if (!fresh) {\n next()\n continue\n }\n const cut = split(word, Math.max(1, room - used))\n row.push({ text: word.slice(0, cut), style })\n word = word.slice(cut)\n next()\n if (!word) break\n }\n pending = after === After.Nothing ? null : style\n }\n if (!fresh || rows.length === 0) rows.push(row)\n return rows\n}\n\n/**\n * A line of code with each tab run out to the next fourth column: a terminal's own stops are\n * eight wide, and an escaped tab is not what was written.\n */\nexport function untabbed(line: string): string {\n if (!line.includes('\\t')) return line\n const pads = tabPads(line)\n return line\n .split('\\t')\n .map((piece, at) => (at > 0 ? ' '.repeat(pads[at - 1]!) : '') + piece)\n .join('')\n}\n\n/** The spaces each tab of `line` stands for, in order: what {@link untabbed} writes in its place. */\nexport function tabPads(line: string): number[] {\n const pads: number[] = []\n let column = 0\n line.split('\\t').forEach((piece, at) => {\n if (at > 0) {\n const pad = 4 - (column % 4)\n pads.push(pad)\n column += pad\n }\n column += width(piece)\n })\n return pads\n}\n\n/**\n * `line` in rows of at most `columns`, broken anywhere with its styles and its spaces kept: for\n * code, whose indentation and alignment mean something.\n */\nexport function fit(line: Line, columns: number): Line[] {\n const room = Math.max(1, columns)\n if (lineWidth(line) <= room) return [line]\n const rows: Line[] = [[]]\n let used = 0\n for (const span of line) {\n let text = ''\n for (const char of span.text) {\n const own = charWidth(char)\n if (used + own > room && used > 0) {\n rows.at(-1)!.push({ text, style: span.style })\n text = ''\n rows.push([])\n used = 0\n }\n text += char\n used += own\n }\n rows.at(-1)!.push({ text, style: span.style })\n }\n return rows\n}\n\nexport const span = (text: string, style: Style): Span => ({ text, style })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wrap.js","names":[],"sources":["../../src/tui/wrap.ts"],"sourcesContent":["/**\n * Styled lines wrapped to a width by display columns, at word boundaries, with a prefix for the\n * first row and another for the rest (a hanging indent): a paragraph never breaks mid-word and\n * its continuation sits under its own start. A word wider than the row is split; nothing is ever\n * wider than `width` while the prefix leaves a column to write in.\n */\nimport type { Line, Span, Style } from './style'\nimport { charWidth, width } from './width'\n\n/**\n * A space a row is not broken at while a row holds what it joins: the spaces of code. Drawn as a\n * space, so what is copied from the screen is what was written.\n */\nexport const NO_BREAK = String.fromCharCode(0xa0)\n\n/** What follows a word. */\nconst enum After {\n /** A space, where a row may end. */\n Space,\n /** A space that keeps its words on one row when a row holds them. */\n Joint,\n /** The next word, with nothing between: \"`code`,\" or \"a**b**\". */\n Nothing,\n}\n\ninterface Word {\n text: string\n style: Style\n after: After\n}\n\nexport const lineWidth = (line: Line): number => {\n let columns = 0\n for (const span of line) columns += width(span.text)\n return columns\n}\n\nconst SPACE = /\\s/\n\n/** The words of `line` with their style and what follows each. */\nfunction words(line: Line): Word[] {\n const out: Word[] = []\n for (const span of line) {\n let word = ''\n for (const char of span.text) {\n if (SPACE.test(char)) {\n const after = char === NO_BREAK ? After.Joint : After.Space\n if (word) {\n out.push({ text: word, style: span.style, after })\n word = ''\n } else if (out.length > 0) out.at(-1)!.after = after\n } else word += char\n }\n if (word) out.push({ text: word, style: span.style, after: After.Nothing })\n }\n return out\n}\n\n/**\n * For each word, the columns kept on one row from it on: the words that run into it, and where a\n * code span starts, the span. A span no row holds is then broken at its spaces, as words are.\n */\nfunction runs(list: Word[]): number[] {\n const out = list.map(() => 0)\n let glued = 0\n let whole = 0\n for (let at = list.length - 1; at >= 0; at--) {\n const { text, after } = list[at]!\n const own = width(text)\n if (after === After.Space) [glued, whole] = [own, own]\n else if (after === After.Joint) [glued, whole] = [own, own + 1 + whole]\n else [glued, whole] = [own + glued, own + whole]\n const before = at > 0 ? list[at - 1]!.after : After.Space\n out[at] = before === After.Space ? whole : before === After.Joint ? glued : 0\n }\n return out\n}\n\n/** Where `word` is cut to fit `columns`: its length when it fits. Always past its first character. */\nfunction split(word: string, columns: number): number {\n let used = 0\n let at = 0\n for (const char of word) {\n const own = charWidth(char)\n if (used + own > columns && at > 0) return at\n used += own\n at += char.length\n }\n return word.length\n}\n\n/**\n * How the space between two words is drawn: with what both are. Inside a link it is underlined\n * with its words; after the link it is not, and the line under the link ends where the link does.\n */\nfunction shared(before: Style, after: Style): Style {\n if (before === after) return before\n const out: Record<string, unknown> = {}\n for (const [field, value] of Object.entries(before))\n if ((after as Record<string, unknown>)[field] === value) out[field] = value\n return out as Style\n}\n\n/** `line` wrapped to `columns`: the first row starts with `first`, the others with `rest`. */\nexport function wrap(line: Line, columns: number, first: Line, rest: Line): Line[] {\n const rows: Line[] = []\n let row: Line = [...first]\n let used = lineWidth(first)\n const indent = lineWidth(rest)\n const room = Math.max(columns, indent + 1)\n let pending: Style | null = null\n let fresh = true\n const list = words(line)\n const kept = runs(list)\n const next = () => {\n rows.push(row)\n row = [...rest]\n used = indent\n fresh = true\n }\n for (let at = 0; at < list.length; at++) {\n const { style, after } = list[at]!\n let word = list[at]!.text\n const run = kept[at]!\n // A word and what runs into it (\"`code`,\" or \"(**b**)\"), and the words of a code span, go\n // to the next row together when a row holds them: no row starts with the comma.\n if (!fresh && used + (pending ? 1 : 0) + run > room && indent + run <= room) next()\n // Measured once, and less each piece cut off: a word of a megabyte is not measured per row.\n let own = width(word)\n for (;;) {\n const gap = pending && !fresh ? 1 : 0\n if (used + gap + own <= room) {\n if (gap) row.push({ text: ' ', style: shared(pending!, style) })\n row.push({ text: word, style })\n used += gap + own\n fresh = false\n break\n }\n if (!fresh) {\n next()\n continue\n }\n const head = word.slice(0, split(word, Math.max(1, room - used)))\n row.push({ text: head, style })\n word = word.slice(head.length)\n own -= width(head)\n next()\n if (!word) break\n }\n pending = after === After.Nothing ? null : style\n }\n if (!fresh || rows.length === 0) rows.push(row)\n return rows\n}\n\n/**\n * A line of code with each tab run out to the next fourth column: a terminal's own stops are\n * eight wide, and an escaped tab is not what was written.\n */\nexport function untabbed(line: string): string {\n if (!line.includes('\\t')) return line\n const pads = tabPads(line)\n return line\n .split('\\t')\n .map((piece, at) => (at > 0 ? ' '.repeat(pads[at - 1]!) : '') + piece)\n .join('')\n}\n\n/** The spaces each tab of `line` stands for, in order: what {@link untabbed} writes in its place. */\nexport function tabPads(line: string): number[] {\n const pads: number[] = []\n let column = 0\n line.split('\\t').forEach((piece, at) => {\n if (at > 0) {\n const pad = 4 - (column % 4)\n pads.push(pad)\n column += pad\n }\n column += width(piece)\n })\n return pads\n}\n\n/**\n * `line` in rows of at most `columns`, broken anywhere with its styles and its spaces kept: for\n * code, whose indentation and alignment mean something.\n */\nexport function fit(line: Line, columns: number): Line[] {\n const room = Math.max(1, columns)\n if (lineWidth(line) <= room) return [line]\n const rows: Line[] = [[]]\n let used = 0\n for (const span of line) {\n let text = ''\n for (const char of span.text) {\n const own = charWidth(char)\n if (used + own > room && used > 0) {\n rows.at(-1)!.push({ text, style: span.style })\n text = ''\n rows.push([])\n used = 0\n }\n text += char\n used += own\n }\n rows.at(-1)!.push({ text, style: span.style })\n }\n return rows\n}\n\nexport const span = (text: string, style: Style): Span => ({ text, style })\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@localix-ai/flowdown",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "Ultrafast, lightweight streaming Markdown for React and AI replies. Its own parser, zero dependencies,
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Ultrafast, lightweight streaming Markdown for React and AI replies. Its own parser, zero dependencies, 32 KB gzipped. GitHub Markdown plus steps, tabs, callouts, diagrams and math. Also as HTML text, on a page with no framework, as a custom element and in a terminal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"ai-chat",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"commonmark-spec": "0.31.2",
|
|
96
96
|
"highlight.js": "11.12.0",
|
|
97
97
|
"katex": "0.19.1",
|
|
98
|
+
"lightningcss": "1.33.0",
|
|
98
99
|
"mermaid": "12.3.0",
|
|
99
100
|
"publint": "0.3.25",
|
|
100
101
|
"react": "19.3.1",
|