@pacem/pacem-foundation 1.0.6-ricci → 2.0.0-abel

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-foundation v1.0.6-ricci (https://js.pacem.it)
2
+ * @pacem/pacem-foundation v2.0.0-abel (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -1532,8 +1532,19 @@ var Strings = class {
1532
1532
  // packages/foundation/dist/esm/index-compile.js
1533
1533
  var index_compile_exports = {};
1534
1534
  __export(index_compile_exports, {
1535
+ CSharpSyntax: () => CSharpSyntax,
1536
+ CSyntax: () => CSyntax,
1537
+ DefaultHighlightClasses: () => DefaultHighlightClasses,
1538
+ HighlightRenderer: () => HighlightRenderer,
1539
+ JavaScriptSyntax: () => JavaScriptSyntax,
1540
+ JsonSyntax: () => JsonSyntax,
1535
1541
  Markdown: () => index_compile_markdown_exports,
1536
- Parser: () => Parser
1542
+ MarkupSyntax: () => MarkupSyntax,
1543
+ PacemBindingSyntax: () => PacemBindingSyntax,
1544
+ Parser: () => Parser,
1545
+ Scanner: () => Scanner,
1546
+ SyntaxTokenType: () => SyntaxTokenType,
1547
+ Syntaxes: () => Syntaxes
1537
1548
  });
1538
1549
 
1539
1550
  // packages/foundation/dist/esm/index-compile-markdown.js
@@ -1590,8 +1601,577 @@ var Parser = class {
1590
1601
  }
1591
1602
  };
1592
1603
 
1604
+ // packages/foundation/dist/esm/compile/syntax/types.js
1605
+ var SyntaxTokenType;
1606
+ (function(SyntaxTokenType2) {
1607
+ SyntaxTokenType2["Text"] = "text";
1608
+ SyntaxTokenType2["Space"] = "space";
1609
+ SyntaxTokenType2["Newline"] = "newline";
1610
+ SyntaxTokenType2["Comment"] = "comment";
1611
+ SyntaxTokenType2["DocComment"] = "doc-comment";
1612
+ SyntaxTokenType2["Keyword"] = "keyword";
1613
+ SyntaxTokenType2["Identifier"] = "identifier";
1614
+ SyntaxTokenType2["String"] = "string";
1615
+ SyntaxTokenType2["Regex"] = "regex";
1616
+ SyntaxTokenType2["Number"] = "number";
1617
+ SyntaxTokenType2["Bracket"] = "bracket";
1618
+ SyntaxTokenType2["Punctuation"] = "punctuation";
1619
+ SyntaxTokenType2["Operator"] = "operator";
1620
+ SyntaxTokenType2["Preprocessor"] = "preprocessor";
1621
+ SyntaxTokenType2["Tag"] = "tag";
1622
+ SyntaxTokenType2["TagName"] = "tagname";
1623
+ SyntaxTokenType2["Attribute"] = "attribute";
1624
+ SyntaxTokenType2["Entity"] = "entity";
1625
+ })(SyntaxTokenType || (SyntaxTokenType = {}));
1626
+
1627
+ // packages/foundation/dist/esm/compile/syntax/registry.js
1628
+ var registry = /* @__PURE__ */ new Map();
1629
+ function normalize(name) {
1630
+ return (name ?? "").trim().toLowerCase();
1631
+ }
1632
+ var Syntaxes = class {
1633
+ /**
1634
+ * Registers (or replaces) a syntax under its name and aliases.
1635
+ * @param syntax The vocabulary to register.
1636
+ */
1637
+ static register(syntax) {
1638
+ if (syntax == null) {
1639
+ return;
1640
+ }
1641
+ const names = [syntax.name].concat(syntax.aliases ?? []);
1642
+ for (let name of names) {
1643
+ const key = normalize(name);
1644
+ registry.set(key, syntax);
1645
+ }
1646
+ }
1647
+ /**
1648
+ * Gets a registered syntax by name or alias.
1649
+ * @param nameOrAlias Case-insensitive name or alias (e.g. `'ts'`).
1650
+ * @returns The syntax, or `null` when unknown.
1651
+ */
1652
+ static get(nameOrAlias) {
1653
+ const key = normalize(nameOrAlias);
1654
+ return registry.get(key) ?? null;
1655
+ }
1656
+ /** Names (and aliases) of every registered syntax. */
1657
+ static names() {
1658
+ const keys = registry.keys();
1659
+ return Array.from(keys);
1660
+ }
1661
+ };
1662
+
1663
+ // packages/foundation/dist/esm/compile/syntax/scanner.js
1664
+ var DEFAULT_START = "root";
1665
+ var DEFAULT_KEYWORD_SOURCES = [SyntaxTokenType.Identifier];
1666
+ var DEFAULT_INSIGNIFICANT = [SyntaxTokenType.Space, SyntaxTokenType.Newline, SyntaxTokenType.Comment, SyntaxTokenType.DocComment];
1667
+ var MAX_EMPTY_TRANSITIONS = 64;
1668
+ var MAX_EXTENDS_DEPTH = 16;
1669
+ function isCombined(item) {
1670
+ return item.combined != null;
1671
+ }
1672
+ var compiledCache = /* @__PURE__ */ new WeakMap();
1673
+ function isIncludeRule(rule) {
1674
+ return "include" in rule;
1675
+ }
1676
+ function toSet(values) {
1677
+ if (values == null || values.length === 0) {
1678
+ return null;
1679
+ }
1680
+ return new Set(values);
1681
+ }
1682
+ function uniqueFlags(flags) {
1683
+ const chars = flags.split("");
1684
+ const unique = new Set(chars);
1685
+ const array = Array.from(unique);
1686
+ return array.join("");
1687
+ }
1688
+ function mergeStates(own, base) {
1689
+ const merged = {};
1690
+ for (let name in base) {
1691
+ merged[name] = base[name].slice();
1692
+ }
1693
+ for (let name in own) {
1694
+ const baseRules = merged[name] ?? [];
1695
+ merged[name] = own[name].concat(baseRules);
1696
+ }
1697
+ return merged;
1698
+ }
1699
+ function mergeKeywords(own, base) {
1700
+ const merged = {};
1701
+ for (let type in base) {
1702
+ merged[type] = base[type].slice();
1703
+ }
1704
+ for (let type in own) {
1705
+ const baseWords = merged[type] ?? [];
1706
+ merged[type] = baseWords.concat(own[type]);
1707
+ }
1708
+ return merged;
1709
+ }
1710
+ function mergeSyntax(syntax, depth = 0) {
1711
+ const lexical = syntax.lexical ?? { states: {} };
1712
+ const own = {
1713
+ start: lexical.start,
1714
+ states: lexical.states ?? {},
1715
+ keywords: lexical.keywords ?? {},
1716
+ keywordSources: lexical.keywordSources,
1717
+ keywordExceptAfter: lexical.keywordExceptAfter,
1718
+ insignificant: lexical.insignificant
1719
+ };
1720
+ const baseSyntax = syntax.extends ? Syntaxes.get(syntax.extends) : null;
1721
+ if (baseSyntax == null || baseSyntax === syntax || depth >= MAX_EXTENDS_DEPTH) {
1722
+ return own;
1723
+ }
1724
+ const base = mergeSyntax(baseSyntax, depth + 1);
1725
+ return {
1726
+ start: own.start ?? base.start,
1727
+ states: mergeStates(own.states, base.states),
1728
+ keywords: mergeKeywords(own.keywords, base.keywords),
1729
+ keywordSources: own.keywordSources ?? base.keywordSources,
1730
+ keywordExceptAfter: own.keywordExceptAfter ?? base.keywordExceptAfter,
1731
+ insignificant: own.insignificant ?? base.insignificant
1732
+ };
1733
+ }
1734
+ function expandRules(states, stateName, visiting) {
1735
+ const rules = states[stateName] ?? [];
1736
+ if (visiting.has(stateName)) {
1737
+ return [];
1738
+ }
1739
+ visiting.add(stateName);
1740
+ const expanded = [];
1741
+ for (let rule of rules) {
1742
+ if (!isIncludeRule(rule)) {
1743
+ expanded.push(rule);
1744
+ continue;
1745
+ }
1746
+ const included = expandRules(states, rule.include, visiting);
1747
+ Array.prototype.push.apply(expanded, included);
1748
+ }
1749
+ visiting.delete(stateName);
1750
+ return expanded;
1751
+ }
1752
+ function compileCondition(condition) {
1753
+ if (condition == null) {
1754
+ return null;
1755
+ }
1756
+ return {
1757
+ previousTypes: toSet(condition.previousTypes),
1758
+ previousNotTypes: toSet(condition.previousNotTypes),
1759
+ previousTexts: toSet(condition.previousTexts),
1760
+ previousNotTexts: toSet(condition.previousNotTexts)
1761
+ };
1762
+ }
1763
+ function compileRule(rule) {
1764
+ const groupTypes = Array.isArray(rule.type) ? rule.type : null;
1765
+ const type = Array.isArray(rule.type) ? rule.type[0] : rule.type;
1766
+ const userFlags = (rule.flags ?? "").replace(/[yd]/g, "");
1767
+ const ownFlags = uniqueFlags(userFlags);
1768
+ const flags = ownFlags + "y" + (groupTypes ? "d" : "");
1769
+ const regex = new RegExp(rule.match, flags);
1770
+ const until = rule.until ? new RegExp(rule.until, "y") : null;
1771
+ const pop = rule.pop === true ? 1 : typeof rule.pop === "number" ? rule.pop : 0;
1772
+ const when = compileCondition(rule.when);
1773
+ return {
1774
+ regex,
1775
+ type,
1776
+ groupTypes,
1777
+ when,
1778
+ pop,
1779
+ until,
1780
+ source: rule.match,
1781
+ flags: ownFlags,
1782
+ next: rule.next ?? null,
1783
+ push: rule.push ?? null,
1784
+ embed: rule.embed ?? null,
1785
+ hasTransition: pop > 0 || !!rule.next || !!rule.push || !!rule.embed
1786
+ };
1787
+ }
1788
+ function compileKeywords(keywords) {
1789
+ const map = /* @__PURE__ */ new Map();
1790
+ for (let type in keywords) {
1791
+ for (let word of keywords[type]) {
1792
+ map.set(word, type);
1793
+ }
1794
+ }
1795
+ return map;
1796
+ }
1797
+ var UNMERGEABLE_SOURCE = /\\[1-9]|\\k<|\(\?<(?![=!])/;
1798
+ function countGroups(source, flags) {
1799
+ const probe = new RegExp(source + "|", flags);
1800
+ const match2 = probe.exec("");
1801
+ return match2.length - 1;
1802
+ }
1803
+ function canMatchEmpty(source, flags) {
1804
+ const probe = new RegExp("^(?:" + source + ")$", flags);
1805
+ return probe.test("");
1806
+ }
1807
+ function isMergeable(rule) {
1808
+ if (rule.when != null || UNMERGEABLE_SOURCE.test(rule.source)) {
1809
+ return false;
1810
+ }
1811
+ return !canMatchEmpty(rule.source, rule.flags);
1812
+ }
1813
+ function combine(rules) {
1814
+ if (rules.length === 1) {
1815
+ return { rule: rules[0], combined: null };
1816
+ }
1817
+ const groupIndices = [];
1818
+ let groupIndex = 1;
1819
+ for (let rule of rules) {
1820
+ groupIndices.push(groupIndex);
1821
+ const ownGroups = countGroups(rule.source, rule.flags);
1822
+ groupIndex += 1 + ownGroups;
1823
+ }
1824
+ const alternatives = rules.map((r) => "(" + r.source + ")");
1825
+ const source = alternatives.join("|");
1826
+ const combined = new RegExp(source, rules[0].flags + "y");
1827
+ return { rule: null, combined, rules, groupIndices };
1828
+ }
1829
+ function segment(rules) {
1830
+ const segments = [];
1831
+ let pending = [];
1832
+ const flush = () => {
1833
+ if (pending.length > 0) {
1834
+ const combinedSegment = combine(pending);
1835
+ segments.push(combinedSegment);
1836
+ }
1837
+ pending = [];
1838
+ };
1839
+ for (let rule of rules) {
1840
+ if (!isMergeable(rule)) {
1841
+ flush();
1842
+ segments.push({ rule, combined: null });
1843
+ continue;
1844
+ }
1845
+ if (pending.length > 0 && pending[0].flags !== rule.flags) {
1846
+ flush();
1847
+ }
1848
+ pending.push(rule);
1849
+ }
1850
+ flush();
1851
+ return segments;
1852
+ }
1853
+ function compileSyntax(syntax) {
1854
+ const cached = compiledCache.get(syntax);
1855
+ if (cached != null) {
1856
+ return cached;
1857
+ }
1858
+ const merged = mergeSyntax(syntax);
1859
+ const states = /* @__PURE__ */ new Map();
1860
+ for (let name in merged.states) {
1861
+ const visiting = /* @__PURE__ */ new Set();
1862
+ const rules = expandRules(merged.states, name, visiting);
1863
+ const compiledRules = rules.map(compileRule);
1864
+ const segments = segment(compiledRules);
1865
+ states.set(name, segments);
1866
+ }
1867
+ const compiled = {
1868
+ name: syntax.name,
1869
+ start: merged.start ?? DEFAULT_START,
1870
+ states,
1871
+ keywords: compileKeywords(merged.keywords),
1872
+ keywordSources: new Set(merged.keywordSources ?? DEFAULT_KEYWORD_SOURCES),
1873
+ keywordExceptAfter: new Set(merged.keywordExceptAfter ?? []),
1874
+ insignificant: new Set(merged.insignificant ?? DEFAULT_INSIGNIFICANT)
1875
+ };
1876
+ compiledCache.set(syntax, compiled);
1877
+ return compiled;
1878
+ }
1879
+ function compileByName(name) {
1880
+ const syntax = Syntaxes.get(name);
1881
+ if (syntax == null) {
1882
+ return null;
1883
+ }
1884
+ return compileSyntax(syntax);
1885
+ }
1886
+ function meets(condition, previous) {
1887
+ const type = previous?.type ?? null, text = previous?.raw ?? null;
1888
+ if (condition.previousTypes != null && !condition.previousTypes.has(type)) {
1889
+ return false;
1890
+ }
1891
+ if (condition.previousNotTypes != null && condition.previousNotTypes.has(type)) {
1892
+ return false;
1893
+ }
1894
+ if (condition.previousTexts != null && !condition.previousTexts.has(text)) {
1895
+ return false;
1896
+ }
1897
+ return condition.previousNotTexts == null || !condition.previousNotTexts.has(text);
1898
+ }
1899
+ var ScanRun = class {
1900
+ constructor(_source, root) {
1901
+ this._source = _source;
1902
+ this._tokens = [];
1903
+ this._position = 0;
1904
+ this._emitted = 0;
1905
+ this._line = 1;
1906
+ this._column = 1;
1907
+ this._previous = null;
1908
+ this._emptyTransitions = 0;
1909
+ this._stack = [{ syntax: root, state: root.start, until: null }];
1910
+ }
1911
+ run() {
1912
+ const length = this._source.length;
1913
+ while (this._position < length) {
1914
+ this._step();
1915
+ }
1916
+ this._flushText();
1917
+ return this._tokens;
1918
+ }
1919
+ get _top() {
1920
+ const stack = this._stack;
1921
+ return stack[stack.length - 1];
1922
+ }
1923
+ _step() {
1924
+ const frame = this._top;
1925
+ if (this._popOnUntil(frame)) {
1926
+ return;
1927
+ }
1928
+ const found = this._findRule(frame);
1929
+ if (found == null) {
1930
+ this._position++;
1931
+ return;
1932
+ }
1933
+ this._flushText();
1934
+ this._emitMatch(found, frame.syntax);
1935
+ this._transition(found.rule, frame.syntax);
1936
+ const length = found.match[0].length;
1937
+ this._position += length;
1938
+ if (length > 0) {
1939
+ this._emptyTransitions = 0;
1940
+ }
1941
+ }
1942
+ /** Pops an embedded syntax as soon as its `until` pattern matches (without consuming input). */
1943
+ _popOnUntil(frame) {
1944
+ const until = frame.until;
1945
+ if (until == null || this._stack.length <= 1) {
1946
+ return false;
1947
+ }
1948
+ until.lastIndex = this._position;
1949
+ if (!until.test(this._source)) {
1950
+ return false;
1951
+ }
1952
+ this._flushText();
1953
+ this._stack.pop();
1954
+ return true;
1955
+ }
1956
+ _findRule(frame) {
1957
+ const segments = frame.syntax.states.get(frame.state) ?? [];
1958
+ for (let item of segments) {
1959
+ const found = isCombined(item) ? this._tryCombined(item) : this._trySingle(item.rule);
1960
+ if (found != null) {
1961
+ return found;
1962
+ }
1963
+ }
1964
+ return null;
1965
+ }
1966
+ _trySingle(rule) {
1967
+ const match2 = this._tryRule(rule);
1968
+ if (match2 == null) {
1969
+ return null;
1970
+ }
1971
+ return { rule, match: match2 };
1972
+ }
1973
+ /** Finds which merged rule matched (the first defined wrapping group), then re-runs it alone for its own groups. */
1974
+ _tryCombined(item) {
1975
+ const combined = item.combined;
1976
+ combined.lastIndex = this._position;
1977
+ const match2 = combined.exec(this._source);
1978
+ if (match2 == null) {
1979
+ return null;
1980
+ }
1981
+ const indices = item.groupIndices;
1982
+ for (let k = 0; k < indices.length; k++) {
1983
+ if (match2[indices[k]] === void 0) {
1984
+ continue;
1985
+ }
1986
+ const rule = item.rules[k];
1987
+ return this._trySingle(rule);
1988
+ }
1989
+ return null;
1990
+ }
1991
+ _tryRule(rule) {
1992
+ if (rule.when != null && !meets(rule.when, this._previous)) {
1993
+ return null;
1994
+ }
1995
+ const regex = rule.regex;
1996
+ regex.lastIndex = this._position;
1997
+ const match2 = regex.exec(this._source);
1998
+ if (match2 == null) {
1999
+ return null;
2000
+ }
2001
+ if (match2[0].length > 0) {
2002
+ return match2;
2003
+ }
2004
+ if (!rule.hasTransition || this._emptyTransitions >= MAX_EMPTY_TRANSITIONS) {
2005
+ return null;
2006
+ }
2007
+ this._emptyTransitions++;
2008
+ return match2;
2009
+ }
2010
+ _emitMatch({ rule, match: match2 }, syntax) {
2011
+ const raw = match2[0];
2012
+ if (rule.groupTypes == null) {
2013
+ this._append(rule.type, raw, syntax);
2014
+ return;
2015
+ }
2016
+ this._emitGroups(rule, match2, syntax);
2017
+ }
2018
+ /** Splits a match into one token per (top-level) capture group; uncovered characters become `text` tokens. */
2019
+ _emitGroups(rule, match2, syntax) {
2020
+ const indices = match2.indices;
2021
+ const start = match2.index, end = start + match2[0].length, types = rule.groupTypes;
2022
+ let cursor = start;
2023
+ for (let i = 1; i < match2.length; i++) {
2024
+ const range = indices[i];
2025
+ if (range == null || range[0] < cursor || range[1] === range[0]) {
2026
+ continue;
2027
+ }
2028
+ if (range[0] > cursor) {
2029
+ const gap = this._source.slice(cursor, range[0]);
2030
+ this._append(SyntaxTokenType.Text, gap, syntax);
2031
+ }
2032
+ const groupText = this._source.slice(range[0], range[1]);
2033
+ const groupType = types[i - 1] ?? types[types.length - 1];
2034
+ this._append(groupType, groupText, syntax);
2035
+ cursor = range[1];
2036
+ }
2037
+ if (cursor < end) {
2038
+ const rest = this._source.slice(cursor, end);
2039
+ this._append(SyntaxTokenType.Text, rest, syntax);
2040
+ }
2041
+ }
2042
+ _transition(rule, syntax) {
2043
+ const stack = this._stack;
2044
+ for (let i = 0; i < rule.pop && stack.length > 1; i++) {
2045
+ stack.pop();
2046
+ }
2047
+ if (rule.next != null) {
2048
+ this._top.state = rule.next;
2049
+ }
2050
+ if (rule.push != null) {
2051
+ stack.push({ syntax, state: rule.push, until: null });
2052
+ }
2053
+ if (rule.embed == null) {
2054
+ return;
2055
+ }
2056
+ const embedded = compileByName(rule.embed);
2057
+ if (embedded == null) {
2058
+ return;
2059
+ }
2060
+ stack.push({ syntax: embedded, state: embedded.start, until: rule.until });
2061
+ }
2062
+ /** Emits the pending unrecognized characters (if any) as a single `text` token. */
2063
+ _flushText() {
2064
+ if (this._emitted >= this._position) {
2065
+ return;
2066
+ }
2067
+ const text = this._source.slice(this._emitted, this._position);
2068
+ const syntax = this._top.syntax;
2069
+ this._append(SyntaxTokenType.Text, text, syntax);
2070
+ }
2071
+ _resolveType(type, raw, syntax) {
2072
+ if (!syntax.keywordSources.has(type)) {
2073
+ return type;
2074
+ }
2075
+ const previousText = this._previous?.raw;
2076
+ if (syntax.keywordExceptAfter.has(previousText)) {
2077
+ return type;
2078
+ }
2079
+ return syntax.keywords.get(raw) ?? type;
2080
+ }
2081
+ _append(type, raw, syntax) {
2082
+ const resolvedType = this._resolveType(type, raw, syntax);
2083
+ const token = {
2084
+ type: resolvedType,
2085
+ raw,
2086
+ text: raw,
2087
+ index: this._emitted,
2088
+ line: this._line,
2089
+ column: this._column,
2090
+ depth: this._stack.length - 1,
2091
+ syntax: syntax.name
2092
+ };
2093
+ this._tokens.push(token);
2094
+ this._advance(raw);
2095
+ if (!syntax.insignificant.has(resolvedType)) {
2096
+ this._previous = token;
2097
+ }
2098
+ }
2099
+ /** Moves the emitted offset and the line/column counters past `raw`. */
2100
+ _advance(raw) {
2101
+ this._emitted += raw.length;
2102
+ const lastNewline = raw.lastIndexOf("\n");
2103
+ if (lastNewline < 0) {
2104
+ this._column += raw.length;
2105
+ return;
2106
+ }
2107
+ for (let i = 0; i <= lastNewline; i++) {
2108
+ if (raw.charCodeAt(i) === 10) {
2109
+ this._line++;
2110
+ }
2111
+ }
2112
+ this._column = raw.length - lastNewline;
2113
+ }
2114
+ };
2115
+ var PLAIN_TEXT_SYNTAX = { name: SyntaxTokenType.Text, lexical: { states: {} } };
2116
+ var Scanner = class {
2117
+ /**
2118
+ * Tokenizes `source`.
2119
+ * @param source Source text.
2120
+ * @param syntax A {@link Syntax} or the name/alias of a registered one (see {@link Syntaxes}); an unknown one yields a single `text` token.
2121
+ * @returns The lossless, positioned token stream.
2122
+ */
2123
+ tokenize(source, syntax) {
2124
+ const text = source ?? "";
2125
+ const resolved = typeof syntax === "string" ? Syntaxes.get(syntax) : syntax;
2126
+ const compiled = compileSyntax(resolved ?? PLAIN_TEXT_SYNTAX);
2127
+ const run = new ScanRun(text, compiled);
2128
+ return run.run();
2129
+ }
2130
+ };
2131
+
2132
+ // packages/foundation/dist/esm/compile/syntax/highlight.js
2133
+ var DefaultHighlightClasses = Object.freeze({
2134
+ "keyword": "code-keyword",
2135
+ "preprocessor": "code-keyword",
2136
+ "string": "code-string",
2137
+ "regex": "code-string",
2138
+ "number": "code-number",
2139
+ "comment": "code-comment",
2140
+ "doc-comment": "code-comment",
2141
+ "tag": "code-tag",
2142
+ "tagname": "code-tagname",
2143
+ "attribute": "code-attribute"
2144
+ });
2145
+ var HTML_ESCAPES = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" };
2146
+ function htmlEncode(text) {
2147
+ return text.replace(/[&<>"]/g, (c) => HTML_ESCAPES[c]);
2148
+ }
2149
+ var HighlightRenderer = class {
2150
+ /**
2151
+ * @param _classes Token type → CSS class mapping (defaults to {@link DefaultHighlightClasses}).
2152
+ */
2153
+ constructor(_classes = DefaultHighlightClasses) {
2154
+ this._classes = _classes;
2155
+ }
2156
+ render(tree) {
2157
+ let html = "";
2158
+ for (let token of tree ?? []) {
2159
+ html += this._renderToken(token);
2160
+ }
2161
+ return html;
2162
+ }
2163
+ _renderToken(token) {
2164
+ const encoded = htmlEncode(token.raw ?? "");
2165
+ const cssClass = this._classes[token.type];
2166
+ if (cssClass == null) {
2167
+ return encoded;
2168
+ }
2169
+ return `<span class="${cssClass}">${encoded}</span>`;
2170
+ }
2171
+ };
2172
+
1593
2173
  // packages/foundation/dist/esm/compile/markdown/parser.js
1594
- function htmlEncode(input) {
2174
+ function htmlEncode2(input) {
1595
2175
  return (input ?? "").replace(/</g, "&lt;");
1596
2176
  }
1597
2177
  function extractReference(input) {
@@ -1606,6 +2186,72 @@ function extractReference(input) {
1606
2186
  }
1607
2187
  return input;
1608
2188
  }
2189
+ function splitUrlAndTitle(destination) {
2190
+ if (NullChecker.isNullOrEmpty(destination)) {
2191
+ return { url: destination };
2192
+ }
2193
+ const trimmed = destination.trim();
2194
+ const arr = /^(\S*)\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\))\s*$/.exec(trimmed);
2195
+ if (arr == null) {
2196
+ return { url: trimmed };
2197
+ }
2198
+ const title = arr[2] ?? arr[3] ?? arr[4];
2199
+ return { url: arr[1], title };
2200
+ }
2201
+ function attributeEncode(input) {
2202
+ return (input ?? "").replace(/&(?!(?:#\d+|#x[\da-fA-F]+|\w+);)/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2203
+ }
2204
+ function splitTableCells(row) {
2205
+ let line = row.trim();
2206
+ if (line.startsWith("|")) {
2207
+ line = line.slice(1);
2208
+ }
2209
+ if (line.endsWith("|") && !line.endsWith("\\|")) {
2210
+ line = line.slice(0, -1);
2211
+ }
2212
+ const cells = line.split(/(?<!\\)\|/);
2213
+ return cells.map((c) => c.trim().replace(/\\\|/g, "|"));
2214
+ }
2215
+ function tableAlignment(delimiter) {
2216
+ const left = delimiter.startsWith(":"), right = delimiter.endsWith(":");
2217
+ if (left && right) {
2218
+ return "center";
2219
+ }
2220
+ if (right) {
2221
+ return "right";
2222
+ }
2223
+ return left ? "left" : null;
2224
+ }
2225
+ function indentationOf(line) {
2226
+ const arr = /^ */.exec(line);
2227
+ return arr[0].length;
2228
+ }
2229
+ function splitListItems(raw) {
2230
+ const lines = raw.replace(/\t/g, " ").split(/\r?\n/);
2231
+ const items = [];
2232
+ for (let line of lines) {
2233
+ const current = items[items.length - 1];
2234
+ const marker = LISTMARKER.exec(line);
2235
+ if (marker != null && (current == null || marker[1].length < current.indent)) {
2236
+ const contentIndent = marker[0].length;
2237
+ const firstLine = line.slice(contentIndent);
2238
+ items.push({ indent: contentIndent, lines: [firstLine] });
2239
+ continue;
2240
+ }
2241
+ if (current == null) {
2242
+ continue;
2243
+ }
2244
+ const dedent = Math.min(current.indent, indentationOf(line));
2245
+ const content = line.slice(dedent);
2246
+ current.lines.push(content);
2247
+ }
2248
+ return items.map((i) => i.lines.join("\n").replace(/\s+$/, ""));
2249
+ }
2250
+ function decodeCode(code) {
2251
+ return (code ?? "").replace(/&lt;/g, "<");
2252
+ }
2253
+ var scanner = new Scanner();
2254
+ var MARKUP_SYNTAX = "markup";
1609
2255
  function regexMatchIndex(arr) {
1610
2256
  return arr?.index || void 0;
1611
2257
  }
@@ -1632,27 +2278,36 @@ function match(input, pattern, fn) {
1632
2278
  return null;
1633
2279
  }
1634
2280
  var COMMENT = /(<!--)([\s\S]*?)(-->|$)/;
1635
- var HR = /^ {0,3}(={3,}|_{3,}|-{3,})(\r?\n|$)/;
2281
+ var HR = /^ {0,3}(={3,}|(?:_[ \t]*){3,}|(?:-[ \t]*){3,}|(?:\*[ \t]*){3,})(\r?\n|$)/;
1636
2282
  var HEADING = /^ {0,3}(#{1,6})\s+([^\n]+)(\r?\n|$)+/;
1637
2283
  var HEADING1 = /^ {0,3}([^\n]+)(\r?\n=+(\r?\n|$))+/;
1638
2284
  var HEADING2 = /^ {0,3}([^\n]+)(\r?\n-+(\r?\n|$))+/;
1639
2285
  var CODEBLOCK = /^ {4,}.+(\r?\n {4,}.+)*(\r?\n|$)+/;
1640
2286
  var FENCES = /^ {0,3}``` *([^\n]*)\r?\n(([\s\S](?!\r?\n {0,3}```))*.(\r?\n)+) {0,3}```(\r?\n|$)+/;
1641
2287
  var BLOCKQUOTE = /^ {0,3}> *([^\n]+)(\r?\n {0,3}> *([^\n]*))*(\r?\n|$)+/;
1642
- var ULIST = /^( {0,3}([-+]).*\r?\n|$)((?!(?: {0,3}(?:\d+[.\)]|\r?\n\S))).*(\r?\n|$))*/;
1643
- var OLIST = /^( {0,3}(\d+[.\)]).*\r?\n|$)((?!(?: {0,3}(?:[+-]|\r?\n\S))).*(\r?\n|$))*/;
1644
- var LISTITEM = /^(?:[-+*]|\d+[.\)])/m;
1645
- var PARAGRAPH = /^(?! {4,})(.+(\n(?! {0,3}```)(?! {0,3}([-+]|\d+[.\)]))(?! {4,})(?! {0,3}>).+)*)/;
2288
+ var ULIST = /^( {0,3}([-+]|\*(?=[ \t])).*(\r?\n|$))((?!(?: ?\d+[.\)]|\r?\n\S)).*(\r?\n|$))*/;
2289
+ var OLIST = /^( {0,3}(\d+[.\)]).*(\r?\n|$))((?!(?: {0,2}(?:[-+]|\*[ \t])|\r?\n\S)).*(\r?\n|$))*/;
2290
+ var LISTMARKER = /^( *)([-+*]|\d+[.\)])([ \t]+|$)/;
2291
+ var TASK = /^\[([ xX])\][ \t]+/;
2292
+ var PARAGRAPH = /^(?! {4,})(?=[ \t]*\S)(.+(\n(?![ \t]*(?:\n|$))(?! {0,3}```)(?! {0,3}([-+]|\*[ \t]|\d+[.\)]))(?! {0,3}#{1,6}[ \t])(?! {4,})(?! {0,3}>).+)*)/;
1646
2293
  var REF = /^ {0,3}(!?)\[([^\]]+)\]: +(\S+)(?: +['"\(](.+)['"\)])?(\r?\n|$)+/;
1647
- var IMAGE_OR_LINK = /!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?(\[[^\[\]]*\]|\([^\(\)]*\))?/;
2294
+ var IMAGE_OR_LINK = /(?<!\\)!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?(\[[^\[\]]*\]|\([^\(\)]*\))?/;
1648
2295
  var EMPHASIZED_LINK = /(\*\*?|__?)(\[[^\]]*]\([^\)]+\))\1/;
1649
2296
  var CODE = /(?:(?<!\\)`)(.+?)(?:(?<!\\)`)/;
1650
- var EMPHASIZE = /(\*\*?|__?)((?!\1\s?)(?:(?!\1)[\S\s])*[^\s])\1/;
1651
- var STRIKE = /(~~?|__?)(?!\1\s?)([^\s][\s\S]*?(?!\1)[^\s])\1/;
2297
+ var EMPHASIZE = /(\*\*?)((?!\1\s?)(?:(?!\1)[\S\s])*[^\s])\1|(?<![A-Za-z0-9])(__?)((?!\3\s?)(?:(?!\3)[\S\s])*[^\s])\3(?![A-Za-z0-9])/;
2298
+ var STRIKE = /(~~?)(?!\1\s?)([^\s][\s\S]*?(?!\1)[^\s])\1/;
1652
2299
  var QUOTE = /(:")(?!":\s?)([^\s][\s\S]*?(?!":)[^\s])":/;
1653
2300
  var SPACE = /^\s+/;
1654
- var LINEBREAK = / {2,}\r?\n/;
2301
+ var BLOCK_SPACE = /^(?:[ \t]*\r?\n)+|^\s+/;
2302
+ var LINEBREAK = /(?: {2,}|\\)\r?\n/;
1655
2303
  var TEXT = /^[^\r\n]+/;
2304
+ var ESCAPE = /\\(&lt;|[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~])/;
2305
+ var ESCAPED_HTML = { "<": "&lt;", "&lt;": "&lt;", "&": "&amp;" };
2306
+ var AUTOLINK = /(?:<|&lt;)((?:https?|ftp|mailto):[^\s<>]+|[\w.+-]+@[\w-]+(?:\.[\w-]+)+)>/;
2307
+ var BARE_URL = /(?<![\w\/\\(\[<"'=;&@])(?:https?:\/\/|www\.)[^\s<>]*[^\s<>.,:;"'!?)\]*_~]/;
2308
+ var FOOTNOTE_REF = /\[\^([^\]\s]+)\]/;
2309
+ var FOOTNOTE_DEF = /^ {0,3}\[\^([^\]\s]+)\]: *([^\r\n]*(?:\r?\n {2,}[^\r\n]+)*)(\r?\n|$)+/;
2310
+ var TABLE = /^ {0,3}(\|?[^\r\n]*\|[^\r\n]*)\r?\n {0,3}(\|? *:?-+:? *(?:\| *:?-+:? *)*\|?) *(?:\r?\n|$)((?:(?! {0,3}(?:\r?\n|$))[^\r\n]*\|[^\r\n]*(?:\r?\n|$))*)/;
1656
2311
  var MARKDOWN_TYPES;
1657
2312
  (function(MARKDOWN_TYPES2) {
1658
2313
  MARKDOWN_TYPES2["Html"] = "html";
@@ -1677,6 +2332,11 @@ var MARKDOWN_TYPES;
1677
2332
  MARKDOWN_TYPES2["UnorderedList"] = "ul";
1678
2333
  MARKDOWN_TYPES2["ListItem"] = "listitem";
1679
2334
  MARKDOWN_TYPES2["Reference"] = "ref";
2335
+ MARKDOWN_TYPES2["Table"] = "table";
2336
+ MARKDOWN_TYPES2["TableRow"] = "tr";
2337
+ MARKDOWN_TYPES2["TableCell"] = "td";
2338
+ MARKDOWN_TYPES2["FootnoteReference"] = "fnref";
2339
+ MARKDOWN_TYPES2["FootnoteDefinition"] = "fndef";
1680
2340
  })(MARKDOWN_TYPES || (MARKDOWN_TYPES = {}));
1681
2341
  var MARKDOWN_RULES;
1682
2342
  (function(MARKDOWN_RULES2) {
@@ -1699,6 +2359,12 @@ var MARKDOWN_RULES;
1699
2359
  MARKDOWN_RULES2[MARKDOWN_RULES2["Quote"] = 16] = "Quote";
1700
2360
  MARKDOWN_RULES2[MARKDOWN_RULES2["Code"] = 17] = "Code";
1701
2361
  MARKDOWN_RULES2[MARKDOWN_RULES2["LineBreak"] = 18] = "LineBreak";
2362
+ MARKDOWN_RULES2[MARKDOWN_RULES2["FootnoteDefinition"] = 19] = "FootnoteDefinition";
2363
+ MARKDOWN_RULES2[MARKDOWN_RULES2["Table"] = 20] = "Table";
2364
+ MARKDOWN_RULES2[MARKDOWN_RULES2["Escape"] = 21] = "Escape";
2365
+ MARKDOWN_RULES2[MARKDOWN_RULES2["AutoLink"] = 22] = "AutoLink";
2366
+ MARKDOWN_RULES2[MARKDOWN_RULES2["FootnoteReference"] = 23] = "FootnoteReference";
2367
+ MARKDOWN_RULES2[MARKDOWN_RULES2["BareUrl"] = 24] = "BareUrl";
1702
2368
  MARKDOWN_RULES2[MARKDOWN_RULES2["Text"] = 254] = "Text";
1703
2369
  MARKDOWN_RULES2[MARKDOWN_RULES2["Space"] = 255] = "Space";
1704
2370
  })(MARKDOWN_RULES || (MARKDOWN_RULES = {}));
@@ -1715,7 +2381,7 @@ function getGrammar(extra = []) {
1715
2381
  text: arr[2]
1716
2382
  }];
1717
2383
  if (index > 0) {
1718
- const left = input.substr(0, index), tokens = lexer.tokenize(left, blockRules);
2384
+ const left = input.substr(0, index), tokens = lexer.tokenize(left, topRules);
1719
2385
  Array.prototype.unshift.apply(output, tokens);
1720
2386
  }
1721
2387
  return output;
@@ -1736,6 +2402,20 @@ function getGrammar(extra = []) {
1736
2402
  title
1737
2403
  }];
1738
2404
  })
2405
+ },
2406
+ // footnote definition (rendered at the end of the document, see HtmlRenderer)
2407
+ [MARKDOWN_RULES.FootnoteDefinition]: {
2408
+ exec: (input, lexer) => match(input, FOOTNOTE_DEF, (arr) => {
2409
+ const raw = arr[0], id = normalizeReference(arr[1]), text = arr[2].replace(/\r?\n {2,}/g, " ");
2410
+ return [{
2411
+ type: MARKDOWN_TYPES.FootnoteDefinition,
2412
+ index: regexMatchIndex(arr),
2413
+ raw,
2414
+ text,
2415
+ id,
2416
+ tokens: lexer.tokenize(text, inlineRules)
2417
+ }];
2418
+ })
1739
2419
  }
1740
2420
  };
1741
2421
  const blockExtra = [], inlineExtra = [], codeExtra = {};
@@ -1798,7 +2478,9 @@ function getGrammar(extra = []) {
1798
2478
  // link/image
1799
2479
  [MARKDOWN_RULES.ImageOrLink]: {
1800
2480
  exec: (input, lexer) => inlineMatch(input, IMAGE_OR_LINK, lexer, (arr) => {
1801
- const index = regexMatchIndex(arr), raw = arr[0], image = raw.charAt(0) === "!", text = arr[1], url = extractUrl(arr[2]), ref = normalizeReference(extractReference(arr[2]) ?? text);
2481
+ const index = regexMatchIndex(arr), raw = arr[0], image = raw.charAt(0) === "!", text = arr[1], destination = extractUrl(arr[2]), reference = extractReference(arr[2]) ?? text, ref = normalizeReference(reference);
2482
+ const { url, title } = splitUrlAndTitle(destination);
2483
+ const tokens = lexer.tokenize(text, inlineRules);
1802
2484
  if (image) {
1803
2485
  return [{
1804
2486
  index,
@@ -1806,26 +2488,83 @@ function getGrammar(extra = []) {
1806
2488
  raw,
1807
2489
  text,
1808
2490
  src: url,
2491
+ title,
1809
2492
  ref,
1810
- tokens: lexer.tokenize(text, inlineRules)
1811
- }];
1812
- } else {
1813
- return [{
1814
- index,
1815
- type: url ? MARKDOWN_TYPES.Link : MARKDOWN_TYPES.LinkLike,
1816
- raw,
1817
- text,
1818
- href: url,
1819
- ref,
1820
- tokens: lexer.tokenize(text, inlineRules)
2493
+ tokens
1821
2494
  }];
1822
2495
  }
2496
+ return [{
2497
+ index,
2498
+ type: url ? MARKDOWN_TYPES.Link : MARKDOWN_TYPES.LinkLike,
2499
+ raw,
2500
+ text,
2501
+ href: url,
2502
+ title,
2503
+ ref,
2504
+ tokens
2505
+ }];
2506
+ })
2507
+ },
2508
+ // backslash escapes: the escaped character is plain text
2509
+ [MARKDOWN_RULES.Escape]: {
2510
+ exec: (input, lexer) => inlineMatch(input, ESCAPE, lexer, (arr) => {
2511
+ const text = ESCAPED_HTML[arr[1]] ?? arr[1];
2512
+ return [{
2513
+ index: regexMatchIndex(arr),
2514
+ raw: arr[0],
2515
+ text,
2516
+ type: MARKDOWN_TYPES.Text
2517
+ }];
2518
+ })
2519
+ },
2520
+ // <https://…>, <user@domain>
2521
+ [MARKDOWN_RULES.AutoLink]: {
2522
+ exec: (input, lexer) => inlineMatch(input, AUTOLINK, lexer, (arr) => {
2523
+ const text = arr[1];
2524
+ const isEmail = !/^[a-z]+:/i.test(text);
2525
+ const href = isEmail ? "mailto:" + text : text;
2526
+ return [{
2527
+ index: regexMatchIndex(arr),
2528
+ raw: arr[0],
2529
+ text,
2530
+ href,
2531
+ type: MARKDOWN_TYPES.Link,
2532
+ tokens: [{ type: MARKDOWN_TYPES.Text, raw: text, text }]
2533
+ }];
2534
+ })
2535
+ },
2536
+ // bare https://… or www.… urls
2537
+ [MARKDOWN_RULES.BareUrl]: {
2538
+ exec: (input, lexer) => inlineMatch(input, BARE_URL, lexer, (arr) => {
2539
+ const text = arr[0];
2540
+ const href = /^www\./i.test(text) ? "http://" + text : text;
2541
+ return [{
2542
+ index: regexMatchIndex(arr),
2543
+ raw: text,
2544
+ text,
2545
+ href,
2546
+ type: MARKDOWN_TYPES.Link,
2547
+ tokens: [{ type: MARKDOWN_TYPES.Text, raw: text, text }]
2548
+ }];
2549
+ })
2550
+ },
2551
+ // [^footnote]
2552
+ [MARKDOWN_RULES.FootnoteReference]: {
2553
+ exec: (input, lexer) => inlineMatch(input, FOOTNOTE_REF, lexer, (arr) => {
2554
+ const id = normalizeReference(arr[1]);
2555
+ return [{
2556
+ index: regexMatchIndex(arr),
2557
+ raw: arr[0],
2558
+ text: arr[1],
2559
+ id,
2560
+ type: MARKDOWN_TYPES.FootnoteReference
2561
+ }];
1823
2562
  })
1824
2563
  },
1825
2564
  // code
1826
2565
  [MARKDOWN_RULES.Code]: {
1827
2566
  exec: (input, lexer) => inlineMatch(input, CODE, lexer, (arr) => {
1828
- const text = htmlEncode(arr[1]);
2567
+ const text = htmlEncode2(arr[1]);
1829
2568
  return [{
1830
2569
  type: MARKDOWN_TYPES.Code,
1831
2570
  raw: arr[0],
@@ -1853,10 +2592,11 @@ function getGrammar(extra = []) {
1853
2592
  // italic/bold
1854
2593
  [MARKDOWN_RULES.Emphasize]: {
1855
2594
  exec: (input, lexer) => inlineMatch(input, EMPHASIZE, lexer, (arr) => {
1856
- if (arr.length < 3 || NullChecker.isNullOrEmpty(arr[2])) {
2595
+ const marker = arr[1] ?? arr[3], text = arr[2] ?? arr[4];
2596
+ if (NullChecker.isNullOrEmpty(text)) {
1857
2597
  return null;
1858
2598
  }
1859
- const type = arr[1].length > 1 ? MARKDOWN_TYPES.Bold : MARKDOWN_TYPES.Italic, text = arr[2];
2599
+ const type = marker.length > 1 ? MARKDOWN_TYPES.Bold : MARKDOWN_TYPES.Italic;
1860
2600
  return [{
1861
2601
  index: regexMatchIndex(arr),
1862
2602
  type,
@@ -1932,7 +2672,19 @@ function getGrammar(extra = []) {
1932
2672
  inPlaceInlineExec(input, output, lexer);
1933
2673
  return output;
1934
2674
  };
1935
- const inlineRules = Object.values(inline);
2675
+ const inlineRules = [
2676
+ inline[MARKDOWN_RULES.FootnoteReference],
2677
+ inline[MARKDOWN_RULES.EmphasizedLink],
2678
+ inline[MARKDOWN_RULES.ImageOrLink],
2679
+ inline[MARKDOWN_RULES.Escape],
2680
+ inline[MARKDOWN_RULES.AutoLink],
2681
+ inline[MARKDOWN_RULES.Emphasize],
2682
+ inline[MARKDOWN_RULES.StrikeThrough],
2683
+ inline[MARKDOWN_RULES.Quote],
2684
+ inline[MARKDOWN_RULES.Code],
2685
+ inline[MARKDOWN_RULES.LineBreak],
2686
+ inline[MARKDOWN_RULES.BareUrl]
2687
+ ];
1936
2688
  Array.prototype.push.apply(inlineRules, inlineExtra);
1937
2689
  inlineRules.push(inlinelowpriority[MARKDOWN_RULES.Text], inlinelowpriority[MARKDOWN_RULES.Space]);
1938
2690
  const getLangGrammar = (lang) => {
@@ -1947,7 +2699,10 @@ function getGrammar(extra = []) {
1947
2699
  // paragraph
1948
2700
  [MARKDOWN_RULES.Paragraph]: {
1949
2701
  exec: (input, lexer) => match(input, PARAGRAPH, (arr) => {
1950
- const raw = arr[0], text = raw;
2702
+ const raw = arr[0], text = raw.replace(/^[ \t]+/gm, "");
2703
+ if (text.trim().length === 0) {
2704
+ return null;
2705
+ }
1951
2706
  return [{
1952
2707
  type: MARKDOWN_TYPES.Paragraph,
1953
2708
  raw,
@@ -1957,12 +2712,56 @@ function getGrammar(extra = []) {
1957
2712
  }];
1958
2713
  })
1959
2714
  },
1960
- // sparse lines
1961
- [MARKDOWN_RULES.Space]: inlinelowpriority[MARKDOWN_RULES.Space]
2715
+ // blank lines (the indentation of the following line is kept: it matters to indented code blocks)
2716
+ [MARKDOWN_RULES.Space]: {
2717
+ exec: (input) => match(input, BLOCK_SPACE, (arr) => {
2718
+ const raw = arr[0];
2719
+ return [{
2720
+ type: MARKDOWN_TYPES.Space,
2721
+ raw,
2722
+ text: raw
2723
+ }];
2724
+ })
2725
+ }
1962
2726
  };
1963
2727
  const tokenizeListItem = (text, lexer) => {
1964
- const grammar = !/^ {0,3}(`{3,}|$|>|[+-]\s|\d+[.\)])/m.test(text) ? inlineRules : blockRules;
1965
- return lexer.tokenize(text, grammar);
2728
+ const needsBlocks = /^ {0,3}(`{3,}|$|>|[-+*]\s|\d+[.\)]|#{1,6}\s|\|)/m.test(text);
2729
+ if (!needsBlocks) {
2730
+ return lexer.tokenize(text, inlineRules);
2731
+ }
2732
+ const tokens = lexer.tokenize(text, blockRules);
2733
+ const first = tokens[0];
2734
+ const tight = !/\n[ \t]*\n/.test(text);
2735
+ if (!tight || first?.type !== MARKDOWN_TYPES.Paragraph) {
2736
+ return tokens;
2737
+ }
2738
+ const inner = first.tokens ?? [];
2739
+ const rest = tokens.slice(1);
2740
+ return inner.concat(rest);
2741
+ };
2742
+ const tokenizeListItems = (raw, lexer) => {
2743
+ const items = splitListItems(raw);
2744
+ const nonEmpty = items.filter((i) => !NullChecker.isNullOrEmpty(i));
2745
+ return nonEmpty.map((item) => {
2746
+ const task = TASK.exec(item);
2747
+ const text = task ? item.slice(task[0].length) : item;
2748
+ const tokens = tokenizeListItem(text, lexer);
2749
+ if (task == null) {
2750
+ return { type: MARKDOWN_TYPES.ListItem, raw: item, text, tokens };
2751
+ }
2752
+ const checked = task[1] !== " ";
2753
+ return { type: MARKDOWN_TYPES.ListItem, raw: item, text, tokens, task: true, checked };
2754
+ });
2755
+ };
2756
+ const tokenizeTableRow = (cells, align, header, lexer) => {
2757
+ const tokens = align.map((cellAlign, i) => {
2758
+ const text = cells[i] ?? "";
2759
+ const cellTokens = lexer.tokenize(text, inlineRules);
2760
+ return { type: MARKDOWN_TYPES.TableCell, raw: text, text, header, align: cellAlign, tokens: cellTokens };
2761
+ });
2762
+ const raw = cells.join(" | ");
2763
+ const row = { type: MARKDOWN_TYPES.TableRow, raw, text: raw, header, tokens };
2764
+ return row;
1966
2765
  };
1967
2766
  const block = {
1968
2767
  // hr
@@ -1979,7 +2778,7 @@ function getGrammar(extra = []) {
1979
2778
  // headings
1980
2779
  [MARKDOWN_RULES.Heading]: {
1981
2780
  exec: (input, lexer) => match(input, HEADING, (arr) => {
1982
- const text = arr[2];
2781
+ const text = arr[2].replace(/[ \t]+#+[ \t]*$/, "");
1983
2782
  return [{
1984
2783
  type: MARKDOWN_TYPES.Heading,
1985
2784
  raw: arr[0],
@@ -2019,79 +2818,104 @@ function getGrammar(extra = []) {
2019
2818
  // codeblock
2020
2819
  [MARKDOWN_RULES.CodeBlock]: {
2021
2820
  exec: (input, lexer) => match(input, CODEBLOCK, (arr) => {
2022
- const raw = arr[0], text = htmlEncode(raw);
2821
+ const raw = arr[0], code = raw.replace(/^ {4}/gm, "").replace(/\s+$/, ""), text = htmlEncode2(code);
2822
+ if (code.length === 0) {
2823
+ return null;
2824
+ }
2023
2825
  return [{
2024
2826
  type: MARKDOWN_TYPES.CodeBlock,
2025
2827
  raw,
2026
2828
  text,
2027
- tokens: lexer.tokenize(text, [])
2829
+ tokens: lexer.tokenize(text, getLangGrammar(""))
2028
2830
  }];
2029
2831
  })
2030
2832
  },
2031
2833
  // codeblock
2032
2834
  [MARKDOWN_RULES.Fences]: {
2033
2835
  exec: (input, lexer) => match(input, FENCES, (arr) => {
2034
- const text = htmlEncode(arr[2]), lang = arr[1]?.toLowerCase();
2836
+ const info = (arr[1] ?? "").trim(), words = info.split(/\s+/), lang = words[0].toLowerCase();
2837
+ const syntax = lang in codeExtra ? null : Syntaxes.get(lang);
2838
+ if (syntax == null) {
2839
+ const text = htmlEncode2(arr[2]);
2840
+ return [{
2841
+ type: MARKDOWN_TYPES.CodeBlock,
2842
+ raw: arr[0],
2843
+ text,
2844
+ lang,
2845
+ tokens: lexer.tokenize(text, getLangGrammar(lang))
2846
+ }];
2847
+ }
2848
+ const code = decodeCode(arr[2]);
2849
+ const tokens = scanner.tokenize(code, syntax);
2035
2850
  return [{
2036
2851
  type: MARKDOWN_TYPES.CodeBlock,
2037
2852
  raw: arr[0],
2038
- text,
2853
+ text: code,
2039
2854
  lang,
2040
- tokens: lexer.tokenize(text, getLangGrammar(lang))
2855
+ syntax: syntax.name,
2856
+ highlighted: true,
2857
+ tokens
2041
2858
  }];
2042
2859
  })
2043
2860
  },
2044
2861
  // blockquote
2045
2862
  [MARKDOWN_RULES.BlockQuote]: {
2046
2863
  exec: (input, lexer) => match(input, BLOCKQUOTE, (arr) => {
2047
- const raw = arr[0], text = raw.replace(/^ {0,3}> */gm, "");
2864
+ const raw = arr[0], text = raw.replace(/^ {0,3}> ?/gm, "");
2048
2865
  return [{
2049
2866
  type: MARKDOWN_TYPES.BlockQuote,
2050
2867
  raw,
2051
2868
  text,
2052
- // recursion
2053
- tokens: lexer.tokenize(text, [
2054
- lowpriority[MARKDOWN_RULES.Paragraph],
2055
- lowpriority[MARKDOWN_RULES.Space]
2056
- ])
2869
+ // recursion: any block (nested quotes, lists, code…)
2870
+ tokens: lexer.tokenize(text, blockRules)
2057
2871
  }];
2058
2872
  })
2059
2873
  },
2060
2874
  // lists
2061
2875
  [MARKDOWN_RULES.OrderedList]: {
2062
2876
  exec: (input, lexer) => match(input, OLIST, (arr) => {
2063
- const raw = arr[0], items = raw.replace(/^ {0,3}/gm, "").split(LISTITEM).filter((i) => !NullChecker.isNullOrEmpty(i)).map((i) => i.trim());
2877
+ const raw = arr[0], startMatch = /\d+/.exec(raw), start = parseInt(startMatch[0]), tokens = tokenizeListItems(raw, lexer);
2064
2878
  return [{
2065
2879
  type: MARKDOWN_TYPES.OrderedList,
2066
- start: parseInt(/\d/.exec(arr[0])[0]),
2880
+ start,
2067
2881
  raw,
2068
2882
  text: raw,
2069
- tokens: items.map((i) => {
2070
- return {
2071
- type: MARKDOWN_TYPES.ListItem,
2072
- raw: i,
2073
- text: i,
2074
- tokens: tokenizeListItem(i, lexer)
2075
- };
2076
- })
2883
+ tokens
2077
2884
  }];
2078
2885
  })
2079
2886
  },
2080
2887
  [MARKDOWN_RULES.UnorderedList]: {
2081
2888
  exec: (input, lexer) => match(input, ULIST, (arr) => {
2082
- const raw = arr[0], items = raw.replace(/^ {0,3}/gm, "").split(LISTITEM).filter((i) => !NullChecker.isNullOrEmpty(i)).map((i) => i.trim());
2889
+ const raw = arr[0], tokens = tokenizeListItems(raw, lexer);
2083
2890
  return [{
2084
2891
  type: MARKDOWN_TYPES.UnorderedList,
2085
2892
  raw,
2086
2893
  text: raw,
2087
- tokens: items.map((i) => {
2088
- return {
2089
- type: MARKDOWN_TYPES.ListItem,
2090
- raw: i,
2091
- text: i,
2092
- tokens: tokenizeListItem(i, lexer)
2093
- };
2094
- })
2894
+ tokens
2895
+ }];
2896
+ })
2897
+ },
2898
+ // GFM tables
2899
+ [MARKDOWN_RULES.Table]: {
2900
+ exec: (input, lexer) => match(input, TABLE, (arr) => {
2901
+ const headers = splitTableCells(arr[1]), delimiters = splitTableCells(arr[2]);
2902
+ if (headers.length !== delimiters.length) {
2903
+ return null;
2904
+ }
2905
+ const align = delimiters.map(tableAlignment);
2906
+ const bodyLines = arr[3].split(/\r?\n/).filter((l) => l.trim().length > 0);
2907
+ const headerRow = tokenizeTableRow(headers, align, true, lexer);
2908
+ const bodyRows = bodyLines.map((line) => {
2909
+ const cells = splitTableCells(line);
2910
+ return tokenizeTableRow(cells, align, false, lexer);
2911
+ });
2912
+ const rows = [headerRow].concat(bodyRows);
2913
+ return [{
2914
+ type: MARKDOWN_TYPES.Table,
2915
+ raw: arr[0],
2916
+ text: arr[0],
2917
+ align,
2918
+ tokens: rows
2095
2919
  }];
2096
2920
  })
2097
2921
  }
@@ -2099,23 +2923,43 @@ function getGrammar(extra = []) {
2099
2923
  const blockRules = Object.values(block);
2100
2924
  Array.prototype.push.apply(blockRules, blockExtra);
2101
2925
  blockRules.push(lowpriority[MARKDOWN_RULES.Paragraph], lowpriority[MARKDOWN_RULES.Space]);
2102
- return [
2926
+ const topRules = [
2103
2927
  // comment first
2104
2928
  inert[MARKDOWN_RULES.Comment],
2929
+ // (before references: `[^id]: …` would match them too)
2930
+ inert[MARKDOWN_RULES.FootnoteDefinition],
2105
2931
  inert[MARKDOWN_RULES.Reference]
2106
2932
  ].concat(
2107
2933
  // block rules contain recursive inline rules (at least)
2108
2934
  blockRules
2109
2935
  );
2936
+ return topRules;
2110
2937
  }
2111
2938
  var CARRIAGE_RETURN_PLACEHOLDER = "\0";
2112
2939
  var TRIM_INSIDE = /[ \r\n]*\0+[ \r\n]*/g;
2113
2940
  function trim(input) {
2114
2941
  return input?.replace(TRIM_INSIDE, "\n").trim();
2115
2942
  }
2943
+ function titleAttribute(title) {
2944
+ if (NullChecker.isNullOrEmpty(title)) {
2945
+ return "";
2946
+ }
2947
+ const encoded = attributeEncode(title);
2948
+ return ` title="${encoded}"`;
2949
+ }
2950
+ function alignAttribute(align) {
2951
+ if (align == null) {
2952
+ return "";
2953
+ }
2954
+ return ` style="text-align: ${align}"`;
2955
+ }
2116
2956
  var HtmlRenderer = class {
2117
2957
  constructor(_extraItemRender = (token, __) => token?.text || "") {
2118
2958
  this._extraItemRender = _extraItemRender;
2959
+ this.#references = [];
2960
+ this.#footnotes = /* @__PURE__ */ new Map();
2961
+ this.#footnoteOrder = [];
2962
+ this.#highlighter = new HighlightRenderer();
2119
2963
  this._renderContent = (token) => {
2120
2964
  const children = token.tokens;
2121
2965
  if (NullChecker.isNullOrEmpty(children)) {
@@ -2124,10 +2968,143 @@ var HtmlRenderer = class {
2124
2968
  return this._render(children);
2125
2969
  };
2126
2970
  }
2971
+ /** Link/image reference definitions of the whole document (they may be referenced from any depth). */
2972
+ #references;
2973
+ /** Footnote definitions by id, and the order of their first reference (their numbering). */
2974
+ #footnotes;
2975
+ #footnoteOrder;
2976
+ #highlighter;
2977
+ /** Collects the reference and footnote definitions of the whole tree. */
2978
+ _collectDefinitions(tree) {
2979
+ for (let token of tree ?? []) {
2980
+ if (token?.type === MARKDOWN_TYPES.Reference) {
2981
+ this.#references.push(token);
2982
+ }
2983
+ if (token?.type === MARKDOWN_TYPES.FootnoteDefinition && !this.#footnotes.has(token["id"])) {
2984
+ this.#footnotes.set(token["id"], token);
2985
+ }
2986
+ this._collectDefinitions(token?.tokens);
2987
+ }
2988
+ }
2989
+ _findReference(ref, image) {
2990
+ if (NullChecker.isNullOrEmpty(ref)) {
2991
+ return void 0;
2992
+ }
2993
+ const key = ref.toLowerCase();
2994
+ return this.#references.find((t) => t.image === true === image && t.id?.toLowerCase() === key);
2995
+ }
2996
+ _renderCodeBlock(token) {
2997
+ const R = CARRIAGE_RETURN_PLACEHOLDER;
2998
+ const lang = token["lang"];
2999
+ if (token["highlighted"] !== true) {
3000
+ const classAttribute = lang ? ' class="' + lang + '"' : "";
3001
+ const content = this._renderContent(token);
3002
+ return `<pre>${R}<code${classAttribute}>${content}</code>${R}</pre>${R}`;
3003
+ }
3004
+ const classes = [lang, "code-highlighted"];
3005
+ if (token["syntax"] === MARKUP_SYNTAX) {
3006
+ classes.push("code-markup");
3007
+ }
3008
+ const classList = attributeEncode(classes.join(" "));
3009
+ const highlighted = this.#highlighter.render(token.tokens);
3010
+ return `<pre>${R}<code class="${classList}">${highlighted}</code>${R}</pre>${R}`;
3011
+ }
3012
+ _renderImage(token) {
3013
+ let src = token.src, title = token.title;
3014
+ if (!src) {
3015
+ const reference = this._findReference(token.ref, true);
3016
+ src = reference?.url;
3017
+ title = reference?.title;
3018
+ }
3019
+ if (!src) {
3020
+ const content = this._renderContent(token);
3021
+ return `![${content}]`;
3022
+ }
3023
+ const titleAttr = titleAttribute(title);
3024
+ return `<img src="${src}" alt="${token.text}"${titleAttr} />`;
3025
+ }
3026
+ _renderLink(token) {
3027
+ let href = token.href, title = token.title;
3028
+ if (!href) {
3029
+ const reference = this._findReference(token.ref, false);
3030
+ href = reference?.url;
3031
+ title = reference?.title;
3032
+ }
3033
+ const content = this._renderContent(token);
3034
+ if (!href) {
3035
+ return `[${content}]`;
3036
+ }
3037
+ const titleAttr = titleAttribute(title);
3038
+ return `<a href="${href}"${titleAttr}>${content}</a>`;
3039
+ }
3040
+ _renderListItem(token) {
3041
+ const R = CARRIAGE_RETURN_PLACEHOLDER;
3042
+ const content = this._renderContent(token);
3043
+ if (token["task"] !== true) {
3044
+ return ` <li>${content}</li>${R}`;
3045
+ }
3046
+ const checked = token["checked"] === true ? " checked" : "";
3047
+ return ` <li class="task-list-item"><input type="checkbox" disabled${checked} /> ${content}</li>${R}`;
3048
+ }
3049
+ _renderTableRow(row) {
3050
+ const R = CARRIAGE_RETURN_PLACEHOLDER;
3051
+ let cells = "";
3052
+ for (let cell of row.tokens ?? []) {
3053
+ const tag = cell["header"] === true ? "th" : "td";
3054
+ const align = alignAttribute(cell["align"]);
3055
+ const content = this._renderContent(cell);
3056
+ cells += `<${tag}${align}>${content}</${tag}>`;
3057
+ }
3058
+ return `<tr>${cells}</tr>${R}`;
3059
+ }
3060
+ _renderTable(token) {
3061
+ const R = CARRIAGE_RETURN_PLACEHOLDER;
3062
+ const rows = token.tokens ?? [];
3063
+ const headerRows = rows.filter((r) => r["header"] === true);
3064
+ const bodyRows = rows.filter((r) => r["header"] !== true);
3065
+ const head = headerRows.map((r) => this._renderTableRow(r)).join("");
3066
+ let html = `<table>${R}<thead>${R}${head}</thead>${R}`;
3067
+ if (bodyRows.length > 0) {
3068
+ const body = bodyRows.map((r) => this._renderTableRow(r)).join("");
3069
+ html += `<tbody>${R}${body}</tbody>${R}`;
3070
+ }
3071
+ return html + `</table>${R}`;
3072
+ }
3073
+ _renderFootnoteReference(token) {
3074
+ const id = token["id"];
3075
+ if (!this.#footnotes.has(id)) {
3076
+ return `[^${token.text}]`;
3077
+ }
3078
+ const order = this.#footnoteOrder;
3079
+ const isFirst = !order.includes(id);
3080
+ if (isFirst) {
3081
+ order.push(id);
3082
+ }
3083
+ const number = order.indexOf(id) + 1;
3084
+ const anchorId = isFirst ? ` id="fnref-${id}"` : "";
3085
+ return `<sup class="footnote-ref"><a href="#fn-${id}"${anchorId}>${number}</a></sup>`;
3086
+ }
3087
+ /** Renders the referenced footnotes, in order of first reference (definitions may reference further footnotes). */
3088
+ _renderFootnotes() {
3089
+ const order = this.#footnoteOrder;
3090
+ if (order.length === 0) {
3091
+ return "";
3092
+ }
3093
+ const R = CARRIAGE_RETURN_PLACEHOLDER;
3094
+ let items = "";
3095
+ for (let i = 0; i < order.length; i++) {
3096
+ const id = order[i];
3097
+ const definition = this.#footnotes.get(id);
3098
+ const content = this._renderContent(definition);
3099
+ items += `<li id="fn-${id}">${content} <a href="#fnref-${id}" class="footnote-backref">&#8617;</a></li>${R}`;
3100
+ }
3101
+ return `<section class="footnotes">${R}<ol>${R}${items}</ol>${R}</section>${R}`;
3102
+ }
2127
3103
  _rendeItem(token, allTokens) {
2128
3104
  const r = this._renderContent, R = CARRIAGE_RETURN_PLACEHOLDER;
2129
3105
  switch (token?.type) {
2130
3106
  case MARKDOWN_TYPES.Reference:
3107
+ case MARKDOWN_TYPES.FootnoteDefinition:
2131
3108
  return "";
2132
3109
  case MARKDOWN_TYPES.Html:
2133
3110
  return token.raw;
@@ -2137,8 +3114,7 @@ ${r(token)}</blockquote>${R}`;
2137
3114
  case MARKDOWN_TYPES.Bold:
2138
3115
  return `<b>${r(token)}</b>`;
2139
3116
  case MARKDOWN_TYPES.CodeBlock:
2140
- const lang = token["lang"];
2141
- return `<pre>${R}<code${lang ? ' class="' + lang + '"' : ""}>${r(token)}</code>${R}</pre>${R}`;
3117
+ return this._renderCodeBlock(token);
2142
3118
  case MARKDOWN_TYPES.Code:
2143
3119
  return `<code>${r(token)}</code>`;
2144
3120
  case MARKDOWN_TYPES.HorizontalRule:
@@ -2148,17 +3124,7 @@ ${r(token)}</blockquote>${R}`;
2148
3124
  return `<h${hlevel} id="${hid}">${r(token)}</h${hlevel}>${R}`;
2149
3125
  case MARKDOWN_TYPES.Image:
2150
3126
  case MARKDOWN_TYPES.ImageLike:
2151
- const itk = token;
2152
- let isrc = itk.src, ititle = "";
2153
- const alt = itk.text, iref = itk.ref;
2154
- if (!isrc && iref) {
2155
- const ireftk = allTokens.find((t) => t.type === MARKDOWN_TYPES.Reference && t["image"] === true && t["id"]?.toLowerCase() === iref.toLowerCase());
2156
- if (ireftk) {
2157
- isrc = ireftk.url;
2158
- ititle = ireftk.title ?? "";
2159
- }
2160
- }
2161
- return isrc ? `<img src="${isrc}" alt="${alt}"${ititle ? ' title="' + ititle + '"' : ""} />` : `![${r(token)}]`;
3127
+ return this._renderImage(token);
2162
3128
  case MARKDOWN_TYPES.Italic:
2163
3129
  return `<i>${r(token)}</i>`;
2164
3130
  case MARKDOWN_TYPES.StrikeThrough:
@@ -2174,20 +3140,14 @@ ${r(token)}</ol>${R}`;
2174
3140
  return `<ul>
2175
3141
  ${r(token)}</ul>${R}`;
2176
3142
  case MARKDOWN_TYPES.ListItem:
2177
- return ` <li>${r(token)}</li>${R}`;
3143
+ return this._renderListItem(token);
2178
3144
  case MARKDOWN_TYPES.Link:
2179
3145
  case MARKDOWN_TYPES.LinkLike:
2180
- const atk = token;
2181
- let ahref = atk.href, atitle = "";
2182
- const aref = atk.ref;
2183
- if (!ahref && aref) {
2184
- const areftk = allTokens.find((t) => t.type === MARKDOWN_TYPES.Reference && t["image"] !== true && t["id"]?.toLowerCase() === aref.toLowerCase());
2185
- if (areftk) {
2186
- ahref = areftk.url;
2187
- atitle = areftk.title ?? "";
2188
- }
2189
- }
2190
- return ahref ? `<a href="${ahref}"${atitle ? ' title="' + atitle + '"' : ""}>${r(token)}</a>` : `[${r(token)}]`;
3146
+ return this._renderLink(token);
3147
+ case MARKDOWN_TYPES.Table:
3148
+ return this._renderTable(token);
3149
+ case MARKDOWN_TYPES.FootnoteReference:
3150
+ return this._renderFootnoteReference(token);
2191
3151
  case MARKDOWN_TYPES.Paragraph:
2192
3152
  return `<p>${r(token)}</p>${R}`;
2193
3153
  case MARKDOWN_TYPES.Text:
@@ -2204,7 +3164,13 @@ ${r(token)}</ul>${R}`;
2204
3164
  return acc;
2205
3165
  }
2206
3166
  render(tree) {
2207
- return trim(this._render(tree));
3167
+ this.#references = [];
3168
+ this.#footnotes.clear();
3169
+ this.#footnoteOrder = [];
3170
+ this._collectDefinitions(tree);
3171
+ const body = this._render(tree);
3172
+ const footnotes = this._renderFootnotes();
3173
+ return trim(body + footnotes);
2208
3174
  }
2209
3175
  };
2210
3176
  var TokenRenderer = class {
@@ -2244,13 +3210,582 @@ var Parser2 = class extends Parser {
2244
3210
  return JSON.parse(json);
2245
3211
  }
2246
3212
  parse(input, grammarOrRenderer = getGrammar(), renderer = new HtmlRenderer()) {
3213
+ const normalized = (input ?? "").replace(/\r\n?/g, "\n");
2247
3214
  if (isRenderer(grammarOrRenderer)) {
2248
- return super.parse(input, getGrammar(), grammarOrRenderer);
2249
- } else {
2250
- return super.parse(input, grammarOrRenderer, renderer);
3215
+ const grammar = getGrammar();
3216
+ return super.parse(normalized, grammar, grammarOrRenderer);
2251
3217
  }
3218
+ return super.parse(normalized, grammarOrRenderer, renderer);
3219
+ }
3220
+ };
3221
+
3222
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/javascript.js
3223
+ var DIVISION_AFTER_TYPES = ["identifier", "number", "string", "regex"];
3224
+ var DIVISION_AFTER_TEXTS = [")", "]", "}", "this", "super", "null", "undefined", "true", "false", "++", "--"];
3225
+ var JAVASCRIPT_KEYWORDS = [
3226
+ // JavaScript
3227
+ "async",
3228
+ "await",
3229
+ "break",
3230
+ "case",
3231
+ "catch",
3232
+ "class",
3233
+ "const",
3234
+ "continue",
3235
+ "debugger",
3236
+ "default",
3237
+ "delete",
3238
+ "do",
3239
+ "else",
3240
+ "enum",
3241
+ "export",
3242
+ "extends",
3243
+ "false",
3244
+ "finally",
3245
+ "for",
3246
+ "from",
3247
+ "function",
3248
+ "get",
3249
+ "if",
3250
+ "import",
3251
+ "in",
3252
+ "instanceof",
3253
+ "let",
3254
+ "new",
3255
+ "null",
3256
+ "of",
3257
+ "return",
3258
+ "set",
3259
+ "static",
3260
+ "super",
3261
+ "switch",
3262
+ "this",
3263
+ "throw",
3264
+ "true",
3265
+ "try",
3266
+ "typeof",
3267
+ "undefined",
3268
+ "var",
3269
+ "void",
3270
+ "while",
3271
+ "with",
3272
+ "yield",
3273
+ // TypeScript
3274
+ "abstract",
3275
+ "accessor",
3276
+ "any",
3277
+ "as",
3278
+ "asserts",
3279
+ "bigint",
3280
+ "boolean",
3281
+ "declare",
3282
+ "implements",
3283
+ "infer",
3284
+ "interface",
3285
+ "is",
3286
+ "keyof",
3287
+ "module",
3288
+ "namespace",
3289
+ "never",
3290
+ "number",
3291
+ "object",
3292
+ "override",
3293
+ "package",
3294
+ "private",
3295
+ "protected",
3296
+ "public",
3297
+ "readonly",
3298
+ "satisfies",
3299
+ "string",
3300
+ "symbol",
3301
+ "type",
3302
+ "unique",
3303
+ "unknown"
3304
+ ];
3305
+ var CODE_RULES = [
3306
+ { match: String.raw`/\*\*(?!/)[\s\S]*?(?:\*/|$)`, type: "doc-comment" },
3307
+ { match: String.raw`/\*[\s\S]*?(?:\*/|$)`, type: "comment" },
3308
+ { match: String.raw`//[^\r\n]*`, type: "comment" },
3309
+ { match: String.raw`\r\n|[\r\n

]`, type: "newline" },
3310
+ { match: String.raw`[ \t\f\v ]+`, type: "space" },
3311
+ { match: "`", type: "string", push: "template" },
3312
+ { match: String.raw`"(?:\\[\s\S]|[^"\\\r\n])*"?`, type: "string" },
3313
+ { match: String.raw`'(?:\\[\s\S]|[^'\\\r\n])*'?`, type: "string" },
3314
+ {
3315
+ // regular expression literal (only where a division can't be)
3316
+ match: String.raw`/(?![*/])(?:\\.|\[(?:\\.|[^\]\\\r\n])*\]|[^/\\\[\r\n])+/[a-z]*`,
3317
+ type: "regex",
3318
+ when: { previousNotTypes: DIVISION_AFTER_TYPES, previousNotTexts: DIVISION_AFTER_TEXTS }
3319
+ },
3320
+ { match: String.raw`0[xX][\da-fA-F_]+n?|0[bB][01_]+n?|0[oO][0-7_]+n?|(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][+-]?\d[\d_]*)?n?`, type: "number" },
3321
+ { match: String.raw`#?[A-Za-z_$ -￿][\w$ -￿]*`, type: "identifier" },
3322
+ { match: String.raw`[()\[\]{}]`, type: "bracket" },
3323
+ { match: String.raw`\?\.(?!\d)|\.\.\.|[;,.]`, type: "punctuation" },
3324
+ { match: String.raw`>>>=|<<=|>>=|>>>|\*\*=|&&=|\|\|=|\?\?=|===|!==|=>|\*\*|\+\+|--|<<|>>|&&|\|\||\?\?|[-+*/%&|^<>!=]=?|[~?:@]`, type: "operator" }
3325
+ ];
3326
+ var JavaScriptSyntax = {
3327
+ name: "javascript",
3328
+ aliases: ["js", "mjs", "cjs", "jsx", "typescript", "ts", "tsx", "script", "ecmascript"],
3329
+ lexical: {
3330
+ start: "root",
3331
+ states: {
3332
+ root: CODE_RULES,
3333
+ template: [
3334
+ { match: "`", type: "string", pop: true },
3335
+ { match: String.raw`\$\{`, type: "punctuation", push: "templateExpression" },
3336
+ { match: String.raw`(?:\\[\s\S]|\$(?!\{)|[^\\` + "`" + String.raw`$])+`, type: "string" }
3337
+ ],
3338
+ templateExpression: [
3339
+ { match: String.raw`\}`, type: "punctuation", pop: true },
3340
+ { match: String.raw`\{`, type: "bracket", push: "braces" },
3341
+ { include: "root" }
3342
+ ],
3343
+ braces: [
3344
+ { match: String.raw`\}`, type: "bracket", pop: true },
3345
+ { match: String.raw`\{`, type: "bracket", push: "braces" },
3346
+ { include: "root" }
3347
+ ]
3348
+ },
3349
+ keywords: { keyword: JAVASCRIPT_KEYWORDS },
3350
+ keywordExceptAfter: [".", "?."]
3351
+ }
3352
+ };
3353
+
3354
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/pacem-binding.js
3355
+ var NOT_AFTER_MEMBER_ACCESS = { previousNotTexts: [".", "?."] };
3356
+ var PacemBindingSyntax = {
3357
+ name: "pacem-binding",
3358
+ aliases: ["pacem", "binding"],
3359
+ extends: "javascript",
3360
+ lexical: {
3361
+ states: {
3362
+ root: [
3363
+ { match: String.raw`:host(?=\.)`, type: "binding-host", when: NOT_AFTER_MEMBER_ACCESS },
3364
+ { match: String.raw`::[A-Za-z_$][\w$]*`, type: "binding-host-property" },
3365
+ { match: String.raw`\^+item(?![\w$])`, type: "binding-item" },
3366
+ { match: String.raw`\^+index(?![\w$])`, type: "binding-index" },
3367
+ { match: String.raw`#[A-Za-z_][\w]*`, type: "binding-element", when: NOT_AFTER_MEMBER_ACCESS },
3368
+ { match: String.raw`\$?this(?![\w$])`, type: "binding-this", when: NOT_AFTER_MEMBER_ACCESS }
3369
+ ]
3370
+ }
3371
+ }
3372
+ };
3373
+
3374
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/markup.js
3375
+ var NEWLINE_RULE = { match: String.raw`\r\n|[\r\n]`, type: "newline" };
3376
+ var ATTRIBUTE_RULES = [
3377
+ NEWLINE_RULE,
3378
+ { match: String.raw`[ \t\f]+`, type: "space" },
3379
+ { match: '"', type: "string", push: "doubleQuoted" },
3380
+ { match: "'", type: "string", push: "singleQuoted" },
3381
+ { match: String.raw`[^\s=/>"']+`, type: "attribute" },
3382
+ { match: "=", type: "operator" },
3383
+ { match: "/", type: "punctuation" }
3384
+ ];
3385
+ var BINDING_RULES = [
3386
+ { match: String.raw`\{\{`, type: "punctuation", embed: "pacem-binding", until: String.raw`\}\}` },
3387
+ { match: String.raw`\}\}`, type: "punctuation" }
3388
+ ];
3389
+ var MarkupSyntax = {
3390
+ name: "markup",
3391
+ aliases: ["html", "htm", "xml", "xhtml", "svg"],
3392
+ lexical: {
3393
+ start: "root",
3394
+ states: {
3395
+ root: [
3396
+ { match: String.raw`<!--[\s\S]*?(?:-->|$)`, type: "comment" },
3397
+ { match: String.raw`<![^>]*>?`, type: "tag" },
3398
+ { match: String.raw`(<\/)([\w:.-]+)(\s*>?)`, type: ["tag", "tagname", "tag"] },
3399
+ { match: String.raw`(<)(script)(?![\w:.-])`, flags: "i", type: ["tag", "tagname"], push: "scriptTag" },
3400
+ { match: String.raw`(<)([\w:.-]+)`, type: ["tag", "tagname"], push: "tag" },
3401
+ { match: String.raw`&(?:#\d+|#[xX][\da-fA-F]+|\w+);`, type: "entity" },
3402
+ NEWLINE_RULE,
3403
+ { match: String.raw`[^<&\r\n]+`, type: "text" }
3404
+ ],
3405
+ tag: [
3406
+ { match: String.raw`/?>`, type: "tag", pop: true },
3407
+ { include: "attributes" }
3408
+ ],
3409
+ scriptTag: [
3410
+ { match: "/>", type: "tag", pop: true },
3411
+ // the script body is tokenized as JavaScript, up to the closing tag
3412
+ { match: ">", type: "tag", pop: true, embed: "javascript", until: String.raw`<\/script` },
3413
+ { include: "attributes" }
3414
+ ],
3415
+ attributes: ATTRIBUTE_RULES,
3416
+ doubleQuoted: [
3417
+ { match: '"', type: "string", pop: true },
3418
+ ...BINDING_RULES,
3419
+ { match: String.raw`(?:[^"{}]|\{(?!\{)|\}(?!\}))+`, type: "string" }
3420
+ ],
3421
+ singleQuoted: [
3422
+ { match: "'", type: "string", pop: true },
3423
+ ...BINDING_RULES,
3424
+ { match: String.raw`(?:[^'{}]|\{(?!\{)|\}(?!\}))+`, type: "string" }
3425
+ ]
3426
+ },
3427
+ insignificant: ["space", "newline", "comment", "text"]
2252
3428
  }
2253
3429
  };
3430
+
3431
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/csharp.js
3432
+ var CSHARP_KEYWORDS = [
3433
+ "abstract",
3434
+ "add",
3435
+ "alias",
3436
+ "and",
3437
+ "args",
3438
+ "as",
3439
+ "ascending",
3440
+ "async",
3441
+ "await",
3442
+ "base",
3443
+ "bool",
3444
+ "break",
3445
+ "by",
3446
+ "byte",
3447
+ "case",
3448
+ "catch",
3449
+ "char",
3450
+ "checked",
3451
+ "class",
3452
+ "const",
3453
+ "continue",
3454
+ "decimal",
3455
+ "default",
3456
+ "delegate",
3457
+ "descending",
3458
+ "do",
3459
+ "double",
3460
+ "dynamic",
3461
+ "else",
3462
+ "enum",
3463
+ "equals",
3464
+ "event",
3465
+ "explicit",
3466
+ "extern",
3467
+ "false",
3468
+ "file",
3469
+ "finally",
3470
+ "fixed",
3471
+ "float",
3472
+ "for",
3473
+ "foreach",
3474
+ "from",
3475
+ "get",
3476
+ "global",
3477
+ "goto",
3478
+ "group",
3479
+ "if",
3480
+ "implicit",
3481
+ "in",
3482
+ "init",
3483
+ "int",
3484
+ "interface",
3485
+ "internal",
3486
+ "into",
3487
+ "is",
3488
+ "join",
3489
+ "let",
3490
+ "lock",
3491
+ "long",
3492
+ "managed",
3493
+ "nameof",
3494
+ "namespace",
3495
+ "new",
3496
+ "nint",
3497
+ "not",
3498
+ "notnull",
3499
+ "nuint",
3500
+ "null",
3501
+ "object",
3502
+ "on",
3503
+ "operator",
3504
+ "or",
3505
+ "orderby",
3506
+ "out",
3507
+ "override",
3508
+ "params",
3509
+ "partial",
3510
+ "private",
3511
+ "protected",
3512
+ "public",
3513
+ "readonly",
3514
+ "record",
3515
+ "ref",
3516
+ "remove",
3517
+ "required",
3518
+ "return",
3519
+ "sbyte",
3520
+ "scoped",
3521
+ "sealed",
3522
+ "select",
3523
+ "set",
3524
+ "short",
3525
+ "sizeof",
3526
+ "stackalloc",
3527
+ "static",
3528
+ "string",
3529
+ "struct",
3530
+ "switch",
3531
+ "this",
3532
+ "throw",
3533
+ "true",
3534
+ "try",
3535
+ "typeof",
3536
+ "uint",
3537
+ "ulong",
3538
+ "unchecked",
3539
+ "unmanaged",
3540
+ "unsafe",
3541
+ "ushort",
3542
+ "using",
3543
+ "value",
3544
+ "var",
3545
+ "virtual",
3546
+ "void",
3547
+ "volatile",
3548
+ "when",
3549
+ "where",
3550
+ "while",
3551
+ "with",
3552
+ "yield"
3553
+ ];
3554
+ var CODE_RULES2 = [
3555
+ { match: String.raw`///[^\r\n]*`, type: "doc-comment" },
3556
+ { match: String.raw`//[^\r\n]*`, type: "comment" },
3557
+ { match: String.raw`/\*[\s\S]*?(?:\*/|$)`, type: "comment" },
3558
+ // preprocessor directives, at the beginning of a line
3559
+ { match: String.raw`(?<=^[ \t]*|[\r\n][ \t]*)#[ \t]*[a-z]+[^\r\n]*`, type: "preprocessor" },
3560
+ { match: String.raw`\r\n|[\r\n]`, type: "newline" },
3561
+ { match: String.raw`[ \t\f\v\u00A0\uFEFF]+`, type: "space" },
3562
+ // raw string literals ("""…""", optionally interpolated)
3563
+ { match: String.raw`\$*("{3,})[\s\S]*?\1`, type: "string" },
3564
+ { match: String.raw`\$@"|@\$"`, type: "string", push: "interpolatedVerbatim" },
3565
+ { match: String.raw`\$"`, type: "string", push: "interpolated" },
3566
+ { match: String.raw`@"(?:[^"]|"")*"?`, type: "string" },
3567
+ { match: String.raw`"(?:\\.|[^"\\\r\n])*"?`, type: "string" },
3568
+ { match: String.raw`'(?:\\.|[^'\\\r\n])*'?`, type: "string" },
3569
+ { match: String.raw`0[xX][\da-fA-F_]+[uUlL]*|0[bB][01_]+[uUlL]*|(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][+-]?\d+)?[fFdDmMuUlL]*`, type: "number" },
3570
+ { match: String.raw`@?[A-Za-z_\u00A0-\uFFFF][\w\u00A0-\uFFFF]*`, type: "identifier" },
3571
+ { match: String.raw`[()\[\]{}]`, type: "bracket" },
3572
+ { match: String.raw`\?\.|::|[;,.]`, type: "punctuation" },
3573
+ { match: String.raw`\?\?=|<<=|>>>=|>>=|>>>|=>|==|!=|<=|>=|&&|\|\||\?\?|\+\+|--|->|<<|[-+*/%&|^<>!=]=?|[~?:]`, type: "operator" }
3574
+ ];
3575
+ var CSharpSyntax = {
3576
+ name: "csharp",
3577
+ aliases: ["cs", "c#", "c-sharp", "dotnet"],
3578
+ lexical: {
3579
+ start: "root",
3580
+ states: {
3581
+ root: CODE_RULES2,
3582
+ interpolated: [
3583
+ { match: '"', type: "string", pop: true },
3584
+ { match: String.raw`\{\{|\}\}`, type: "string" },
3585
+ { match: String.raw`\{`, type: "punctuation", push: "interpolation" },
3586
+ { match: String.raw`(?:\\.|[^"\\{}\r\n])+`, type: "string" }
3587
+ ],
3588
+ interpolatedVerbatim: [
3589
+ { match: '""', type: "string" },
3590
+ { match: '"', type: "string", pop: true },
3591
+ { match: String.raw`\{\{|\}\}`, type: "string" },
3592
+ { match: String.raw`\{`, type: "punctuation", push: "interpolation" },
3593
+ { match: String.raw`[^"{}]+`, type: "string" }
3594
+ ],
3595
+ interpolation: [
3596
+ { match: String.raw`\}`, type: "punctuation", pop: true },
3597
+ { match: String.raw`\{`, type: "bracket", push: "braces" },
3598
+ { include: "root" }
3599
+ ],
3600
+ braces: [
3601
+ { match: String.raw`\}`, type: "bracket", pop: true },
3602
+ { match: String.raw`\{`, type: "bracket", push: "braces" },
3603
+ { include: "root" }
3604
+ ]
3605
+ },
3606
+ keywords: { keyword: CSHARP_KEYWORDS },
3607
+ keywordExceptAfter: [".", "?."]
3608
+ }
3609
+ };
3610
+
3611
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/c.js
3612
+ var C_KEYWORDS = [
3613
+ // C
3614
+ "auto",
3615
+ "break",
3616
+ "case",
3617
+ "char",
3618
+ "const",
3619
+ "continue",
3620
+ "default",
3621
+ "do",
3622
+ "double",
3623
+ "else",
3624
+ "enum",
3625
+ "extern",
3626
+ "float",
3627
+ "for",
3628
+ "goto",
3629
+ "if",
3630
+ "inline",
3631
+ "int",
3632
+ "long",
3633
+ "register",
3634
+ "restrict",
3635
+ "return",
3636
+ "short",
3637
+ "signed",
3638
+ "sizeof",
3639
+ "static",
3640
+ "struct",
3641
+ "switch",
3642
+ "typedef",
3643
+ "union",
3644
+ "unsigned",
3645
+ "void",
3646
+ "volatile",
3647
+ "while",
3648
+ "bool",
3649
+ "true",
3650
+ "false",
3651
+ "NULL",
3652
+ "_Bool",
3653
+ "_Complex",
3654
+ "_Imaginary",
3655
+ "_Alignas",
3656
+ "_Alignof",
3657
+ "_Atomic",
3658
+ "_Generic",
3659
+ "_Noreturn",
3660
+ "_Static_assert",
3661
+ "_Thread_local",
3662
+ // C++
3663
+ "alignas",
3664
+ "alignof",
3665
+ "and",
3666
+ "and_eq",
3667
+ "asm",
3668
+ "bitand",
3669
+ "bitor",
3670
+ "catch",
3671
+ "char8_t",
3672
+ "char16_t",
3673
+ "char32_t",
3674
+ "class",
3675
+ "co_await",
3676
+ "co_return",
3677
+ "co_yield",
3678
+ "compl",
3679
+ "concept",
3680
+ "consteval",
3681
+ "constexpr",
3682
+ "constinit",
3683
+ "const_cast",
3684
+ "decltype",
3685
+ "delete",
3686
+ "dynamic_cast",
3687
+ "explicit",
3688
+ "export",
3689
+ "final",
3690
+ "friend",
3691
+ "mutable",
3692
+ "namespace",
3693
+ "new",
3694
+ "noexcept",
3695
+ "not",
3696
+ "not_eq",
3697
+ "nullptr",
3698
+ "operator",
3699
+ "or",
3700
+ "or_eq",
3701
+ "override",
3702
+ "private",
3703
+ "protected",
3704
+ "public",
3705
+ "reinterpret_cast",
3706
+ "requires",
3707
+ "static_assert",
3708
+ "static_cast",
3709
+ "template",
3710
+ "this",
3711
+ "thread_local",
3712
+ "throw",
3713
+ "try",
3714
+ "typeid",
3715
+ "typename",
3716
+ "using",
3717
+ "virtual",
3718
+ "wchar_t",
3719
+ "xor",
3720
+ "xor_eq"
3721
+ ];
3722
+ var CSyntax = {
3723
+ name: "c",
3724
+ aliases: ["cpp", "c++", "cc", "cxx", "h", "hpp", "hxx", "objc"],
3725
+ lexical: {
3726
+ start: "root",
3727
+ states: {
3728
+ root: [
3729
+ { match: String.raw`/\*\*(?!/)[\s\S]*?(?:\*/|$)|///[^\r\n]*`, type: "doc-comment" },
3730
+ { match: String.raw`/\*[\s\S]*?(?:\*/|$)`, type: "comment" },
3731
+ { match: String.raw`//[^\r\n]*`, type: "comment" },
3732
+ // preprocessor directives, at the beginning of a line (line continuations included)
3733
+ { match: String.raw`(?<=^[ \t]*|[\r\n][ \t]*)#[ \t]*\w+(?:\\\r?\n|[^\r\n])*`, type: "preprocessor" },
3734
+ { match: String.raw`\r\n|[\r\n]`, type: "newline" },
3735
+ { match: String.raw`[ \t\f\v]+`, type: "space" },
3736
+ { match: String.raw`(?:u8|u|U|L)?R"([^()\\\s]{0,16})\([\s\S]*?\)\1"`, type: "string" },
3737
+ { match: String.raw`(?:u8|u|U|L)?"(?:\\[\s\S]|[^"\\\r\n])*"?`, type: "string" },
3738
+ { match: String.raw`(?:u8|u|U|L)?'(?:\\.|[^'\\\r\n])*'?`, type: "string" },
3739
+ { match: String.raw`0[xX][\da-fA-F']+[uUlL]*|0[bB][01']+[uUlL]*|(?:\d[\d']*\.?[\d']*|\.\d[\d']*)(?:[eEpP][+-]?\d+)?[fFlLuU]*`, type: "number" },
3740
+ { match: String.raw`[A-Za-z_][\w]*`, type: "identifier" },
3741
+ { match: String.raw`[()\[\]{}]`, type: "bracket" },
3742
+ { match: String.raw`::|\.\.\.|->\*?|\.\*?|[;,]`, type: "punctuation" },
3743
+ { match: String.raw`<=>|<<=|>>=|<<|>>|\+\+|--|&&|\|\||[-+*/%&|^<>!=]=?|[~?:#]`, type: "operator" }
3744
+ ]
3745
+ },
3746
+ keywords: { keyword: C_KEYWORDS },
3747
+ keywordExceptAfter: [".", "->", "::"]
3748
+ }
3749
+ };
3750
+
3751
+ // packages/foundation/dist/esm/compile/syntax/vocabularies/json.js
3752
+ var JsonSyntax = {
3753
+ name: "json",
3754
+ aliases: ["jsonc", "json5", "webmanifest"],
3755
+ lexical: {
3756
+ start: "root",
3757
+ states: {
3758
+ root: [
3759
+ { match: String.raw`/\*[\s\S]*?(?:\*/|$)`, type: "comment" },
3760
+ { match: String.raw`//[^\r\n]*`, type: "comment" },
3761
+ { match: String.raw`\r\n|[\r\n]`, type: "newline" },
3762
+ { match: String.raw`[ \t\f\v ]+`, type: "space" },
3763
+ // keys: strings followed by a colon
3764
+ { match: String.raw`(?:"(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*')(?=\s*:)`, type: "attribute" },
3765
+ { match: String.raw`"(?:\\.|[^"\\\r\n])*"?|'(?:\\.|[^'\\\r\n])*'?`, type: "string" },
3766
+ { match: String.raw`-?(?:0[xX][\da-fA-F]+|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)|-?Infinity|NaN`, type: "number" },
3767
+ { match: String.raw`[A-Za-z_$][\w$]*`, type: "identifier" },
3768
+ { match: String.raw`[\[\]{}]`, type: "bracket" },
3769
+ { match: String.raw`[:,]`, type: "punctuation" }
3770
+ ]
3771
+ },
3772
+ keywords: { keyword: ["true", "false", "null"] }
3773
+ }
3774
+ };
3775
+
3776
+ // packages/foundation/dist/esm/compile/syntax/builtins.js
3777
+ var BUILTIN_SYNTAXES = {
3778
+ "javascript": JavaScriptSyntax,
3779
+ "pacem-binding": PacemBindingSyntax,
3780
+ "markup": MarkupSyntax,
3781
+ "csharp": CSharpSyntax,
3782
+ "c": CSyntax,
3783
+ "json": JsonSyntax
3784
+ };
3785
+ for (let name in BUILTIN_SYNTAXES) {
3786
+ const syntax = BUILTIN_SYNTAXES[name];
3787
+ Syntaxes.register(syntax);
3788
+ }
2254
3789
  export {
2255
3790
  Angle,
2256
3791
  Arrays,