@nutrient-sdk/document-authoring 1.10.0-preview.202512171254.414ae9476ccdf6c895ab5cf4a5c42a6d1dc61dd9 → 1.10.0-preview.202512190816.90cd35dd5494eda6e0aba78c724b366b267c7ec8

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