@scrider/formatter 1.1.0 → 1.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/dist/index.cjs +80 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -3
- package/dist/index.d.ts +109 -3
- package/dist/index.js +77 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AttributeMap, Op, Delta } from '@scrider/delta';
|
|
1
|
+
import { AttributeMap, Op, Delta, InsertOp } from '@scrider/delta';
|
|
2
2
|
export * from '@scrider/delta';
|
|
3
|
+
export { InsertOp as ContentOp } from '@scrider/delta';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* DOM Adapter Interface
|
|
@@ -1556,6 +1557,18 @@ interface DeltaToMarkdownOptions {
|
|
|
1556
1557
|
* `render()` is used as HTML fallback in Markdown.
|
|
1557
1558
|
*/
|
|
1558
1559
|
registry?: Registry;
|
|
1560
|
+
/**
|
|
1561
|
+
* Strip trailing newlines from the final output.
|
|
1562
|
+
*
|
|
1563
|
+
* Useful when serialising a single block (e.g. one table for inline
|
|
1564
|
+
* editing) where the GFM padding (blank line after a table, trailing
|
|
1565
|
+
* paragraph newline, etc.) is not wanted. The internal structure of the
|
|
1566
|
+
* markdown is unaffected — only trailing `\n+` at the very end of the
|
|
1567
|
+
* returned string is removed.
|
|
1568
|
+
*
|
|
1569
|
+
* @default false
|
|
1570
|
+
*/
|
|
1571
|
+
trimTrailingNewlines?: boolean;
|
|
1559
1572
|
}
|
|
1560
1573
|
/**
|
|
1561
1574
|
* Convert Delta to Markdown
|
|
@@ -1661,9 +1674,39 @@ interface ParserContext {
|
|
|
1661
1674
|
pushNewline(attrs?: AttributeMap): void;
|
|
1662
1675
|
}
|
|
1663
1676
|
/**
|
|
1664
|
-
* Check if remark is available
|
|
1677
|
+
* Check if remark is available for synchronous use.
|
|
1678
|
+
*
|
|
1679
|
+
* Returns true if either:
|
|
1680
|
+
* - remark modules have been preloaded (via {@link preloadRemark} or a prior
|
|
1681
|
+
* `markdownToDelta` / `markdownToDeltaSync` call), OR
|
|
1682
|
+
* - CommonJS `require()` is available and can resolve `unified` and
|
|
1683
|
+
* `remark-parse` (Node.js without ESM-only mode).
|
|
1684
|
+
*
|
|
1685
|
+
* In browser ESM environments where `require` is undefined, this returns
|
|
1686
|
+
* `false` until {@link preloadRemark} has been awaited at least once.
|
|
1665
1687
|
*/
|
|
1666
1688
|
declare function isRemarkAvailable(): boolean;
|
|
1689
|
+
/**
|
|
1690
|
+
* Preload remark modules (`unified`, `remark-parse`, `remark-gfm`, optionally
|
|
1691
|
+
* `remark-math`) asynchronously. After this resolves successfully, the
|
|
1692
|
+
* synchronous {@link markdownToDeltaSync} is usable in environments where
|
|
1693
|
+
* `require()` is not available (e.g. browser ESM).
|
|
1694
|
+
*
|
|
1695
|
+
* Safe to call multiple times: subsequent calls short-circuit if modules are
|
|
1696
|
+
* already loaded.
|
|
1697
|
+
*
|
|
1698
|
+
* @returns `true` if mandatory modules (`unified`, `remark-parse`,
|
|
1699
|
+
* `remark-gfm`) are now loaded; `false` if any required module is missing.
|
|
1700
|
+
* The function never throws — callers can branch on the boolean for
|
|
1701
|
+
* graceful degradation.
|
|
1702
|
+
*
|
|
1703
|
+
* @example
|
|
1704
|
+
* // On editor mount:
|
|
1705
|
+
* useEffect(() => {
|
|
1706
|
+
* preloadRemark();
|
|
1707
|
+
* }, []);
|
|
1708
|
+
*/
|
|
1709
|
+
declare function preloadRemark(): Promise<boolean>;
|
|
1667
1710
|
/**
|
|
1668
1711
|
* Convert Markdown to Delta (async)
|
|
1669
1712
|
*/
|
|
@@ -1673,4 +1716,67 @@ declare function markdownToDelta(markdown: string, options?: MarkdownToDeltaOpti
|
|
|
1673
1716
|
*/
|
|
1674
1717
|
declare function markdownToDeltaSync(markdown: string, options?: MarkdownToDeltaOptions): Delta;
|
|
1675
1718
|
|
|
1676
|
-
|
|
1719
|
+
/**
|
|
1720
|
+
* Simple-table region detection in flat Delta.
|
|
1721
|
+
*
|
|
1722
|
+
* Helpers for callers (e.g. editors that need to find the boundaries of a
|
|
1723
|
+
* markdown-style table within a Delta op stream — for example to enter
|
|
1724
|
+
* "edit as markdown source" mode on double-click of a rendered table cell).
|
|
1725
|
+
*
|
|
1726
|
+
* A simple-table region is a contiguous run of ops that ends, for each cell,
|
|
1727
|
+
* with a `\n`-op carrying the `table-row` attribute (the standard format
|
|
1728
|
+
* produced by {@link markdownToDelta} for GFM tables and consumed by
|
|
1729
|
+
* {@link deltaToMarkdown}).
|
|
1730
|
+
*/
|
|
1731
|
+
|
|
1732
|
+
/**
|
|
1733
|
+
* Detected boundaries of a simple-table region.
|
|
1734
|
+
*/
|
|
1735
|
+
interface TableRegion {
|
|
1736
|
+
/** Inclusive start index in the original ops array. */
|
|
1737
|
+
startOpIdx: number;
|
|
1738
|
+
/**
|
|
1739
|
+
* Inclusive end index — always points at the last `\n`-op of the table
|
|
1740
|
+
* (the terminator of the last cell of the last row).
|
|
1741
|
+
*/
|
|
1742
|
+
endOpIdx: number;
|
|
1743
|
+
/** Slice of the original ops array covering the region. */
|
|
1744
|
+
ops: InsertOp[];
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Predicate: this op is a `\n`-op that terminates a simple-table cell
|
|
1748
|
+
* (i.e. it carries a `table-row` attribute).
|
|
1749
|
+
*/
|
|
1750
|
+
declare function isTableNewlineOp(op: Op | undefined): boolean;
|
|
1751
|
+
/**
|
|
1752
|
+
* Find the boundaries of the simple-table region containing the given hint
|
|
1753
|
+
* op index. The hint may be:
|
|
1754
|
+
* - an inline op inside a cell,
|
|
1755
|
+
* - the cell-terminating `\n`-op itself,
|
|
1756
|
+
* - any op between two table newlines.
|
|
1757
|
+
*
|
|
1758
|
+
* The function walks **forward** from the hint to find the nearest `\n`-op:
|
|
1759
|
+
* if it does not carry a `table-row` attribute, the hint is not inside a
|
|
1760
|
+
* table and `null` is returned. Otherwise the algorithm extends the region
|
|
1761
|
+
* forward through contiguous table newlines and backward to the op just
|
|
1762
|
+
* after the previous non-table `\n`-op (or the start of the array).
|
|
1763
|
+
*
|
|
1764
|
+
* @param ops - The full ops array (e.g. `delta.ops`).
|
|
1765
|
+
* @param hintOpIdx - Any op index known or guessed to be within a table.
|
|
1766
|
+
* @returns The detected region, or `null` if `hintOpIdx` is out of range or
|
|
1767
|
+
* not within any simple-table region.
|
|
1768
|
+
*
|
|
1769
|
+
* @example
|
|
1770
|
+
* // After hit-testing a `<td>` element to a Delta op index:
|
|
1771
|
+
* const region = extractTableRegion(state.delta.ops, hitOpIdx);
|
|
1772
|
+
* if (region) {
|
|
1773
|
+
* const md = deltaToMarkdown(new Delta(region.ops), {
|
|
1774
|
+
* trimTrailingNewlines: true,
|
|
1775
|
+
* });
|
|
1776
|
+
* // replace ops in [region.startOpIdx, region.endOpIdx] with a single
|
|
1777
|
+
* // { insert: md + '\n' } op to enter source-edit mode
|
|
1778
|
+
* }
|
|
1779
|
+
*/
|
|
1780
|
+
declare function extractTableRegion(ops: readonly Op[], hintOpIdx: number): TableRegion | null;
|
|
1781
|
+
|
|
1782
|
+
export { ALERT_TYPES, type AlertBlockData, type AlertType, type AlignType, BOX_FLOAT_VALUES, BOX_OVERFLOW_VALUES, type BlockContext, type BlockHandler, BlockHandlerRegistry, type BlockRenderOptions, type BoxBlockData, type BoxFloat, type BoxOpAttributes, type BoxOverflow, BrowserDOMAdapter, type CellAlign, type CellData, type ColumnsBlockData, type DOMAdapter, type DOMDocument, type DOMDocumentFragment, type DOMElement, type DOMNode, type DOMNodeList, type DeltaToHtmlOptions, type DeltaToMarkdownOptions, type FootnotesBlockData, type Format, type FormatDefinition, type FormatMatchResult, type FormatScope, type HtmlToDeltaOptions, type ListType, type MarkdownToDeltaOptions, NODE_TYPE, NodeDOMAdapter, Registry, type SanitizeOptions, type TableBlockData, type TableColAlignType, type TableRegion, alertBlockHandler, alignFormat, backgroundFormat, blockFormat, blockquoteFormat, boldFormat, boxBlockHandler, browserAdapter, cloneDelta, codeBlockFormat, codeFormat, colorFormat, columnsBlockHandler, createDefaultBlockHandlers, createDefaultRegistry, defaultBlockFormats, defaultEmbedFormats, defaultFormats, defaultInlineFormats, deltaToHtml, deltaToMarkdown, dividerFormat, escapeHtml, extractBoxOpAttributes, extractTableRegion, fontFormat, footnoteRefFormat, footnotesBlockHandler, formulaFormat, getAdapter, getNamedColors, headerFormat, headerIdFormat, htmlToDelta, imageFormat, indentFormat, isAdapterAvailable, isElement, isRemarkAvailable, isTableNewlineOp, isTextNode, isValidColor, isValidHexColor, italicFormat, kbdFormat, linkFormat, listFormat, markFormat, markdownToDelta, markdownToDeltaSync, nodeAdapter, normalizeDelta, preloadRemark, sanitizeDelta, sizeFormat, slugify, slugifyWithDedup, strikeFormat, subscriptFormat, superscriptFormat, tableBlockHandler, tableColAlignFormat, tableColFormat, tableHeaderFormat, tableRowFormat, toHexColor, underlineFormat, unescapeHtml, validateDelta, videoFormat };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AttributeMap, Op, Delta } from '@scrider/delta';
|
|
1
|
+
import { AttributeMap, Op, Delta, InsertOp } from '@scrider/delta';
|
|
2
2
|
export * from '@scrider/delta';
|
|
3
|
+
export { InsertOp as ContentOp } from '@scrider/delta';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* DOM Adapter Interface
|
|
@@ -1556,6 +1557,18 @@ interface DeltaToMarkdownOptions {
|
|
|
1556
1557
|
* `render()` is used as HTML fallback in Markdown.
|
|
1557
1558
|
*/
|
|
1558
1559
|
registry?: Registry;
|
|
1560
|
+
/**
|
|
1561
|
+
* Strip trailing newlines from the final output.
|
|
1562
|
+
*
|
|
1563
|
+
* Useful when serialising a single block (e.g. one table for inline
|
|
1564
|
+
* editing) where the GFM padding (blank line after a table, trailing
|
|
1565
|
+
* paragraph newline, etc.) is not wanted. The internal structure of the
|
|
1566
|
+
* markdown is unaffected — only trailing `\n+` at the very end of the
|
|
1567
|
+
* returned string is removed.
|
|
1568
|
+
*
|
|
1569
|
+
* @default false
|
|
1570
|
+
*/
|
|
1571
|
+
trimTrailingNewlines?: boolean;
|
|
1559
1572
|
}
|
|
1560
1573
|
/**
|
|
1561
1574
|
* Convert Delta to Markdown
|
|
@@ -1661,9 +1674,39 @@ interface ParserContext {
|
|
|
1661
1674
|
pushNewline(attrs?: AttributeMap): void;
|
|
1662
1675
|
}
|
|
1663
1676
|
/**
|
|
1664
|
-
* Check if remark is available
|
|
1677
|
+
* Check if remark is available for synchronous use.
|
|
1678
|
+
*
|
|
1679
|
+
* Returns true if either:
|
|
1680
|
+
* - remark modules have been preloaded (via {@link preloadRemark} or a prior
|
|
1681
|
+
* `markdownToDelta` / `markdownToDeltaSync` call), OR
|
|
1682
|
+
* - CommonJS `require()` is available and can resolve `unified` and
|
|
1683
|
+
* `remark-parse` (Node.js without ESM-only mode).
|
|
1684
|
+
*
|
|
1685
|
+
* In browser ESM environments where `require` is undefined, this returns
|
|
1686
|
+
* `false` until {@link preloadRemark} has been awaited at least once.
|
|
1665
1687
|
*/
|
|
1666
1688
|
declare function isRemarkAvailable(): boolean;
|
|
1689
|
+
/**
|
|
1690
|
+
* Preload remark modules (`unified`, `remark-parse`, `remark-gfm`, optionally
|
|
1691
|
+
* `remark-math`) asynchronously. After this resolves successfully, the
|
|
1692
|
+
* synchronous {@link markdownToDeltaSync} is usable in environments where
|
|
1693
|
+
* `require()` is not available (e.g. browser ESM).
|
|
1694
|
+
*
|
|
1695
|
+
* Safe to call multiple times: subsequent calls short-circuit if modules are
|
|
1696
|
+
* already loaded.
|
|
1697
|
+
*
|
|
1698
|
+
* @returns `true` if mandatory modules (`unified`, `remark-parse`,
|
|
1699
|
+
* `remark-gfm`) are now loaded; `false` if any required module is missing.
|
|
1700
|
+
* The function never throws — callers can branch on the boolean for
|
|
1701
|
+
* graceful degradation.
|
|
1702
|
+
*
|
|
1703
|
+
* @example
|
|
1704
|
+
* // On editor mount:
|
|
1705
|
+
* useEffect(() => {
|
|
1706
|
+
* preloadRemark();
|
|
1707
|
+
* }, []);
|
|
1708
|
+
*/
|
|
1709
|
+
declare function preloadRemark(): Promise<boolean>;
|
|
1667
1710
|
/**
|
|
1668
1711
|
* Convert Markdown to Delta (async)
|
|
1669
1712
|
*/
|
|
@@ -1673,4 +1716,67 @@ declare function markdownToDelta(markdown: string, options?: MarkdownToDeltaOpti
|
|
|
1673
1716
|
*/
|
|
1674
1717
|
declare function markdownToDeltaSync(markdown: string, options?: MarkdownToDeltaOptions): Delta;
|
|
1675
1718
|
|
|
1676
|
-
|
|
1719
|
+
/**
|
|
1720
|
+
* Simple-table region detection in flat Delta.
|
|
1721
|
+
*
|
|
1722
|
+
* Helpers for callers (e.g. editors that need to find the boundaries of a
|
|
1723
|
+
* markdown-style table within a Delta op stream — for example to enter
|
|
1724
|
+
* "edit as markdown source" mode on double-click of a rendered table cell).
|
|
1725
|
+
*
|
|
1726
|
+
* A simple-table region is a contiguous run of ops that ends, for each cell,
|
|
1727
|
+
* with a `\n`-op carrying the `table-row` attribute (the standard format
|
|
1728
|
+
* produced by {@link markdownToDelta} for GFM tables and consumed by
|
|
1729
|
+
* {@link deltaToMarkdown}).
|
|
1730
|
+
*/
|
|
1731
|
+
|
|
1732
|
+
/**
|
|
1733
|
+
* Detected boundaries of a simple-table region.
|
|
1734
|
+
*/
|
|
1735
|
+
interface TableRegion {
|
|
1736
|
+
/** Inclusive start index in the original ops array. */
|
|
1737
|
+
startOpIdx: number;
|
|
1738
|
+
/**
|
|
1739
|
+
* Inclusive end index — always points at the last `\n`-op of the table
|
|
1740
|
+
* (the terminator of the last cell of the last row).
|
|
1741
|
+
*/
|
|
1742
|
+
endOpIdx: number;
|
|
1743
|
+
/** Slice of the original ops array covering the region. */
|
|
1744
|
+
ops: InsertOp[];
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Predicate: this op is a `\n`-op that terminates a simple-table cell
|
|
1748
|
+
* (i.e. it carries a `table-row` attribute).
|
|
1749
|
+
*/
|
|
1750
|
+
declare function isTableNewlineOp(op: Op | undefined): boolean;
|
|
1751
|
+
/**
|
|
1752
|
+
* Find the boundaries of the simple-table region containing the given hint
|
|
1753
|
+
* op index. The hint may be:
|
|
1754
|
+
* - an inline op inside a cell,
|
|
1755
|
+
* - the cell-terminating `\n`-op itself,
|
|
1756
|
+
* - any op between two table newlines.
|
|
1757
|
+
*
|
|
1758
|
+
* The function walks **forward** from the hint to find the nearest `\n`-op:
|
|
1759
|
+
* if it does not carry a `table-row` attribute, the hint is not inside a
|
|
1760
|
+
* table and `null` is returned. Otherwise the algorithm extends the region
|
|
1761
|
+
* forward through contiguous table newlines and backward to the op just
|
|
1762
|
+
* after the previous non-table `\n`-op (or the start of the array).
|
|
1763
|
+
*
|
|
1764
|
+
* @param ops - The full ops array (e.g. `delta.ops`).
|
|
1765
|
+
* @param hintOpIdx - Any op index known or guessed to be within a table.
|
|
1766
|
+
* @returns The detected region, or `null` if `hintOpIdx` is out of range or
|
|
1767
|
+
* not within any simple-table region.
|
|
1768
|
+
*
|
|
1769
|
+
* @example
|
|
1770
|
+
* // After hit-testing a `<td>` element to a Delta op index:
|
|
1771
|
+
* const region = extractTableRegion(state.delta.ops, hitOpIdx);
|
|
1772
|
+
* if (region) {
|
|
1773
|
+
* const md = deltaToMarkdown(new Delta(region.ops), {
|
|
1774
|
+
* trimTrailingNewlines: true,
|
|
1775
|
+
* });
|
|
1776
|
+
* // replace ops in [region.startOpIdx, region.endOpIdx] with a single
|
|
1777
|
+
* // { insert: md + '\n' } op to enter source-edit mode
|
|
1778
|
+
* }
|
|
1779
|
+
*/
|
|
1780
|
+
declare function extractTableRegion(ops: readonly Op[], hintOpIdx: number): TableRegion | null;
|
|
1781
|
+
|
|
1782
|
+
export { ALERT_TYPES, type AlertBlockData, type AlertType, type AlignType, BOX_FLOAT_VALUES, BOX_OVERFLOW_VALUES, type BlockContext, type BlockHandler, BlockHandlerRegistry, type BlockRenderOptions, type BoxBlockData, type BoxFloat, type BoxOpAttributes, type BoxOverflow, BrowserDOMAdapter, type CellAlign, type CellData, type ColumnsBlockData, type DOMAdapter, type DOMDocument, type DOMDocumentFragment, type DOMElement, type DOMNode, type DOMNodeList, type DeltaToHtmlOptions, type DeltaToMarkdownOptions, type FootnotesBlockData, type Format, type FormatDefinition, type FormatMatchResult, type FormatScope, type HtmlToDeltaOptions, type ListType, type MarkdownToDeltaOptions, NODE_TYPE, NodeDOMAdapter, Registry, type SanitizeOptions, type TableBlockData, type TableColAlignType, type TableRegion, alertBlockHandler, alignFormat, backgroundFormat, blockFormat, blockquoteFormat, boldFormat, boxBlockHandler, browserAdapter, cloneDelta, codeBlockFormat, codeFormat, colorFormat, columnsBlockHandler, createDefaultBlockHandlers, createDefaultRegistry, defaultBlockFormats, defaultEmbedFormats, defaultFormats, defaultInlineFormats, deltaToHtml, deltaToMarkdown, dividerFormat, escapeHtml, extractBoxOpAttributes, extractTableRegion, fontFormat, footnoteRefFormat, footnotesBlockHandler, formulaFormat, getAdapter, getNamedColors, headerFormat, headerIdFormat, htmlToDelta, imageFormat, indentFormat, isAdapterAvailable, isElement, isRemarkAvailable, isTableNewlineOp, isTextNode, isValidColor, isValidHexColor, italicFormat, kbdFormat, linkFormat, listFormat, markFormat, markdownToDelta, markdownToDeltaSync, nodeAdapter, normalizeDelta, preloadRemark, sanitizeDelta, sizeFormat, slugify, slugifyWithDedup, strikeFormat, subscriptFormat, superscriptFormat, tableBlockHandler, tableColAlignFormat, tableColFormat, tableHeaderFormat, tableRowFormat, toHexColor, underlineFormat, unescapeHtml, validateDelta, videoFormat };
|
package/dist/index.js
CHANGED
|
@@ -3654,7 +3654,8 @@ function deltaToMarkdown(delta, options = {}) {
|
|
|
3654
3654
|
embedRenderers = {},
|
|
3655
3655
|
blockHandlers,
|
|
3656
3656
|
prettyHtml = false,
|
|
3657
|
-
registry
|
|
3657
|
+
registry,
|
|
3658
|
+
trimTrailingNewlines = false
|
|
3658
3659
|
} = options;
|
|
3659
3660
|
const useLatexDelimiters = mathSyntax === "latex";
|
|
3660
3661
|
const lines = splitIntoLines2(delta.ops);
|
|
@@ -3752,7 +3753,8 @@ ${code}
|
|
|
3752
3753
|
lastIndent = indent;
|
|
3753
3754
|
lastWasBlockquote = isBlockquote;
|
|
3754
3755
|
}
|
|
3755
|
-
|
|
3756
|
+
const md = result.join("\n");
|
|
3757
|
+
return trimTrailingNewlines ? md.replace(/\n+$/, "") : md;
|
|
3756
3758
|
}
|
|
3757
3759
|
function hasBlockFormat(attrs) {
|
|
3758
3760
|
return !!(attrs.header || attrs.list || attrs.blockquote || attrs["code-block"] || attrs.align || attrs.indent);
|
|
@@ -4141,6 +4143,8 @@ var remarkGfm = null;
|
|
|
4141
4143
|
var remarkMath = null;
|
|
4142
4144
|
var unified = null;
|
|
4143
4145
|
function isRemarkAvailable() {
|
|
4146
|
+
if (unified && remarkParse) return true;
|
|
4147
|
+
if (typeof __require === "undefined") return false;
|
|
4144
4148
|
try {
|
|
4145
4149
|
__require.resolve("unified");
|
|
4146
4150
|
__require.resolve("remark-parse");
|
|
@@ -4149,8 +4153,8 @@ function isRemarkAvailable() {
|
|
|
4149
4153
|
return false;
|
|
4150
4154
|
}
|
|
4151
4155
|
}
|
|
4152
|
-
async function
|
|
4153
|
-
if (unified) return;
|
|
4156
|
+
async function preloadRemark() {
|
|
4157
|
+
if (unified && remarkParse && remarkGfm) return true;
|
|
4154
4158
|
try {
|
|
4155
4159
|
const [unifiedMod, remarkParseMod, remarkGfmMod] = await Promise.all([
|
|
4156
4160
|
import("unified"),
|
|
@@ -4161,15 +4165,16 @@ async function loadRemark() {
|
|
|
4161
4165
|
remarkParse = remarkParseMod.default;
|
|
4162
4166
|
remarkGfm = remarkGfmMod.default;
|
|
4163
4167
|
} catch {
|
|
4164
|
-
|
|
4165
|
-
"remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
|
|
4166
|
-
);
|
|
4168
|
+
return false;
|
|
4167
4169
|
}
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4170
|
+
if (!remarkMath) {
|
|
4171
|
+
try {
|
|
4172
|
+
const remarkMathMod = await import("remark-math");
|
|
4173
|
+
remarkMath = remarkMathMod.default;
|
|
4174
|
+
} catch {
|
|
4175
|
+
}
|
|
4172
4176
|
}
|
|
4177
|
+
return true;
|
|
4173
4178
|
}
|
|
4174
4179
|
function preprocessMarkdown(markdown, mathBlock) {
|
|
4175
4180
|
markdown = markdown.replace(/\\\((.+?)\\\)/g, (_match, content) => `$${content}$`);
|
|
@@ -4193,9 +4198,11 @@ async function markdownToDelta(markdown, options = {}) {
|
|
|
4193
4198
|
nodeHandlers = {}
|
|
4194
4199
|
} = options;
|
|
4195
4200
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4196
|
-
await
|
|
4197
|
-
if (!unified || !remarkParse) {
|
|
4198
|
-
throw new Error(
|
|
4201
|
+
const loaded = await preloadRemark();
|
|
4202
|
+
if (!loaded || !unified || !remarkParse) {
|
|
4203
|
+
throw new Error(
|
|
4204
|
+
"remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
|
|
4205
|
+
);
|
|
4199
4206
|
}
|
|
4200
4207
|
let processor = unified().use(remarkParse);
|
|
4201
4208
|
if (gfm && remarkGfm) {
|
|
@@ -4224,6 +4231,11 @@ function markdownToDeltaSync(markdown, options = {}) {
|
|
|
4224
4231
|
} = options;
|
|
4225
4232
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4226
4233
|
if (!unified || !remarkParse) {
|
|
4234
|
+
if (typeof __require === "undefined") {
|
|
4235
|
+
throw new Error(
|
|
4236
|
+
"markdownToDeltaSync requires remark to be preloaded in this environment. `require()` is not available (likely browser ESM). Call `await preloadRemark()` once on application startup before using the sync API, or use the async `markdownToDelta()` instead."
|
|
4237
|
+
);
|
|
4238
|
+
}
|
|
4227
4239
|
try {
|
|
4228
4240
|
const unifiedMod = __require("unified");
|
|
4229
4241
|
const remarkParseMod = __require("remark-parse");
|
|
@@ -4812,6 +4824,54 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4812
4824
|
}
|
|
4813
4825
|
return delta;
|
|
4814
4826
|
}
|
|
4827
|
+
|
|
4828
|
+
// src/conversion/markdown/table-region.ts
|
|
4829
|
+
import { isInsert as isInsert4, isTextInsert as isTextInsert3 } from "@scrider/delta";
|
|
4830
|
+
function isTableNewlineOp(op) {
|
|
4831
|
+
if (!op || !isInsert4(op) || !isTextInsert3(op)) return false;
|
|
4832
|
+
if (!op.insert.includes("\n")) return false;
|
|
4833
|
+
return !!op.attributes && "table-row" in op.attributes;
|
|
4834
|
+
}
|
|
4835
|
+
function extractTableRegion(ops, hintOpIdx) {
|
|
4836
|
+
if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
|
|
4837
|
+
let probeIdx = -1;
|
|
4838
|
+
for (let i = hintOpIdx; i < ops.length; i++) {
|
|
4839
|
+
const op = ops[i];
|
|
4840
|
+
if (!op || !isInsert4(op)) continue;
|
|
4841
|
+
if (isTextInsert3(op) && op.insert.includes("\n")) {
|
|
4842
|
+
probeIdx = i;
|
|
4843
|
+
break;
|
|
4844
|
+
}
|
|
4845
|
+
}
|
|
4846
|
+
if (probeIdx < 0) return null;
|
|
4847
|
+
if (!isTableNewlineOp(ops[probeIdx])) return null;
|
|
4848
|
+
let endOpIdx = probeIdx;
|
|
4849
|
+
for (let i = probeIdx + 1; i < ops.length; i++) {
|
|
4850
|
+
const op = ops[i];
|
|
4851
|
+
if (!op || !isInsert4(op)) break;
|
|
4852
|
+
if (isTextInsert3(op) && op.insert.includes("\n")) {
|
|
4853
|
+
if (isTableNewlineOp(op)) {
|
|
4854
|
+
endOpIdx = i;
|
|
4855
|
+
} else {
|
|
4856
|
+
break;
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
}
|
|
4860
|
+
let startOpIdx = 0;
|
|
4861
|
+
for (let i = probeIdx - 1; i >= 0; i--) {
|
|
4862
|
+
const op = ops[i];
|
|
4863
|
+
if (!op || !isInsert4(op)) {
|
|
4864
|
+
startOpIdx = i + 1;
|
|
4865
|
+
break;
|
|
4866
|
+
}
|
|
4867
|
+
if (isTextInsert3(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
|
|
4868
|
+
startOpIdx = i + 1;
|
|
4869
|
+
break;
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
|
|
4873
|
+
return { startOpIdx, endOpIdx, ops: regionOps };
|
|
4874
|
+
}
|
|
4815
4875
|
export {
|
|
4816
4876
|
ALERT_TYPES,
|
|
4817
4877
|
BOX_FLOAT_VALUES,
|
|
@@ -4845,6 +4905,7 @@ export {
|
|
|
4845
4905
|
dividerFormat,
|
|
4846
4906
|
escapeHtml,
|
|
4847
4907
|
extractBoxOpAttributes,
|
|
4908
|
+
extractTableRegion,
|
|
4848
4909
|
fontFormat,
|
|
4849
4910
|
footnoteRefFormat,
|
|
4850
4911
|
footnotesBlockHandler,
|
|
@@ -4859,6 +4920,7 @@ export {
|
|
|
4859
4920
|
isAdapterAvailable,
|
|
4860
4921
|
isElement,
|
|
4861
4922
|
isRemarkAvailable,
|
|
4923
|
+
isTableNewlineOp,
|
|
4862
4924
|
isTextNode,
|
|
4863
4925
|
isValidColor,
|
|
4864
4926
|
isValidHexColor,
|
|
@@ -4871,6 +4933,7 @@ export {
|
|
|
4871
4933
|
markdownToDeltaSync,
|
|
4872
4934
|
nodeAdapter,
|
|
4873
4935
|
normalizeDelta,
|
|
4936
|
+
preloadRemark,
|
|
4874
4937
|
sanitizeDelta,
|
|
4875
4938
|
sizeFormat,
|
|
4876
4939
|
slugify,
|