@scrider/formatter 1.0.1 → 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 +136 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -3
- package/dist/index.d.ts +127 -3
- package/dist/index.js +131 -20
- 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
|
|
@@ -67,6 +68,8 @@ interface DOMCSSStyleDeclaration {
|
|
|
67
68
|
setProperty(property: string, value: string): void;
|
|
68
69
|
color?: string;
|
|
69
70
|
backgroundColor?: string;
|
|
71
|
+
fontFamily?: string;
|
|
72
|
+
fontSize?: string;
|
|
70
73
|
fontWeight?: string;
|
|
71
74
|
fontStyle?: string;
|
|
72
75
|
textDecoration?: string;
|
|
@@ -788,6 +791,13 @@ declare const codeFormat: Format<boolean>;
|
|
|
788
791
|
*/
|
|
789
792
|
declare const colorFormat: Format<string>;
|
|
790
793
|
|
|
794
|
+
/**
|
|
795
|
+
* Font family format
|
|
796
|
+
*
|
|
797
|
+
* Delta: { insert: "text", attributes: { font: "Times New Roman" } }
|
|
798
|
+
*/
|
|
799
|
+
declare const fontFormat: Format<string>;
|
|
800
|
+
|
|
791
801
|
/**
|
|
792
802
|
* Italic format
|
|
793
803
|
*
|
|
@@ -825,6 +835,15 @@ declare const linkFormat: Format<string>;
|
|
|
825
835
|
*/
|
|
826
836
|
declare const markFormat: Format<boolean>;
|
|
827
837
|
|
|
838
|
+
/**
|
|
839
|
+
* Font size format
|
|
840
|
+
*
|
|
841
|
+
* Delta: { insert: "text", attributes: { size: "14pt" } }
|
|
842
|
+
*
|
|
843
|
+
* Value is a string with CSS unit (e.g. "14pt", "16px", "1.2em").
|
|
844
|
+
*/
|
|
845
|
+
declare const sizeFormat: Format<string>;
|
|
846
|
+
|
|
828
847
|
/**
|
|
829
848
|
* Strikethrough format
|
|
830
849
|
*
|
|
@@ -1538,6 +1557,18 @@ interface DeltaToMarkdownOptions {
|
|
|
1538
1557
|
* `render()` is used as HTML fallback in Markdown.
|
|
1539
1558
|
*/
|
|
1540
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;
|
|
1541
1572
|
}
|
|
1542
1573
|
/**
|
|
1543
1574
|
* Convert Delta to Markdown
|
|
@@ -1643,9 +1674,39 @@ interface ParserContext {
|
|
|
1643
1674
|
pushNewline(attrs?: AttributeMap): void;
|
|
1644
1675
|
}
|
|
1645
1676
|
/**
|
|
1646
|
-
* 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.
|
|
1647
1687
|
*/
|
|
1648
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>;
|
|
1649
1710
|
/**
|
|
1650
1711
|
* Convert Markdown to Delta (async)
|
|
1651
1712
|
*/
|
|
@@ -1655,4 +1716,67 @@ declare function markdownToDelta(markdown: string, options?: MarkdownToDeltaOpti
|
|
|
1655
1716
|
*/
|
|
1656
1717
|
declare function markdownToDeltaSync(markdown: string, options?: MarkdownToDeltaOptions): Delta;
|
|
1657
1718
|
|
|
1658
|
-
|
|
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
|
|
@@ -67,6 +68,8 @@ interface DOMCSSStyleDeclaration {
|
|
|
67
68
|
setProperty(property: string, value: string): void;
|
|
68
69
|
color?: string;
|
|
69
70
|
backgroundColor?: string;
|
|
71
|
+
fontFamily?: string;
|
|
72
|
+
fontSize?: string;
|
|
70
73
|
fontWeight?: string;
|
|
71
74
|
fontStyle?: string;
|
|
72
75
|
textDecoration?: string;
|
|
@@ -788,6 +791,13 @@ declare const codeFormat: Format<boolean>;
|
|
|
788
791
|
*/
|
|
789
792
|
declare const colorFormat: Format<string>;
|
|
790
793
|
|
|
794
|
+
/**
|
|
795
|
+
* Font family format
|
|
796
|
+
*
|
|
797
|
+
* Delta: { insert: "text", attributes: { font: "Times New Roman" } }
|
|
798
|
+
*/
|
|
799
|
+
declare const fontFormat: Format<string>;
|
|
800
|
+
|
|
791
801
|
/**
|
|
792
802
|
* Italic format
|
|
793
803
|
*
|
|
@@ -825,6 +835,15 @@ declare const linkFormat: Format<string>;
|
|
|
825
835
|
*/
|
|
826
836
|
declare const markFormat: Format<boolean>;
|
|
827
837
|
|
|
838
|
+
/**
|
|
839
|
+
* Font size format
|
|
840
|
+
*
|
|
841
|
+
* Delta: { insert: "text", attributes: { size: "14pt" } }
|
|
842
|
+
*
|
|
843
|
+
* Value is a string with CSS unit (e.g. "14pt", "16px", "1.2em").
|
|
844
|
+
*/
|
|
845
|
+
declare const sizeFormat: Format<string>;
|
|
846
|
+
|
|
828
847
|
/**
|
|
829
848
|
* Strikethrough format
|
|
830
849
|
*
|
|
@@ -1538,6 +1557,18 @@ interface DeltaToMarkdownOptions {
|
|
|
1538
1557
|
* `render()` is used as HTML fallback in Markdown.
|
|
1539
1558
|
*/
|
|
1540
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;
|
|
1541
1572
|
}
|
|
1542
1573
|
/**
|
|
1543
1574
|
* Convert Delta to Markdown
|
|
@@ -1643,9 +1674,39 @@ interface ParserContext {
|
|
|
1643
1674
|
pushNewline(attrs?: AttributeMap): void;
|
|
1644
1675
|
}
|
|
1645
1676
|
/**
|
|
1646
|
-
* 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.
|
|
1647
1687
|
*/
|
|
1648
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>;
|
|
1649
1710
|
/**
|
|
1650
1711
|
* Convert Markdown to Delta (async)
|
|
1651
1712
|
*/
|
|
@@ -1655,4 +1716,67 @@ declare function markdownToDelta(markdown: string, options?: MarkdownToDeltaOpti
|
|
|
1655
1716
|
*/
|
|
1656
1717
|
declare function markdownToDeltaSync(markdown: string, options?: MarkdownToDeltaOptions): Delta;
|
|
1657
1718
|
|
|
1658
|
-
|
|
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
|
@@ -1563,6 +1563,15 @@ var colorFormat = {
|
|
|
1563
1563
|
}
|
|
1564
1564
|
};
|
|
1565
1565
|
|
|
1566
|
+
// src/schema/formats/inline/font.ts
|
|
1567
|
+
var fontFormat = {
|
|
1568
|
+
name: "font",
|
|
1569
|
+
scope: "inline",
|
|
1570
|
+
validate(value) {
|
|
1571
|
+
return typeof value === "string" && value.length > 0;
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
|
|
1566
1575
|
// src/schema/formats/inline/italic.ts
|
|
1567
1576
|
var italicFormat = {
|
|
1568
1577
|
name: "italic",
|
|
@@ -1620,6 +1629,15 @@ var markFormat = {
|
|
|
1620
1629
|
}
|
|
1621
1630
|
};
|
|
1622
1631
|
|
|
1632
|
+
// src/schema/formats/inline/size.ts
|
|
1633
|
+
var sizeFormat = {
|
|
1634
|
+
name: "size",
|
|
1635
|
+
scope: "inline",
|
|
1636
|
+
validate(value) {
|
|
1637
|
+
return typeof value === "string" && value.length > 0;
|
|
1638
|
+
}
|
|
1639
|
+
};
|
|
1640
|
+
|
|
1623
1641
|
// src/schema/formats/inline/strike.ts
|
|
1624
1642
|
var strikeFormat = {
|
|
1625
1643
|
name: "strike",
|
|
@@ -1827,7 +1845,9 @@ var INLINE_FORMAT_ORDER = [
|
|
|
1827
1845
|
];
|
|
1828
1846
|
var INLINE_STYLE_FORMATS = {
|
|
1829
1847
|
color: "color",
|
|
1830
|
-
background: "background-color"
|
|
1848
|
+
background: "background-color",
|
|
1849
|
+
font: "font-family",
|
|
1850
|
+
size: "font-size"
|
|
1831
1851
|
};
|
|
1832
1852
|
var BLOCK_FORMAT_TAGS = {
|
|
1833
1853
|
header: (value) => `h${String(value)}`,
|
|
@@ -2212,6 +2232,8 @@ var defaultInlineFormats = [
|
|
|
2212
2232
|
linkFormat,
|
|
2213
2233
|
colorFormat,
|
|
2214
2234
|
backgroundFormat,
|
|
2235
|
+
fontFormat,
|
|
2236
|
+
sizeFormat,
|
|
2215
2237
|
markFormat,
|
|
2216
2238
|
kbdFormat
|
|
2217
2239
|
];
|
|
@@ -3242,6 +3264,14 @@ function htmlToDelta(html, options = {}) {
|
|
|
3242
3264
|
if (bg) {
|
|
3243
3265
|
currentAttributes.background = bg;
|
|
3244
3266
|
}
|
|
3267
|
+
const fontFamily = element.style?.fontFamily || element.style?.getPropertyValue?.("font-family");
|
|
3268
|
+
if (fontFamily) {
|
|
3269
|
+
currentAttributes.font = fontFamily.replace(/^["']|["']$/g, "");
|
|
3270
|
+
}
|
|
3271
|
+
const fontSize = element.style?.fontSize || element.style?.getPropertyValue?.("font-size");
|
|
3272
|
+
if (fontSize) {
|
|
3273
|
+
currentAttributes.size = fontSize;
|
|
3274
|
+
}
|
|
3245
3275
|
processChildren(element);
|
|
3246
3276
|
flushText();
|
|
3247
3277
|
currentAttributes = prevAttrs;
|
|
@@ -3624,7 +3654,8 @@ function deltaToMarkdown(delta, options = {}) {
|
|
|
3624
3654
|
embedRenderers = {},
|
|
3625
3655
|
blockHandlers,
|
|
3626
3656
|
prettyHtml = false,
|
|
3627
|
-
registry
|
|
3657
|
+
registry,
|
|
3658
|
+
trimTrailingNewlines = false
|
|
3628
3659
|
} = options;
|
|
3629
3660
|
const useLatexDelimiters = mathSyntax === "latex";
|
|
3630
3661
|
const lines = splitIntoLines2(delta.ops);
|
|
@@ -3722,7 +3753,8 @@ ${code}
|
|
|
3722
3753
|
lastIndent = indent;
|
|
3723
3754
|
lastWasBlockquote = isBlockquote;
|
|
3724
3755
|
}
|
|
3725
|
-
|
|
3756
|
+
const md = result.join("\n");
|
|
3757
|
+
return trimTrailingNewlines ? md.replace(/\n+$/, "") : md;
|
|
3726
3758
|
}
|
|
3727
3759
|
function hasBlockFormat(attrs) {
|
|
3728
3760
|
return !!(attrs.header || attrs.list || attrs.blockquote || attrs["code-block"] || attrs.align || attrs.indent);
|
|
@@ -3943,11 +3975,14 @@ function renderInlineText2(text, attributes) {
|
|
|
3943
3975
|
if (link) {
|
|
3944
3976
|
result = renderLink(result, link);
|
|
3945
3977
|
}
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3978
|
+
const styleProps = [];
|
|
3979
|
+
if (typeof attributes.color === "string") styleProps.push(`color: ${attributes.color}`);
|
|
3980
|
+
if (typeof attributes.background === "string")
|
|
3981
|
+
styleProps.push(`background-color: ${attributes.background}`);
|
|
3982
|
+
if (typeof attributes.font === "string") styleProps.push(`font-family: ${attributes.font}`);
|
|
3983
|
+
if (typeof attributes.size === "string") styleProps.push(`font-size: ${attributes.size}`);
|
|
3984
|
+
if (styleProps.length > 0) {
|
|
3985
|
+
result = `<span style="${styleProps.join("; ")}">${result}</span>`;
|
|
3951
3986
|
}
|
|
3952
3987
|
return result;
|
|
3953
3988
|
}
|
|
@@ -4108,6 +4143,8 @@ var remarkGfm = null;
|
|
|
4108
4143
|
var remarkMath = null;
|
|
4109
4144
|
var unified = null;
|
|
4110
4145
|
function isRemarkAvailable() {
|
|
4146
|
+
if (unified && remarkParse) return true;
|
|
4147
|
+
if (typeof __require === "undefined") return false;
|
|
4111
4148
|
try {
|
|
4112
4149
|
__require.resolve("unified");
|
|
4113
4150
|
__require.resolve("remark-parse");
|
|
@@ -4116,8 +4153,8 @@ function isRemarkAvailable() {
|
|
|
4116
4153
|
return false;
|
|
4117
4154
|
}
|
|
4118
4155
|
}
|
|
4119
|
-
async function
|
|
4120
|
-
if (unified) return;
|
|
4156
|
+
async function preloadRemark() {
|
|
4157
|
+
if (unified && remarkParse && remarkGfm) return true;
|
|
4121
4158
|
try {
|
|
4122
4159
|
const [unifiedMod, remarkParseMod, remarkGfmMod] = await Promise.all([
|
|
4123
4160
|
import("unified"),
|
|
@@ -4128,15 +4165,16 @@ async function loadRemark() {
|
|
|
4128
4165
|
remarkParse = remarkParseMod.default;
|
|
4129
4166
|
remarkGfm = remarkGfmMod.default;
|
|
4130
4167
|
} catch {
|
|
4131
|
-
|
|
4132
|
-
"remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
|
|
4133
|
-
);
|
|
4168
|
+
return false;
|
|
4134
4169
|
}
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4170
|
+
if (!remarkMath) {
|
|
4171
|
+
try {
|
|
4172
|
+
const remarkMathMod = await import("remark-math");
|
|
4173
|
+
remarkMath = remarkMathMod.default;
|
|
4174
|
+
} catch {
|
|
4175
|
+
}
|
|
4139
4176
|
}
|
|
4177
|
+
return true;
|
|
4140
4178
|
}
|
|
4141
4179
|
function preprocessMarkdown(markdown, mathBlock) {
|
|
4142
4180
|
markdown = markdown.replace(/\\\((.+?)\\\)/g, (_match, content) => `$${content}$`);
|
|
@@ -4160,9 +4198,11 @@ async function markdownToDelta(markdown, options = {}) {
|
|
|
4160
4198
|
nodeHandlers = {}
|
|
4161
4199
|
} = options;
|
|
4162
4200
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4163
|
-
await
|
|
4164
|
-
if (!unified || !remarkParse) {
|
|
4165
|
-
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
|
+
);
|
|
4166
4206
|
}
|
|
4167
4207
|
let processor = unified().use(remarkParse);
|
|
4168
4208
|
if (gfm && remarkGfm) {
|
|
@@ -4191,6 +4231,11 @@ function markdownToDeltaSync(markdown, options = {}) {
|
|
|
4191
4231
|
} = options;
|
|
4192
4232
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4193
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
|
+
}
|
|
4194
4239
|
try {
|
|
4195
4240
|
const unifiedMod = __require("unified");
|
|
4196
4241
|
const remarkParseMod = __require("remark-parse");
|
|
@@ -4689,6 +4734,19 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4689
4734
|
currentInlineAttrs = { ...currentInlineAttrs, background: bgMatch[1].trim() };
|
|
4690
4735
|
addedKeys.push("background");
|
|
4691
4736
|
}
|
|
4737
|
+
const fontMatch = style.match(/(?:^|;)\s*font-family\s*:\s*([^;]+)/i);
|
|
4738
|
+
if (fontMatch) {
|
|
4739
|
+
currentInlineAttrs = {
|
|
4740
|
+
...currentInlineAttrs,
|
|
4741
|
+
font: fontMatch[1].trim().replace(/^["']|["']$/g, "")
|
|
4742
|
+
};
|
|
4743
|
+
addedKeys.push("font");
|
|
4744
|
+
}
|
|
4745
|
+
const sizeMatch = style.match(/(?:^|;)\s*font-size\s*:\s*([^;]+)/i);
|
|
4746
|
+
if (sizeMatch) {
|
|
4747
|
+
currentInlineAttrs = { ...currentInlineAttrs, size: sizeMatch[1].trim() };
|
|
4748
|
+
addedKeys.push("size");
|
|
4749
|
+
}
|
|
4692
4750
|
spanAttrStack.push(addedKeys);
|
|
4693
4751
|
return;
|
|
4694
4752
|
}
|
|
@@ -4766,6 +4824,54 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4766
4824
|
}
|
|
4767
4825
|
return delta;
|
|
4768
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
|
+
}
|
|
4769
4875
|
export {
|
|
4770
4876
|
ALERT_TYPES,
|
|
4771
4877
|
BOX_FLOAT_VALUES,
|
|
@@ -4799,6 +4905,8 @@ export {
|
|
|
4799
4905
|
dividerFormat,
|
|
4800
4906
|
escapeHtml,
|
|
4801
4907
|
extractBoxOpAttributes,
|
|
4908
|
+
extractTableRegion,
|
|
4909
|
+
fontFormat,
|
|
4802
4910
|
footnoteRefFormat,
|
|
4803
4911
|
footnotesBlockHandler,
|
|
4804
4912
|
formulaFormat,
|
|
@@ -4812,6 +4920,7 @@ export {
|
|
|
4812
4920
|
isAdapterAvailable,
|
|
4813
4921
|
isElement,
|
|
4814
4922
|
isRemarkAvailable,
|
|
4923
|
+
isTableNewlineOp,
|
|
4815
4924
|
isTextNode,
|
|
4816
4925
|
isValidColor,
|
|
4817
4926
|
isValidHexColor,
|
|
@@ -4824,7 +4933,9 @@ export {
|
|
|
4824
4933
|
markdownToDeltaSync,
|
|
4825
4934
|
nodeAdapter,
|
|
4826
4935
|
normalizeDelta,
|
|
4936
|
+
preloadRemark,
|
|
4827
4937
|
sanitizeDelta,
|
|
4938
|
+
sizeFormat,
|
|
4828
4939
|
slugify,
|
|
4829
4940
|
slugifyWithDedup,
|
|
4830
4941
|
strikeFormat,
|