gutterpress 0.11.23-beta.1 → 0.11.23-beta.3

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 (65) hide show
  1. package/README.md +13 -3
  2. package/dist/api/index.d.ts +5 -5
  3. package/dist/api/index.js +19 -7
  4. package/dist/{build-dg8a566j.js → build-fq3mexhy.js} +9 -9
  5. package/dist/checks/asset/approved-fonts.d.ts +8 -0
  6. package/dist/checks/asset/extensions.d.ts +1 -1
  7. package/dist/checks/asset/index.d.ts +1 -0
  8. package/dist/{cli-e31jshz6.js → cli-5zbdb6mt.js} +296 -65
  9. package/dist/{cli-ttj95aex.js → cli-7mt0dftw.js} +47 -18
  10. package/dist/{cli-989eg8jz.js → cli-ah93yyzb.js} +163 -55
  11. package/dist/{cli-31anr0r9.js → cli-eymdsefg.js} +69 -29
  12. package/dist/{cli-1fy1pm9d.js → cli-fh685nqs.js} +1 -1
  13. package/dist/{cli-k087gj0p.js → cli-fsjre61x.js} +123 -12
  14. package/dist/{cli-s1zt779w.js → cli-q7t04gjt.js} +1 -1
  15. package/dist/{cli-vhav8g82.js → cli-rybz2dfs.js} +1 -1
  16. package/dist/cli.js +12 -12
  17. package/dist/{doctor-g4a42tcz.js → doctor-tg9ht1n3.js} +3 -3
  18. package/dist/engine/compiler/postprocess.d.ts +3 -0
  19. package/dist/engine/shared/pdf-inspect.d.ts +33 -0
  20. package/dist/{engine-jvkcahr1.js → engine-17v87vq5.js} +1 -1
  21. package/dist/{engine-wgkaqjsc.js → engine-y9fnarfa.js} +2 -2
  22. package/dist/{ext-w9d5ftcg.js → ext-esz03jz4.js} +27 -10
  23. package/dist/{extension-restore-5x4mj79d.js → extension-restore-91gy1e28.js} +3 -3
  24. package/dist/{extension-restore-as0g38p1.js → extension-restore-q70wqah5.js} +5 -5
  25. package/dist/{gutterpress-agent-d29ry3ak.js → gutterpress-agent-wyryqehx.js} +13 -4
  26. package/dist/{gutterpress-viewer-ze691rrd.js → gutterpress-viewer-ywkf49q5.js} +38 -153
  27. package/dist/{index-a4j3xcfp.js → index-67g8f7r4.js} +47 -18
  28. package/dist/{index-798jt0qc.js → index-d9w3r89w.js} +3 -3
  29. package/dist/{index-rj5vrhz6.js → index-fntpr44x.js} +321 -66
  30. package/dist/{index-5x42amh8.js → index-g3te5ey1.js} +2 -1
  31. package/dist/{index-cw03e9p4.js → index-kw4tbthz.js} +69 -29
  32. package/dist/{index-fk2kpf2t.js → index-santcs4q.js} +121 -10
  33. package/dist/{index-c6y0p7jy.js → index-z6vzj3s5.js} +243 -73
  34. package/dist/index.js +35 -8
  35. package/dist/lib/check-options.d.ts +70 -0
  36. package/dist/lib/extension-manager.d.ts +16 -1
  37. package/dist/lib/extension-scaffold.d.ts +15 -2
  38. package/dist/lib/extension-specifier.d.ts +8 -1
  39. package/dist/lib/manifest-config.d.ts +3 -1
  40. package/dist/lib/manifest-old-spellings.d.ts +32 -9
  41. package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
  42. package/dist/lib/markdown/math.d.ts +1 -1
  43. package/dist/lib/markdown/typography.d.ts +1 -0
  44. package/dist/lib/page-size.d.ts +12 -4
  45. package/dist/lib/plugin-vendor.d.ts +6 -0
  46. package/dist/lib/presets.d.ts +2 -2
  47. package/dist/lib/root-tokens.d.ts +2 -1
  48. package/dist/lib/source-provider.d.ts +27 -0
  49. package/dist/lib/style-resolver.d.ts +2 -1
  50. package/dist/lib/version-changes.d.ts +22 -6
  51. package/dist/{manifest.schema-0jgj0jt1.json → manifest.schema-5cm13vr3.json} +215 -5
  52. package/dist/{new-jtk028rf.js → new-rmfyb7va.js} +22 -15
  53. package/dist/{plugins-bcbe7xs8.js → plugins-gs21xz5s.js} +2 -2
  54. package/dist/{plugins-zsm6wv79.js → plugins-tqv1s16f.js} +4 -4
  55. package/dist/{preflight-cs6mj1d6.js → preflight-bjyeeq0d.js} +9 -9
  56. package/dist/{preview-d1j1g4qf.js → preview-ke03fk5d.js} +9 -9
  57. package/dist/{publish-7yw4jyrt.js → publish-wpnz0qng.js} +9 -9
  58. package/dist/render.js +55 -13
  59. package/dist/schema/manifest.types.d.ts +45 -7
  60. package/dist/{source-provider-n7vehh6t.js → source-provider-3g3yrn1f.js} +6 -2
  61. package/dist/{source-provider-tgzet3j5.js → source-provider-azg9ywhb.js} +6 -2
  62. package/dist/test-helpers/vocabulary.d.ts +12 -0
  63. package/dist/{validate-rkcdnzhw.js → validate-zcwykb43.js} +9 -9
  64. package/package.json +1 -1
  65. /package/dist/{cli-y28j019d.js → cli-1dha1nxk.js} +0 -0
@@ -40,7 +40,6 @@
40
40
  fragmentDocument: () => fragmentDocument,
41
41
  cssZoomOf: () => cssZoomOf,
42
42
  contentEdgeRect: () => contentEdgeRect,
43
- compensateRepeatedHeaders: () => compensateRepeatedHeaders,
44
43
  compensateRectoBreaks: () => compensateRectoBreaks,
45
44
  columnReserve: () => columnReserve,
46
45
  collectCssText: () => collectCssText,
@@ -193,6 +192,29 @@
193
192
  no extractable body text; \`rabbit-walking.png\` (1379x2530, unique) sits on
194
193
  PDF p134 vs viewer folio 135. */
195
194
 
195
+ /* Repeated table headers and footers. Print draws a table's header group
196
+ (\`thead\`) at the top of every page the table spans, and its footer group
197
+ (\`tfoot\`) at the foot of each, and never leaves a header alone at the foot
198
+ of a page. Chromium does the same in a multicol column, through the same
199
+ table fragmentation, when the group is unbreakable; print media treats
200
+ every header and footer group so, the screen only one that is
201
+ \`break-inside: avoid\` (measured: on screen, a plain \`thead\` printed once and
202
+ a \`break-inside: avoid\` one on every column, exactly as print media does).
203
+ Setting it here makes the columns repeat the groups print repeats, where
204
+ print repeats them, and break around them as print does. A group the author
205
+ set to another \`display\` is not a header group and repeats in neither.
206
+
207
+ The viewer used to imitate this in script, cloning the header into each
208
+ continuation column and forcing a break before a table whose header would
209
+ be left alone. It moved a lead-in paragraph whole where print splits it,
210
+ left a clone at a column's foot, drew a second header wherever Chromium
211
+ already drew one, and shifted pages after the forced-break spacers had been
212
+ placed, losing a chapter's break (the gp-dimm-city design guide's reference
213
+ tables: #454). docs/fixtures/repeated-table-header pins it. */
214
+ .gp-strip :is(thead, tfoot) {
215
+ break-inside: avoid;
216
+ }
217
+
196
218
  /* View mode (\`applySpreadMode\` in fragment.ts): wraps this run's multicol
197
219
  columns into \`--gp-wrap-cols\` ROWS instead of one long row — 2 for
198
220
  two-up/spread, 1 for single (a plain vertical stack of pages), using
@@ -1482,10 +1504,13 @@
1482
1504
  function clearLeadingForcedBreaks(strip) {
1483
1505
  for (let el = strip.firstElementChild;el; el = el.firstElementChild) {
1484
1506
  const cs = getComputedStyle(el);
1485
- if (FORCED_BREAK.test(cs.breakBefore))
1486
- el.style.breakBefore = "auto";
1507
+ if (!FORCED_BREAK.test(cs.breakBefore))
1508
+ continue;
1509
+ clearedLeadingBreaks.set(el, cs.breakBefore);
1510
+ el.style.breakBefore = "auto";
1487
1511
  }
1488
1512
  }
1513
+ var clearedLeadingBreaks = new WeakMap;
1489
1514
  function stabilizeFullHeightPageRoots(model, strips) {
1490
1515
  let stabilized = 0;
1491
1516
  for (const strip of strips) {
@@ -1688,148 +1713,6 @@
1688
1713
  clearLeadingForcedBreaks(s.el);
1689
1714
  return strips;
1690
1715
  }
1691
- var AVOID_BREAK = /^avoid(-page|-column)?$/;
1692
- function keepChainHead(el) {
1693
- let head = el;
1694
- for (let prev = head.previousElementSibling;prev instanceof HTMLElement; prev = head.previousElementSibling) {
1695
- const linked = AVOID_BREAK.test(getComputedStyle(prev).breakAfter) || AVOID_BREAK.test(getComputedStyle(head).breakBefore);
1696
- if (!linked)
1697
- break;
1698
- head = prev;
1699
- }
1700
- return head;
1701
- }
1702
- var pushTargets = new WeakMap;
1703
- function repeatingHead(table) {
1704
- const head = table.tHead;
1705
- return head && getComputedStyle(head).display === "table-header-group" ? head : null;
1706
- }
1707
- function repeatingFoot(table) {
1708
- const foot = table.tFoot;
1709
- return foot && getComputedStyle(foot).display === "table-footer-group" ? foot : null;
1710
- }
1711
- function compensateRepeatedHeaders(strips, maxPasses = 24) {
1712
- const warnings = [];
1713
- let passes = 0;
1714
- let touched = 0;
1715
- for (const strip of strips) {
1716
- const tables = Array.from(strip.el.querySelectorAll("table")).filter((t) => repeatingHead(t) || repeatingFoot(t));
1717
- if (!tables.length)
1718
- continue;
1719
- for (const table of tables) {
1720
- for (const shim of Array.from(table.querySelectorAll("tr.gp-thead-shim, tr.gp-tfoot-shim")))
1721
- shim.remove();
1722
- table.style.breakBefore = "";
1723
- const target = pushTargets.get(table);
1724
- if (target)
1725
- target.style.breakBefore = "";
1726
- pushTargets.delete(table);
1727
- }
1728
- const pushed = new Set;
1729
- const footClaims = new Map;
1730
- let previous = "";
1731
- for (let pass = 0;pass < maxPasses; pass++) {
1732
- passes = Math.max(passes, pass + 1);
1733
- const { stride, height: colBottom } = stripMetrics(strip.el);
1734
- const stripLeft = strip.el.getBoundingClientRect().left - strip.el.scrollLeft;
1735
- const zoom = cssZoomOf(strip.el);
1736
- const colOf = (r) => Math.floor(((r.left - stripLeft) / zoom + 1) / stride);
1737
- const stripTop = strip.el.getBoundingClientRect().top;
1738
- const plans = [];
1739
- for (const table of tables) {
1740
- const head = repeatingHead(table);
1741
- const headRect = head?.getClientRects()[0];
1742
- const footHeight = (repeatingFoot(table)?.getBoundingClientRect().height ?? 0) / zoom;
1743
- const rows = Array.from(table.querySelectorAll("tbody > tr")).filter((r) => !r.classList.contains("gp-thead-shim") && !r.classList.contains("gp-tfoot-shim"));
1744
- if (!rows.length)
1745
- continue;
1746
- const rects = rows.map((r) => r.getClientRects()[0] ?? r.getBoundingClientRect());
1747
- const cols = rects.map(colOf);
1748
- const claims = footClaims.get(table) ?? new Map;
1749
- footClaims.set(table, claims);
1750
- let newClaim;
1751
- if (footHeight > 0) {
1752
- const lastCol = cols[cols.length - 1];
1753
- for (let i = 0;i < rows.length; i++) {
1754
- const row = rows[i];
1755
- if (cols[i] === lastCol || claims.has(row))
1756
- continue;
1757
- const bottom = (rects[i].bottom - stripTop) / zoom;
1758
- if (bottom > colBottom - footHeight + 0.5) {
1759
- newClaim = row;
1760
- claims.set(row, colBottom - (rects[i].top - stripTop) / zoom);
1761
- break;
1762
- }
1763
- }
1764
- }
1765
- plans.push({
1766
- table,
1767
- push: headRect ? colOf(headRect) < cols[0] : false,
1768
- headHeight: (headRect?.height ?? 0) / zoom,
1769
- footHeight,
1770
- breakRows: headRect ? rows.filter((_, i) => i > 0 && cols[i] > cols[i - 1]) : [],
1771
- footRows: [...claims.entries()],
1772
- grew: newClaim !== undefined,
1773
- cells: Math.max(1, ...rows.map((r) => r.cells.length))
1774
- });
1775
- }
1776
- const signature = plans.map((p) => `${p.push || pushed.has(p.table) ? "P" : ""}${p.breakRows.map((r) => r.rowIndex).join(".")}~${p.footRows.map(([r]) => r.rowIndex).join(".")}`).join("|");
1777
- const anyGrowth = plans.some((p) => p.grew);
1778
- if (!anyGrowth && signature === previous)
1779
- break;
1780
- previous = signature;
1781
- for (const plan of plans) {
1782
- for (const shim of Array.from(plan.table.querySelectorAll("tr.gp-thead-shim, tr.gp-tfoot-shim")))
1783
- shim.remove();
1784
- if (plan.push && !pushed.has(plan.table)) {
1785
- pushed.add(plan.table);
1786
- const target = keepChainHead(plan.table);
1787
- target.style.breakBefore = "column";
1788
- pushTargets.set(plan.table, target);
1789
- touched++;
1790
- continue;
1791
- }
1792
- for (const row of plan.breakRows) {
1793
- row.before(headerShim(plan.table.tHead, plan.headHeight, plan.cells));
1794
- touched++;
1795
- }
1796
- for (const [row, height] of plan.footRows) {
1797
- row.before(sectionShim(plan.table.tFoot, height, plan.cells, "gp-tfoot-shim"));
1798
- touched++;
1799
- }
1800
- }
1801
- }
1802
- }
1803
- return { tables: touched, passes, warnings };
1804
- }
1805
- function headerShim(head, height, cells) {
1806
- return sectionShim(head, height, cells, "gp-thead-shim");
1807
- }
1808
- function sectionShim(section, height, cells, className) {
1809
- const shim = document.createElement("tr");
1810
- shim.className = className;
1811
- shim.setAttribute("aria-hidden", "true");
1812
- shim.style.height = `${height}px`;
1813
- if (className === "gp-tfoot-shim")
1814
- shim.style.verticalAlign = "bottom";
1815
- const source = section.rows[0];
1816
- if (source) {
1817
- for (const cell of Array.from(source.cells)) {
1818
- const td = document.createElement("td");
1819
- td.colSpan = cell.colSpan;
1820
- td.innerHTML = cell.innerHTML;
1821
- const cs = getComputedStyle(cell);
1822
- td.style.cssText = `font:${cs.font};color:${cs.color};letter-spacing:${cs.letterSpacing};text-transform:${cs.textTransform};vertical-align:${cs.verticalAlign};text-align:${cs.textAlign};padding:${cs.padding};border:${cs.border};background:${cs.backgroundColor};`;
1823
- shim.appendChild(td);
1824
- }
1825
- } else {
1826
- const td = document.createElement("td");
1827
- td.colSpan = cells;
1828
- td.style.cssText = `height:${height}px;padding:0;border:0;`;
1829
- shim.appendChild(td);
1830
- }
1831
- return shim;
1832
- }
1833
1716
  function compensateRectoBreaks(model, strips) {
1834
1717
  const decls2 = model.breaks.filter(isRectoVersoBreak);
1835
1718
  for (const spacer of Array.from(document.querySelectorAll(".gp-recto-spacer")))
@@ -1837,6 +1720,7 @@
1837
1720
  if (!decls2.length)
1838
1721
  return 0;
1839
1722
  const sites = [];
1723
+ const seen = new Set;
1840
1724
  for (const d of decls2) {
1841
1725
  let els = [];
1842
1726
  try {
@@ -1844,8 +1728,13 @@
1844
1728
  } catch {
1845
1729
  continue;
1846
1730
  }
1847
- for (const el of els)
1848
- sites.push({ el, wantsRecto: wantsRecto(d.value) });
1731
+ for (const el of els) {
1732
+ const value = clearedLeadingBreaks.get(el) ?? getComputedStyle(el).breakBefore;
1733
+ if (seen.has(el) || !RECTO_VERSO_VALUES.test(value))
1734
+ continue;
1735
+ seen.add(el);
1736
+ sites.push({ el, wantsRecto: wantsRecto(value) });
1737
+ }
1849
1738
  }
1850
1739
  sites.sort((a, b) => a.el.compareDocumentPosition(b.el) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
1851
1740
  const plan = planRectoBlanks(sites.map((site) => ({ page: pageOf(site.el, strips) + 1, wantsRecto: site.wantsRecto })));
@@ -2043,7 +1932,6 @@
2043
1932
  const blanks = compensateRectoBreaks(model, strips);
2044
1933
  if (blanks)
2045
1934
  measure(strips);
2046
- const headers = opts.compensateHeaders === false ? { tables: 0, passes: 0, warnings: [] } : compensateRepeatedHeaders(strips);
2047
1935
  const contentPages = measure(strips).totalPages;
2048
1936
  const totalPages = padToSignature(strips, contentPages);
2049
1937
  fitVersoPinRoots(model, strips);
@@ -2051,7 +1939,7 @@
2051
1939
  model,
2052
1940
  strips,
2053
1941
  totalPages,
2054
- warnings: [...new Set([...authoring, ...headers.warnings])],
1942
+ warnings: [...new Set(authoring)],
2055
1943
  blankPages: blanks,
2056
1944
  blankPageIndices: blankPageIndices(strips),
2057
1945
  paddedPageIndices: pagesAfter(contentPages, totalPages),
@@ -2072,10 +1960,7 @@
2072
1960
  synthesizeColumnBreaks(model);
2073
1961
  measure(strips);
2074
1962
  api.blankPages = compensateRectoBreaks(model, strips);
2075
- if (opts.compensateHeaders !== false)
2076
- api.warnings = [
2077
- ...new Set([...authoring, ...compensateRepeatedHeaders(strips).warnings])
2078
- ];
1963
+ api.warnings = [...new Set(authoring)];
2079
1964
  const content = measure(strips).totalPages;
2080
1965
  padToSignature(strips, content);
2081
1966
  const r = measure(strips);
@@ -7,7 +7,7 @@ import {
7
7
  resolveVendoredPluginInstallRoot,
8
8
  safePackageTarget,
9
9
  vendoredNpmPluginPackageDir
10
- } from "./index-5x42amh8.js";
10
+ } from "./index-g3te5ey1.js";
11
11
 
12
12
  // src/lib/markdown/plugins.ts
13
13
  import { existsSync as existsSync2, readFileSync, statSync, unlinkSync } from "node:fs";
@@ -288,7 +288,7 @@ th, td { padding: 0.2em 0.8em; }
288
288
  `;
289
289
 
290
290
  // src/lib/extension-specifier.ts
291
- var BUNDLED_EXTENSIONS = [
291
+ var BUNDLED_EXTENSION_DETAILS = [
292
292
  {
293
293
  name: "markdown-it-mark",
294
294
  label: "Highlight",
@@ -344,8 +344,9 @@ var BUNDLED_EXTENSIONS = [
344
344
  css: theme_default4
345
345
  }
346
346
  ];
347
+ var BUNDLED_EXTENSIONS = BUNDLED_EXTENSION_DETAILS.map((e) => e.name);
347
348
  function bundledExtension(name) {
348
- return BUNDLED_EXTENSIONS.find((e) => e.name === name);
349
+ return BUNDLED_EXTENSION_DETAILS.find((e) => e.name === name);
349
350
  }
350
351
  function isBundledExtension(name) {
351
352
  return bundledExtension(name) !== undefined;
@@ -398,7 +399,7 @@ import { satisfies, validRange } from "semver";
398
399
  // package.json
399
400
  var package_default = {
400
401
  name: "gutterpress",
401
- version: "0.11.23-beta.1",
402
+ version: "0.11.23-beta.3",
402
403
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
403
404
  author: "itlackey",
404
405
  license: "MPL-2.0",
@@ -2122,8 +2123,9 @@ img.gp-shape {
2122
2123
 
2123
2124
  /* Math (the bundled gutterpress-math feature, math.ts): MathJax's own rules
2124
2125
  for the <mjx-container> SVG output it emits, from its SVG output jax's
2125
- stylesheet, less the ones for its interactive menu and tooltips. Inert in
2126
- a book without formulas. */
2126
+ stylesheet, less the ones for its interactive menu and tooltips, plus one
2127
+ bound of ours on the hidden MathML copy (#469, below). Inert in a book
2128
+ without formulas. */
2127
2129
  mjx-container[jax="SVG"] { direction: ltr; }
2128
2130
  mjx-container[jax="SVG"] > svg { overflow: visible; min-height: 1px; min-width: 1px; }
2129
2131
  mjx-container[jax="SVG"] > svg a { fill: blue; stroke: blue; }
@@ -2140,6 +2142,15 @@ mjx-assistive-mml {
2140
2142
  border: 0px !important;
2141
2143
  display: block !important;
2142
2144
  width: auto !important;
2145
+ /* Ours (#469). The browser lays the copy out in whatever math font it has,
2146
+ so it can be wider than the formula's SVG; ending a line, it crossed the
2147
+ column edge and Chromium shrank the whole print to fit. MathJax makes the
2148
+ container position: relative with the copy at its top left, so 100% is
2149
+ the formula's width. Clip and overflow still hide the copy and its MathML
2150
+ still reaches screen readers; only its box changes. Not the 1px
2151
+ visually-hidden box MathJax 2 used: its docs note VoiceOver on iOS could
2152
+ not reach a formula by touch in it. */
2153
+ max-width: 100% !important;
2143
2154
  overflow: hidden !important;
2144
2155
  user-select: none;
2145
2156
  }
@@ -2710,22 +2721,39 @@ th[data-align="right"], td[data-align="right"] { text-align: right; }
2710
2721
  `;
2711
2722
 
2712
2723
  // src/lib/markdown/typography.ts
2724
+ var SCOPED = /\((c|tm|r)\)/gi;
2725
+ var SYMBOLS = { c: "©", r: "®", tm: "™" };
2726
+ var LABEL_BEFORE = { c: "(b)", C: "(B)", r: "(q)", R: "(Q)" };
2727
+ var LABELS = /\((b|q)\)/gi;
2728
+ var RARE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
2713
2729
  var EM_DASH = /(^|[^-])---(?=[^-]|$)/gm;
2714
2730
  var EN_DASH_SPACED = /(^|\s)--(?=\s|$)/gm;
2715
2731
  var EN_DASH = /(^|[^-\s])--(?=[^-\s]|$)/gm;
2716
- var ELLIPSIS = /\.\.\./g;
2717
- var CANDIDATE = /--|\.\.\./;
2718
- function replaceInText(children) {
2732
+ var CANDIDATE = /\((?:c|tm|r|b|q)\)|\+-|\.\.|\?\?\?\?|!!!!|,,|--/i;
2733
+ function replaceRare(text) {
2734
+ return text.replace(/\+-/g, "±").replace(/\.{2,}/g, "…").replace(/([?!])…/g, "$1..").replace(/([?!]){4,}/g, "$1$1$1").replace(/,{2,}/g, ",").replace(EM_DASH, "$1—").replace(EN_DASH_SPACED, "$1–").replace(EN_DASH, "$1–");
2735
+ }
2736
+ function replaceInText(children, seen) {
2719
2737
  let insideAutolink = 0;
2720
- for (let i = children.length - 1;i >= 0; i--) {
2721
- const token = children[i];
2722
- if (token.type === "text" && !insideAutolink && CANDIDATE.test(token.content)) {
2723
- token.content = token.content.replace(ELLIPSIS, "…").replace(EM_DASH, "$1—").replace(EN_DASH_SPACED, "$1–").replace(EN_DASH, "$1–");
2724
- }
2725
- if (token.type === "link_close" && token.info === "auto")
2726
- insideAutolink++;
2738
+ for (const token of children) {
2727
2739
  if (token.type === "link_open" && token.info === "auto")
2740
+ insideAutolink++;
2741
+ if (token.type === "link_close" && token.info === "auto")
2728
2742
  insideAutolink--;
2743
+ if (token.type !== "text")
2744
+ continue;
2745
+ const typed = token.content;
2746
+ if (!insideAutolink) {
2747
+ let text = typed.replace(SCOPED, (match, name, offset) => {
2748
+ const label = LABEL_BEFORE[name];
2749
+ return label && (seen.has(label) || typed.slice(0, offset).includes(label)) ? match : SYMBOLS[name.toLowerCase()];
2750
+ });
2751
+ if (RARE.test(text))
2752
+ text = replaceRare(text);
2753
+ token.content = text;
2754
+ }
2755
+ for (const [label] of typed.matchAll(LABELS))
2756
+ seen.add(label);
2729
2757
  }
2730
2758
  }
2731
2759
  var QUOTES = {
@@ -2752,10 +2780,11 @@ function quotesFor(language) {
2752
2780
  function gpTypography(md) {
2753
2781
  md.disable("replacements");
2754
2782
  md.core.ruler.after("linkify", "gp_typography", (state) => {
2783
+ const seen = new Set;
2755
2784
  for (const token of state.tokens) {
2756
2785
  if (token.type !== "inline" || !token.children || !CANDIDATE.test(token.content))
2757
2786
  continue;
2758
- replaceInText(token.children);
2787
+ replaceInText(token.children, seen);
2759
2788
  }
2760
2789
  });
2761
2790
  }
@@ -4069,4 +4098,4 @@ async function loadPluginsWithCss(configs, baseDir, onError) {
4069
4098
  };
4070
4099
  }
4071
4100
 
4072
- export { BUNDLED_EXTENSIONS, bundledExtension, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, pinnedNpmSpecifier, YOUR_VERSION_LABEL, ONLINE_VERSION_LABEL, TWO_VERSIONS_OPEN, TWO_VERSIONS_CLOSE, buildDeclaredMarkerRegistry, MARKER_CSS, GUTTERPRESS_CSS, TWO_VERSIONS_CSS, TABLE_ALIGN_CSS, slugify, prettify, setLogLevel, debug, info, warn, error, log, parseSrcsetUrlCandidates, collectHtmlImageRefs, createMarkdownRenderer, applyPlugins, collectPluginCss, collectPluginStylePaths, collectPluginStyleGroups, resolveDeclaredStyles, package_default, PACKAGE_META, PACKAGE_VERSION, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, __resetPathPluginCacheForTests, loadPlugin, loadPublishFunction, loadPlugins, loadPluginsWithCss };
4101
+ export { BUNDLED_EXTENSION_DETAILS, BUNDLED_EXTENSIONS, bundledExtension, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, pinnedNpmSpecifier, YOUR_VERSION_LABEL, ONLINE_VERSION_LABEL, TWO_VERSIONS_OPEN, TWO_VERSIONS_CLOSE, buildDeclaredMarkerRegistry, MARKER_CSS, GUTTERPRESS_CSS, TWO_VERSIONS_CSS, TABLE_ALIGN_CSS, slugify, prettify, setLogLevel, debug, info, warn, error, log, parseSrcsetUrlCandidates, collectHtmlImageRefs, createMarkdownRenderer, applyPlugins, collectPluginCss, collectPluginStylePaths, collectPluginStyleGroups, resolveDeclaredStyles, package_default, PACKAGE_META, PACKAGE_VERSION, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, __resetPathPluginCacheForTests, loadPlugin, loadPublishFunction, loadPlugins, loadPluginsWithCss };
@@ -697,7 +697,7 @@ import { fileURLToPath } from "node:url";
697
697
  var favicon_default = "./favicon-272ga6y0.ico";
698
698
 
699
699
  // src/assets/manifest.schema.json
700
- var manifest_schema_default = "./manifest.schema-0jgj0jt1.json";
700
+ var manifest_schema_default = "./manifest.schema-5cm13vr3.json";
701
701
 
702
702
  // src/assets/preview/scripts/preview-interface.js
703
703
  var preview_interface_default = "./preview-interface-0xdh0r5b.js";
@@ -712,10 +712,10 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
712
712
  var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
713
713
 
714
714
  // src/assets/engine/gutterpress-viewer.js
715
- var gutterpress_viewer_default = "./gutterpress-viewer-ze691rrd.js";
715
+ var gutterpress_viewer_default = "./gutterpress-viewer-ywkf49q5.js";
716
716
 
717
717
  // src/assets/engine/gutterpress-agent.js
718
- var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
718
+ var gutterpress_agent_default = "./gutterpress-agent-wyryqehx.js";
719
719
 
720
720
  // src/assets/templates/book/manifest.yaml
721
721
  var manifest_default = "./manifest-mffah3hr.yaml";