gutterpress 0.11.22 → 0.11.23-alpha.1

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.
Files changed (57) hide show
  1. package/README.md +5 -5
  2. package/dist/{README-3nj919rm.md → README-8ef336pp.md} +1 -1
  3. package/dist/api/index.js +4 -4
  4. package/dist/{build-53bw14h7.js → build-09cd1n7s.js} +8 -8
  5. package/dist/{chapter-01-rkpyvjna.md → chapter-01-gsbjt584.md} +1 -1
  6. package/dist/chapter-01-s71xrf5q.md +69 -0
  7. package/dist/{chapter-01-7jwqg1ct.md → chapter-01-wgjfz4w6.md} +1 -1
  8. package/dist/checks/source/character-table.d.ts +12 -6
  9. package/dist/{cli-ke86zsz6.js → cli-5hkmp2wy.js} +70 -40
  10. package/dist/{cli-kx4hbnx2.js → cli-b0vyjvmt.js} +1 -1
  11. package/dist/{cli-1hxxwbaq.js → cli-ccp7sxz3.js} +1 -1
  12. package/dist/{cli-zj5xaepv.js → cli-dd115fa8.js} +22 -6
  13. package/dist/{cli-8kg0wjdt.js → cli-dtckwda1.js} +1 -1
  14. package/dist/{cli-1ngqzg8s.js → cli-fe43evmf.js} +21 -5
  15. package/dist/{cli-ntwqmdnw.js → cli-h17e3mtz.js} +462 -4
  16. package/dist/{cli-cjftezxr.js → cli-nr6j6300.js} +2 -1
  17. package/dist/cli.js +12 -12
  18. package/dist/{doctor-xka1frnx.js → doctor-nddspx4n.js} +3 -3
  19. package/dist/{engine-p93f06gj.js → engine-892swzzc.js} +2 -2
  20. package/dist/{engine-0ndvy8vj.js → engine-yjzknt0g.js} +2 -2
  21. package/dist/{ext-dwfqyy1j.js → ext-zjpen4yx.js} +9 -9
  22. package/dist/{extension-restore-7vp3vh77.js → extension-restore-jvs60x9b.js} +3 -3
  23. package/dist/{extension-restore-ct1wk344.js → extension-restore-w8xt4kbq.js} +5 -5
  24. package/dist/{index-53nrm5j1.js → index-0w2azsk1.js} +1 -1
  25. package/dist/{index-4v7e621e.js → index-2jpk25en.js} +464 -5
  26. package/dist/{index-vay3ff1f.js → index-dsvk7q6s.js} +21 -5
  27. package/dist/{index-6cmn2wpd.js → index-m4hhzg3c.js} +21 -5
  28. package/dist/{index-kh7fayjv.js → index-zrhyb967.js} +328 -311
  29. package/dist/index.js +5 -5
  30. package/dist/lib/build-runner.d.ts +1 -1
  31. package/dist/lib/extension-manager.d.ts +1 -1
  32. package/dist/lib/extension-specifier.d.ts +1 -1
  33. package/dist/lib/markdown/assemble.d.ts +7 -1
  34. package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
  35. package/dist/lib/markdown/index.d.ts +4 -0
  36. package/dist/lib/markdown/math.d.ts +43 -0
  37. package/dist/lib/markdown/renderer.d.ts +11 -8
  38. package/dist/lib/markdown/table.d.ts +46 -0
  39. package/dist/lib/markdown/typography.d.ts +12 -0
  40. package/dist/lib/presets.d.ts +1 -1
  41. package/dist/lib/project-scaffold.d.ts +1 -1
  42. package/dist/lib/project-templates.d.ts +9 -1
  43. package/dist/manifest-8f10dr4f.yaml +17 -0
  44. package/dist/{manifest.schema-399bx3vc.json → manifest.schema-9aeaered.json} +8 -1
  45. package/dist/{new-1pawj2qf.js → new-xhq8wczn.js} +8 -8
  46. package/dist/package-zttkgydq.json +10 -0
  47. package/dist/{plugins-fr4fnzhb.js → plugins-9en8m9y0.js} +3 -3
  48. package/dist/{plugins-g4dgw7mn.js → plugins-gf0gkjmv.js} +1 -1
  49. package/dist/{preflight-ept9q57t.js → preflight-negnxg7b.js} +8 -8
  50. package/dist/preview/file-watcher.d.ts +1 -0
  51. package/dist/{preview-fxpnjv7k.js → preview-cep2s9cg.js} +8 -8
  52. package/dist/{publish-zhqqsgmr.js → publish-xery6qc6.js} +8 -8
  53. package/dist/render.js +470 -11
  54. package/dist/schema/manifest.types.d.ts +8 -0
  55. package/dist/theme-9c58td2d.css +76 -0
  56. package/dist/{validate-t68gvckq.js → validate-3d0sgf4g.js} +8 -8
  57. package/package.json +2 -1
@@ -9,7 +9,7 @@ import { fileURLToPath } from "node:url";
9
9
  var favicon_default = "./favicon-272ga6y0.ico";
10
10
 
11
11
  // src/assets/manifest.schema.json
12
- var manifest_schema_default = "./manifest.schema-399bx3vc.json";
12
+ var manifest_schema_default = "./manifest.schema-9aeaered.json";
13
13
 
14
14
  // src/assets/preview/scripts/preview-interface.js
15
15
  var preview_interface_default = "./preview-interface-nnmrxyqm.js";
@@ -33,13 +33,13 @@ var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
33
33
  var manifest_default = "./manifest-n1gh3qw5.yaml";
34
34
 
35
35
  // src/assets/templates/book/chapter-01.md
36
- var chapter_01_default = "./chapter-01-rkpyvjna.md";
36
+ var chapter_01_default = "./chapter-01-gsbjt584.md";
37
37
 
38
38
  // src/assets/templates/zine/manifest.yaml
39
39
  var manifest_default2 = "./manifest-n1gh3qw5.yaml";
40
40
 
41
41
  // src/assets/templates/zine/chapter-01.md
42
- var chapter_01_default2 = "./chapter-01-7jwqg1ct.md";
42
+ var chapter_01_default2 = "./chapter-01-wgjfz4w6.md";
43
43
 
44
44
  // src/assets/templates/technical/manifest.yaml
45
45
  var manifest_default3 = "./manifest-n1gh3qw5.yaml";
@@ -47,6 +47,12 @@ var manifest_default3 = "./manifest-n1gh3qw5.yaml";
47
47
  // src/assets/templates/technical/chapter-01.md
48
48
  var chapter_01_default3 = "./chapter-01-6fn9pvd0.md";
49
49
 
50
+ // src/assets/templates/paper/manifest.yaml
51
+ var manifest_default4 = "./manifest-8f10dr4f.yaml";
52
+
53
+ // src/assets/templates/paper/chapter-01.md
54
+ var chapter_01_default4 = "./chapter-01-s71xrf5q.md";
55
+
50
56
  // src/assets/extension-templates/plugin/package.json
51
57
  var package_default = "./package-9rv69pxm.json";
52
58
 
@@ -75,7 +81,7 @@ var plugin_test_js_default = "./plugin.test.js-xgxrd8hf.tpl";
75
81
  var package_default2 = "./package-aenwjew3.json";
76
82
 
77
83
  // src/assets/extension-templates/theme/README.md
78
- var README_default2 = "./README-3nj919rm.md";
84
+ var README_default2 = "./README-8ef336pp.md";
79
85
 
80
86
  // src/assets/extension-templates/theme/components.yaml
81
87
  var components_default = "./components-zzqdpt3m.yaml";
@@ -119,6 +125,12 @@ var theme_default3 = "./theme-nn6d53zy.css";
119
125
  // src/assets/themes/technical-doc/package.json
120
126
  var package_default5 = "./package-nrhkwf2m.json";
121
127
 
128
+ // src/assets/themes/academic/theme.css
129
+ var theme_default4 = "./theme-9c58td2d.css";
130
+
131
+ // src/assets/themes/academic/package.json
132
+ var package_default6 = "./package-zttkgydq.json";
133
+
122
134
  // src/lib/embedded-assets.ts
123
135
  var __libdir = dirname(fileURLToPath(import.meta.url));
124
136
  var abs = (p) => resolve(__libdir, p);
@@ -138,6 +150,8 @@ var EMBEDDED_ASSETS = {
138
150
  "templates/zine/chapter-01.md": abs(filePath(chapter_01_default2)),
139
151
  "templates/technical/manifest.yaml": abs(filePath(manifest_default3)),
140
152
  "templates/technical/chapter-01.md": abs(filePath(chapter_01_default3)),
153
+ "templates/paper/manifest.yaml": abs(filePath(manifest_default4)),
154
+ "templates/paper/chapter-01.md": abs(filePath(chapter_01_default4)),
141
155
  "extension-templates/plugin/package.json": abs(filePath(package_default)),
142
156
  "extension-templates/plugin/README.md": abs(filePath(README_default)),
143
157
  "extension-templates/plugin/plugin.js.tpl": abs(filePath(plugin_js_default)),
@@ -161,7 +175,9 @@ var EMBEDDED_ASSETS = {
161
175
  "themes/zine/theme.css": abs(filePath(theme_default2)),
162
176
  "themes/zine/package.json": abs(filePath(package_default4)),
163
177
  "themes/technical-doc/theme.css": abs(filePath(theme_default3)),
164
- "themes/technical-doc/package.json": abs(filePath(package_default5))
178
+ "themes/technical-doc/package.json": abs(filePath(package_default5)),
179
+ "themes/academic/theme.css": abs(filePath(theme_default4)),
180
+ "themes/academic/package.json": abs(filePath(package_default6))
165
181
  };
166
182
  var extractPromise = null;
167
183
  async function extractAssets() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PACKAGE_VERSION,
3
3
  debug
4
- } from "./cli-kx4hbnx2.js";
4
+ } from "./cli-b0vyjvmt.js";
5
5
  import {
6
6
  isExactNpmVersion,
7
7
  isValidNpmPackageName,
@@ -1589,6 +1589,38 @@ img.gp-shape {
1589
1589
  :where(.gp-alert-important) { --gp-alert-color: var(--gp-alert-important-color); }
1590
1590
  :where(.gp-alert-warning) { --gp-alert-color: var(--gp-alert-warning-color); }
1591
1591
  :where(.gp-alert-caution) { --gp-alert-color: var(--gp-alert-caution-color); }
1592
+
1593
+ /* Math (the bundled gutterpress-math feature, math.ts): MathJax's own rules
1594
+ for the <mjx-container> SVG output it emits, from its SVG output jax's
1595
+ stylesheet, less the ones for its interactive menu and tooltips. Inert in
1596
+ a book without formulas. */
1597
+ mjx-container[jax="SVG"] { direction: ltr; }
1598
+ mjx-container[jax="SVG"] > svg { overflow: visible; min-height: 1px; min-width: 1px; }
1599
+ mjx-container[jax="SVG"] > svg a { fill: blue; stroke: blue; }
1600
+ mjx-container[jax="SVG"][display="true"] { display: block; text-align: center; margin: 1em 0; }
1601
+ mjx-container[jax="SVG"][display="true"][width="full"] { display: flex; }
1602
+ mjx-container[jax="SVG"][justify="left"] { text-align: left; }
1603
+ mjx-container[jax="SVG"][justify="right"] { text-align: right; }
1604
+ mjx-container[jax="SVG"] path[data-c], mjx-container[jax="SVG"] use[data-c] { stroke-width: 3; }
1605
+ mjx-assistive-mml {
1606
+ position: absolute !important;
1607
+ top: 0px; left: 0px;
1608
+ clip: rect(1px, 1px, 1px, 1px);
1609
+ padding: 1px 0px 0px 0px !important;
1610
+ border: 0px !important;
1611
+ display: block !important;
1612
+ width: auto !important;
1613
+ overflow: hidden !important;
1614
+ user-select: none;
1615
+ }
1616
+ mjx-assistive-mml[display="block"] { width: 100% !important; }
1617
+ g[data-mml-node="merror"] > g { fill: red; stroke: red; }
1618
+ g[data-mml-node="merror"] > rect[data-background] { fill: yellow; stroke: none; }
1619
+ g[data-mml-node="mtable"] > line[data-line], svg[data-table] > g > line[data-line] { stroke-width: 70px; fill: none; }
1620
+ g[data-mml-node="mtable"] > rect[data-frame], svg[data-table] > g > rect[data-frame] { stroke-width: 70px; fill: none; }
1621
+ g[data-mml-node="mtable"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed { stroke-dasharray: 140; }
1622
+ g[data-mml-node="mtable"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted { stroke-linecap: round; stroke-dasharray: 0,140; }
1623
+ g[data-mml-node="mtable"] > g > svg { overflow: visible; }
1592
1624
  `;
1593
1625
  var GP_CLASSES = new Set([
1594
1626
  "gp-left",
@@ -1903,6 +1935,224 @@ function gpBlockNames(md) {
1903
1935
  md.core.ruler.push("gp_block_names", (state) => nameBlocksAndHeadings(state.tokens));
1904
1936
  }
1905
1937
 
1938
+ // src/lib/markdown/table.ts
1939
+ import { isSpace } from "markdown-it/lib/common/utils.mjs";
1940
+ var scanCodeSpan = (src, start, max) => {
1941
+ let open = start;
1942
+ while (open < max && src.charCodeAt(open) === 96)
1943
+ open++;
1944
+ const length = open - start;
1945
+ let pos = open;
1946
+ while (pos < max) {
1947
+ if (src.charCodeAt(pos) !== 96) {
1948
+ pos++;
1949
+ continue;
1950
+ }
1951
+ let run = pos;
1952
+ while (run < max && src.charCodeAt(run) === 96)
1953
+ run++;
1954
+ if (run - pos === length)
1955
+ return run;
1956
+ pos = run;
1957
+ }
1958
+ return open;
1959
+ };
1960
+ var DEFAULT_SPANS = { 96: scanCodeSpan };
1961
+ function splitCells(str2, spans) {
1962
+ const result = [];
1963
+ const max = str2.length;
1964
+ let pos = 0;
1965
+ let lastPos = 0;
1966
+ let current = "";
1967
+ let isEscaped = false;
1968
+ while (pos < max) {
1969
+ const ch = str2.charCodeAt(pos);
1970
+ if (ch === 124) {
1971
+ if (!isEscaped) {
1972
+ result.push(current + str2.substring(lastPos, pos));
1973
+ current = "";
1974
+ lastPos = pos + 1;
1975
+ } else {
1976
+ current += str2.substring(lastPos, pos - 1);
1977
+ lastPos = pos;
1978
+ }
1979
+ } else if (!isEscaped && spans[ch]) {
1980
+ pos = spans[ch](str2, pos, max);
1981
+ continue;
1982
+ }
1983
+ isEscaped = ch === 92;
1984
+ pos++;
1985
+ }
1986
+ result.push(current + str2.substring(lastPos));
1987
+ return result;
1988
+ }
1989
+ function getLine(state, line) {
1990
+ const pos = state.bMarks[line] + state.tShift[line];
1991
+ const max = state.eMarks[line];
1992
+ return state.src.slice(pos, max);
1993
+ }
1994
+ var MAX_AUTOCOMPLETED_CELLS = 65536;
1995
+ function warnExtraCells(env, line, cells, columns) {
1996
+ if (!env.layoutWarnings)
1997
+ env.layoutWarnings = [];
1998
+ const extra = cells - columns;
1999
+ env.layoutWarnings.push({
2000
+ line: line + 1,
2001
+ type: "table_extra_cells",
2002
+ message: `This row has ${cells} cells but the table has ${columns} columns, so its last ` + `${extra === 1 ? "cell is" : `${extra} cells are`} left out. ` + "A | inside a cell splits it: write \\| for a literal one."
2003
+ });
2004
+ }
2005
+ function tableRule(spans) {
2006
+ return function table(state, startLine, endLine, silent) {
2007
+ if (startLine + 2 > endLine)
2008
+ return false;
2009
+ let nextLine = startLine + 1;
2010
+ if (state.sCount[nextLine] < state.blkIndent)
2011
+ return false;
2012
+ if (state.sCount[nextLine] - state.blkIndent >= 4)
2013
+ return false;
2014
+ let pos = state.bMarks[nextLine] + state.tShift[nextLine];
2015
+ if (pos >= state.eMarks[nextLine])
2016
+ return false;
2017
+ const firstCh = state.src.charCodeAt(pos++);
2018
+ if (firstCh !== 124 && firstCh !== 45 && firstCh !== 58)
2019
+ return false;
2020
+ if (pos >= state.eMarks[nextLine])
2021
+ return false;
2022
+ const secondCh = state.src.charCodeAt(pos++);
2023
+ if (secondCh !== 124 && secondCh !== 45 && secondCh !== 58 && !isSpace(secondCh)) {
2024
+ return false;
2025
+ }
2026
+ if (firstCh === 45 && isSpace(secondCh))
2027
+ return false;
2028
+ while (pos < state.eMarks[nextLine]) {
2029
+ const ch = state.src.charCodeAt(pos);
2030
+ if (ch !== 124 && ch !== 45 && ch !== 58 && !isSpace(ch))
2031
+ return false;
2032
+ pos++;
2033
+ }
2034
+ let lineText = getLine(state, startLine + 1);
2035
+ let columns = lineText.split("|");
2036
+ const aligns = [];
2037
+ for (let i = 0;i < columns.length; i++) {
2038
+ const t = columns[i].trim();
2039
+ if (!t) {
2040
+ if (i === 0 || i === columns.length - 1) {
2041
+ continue;
2042
+ } else {
2043
+ return false;
2044
+ }
2045
+ }
2046
+ if (!/^:?-+:?$/.test(t))
2047
+ return false;
2048
+ if (t.charCodeAt(t.length - 1) === 58) {
2049
+ aligns.push(t.charCodeAt(0) === 58 ? "center" : "right");
2050
+ } else if (t.charCodeAt(0) === 58) {
2051
+ aligns.push("left");
2052
+ } else {
2053
+ aligns.push("");
2054
+ }
2055
+ }
2056
+ lineText = getLine(state, startLine).trim();
2057
+ if (lineText.indexOf("|") === -1)
2058
+ return false;
2059
+ if (state.sCount[startLine] - state.blkIndent >= 4)
2060
+ return false;
2061
+ columns = splitCells(lineText, spans);
2062
+ if (columns.length && columns[0] === "")
2063
+ columns.shift();
2064
+ if (columns.length && columns[columns.length - 1] === "")
2065
+ columns.pop();
2066
+ const columnCount = columns.length;
2067
+ if (columnCount === 0 || columnCount !== aligns.length)
2068
+ return false;
2069
+ if (silent)
2070
+ return true;
2071
+ const oldParentType = state.parentType;
2072
+ state.parentType = "table";
2073
+ const terminatorRules = state.md.block.ruler.getRules("blockquote");
2074
+ const token_to = state.push("table_open", "table", 1);
2075
+ const tableLines = [startLine, 0];
2076
+ token_to.map = tableLines;
2077
+ const token_tho = state.push("thead_open", "thead", 1);
2078
+ token_tho.map = [startLine, startLine + 1];
2079
+ const token_htro = state.push("tr_open", "tr", 1);
2080
+ token_htro.map = [startLine, startLine + 1];
2081
+ for (let i = 0;i < columns.length; i++) {
2082
+ const token_ho = state.push("th_open", "th", 1);
2083
+ if (aligns[i]) {
2084
+ token_ho.attrs = [["style", "text-align:" + aligns[i]]];
2085
+ }
2086
+ const token_il = state.push("inline", "", 0);
2087
+ token_il.content = columns[i].trim();
2088
+ token_il.children = [];
2089
+ state.push("th_close", "th", -1);
2090
+ }
2091
+ state.push("tr_close", "tr", -1);
2092
+ state.push("thead_close", "thead", -1);
2093
+ let tbodyLines;
2094
+ let autocompletedCells = 0;
2095
+ for (nextLine = startLine + 2;nextLine < endLine; nextLine++) {
2096
+ if (state.sCount[nextLine] < state.blkIndent)
2097
+ break;
2098
+ let terminate = false;
2099
+ for (let i = 0, l = terminatorRules.length;i < l; i++) {
2100
+ if (terminatorRules[i](state, nextLine, endLine, true)) {
2101
+ terminate = true;
2102
+ break;
2103
+ }
2104
+ }
2105
+ if (terminate)
2106
+ break;
2107
+ lineText = getLine(state, nextLine).trim();
2108
+ if (!lineText)
2109
+ break;
2110
+ if (state.sCount[nextLine] - state.blkIndent >= 4)
2111
+ break;
2112
+ columns = splitCells(lineText, spans);
2113
+ if (columns.length && columns[0] === "")
2114
+ columns.shift();
2115
+ if (columns.length && columns[columns.length - 1] === "")
2116
+ columns.pop();
2117
+ if (columns.length > columnCount) {
2118
+ warnExtraCells(state.env, nextLine, columns.length, columnCount);
2119
+ }
2120
+ autocompletedCells += columnCount - columns.length;
2121
+ if (autocompletedCells > MAX_AUTOCOMPLETED_CELLS)
2122
+ break;
2123
+ if (nextLine === startLine + 2) {
2124
+ const token_tbo = state.push("tbody_open", "tbody", 1);
2125
+ token_tbo.map = tbodyLines = [startLine + 2, 0];
2126
+ }
2127
+ const token_tro = state.push("tr_open", "tr", 1);
2128
+ token_tro.map = [nextLine, nextLine + 1];
2129
+ for (let i = 0;i < columnCount; i++) {
2130
+ const token_tdo = state.push("td_open", "td", 1);
2131
+ if (aligns[i]) {
2132
+ token_tdo.attrs = [["style", "text-align:" + aligns[i]]];
2133
+ }
2134
+ const token_il = state.push("inline", "", 0);
2135
+ token_il.content = columns[i] ? columns[i].trim() : "";
2136
+ token_il.children = [];
2137
+ state.push("td_close", "td", -1);
2138
+ }
2139
+ state.push("tr_close", "tr", -1);
2140
+ }
2141
+ if (tbodyLines) {
2142
+ state.push("tbody_close", "tbody", -1);
2143
+ tbodyLines[1] = nextLine;
2144
+ }
2145
+ state.push("table_close", "table", -1);
2146
+ tableLines[1] = nextLine;
2147
+ state.parentType = oldParentType;
2148
+ state.line = nextLine;
2149
+ return true;
2150
+ };
2151
+ }
2152
+ function gpTable(md, options) {
2153
+ md.block.ruler.at("table", tableRule(options?.spans ?? DEFAULT_SPANS), { alt: ["paragraph", "reference"] });
2154
+ }
2155
+
1906
2156
  // src/lib/markdown/table-align.ts
1907
2157
  var ALIGN = /^text-align:(left|center|right)$/;
1908
2158
  function gpTableAlign(md) {
@@ -1924,6 +2174,57 @@ th[data-align="center"], td[data-align="center"] { text-align: center; }
1924
2174
  th[data-align="right"], td[data-align="right"] { text-align: right; }
1925
2175
  `;
1926
2176
 
2177
+ // src/lib/markdown/typography.ts
2178
+ var EM_DASH = /(^|[^-])---(?=[^-]|$)/gm;
2179
+ var EN_DASH_SPACED = /(^|\s)--(?=\s|$)/gm;
2180
+ var EN_DASH = /(^|[^-\s])--(?=[^-\s]|$)/gm;
2181
+ var ELLIPSIS = /\.\.\./g;
2182
+ var CANDIDATE = /--|\.\.\./;
2183
+ function replaceInText(children) {
2184
+ let insideAutolink = 0;
2185
+ for (let i = children.length - 1;i >= 0; i--) {
2186
+ const token = children[i];
2187
+ if (token.type === "text" && !insideAutolink && CANDIDATE.test(token.content)) {
2188
+ token.content = token.content.replace(ELLIPSIS, "…").replace(EM_DASH, "$1—").replace(EN_DASH_SPACED, "$1–").replace(EN_DASH, "$1–");
2189
+ }
2190
+ if (token.type === "link_close" && token.info === "auto")
2191
+ insideAutolink++;
2192
+ if (token.type === "link_open" && token.info === "auto")
2193
+ insideAutolink--;
2194
+ }
2195
+ }
2196
+ var QUOTES = {
2197
+ en: "“”‘’",
2198
+ de: "„“‚‘",
2199
+ "de-ch": "«»‹›",
2200
+ "de-li": "«»‹›",
2201
+ fr: ["« ", " »", "‹ ", " ›"],
2202
+ es: "«»“”",
2203
+ it: "«»“”",
2204
+ pt: "«»“”",
2205
+ "pt-br": "“”‘’",
2206
+ ru: "«»„“",
2207
+ pl: "„”«»",
2208
+ cs: "„“‚‘",
2209
+ sk: "„“‚‘",
2210
+ sv: "””’’",
2211
+ fi: "””’’"
2212
+ };
2213
+ function quotesFor(language) {
2214
+ const tag = (language ?? "en").toLowerCase();
2215
+ return QUOTES[tag] ?? QUOTES[tag.split("-")[0]] ?? QUOTES.en;
2216
+ }
2217
+ function gpTypography(md) {
2218
+ md.disable("replacements");
2219
+ md.core.ruler.after("linkify", "gp_typography", (state) => {
2220
+ for (const token of state.tokens) {
2221
+ if (token.type !== "inline" || !token.children || !CANDIDATE.test(token.content))
2222
+ continue;
2223
+ replaceInText(token.children);
2224
+ }
2225
+ });
2226
+ }
2227
+
1927
2228
  // src/lib/two-versions-markers.ts
1928
2229
  var YOUR_VERSION_LABEL = "your version";
1929
2230
  var ONLINE_VERSION_LABEL = "online version";
@@ -2145,6 +2446,159 @@ function gfmAlerts(md) {
2145
2446
  md.core.ruler.after("block", "gp_gfm_alerts", gfmAlertsRule);
2146
2447
  }
2147
2448
 
2449
+ // src/lib/markdown/math.ts
2450
+ import { mathjax } from "mathjax-full/js/mathjax.js";
2451
+ import { TeX } from "mathjax-full/js/input/tex.js";
2452
+ import { SVG } from "mathjax-full/js/output/svg.js";
2453
+ import { liteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
2454
+ import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html.js";
2455
+ import { AssistiveMmlHandler } from "mathjax-full/js/a11y/assistive-mml.js";
2456
+ import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js";
2457
+ function findInlineMathEnd(src, start, max) {
2458
+ const after = src.charCodeAt(start + 1);
2459
+ if (after === 32 || after === 9)
2460
+ return -1;
2461
+ let match = start + 1;
2462
+ while ((match = src.indexOf("$", match)) !== -1 && match < max) {
2463
+ let pos = match - 1;
2464
+ while (src.charCodeAt(pos) === 92)
2465
+ pos--;
2466
+ if ((match - pos) % 2 === 1)
2467
+ break;
2468
+ match++;
2469
+ }
2470
+ if (match === -1 || match >= max)
2471
+ return -1;
2472
+ if (match === start + 1)
2473
+ return -2;
2474
+ const before = src.charCodeAt(match - 1);
2475
+ const next = src.charCodeAt(match + 1);
2476
+ if (before === 32 || before === 9 || next >= 48 && next <= 57)
2477
+ return -1;
2478
+ return match;
2479
+ }
2480
+ var scanInlineMath = (src, start, max) => {
2481
+ const end = findInlineMathEnd(src, start, max);
2482
+ return end >= 0 ? end + 1 : end === -2 ? start + 2 : start + 1;
2483
+ };
2484
+ function mathInline(state, silent) {
2485
+ if (state.src.charCodeAt(state.pos) !== 36)
2486
+ return false;
2487
+ const end = findInlineMathEnd(state.src, state.pos, state.posMax);
2488
+ if (end < 0) {
2489
+ const literal = end === -2 ? "$$" : "$";
2490
+ if (!silent)
2491
+ state.pending += literal;
2492
+ state.pos += literal.length;
2493
+ return true;
2494
+ }
2495
+ if (!silent) {
2496
+ const token = state.push("math_inline", "math", 0);
2497
+ token.markup = "$";
2498
+ token.content = state.src.slice(state.pos + 1, end);
2499
+ }
2500
+ state.pos = end + 1;
2501
+ return true;
2502
+ }
2503
+ function mathBlock(state, start, end, silent) {
2504
+ let pos = state.bMarks[start] + state.tShift[start];
2505
+ let max = state.eMarks[start];
2506
+ if (pos + 2 > max)
2507
+ return false;
2508
+ if (state.src.slice(pos, pos + 2) !== "$$")
2509
+ return false;
2510
+ pos += 2;
2511
+ let firstLine = state.src.slice(pos, max);
2512
+ if (silent)
2513
+ return true;
2514
+ let found = false;
2515
+ let lastLine = "";
2516
+ if (firstLine.trim().slice(-2) === "$$") {
2517
+ firstLine = firstLine.trim().slice(0, -2);
2518
+ found = true;
2519
+ }
2520
+ let next = start;
2521
+ while (!found) {
2522
+ next++;
2523
+ if (next >= end)
2524
+ break;
2525
+ pos = state.bMarks[next] + state.tShift[next];
2526
+ max = state.eMarks[next];
2527
+ if (pos < max && state.tShift[next] < state.blkIndent) {
2528
+ break;
2529
+ }
2530
+ if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
2531
+ const lastPos = state.src.slice(0, max).lastIndexOf("$$");
2532
+ lastLine = state.src.slice(pos, lastPos);
2533
+ found = true;
2534
+ }
2535
+ }
2536
+ state.line = next + 1;
2537
+ const token = state.push("math_block", "math", 0);
2538
+ token.block = true;
2539
+ token.content = (firstLine && firstLine.trim() ? firstLine + `
2540
+ ` : "") + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
2541
+ token.map = [start, state.line];
2542
+ token.markup = "$$";
2543
+ return true;
2544
+ }
2545
+ var adaptor = null;
2546
+ function getAdaptor() {
2547
+ if (!adaptor) {
2548
+ adaptor = liteAdaptor();
2549
+ AssistiveMmlHandler(RegisterHTMLHandler(adaptor));
2550
+ }
2551
+ return adaptor;
2552
+ }
2553
+ var PACKAGES = AllPackages.filter((name) => name !== "noerrors" && name !== "noundefined");
2554
+ function gpMath(md) {
2555
+ const html = getAdaptor();
2556
+ let errors = [];
2557
+ const tex = new TeX({
2558
+ packages: PACKAGES,
2559
+ formatError: (jax, err) => {
2560
+ errors.push(err.message);
2561
+ return jax.formatError(err);
2562
+ }
2563
+ });
2564
+ const document = mathjax.document("", { InputJax: tex, OutputJax: new SVG({ fontCache: "none" }) });
2565
+ const typeset = (token, display, env) => {
2566
+ errors = [];
2567
+ const out = html.outerHTML(document.convert(token.content, { display }));
2568
+ for (const message of errors) {
2569
+ if (!env.layoutWarnings)
2570
+ env.layoutWarnings = [];
2571
+ env.layoutWarnings.push({
2572
+ line: token.meta?.line ?? (token.map?.[0] ?? 0) + 1,
2573
+ type: "math_error",
2574
+ message: `This formula could not be typeset: ${message}. It prints in red until it is fixed.`
2575
+ });
2576
+ }
2577
+ return display ? out + `
2578
+ ` : out;
2579
+ };
2580
+ md.inline.ruler.after("escape", "math_inline", mathInline);
2581
+ md.block.ruler.after("blockquote", "math_block", mathBlock, {
2582
+ alt: ["paragraph", "reference", "blockquote", "list"]
2583
+ });
2584
+ md.core.ruler.after("inline", "math_lines", (state) => {
2585
+ let line = 1;
2586
+ for (const token of state.tokens) {
2587
+ if (token.map)
2588
+ line = token.map[0] + 1;
2589
+ if (token.type !== "inline" || !token.children)
2590
+ continue;
2591
+ for (const child of token.children) {
2592
+ if (child.type === "math_inline")
2593
+ child.meta = { line };
2594
+ }
2595
+ }
2596
+ });
2597
+ md.renderer.rules.math_inline = (tokens, idx, _options, env) => typeset(tokens[idx], false, env);
2598
+ md.renderer.rules.math_block = (tokens, idx, _options, env) => typeset(tokens[idx], true, env);
2599
+ md.use(gpTable, { spans: { ...DEFAULT_SPANS, 36: scanInlineMath } });
2600
+ }
2601
+
2148
2602
  // src/lib/markdown/images.ts
2149
2603
  var isSrcsetSpace = (char) => char === "\t" || char === `
2150
2604
  ` || char === "\f" || char === "\r" || char === " ";
@@ -2571,14 +3025,17 @@ var BUILTIN_OPTIONAL_PLUGINS = {
2571
3025
  "markdown-it-sub": unwrapPlugin(markdownItSub),
2572
3026
  "markdown-it-sup": unwrapPlugin(markdownItSup),
2573
3027
  "markdown-it-abbr": unwrapPlugin(markdownItAbbr),
2574
- "gutterpress-gfm-alerts": gfmAlerts
3028
+ "gutterpress-gfm-alerts": gfmAlerts,
3029
+ "gutterpress-math": gpMath
2575
3030
  };
2576
- function createMarkdownRenderer(customPlugins) {
3031
+ function createMarkdownRenderer(customPlugins, options) {
2577
3032
  const md = new MarkdownIt({
2578
3033
  html: true,
2579
3034
  linkify: true,
2580
- typographer: true
3035
+ typographer: true,
3036
+ quotes: quotesFor(options?.language)
2581
3037
  });
3038
+ md.use(gpTypography);
2582
3039
  md.use(unwrapPlugin(markdownItAttrs));
2583
3040
  md.use(unwrapPlugin(markdownItFootnote));
2584
3041
  md.use(unwrapPlugin(markdownItDeflist));
@@ -2588,6 +3045,7 @@ function createMarkdownRenderer(customPlugins) {
2588
3045
  md.use(plugin, { declaredMarkers });
2589
3046
  md.use(gpPinScope);
2590
3047
  md.use(gpBlockNames);
3048
+ md.use(gpTable);
2591
3049
  md.use(gpTableAlign);
2592
3050
  md.use(gpTwoVersions);
2593
3051
  registerImageRule(md);
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "gutterpress",
4
- version: "0.11.22",
4
+ version: "0.11.23-alpha.1",
5
5
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
6
6
  author: "itlackey",
7
7
  license: "MPL-2.0",
@@ -79,6 +79,7 @@ var package_default = {
79
79
  "markdown-it-sub": "^2.0.0",
80
80
  "markdown-it-sup": "^2.0.0",
81
81
  markdownlint: "^0.40.0",
82
+ "mathjax-full": "^3.2.2",
82
83
  "pdf-lib": "^1.17.1",
83
84
  postcss: "^8.5.18",
84
85
  "resolve.exports": "2.0.3",
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  } from "./cli-d8xjns66.js";
9
9
  import {
10
10
  package_default
11
- } from "./cli-cjftezxr.js";
11
+ } from "./cli-nr6j6300.js";
12
12
  import {
13
13
  EXIT_CODES
14
14
  } from "./cli-46ycxe6r.js";
@@ -20,14 +20,14 @@ import {
20
20
  import { defineCommand, parseArgs, runMain } from "citty";
21
21
  import { statSync } from "node:fs";
22
22
  var SUBCOMMANDS = {
23
- new: () => import("./new-1pawj2qf.js").then((m) => m.default),
24
- preview: () => import("./preview-fxpnjv7k.js").then((m) => m.default),
25
- build: () => import("./build-53bw14h7.js").then((m) => m.default),
26
- publish: () => import("./publish-zhqqsgmr.js").then((m) => m.default),
27
- validate: () => import("./validate-t68gvckq.js").then((m) => m.default),
28
- preflight: () => import("./preflight-ept9q57t.js").then((m) => m.default),
29
- doctor: () => import("./doctor-xka1frnx.js").then((m) => m.default),
30
- ext: () => import("./ext-dwfqyy1j.js").then((m) => m.default)
23
+ new: () => import("./new-xhq8wczn.js").then((m) => m.default),
24
+ preview: () => import("./preview-cep2s9cg.js").then((m) => m.default),
25
+ build: () => import("./build-09cd1n7s.js").then((m) => m.default),
26
+ publish: () => import("./publish-xery6qc6.js").then((m) => m.default),
27
+ validate: () => import("./validate-3d0sgf4g.js").then((m) => m.default),
28
+ preflight: () => import("./preflight-negnxg7b.js").then((m) => m.default),
29
+ doctor: () => import("./doctor-nddspx4n.js").then((m) => m.default),
30
+ ext: () => import("./ext-zjpen4yx.js").then((m) => m.default)
31
31
  };
32
32
  var VERSION = package_default.version;
33
33
  var main = defineCommand({
@@ -52,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
52
52
  const [command, ...commandArgs] = rawArgs;
53
53
  try {
54
54
  if (command === "new") {
55
- const { newArgs } = await import("./new-1pawj2qf.js");
55
+ const { newArgs } = await import("./new-xhq8wczn.js");
56
56
  rejectUnknownFlags(commandArgs, newArgs, "new");
57
57
  const parsed = parseArgs(commandArgs, {
58
58
  ...newArgs,
@@ -64,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
64
64
  return;
65
65
  }
66
66
  if (command === "preflight") {
67
- const { preflightArgs } = await import("./preflight-ept9q57t.js");
67
+ const { preflightArgs } = await import("./preflight-negnxg7b.js");
68
68
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
69
69
  const parsed = parseArgs(commandArgs, {
70
70
  ...preflightArgs,
@@ -84,7 +84,7 @@ async function preflightRequiredInvocations(rawArgs) {
84
84
  }
85
85
  if (subcommand.startsWith("-"))
86
86
  return;
87
- const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-dwfqyy1j.js");
87
+ const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-zjpen4yx.js");
88
88
  if (!EXT_SUBCOMMANDS.includes(subcommand)) {
89
89
  throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
90
90
  }
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  getSystemDiagnostics
3
- } from "./cli-1hxxwbaq.js";
3
+ } from "./cli-ccp7sxz3.js";
4
4
  import"./cli-asap4t1z.js";
5
5
  import {
6
6
  log
7
- } from "./cli-kx4hbnx2.js";
7
+ } from "./cli-b0vyjvmt.js";
8
8
  import {
9
9
  UsageError,
10
10
  rejectExtraPositionals,
11
11
  rejectUnknownFlags
12
12
  } from "./cli-d8xjns66.js";
13
- import"./cli-cjftezxr.js";
13
+ import"./cli-nr6j6300.js";
14
14
  import"./cli-46ycxe6r.js";
15
15
  import"./cli-37x76zdn.js";
16
16