@nutrient-sdk/document-authoring 1.10.0-preview.202512171254.414ae9476ccdf6c895ab5cf4a5c42a6d1dc61dd9 → 1.10.0-preview.202512191647.d0b04b954e3b7e0dd1b4246e792bf01d9cf963f4

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/lib/index.d.mts CHANGED
@@ -652,7 +652,32 @@ export declare type DocAuthDocument = {
652
652
  */
653
653
  exportDOCX(options?: ExportDOCXOptions): Promise<ArrayBuffer>;
654
654
  /**
655
- * @alpha
655
+ * Executes a transaction to programmatically read or modify the document.
656
+ *
657
+ * @remarks
658
+ * Provides programmatic access to the document structure through a draft document that can be
659
+ * read and modified. Changes are atomic and isolated until the transaction commits.
660
+ *
661
+ * The callback executes after all pending transactions and input have been processed. While
662
+ * the callback runs, document access is blocked, preventing any UI interactions until the
663
+ * transaction completes.
664
+ *
665
+ * @param callback - A {@linkcode TransactionCallback} function that receives a draft document
666
+ * @returns A Promise that resolves to the result value from the callback
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * await doc.transaction(async ({ draft }) => {
671
+ * const section = draft.body().sections()[0];
672
+ * const para = section.content().addParagraph();
673
+ * para.asTextView().setText('Hello, World!');
674
+ * return { commit: true };
675
+ * });
676
+ * ```
677
+ *
678
+ * @see {@linkcode TransactionCallback} for the callback function signature
679
+ * @see {@linkcode TransactionResult} for return value options
680
+ * @see {@linkcode Programmatic} for the full programmatic API namespace
656
681
  */
657
682
  transaction<T = void>(callback: TransactionCallback<T>): Promise<T>;
658
683
  /**
@@ -826,6 +851,24 @@ export declare type DocAuthEditor = {
826
851
  * @sidebarGroupOrder 7
827
852
  */
828
853
  setToolbarConfig(config: ToolbarConfig): void;
854
+ /**
855
+ * Sets the author name used when creating comments and replies.
856
+ *
857
+ * @since 1.10.0
858
+ * @example
859
+ *
860
+ * ```ts
861
+ * // Set author when user logs in
862
+ * editor.setAuthor('John Doe');
863
+ *
864
+ * // Clear author when user logs out (will use localized "Anonymous")
865
+ * editor.setAuthor('');
866
+ * ```
867
+ *
868
+ * @param name - The author name to use for new comments
869
+ * @see {@linkcode UIOptions#author | UIOptions.author} for setting the initial author.
870
+ */
871
+ setAuthor(name: string): void;
829
872
  /**
830
873
  * Adds an event listener that will be called every time the specified event is emitted.
831
874
  *
@@ -1389,42 +1432,282 @@ export declare type ImportDOCXOptions = {
1389
1432
  export declare type Locale = 'en' | 'fr' | 'de';
1390
1433
 
1391
1434
  /**
1392
- * @alpha
1435
+ * @public
1393
1436
  * @sidebarGroup programmatic api
1394
1437
  */
1395
1438
  export declare namespace Programmatic {
1396
1439
  /**
1440
+ * Opaque type representing a contiguous region within the content.
1441
+ *
1442
+ * @remarks
1443
+ * Ranges can be obtained from various API methods and then passed to other operations.
1444
+ *
1445
+ * **Examples:**
1446
+ * - {@linkcode TextView.searchText} - Returns a range for a text match
1447
+ * - {@linkcode TextView.setText} - Can be used to replace a given range
1448
+ * - {@linkcode TextView.getPlainText} - Can be used to extract text at a specific range
1449
+ * - {@linkcode TextView.setFormatting} - Can be used to apply formatting to a specific range
1450
+ *
1397
1451
  * @sidebarGroup programmatic api
1398
1452
  */
1399
1453
  export type Range = {
1454
+ /**
1455
+ * @internal
1456
+ */
1400
1457
  begin: number;
1458
+ /**
1459
+ * @internal
1460
+ */
1401
1461
  end?: number;
1402
1462
  };
1403
1463
  /**
1464
+ * Defines text formatting properties that can be applied to document content.
1465
+ *
1466
+ * @remarks
1467
+ * The `Formatting` type specifies visual styling properties for text. All properties
1468
+ * use `null` to represent "inherited from style".
1469
+ *
1470
+ * When applying formatting via e.g. {@linkcode TextView.setFormatting}, you typically use
1471
+ * `Partial<Formatting>` to specify only the properties you want to change.
1472
+ *
1473
+ * @example
1474
+ * Apply bold and color to text:
1475
+ * ```typescript
1476
+ * textView.setFormatting({
1477
+ * bold: true,
1478
+ * color: "#ff0000"
1479
+ * });
1480
+ * ```
1481
+ *
1404
1482
  * @sidebarGroup programmatic api
1405
1483
  */
1406
1484
  export type Formatting = {
1485
+ /**
1486
+ * Font family name (e.g., "Arial", "Times New Roman").
1487
+ *
1488
+ * @remarks
1489
+ * Specifies the typeface for the text.
1490
+ * `null` means no explicit font is set (inherits from style).
1491
+ */
1407
1492
  font: string | null;
1493
+ /**
1494
+ * Font size in points (e.g., 12, 14, 18).
1495
+ *
1496
+ * @remarks
1497
+ * Specifies the size of the text in typographic points (1 point = 1/72 inch).
1498
+ * Common sizes are 10-12 for body text, 14-18 for headings. `null` means no
1499
+ * explicit size is set (inherits from style).
1500
+ */
1408
1501
  fontSize: number | null;
1502
+ /**
1503
+ * Bold text weight.
1504
+ *
1505
+ * @remarks
1506
+ * When `true`, text is rendered in bold weight. `false` or `null` means normal weight.
1507
+ */
1409
1508
  bold: boolean | null;
1509
+ /**
1510
+ * Italic text style.
1511
+ *
1512
+ * @remarks
1513
+ * When `true`, text is rendered in italic style. `false` or `null` means normal (upright) style.
1514
+ */
1410
1515
  italic: boolean | null;
1516
+ /**
1517
+ * Text foreground color.
1518
+ *
1519
+ * @remarks
1520
+ * Specifies the color of the text characters. Accepts hex color codes (e.g., "#ff0000" for red,
1521
+ * "#0000ff" for blue). `null` means no explicit color is set (inherits from style).
1522
+ */
1411
1523
  color: string | null;
1524
+ /**
1525
+ * Text background highlight color.
1526
+ *
1527
+ * @remarks
1528
+ * Specifies the background color behind the text (like a highlighter pen). Accepts hex color
1529
+ * codes (e.g., "#ffff00" for yellow, "#00ff00" for green). `null` means no highlight.
1530
+ */
1412
1531
  highlight: string | null;
1532
+ /**
1533
+ * Strikethrough text decoration.
1534
+ *
1535
+ * @remarks
1536
+ * When `true`, text is rendered with a horizontal line through the middle.
1537
+ */
1413
1538
  strikeout: boolean | null;
1539
+ /**
1540
+ * Underline text decoration.
1541
+ *
1542
+ * @remarks
1543
+ * When `true`, text is rendered with a line underneath.
1544
+ */
1414
1545
  underline: boolean | null;
1415
1546
  };
1416
1547
  /**
1548
+ * Pattern type for searching content in documents.
1549
+ *
1550
+ * @remarks
1551
+ * `SearchFor` accepts either a string literal for exact matching or a regular expression
1552
+ * for pattern-based matching. Used by search and replace operations throughout the API.
1553
+ *
1554
+ * **String literals:**
1555
+ * - Performs case-sensitive exact substring matching
1556
+ * - Finds the first occurrence of the exact string
1557
+ *
1558
+ * **Regular expressions:**
1559
+ * - Supports full JavaScript RegExp syntax
1560
+ * - Use flags for case-insensitive (`i`)
1561
+ * - Word boundaries (`\b`), character classes, quantifiers, etc. are all supported
1562
+ *
1563
+ * @example
1564
+ * String literal search (exact, case-sensitive):
1565
+ * ```typescript
1566
+ * // Find exact string "hello"
1567
+ * const result = textView.searchText("hello");
1568
+ * ```
1569
+ *
1570
+ * @example
1571
+ * Case-insensitive word search:
1572
+ * ```typescript
1573
+ * // Find "hello" regardless of case, as a whole word
1574
+ * const result = textView.searchText(/\bhello\b/i);
1575
+ * ```
1576
+ *
1577
+ * @example
1578
+ * Pattern matching with RegExp:
1579
+ * ```typescript
1580
+ * // Find all numbers
1581
+ * draft.replaceText(/\d+/g, (match) => {
1582
+ * return `[${match}]`;
1583
+ * });
1584
+ *
1585
+ * // Find words starting with capital letter
1586
+ * const capitalWord = textView.searchText(/\b[A-Z][a-z]+\b/);
1587
+ * ```
1588
+ *
1589
+ * @example
1590
+ * Search and replace with different patterns:
1591
+ * ```typescript
1592
+ * // Replace exact string
1593
+ * paragraph.replaceText("TODO", "DONE");
1594
+ *
1595
+ * // Replace using pattern
1596
+ * paragraph.replaceText(/\bTODO\b/gi, "DONE");
1597
+ *
1598
+ * // Find dates in MM/DD/YYYY format
1599
+ * const datePattern = /\b\d{2}\/\d{2}\/\d{4}\b/;
1600
+ * paragraph.replaceText(datePattern, (match) => ({
1601
+ * text: match,
1602
+ * formatting: { bold: true, color: "#0000ff" }
1603
+ * }));
1604
+ * ```
1605
+ *
1417
1606
  * @sidebarGroup programmatic api
1418
1607
  */
1419
1608
  export type SearchFor = string | RegExp;
1420
1609
  /**
1610
+ * Specifies replacement content for text operations, including both text and formatting.
1611
+ *
1612
+ * @remarks
1613
+ * `Replacement` is used with replace operations to specify what should replace the matched content.
1614
+ *
1615
+ * When used in {@linkcode ReplaceTextSignature} operations, if `text` is omitted, the original
1616
+ * matched text is preserved and only formatting is modified.
1617
+ *
1618
+ * @example
1619
+ * Replace formatting only (preserve text):
1620
+ * ```typescript
1621
+ * // Highlight all occurrences of "important" without changing text
1622
+ * paragraph.replaceText(/important/gi, {
1623
+ * formatting: { highlight: "#ffff00", bold: true }
1624
+ * });
1625
+ * ```
1626
+ *
1627
+ * @example
1628
+ * Dynamic replacement based on match (using with {@linkcode ReplaceFn}):
1629
+ * ```typescript
1630
+ * // Convert numbers to currency format with styling
1631
+ * paragraph.replaceText(/\$?(\d+(\.\d{2})?)/g, (match) => {
1632
+ * const amount = parseFloat(match.replace('$', ''));
1633
+ * return {
1634
+ * text: `$${amount.toFixed(2)}`,
1635
+ * formatting: {
1636
+ * color: amount > 100 ? "#ff0000" : "#00ff00",
1637
+ * bold: amount > 100
1638
+ * }
1639
+ * };
1640
+ * });
1641
+ * ```
1642
+ *
1421
1643
  * @sidebarGroup programmatic api
1422
1644
  */
1423
1645
  export type Replacement = {
1646
+ /**
1647
+ * The replacement text content.
1648
+ *
1649
+ * @remarks
1650
+ * When specified, replaces the matched text with this string. When omitted,
1651
+ * the original matched text is preserved (useful for formatting-only changes).
1652
+ */
1424
1653
  text?: string;
1654
+ /**
1655
+ * Formatting to apply to the replacement text.
1656
+ *
1657
+ * @remarks
1658
+ * Specifies formatting properties to apply.
1659
+ */
1425
1660
  formatting?: Partial<Formatting>;
1426
1661
  };
1427
1662
  /**
1663
+ * Callback function that dynamically generates replacement content based on matched text.
1664
+ *
1665
+ * @remarks
1666
+ * `ReplaceFn` allows you to compute replacement content dynamically for each match found
1667
+ * during a replace operation. The function receives the matched text as input and returns
1668
+ * the replacment.
1669
+ *
1670
+ * This is particularly useful for:
1671
+ * - Transforming matched text based on its content (e.g., converting to uppercase, parsing numbers)
1672
+ * - Applying conditional formatting based on matched values
1673
+ * - Implementing complex replacement logic that depends on the match
1674
+ *
1675
+ * @param value - The matched text string from the search pattern
1676
+ * @returns Either a {@linkcode Replacement} object (for text and/or formatting changes) or a string (for simple text replacement)
1677
+ *
1678
+ * @example
1679
+ * Transform matched text to uppercase:
1680
+ * ```typescript
1681
+ * // Convert all words in parentheses to uppercase
1682
+ * paragraph.replaceText(/\((\w+)\)/g, (match) => {
1683
+ * return match.toUpperCase();
1684
+ * });
1685
+ * ```
1686
+ *
1687
+ * @example
1688
+ * Apply conditional formatting based on content:
1689
+ * ```typescript
1690
+ * // Highlight TODO items in yellow, URGENT items in red
1691
+ * draft.replaceText(/\b(TODO|URGENT)\b/g, (match) => {
1692
+ * return {
1693
+ * text: match,
1694
+ * formatting: {
1695
+ * highlight: match === "URGENT" ? "#ff0000" : "#ffff00",
1696
+ * bold: match === "URGENT"
1697
+ * }
1698
+ * };
1699
+ * });
1700
+ * ```
1701
+ *
1702
+ * @example
1703
+ * Parse and transform numeric values:
1704
+ * ```typescript
1705
+ * // Double all numbers in the text
1706
+ * paragraph.replaceText(/\d+/g, (match) => {
1707
+ * const num = parseInt(match);
1708
+ * return (num * 2).toString();
1709
+ * });
1710
+ * ```
1428
1711
  * @sidebarGroup programmatic api
1429
1712
  */
1430
1713
  export type ReplaceFn = (value: string) => Replacement | string;
@@ -1433,49 +1716,825 @@ export declare namespace Programmatic {
1433
1716
  */
1434
1717
  export type ReplacementOrReplaceFn = Replacement | ReplaceFn | string;
1435
1718
  /**
1719
+ * Function signature for replacing text content within a document element.
1720
+ *
1721
+ * @remarks
1722
+ * The `replaceText` method searches for all occurrences of a specified pattern and replaces them
1723
+ * with new content. It can operate on various document elements including paragraphs, tables,
1724
+ * sections, and the entire document body. The method processes all matches sequentially and
1725
+ * returns the total number of replacements made.
1726
+ *
1727
+ * @param searchFor - The pattern to search for. Can be:
1728
+ * - A string literal (case-sensitive, will match exact occurrences)
1729
+ * - A RegExp for pattern matching (e.g., `/\bword\b/i` for case-insensitive word boundaries)
1730
+ *
1731
+ * @param replace - The replacement content. Can be:
1732
+ * - A string: Simple text replacement
1733
+ * - A {@linkcode Replacement} object: Replace text and/or apply formatting
1734
+ * - A {@linkcode ReplaceFn} callback: Dynamic replacement based on matched text
1735
+ *
1736
+ * @returns The total number of replacements made
1737
+ *
1738
+ * @example Simple string replacement
1739
+ * ```typescript
1740
+ * // Replace all occurrences of "hello" with "goodbye"
1741
+ * const count = paragraph.replaceText("hello", "goodbye");
1742
+ * console.log(`Replaced ${count} occurrences`);
1743
+ * ```
1744
+ *
1745
+ * @example Regular expression with formatting
1746
+ * ```typescript
1747
+ * // Find all "hi" and highlight them
1748
+ * draft.replaceText(/\\bhi\\b/i, {
1749
+ * text: "REPLACED",
1750
+ * formatting: {
1751
+ * highlight: "#ff0000",
1752
+ * bold: true
1753
+ * }
1754
+ * });
1755
+ * ```
1756
+ *
1757
+ * @example Dynamic replacement with callback
1758
+ * ```typescript
1759
+ * // Convert all numbers to their doubled value
1760
+ * draft.replaceText(/\d+/g, (match) => {
1761
+ * const num = parseInt(match);
1762
+ * return {
1763
+ * text: (num * 2).toString(),
1764
+ * formatting: { color: "#0000ff" }
1765
+ * };
1766
+ * });
1767
+ * ```
1768
+ *
1769
+ * @example Formatting-only changes (preserving original text)
1770
+ * ```typescript
1771
+ * // Highlight all occurrences of "important" without changing the text
1772
+ * draft.replaceText(/important/i, (match) => ({
1773
+ * text: match, // Keep original text (preserves case)
1774
+ * formatting: { highlight: "#ffff00", bold: true }
1775
+ * }));
1776
+ * ```
1777
+ *
1436
1778
  * @sidebarGroup programmatic api
1437
1779
  */
1438
1780
  export type ReplaceTextSignature = (searchFor: SearchFor, replace: ReplacementOrReplaceFn) => number;
1439
1781
  /**
1782
+ * Represents a single match found by a search operation.
1783
+ *
1784
+ * @remarks
1785
+ * `SearchResult` is returned by {@linkcode TextView.searchText} when a match is found. It contains
1786
+ * both the matched text and a range, allowing you to inspect the match
1787
+ * and perform further operations on it.
1788
+ *
1789
+ * The `range` property can be passed to other methods like {@linkcode TextView.setFormatting},
1790
+ * {@linkcode TextView.setText}, or back to {@linkcode TextView.searchText} to continue searching
1791
+ * after this match.
1792
+ *
1793
+ * When no match is found, `searchText` returns `undefined` instead of a `SearchResult`.
1794
+ *
1795
+ * @example
1796
+ * Find and highlight the first occurrence:
1797
+ * ```typescript
1798
+ * const result = textView.searchText("important");
1799
+ * if (result) {
1800
+ * console.log(`Found "${result.text}"`);
1801
+ * textView.setFormatting({ highlight: "#ffff00" }, result.range);
1802
+ * }
1803
+ * ```
1804
+ *
1805
+ * @example
1806
+ * Double all numbers:
1807
+ * ```typescript
1808
+ * const searchFor = /\d+/i
1809
+ * let result = textView.search(searchFor)
1810
+ *
1811
+ * while(result) {
1812
+ * const newRange = textView.replace(`${parseFloat(result.text)*2}`,result.range)
1813
+ * result = textView.search(searchFor,newRange)
1814
+ * }
1815
+ * ```
1816
+ *
1440
1817
  * @sidebarGroup programmatic api
1441
1818
  */
1442
1819
  export type SearchResult = {
1820
+ /**
1821
+ * The location of the matched text within the document.
1822
+ *
1823
+ * @remarks
1824
+ * An opaque {@linkcode Range} object identifying where the match was found. This range
1825
+ * can be used with other TextView methods to manipulate the matched text, or passed
1826
+ * back to {@linkcode TextView.searchText} to continue searching after this match.
1827
+ */
1443
1828
  range: Range;
1829
+ /**
1830
+ * The matched text content.
1831
+ *
1832
+ * @remarks
1833
+ * The actual text string that was matched by the search pattern. For string searches,
1834
+ * this is identical to the search string. For RegExp searches, this is the text that
1835
+ * matched the pattern.
1836
+ */
1444
1837
  text: string;
1445
1838
  };
1446
1839
  /**
1840
+ * Provides methods for reading and manipulating text content within a paragraph.
1841
+ *
1842
+ * @remarks
1843
+ * `TextView` is the primary interface for working with text content in paragraphs. It provides
1844
+ * comprehensive text manipulation capabilities including:
1845
+ * - Reading plain text ({@linkcode getPlainText})
1846
+ * - Searching for patterns ({@linkcode searchText})
1847
+ * - Replacing text with formatting ({@linkcode replaceText})
1848
+ * - Setting or replacing text content ({@linkcode setText})
1849
+ * - Applying formatting to existing text ({@linkcode setFormatting})
1850
+ * - Accessing inline elements like text runs, images, line breaks ({@linkcode inlines})
1851
+ * - Adding new inline elements
1852
+ *
1853
+ * You obtain a `TextView` by calling {@linkcode Paragraph.asTextView} on a paragraph object.
1854
+ *
1855
+ * @example
1856
+ * Basic text operations:
1857
+ * ```typescript
1858
+ * const textView = paragraph.asTextView();
1859
+ *
1860
+ * // Read text
1861
+ * const text = textView.getPlainText();
1862
+ * console.log('Paragraph text:', text);
1863
+ *
1864
+ * // Replace text
1865
+ * textView.setText('New paragraph content');
1866
+ *
1867
+ * // Apply formatting
1868
+ * textView.setFormatting({ bold: true, fontSize: 14 });
1869
+ * ```
1870
+ *
1871
+ * @example
1872
+ * Search and replace operations:
1873
+ * ```typescript
1874
+ * const textView = paragraph.asTextView();
1875
+ *
1876
+ * // Find first occurrence
1877
+ * const result = textView.searchText(/important/i);
1878
+ * if (result) {
1879
+ * console.log(`Found "${result.text}" at range`);
1880
+ * textView.setFormatting({ highlight: '#ffff00' }, result.range);
1881
+ * }
1882
+ *
1883
+ * // Replace all occurrences
1884
+ * const count = textView.replaceText(/TODO/g, {
1885
+ * text: 'DONE',
1886
+ * formatting: { color: '#00ff00' }
1887
+ * });
1888
+ * console.log(`Replaced ${count} occurrences`);
1889
+ * ```
1890
+ *
1891
+ * @example
1892
+ * Working with inline elements:
1893
+ * ```typescript
1894
+ * const textView = paragraph.asTextView();
1895
+ *
1896
+ * // Get all inline elements
1897
+ * const inlines = textView.inlines();
1898
+ *
1899
+ * // Find text and images
1900
+ * for (const rangeInline of inlines) {
1901
+ * if (rangeInline.inline.type === 'text') {
1902
+ * console.log('Text:', rangeInline.inline.plainText());
1903
+ * } else if (rangeInline.inline.type === 'image') {
1904
+ * const extent = rangeInline.inline.extent();
1905
+ * console.log(`Image: ${extent.width}x${extent.height}`);
1906
+ * }
1907
+ * }
1908
+ *
1909
+ * // Add new content
1910
+ * textView.addInlineText(' (added text)');
1911
+ * textView.addLineBreak();
1912
+ * ```
1913
+ *
1447
1914
  * @sidebarGroup programmatic api
1448
1915
  */
1449
1916
  export type TextView = {
1917
+ /**
1918
+ * Extracts the plain text content without formatting.
1919
+ *
1920
+ * @param range - Optional range to extract text from. If omitted, returns all text.
1921
+ * @returns The plain text string
1922
+ *
1923
+ * @remarks
1924
+ * Returns the text content as a plain string, stripping out all formatting, images, and
1925
+ * other inline elements. Line breaks within the paragraph are preserved as newline characters.
1926
+ *
1927
+ * When a range is provided, only the text within that range is returned. Ranges are typically
1928
+ * obtained from search operations ({@linkcode searchText}) or other API methods.
1929
+ *
1930
+ * @example
1931
+ * Get all text from a paragraph:
1932
+ * ```typescript
1933
+ * const textView = paragraph.asTextView();
1934
+ * const text = textView.getPlainText();
1935
+ * console.log('Full text:', text);
1936
+ * ```
1937
+ *
1938
+ * @example
1939
+ * Get text from a specific range:
1940
+ * ```typescript
1941
+ * const result = textView.searchText('important');
1942
+ * if (result) {
1943
+ * const matchedText = textView.getPlainText(result.range);
1944
+ * console.log('Matched text:', matchedText); // "important"
1945
+ * }
1946
+ * ```
1947
+ */
1450
1948
  getPlainText(range?: Range): string;
1949
+ /**
1950
+ * Searches for the first occurrence of a pattern.
1951
+ *
1952
+ * @param searchFor - The pattern to search for (string or RegExp)
1953
+ * @param after - Optional range to start searching after. If omitted, searches from the beginning.
1954
+ * @returns A {@linkcode SearchResult} if found, or `undefined` if no match exists
1955
+ *
1956
+ * @remarks
1957
+ * Searches for the first occurrence of the specified pattern within the text view. Returns
1958
+ * a {@linkcode SearchResult} containing both the matched text and its location as a {@linkcode Range}.
1959
+ *
1960
+ * The `after` parameter allows you to search iteratively by passing the range from a previous
1961
+ * match, enabling you to find subsequent occurrences. This is useful for implementing custom
1962
+ * find-next functionality.
1963
+ *
1964
+ * Unlike {@linkcode replaceText}, this method only finds the first occurrence (or the first
1965
+ * occurrence after the specified range). Use this when you need to:
1966
+ * - Check if a pattern exists
1967
+ * - Get the location of a match for further processing
1968
+ * - Iterate through matches manually with custom logic
1969
+ *
1970
+ * @example
1971
+ * Find first occurrence:
1972
+ * ```typescript
1973
+ * const result = textView.searchText('hello');
1974
+ * if (result) {
1975
+ * console.log(`Found "${result.text}"`);
1976
+ * // Apply formatting to the match
1977
+ * textView.setFormatting({ bold: true }, result.range);
1978
+ * } else {
1979
+ * console.log('Pattern not found');
1980
+ * }
1981
+ * ```
1982
+ *
1983
+ * @example
1984
+ * Iterate through all matches:
1985
+ * ```typescript
1986
+ * const pattern = /TODO/gi;
1987
+ * let result = textView.searchText(pattern);
1988
+ * let count = 0;
1989
+ *
1990
+ * while (result) {
1991
+ * count++;
1992
+ * console.log(`Match ${count}: "${result.text}"`);
1993
+ * // Highlight each match
1994
+ * textView.setFormatting({ highlight: '#ffff00' }, result.range);
1995
+ * // Search for next occurrence after this one
1996
+ * result = textView.searchText(pattern, result.range);
1997
+ * }
1998
+ * console.log(`Found ${count} matches`);
1999
+ * ```
2000
+ *
2001
+ * @example
2002
+ * Case-insensitive search:
2003
+ * ```typescript
2004
+ * const result = textView.searchText(/error/i);
2005
+ * if (result) {
2006
+ * // Matches "error", "Error", "ERROR", etc.
2007
+ * textView.setFormatting({ color: '#ff0000' }, result.range);
2008
+ * }
2009
+ * ```
2010
+ */
1451
2011
  searchText(searchFor: SearchFor, after?: Range): SearchResult | undefined;
2012
+ /**
2013
+ * Replaces all occurrences of a pattern with new content.
2014
+ *
2015
+ * @remarks
2016
+ * Searches for all matches of the pattern within this text view and replaces them with
2017
+ * the specified content. The replacement can be a simple string, a {@linkcode Replacement}
2018
+ * object with text and formatting, or a {@linkcode ReplaceFn} callback for dynamic replacements.
2019
+ *
2020
+ * Returns the total number of replacements made, which is useful for confirming the
2021
+ * operation succeeded and for logging/reporting purposes.
2022
+ *
2023
+ * See {@linkcode ReplaceTextSignature} for complete documentation, parameters, and examples.
2024
+ *
2025
+ * @example
2026
+ * Simple text replacement:
2027
+ * ```typescript
2028
+ * const count = textView.replaceText('old', 'new');
2029
+ * console.log(`Replaced ${count} occurrences`);
2030
+ * ```
2031
+ *
2032
+ * @example
2033
+ * Replace with formatting:
2034
+ * ```typescript
2035
+ * textView.replaceText(/ERROR/gi, {
2036
+ * text: 'ERROR',
2037
+ * formatting: { color: '#ff0000', bold: true }
2038
+ * });
2039
+ * ```
2040
+ *
2041
+ * @example
2042
+ * Dynamic replacement with callback:
2043
+ * ```typescript
2044
+ * textView.replaceText(/\d+/g, (match) => {
2045
+ * const num = parseInt(match);
2046
+ * return (num * 2).toString();
2047
+ * });
2048
+ * ```
2049
+ */
1452
2050
  replaceText: ReplaceTextSignature;
2051
+ /**
2052
+ * Sets or replaces text content within the text view.
2053
+ *
2054
+ * @param value - The new text content to insert
2055
+ * @param range - Optional range to replace. If omitted, replaces all content.
2056
+ * @returns A {@linkcode Range} representing the location of the newly inserted text
2057
+ *
2058
+ * @remarks
2059
+ * Inserts or replaces text content. When no range is specified, this replaces all
2060
+ * existing content in the text view with the new value. When a range is provided,
2061
+ * only the content within that range is replaced.
2062
+ *
2063
+ * The returned range represents the location of the newly inserted text, which can
2064
+ * be used for subsequent operations like applying formatting or further modifications.
2065
+ *
2066
+ * **Important:** This method replaces text but does not apply formatting. To apply
2067
+ * formatting, use {@linkcode setFormatting} with the returned range, or use
2068
+ * {@linkcode replaceText} to replace with both text and formatting in one operation.
2069
+ *
2070
+ * @example
2071
+ * Replace all content:
2072
+ * ```typescript
2073
+ * const textView = paragraph.asTextView();
2074
+ * const newRange = textView.setText('This is new content');
2075
+ *
2076
+ * // Apply formatting to the new text
2077
+ * textView.setFormatting({ bold: true, fontSize: 14 }, newRange);
2078
+ * ```
2079
+ *
2080
+ * @example
2081
+ * Replace text at a specific range:
2082
+ * ```typescript
2083
+ * const result = textView.searchText('hello');
2084
+ * if (result) {
2085
+ * // Replace "hello" with "goodbye"
2086
+ * const newRange = textView.setText('goodbye', result.range);
2087
+ * textView.setFormatting({ italic: true }, newRange);
2088
+ * }
2089
+ * ```
2090
+ *
2091
+ * @example
2092
+ * Build up content with multiple insertions:
2093
+ * ```typescript
2094
+ * const textView = paragraph.asTextView();
2095
+ *
2096
+ * // Start with empty content
2097
+ * textView.setText('');
2098
+ *
2099
+ * // Add content at the beginning
2100
+ * const range1 = textView.setText('First sentence. ');
2101
+ * textView.setFormatting({ bold: true }, range1);
2102
+ *
2103
+ * // Add more content
2104
+ * const range2 = textView.setText('Second sentence. ');
2105
+ * textView.setFormatting({ italic: true }, range2);
2106
+ * ```
2107
+ */
1453
2108
  setText(value: string, range?: Range): Range;
2109
+ /**
2110
+ * Applies formatting to text content.
2111
+ *
2112
+ * @param formatting - Partial formatting properties to apply
2113
+ * @param range - Optional range to apply formatting to. If omitted, formats all content.
2114
+ *
2115
+ * @remarks
2116
+ * Applies the specified formatting properties to text within the text view. Only the
2117
+ * properties included in the `formatting` parameter are modified; other formatting
2118
+ * properties remain unchanged.
2119
+ *
2120
+ * When no range is specified, formatting is applied to all content in the text view.
2121
+ * When a range is provided, only the content within that range is formatted. Ranges
2122
+ * are typically obtained from {@linkcode searchText} or {@linkcode setText}.
2123
+ *
2124
+ * **Note:** This method modifies formatting but does not change the text content itself.
2125
+ * To change both text and formatting simultaneously, use {@linkcode replaceText}.
2126
+ *
2127
+ * @example
2128
+ * Format entire paragraph:
2129
+ * ```typescript
2130
+ * const textView = paragraph.asTextView();
2131
+ * textView.setFormatting({
2132
+ * font: 'Arial',
2133
+ * fontSize: 12,
2134
+ * bold: true
2135
+ * });
2136
+ * ```
2137
+ *
2138
+ * @example
2139
+ * Format specific text found by search:
2140
+ * ```typescript
2141
+ * const result = textView.searchText(/important/i);
2142
+ * if (result) {
2143
+ * textView.setFormatting({
2144
+ * highlight: '#ffff00',
2145
+ * bold: true
2146
+ * }, result.range);
2147
+ * }
2148
+ * ```
2149
+ *
2150
+ * @example
2151
+ * Format newly inserted text:
2152
+ * ```typescript
2153
+ * const newRange = textView.setText('New heading');
2154
+ * textView.setFormatting({
2155
+ * fontSize: 18,
2156
+ * bold: true,
2157
+ * color: '#0000ff'
2158
+ * }, newRange);
2159
+ * ```
2160
+ *
2161
+ * @example
2162
+ * Apply partial formatting (only change color):
2163
+ * ```typescript
2164
+ * // Only change color, preserve all other formatting
2165
+ * textView.setFormatting({ color: '#ff0000' });
2166
+ * ```
2167
+ */
1454
2168
  setFormatting(formatting: Partial<Formatting>, range?: Range): void;
2169
+ /**
2170
+ * Gets all inline elements within the text view.
2171
+ *
2172
+ * @returns An array of {@linkcode RangeInline} objects, each containing an inline element and its range
2173
+ *
2174
+ * @remarks
2175
+ * Returns all inline elements (text runs, images, line breaks, footnotes, etc.) within
2176
+ * the text view. Each element is paired with its location ({@linkcode Range}) in a
2177
+ * {@linkcode RangeInline} object.
2178
+ *
2179
+ * The returned array preserves document order. Text content is split into multiple
2180
+ * {@linkcode InlineText} elements whenever formatting changes. Other inline types include:
2181
+ * - `'text'` - Text with consistent formatting ({@linkcode InlineText})
2182
+ * - `'image'` - Embedded images ({@linkcode Image})
2183
+ * - `'line-break'` - Soft line breaks ({@linkcode LineBreak})
2184
+ * - `'page-break'` - Page breaks ({@linkcode PageBreak})
2185
+ * - `'footnote'` - Footnote markers ({@linkcode Footnote})
2186
+ * - `'endnote'` - Endnote markers ({@linkcode Endnote})
2187
+ * - `'tab'` - Tab characters ({@linkcode Tab})
2188
+ * - And more (see {@linkcode Inline})
2189
+ *
2190
+ * Use the `type` property on each inline element to discriminate and access type-specific
2191
+ * methods and properties.
2192
+ *
2193
+ * @example
2194
+ * List all inline elements:
2195
+ * ```typescript
2196
+ * const inlines = textView.inlines();
2197
+ *
2198
+ * for (const rangeInline of inlines) {
2199
+ * const { inline, range } = rangeInline;
2200
+ *
2201
+ * if (inline.type === 'text') {
2202
+ * const text = inline.plainText();
2203
+ * const fmt = inline.formatting();
2204
+ * console.log(`Text: "${text}", Bold: ${fmt.bold}`);
2205
+ * } else if (inline.type === 'image') {
2206
+ * const extent = inline.extent();
2207
+ * console.log(`Image: ${extent.width}x${extent.height}`);
2208
+ * } else if (inline.type === 'line-break') {
2209
+ * console.log('Line break');
2210
+ * }
2211
+ * }
2212
+ * ```
2213
+ *
2214
+ * @example
2215
+ * Find and resize all images:
2216
+ * ```typescript
2217
+ * const inlines = textView.inlines();
2218
+ *
2219
+ * for (const rangeInline of inlines) {
2220
+ * if (rangeInline.inline.type === 'image') {
2221
+ * const image = rangeInline.inline;
2222
+ * const current = image.extent();
2223
+ *
2224
+ * // Scale to 50%
2225
+ * image.setExtent({
2226
+ * width: current.width * 0.5,
2227
+ * height: current.height * 0.5
2228
+ * });
2229
+ * }
2230
+ * }
2231
+ * ```
2232
+ *
2233
+ * @example
2234
+ * Extract and format all text runs:
2235
+ * ```typescript
2236
+ * const inlines = textView.inlines();
2237
+ *
2238
+ * for (const rangeInline of inlines) {
2239
+ * if (rangeInline.inline.type === 'text') {
2240
+ * const text = rangeInline.inline.plainText();
2241
+ * if (text.includes('TODO')) {
2242
+ * // Highlight TODOs
2243
+ * textView.setFormatting({ highlight: '#ffff00' }, rangeInline.range);
2244
+ * }
2245
+ * }
2246
+ * }
2247
+ * ```
2248
+ *
2249
+ * @example
2250
+ * Access footnote content:
2251
+ * ```typescript
2252
+ * const inlines = textView.inlines();
2253
+ *
2254
+ * for (const rangeInline of inlines) {
2255
+ * if (rangeInline.inline.type === 'footnote') {
2256
+ * const footnote = rangeInline.inline;
2257
+ * const content = footnote.content();
2258
+ * const paragraphs = content.blocklevels();
2259
+ * console.log(`Footnote has ${paragraphs.length} paragraphs`);
2260
+ * }
2261
+ * }
2262
+ * ```
2263
+ */
1455
2264
  inlines(): RangeInline[];
1456
- addLineBreak(insertionPoint?: {
1457
- placement: 'before' | 'after';
1458
- range: Range;
1459
- }): LineBreak;
2265
+ /**
2266
+ * Adds new inline text at a specific position.
2267
+ *
2268
+ * @param text - The text content to add
2269
+ * @param insertionPoint - Optional position to insert. If omitted, appends to the end.
2270
+ * @returns A {@linkcode Range} representing the location of the newly inserted text
2271
+ *
2272
+ * @remarks
2273
+ * Inserts new text content at the specified position without replacing existing content.
2274
+ * When no insertion point is provided, the text is appended to the end.
2275
+ *
2276
+ * The `insertionPoint` parameter specifies both a reference range and a placement
2277
+ * relative to that range:
2278
+ * - `placement: 'before'` - Insert before the reference range
2279
+ * - `placement: 'after'` - Insert after the reference range
2280
+ *
2281
+ * The returned range represents the location of the newly inserted text, which can
2282
+ * be used for subsequent operations like applying formatting.
2283
+ *
2284
+ * **Note:** The newly inserted text inherits formatting from its context. To apply
2285
+ * specific formatting, use {@linkcode setFormatting} with the returned range.
2286
+ *
2287
+ * @example
2288
+ * Append text to the end:
2289
+ * ```typescript
2290
+ * const newRange = textView.addInlineText(' (additional text)');
2291
+ * textView.setFormatting({ italic: true }, newRange);
2292
+ * ```
2293
+ *
2294
+ * @example
2295
+ * Insert before specific text:
2296
+ * ```typescript
2297
+ * const result = textView.searchText('important');
2298
+ * if (result) {
2299
+ * const newRange = textView.addInlineText('VERY ', {
2300
+ * placement: 'before',
2301
+ * range: result.range
2302
+ * });
2303
+ * textView.setFormatting({ bold: true }, newRange);
2304
+ * }
2305
+ * // Result: "VERY important"
2306
+ * ```
2307
+ *
2308
+ * @example
2309
+ * Insert after specific text:
2310
+ * ```typescript
2311
+ * const result = textView.searchText(/chapter \d+/i);
2312
+ * if (result) {
2313
+ * const newRange = textView.addInlineText(' (revised)', {
2314
+ * placement: 'after',
2315
+ * range: result.range
2316
+ * });
2317
+ * textView.setFormatting({ fontSize: 10 }, newRange);
2318
+ * }
2319
+ * // Result: "Chapter 5 (revised)"
2320
+ * ```
2321
+ *
2322
+ * @example
2323
+ * Build content with multiple insertions:
2324
+ * ```typescript
2325
+ * const textView = paragraph.asTextView();
2326
+ * textView.setText('');
2327
+ *
2328
+ * let lastRange = textView.addInlineText('First');
2329
+ * textView.setFormatting({ bold: true }, lastRange);
2330
+ *
2331
+ * lastRange = textView.addInlineText(', Second', {
2332
+ * placement: 'after',
2333
+ * range: lastRange
2334
+ * });
2335
+ * textView.setFormatting({ italic: true }, lastRange);
2336
+ *
2337
+ * // Result: "First, Second" (First is bold, Second is italic)
2338
+ * ```
2339
+ */
1460
2340
  addInlineText(text: string, insertionPoint?: {
1461
2341
  placement: 'before' | 'after';
1462
2342
  range: Range;
1463
- }): InlineText;
1464
- removeInline(index?: number): Inline | undefined;
1465
- };
1466
- /**
1467
- * @sidebarGroup programmatic api
1468
- */
1469
- export type Extent = {
1470
- width: number;
1471
- height: number;
1472
- };
1473
- /**
1474
- * @sidebarGroup programmatic api
2343
+ }): Range;
2344
+ /**
2345
+ * Adds a line break (soft return) at a specific position.
2346
+ *
2347
+ * @param insertionPoint - Optional position to insert. If omitted, appends to the end.
2348
+ * @returns A {@linkcode Range} representing the location of the newly inserted line break
2349
+ *
2350
+ * @remarks
2351
+ * Inserts a line break (also called a soft return) at the specified position. Line breaks
2352
+ * create a new line within the same paragraph without starting a new paragraph. This is
2353
+ * equivalent to pressing Shift+Enter in most word processors.
2354
+ *
2355
+ * When no insertion point is provided, the line break is appended to the end of the
2356
+ * text view content.
2357
+ *
2358
+ * The `insertionPoint` parameter specifies both a reference range and a placement
2359
+ * relative to that range:
2360
+ * - `placement: 'before'` - Insert before the reference range
2361
+ * - `placement: 'after'` - Insert after the reference range
2362
+ *
2363
+ * The returned range represents the location of the line break, which can be used
2364
+ * for further operations if needed.
2365
+ *
2366
+ * **Use cases:**
2367
+ * - Multi-line addresses within a single paragraph
2368
+ * - Poetry or verse formatting
2369
+ * - Breaking text within list items or table cells
2370
+ * - Any scenario where visual line separation is needed without semantic paragraph breaks
2371
+ *
2372
+ * @example
2373
+ * Add line break at the end:
2374
+ * ```typescript
2375
+ * const textView = paragraph.asTextView();
2376
+ * textView.setText('First line');
2377
+ * textView.addLineBreak();
2378
+ * textView.addInlineText('Second line');
2379
+ * // Result:
2380
+ * // First line
2381
+ * // Second line
2382
+ * // (in same paragraph)
2383
+ * ```
2384
+ *
2385
+ * @example
2386
+ * Insert line break at specific position:
2387
+ * ```typescript
2388
+ * const result = textView.searchText(/\d{5}/); // Find ZIP code
2389
+ * if (result) {
2390
+ * textView.addLineBreak({
2391
+ * placement: 'before',
2392
+ * range: result.range
2393
+ * });
2394
+ * }
2395
+ * // Result:
2396
+ * // 123 Main St
2397
+ * // 12345
2398
+ * ```
2399
+ *
2400
+ * @example
2401
+ * Format a multi-line address:
2402
+ * ```typescript
2403
+ * const textView = paragraph.asTextView();
2404
+ * textView.setText('John Smith');
2405
+ * textView.addLineBreak();
2406
+ * textView.addInlineText('123 Main Street');
2407
+ * textView.addLineBreak();
2408
+ * textView.addInlineText('Springfield, IL 62701');
2409
+ *
2410
+ * // All in one paragraph:
2411
+ * // John Smith
2412
+ * // 123 Main Street
2413
+ * // Springfield, IL 62701
2414
+ * ```
2415
+ *
2416
+ * @example
2417
+ * Poetry formatting:
2418
+ * ```typescript
2419
+ * const textView = paragraph.asTextView();
2420
+ * textView.setText('Roses are red,');
2421
+ * textView.addLineBreak();
2422
+ * textView.addInlineText('Violets are blue,');
2423
+ * textView.addLineBreak();
2424
+ * textView.addInlineText('Programming is great,');
2425
+ * textView.addLineBreak();
2426
+ * textView.addInlineText('And so are you!');
2427
+ * ```
2428
+ */
2429
+ addLineBreak(insertionPoint?: {
2430
+ placement: 'before' | 'after';
2431
+ range: Range;
2432
+ }): Range;
2433
+ };
2434
+ /**
2435
+ * Represents the dimensions (width and height) of a document element.
2436
+ *
2437
+ * @remarks
2438
+ * `Extent` specifies the size of elements like images in the document. Dimensions are
2439
+ * measured in points (1 point = 1/72 inch).
2440
+ *
2441
+ * @example
2442
+ * Get image dimensions:
2443
+ * ```typescript
2444
+ * const inlines = textView.inlines();
2445
+ * for (const rangeInline of inlines) {
2446
+ * if (rangeInline.inline.type === 'image') {
2447
+ * const extent = rangeInline.inline.extent();
2448
+ * console.log(`Image size: ${extent.width} x ${extent.height}`);
2449
+ * }
2450
+ * }
2451
+ * ```
2452
+ *
2453
+ * @example
2454
+ * Scale image proportionally:
2455
+ * ```typescript
2456
+ * const inlines = textView.inlines();
2457
+ * for (const rangeInline of inlines) {
2458
+ * if (rangeInline.inline.type === 'image') {
2459
+ * const current = rangeInline.inline.extent();
2460
+ * const scale = 0.5; // Scale to 50%
2461
+ *
2462
+ * rangeInline.inline.setExtent({
2463
+ * width: current.width * scale,
2464
+ * height: current.height * scale
2465
+ * });
2466
+ * }
2467
+ * }
2468
+ * ```
2469
+ *
2470
+ * @sidebarGroup programmatic api
2471
+ */
2472
+ export type Extent = {
2473
+ /**
2474
+ * The width of the element.
2475
+ *
2476
+ * @remarks
2477
+ * Width dimension. Measured in points (1 point = 1/72 inch).
2478
+ */
2479
+ width: number;
2480
+ /**
2481
+ * The height of the element.
2482
+ *
2483
+ * @remarks
2484
+ * Height dimension. Measured in points (1 point = 1/72 inch).
2485
+ */
2486
+ height: number;
2487
+ };
2488
+ /**
2489
+ * Represents an image element within a document.
2490
+ *
2491
+ * @remarks
2492
+ * `Image` is one of the inline element types that can appear within text content. Images
2493
+ * are embedded within paragraphs alongside text and other inline elements. You obtain
2494
+ * `Image` objects by iterating through inline elements and checking their type discriminator.
2495
+ *
2496
+ * @sidebarGroup programmatic api
1475
2497
  */
1476
2498
  export type Image = {
2499
+ /**
2500
+ * Type discriminator for inline elements.
2501
+ *
2502
+ * @remarks
2503
+ * Always has the value `'image'`. Use this property to narrow the inline element
2504
+ * type and access image-specific methods.
2505
+ */
1477
2506
  type: 'image';
2507
+ /**
2508
+ * Gets the current display dimensions of the image.
2509
+ *
2510
+ * @returns An {@linkcode Extent} object containing the image's width and height
2511
+ *
2512
+ * @remarks
2513
+ * Returns the current display size of the image in the document. Dimensions are
2514
+ * in points (1 point = 1/72 inch).
2515
+ *
2516
+ * @example
2517
+ * ```typescript
2518
+ * if (inline.type === 'image') {
2519
+ * const extent = inline.extent();
2520
+ * console.log(`Image: ${extent.width} x ${extent.height}`);
2521
+ * }
2522
+ * ```
2523
+ */
1478
2524
  extent(): Extent;
2525
+ /**
2526
+ * Sets the display dimensions of the image. Dimensions are
2527
+ * in points (1 point = 1/72 inch).
2528
+ *
2529
+ * @param extent - Partial extent object with width and/or height to set
2530
+ *
2531
+ * @remarks
2532
+ * Modifies how the image is displayed in the document. You can specify both width
2533
+ * and height, or just one dimension. When specifying only one dimension, the other
2534
+ * remains unchanged (it does NOT maintain aspect ratio automatically).
2535
+ *
2536
+ * This modifies only the display size, not the underlying image data.
2537
+ */
1479
2538
  setExtent(extent: Partial<Extent>): void;
1480
2539
  };
1481
2540
  /**
@@ -1485,39 +2544,236 @@ export declare namespace Programmatic {
1485
2544
  type: 'field';
1486
2545
  };
1487
2546
  /**
2547
+ * Represents a footnote element within document content.
2548
+ *
2549
+ * @remarks
2550
+ * `Footnote` is an inline element that contains a footnote reference mark in the main text
2551
+ * and associated content that appears at the bottom of the page.
2552
+ * The footnote itself contains block-level content (paragraphs, tables) accessed via the
2553
+ * `content()` method.
2554
+ *
2555
+ * Footnotes are discovered by iterating through inline elements and checking their type
2556
+ * discriminator. Once you have a `Footnote` object, you can access and modify its content
2557
+ * using the {@linkcode BlockLevelContainer} interface.
2558
+ *
2559
+ * @example
2560
+ * Find and list all footnotes:
2561
+ * ```typescript
2562
+ * const inlines = textView.inlines();
2563
+ * for (const rangeInline of inlines) {
2564
+ * if (rangeInline.inline.type === 'footnote') {
2565
+ * const footnoteContent = rangeInline.inline.content();
2566
+ * const text = footnoteContent.blocklevels()
2567
+ * .map(bl => bl.type === 'paragraph' ? bl.asTextView().getPlainText() : '')
2568
+ * .join(' ');
2569
+ * console.log('Footnote text:', text);
2570
+ * }
2571
+ * }
2572
+ * ```
2573
+ *
2574
+ * @example
2575
+ * Search and replace within footnote content:
2576
+ * ```typescript
2577
+ * for (const rangeInline of textView.inlines()) {
2578
+ * if (rangeInline.inline.type === 'footnote') {
2579
+ * const footnoteContent = rangeInline.inline.content();
2580
+ * // Replace text in all footnote content
2581
+ * const count = footnoteContent.replaceText(/TODO/g, 'DONE');
2582
+ * console.log(`Replaced ${count} occurrences in footnote`);
2583
+ * }
2584
+ * }
2585
+ * ```
2586
+ *
1488
2587
  * @sidebarGroup programmatic api
1489
2588
  */
1490
2589
  export type Footnote = {
2590
+ /**
2591
+ * Type discriminator for inline elements.
2592
+ *
2593
+ * @remarks
2594
+ * Always has the value `'footnote'`. Use this property to narrow the inline element
2595
+ * type and access footnote-specific methods.
2596
+ */
1491
2597
  type: 'footnote';
2598
+ /**
2599
+ * Gets the block-level content container for this footnote.
2600
+ *
2601
+ * @returns A {@linkcode BlockLevelContainer} containing the footnote's paragraphs and tables
2602
+ *
2603
+ * @remarks
2604
+ * Returns a container that holds the actual content of the footnote (what appears at
2605
+ * the bottom of the page). You can use this to read, modify, add, or remove content
2606
+ * within the footnote using the standard {@linkcode BlockLevelContainer} methods.
2607
+ *
2608
+ * @example
2609
+ * ```typescript
2610
+ * if (inline.type === 'footnote') {
2611
+ * const content = inline.content();
2612
+ * const paragraphs = content.blocklevels();
2613
+ * console.log(`Footnote has ${paragraphs.length} paragraphs`);
2614
+ * }
2615
+ * ```
2616
+ */
2617
+ content(): BlockLevelContainer;
1492
2618
  };
1493
2619
  /**
2620
+ * Represents a reference to a footnote within footnote content.
2621
+ *
2622
+ * @remarks
2623
+ * `FootnoteRef` is an inline element that appears within the content of a footnote itself,
2624
+ * representing a reference back to where the footnote is cited in the main text. This is
2625
+ * typically rendered as a superscript number or symbol at the beginning of the footnote text.
2626
+ *
2627
+ * Unlike {@linkcode Footnote} (which is the footnote marker in the main text with its associated
2628
+ * content), `FootnoteRef` appears inside the footnote content area and links back to the
2629
+ * main text.
2630
+ *
2631
+ * This is a marker element with no additional methods or properties beyond the type discriminator.
2632
+ *
1494
2633
  * @sidebarGroup programmatic api
1495
2634
  */
1496
2635
  export type FootnoteRef = {
2636
+ /**
2637
+ * Type discriminator for inline elements.
2638
+ *
2639
+ * @remarks
2640
+ * Always has the value `'footnote/ref'`. Use this property to identify footnote
2641
+ * reference markers within footnote content.
2642
+ */
1497
2643
  type: 'footnote/ref';
1498
2644
  };
1499
2645
  /**
2646
+ * Represents an endnote element within document content.
2647
+ *
2648
+ * @remarks
2649
+ * `Endnote` is an inline element that contains an endnote reference mark in the main text
2650
+ * and associated content that appears at the end of the document or section. Endnotes are
2651
+ * similar to footnotes but collected at the end rather than at the bottom of each page.
2652
+ *
2653
+ * The endnote contains block-level content (paragraphs, tables) accessed via the `content()`
2654
+ * method. Endnotes are discovered by iterating through inline elements and checking their
2655
+ * type discriminator.
2656
+
2657
+ * @example
2658
+ * Find and list all endnotes:
2659
+ * ```typescript
2660
+ * const inlines = textView.inlines();
2661
+ * for (const rangeInline of inlines) {
2662
+ * if (rangeInline.inline.type === 'endnote') {
2663
+ * const endnoteContent = rangeInline.inline.content();
2664
+ * const text = endnoteContent.blocklevels()
2665
+ * .map(bl => bl.type === 'paragraph' ? bl.asTextView().getPlainText() : '')
2666
+ * .join(' ');
2667
+ * console.log('Endnote text:', text);
2668
+ * }
2669
+ * }
2670
+ * ```
2671
+ *
1500
2672
  * @sidebarGroup programmatic api
1501
2673
  */
1502
2674
  export type Endnote = {
2675
+ /**
2676
+ * Type discriminator for inline elements.
2677
+ *
2678
+ * @remarks
2679
+ * Always has the value `'endnote'`. Use this property to narrow the inline element
2680
+ * type and access endnote-specific methods.
2681
+ */
1503
2682
  type: 'endnote';
2683
+ /**
2684
+ * Gets the block-level content container for this endnote.
2685
+ *
2686
+ * @returns A {@linkcode BlockLevelContainer} containing the endnote's paragraphs and tables
2687
+ *
2688
+ * @remarks
2689
+ * Returns a container that holds the actual content of the endnote (what appears at
2690
+ * the end of the document or section). You can use this to read, modify, add, or remove
2691
+ * content within the endnote using the standard {@linkcode BlockLevelContainer} methods.
2692
+ *
2693
+ * @example
2694
+ * ```typescript
2695
+ * if (inline.type === 'endnote') {
2696
+ * const content = inline.content();
2697
+ * const paragraphs = content.blocklevels();
2698
+ * console.log(`Endnote has ${paragraphs.length} paragraphs`);
2699
+ * }
2700
+ * ```
2701
+ */
2702
+ content(): BlockLevelContainer;
1504
2703
  };
1505
2704
  /**
2705
+ * Represents a reference to an endnote within endnote content.
2706
+ *
2707
+ * @remarks
2708
+ * `EndnoteRef` is an inline element that appears within the content of an endnote itself,
2709
+ * representing a reference back to where the endnote is cited in the main text. This is
2710
+ * typically rendered as a superscript number or symbol at the beginning of the endnote text.
2711
+ *
2712
+ * Unlike {@linkcode Endnote} (which is the endnote marker in the main text with its associated
2713
+ * content), `EndnoteRef` appears inside the endnote content area and links back to the
2714
+ * main text.
2715
+ *
2716
+ * This is a marker element with no additional methods or properties beyond the type discriminator.
2717
+ *
1506
2718
  * @sidebarGroup programmatic api
1507
2719
  */
1508
2720
  export type EndnoteRef = {
2721
+ /**
2722
+ * Type discriminator for inline elements.
2723
+ *
2724
+ * @remarks
2725
+ * Always has the value `'endnote/ref'`. Use this property to identify endnote
2726
+ * reference markers within endnote content.
2727
+ */
1509
2728
  type: 'endnote/ref';
1510
2729
  };
1511
2730
  /**
2731
+ * Represents a line break (soft return) within a paragraph.
2732
+ *
2733
+ * @remarks
2734
+ * `LineBreak` is an inline element that creates a new line within the same paragraph without
2735
+ * starting a new paragraph. This is also known as a "soft return" or "line wrap" and is
2736
+ * typically inserted with Shift+Enter in word processors.
2737
+ *
2738
+ * Unlike starting a new paragraph, a line break:
2739
+ * - Keeps the text in the same paragraph
2740
+ * - Maintains paragraph-level formatting and numbering
2741
+ * - Creates visual line separation without semantic paragraph separation
2742
+ *
2743
+ * Line breaks can be added programmatically using {@linkcode TextView.addLineBreak}.
2744
+ *
2745
+ * @example
2746
+ * Find all line breaks in a paragraph:
2747
+ * ```typescript
2748
+ * const inlines = textView.inlines();
2749
+ * const lineBreaks = inlines.filter(ri => ri.inline.type === 'line-break');
2750
+ * console.log(`Found ${lineBreaks.length} line breaks`);
2751
+ * ```
2752
+ *
1512
2753
  * @sidebarGroup programmatic api
1513
2754
  */
1514
2755
  export type LineBreak = {
2756
+ /**
2757
+ * Type discriminator for inline elements.
2758
+ *
2759
+ * @remarks
2760
+ * Always has the value `'line-break'`. Use this property to identify line break
2761
+ * elements within text content.
2762
+ */
1515
2763
  type: 'line-break';
1516
2764
  };
1517
2765
  /**
2766
+ *
1518
2767
  * @sidebarGroup programmatic api
1519
2768
  */
1520
2769
  export type PageBreak = {
2770
+ /**
2771
+ * Type discriminator for inline elements.
2772
+ *
2773
+ * @remarks
2774
+ * Always has the value `'page-break'`. Use this property to identify page break
2775
+ * elements within text content.
2776
+ */
1521
2777
  type: 'page-break';
1522
2778
  };
1523
2779
  /**
@@ -1533,11 +2789,84 @@ export declare namespace Programmatic {
1533
2789
  type: 'sep';
1534
2790
  };
1535
2791
  /**
2792
+ * Represents a text segment with consistent formatting within a paragraph.
2793
+ *
2794
+ * @remarks
2795
+ * `InlineText` is the most common inline element type, representing actual text content
2796
+ * with uniform formatting properties. A paragraph's text is broken into multiple `InlineText`
2797
+ * elements whenever formatting changes (e.g., switching from regular to bold text creates
2798
+ * two separate `InlineText` elements).
2799
+ *
2800
+ * Each `InlineText` element has:
2801
+ * - The actual text content (via {@linkcode plainText})
2802
+ * - The formatting applied to that text (via {@linkcode formatting})
2803
+ *
2804
+ * `InlineText` elements are discovered by iterating through inline elements using
2805
+ * {@linkcode TextView.inlines}.
2806
+ *
2807
+ * @example
2808
+ * Extract all text content with formatting information:
2809
+ * ```typescript
2810
+ * const inlines = textView.inlines();
2811
+ * for (const rangeInline of inlines) {
2812
+ * if (rangeInline.inline.type === 'text') {
2813
+ * const text = rangeInline.inline.plainText();
2814
+ * const fmt = rangeInline.inline.formatting();
2815
+ * console.log(`Text: "${text}", Bold: ${fmt.bold}, Color: ${fmt.color}`);
2816
+ * }
2817
+ * }
2818
+ * ```
2819
+ *
1536
2820
  * @sidebarGroup programmatic api
1537
2821
  */
1538
2822
  export type InlineText = {
2823
+ /**
2824
+ * Type discriminator for inline elements.
2825
+ *
2826
+ * @remarks
2827
+ * Always has the value `'text'`. Use this property to identify text content
2828
+ * elements and distinguish them from other inline types (images, line breaks, etc.).
2829
+ */
1539
2830
  type: 'text';
2831
+ /**
2832
+ * Gets the plain text content of this inline element.
2833
+ *
2834
+ * @returns The text string contained in this element
2835
+ *
2836
+ * @remarks
2837
+ * Returns the actual text content without any formatting information. Each `InlineText`
2838
+ * element represents a contiguous segment of text with uniform formatting.
2839
+ *
2840
+ * @example
2841
+ * ```typescript
2842
+ * if (inline.type === 'text') {
2843
+ * const text = inline.plainText();
2844
+ * console.log(`Text content: "${text}"`);
2845
+ * }
2846
+ * ```
2847
+ */
1540
2848
  plainText(): string;
2849
+ /**
2850
+ * Gets the formatting properties applied to this text.
2851
+ *
2852
+ * @returns A {@linkcode Formatting} object describing all formatting properties
2853
+ *
2854
+ * @remarks
2855
+ * Returns the complete formatting information for this text segment, including font,
2856
+ * size, color, bold, italic, and other properties. Properties that are not explicitly
2857
+ * set will have `null` values, indicating they inherit from the paragraph or document style.
2858
+ *
2859
+ * @example
2860
+ * ```typescript
2861
+ * if (inline.type === 'text') {
2862
+ * const fmt = inline.formatting();
2863
+ * console.log(`Font: ${fmt.font ?? 'default'}`);
2864
+ * console.log(`Size: ${fmt.fontSize ?? 'default'}`);
2865
+ * console.log(`Bold: ${fmt.bold ?? false}`);
2866
+ * console.log(`Color: ${fmt.color ?? 'default'}`);
2867
+ * }
2868
+ * ```
2869
+ */
1541
2870
  formatting(): Formatting;
1542
2871
  };
1543
2872
  /**
@@ -1545,18 +2874,149 @@ export declare namespace Programmatic {
1545
2874
  */
1546
2875
  export type Inline = InlineText | Tab | Separator | LineBreak | PageBreak | Image | Field | Footnote | FootnoteRef | Endnote | EndnoteRef;
1547
2876
  /**
2877
+ * Pairs an inline element with its location in the text view.
2878
+ *
2879
+ * @remarks
2880
+ * `RangeInline` combines an inline element with the {@linkcode Range} indicating where it appears
2881
+ * in the text view. This type is returned by {@linkcode TextView.inlines}, allowing you to both inspect
2882
+ * inline elements and know their positions for further operations.
2883
+ *
2884
+ * The `range` property identifies the exact location of the inline element, which
2885
+ * you can use with other TextView methods like {@linkcode TextView.setFormatting} or
2886
+ * {@linkcode TextView.setText} to manipulate that specific range.
2887
+ *
2888
+ * This pairing is essential because:
2889
+ * - You need the inline element to inspect its type and properties
2890
+ * - You need the range to perform operations on that specific element
2891
+ *
1548
2892
  * @sidebarGroup programmatic api
1549
2893
  */
1550
2894
  export type RangeInline = {
2895
+ /**
2896
+ * The location of the inline element within the text view.
2897
+ *
2898
+ * @remarks
2899
+ * An opaque {@linkcode Range} object specifying where this inline element appears.
2900
+ * This range can be passed to TextView methods to manipulate the element
2901
+ * (e.g., {@linkcode TextView.setFormatting}).
2902
+ */
1551
2903
  range: Range;
2904
+ /**
2905
+ * The inline element at this location.
2906
+ *
2907
+ * @remarks
2908
+ * The actual inline element, which could be text, an image, a line break, or any
2909
+ * other inline type. Use the `type` property to discriminate and access
2910
+ * type-specific methods.
2911
+ */
1552
2912
  inline: Inline;
1553
2913
  };
1554
2914
  /**
2915
+ * Represents a paragraph block-level element within a document.
2916
+ *
2917
+ * @remarks
2918
+ * `Paragraph` is one of the primary block-level elements in a document (along with {@linkcode Table}).
2919
+ * It contains content like text, images, line breaks, and other elements.
2920
+ *
2921
+ * Paragraphs are obtained from:
2922
+ * - {@linkcode BlockLevelContainer.blocklevels} - Get all block-level elements
2923
+ * - {@linkcode BlockLevelContainer.addParagraph} - Create a new paragraph
2924
+ *
2925
+ * To work with paragraph content, use {@linkcode asTextView} to get a {@linkcode TextView} interface
2926
+ * that provides methods for reading and manipulating the text and inline elements.
2927
+ *
2928
+ * @example
2929
+ * Iterate through all paragraphs in a section:
2930
+ * ```typescript
2931
+ * const blockLevels = section.content().blocklevels();
2932
+ * for (const bl of blockLevels) {
2933
+ * if (bl.type === 'paragraph') {
2934
+ * const textView = bl.asTextView();
2935
+ * const text = textView.getPlainText();
2936
+ * console.log('Paragraph text:', text);
2937
+ * }
2938
+ * }
2939
+ * ```
2940
+ *
2941
+ * @example
2942
+ * Add and populate a new paragraph:
2943
+ * ```typescript
2944
+ * const container = section.content();
2945
+ * const newPara = container.addParagraph();
2946
+ *
2947
+ * // Set text content
2948
+ * const textView = newPara.asTextView();
2949
+ * textView.setText('This is a new paragraph.');
2950
+ *
2951
+ * // Apply formatting
2952
+ * textView.setFormatting({ bold: true, fontSize: 14 });
2953
+ * ```
2954
+ *
1555
2955
  * @sidebarGroup programmatic api
1556
2956
  */
1557
2957
  export type Paragraph = {
2958
+ /**
2959
+ * Type discriminator for block-level elements.
2960
+ *
2961
+ * @remarks
2962
+ * Always has the value `'paragraph'`. Use this property to narrow the block-level
2963
+ * element type and access paragraph-specific methods.
2964
+ */
1558
2965
  type: 'paragraph';
2966
+ /**
2967
+ * Gets a TextView interface for reading and manipulating the paragraph's content.
2968
+ *
2969
+ * @returns A {@linkcode TextView} that provides access to the paragraph's inline elements
2970
+ *
2971
+ * @remarks
2972
+ * Returns a {@linkcode TextView} interface that exposes methods for working with the
2973
+ * paragraph's text and inline elements. Use this to:
2974
+ * - Read text content ({@linkcode TextView.getPlainText})
2975
+ * - Search for text ({@linkcode TextView.searchText})
2976
+ * - Modify text ({@linkcode TextView.setText})
2977
+ * - Apply formatting ({@linkcode TextView.setFormatting})
2978
+ * - Access inline elements ({@linkcode TextView.inlines})
2979
+ *
2980
+ * @example
2981
+ * ```typescript
2982
+ * if (blockLevel.type === 'paragraph') {
2983
+ * const textView = blockLevel.asTextView();
2984
+ * const text = textView.getPlainText();
2985
+ * console.log('Paragraph content:', text);
2986
+ * }
2987
+ * ```
2988
+ */
1559
2989
  asTextView(): TextView;
2990
+ /**
2991
+ * Replaces all occurrences of a pattern with new content.
2992
+ *
2993
+ * @remarks
2994
+ * Convenience method equivalent to calling {@linkcode TextView.replaceText} on the result
2995
+ * of {@linkcode asTextView}. Searches for all matches of the pattern within this paragraph
2996
+ * and replaces them with the specified content.
2997
+ *
2998
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
2999
+ *
3000
+ * @example
3001
+ * ```typescript
3002
+ * if (blockLevel.type === 'paragraph') {
3003
+ * // Replace all "TODO" with "DONE"
3004
+ * const count = blockLevel.replaceText(/TODO/g, 'DONE');
3005
+ * console.log(`Replaced ${count} occurrences`);
3006
+ * }
3007
+ * ```
3008
+ *
3009
+ * @example
3010
+ * ```typescript
3011
+ * if (blockLevel.type === 'paragraph') {
3012
+ * // Replace with formatting
3013
+ * blockLevel.replaceText(/ERROR/gi, {
3014
+ * text: 'ERROR',
3015
+ * formatting: { color: '#ff0000', bold: true }
3016
+ * });
3017
+ * }
3018
+ * ```
3019
+ */
1560
3020
  replaceText: ReplaceTextSignature;
1561
3021
  };
1562
3022
  /**
@@ -1583,17 +3043,180 @@ export declare namespace Programmatic {
1583
3043
  replaceText: ReplaceTextSignature;
1584
3044
  };
1585
3045
  /**
3046
+ * Union type representing the block-level elements that can appear in a document.
3047
+ *
3048
+ * @remarks
3049
+ * `BlockLevel` is a discriminated union of {@linkcode Paragraph} and {@linkcode Table}, the two
3050
+ * types of block-level elements that can exist within a document's content structure. Block-level
3051
+ * elements are the primary building blocks of document content, appearing within:
3052
+ * - Section content ({@linkcode Section.content})
3053
+ * - Table cells ({@linkcode TableCell})
3054
+ * - Footnote content ({@linkcode Footnote.content})
3055
+ * - Endnote content ({@linkcode Endnote.content})
3056
+ * - Headers and footers ({@linkcode HeaderFooter})
3057
+ *
3058
+ * Use the `type` discriminator property to determine which specific block-level element you're
3059
+ * working with:
3060
+ * - `type: 'paragraph'` - A {@linkcode Paragraph} element
3061
+ * - `type: 'table'` - A {@linkcode Table} element
3062
+ *
3063
+ * Block-level elements are obtained from {@linkcode BlockLevelContainer.blocklevels}, which returns
3064
+ * an array of `BlockLevel` elements that you can iterate through and process based on their type.
3065
+ *
3066
+ * @example
3067
+ * Iterate through and process block-level elements:
3068
+ * ```typescript
3069
+ * const content = section.content();
3070
+ * const blockLevels = content.blocklevels();
3071
+ *
3072
+ * for (const blockLevel of blockLevels) {
3073
+ * if (blockLevel.type === 'paragraph') {
3074
+ * // It's a paragraph
3075
+ * const textView = blockLevel.asTextView();
3076
+ * const text = textView.getPlainText();
3077
+ * console.log('Paragraph:', text);
3078
+ * } else if (blockLevel.type === 'table') {
3079
+ * // It's a table
3080
+ * const rows = blockLevel.rows();
3081
+ * console.log(`Table with ${rows.length} rows`);
3082
+ * }
3083
+ * }
3084
+ * ```
3085
+ *
3086
+ * @example
3087
+ * Count paragraphs and tables in a section:
3088
+ * ```typescript
3089
+ * const blockLevels = section.content().blocklevels();
3090
+ *
3091
+ * let paragraphCount = 0;
3092
+ * let tableCount = 0;
3093
+ *
3094
+ * for (const bl of blockLevels) {
3095
+ * if (bl.type === 'paragraph') {
3096
+ * paragraphCount++;
3097
+ * } else if (bl.type === 'table') {
3098
+ * tableCount++;
3099
+ * }
3100
+ * }
3101
+ *
3102
+ * console.log(`Section has ${paragraphCount} paragraphs and ${tableCount} tables`);
3103
+ * ```
3104
+ *
3105
+ * @example
3106
+ * Process only paragraphs with specific text:
3107
+ * ```typescript
3108
+ * const blockLevels = section.content().blocklevels();
3109
+ *
3110
+ * for (const bl of blockLevels) {
3111
+ * if (bl.type === 'paragraph') {
3112
+ * const text = bl.asTextView().getPlainText();
3113
+ * if (text.includes('TODO')) {
3114
+ * // Highlight TODOs in red
3115
+ * bl.replaceText(/TODO/g, {
3116
+ * text: 'TODO',
3117
+ * formatting: { color: '#ff0000', bold: true }
3118
+ * });
3119
+ * }
3120
+ * }
3121
+ * }
3122
+ * ```
3123
+ *
3124
+ * @example
3125
+ * Find the first table in a section:
3126
+ * ```typescript
3127
+ * const blockLevels = section.content().blocklevels();
3128
+ * const firstTable = blockLevels.find(bl => bl.type === 'table');
3129
+ *
3130
+ * if (firstTable && firstTable.type === 'table') {
3131
+ * // TypeScript knows this is a Table due to type narrowing
3132
+ * const rows = firstTable.rows();
3133
+ * console.log(`First table has ${rows.length} rows`);
3134
+ * } else {
3135
+ * console.log('No tables found');
3136
+ * }
3137
+ * ```
3138
+ *
3139
+ * @example
3140
+ * Extract all text from both paragraphs and tables:
3141
+ * ```typescript
3142
+ * const blockLevels = section.content().blocklevels();
3143
+ * const allText: string[] = [];
3144
+ *
3145
+ * for (const bl of blockLevels) {
3146
+ * if (bl.type === 'paragraph') {
3147
+ * const text = bl.asTextView().getPlainText();
3148
+ * allText.push(text);
3149
+ * } else if (bl.type === 'table') {
3150
+ * // Extract text from all cells in the table
3151
+ * for (const row of bl.rows()) {
3152
+ * for (const cell of row.cells()) {
3153
+ * const cellBlocks = cell.blocklevels();
3154
+ * for (const cellBl of cellBlocks) {
3155
+ * if (cellBl.type === 'paragraph') {
3156
+ * const text = cellBl.asTextView().getPlainText();
3157
+ * allText.push(text);
3158
+ * }
3159
+ * }
3160
+ * }
3161
+ * }
3162
+ * }
3163
+ * }
3164
+ *
3165
+ * console.log('All text:', allText.join('\n'));
3166
+ * ```
3167
+ *
3168
+ * @example
3169
+ * Replace text across all block-level elements:
3170
+ * ```typescript
3171
+ * const blockLevels = section.content().blocklevels();
3172
+ * let totalReplacements = 0;
3173
+ *
3174
+ * for (const bl of blockLevels) {
3175
+ * // Both Paragraph and Table have replaceText method
3176
+ * const count = bl.replaceText(/old/g, 'new');
3177
+ * totalReplacements += count;
3178
+ * }
3179
+ *
3180
+ * console.log(`Replaced ${totalReplacements} occurrences`);
3181
+ * ```
3182
+ *
1586
3183
  * @sidebarGroup programmatic api
1587
3184
  */
1588
3185
  export type BlockLevel = Paragraph | Table;
1589
3186
  /**
3187
+ * Container for block-level elements (paragraphs and tables).
3188
+ *
3189
+ * @remarks
3190
+ * `BlockLevelContainer` is implemented by {@linkcode Body} and {@linkcode TableCell}, providing
3191
+ * methods to manage block-level content within these containers.
3192
+ *
3193
+ * @example
3194
+ * Adding paragraphs and tables:
3195
+ * ```typescript
3196
+ * const body = draft.body();
3197
+ * const paragraph = body.addParagraph(); // Append paragraph at end
3198
+ * const table = body.addTable(0); // Insert table at start
3199
+ * ```
3200
+ *
3201
+ * @example
3202
+ * Accessing and removing elements:
3203
+ * ```typescript
3204
+ * const elements = body.blocklevels();
3205
+ * const removed = body.removeElement(0);
3206
+ * ```
3207
+ *
1590
3208
  * @sidebarGroup programmatic api
1591
3209
  */
1592
3210
  export type BlockLevelContainer = {
3211
+ /** Returns all block-level elements in this container. */
1593
3212
  blocklevels(): BlockLevel[];
3213
+ /** Adds a new paragraph. If `index` is provided, inserts at that position; otherwise appends to the end. */
1594
3214
  addParagraph(index?: number): Paragraph;
3215
+ /** Adds a new table. If `index` is provided, inserts at that position; otherwise appends to the end. */
1595
3216
  addTable(index?: number): Table;
3217
+ /** Removes the element at the specified index. Returns the removed element, or `undefined` if index is out of bounds. */
1596
3218
  removeElement(index: number): BlockLevel | undefined;
3219
+ /** Searches and replaces text within this container. See {@linkcode ReplaceTextSignature}. */
1597
3220
  replaceText: ReplaceTextSignature;
1598
3221
  };
1599
3222
  /**
@@ -1604,21 +3227,158 @@ export declare namespace Programmatic {
1604
3227
  height: number;
1605
3228
  };
1606
3229
  /**
3230
+ * Defines the margin dimensions for all four edges of a page.
3231
+ *
3232
+ * @remarks
3233
+ * `PageMargins` specifies the whitespace between the page edges and the content area for
3234
+ * a section. All margin values are measured in points (1 point = 1/72 inch).
3235
+ *
3236
+ * Page margins are configured through {@linkcode PageSetup.setPageMargins} and retrieved
3237
+ * via {@linkcode PageSetup.pageMargins}. Each section can have its own margin settings,
3238
+ * allowing different parts of a document to have different layouts.
3239
+ *
3240
+ * **Common margin values:**
3241
+ * - **Normal margins** (US Letter): 72 points (1 inch) on all sides
3242
+ * - **Narrow margins**: 36 points (0.5 inch) on all sides
3243
+ * - **Wide margins**: 144 points (2 inches) on all sides
3244
+ *
3245
+ * @example
3246
+ * Get current margins:
3247
+ * ```typescript
3248
+ * const pageSetup = section.pageSetup();
3249
+ * const margins = pageSetup.pageMargins();
3250
+ *
3251
+ * console.log(`Top: ${margins.top}pt`);
3252
+ * console.log(`Bottom: ${margins.bottom}pt`);
3253
+ * console.log(`Left: ${margins.left}pt`);
3254
+ * console.log(`Right: ${margins.right}pt`);
3255
+ * ```
3256
+ *
3257
+ * @example
3258
+ * Set standard 1-inch margins:
3259
+ * ```typescript
3260
+ * const pageSetup = section.pageSetup();
3261
+ * pageSetup.setPageMargins({
3262
+ * top: 72,
3263
+ * bottom: 72,
3264
+ * left: 72,
3265
+ * right: 72
3266
+ * });
3267
+ * ```
3268
+ *
3269
+ * @example
3270
+ * Set narrow margins (0.5 inch):
3271
+ * ```typescript
3272
+ * pageSetup.setPageMargins({
3273
+ * top: 36,
3274
+ * bottom: 36,
3275
+ * left: 36,
3276
+ * right: 36
3277
+ * });
3278
+ * ```
3279
+ *
1607
3280
  * @sidebarGroup programmatic api
1608
3281
  */
1609
3282
  export type PageMargins = {
3283
+ /**
3284
+ * The left margin width in points.
3285
+ *
3286
+ * @remarks
3287
+ * Distance from the left edge of the page to the start of the content area.
3288
+ * Measured in points (1 point = 1/72 inch).
3289
+ */
1610
3290
  left: number;
3291
+ /**
3292
+ * The right margin width in points.
3293
+ *
3294
+ * @remarks
3295
+ * Distance from the right edge of the page to the end of the content area.
3296
+ * Measured in points (1 point = 1/72 inch).
3297
+ */
1611
3298
  right: number;
3299
+ /**
3300
+ * The top margin height in points.
3301
+ *
3302
+ * @remarks
3303
+ * Distance from the top edge of the page to the start of the content area.
3304
+ * Measured in points (1 point = 1/72 inch).
3305
+ */
1612
3306
  top: number;
3307
+ /**
3308
+ * The bottom margin height in points.
3309
+ *
3310
+ * @remarks
3311
+ * Distance from the bottom edge of the page to the end of the content area.
3312
+ * Measured in points (1 point = 1/72 inch).
3313
+ */
1613
3314
  bottom: number;
1614
3315
  };
1615
3316
  /**
3317
+ * Controls physical page properties for a section.
3318
+ *
3319
+ * @remarks
3320
+ * `PageSetup` provides methods to configure and query the physical page dimensions and
3321
+ * margins for a section. Each section can have its own page setup, allowing different
3322
+ * parts of a document to use different page sizes or orientations.
3323
+ *
3324
+ * Page setup is accessed via {@linkcode Section.pageSetup} and includes:
3325
+ * - Page size (width and height)
3326
+ * - Page margins (top, bottom, left, right)
3327
+ *
3328
+ * @example
3329
+ * Change to landscape orientation:
3330
+ * ```typescript
3331
+ * const pageSetup = section.pageSetup();
3332
+ * const currentSize = pageSetup.pageSize();
3333
+ *
3334
+ * // Swap width and height for landscape
3335
+ * pageSetup.setPageSize({
3336
+ * width: currentSize.height,
3337
+ * height: currentSize.width
3338
+ * });
3339
+ * ```
3340
+ *
1616
3341
  * @sidebarGroup programmatic api
1617
3342
  */
1618
3343
  export type PageSetup = {
3344
+ /**
3345
+ * Sets the page size for this section.
3346
+ *
3347
+ * @param size - Partial page size with width and/or height to set
3348
+ *
3349
+ * @remarks
3350
+ * All dimensions are in points (1 point = 1/72 inch).
3351
+ *
3352
+ * To change orientation, swap the width and height values.
3353
+ */
1619
3354
  setPageSize(size: Partial<PageSize>): void;
3355
+ /**
3356
+ * Sets the page margins for this section.
3357
+ *
3358
+ * @param margins - Partial page margins with top, bottom, left, and/or right to set
3359
+ *
3360
+ * @remarks
3361
+ * All dimensions are in points (1 point = 1/72 inch).
3362
+ */
1620
3363
  setPageMargins(margins: Partial<PageMargins>): void;
3364
+ /**
3365
+ * Gets the current page size for this section.
3366
+ *
3367
+ * @returns The current {@linkcode PageSize} with width and height
3368
+ *
3369
+ * @remarks
3370
+ * All dimensions are in points (1 point = 1/72 inch).
3371
+ *
3372
+ */
1621
3373
  pageSize(): PageSize;
3374
+ /**
3375
+ * Gets the current page margins for this section.
3376
+ *
3377
+ * @returns The current {@linkcode PageMargins} with top, bottom, left, and right
3378
+ *
3379
+ * @remarks
3380
+ * All dimensions are in points (1 point = 1/72 inch).
3381
+ */
1622
3382
  pageMargins(): PageMargins;
1623
3383
  };
1624
3384
  /**
@@ -1626,44 +3386,837 @@ export declare namespace Programmatic {
1626
3386
  */
1627
3387
  export type HeaderFooter = BlockLevelContainer;
1628
3388
  /**
3389
+ * Collection providing access to different header or footer variants.
3390
+ *
3391
+ * @remarks
3392
+ * `HeadersFooters` represents a collection of header or footer variants for a section.
3393
+ * The same type is used for both headers (via {@linkcode HeadersAndFooters.headers}) and
3394
+ * footers (via {@linkcode HeadersAndFooters.footers}).
3395
+ *
3396
+ * Documents can have up to three variants for headers/footers:
3397
+ * - **Default**: Used for most pages (typically odd pages in two-sided printing)
3398
+ * - **First**: Used for the first page only (often different for title pages)
3399
+ * - **Even**: Used for even pages in two-sided printing
3400
+ *
3401
+ * Each variant can be `null` if not configured in the document. Check for `null` before
3402
+ * attempting to access or modify content.
3403
+ *
3404
+ * @example
3405
+ * Access different header variants:
3406
+ * ```typescript
3407
+ * const headers = section.headersAndFooters().headers();
3408
+ *
3409
+ * // Default header (most pages)
3410
+ * const defaultHeader = headers.default();
3411
+ * if (defaultHeader) {
3412
+ * const para = defaultHeader.addParagraph();
3413
+ * para.asTextView().setText('Chapter Title');
3414
+ * }
3415
+ *
3416
+ * // First page header (title page)
3417
+ * const firstHeader = headers.first();
3418
+ * if (firstHeader) {
3419
+ * const para = firstHeader.addParagraph();
3420
+ * para.asTextView().setText('Document Title');
3421
+ * }
3422
+ *
3423
+ * // Even page header (for two-sided printing)
3424
+ * const evenHeader = headers.even();
3425
+ * if (evenHeader) {
3426
+ * const para = evenHeader.addParagraph();
3427
+ * para.asTextView().setText('Chapter Title - Even Page');
3428
+ * }
3429
+ * ```
3430
+ *
3431
+ * @example
3432
+ * Set up page numbers in footer variants:
3433
+ * ```typescript
3434
+ * const footers = section.headersAndFooters().footers();
3435
+ *
3436
+ * // Default footer with page number
3437
+ * const defaultFooter = footers.default();
3438
+ * if (defaultFooter) {
3439
+ * const para = defaultFooter.addParagraph();
3440
+ * para.asTextView().setText('Page ');
3441
+ * // Note: Page number fields would be added separately
3442
+ * }
3443
+ *
3444
+ * // First page footer (often empty or different)
3445
+ * const firstFooter = footers.first();
3446
+ * if (firstFooter) {
3447
+ * // Leave empty or add copyright notice
3448
+ * const para = firstFooter.addParagraph();
3449
+ * para.asTextView().setText('© 2024 Company Name');
3450
+ * }
3451
+ * ```
3452
+ *
3453
+ * @example
3454
+ * Replace text across all variants:
3455
+ * ```typescript
3456
+ * const headers = section.headersAndFooters().headers();
3457
+ *
3458
+ * // Replace across all header variants that exist
3459
+ * const count = headers.replaceText(/Draft/g, 'Final');
3460
+ * console.log(`Updated ${count} occurrences across all header variants`);
3461
+ * ```
3462
+ *
3463
+ * @example
3464
+ * Check which variants exist:
3465
+ * ```typescript
3466
+ * const headers = section.headersAndFooters().headers();
3467
+ *
3468
+ * const hasDefault = headers.default() !== null;
3469
+ * const hasFirst = headers.first() !== null;
3470
+ * const hasEven = headers.even() !== null;
3471
+ *
3472
+ * console.log(`Header variants: default=${hasDefault}, first=${hasFirst}, even=${hasEven}`);
3473
+ * ```
3474
+ *
1629
3475
  * @sidebarGroup programmatic api
1630
3476
  */
1631
3477
  export type HeadersFooters = {
3478
+ /**
3479
+ * Gets the default header or footer.
3480
+ *
3481
+ * @returns The default {@linkcode HeaderFooter}, or `null` if not configured
3482
+ *
3483
+ * @remarks
3484
+ * Returns the default (primary) header or footer used for most pages. In two-sided
3485
+ * printing, this is typically used for odd pages when an even page variant is also
3486
+ * configured. Returns `null` if the default variant is not configured in the document.
3487
+ *
3488
+ * @example
3489
+ * ```typescript
3490
+ * const headers = section.headersAndFooters().headers();
3491
+ * const defaultHeader = headers.default();
3492
+ *
3493
+ * if (defaultHeader) {
3494
+ * const para = defaultHeader.addParagraph();
3495
+ * para.asTextView().setText('Document Header');
3496
+ * } else {
3497
+ * console.log('No default header configured');
3498
+ * }
3499
+ * ```
3500
+ */
1632
3501
  default(): HeaderFooter | null;
3502
+ /**
3503
+ * Gets the first page header or footer.
3504
+ *
3505
+ * @returns The first page {@linkcode HeaderFooter}, or `null` if not configured
3506
+ *
3507
+ * @remarks
3508
+ * Returns the header or footer specifically for the first page of the section.
3509
+ * This is commonly used for title pages that need different headers/footers from
3510
+ * the rest of the document. Returns `null` if the first page variant is not
3511
+ * configured in the document.
3512
+ *
3513
+ * @example
3514
+ * ```typescript
3515
+ * const headers = section.headersAndFooters().headers();
3516
+ * const firstHeader = headers.first();
3517
+ *
3518
+ * if (firstHeader) {
3519
+ * const para = firstHeader.addParagraph();
3520
+ * para.asTextView().setText('Title Page Header');
3521
+ * } else {
3522
+ * console.log('No first page header configured');
3523
+ * }
3524
+ * ```
3525
+ */
1633
3526
  first(): HeaderFooter | null;
3527
+ /**
3528
+ * Gets the even page header or footer.
3529
+ *
3530
+ * @returns The even page {@linkcode HeaderFooter}, or `null` if not configured
3531
+ *
3532
+ * @remarks
3533
+ * Returns the header or footer specifically for even-numbered pages, typically
3534
+ * used in two-sided (duplex) printing where odd and even pages have different
3535
+ * headers/footers (e.g., page numbers on different sides). Returns `null` if the
3536
+ * even page variant is not configured in the document.
3537
+ *
3538
+ * @example
3539
+ * ```typescript
3540
+ * const headers = section.headersAndFooters().headers();
3541
+ * const evenHeader = headers.even();
3542
+ *
3543
+ * if (evenHeader) {
3544
+ * const para = evenHeader.addParagraph();
3545
+ * para.asTextView().setText('Even Page Header');
3546
+ * } else {
3547
+ * console.log('No even page header configured');
3548
+ * }
3549
+ * ```
3550
+ */
1634
3551
  even(): HeaderFooter | null;
3552
+ /**
3553
+ * Replaces all occurrences of a pattern across all configured variants.
3554
+ *
3555
+ * @remarks
3556
+ * Convenience method that searches and replaces text across all variants (default,
3557
+ * first, and even) that are configured. Only operates on non-null variants.
3558
+ *
3559
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
3560
+ *
3561
+ * @example
3562
+ * ```typescript
3563
+ * const headers = section.headersAndFooters().headers();
3564
+ * const count = headers.replaceText('Company', 'Corporation');
3565
+ * console.log(`Updated ${count} occurrences in headers`);
3566
+ * ```
3567
+ *
3568
+ * @example
3569
+ * ```typescript
3570
+ * const footers = section.headersAndFooters().footers();
3571
+ * footers.replaceText(/v\d+\.\d+/g, {
3572
+ * text: 'v2.0',
3573
+ * formatting: { fontSize: 9 }
3574
+ * });
3575
+ * ```
3576
+ */
1635
3577
  replaceText: ReplaceTextSignature;
1636
3578
  };
1637
3579
  /**
3580
+ * Provides access to both headers and footers for a section.
3581
+ *
3582
+ * @remarks
3583
+ * `HeadersAndFooters` is a container that provides access to both the headers and footers
3584
+ * for a section. It's obtained via {@linkcode Section.headersAndFooters} and acts as a gateway
3585
+ * to the {@linkcode HeadersFooters} collections for headers and footers separately.
3586
+ *
3587
+ * Headers appear at the top of pages, footers at the bottom. Both can have different
3588
+ * content for:
3589
+ * - Default pages (typically odd pages)
3590
+ * - First page (often different for title pages)
3591
+ * - Even pages (for two-sided printing)
3592
+ *
3593
+ * @example
3594
+ * Access headers and footers:
3595
+ * ```typescript
3596
+ * const hf = section.headersAndFooters();
3597
+ * const headers = hf.headers();
3598
+ * const footers = hf.footers();
3599
+ *
3600
+ * // Work with default header
3601
+ * const defaultHeader = headers.default();
3602
+ * if (defaultHeader) {
3603
+ * const para = defaultHeader.addParagraph();
3604
+ * para.asTextView().setText('Document Title');
3605
+ * }
3606
+ *
3607
+ * // Work with default footer
3608
+ * const defaultFooter = footers.default();
3609
+ * if (defaultFooter) {
3610
+ * const para = defaultFooter.addParagraph();
3611
+ * para.asTextView().setText('Page ');
3612
+ * }
3613
+ * ```
3614
+ *
3615
+ * @example
3616
+ * Replace text in all headers and footers:
3617
+ * ```typescript
3618
+ * const hf = section.headersAndFooters();
3619
+ *
3620
+ * // Replace across all headers and footers (default, first, even)
3621
+ * const count = hf.replaceText(/Company Name/g, 'Acme Corporation');
3622
+ * console.log(`Updated ${count} occurrences in headers/footers`);
3623
+ * ```
3624
+ *
3625
+ * @example
3626
+ * Add content to different header/footer types:
3627
+ * ```typescript
3628
+ * const hf = section.headersAndFooters();
3629
+ *
3630
+ * // Set up first page header (title page)
3631
+ * const firstHeader = hf.headers().first();
3632
+ * if (firstHeader) {
3633
+ * const para = firstHeader.addParagraph();
3634
+ * para.asTextView().setText('Title Page Header');
3635
+ * }
3636
+ *
3637
+ * // Set up default header (for subsequent pages)
3638
+ * const defaultHeader = hf.headers().default();
3639
+ * if (defaultHeader) {
3640
+ * const para = defaultHeader.addParagraph();
3641
+ * para.asTextView().setText('Chapter 1');
3642
+ * }
3643
+ * ```
3644
+ *
1638
3645
  * @sidebarGroup programmatic api
1639
3646
  */
1640
3647
  export type HeadersAndFooters = {
3648
+ /**
3649
+ * Gets the headers collection for this section.
3650
+ *
3651
+ * @returns A {@linkcode HeadersFooters} object providing access to header variants
3652
+ *
3653
+ * @remarks
3654
+ * Returns the headers collection, which provides access to default, first page,
3655
+ * and even page headers. Headers appear at the top of pages.
3656
+ *
3657
+ * @example
3658
+ * ```typescript
3659
+ * const headers = headersAndFooters.headers();
3660
+ * const defaultHeader = headers.default();
3661
+ * const firstPageHeader = headers.first();
3662
+ * const evenPageHeader = headers.even();
3663
+ * ```
3664
+ */
1641
3665
  headers(): HeadersFooters;
3666
+ /**
3667
+ * Gets the footers collection for this section.
3668
+ *
3669
+ * @returns A {@linkcode HeadersFooters} object providing access to footer variants
3670
+ *
3671
+ * @remarks
3672
+ * Returns the footers collection, which provides access to default, first page,
3673
+ * and even page footers. Footers appear at the bottom of pages.
3674
+ *
3675
+ * @example
3676
+ * ```typescript
3677
+ * const footers = headersAndFooters.footers();
3678
+ * const defaultFooter = footers.default();
3679
+ * const firstPageFooter = footers.first();
3680
+ * const evenPageFooter = footers.even();
3681
+ * ```
3682
+ */
1642
3683
  footers(): HeadersFooters;
3684
+ /**
3685
+ * Replaces all occurrences of a pattern in all headers and footers.
3686
+ *
3687
+ * @remarks
3688
+ * Convenience method that searches and replaces text across all headers and footers
3689
+ * for this section, including default, first page, and even page variants.
3690
+ *
3691
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
3692
+ *
3693
+ * @example
3694
+ * ```typescript
3695
+ * const count = headersAndFooters.replaceText('Draft', 'Final');
3696
+ * console.log(`Updated ${count} occurrences`);
3697
+ * ```
3698
+ *
3699
+ * @example
3700
+ * ```typescript
3701
+ * headersAndFooters.replaceText(/\(c\)/gi, {
3702
+ * text: '©',
3703
+ * formatting: { fontSize: 10 }
3704
+ * });
3705
+ * ```
3706
+ */
1643
3707
  replaceText: ReplaceTextSignature;
1644
3708
  };
1645
3709
  /**
3710
+ * Represents a section within a document body.
3711
+ *
3712
+ * @remarks
3713
+ * `Section` is a major organizational unit within a document. Each section can have its own:
3714
+ * - Page setup (size, margins, orientation) via {@linkcode pageSetup}
3715
+ * - Headers and footers via {@linkcode headersAndFooters}
3716
+ * - Content (paragraphs and tables) via {@linkcode content}
3717
+ *
3718
+ * Most documents have a single section with consistent page layout and headers/footers
3719
+ * throughout. Multi-section documents are used when you need different page layouts
3720
+ * (e.g., landscape vs portrait) or different headers/footers (e.g., different headers
3721
+ * per chapter) in different parts of the document.
3722
+ *
3723
+ * Sections are obtained from {@linkcode Body.sections} and can be added with {@linkcode Body.addSection}.
3724
+ *
3725
+ * @example
3726
+ * Access and work with section components:
3727
+ * ```typescript
3728
+ * const sections = document.body().sections();
3729
+ * const section = sections[0];
3730
+ *
3731
+ * // Access page setup
3732
+ * const pageSetup = section.pageSetup();
3733
+ * const size = pageSetup.pageSize();
3734
+ * console.log(`Page size: ${size.width} x ${size.height}`);
3735
+ *
3736
+ * // Access content
3737
+ * const content = section.content();
3738
+ * const blockLevels = content.blocklevels();
3739
+ * console.log(`Section has ${blockLevels.length} elements`);
3740
+ *
3741
+ * // Access headers/footers
3742
+ * const hf = section.headersAndFooters();
3743
+ * const headers = hf.headers();
3744
+ * ```
3745
+ *
3746
+ * @example
3747
+ * Add content to a section:
3748
+ * ```typescript
3749
+ * const section = document.body().sections()[0];
3750
+ * const content = section.content();
3751
+ *
3752
+ * // Add a paragraph
3753
+ * const paragraph = content.addParagraph();
3754
+ * paragraph.asTextView().setText('This is a new paragraph.');
3755
+ *
3756
+ * // Add a table
3757
+ * const table = content.addTable();
3758
+ * const row = table.addRow();
3759
+ * const cell = row.addCell();
3760
+ * ```
3761
+ *
3762
+ * @example
3763
+ * Replace text within a section:
3764
+ * ```typescript
3765
+ * const section = document.body().sections()[0];
3766
+ *
3767
+ * // Replace text in this section only (content + headers/footers)
3768
+ * const count = section.replaceText(/TODO/g, {
3769
+ * text: 'DONE',
3770
+ * formatting: { highlight: '#ffff00' }
3771
+ * });
3772
+ *
3773
+ * console.log(`Replaced ${count} occurrences in this section`);
3774
+ * ```
3775
+ *
1646
3776
  * @sidebarGroup programmatic api
1647
3777
  */
1648
3778
  export type Section = {
3779
+ /**
3780
+ * Gets the page setup configuration for this section.
3781
+ *
3782
+ * @returns The {@linkcode PageSetup} for this section
3783
+ *
3784
+ * @remarks
3785
+ * Returns the page setup object that controls the physical page properties for this
3786
+ * section, including page size (width/height) and margins. Each section can have
3787
+ * different page setup settings.
3788
+ *
3789
+ * @example
3790
+ * ```typescript
3791
+ * const pageSetup = section.pageSetup();
3792
+ * const size = pageSetup.pageSize();
3793
+ * const margins = pageSetup.pageMargins();
3794
+ *
3795
+ * console.log(`Page: ${size.width}x${size.height}`);
3796
+ * console.log(`Margins: T:${margins.top} B:${margins.bottom}`);
3797
+ * ```
3798
+ */
1649
3799
  pageSetup(): PageSetup;
3800
+ /**
3801
+ * Gets the headers and footers configuration for this section.
3802
+ *
3803
+ * @returns The {@linkcode HeadersAndFooters} container for this section
3804
+ *
3805
+ * @remarks
3806
+ * Returns an object that provides access to headers and footers for this section.
3807
+ * Headers and footers can have different content for the first page, even pages,
3808
+ * and default (odd) pages.
3809
+ *
3810
+ * @example
3811
+ * ```typescript
3812
+ * const hf = section.headersAndFooters();
3813
+ * const headers = hf.headers();
3814
+ * const footers = hf.footers();
3815
+ *
3816
+ * // Access default header
3817
+ * const defaultHeader = headers.default();
3818
+ * if (defaultHeader) {
3819
+ * const para = defaultHeader.addParagraph();
3820
+ * para.asTextView().setText('Document Title');
3821
+ * }
3822
+ * ```
3823
+ */
1650
3824
  headersAndFooters(): HeadersAndFooters;
3825
+ /**
3826
+ * Gets the main content container for this section.
3827
+ *
3828
+ * @returns The {@linkcode BlockLevelContainer} containing the section's content
3829
+ *
3830
+ * @remarks
3831
+ * Returns a container that holds all block-level elements (paragraphs and tables)
3832
+ * for this section. This is where the main document content resides, separate from
3833
+ * headers and footers.
3834
+ *
3835
+ * @example
3836
+ * ```typescript
3837
+ * const content = section.content();
3838
+ * const blockLevels = content.blocklevels();
3839
+ *
3840
+ * // Iterate through paragraphs and tables
3841
+ * for (const bl of blockLevels) {
3842
+ * if (bl.type === 'paragraph') {
3843
+ * const text = bl.asTextView().getPlainText();
3844
+ * console.log('Paragraph:', text);
3845
+ * } else if (bl.type === 'table') {
3846
+ * console.log('Table with', bl.rows().length, 'rows');
3847
+ * }
3848
+ * }
3849
+ * ```
3850
+ */
1651
3851
  content(): BlockLevelContainer;
3852
+ /**
3853
+ * Replaces all occurrences of a pattern within this section.
3854
+ *
3855
+ * @remarks
3856
+ * Convenience method that searches and replaces text across all content in this
3857
+ * section, including the main content, headers, and footers. This is scoped to
3858
+ * just this section, unlike {@linkcode Body.replaceText} or {@linkcode Document.replaceText}
3859
+ * which operate across all sections.
3860
+ *
3861
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
3862
+ *
3863
+ * @example
3864
+ * ```typescript
3865
+ * // Replace only in this section
3866
+ * const count = section.replaceText(/old/g, 'new');
3867
+ * console.log(`Replaced ${count} occurrences in section`);
3868
+ * ```
3869
+ *
3870
+ * @example
3871
+ * ```typescript
3872
+ * section.replaceText(/DRAFT/gi, {
3873
+ * text: 'FINAL',
3874
+ * formatting: { color: '#00aa00', bold: true }
3875
+ * });
3876
+ * ```
3877
+ */
3878
+ replaceText: ReplaceTextSignature;
1652
3879
  };
1653
3880
  /**
3881
+ * Represents the document body containing all sections.
3882
+ *
3883
+ * @remarks
3884
+ * `Body` is the container for all {@linkcode Section} elements in a document. Each section can
3885
+ * have its own page setup (size, margins, orientation) and headers/footers. Most documents
3886
+ * have a single section, but documents can be divided into multiple sections for different
3887
+ * page layouts or header/footer configurations.
3888
+ *
3889
+ * The body is accessed via {@linkcode Document.body} and provides methods to:
3890
+ * - Get all sections ({@linkcode sections})
3891
+ * - Add new sections ({@linkcode addSection})
3892
+ * - Remove sections ({@linkcode removeSection})
3893
+ * - Replace text across all sections ({@linkcode replaceText})
3894
+ *
3895
+ * @example
3896
+ * Access and iterate through sections:
3897
+ * ```typescript
3898
+ * const body = document.body();
3899
+ * const sections = body.sections();
3900
+ *
3901
+ * console.log(`Document has ${sections.length} sections`);
3902
+ *
3903
+ * for (const section of sections) {
3904
+ * const content = section.content();
3905
+ * const paragraphs = content.blocklevels()
3906
+ * .filter(bl => bl.type === 'paragraph');
3907
+ * console.log(`Section has ${paragraphs.length} paragraphs`);
3908
+ * }
3909
+ * ```
3910
+ *
3911
+ * @example
3912
+ * Add a new section to the document:
3913
+ * ```typescript
3914
+ * const body = document.body();
3915
+ *
3916
+ * // Add section at the end
3917
+ * const newSection = body.addSection();
3918
+ *
3919
+ * // Configure page setup
3920
+ * const pageSetup = newSection.pageSetup();
3921
+ * pageSetup.setPageSize({ width: 12240000, height: 15840000 }); // Letter size
3922
+ *
3923
+ * // Add content
3924
+ * const para = newSection.content().addParagraph();
3925
+ * para.asTextView().setText('This is a new section');
3926
+ * ```
3927
+ *
3928
+ * @example
3929
+ * Replace text across all sections:
3930
+ * ```typescript
3931
+ * const body = document.body();
3932
+ *
3933
+ * // Replace across entire document body
3934
+ * const count = body.replaceText(/TODO/g, {
3935
+ * text: 'DONE',
3936
+ * formatting: { highlight: '#00ff00' }
3937
+ * });
3938
+ *
3939
+ * console.log(`Replaced ${count} occurrences across all sections`);
3940
+ * ```
3941
+ *
3942
+ * @example
3943
+ * Remove a section:
3944
+ * ```typescript
3945
+ * const body = document.body();
3946
+ * const sections = body.sections();
3947
+ *
3948
+ * if (sections.length > 1) {
3949
+ * // Remove the last section
3950
+ * const removed = body.removeSection(sections.length - 1);
3951
+ * if (removed) {
3952
+ * console.log('Removed last section');
3953
+ * }
3954
+ * }
3955
+ * ```
3956
+ *
1654
3957
  * @sidebarGroup programmatic api
1655
3958
  */
1656
3959
  export type Body = {
3960
+ /**
3961
+ * Gets all sections in the document body.
3962
+ *
3963
+ * @returns An array of {@linkcode Section} objects
3964
+ *
3965
+ * @remarks
3966
+ * Returns all sections in the document in order. Most documents have a single section,
3967
+ * but documents can contain multiple sections with different page setups or
3968
+ * headers/footers.
3969
+ *
3970
+ * @example
3971
+ * ```typescript
3972
+ * const sections = body.sections();
3973
+ * console.log(`Document has ${sections.length} sections`);
3974
+ *
3975
+ * sections.forEach((section, index) => {
3976
+ * console.log(`Section ${index + 1}`);
3977
+ * });
3978
+ * ```
3979
+ */
1657
3980
  sections(): Section[];
3981
+ /**
3982
+ * Adds a new section to the document body.
3983
+ *
3984
+ * @param index - Optional zero-based position to insert the section. If omitted, adds at the end.
3985
+ * @returns The newly created {@linkcode Section}
3986
+ *
3987
+ * @remarks
3988
+ * Creates and inserts a new section at the specified position. If no index is provided,
3989
+ * the section is added at the end. The new section is initialized with default page
3990
+ * setup and empty content.
3991
+ *
3992
+ * Use this when you need different page layouts, orientations, or headers/footers
3993
+ * for different parts of your document.
3994
+ *
3995
+ * @example
3996
+ * Add section at the end:
3997
+ * ```typescript
3998
+ * const newSection = body.addSection();
3999
+ * const para = newSection.content().addParagraph();
4000
+ * para.asTextView().setText('New section content');
4001
+ * ```
4002
+ *
4003
+ * @example
4004
+ * Insert section at specific position:
4005
+ * ```typescript
4006
+ * // Insert as the second section (index 1)
4007
+ * const section = body.addSection(1);
4008
+ * ```
4009
+ */
1658
4010
  addSection(index?: number): Section;
4011
+ /**
4012
+ * Removes a section from the document body.
4013
+ *
4014
+ * @param index - Zero-based index of the section to remove
4015
+ * @returns The removed {@linkcode Section}, or `undefined` if the index is invalid
4016
+ *
4017
+ * @remarks
4018
+ * Removes the section at the specified index. If the index is out of bounds,
4019
+ * returns `undefined`. Be cautious when removing sections as this removes all
4020
+ * content within that section.
4021
+ *
4022
+ * @example
4023
+ * ```typescript
4024
+ * const sections = body.sections();
4025
+ * if (sections.length > 1) {
4026
+ * // Remove the last section
4027
+ * const removed = body.removeSection(sections.length - 1);
4028
+ * if (removed) {
4029
+ * console.log('Successfully removed section');
4030
+ * }
4031
+ * }
4032
+ * ```
4033
+ *
4034
+ * @example
4035
+ * Remove specific section with confirmation:
4036
+ * ```typescript
4037
+ * const indexToRemove = 2;
4038
+ * const sections = body.sections();
4039
+ *
4040
+ * if (indexToRemove < sections.length) {
4041
+ * const removed = body.removeSection(indexToRemove);
4042
+ * console.log(`Removed section ${indexToRemove + 1}`);
4043
+ * }
4044
+ * ```
4045
+ */
1659
4046
  removeSection(index: number): Section | undefined;
4047
+ /**
4048
+ * Replaces all occurrences of a pattern across all sections.
4049
+ *
4050
+ * @remarks
4051
+ * Convenience method that searches and replaces text across all sections in the body,
4052
+ * including all content, headers, and footers. This provides a simpler API than
4053
+ * manually iterating through sections.
4054
+ *
4055
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
4056
+ *
4057
+ * @example
4058
+ * ```typescript
4059
+ * const count = body.replaceText(/old/g, 'new');
4060
+ * console.log(`Replaced ${count} occurrences`);
4061
+ * ```
4062
+ *
4063
+ * @example
4064
+ * ```typescript
4065
+ * body.replaceText(/ERROR/gi, {
4066
+ * text: 'ERROR',
4067
+ * formatting: { color: '#ff0000', bold: true }
4068
+ * });
4069
+ * ```
4070
+ */
1660
4071
  replaceText: ReplaceTextSignature;
1661
4072
  };
1662
4073
  /**
4074
+ * Represents the root of a document structure in the programmatic API.
4075
+ *
4076
+ * @remarks
4077
+ * `Document` is the top-level entry point for programmatically accessing and modifying
4078
+ * document content. It provides access to the document {@linkcode Body}, which contains all
4079
+ * sections and their content.
4080
+ *
4081
+ * You typically obtain a `Document` instance from a transaction context when using the
4082
+ * programmatic API to modify documents. The document is organized hierarchically:
4083
+ *
4084
+ * ```
4085
+ * Document
4086
+ * └─ Body
4087
+ * └─ Section(s)
4088
+ * ├─ Content (BlockLevelContainer)
4089
+ * │ └─ Paragraph(s) / Table(s)
4090
+ * └─ Headers & Footers
4091
+ * ```
4092
+ *
4093
+ * For document-wide operations, you can use the convenience {@linkcode replaceText} method
4094
+ * to search and replace across all content without manually traversing the hierarchy.
4095
+ *
4096
+ * @example
4097
+ * Access document structure and iterate through content:
4098
+ * ```typescript
4099
+ * const body = document.body();
4100
+ * const sections = body.sections();
4101
+ *
4102
+ * console.log(`Document has ${sections.length} sections`);
4103
+ *
4104
+ * for (const section of sections) {
4105
+ * const content = section.content();
4106
+ * const blockLevels = content.blocklevels();
4107
+ * console.log(`Section has ${blockLevels.length} paragraphs/tables`);
4108
+ * }
4109
+ * ```
4110
+ *
4111
+ * @example
4112
+ * Replace text across entire document:
4113
+ * ```typescript
4114
+ * // Replace all occurrences of "TODO" with "DONE" throughout the document
4115
+ * const count = document.replaceText(/TODO/g, 'DONE');
4116
+ * console.log(`Replaced ${count} occurrences across entire document`);
4117
+ * ```
4118
+ *
4119
+ * @example
4120
+ * Replace text with formatting across document:
4121
+ * ```typescript
4122
+ * // Highlight all instances of "IMPORTANT" in the entire document
4123
+ * document.replaceText(/IMPORTANT/gi, {
4124
+ * text: 'IMPORTANT',
4125
+ * formatting: {
4126
+ * highlight: '#ffff00',
4127
+ * bold: true
4128
+ * }
4129
+ * });
4130
+ * ```
4131
+ *
4132
+ * @example
4133
+ * Typical usage in a transaction:
4134
+ * ```typescript
4135
+ * await docAuthDoc.transaction(async (context) => {
4136
+ * const { draft } = context;
4137
+ *
4138
+ * // 'draft' is a Programmatic.Document
4139
+ * const body = draft.body();
4140
+ * const sections = body.sections();
4141
+ *
4142
+ * // Add a new section
4143
+ * const newSection = body.addSection();
4144
+ * const para = newSection.content().addParagraph();
4145
+ * para.asTextView().setText('New section content');
4146
+ *
4147
+ * // Or use document-wide replace
4148
+ * draft.replaceText(/old/g, 'new');
4149
+ *
4150
+ * return { commit: true };
4151
+ * });
4152
+ * ```
4153
+ *
1663
4154
  * @sidebarGroup programmatic api
1664
4155
  */
1665
4156
  export type Document = {
4157
+ /**
4158
+ * Gets the document body containing all sections.
4159
+ *
4160
+ * @returns The {@linkcode Body} of the document
4161
+ *
4162
+ * @remarks
4163
+ * Returns the document's body, which contains all sections. Each section has its
4164
+ * own content (paragraphs and tables) and headers/footers. Use this as the entry
4165
+ * point for navigating and modifying document structure.
4166
+ *
4167
+ * @example
4168
+ * ```typescript
4169
+ * const body = document.body();
4170
+ * const sections = body.sections();
4171
+ *
4172
+ * // Work with sections
4173
+ * for (const section of sections) {
4174
+ * const content = section.content();
4175
+ * // ... work with content
4176
+ * }
4177
+ * ```
4178
+ */
1666
4179
  body(): Body;
4180
+ /**
4181
+ * Replaces all occurrences of a pattern throughout the entire document.
4182
+ *
4183
+ * @remarks
4184
+ * Convenience method that searches and replaces text across all document content,
4185
+ * including all sections, paragraphs, tables, headers, and footers. This is equivalent
4186
+ * to manually calling {@linkcode Body.replaceText} on the document body, but provides a
4187
+ * simpler API for document-wide operations.
4188
+ *
4189
+ * See {@linkcode ReplaceTextSignature} for detailed parameter and usage information.
4190
+ *
4191
+ * @example
4192
+ * Simple document-wide replacement:
4193
+ * ```typescript
4194
+ * const count = document.replaceText('old text', 'new text');
4195
+ * console.log(`Replaced ${count} occurrences`);
4196
+ * ```
4197
+ *
4198
+ * @example
4199
+ * Replace with formatting:
4200
+ * ```typescript
4201
+ * document.replaceText(/ERROR/g, {
4202
+ * text: 'ERROR',
4203
+ * formatting: { color: '#ff0000', bold: true }
4204
+ * });
4205
+ * ```
4206
+ *
4207
+ * @example
4208
+ * Dynamic replacement with callback:
4209
+ * ```typescript
4210
+ * // Convert all numbers to currency format
4211
+ * document.replaceText(/\$?(\d+(\.\d{2})?)/g, (match) => {
4212
+ * const amount = parseFloat(match.replace('$', ''));
4213
+ * return {
4214
+ * text: `$${amount.toFixed(2)}`,
4215
+ * formatting: { color: '#00aa00' }
4216
+ * };
4217
+ * });
4218
+ * ```
4219
+ */
1667
4220
  replaceText: ReplaceTextSignature;
1668
4221
  };
1669
4222
  {};
@@ -1885,16 +4438,102 @@ export declare type ToolbarSeparatorItem = {
1885
4438
  };
1886
4439
 
1887
4440
  /**
1888
- * @alpha
4441
+ * Callback function for document transactions that provides access to a draft document for modification.
4442
+ *
4443
+ * @remarks
4444
+ * `TransactionCallback` is the function signature used when working with document transactions via
4445
+ * {@linkcode DocAuthDocument.transaction}. The callback receives a context object containing a
4446
+ * `draft` document that can be modified, and returns a {@linkcode TransactionResult} to control
4447
+ * whether changes are committed .
4448
+ *
4449
+ * **Key concepts:**
4450
+ *
4451
+ * **Context parameter:**
4452
+ * - `context.draft` - A {@linkcode Programmatic.Document} instance representing the document in draft state
4453
+ * - All modifications are made on this draft
4454
+ * - Changes are isolated until the transaction commits
4455
+ *
4456
+ * **Return value:**
4457
+ * - Must return a {@linkcode TransactionResult}
4458
+ * - Return `true`, or `{ commit: true }` to commit changes
4459
+ * - Optionally return a result value with `{ commit: boolean, result: T }`
4460
+ *
4461
+ * @example
4462
+ * Explicit commit:
4463
+ * ```typescript
4464
+ * const r = await doc.transaction(async ({ draft }) => {
4465
+ * const replacementCount = draft.replaceText(/old/g, 'new');
4466
+ *
4467
+ * return { commit: true, result: replacementCount };
4468
+ * });
4469
+ * ```
4470
+ *
4471
+ * @param context - Object containing the draft document to modify
4472
+ * @returns A {@linkcode TransactionResult} controlling commit/rollback and optionally providing a result value
4473
+ *
4474
+ * @public
1889
4475
  * @sidebarGroup programmatic api
1890
4476
  * @see {@linkcode DocAuthDocument.transaction} for running transactions with this callback type.
4477
+ * @see {@linkcode TransactionResult} for details on return value options.
4478
+ */
4479
+ export declare type TransactionCallback<T = void> = (context: TransactionContext) => Promise<TransactionResult<T>>;
4480
+
4481
+ /**
4482
+ * Context object passed to transaction callbacks.
4483
+ *
4484
+ * @remarks
4485
+ * Contains the draft document that can be read or modified within a transaction.
4486
+ *
4487
+ * @public
4488
+ * @sidebarGroup programmatic api
4489
+ * @see {@linkcode TransactionCallback} for how this context is used
1891
4490
  */
1892
- export declare type TransactionCallback<T = void> = (context: {
4491
+ export declare type TransactionContext = {
4492
+ /**
4493
+ * The draft document for reading and modification.
4494
+ *
4495
+ * @remarks
4496
+ * A {@linkcode Programmatic.Document} instance representing the document in draft state.
4497
+ * All modifications are made to this draft and are isolated until the transaction commits.
4498
+ */
1893
4499
  draft: Programmatic.Document;
1894
- }) => Promise<TransactionResult<T>>;
4500
+ };
1895
4501
 
1896
4502
  /**
1897
- * @alpha
4503
+ * Return type for transaction callbacks that control whether changes are committed and optionally return a result.
4504
+ *
4505
+ * @remarks
4506
+ * `TransactionResult` is returned from {@linkcode TransactionCallback} functions to control the outcome
4507
+ * of a document transaction. It determines whether the changes made during the transaction should be
4508
+ * committed to the document and optionally provides a result value to the transaction caller.
4509
+ *
4510
+ * **Commit behavior:**
4511
+ * - `true` - **Commits** the transaction
4512
+ * - `{ commit: true }` - **Commits** the transaction
4513
+ * - `{ commit: true, result: T }` - **Commits** the transaction and returns a result value
4514
+ * - `false` - Does **not** commit the transaction
4515
+ * - `{ commit: false }` - Does **not** commit the transaction
4516
+ * - `{ commit: false, result: T }` - Does **not** commit the transaction but still returns a result value
4517
+ *
4518
+ * **Async support:**
4519
+ * All return values can be wrapped in a `Promise`, allowing async transaction callbacks.
4520
+ *
4521
+ * **Type parameter `T`:**
4522
+ * - Defaults to `void` if no result is needed
4523
+ * - Set to a specific type when you want to return a value from the transaction
4524
+ * - The result can be returned regardless of whether the transaction commits or not
4525
+ *
4526
+ * @example
4527
+ * Explicit commit:
4528
+ * ```typescript
4529
+ * const r = await doc.transaction(async ({ draft }) => {
4530
+ * const replacementCount = draft.replaceText(/old/g, 'new');
4531
+ *
4532
+ * return { commit: true, result: replacementCount };
4533
+ * });
4534
+ * ```
4535
+ *
4536
+ * @public
1898
4537
  * @sidebarGroup programmatic api
1899
4538
  * @see {@linkcode TransactionCallback} for the callback signature that returns this result type.
1900
4539
  */
@@ -2050,6 +4689,25 @@ export declare type UIOptions = {
2050
4689
  * ```
2051
4690
  */
2052
4691
  actions?: Action[];
4692
+ /**
4693
+ * The author name to use when creating comments and replies.
4694
+ *
4695
+ * This can also be changed at runtime using {@linkcode DocAuthEditor#setAuthor | editor.setAuthor()}.
4696
+ *
4697
+ * If not provided, comments will show a localized "Anonymous" author.
4698
+ *
4699
+ * @since 1.10.0
4700
+ * @example
4701
+ *
4702
+ * ```ts
4703
+ * const editor = await system.createEditor(target, {
4704
+ * ui: {
4705
+ * author: 'John Doe',
4706
+ * },
4707
+ * });
4708
+ * ```
4709
+ */
4710
+ author?: string;
2053
4711
  };
2054
4712
 
2055
4713
  /**