gutterpress 0.11.22 → 0.11.23-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -24
- package/dist/{README-3nj919rm.md → README-8ef336pp.md} +1 -1
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.js +16 -22
- package/dist/{build-53bw14h7.js → build-encgnv0c.js} +9 -10
- package/dist/{chapter-01-rkpyvjna.md → chapter-01-gsbjt584.md} +1 -1
- package/dist/chapter-01-s71xrf5q.md +69 -0
- package/dist/{chapter-01-7jwqg1ct.md → chapter-01-wgjfz4w6.md} +1 -1
- package/dist/checks/source/character-table.d.ts +12 -6
- package/dist/{cli-habkc5ng.js → cli-a35w7wzg.js} +5 -4
- package/dist/{cli-kx4hbnx2.js → cli-aqh6brew.js} +1 -1
- package/dist/{cli-1hxxwbaq.js → cli-evg8sbht.js} +1 -1
- package/dist/{cli-cjftezxr.js → cli-kh8v4vvw.js} +2 -1
- package/dist/{cli-ntwqmdnw.js → cli-pwwfxdgb.js} +846 -13
- package/dist/{cli-8kg0wjdt.js → cli-pz4bn98t.js} +185 -9
- package/dist/{cli-zj5xaepv.js → cli-sdmv4bba.js} +57 -117
- package/dist/{cli-ke86zsz6.js → cli-xq6djqbj.js} +51 -54
- package/dist/{index-r7jcsk6h.js → cli-y28j019d.js} +19 -10
- package/dist/cli.js +12 -12
- package/dist/{doctor-xka1frnx.js → doctor-5gtpgpd1.js} +3 -3
- package/dist/{engine-p93f06gj.js → engine-mc5br8g8.js} +1 -2
- package/dist/{engine-0ndvy8vj.js → engine-tn13gk0b.js} +3 -3
- package/dist/{ext-dwfqyy1j.js → ext-wn2a5afq.js} +18 -33
- package/dist/{extension-restore-ct1wk344.js → extension-restore-g8jnmmzq.js} +5 -6
- package/dist/{extension-restore-7vp3vh77.js → extension-restore-s3x1618g.js} +4 -4
- package/dist/{index-apc8w9w8.js → index-0skhjx3e.js} +180 -1
- package/dist/{index-4v7e621e.js → index-2bjcghze.js} +847 -13
- package/dist/index-46ycxe6r.js +18 -0
- package/dist/{index-53nrm5j1.js → index-4x6y8krm.js} +2 -4
- package/dist/{cli-h3phdstf.js → index-5x42amh8.js} +19 -10
- package/dist/{index-93pqkvty.js → index-h6yk5tjx.js} +5 -4
- package/dist/{index-kh7fayjv.js → index-j5z86r4a.js} +57 -54
- package/dist/{index-6cmn2wpd.js → index-x3ema2w3.js} +69 -128
- package/dist/index.js +17 -23
- package/dist/lib/build-runner.d.ts +1 -1
- package/dist/lib/extension-manager.d.ts +16 -43
- package/dist/lib/extension-scaffold.d.ts +3 -3
- package/dist/lib/extension-specifier.d.ts +23 -6
- package/dist/lib/markdown/assemble.d.ts +7 -1
- package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
- package/dist/lib/markdown/index.d.ts +4 -0
- package/dist/lib/markdown/math.d.ts +43 -0
- package/dist/lib/markdown/renderer.d.ts +11 -8
- package/dist/lib/markdown/table.d.ts +46 -0
- package/dist/lib/markdown/typography.d.ts +12 -0
- package/dist/lib/npm-plugin-installer.d.ts +1 -1
- package/dist/lib/plugin-vendor.d.ts +11 -3
- package/dist/lib/presets.d.ts +1 -1
- package/dist/lib/project-gitignore.d.ts +2 -2
- package/dist/lib/project-scaffold.d.ts +6 -8
- package/dist/lib/project-templates.d.ts +6 -1
- package/dist/lib/snippets.d.ts +2 -1
- package/dist/lib/style-resolver.d.ts +1 -2
- package/dist/manifest-eagfhba6.yaml +19 -0
- package/dist/{manifest.schema-399bx3vc.json → manifest.schema-t7nx2stg.json} +12 -5
- package/dist/{new-1pawj2qf.js → new-mhs46pw3.js} +22 -21
- package/dist/{plugins-fr4fnzhb.js → plugins-1sxe0dkz.js} +4 -4
- package/dist/{plugins-g4dgw7mn.js → plugins-2cek4mz1.js} +2 -2
- package/dist/{preflight-ept9q57t.js → preflight-3k2b1x8e.js} +9 -10
- package/dist/preview/file-watcher.d.ts +1 -0
- package/dist/{preview-fxpnjv7k.js → preview-6p9v6rht.js} +9 -10
- package/dist/{publish-zhqqsgmr.js → publish-qgsngy8s.js} +9 -10
- package/dist/render.js +470 -11
- package/dist/schema/manifest.types.d.ts +8 -0
- package/dist/{source-provider-qbfknhyy.js → source-provider-98k5deda.js} +2 -2
- package/dist/{source-provider-2r74a7wp.js → source-provider-knmcam50.js} +2 -2
- package/dist/{validate-t68gvckq.js → validate-0v7xw6wa.js} +9 -10
- package/package.json +2 -1
- package/dist/cli-1ngqzg8s.js +0 -196
- package/dist/index-vay3ff1f.js +0 -213
- package/dist/package-97gm31sg.json +0 -10
- package/dist/package-gag6ykwn.json +0 -10
- package/dist/package-nrhkwf2m.json +0 -10
- package/dist/theme-h5recz6c.css +0 -61
- package/dist/theme-j2bagrfx.css +0 -59
- package/dist/theme-nn6d53zy.css +0 -71
|
@@ -41,6 +41,7 @@ export declare function injectPreviewScripts(html: string): string;
|
|
|
41
41
|
*/
|
|
42
42
|
export declare function generateAndWriteHtml(inputPath: string, tempDir: string, config: {
|
|
43
43
|
title?: string;
|
|
44
|
+
language?: string;
|
|
44
45
|
styles?: string[];
|
|
45
46
|
source?: {
|
|
46
47
|
files?: string[] | null;
|
|
@@ -3,23 +3,23 @@ import {
|
|
|
3
3
|
runBuild,
|
|
4
4
|
splitOutPath,
|
|
5
5
|
startPreviewServer
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
6
|
+
} from "./cli-xq6djqbj.js";
|
|
7
|
+
import"./cli-evg8sbht.js";
|
|
8
8
|
import {
|
|
9
9
|
previewArgs
|
|
10
10
|
} from "./cli-75qkn0k5.js";
|
|
11
11
|
import"./cli-ht1bcqdd.js";
|
|
12
|
-
import"./cli-
|
|
12
|
+
import"./cli-pz4bn98t.js";
|
|
13
13
|
import"./cli-2ppw6q9v.js";
|
|
14
14
|
import"./cli-eyyggect.js";
|
|
15
15
|
import"./cli-asap4t1z.js";
|
|
16
|
-
import"./cli-
|
|
16
|
+
import"./cli-a35w7wzg.js";
|
|
17
17
|
import"./cli-v5mp7a6q.js";
|
|
18
|
-
import"./cli-
|
|
19
|
-
import"./cli-
|
|
18
|
+
import"./cli-sdmv4bba.js";
|
|
19
|
+
import"./cli-pwwfxdgb.js";
|
|
20
20
|
import {
|
|
21
21
|
log
|
|
22
|
-
} from "./cli-
|
|
22
|
+
} from "./cli-aqh6brew.js";
|
|
23
23
|
import {
|
|
24
24
|
UsageError,
|
|
25
25
|
parseFormat,
|
|
@@ -28,12 +28,11 @@ import {
|
|
|
28
28
|
rejectUnknownFlags,
|
|
29
29
|
resolvePort
|
|
30
30
|
} from "./cli-d8xjns66.js";
|
|
31
|
-
import"./cli-
|
|
32
|
-
import"./cli-1ngqzg8s.js";
|
|
31
|
+
import"./cli-kh8v4vvw.js";
|
|
33
32
|
import {
|
|
34
33
|
BuildError
|
|
35
34
|
} from "./cli-46ycxe6r.js";
|
|
36
|
-
import"./cli-
|
|
35
|
+
import"./cli-y28j019d.js";
|
|
37
36
|
import"./cli-37x76zdn.js";
|
|
38
37
|
|
|
39
38
|
// src/commands/preview.ts
|
|
@@ -10,36 +10,35 @@ import {
|
|
|
10
10
|
resolvePublishFormat,
|
|
11
11
|
resolvePublishProvider,
|
|
12
12
|
runPublish
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-xq6djqbj.js";
|
|
14
14
|
import {
|
|
15
15
|
FileTokenStore
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-evg8sbht.js";
|
|
17
17
|
import"./cli-ht1bcqdd.js";
|
|
18
|
-
import"./cli-
|
|
18
|
+
import"./cli-pz4bn98t.js";
|
|
19
19
|
import"./cli-2ppw6q9v.js";
|
|
20
20
|
import"./cli-eyyggect.js";
|
|
21
21
|
import"./cli-asap4t1z.js";
|
|
22
|
-
import"./cli-
|
|
22
|
+
import"./cli-a35w7wzg.js";
|
|
23
23
|
import"./cli-v5mp7a6q.js";
|
|
24
24
|
import {
|
|
25
25
|
loadManifestWithPath
|
|
26
|
-
} from "./cli-
|
|
27
|
-
import"./cli-
|
|
26
|
+
} from "./cli-sdmv4bba.js";
|
|
27
|
+
import"./cli-pwwfxdgb.js";
|
|
28
28
|
import {
|
|
29
29
|
log
|
|
30
|
-
} from "./cli-
|
|
30
|
+
} from "./cli-aqh6brew.js";
|
|
31
31
|
import {
|
|
32
32
|
UsageError,
|
|
33
33
|
rejectExtraPositionals,
|
|
34
34
|
rejectUnknownFlags
|
|
35
35
|
} from "./cli-d8xjns66.js";
|
|
36
|
-
import"./cli-
|
|
37
|
-
import"./cli-1ngqzg8s.js";
|
|
36
|
+
import"./cli-kh8v4vvw.js";
|
|
38
37
|
import {
|
|
39
38
|
BuildError,
|
|
40
39
|
EXIT_CODES
|
|
41
40
|
} from "./cli-46ycxe6r.js";
|
|
42
|
-
import"./cli-
|
|
41
|
+
import"./cli-y28j019d.js";
|
|
43
42
|
import"./cli-37x76zdn.js";
|
|
44
43
|
|
|
45
44
|
// src/commands/publish.ts
|
package/dist/render.js
CHANGED
|
@@ -1428,6 +1428,38 @@ img.gp-shape {
|
|
|
1428
1428
|
:where(.gp-alert-important) { --gp-alert-color: var(--gp-alert-important-color); }
|
|
1429
1429
|
:where(.gp-alert-warning) { --gp-alert-color: var(--gp-alert-warning-color); }
|
|
1430
1430
|
:where(.gp-alert-caution) { --gp-alert-color: var(--gp-alert-caution-color); }
|
|
1431
|
+
|
|
1432
|
+
/* Math (the bundled gutterpress-math feature, math.ts): MathJax's own rules
|
|
1433
|
+
for the <mjx-container> SVG output it emits, from its SVG output jax's
|
|
1434
|
+
stylesheet, less the ones for its interactive menu and tooltips. Inert in
|
|
1435
|
+
a book without formulas. */
|
|
1436
|
+
mjx-container[jax="SVG"] { direction: ltr; }
|
|
1437
|
+
mjx-container[jax="SVG"] > svg { overflow: visible; min-height: 1px; min-width: 1px; }
|
|
1438
|
+
mjx-container[jax="SVG"] > svg a { fill: blue; stroke: blue; }
|
|
1439
|
+
mjx-container[jax="SVG"][display="true"] { display: block; text-align: center; margin: 1em 0; }
|
|
1440
|
+
mjx-container[jax="SVG"][display="true"][width="full"] { display: flex; }
|
|
1441
|
+
mjx-container[jax="SVG"][justify="left"] { text-align: left; }
|
|
1442
|
+
mjx-container[jax="SVG"][justify="right"] { text-align: right; }
|
|
1443
|
+
mjx-container[jax="SVG"] path[data-c], mjx-container[jax="SVG"] use[data-c] { stroke-width: 3; }
|
|
1444
|
+
mjx-assistive-mml {
|
|
1445
|
+
position: absolute !important;
|
|
1446
|
+
top: 0px; left: 0px;
|
|
1447
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
1448
|
+
padding: 1px 0px 0px 0px !important;
|
|
1449
|
+
border: 0px !important;
|
|
1450
|
+
display: block !important;
|
|
1451
|
+
width: auto !important;
|
|
1452
|
+
overflow: hidden !important;
|
|
1453
|
+
user-select: none;
|
|
1454
|
+
}
|
|
1455
|
+
mjx-assistive-mml[display="block"] { width: 100% !important; }
|
|
1456
|
+
g[data-mml-node="merror"] > g { fill: red; stroke: red; }
|
|
1457
|
+
g[data-mml-node="merror"] > rect[data-background] { fill: yellow; stroke: none; }
|
|
1458
|
+
g[data-mml-node="mtable"] > line[data-line], svg[data-table] > g > line[data-line] { stroke-width: 70px; fill: none; }
|
|
1459
|
+
g[data-mml-node="mtable"] > rect[data-frame], svg[data-table] > g > rect[data-frame] { stroke-width: 70px; fill: none; }
|
|
1460
|
+
g[data-mml-node="mtable"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed { stroke-dasharray: 140; }
|
|
1461
|
+
g[data-mml-node="mtable"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted { stroke-linecap: round; stroke-dasharray: 0,140; }
|
|
1462
|
+
g[data-mml-node="mtable"] > g > svg { overflow: visible; }
|
|
1431
1463
|
`;
|
|
1432
1464
|
var GP_CLASSES = new Set([
|
|
1433
1465
|
"gp-left",
|
|
@@ -1625,6 +1657,11 @@ function canonicalChapterId(p) {
|
|
|
1625
1657
|
return s;
|
|
1626
1658
|
}
|
|
1627
1659
|
|
|
1660
|
+
// src/lib/slug.ts
|
|
1661
|
+
function slugify(name, fallback = "") {
|
|
1662
|
+
return name.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || fallback;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1628
1665
|
// src/lib/markdown/renderer.ts
|
|
1629
1666
|
import MarkdownIt from "markdown-it";
|
|
1630
1667
|
|
|
@@ -1777,11 +1814,6 @@ function gpPinScope(md) {
|
|
|
1777
1814
|
});
|
|
1778
1815
|
}
|
|
1779
1816
|
|
|
1780
|
-
// src/lib/slug.ts
|
|
1781
|
-
function slugify(name, fallback = "") {
|
|
1782
|
-
return name.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || fallback;
|
|
1783
|
-
}
|
|
1784
|
-
|
|
1785
1817
|
// src/lib/markdown/block-names.ts
|
|
1786
1818
|
var BLOCK_OPEN = /^layout_(chapter|spread|page|section|component)_open$/;
|
|
1787
1819
|
var BLOCK_CLOSE = /^layout_(chapter|spread|page|section|component)_close$/;
|
|
@@ -1923,6 +1955,275 @@ function gpBlockNames(md) {
|
|
|
1923
1955
|
md.core.ruler.push("gp_block_names", (state) => nameBlocksAndHeadings(state.tokens));
|
|
1924
1956
|
}
|
|
1925
1957
|
|
|
1958
|
+
// src/lib/markdown/table.ts
|
|
1959
|
+
import { isSpace } from "markdown-it/lib/common/utils.mjs";
|
|
1960
|
+
var scanCodeSpan = (src, start, max) => {
|
|
1961
|
+
let open = start;
|
|
1962
|
+
while (open < max && src.charCodeAt(open) === 96)
|
|
1963
|
+
open++;
|
|
1964
|
+
const length = open - start;
|
|
1965
|
+
let pos = open;
|
|
1966
|
+
while (pos < max) {
|
|
1967
|
+
if (src.charCodeAt(pos) !== 96) {
|
|
1968
|
+
pos++;
|
|
1969
|
+
continue;
|
|
1970
|
+
}
|
|
1971
|
+
let run = pos;
|
|
1972
|
+
while (run < max && src.charCodeAt(run) === 96)
|
|
1973
|
+
run++;
|
|
1974
|
+
if (run - pos === length)
|
|
1975
|
+
return run;
|
|
1976
|
+
pos = run;
|
|
1977
|
+
}
|
|
1978
|
+
return open;
|
|
1979
|
+
};
|
|
1980
|
+
var DEFAULT_SPANS = { 96: scanCodeSpan };
|
|
1981
|
+
function splitCells(str, spans) {
|
|
1982
|
+
const result = [];
|
|
1983
|
+
const max = str.length;
|
|
1984
|
+
let pos = 0;
|
|
1985
|
+
let lastPos = 0;
|
|
1986
|
+
let current = "";
|
|
1987
|
+
let isEscaped = false;
|
|
1988
|
+
while (pos < max) {
|
|
1989
|
+
const ch = str.charCodeAt(pos);
|
|
1990
|
+
if (ch === 124) {
|
|
1991
|
+
if (!isEscaped) {
|
|
1992
|
+
result.push(current + str.substring(lastPos, pos));
|
|
1993
|
+
current = "";
|
|
1994
|
+
lastPos = pos + 1;
|
|
1995
|
+
} else {
|
|
1996
|
+
current += str.substring(lastPos, pos - 1);
|
|
1997
|
+
lastPos = pos;
|
|
1998
|
+
}
|
|
1999
|
+
} else if (!isEscaped && spans[ch]) {
|
|
2000
|
+
pos = spans[ch](str, pos, max);
|
|
2001
|
+
continue;
|
|
2002
|
+
}
|
|
2003
|
+
isEscaped = ch === 92;
|
|
2004
|
+
pos++;
|
|
2005
|
+
}
|
|
2006
|
+
result.push(current + str.substring(lastPos));
|
|
2007
|
+
return result;
|
|
2008
|
+
}
|
|
2009
|
+
function getLine(state, line) {
|
|
2010
|
+
const pos = state.bMarks[line] + state.tShift[line];
|
|
2011
|
+
const max = state.eMarks[line];
|
|
2012
|
+
return state.src.slice(pos, max);
|
|
2013
|
+
}
|
|
2014
|
+
var MAX_AUTOCOMPLETED_CELLS = 65536;
|
|
2015
|
+
function warnExtraCells(env, line, cells, columns) {
|
|
2016
|
+
if (!env.layoutWarnings)
|
|
2017
|
+
env.layoutWarnings = [];
|
|
2018
|
+
const extra = cells - columns;
|
|
2019
|
+
env.layoutWarnings.push({
|
|
2020
|
+
line: line + 1,
|
|
2021
|
+
type: "table_extra_cells",
|
|
2022
|
+
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."
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
function tableRule(spans) {
|
|
2026
|
+
return function table(state, startLine, endLine, silent) {
|
|
2027
|
+
if (startLine + 2 > endLine)
|
|
2028
|
+
return false;
|
|
2029
|
+
let nextLine = startLine + 1;
|
|
2030
|
+
if (state.sCount[nextLine] < state.blkIndent)
|
|
2031
|
+
return false;
|
|
2032
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4)
|
|
2033
|
+
return false;
|
|
2034
|
+
let pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
2035
|
+
if (pos >= state.eMarks[nextLine])
|
|
2036
|
+
return false;
|
|
2037
|
+
const firstCh = state.src.charCodeAt(pos++);
|
|
2038
|
+
if (firstCh !== 124 && firstCh !== 45 && firstCh !== 58)
|
|
2039
|
+
return false;
|
|
2040
|
+
if (pos >= state.eMarks[nextLine])
|
|
2041
|
+
return false;
|
|
2042
|
+
const secondCh = state.src.charCodeAt(pos++);
|
|
2043
|
+
if (secondCh !== 124 && secondCh !== 45 && secondCh !== 58 && !isSpace(secondCh)) {
|
|
2044
|
+
return false;
|
|
2045
|
+
}
|
|
2046
|
+
if (firstCh === 45 && isSpace(secondCh))
|
|
2047
|
+
return false;
|
|
2048
|
+
while (pos < state.eMarks[nextLine]) {
|
|
2049
|
+
const ch = state.src.charCodeAt(pos);
|
|
2050
|
+
if (ch !== 124 && ch !== 45 && ch !== 58 && !isSpace(ch))
|
|
2051
|
+
return false;
|
|
2052
|
+
pos++;
|
|
2053
|
+
}
|
|
2054
|
+
let lineText2 = getLine(state, startLine + 1);
|
|
2055
|
+
let columns = lineText2.split("|");
|
|
2056
|
+
const aligns = [];
|
|
2057
|
+
for (let i = 0;i < columns.length; i++) {
|
|
2058
|
+
const t = columns[i].trim();
|
|
2059
|
+
if (!t) {
|
|
2060
|
+
if (i === 0 || i === columns.length - 1) {
|
|
2061
|
+
continue;
|
|
2062
|
+
} else {
|
|
2063
|
+
return false;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
if (!/^:?-+:?$/.test(t))
|
|
2067
|
+
return false;
|
|
2068
|
+
if (t.charCodeAt(t.length - 1) === 58) {
|
|
2069
|
+
aligns.push(t.charCodeAt(0) === 58 ? "center" : "right");
|
|
2070
|
+
} else if (t.charCodeAt(0) === 58) {
|
|
2071
|
+
aligns.push("left");
|
|
2072
|
+
} else {
|
|
2073
|
+
aligns.push("");
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
lineText2 = getLine(state, startLine).trim();
|
|
2077
|
+
if (lineText2.indexOf("|") === -1)
|
|
2078
|
+
return false;
|
|
2079
|
+
if (state.sCount[startLine] - state.blkIndent >= 4)
|
|
2080
|
+
return false;
|
|
2081
|
+
columns = splitCells(lineText2, spans);
|
|
2082
|
+
if (columns.length && columns[0] === "")
|
|
2083
|
+
columns.shift();
|
|
2084
|
+
if (columns.length && columns[columns.length - 1] === "")
|
|
2085
|
+
columns.pop();
|
|
2086
|
+
const columnCount = columns.length;
|
|
2087
|
+
if (columnCount === 0 || columnCount !== aligns.length)
|
|
2088
|
+
return false;
|
|
2089
|
+
if (silent)
|
|
2090
|
+
return true;
|
|
2091
|
+
const oldParentType = state.parentType;
|
|
2092
|
+
state.parentType = "table";
|
|
2093
|
+
const terminatorRules = state.md.block.ruler.getRules("blockquote");
|
|
2094
|
+
const token_to = state.push("table_open", "table", 1);
|
|
2095
|
+
const tableLines = [startLine, 0];
|
|
2096
|
+
token_to.map = tableLines;
|
|
2097
|
+
const token_tho = state.push("thead_open", "thead", 1);
|
|
2098
|
+
token_tho.map = [startLine, startLine + 1];
|
|
2099
|
+
const token_htro = state.push("tr_open", "tr", 1);
|
|
2100
|
+
token_htro.map = [startLine, startLine + 1];
|
|
2101
|
+
for (let i = 0;i < columns.length; i++) {
|
|
2102
|
+
const token_ho = state.push("th_open", "th", 1);
|
|
2103
|
+
if (aligns[i]) {
|
|
2104
|
+
token_ho.attrs = [["style", "text-align:" + aligns[i]]];
|
|
2105
|
+
}
|
|
2106
|
+
const token_il = state.push("inline", "", 0);
|
|
2107
|
+
token_il.content = columns[i].trim();
|
|
2108
|
+
token_il.children = [];
|
|
2109
|
+
state.push("th_close", "th", -1);
|
|
2110
|
+
}
|
|
2111
|
+
state.push("tr_close", "tr", -1);
|
|
2112
|
+
state.push("thead_close", "thead", -1);
|
|
2113
|
+
let tbodyLines;
|
|
2114
|
+
let autocompletedCells = 0;
|
|
2115
|
+
for (nextLine = startLine + 2;nextLine < endLine; nextLine++) {
|
|
2116
|
+
if (state.sCount[nextLine] < state.blkIndent)
|
|
2117
|
+
break;
|
|
2118
|
+
let terminate = false;
|
|
2119
|
+
for (let i = 0, l = terminatorRules.length;i < l; i++) {
|
|
2120
|
+
if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
2121
|
+
terminate = true;
|
|
2122
|
+
break;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
if (terminate)
|
|
2126
|
+
break;
|
|
2127
|
+
lineText2 = getLine(state, nextLine).trim();
|
|
2128
|
+
if (!lineText2)
|
|
2129
|
+
break;
|
|
2130
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4)
|
|
2131
|
+
break;
|
|
2132
|
+
columns = splitCells(lineText2, spans);
|
|
2133
|
+
if (columns.length && columns[0] === "")
|
|
2134
|
+
columns.shift();
|
|
2135
|
+
if (columns.length && columns[columns.length - 1] === "")
|
|
2136
|
+
columns.pop();
|
|
2137
|
+
if (columns.length > columnCount) {
|
|
2138
|
+
warnExtraCells(state.env, nextLine, columns.length, columnCount);
|
|
2139
|
+
}
|
|
2140
|
+
autocompletedCells += columnCount - columns.length;
|
|
2141
|
+
if (autocompletedCells > MAX_AUTOCOMPLETED_CELLS)
|
|
2142
|
+
break;
|
|
2143
|
+
if (nextLine === startLine + 2) {
|
|
2144
|
+
const token_tbo = state.push("tbody_open", "tbody", 1);
|
|
2145
|
+
token_tbo.map = tbodyLines = [startLine + 2, 0];
|
|
2146
|
+
}
|
|
2147
|
+
const token_tro = state.push("tr_open", "tr", 1);
|
|
2148
|
+
token_tro.map = [nextLine, nextLine + 1];
|
|
2149
|
+
for (let i = 0;i < columnCount; i++) {
|
|
2150
|
+
const token_tdo = state.push("td_open", "td", 1);
|
|
2151
|
+
if (aligns[i]) {
|
|
2152
|
+
token_tdo.attrs = [["style", "text-align:" + aligns[i]]];
|
|
2153
|
+
}
|
|
2154
|
+
const token_il = state.push("inline", "", 0);
|
|
2155
|
+
token_il.content = columns[i] ? columns[i].trim() : "";
|
|
2156
|
+
token_il.children = [];
|
|
2157
|
+
state.push("td_close", "td", -1);
|
|
2158
|
+
}
|
|
2159
|
+
state.push("tr_close", "tr", -1);
|
|
2160
|
+
}
|
|
2161
|
+
if (tbodyLines) {
|
|
2162
|
+
state.push("tbody_close", "tbody", -1);
|
|
2163
|
+
tbodyLines[1] = nextLine;
|
|
2164
|
+
}
|
|
2165
|
+
state.push("table_close", "table", -1);
|
|
2166
|
+
tableLines[1] = nextLine;
|
|
2167
|
+
state.parentType = oldParentType;
|
|
2168
|
+
state.line = nextLine;
|
|
2169
|
+
return true;
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
function gpTable(md, options) {
|
|
2173
|
+
md.block.ruler.at("table", tableRule(options?.spans ?? DEFAULT_SPANS), { alt: ["paragraph", "reference"] });
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
// src/lib/markdown/typography.ts
|
|
2177
|
+
var EM_DASH = /(^|[^-])---(?=[^-]|$)/gm;
|
|
2178
|
+
var EN_DASH_SPACED = /(^|\s)--(?=\s|$)/gm;
|
|
2179
|
+
var EN_DASH = /(^|[^-\s])--(?=[^-\s]|$)/gm;
|
|
2180
|
+
var ELLIPSIS = /\.\.\./g;
|
|
2181
|
+
var CANDIDATE = /--|\.\.\./;
|
|
2182
|
+
function replaceInText(children) {
|
|
2183
|
+
let insideAutolink = 0;
|
|
2184
|
+
for (let i = children.length - 1;i >= 0; i--) {
|
|
2185
|
+
const token = children[i];
|
|
2186
|
+
if (token.type === "text" && !insideAutolink && CANDIDATE.test(token.content)) {
|
|
2187
|
+
token.content = token.content.replace(ELLIPSIS, "…").replace(EM_DASH, "$1—").replace(EN_DASH_SPACED, "$1–").replace(EN_DASH, "$1–");
|
|
2188
|
+
}
|
|
2189
|
+
if (token.type === "link_close" && token.info === "auto")
|
|
2190
|
+
insideAutolink++;
|
|
2191
|
+
if (token.type === "link_open" && token.info === "auto")
|
|
2192
|
+
insideAutolink--;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
var QUOTES = {
|
|
2196
|
+
en: "“”‘’",
|
|
2197
|
+
de: "„“‚‘",
|
|
2198
|
+
"de-ch": "«»‹›",
|
|
2199
|
+
"de-li": "«»‹›",
|
|
2200
|
+
fr: ["« ", " »", "‹ ", " ›"],
|
|
2201
|
+
es: "«»“”",
|
|
2202
|
+
it: "«»“”",
|
|
2203
|
+
pt: "«»“”",
|
|
2204
|
+
"pt-br": "“”‘’",
|
|
2205
|
+
ru: "«»„“",
|
|
2206
|
+
pl: "„”«»",
|
|
2207
|
+
cs: "„“‚‘",
|
|
2208
|
+
sk: "„“‚‘",
|
|
2209
|
+
sv: "””’’",
|
|
2210
|
+
fi: "””’’"
|
|
2211
|
+
};
|
|
2212
|
+
function quotesFor(language) {
|
|
2213
|
+
const tag = (language ?? "en").toLowerCase();
|
|
2214
|
+
return QUOTES[tag] ?? QUOTES[tag.split("-")[0]] ?? QUOTES.en;
|
|
2215
|
+
}
|
|
2216
|
+
function gpTypography(md) {
|
|
2217
|
+
md.disable("replacements");
|
|
2218
|
+
md.core.ruler.after("linkify", "gp_typography", (state) => {
|
|
2219
|
+
for (const token of state.tokens) {
|
|
2220
|
+
if (token.type !== "inline" || !token.children || !CANDIDATE.test(token.content))
|
|
2221
|
+
continue;
|
|
2222
|
+
replaceInText(token.children);
|
|
2223
|
+
}
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
|
|
1926
2227
|
// src/lib/markdown/renderer.ts
|
|
1927
2228
|
import markdownItSourceMap from "markdown-it-source-map";
|
|
1928
2229
|
import markdownItDeflist from "markdown-it-deflist";
|
|
@@ -2026,6 +2327,159 @@ function gfmAlerts(md) {
|
|
|
2026
2327
|
md.core.ruler.after("block", "gp_gfm_alerts", gfmAlertsRule);
|
|
2027
2328
|
}
|
|
2028
2329
|
|
|
2330
|
+
// src/lib/markdown/math.ts
|
|
2331
|
+
import { mathjax } from "mathjax-full/js/mathjax.js";
|
|
2332
|
+
import { TeX } from "mathjax-full/js/input/tex.js";
|
|
2333
|
+
import { SVG } from "mathjax-full/js/output/svg.js";
|
|
2334
|
+
import { liteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
|
|
2335
|
+
import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html.js";
|
|
2336
|
+
import { AssistiveMmlHandler } from "mathjax-full/js/a11y/assistive-mml.js";
|
|
2337
|
+
import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js";
|
|
2338
|
+
function findInlineMathEnd(src, start, max) {
|
|
2339
|
+
const after = src.charCodeAt(start + 1);
|
|
2340
|
+
if (after === 32 || after === 9)
|
|
2341
|
+
return -1;
|
|
2342
|
+
let match = start + 1;
|
|
2343
|
+
while ((match = src.indexOf("$", match)) !== -1 && match < max) {
|
|
2344
|
+
let pos = match - 1;
|
|
2345
|
+
while (src.charCodeAt(pos) === 92)
|
|
2346
|
+
pos--;
|
|
2347
|
+
if ((match - pos) % 2 === 1)
|
|
2348
|
+
break;
|
|
2349
|
+
match++;
|
|
2350
|
+
}
|
|
2351
|
+
if (match === -1 || match >= max)
|
|
2352
|
+
return -1;
|
|
2353
|
+
if (match === start + 1)
|
|
2354
|
+
return -2;
|
|
2355
|
+
const before = src.charCodeAt(match - 1);
|
|
2356
|
+
const next = src.charCodeAt(match + 1);
|
|
2357
|
+
if (before === 32 || before === 9 || next >= 48 && next <= 57)
|
|
2358
|
+
return -1;
|
|
2359
|
+
return match;
|
|
2360
|
+
}
|
|
2361
|
+
var scanInlineMath = (src, start, max) => {
|
|
2362
|
+
const end = findInlineMathEnd(src, start, max);
|
|
2363
|
+
return end >= 0 ? end + 1 : end === -2 ? start + 2 : start + 1;
|
|
2364
|
+
};
|
|
2365
|
+
function mathInline(state, silent) {
|
|
2366
|
+
if (state.src.charCodeAt(state.pos) !== 36)
|
|
2367
|
+
return false;
|
|
2368
|
+
const end = findInlineMathEnd(state.src, state.pos, state.posMax);
|
|
2369
|
+
if (end < 0) {
|
|
2370
|
+
const literal = end === -2 ? "$$" : "$";
|
|
2371
|
+
if (!silent)
|
|
2372
|
+
state.pending += literal;
|
|
2373
|
+
state.pos += literal.length;
|
|
2374
|
+
return true;
|
|
2375
|
+
}
|
|
2376
|
+
if (!silent) {
|
|
2377
|
+
const token = state.push("math_inline", "math", 0);
|
|
2378
|
+
token.markup = "$";
|
|
2379
|
+
token.content = state.src.slice(state.pos + 1, end);
|
|
2380
|
+
}
|
|
2381
|
+
state.pos = end + 1;
|
|
2382
|
+
return true;
|
|
2383
|
+
}
|
|
2384
|
+
function mathBlock(state, start, end, silent) {
|
|
2385
|
+
let pos = state.bMarks[start] + state.tShift[start];
|
|
2386
|
+
let max = state.eMarks[start];
|
|
2387
|
+
if (pos + 2 > max)
|
|
2388
|
+
return false;
|
|
2389
|
+
if (state.src.slice(pos, pos + 2) !== "$$")
|
|
2390
|
+
return false;
|
|
2391
|
+
pos += 2;
|
|
2392
|
+
let firstLine = state.src.slice(pos, max);
|
|
2393
|
+
if (silent)
|
|
2394
|
+
return true;
|
|
2395
|
+
let found = false;
|
|
2396
|
+
let lastLine = "";
|
|
2397
|
+
if (firstLine.trim().slice(-2) === "$$") {
|
|
2398
|
+
firstLine = firstLine.trim().slice(0, -2);
|
|
2399
|
+
found = true;
|
|
2400
|
+
}
|
|
2401
|
+
let next = start;
|
|
2402
|
+
while (!found) {
|
|
2403
|
+
next++;
|
|
2404
|
+
if (next >= end)
|
|
2405
|
+
break;
|
|
2406
|
+
pos = state.bMarks[next] + state.tShift[next];
|
|
2407
|
+
max = state.eMarks[next];
|
|
2408
|
+
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
2409
|
+
break;
|
|
2410
|
+
}
|
|
2411
|
+
if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
|
|
2412
|
+
const lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
2413
|
+
lastLine = state.src.slice(pos, lastPos);
|
|
2414
|
+
found = true;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
state.line = next + 1;
|
|
2418
|
+
const token = state.push("math_block", "math", 0);
|
|
2419
|
+
token.block = true;
|
|
2420
|
+
token.content = (firstLine && firstLine.trim() ? firstLine + `
|
|
2421
|
+
` : "") + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
2422
|
+
token.map = [start, state.line];
|
|
2423
|
+
token.markup = "$$";
|
|
2424
|
+
return true;
|
|
2425
|
+
}
|
|
2426
|
+
var adaptor = null;
|
|
2427
|
+
function getAdaptor() {
|
|
2428
|
+
if (!adaptor) {
|
|
2429
|
+
adaptor = liteAdaptor();
|
|
2430
|
+
AssistiveMmlHandler(RegisterHTMLHandler(adaptor));
|
|
2431
|
+
}
|
|
2432
|
+
return adaptor;
|
|
2433
|
+
}
|
|
2434
|
+
var PACKAGES = AllPackages.filter((name) => name !== "noerrors" && name !== "noundefined");
|
|
2435
|
+
function gpMath(md) {
|
|
2436
|
+
const html = getAdaptor();
|
|
2437
|
+
let errors = [];
|
|
2438
|
+
const tex = new TeX({
|
|
2439
|
+
packages: PACKAGES,
|
|
2440
|
+
formatError: (jax, err) => {
|
|
2441
|
+
errors.push(err.message);
|
|
2442
|
+
return jax.formatError(err);
|
|
2443
|
+
}
|
|
2444
|
+
});
|
|
2445
|
+
const document = mathjax.document("", { InputJax: tex, OutputJax: new SVG({ fontCache: "none" }) });
|
|
2446
|
+
const typeset = (token, display, env) => {
|
|
2447
|
+
errors = [];
|
|
2448
|
+
const out = html.outerHTML(document.convert(token.content, { display }));
|
|
2449
|
+
for (const message of errors) {
|
|
2450
|
+
if (!env.layoutWarnings)
|
|
2451
|
+
env.layoutWarnings = [];
|
|
2452
|
+
env.layoutWarnings.push({
|
|
2453
|
+
line: token.meta?.line ?? (token.map?.[0] ?? 0) + 1,
|
|
2454
|
+
type: "math_error",
|
|
2455
|
+
message: `This formula could not be typeset: ${message}. It prints in red until it is fixed.`
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
return display ? out + `
|
|
2459
|
+
` : out;
|
|
2460
|
+
};
|
|
2461
|
+
md.inline.ruler.after("escape", "math_inline", mathInline);
|
|
2462
|
+
md.block.ruler.after("blockquote", "math_block", mathBlock, {
|
|
2463
|
+
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
2464
|
+
});
|
|
2465
|
+
md.core.ruler.after("inline", "math_lines", (state) => {
|
|
2466
|
+
let line = 1;
|
|
2467
|
+
for (const token of state.tokens) {
|
|
2468
|
+
if (token.map)
|
|
2469
|
+
line = token.map[0] + 1;
|
|
2470
|
+
if (token.type !== "inline" || !token.children)
|
|
2471
|
+
continue;
|
|
2472
|
+
for (const child of token.children) {
|
|
2473
|
+
if (child.type === "math_inline")
|
|
2474
|
+
child.meta = { line };
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
});
|
|
2478
|
+
md.renderer.rules.math_inline = (tokens, idx, _options, env) => typeset(tokens[idx], false, env);
|
|
2479
|
+
md.renderer.rules.math_block = (tokens, idx, _options, env) => typeset(tokens[idx], true, env);
|
|
2480
|
+
md.use(gpTable, { spans: { ...DEFAULT_SPANS, 36: scanInlineMath } });
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2029
2483
|
// src/lib/markdown/images.ts
|
|
2030
2484
|
var isSrcsetSpace = (char) => char === "\t" || char === `
|
|
2031
2485
|
` || char === "\f" || char === "\r" || char === " ";
|
|
@@ -2452,14 +2906,17 @@ var BUILTIN_OPTIONAL_PLUGINS = {
|
|
|
2452
2906
|
"markdown-it-sub": unwrapPlugin(markdownItSub),
|
|
2453
2907
|
"markdown-it-sup": unwrapPlugin(markdownItSup),
|
|
2454
2908
|
"markdown-it-abbr": unwrapPlugin(markdownItAbbr),
|
|
2455
|
-
"gutterpress-gfm-alerts": gfmAlerts
|
|
2909
|
+
"gutterpress-gfm-alerts": gfmAlerts,
|
|
2910
|
+
"gutterpress-math": gpMath
|
|
2456
2911
|
};
|
|
2457
|
-
function createMarkdownRenderer(customPlugins) {
|
|
2912
|
+
function createMarkdownRenderer(customPlugins, options) {
|
|
2458
2913
|
const md = new MarkdownIt({
|
|
2459
2914
|
html: true,
|
|
2460
2915
|
linkify: true,
|
|
2461
|
-
typographer: true
|
|
2916
|
+
typographer: true,
|
|
2917
|
+
quotes: quotesFor(options?.language)
|
|
2462
2918
|
});
|
|
2919
|
+
md.use(gpTypography);
|
|
2463
2920
|
md.use(unwrapPlugin(markdownItAttrs));
|
|
2464
2921
|
md.use(unwrapPlugin(markdownItFootnote));
|
|
2465
2922
|
md.use(unwrapPlugin(markdownItDeflist));
|
|
@@ -2469,6 +2926,7 @@ function createMarkdownRenderer(customPlugins) {
|
|
|
2469
2926
|
md.use(plugin, { declaredMarkers });
|
|
2470
2927
|
md.use(gpPinScope);
|
|
2471
2928
|
md.use(gpBlockNames);
|
|
2929
|
+
md.use(gpTable);
|
|
2472
2930
|
md.use(gpTableAlign);
|
|
2473
2931
|
md.use(gpTwoVersions);
|
|
2474
2932
|
registerImageRule(md);
|
|
@@ -3108,11 +3566,12 @@ async function assembleBookHtml(opts) {
|
|
|
3108
3566
|
const title = opts.title ?? "Document";
|
|
3109
3567
|
const projectCss = opts.projectCss ?? "";
|
|
3110
3568
|
const pluginCss = opts.pluginCss ?? "";
|
|
3569
|
+
const language = opts.language ?? "en";
|
|
3111
3570
|
const files = opts.files;
|
|
3112
3571
|
if (files.length === 0) {
|
|
3113
3572
|
throw new Error("No markdown files to render");
|
|
3114
3573
|
}
|
|
3115
|
-
const md = createMarkdownRenderer(opts.plugins);
|
|
3574
|
+
const md = createMarkdownRenderer(opts.plugins, { language });
|
|
3116
3575
|
let bodyContent = "";
|
|
3117
3576
|
const imageRefs = new Set;
|
|
3118
3577
|
for (const file of files) {
|
|
@@ -3124,7 +3583,7 @@ async function assembleBookHtml(opts) {
|
|
|
3124
3583
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
3125
3584
|
throw new Error(`Failed to read file ${file}: ${errorMsg}`);
|
|
3126
3585
|
}
|
|
3127
|
-
const env = {};
|
|
3586
|
+
const env = { docId: slugify(chapterId) };
|
|
3128
3587
|
if (opts.annotateSourceChapters)
|
|
3129
3588
|
env.sourceChapter = chapterId;
|
|
3130
3589
|
const rendered = md.render(content, env);
|
|
@@ -3170,7 +3629,7 @@ ${projectCss.trim()}` : null
|
|
|
3170
3629
|
const lastPage = opts.print && lastPageMode(opts.print);
|
|
3171
3630
|
const printAttrs = (opts.print?.signature && opts.print.signature > 1 ? ` data-gp-signature="${opts.print.signature}"` : "") + (lastPage ? ` data-gp-last-page="${lastPage}"` : "");
|
|
3172
3631
|
return `<!DOCTYPE html>
|
|
3173
|
-
<html lang="
|
|
3632
|
+
<html lang="${language}"${printAttrs}>
|
|
3174
3633
|
<head>
|
|
3175
3634
|
<meta charset="UTF-8">
|
|
3176
3635
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">${opts.printArea ? `
|
|
@@ -91,6 +91,12 @@ interface PublishSettings {
|
|
|
91
91
|
export interface GutterpressManifest {
|
|
92
92
|
title?: string;
|
|
93
93
|
authors?: string[];
|
|
94
|
+
/**
|
|
95
|
+
* The book's language as a BCP 47 tag (`en`, `de-CH`, `pt-BR`); default
|
|
96
|
+
* `en`. It is the `lang` of the built HTML, which is what hyphenation
|
|
97
|
+
* follows, and the typographer sets quotation marks by it.
|
|
98
|
+
*/
|
|
99
|
+
language?: string;
|
|
94
100
|
publish?: PublishSettings;
|
|
95
101
|
/** How the book is designed (ADR 0008). The registry in lib/presets.ts is authoritative. */
|
|
96
102
|
preset?: "dtrpg" | "book" | "custom";
|
|
@@ -318,6 +324,8 @@ export interface PrintSpec {
|
|
|
318
324
|
export interface ResolvedConfig {
|
|
319
325
|
title: string;
|
|
320
326
|
authors: string[];
|
|
327
|
+
/** BCP 47 language tag; `en` when the manifest sets none. */
|
|
328
|
+
language: string;
|
|
321
329
|
/** The id of the preset this book resolved against (`dtrpg`, `book`, `custom`). */
|
|
322
330
|
preset: string;
|
|
323
331
|
/** The printer spec that preset follows, when it follows one: how a host credits the numbers it draws. */
|
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
switchBranch,
|
|
22
22
|
whenGitIdle,
|
|
23
23
|
withRepoLock
|
|
24
|
-
} from "./index-
|
|
25
|
-
import"./index-
|
|
24
|
+
} from "./index-h6yk5tjx.js";
|
|
25
|
+
import"./index-5x42amh8.js";
|
|
26
26
|
import"./index-v5mp7a6q.js";
|
|
27
27
|
import"./index-37x76zdn.js";
|
|
28
28
|
export {
|