@kensio/colophon 2.11.1 → 2.13.0
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 +4 -1
- package/dist/astro/index.d.ts.map +1 -1
- package/dist/astro/index.js +0 -1
- package/dist/astro/index.js.map +1 -1
- package/dist/config/defaults.d.ts +24 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +29 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/size.d.ts.map +1 -1
- package/dist/config/size.js +3 -0
- package/dist/config/size.js.map +1 -1
- package/dist/layout/fill.d.ts +32 -0
- package/dist/layout/fill.d.ts.map +1 -0
- package/dist/layout/fill.js +34 -0
- package/dist/layout/fill.js.map +1 -0
- package/dist/layout/index.d.ts +4 -2
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +2 -1
- package/dist/layout/index.js.map +1 -1
- package/dist/measure/faces.d.ts.map +1 -1
- package/dist/measure/faces.js.map +1 -1
- package/dist/render/svg.js +1 -1
- package/dist/render/svg.js.map +1 -1
- package/dist/templates/banner/index.js +2 -2
- package/dist/templates/banner/index.js.map +1 -1
- package/dist/templates/card/index.js +2 -2
- package/dist/templates/card/index.js.map +1 -1
- package/dist/templates/code/bar.d.ts +24 -0
- package/dist/templates/code/bar.d.ts.map +1 -0
- package/dist/templates/code/bar.js +31 -0
- package/dist/templates/code/bar.js.map +1 -0
- package/dist/templates/code/gutter.d.ts +30 -0
- package/dist/templates/code/gutter.d.ts.map +1 -0
- package/dist/templates/code/gutter.js +64 -0
- package/dist/templates/code/gutter.js.map +1 -0
- package/dist/templates/code/index.d.ts.map +1 -1
- package/dist/templates/code/index.js +34 -15
- package/dist/templates/code/index.js.map +1 -1
- package/dist/templates/code/layout.d.ts +6 -1
- package/dist/templates/code/layout.d.ts.map +1 -1
- package/dist/templates/code/layout.js +8 -3
- package/dist/templates/code/layout.js.map +1 -1
- package/dist/templates/code/mark/draw.d.ts +26 -0
- package/dist/templates/code/mark/draw.d.ts.map +1 -0
- package/dist/templates/code/mark/draw.js +41 -0
- package/dist/templates/code/mark/draw.js.map +1 -0
- package/dist/templates/code/mark/index.d.ts +16 -0
- package/dist/templates/code/mark/index.d.ts.map +1 -0
- package/dist/templates/code/mark/index.js +34 -0
- package/dist/templates/code/mark/index.js.map +1 -0
- package/dist/templates/code/mark/locate.d.ts +20 -0
- package/dist/templates/code/mark/locate.d.ts.map +1 -0
- package/dist/templates/code/mark/locate.js +56 -0
- package/dist/templates/code/mark/locate.js.map +1 -0
- package/dist/templates/code/mark/read.d.ts +30 -0
- package/dist/templates/code/mark/read.d.ts.map +1 -0
- package/dist/templates/code/mark/read.js +61 -0
- package/dist/templates/code/mark/read.js.map +1 -0
- package/dist/templates/code/plate.d.ts +7 -1
- package/dist/templates/code/plate.d.ts.map +1 -1
- package/dist/templates/code/plate.js +14 -4
- package/dist/templates/code/plate.js.map +1 -1
- package/dist/templates/footer.d.ts +9 -1
- package/dist/templates/footer.d.ts.map +1 -1
- package/dist/templates/footer.js +24 -0
- package/dist/templates/footer.js.map +1 -1
- package/dist/templates/frame.d.ts.map +1 -1
- package/dist/templates/frame.js +5 -7
- package/dist/templates/frame.js.map +1 -1
- package/dist/templates/index.d.ts +1 -0
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +3 -0
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/terminal/index.js +4 -4
- package/dist/templates/terminal/index.js.map +1 -1
- package/dist/templates/thumbnail/index.d.ts +21 -0
- package/dist/templates/thumbnail/index.d.ts.map +1 -0
- package/dist/templates/thumbnail/index.js +68 -0
- package/dist/templates/thumbnail/index.js.map +1 -0
- package/dist/templates/thumbnail/lines.d.ts +38 -0
- package/dist/templates/thumbnail/lines.d.ts.map +1 -0
- package/dist/templates/thumbnail/lines.js +76 -0
- package/dist/templates/thumbnail/lines.js.map +1 -0
- package/dist/templates/window/dots.d.ts +11 -0
- package/dist/templates/window/dots.d.ts.map +1 -0
- package/dist/templates/window/dots.js +32 -0
- package/dist/templates/window/dots.js.map +1 -0
- package/dist/templates/{terminal/window.d.ts → window/index.d.ts} +4 -2
- package/dist/templates/window/index.d.ts.map +1 -0
- package/dist/templates/window/index.js +48 -0
- package/dist/templates/window/index.js.map +1 -0
- package/dist/templates/window/title.d.ts +9 -0
- package/dist/templates/window/title.d.ts.map +1 -0
- package/dist/templates/window/title.js +24 -0
- package/dist/templates/window/title.js.map +1 -0
- package/dist/text/fill.d.ts +34 -0
- package/dist/text/fill.d.ts.map +1 -0
- package/dist/text/fill.js +57 -0
- package/dist/text/fill.js.map +1 -0
- package/dist/text/fit.d.ts.map +1 -1
- package/dist/text/fit.js +2 -6
- package/dist/text/fit.js.map +1 -1
- package/dist/text/index.d.ts +2 -0
- package/dist/text/index.d.ts.map +1 -1
- package/dist/text/index.js +1 -0
- package/dist/text/index.js.map +1 -1
- package/dist/text/step.d.ts +13 -0
- package/dist/text/step.d.ts.map +1 -0
- package/dist/text/step.js +17 -0
- package/dist/text/step.js.map +1 -0
- package/dist/text/unbroken.d.ts +22 -0
- package/dist/text/unbroken.d.ts.map +1 -0
- package/dist/text/unbroken.js +29 -0
- package/dist/text/unbroken.js.map +1 -0
- package/dist/texture/chevrons.d.ts +13 -0
- package/dist/texture/chevrons.d.ts.map +1 -0
- package/dist/texture/chevrons.js +22 -0
- package/dist/texture/chevrons.js.map +1 -0
- package/dist/texture/grid.d.ts +14 -0
- package/dist/texture/grid.d.ts.map +1 -0
- package/dist/texture/grid.js +38 -0
- package/dist/texture/grid.js.map +1 -0
- package/dist/texture/halftone.d.ts +14 -0
- package/dist/texture/halftone.d.ts.map +1 -0
- package/dist/texture/halftone.js +55 -0
- package/dist/texture/halftone.js.map +1 -0
- package/dist/texture/honeycomb.d.ts +14 -0
- package/dist/texture/honeycomb.d.ts.map +1 -0
- package/dist/texture/honeycomb.js +43 -0
- package/dist/texture/honeycomb.js.map +1 -0
- package/dist/texture/index.d.ts +15 -4
- package/dist/texture/index.d.ts.map +1 -1
- package/dist/texture/index.js +64 -14
- package/dist/texture/index.js.map +1 -1
- package/dist/texture/moire.d.ts +18 -0
- package/dist/texture/moire.d.ts.map +1 -0
- package/dist/texture/moire.js +44 -0
- package/dist/texture/moire.js.map +1 -0
- package/dist/texture/pattern.d.ts +10 -0
- package/dist/texture/pattern.d.ts.map +1 -1
- package/dist/texture/pattern.js +36 -13
- package/dist/texture/pattern.js.map +1 -1
- package/dist/texture/rays.d.ts +13 -0
- package/dist/texture/rays.d.ts.map +1 -0
- package/dist/texture/rays.js +36 -0
- package/dist/texture/rays.js.map +1 -0
- package/dist/texture/resolve.d.ts +10 -0
- package/dist/texture/resolve.d.ts.map +1 -1
- package/dist/texture/resolve.js +15 -0
- package/dist/texture/resolve.js.map +1 -1
- package/dist/texture/scallops.d.ts +14 -0
- package/dist/texture/scallops.d.ts.map +1 -0
- package/dist/texture/scallops.js +29 -0
- package/dist/texture/scallops.js.map +1 -0
- package/dist/texture/tile.d.ts +14 -0
- package/dist/texture/tile.d.ts.map +1 -0
- package/dist/texture/tile.js +23 -0
- package/dist/texture/tile.js.map +1 -0
- package/dist/texture/topographic/contours.d.ts +13 -0
- package/dist/texture/topographic/contours.d.ts.map +1 -0
- package/dist/texture/topographic/contours.js +72 -0
- package/dist/texture/topographic/contours.js.map +1 -0
- package/dist/texture/topographic/field.d.ts +8 -0
- package/dist/texture/topographic/field.d.ts.map +1 -0
- package/dist/texture/topographic/field.js +29 -0
- package/dist/texture/topographic/field.js.map +1 -0
- package/dist/texture/topographic/index.d.ts +17 -0
- package/dist/texture/topographic/index.d.ts.map +1 -0
- package/dist/texture/topographic/index.js +48 -0
- package/dist/texture/topographic/index.js.map +1 -0
- package/dist/theme/presets.d.ts +13 -5
- package/dist/theme/presets.d.ts.map +1 -1
- package/dist/theme/presets.js +16 -5
- package/dist/theme/presets.js.map +1 -1
- package/dist/types.d.ts +259 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/collect.d.ts.map +1 -1
- package/dist/validate/collect.js +2 -1
- package/dist/validate/collect.js.map +1 -1
- package/dist/validate/keys.d.ts +37 -0
- package/dist/validate/keys.d.ts.map +1 -1
- package/dist/validate/keys.js +132 -2
- package/dist/validate/keys.js.map +1 -1
- package/dist/validate/texture.d.ts +4 -5
- package/dist/validate/texture.d.ts.map +1 -1
- package/dist/validate/texture.js +11 -20
- package/dist/validate/texture.js.map +1 -1
- package/dist/validate/values.d.ts +6 -0
- package/dist/validate/values.d.ts.map +1 -1
- package/dist/validate/values.js +16 -1
- package/dist/validate/values.js.map +1 -1
- package/package.json +3 -10
- package/dist/templates/terminal/window.d.ts.map +0 -1
- package/dist/templates/terminal/window.js +0 -84
- package/dist/templates/terminal/window.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gutter.js","sourceRoot":"","sources":["../../../src/templates/code/gutter.ts"],"names":[],"mappings":"AAGA,8DAA8D;AAC9D,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,+DAA+D;AAC/D,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAsB,EAAE,KAAa;IACjE,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW;QAC5B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS;QAC/C,CAAC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,0EAA0E;AAC1E,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE1B,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,MAAM;QACzC,yEAAyE;QACzE,uDAAuD;QACvD,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,KAAK;KACd,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CACzB,KAAwC,EACxC,OAAe,EACf,OAAe;IAEf,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrC,GAAG,KAAK;YACR,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO;SAC/B,CAAC,CAAC,CAAC;QAEJ,OAAO,KAAK,GAAG,QAAQ;YACrB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;YAC/C,CAAC,CAAC,OAAO,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/code/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/code/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAe/C;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,QA8G1B,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { highlightCode } from "../../highlight/index.js";
|
|
2
|
-
import { hasFooter } from "../footer.js";
|
|
2
|
+
import { footerFontSize, hasFooter } from "../footer.js";
|
|
3
3
|
import { optionalString } from "../../props.js";
|
|
4
|
+
import { barRoom, windowBar } from "./bar.js";
|
|
4
5
|
import { codeFooter, codeHeading } from "./chrome.js";
|
|
5
6
|
import { blockColumns } from "./fit.js";
|
|
7
|
+
import { gutterColumns, numberLines } from "./gutter.js";
|
|
8
|
+
import { codeMarks } from "./mark/index.js";
|
|
6
9
|
import { fitSnippet } from "./layout.js";
|
|
7
10
|
import { layoutPanel, titleBand } from "./panel.js";
|
|
8
11
|
import { hugPanel, panelSvg } from "./plate.js";
|
|
@@ -24,40 +27,56 @@ export const codeTemplate = {
|
|
|
24
27
|
const { width, height } = dimensions;
|
|
25
28
|
const title = optionalString(props.title);
|
|
26
29
|
const titleFs = Math.round(height * 0.045);
|
|
27
|
-
const footerFs =
|
|
30
|
+
const footerFs = footerFontSize(dimensions);
|
|
28
31
|
const highlighted = await highlightCode(optionalString(props["code"]) ?? "", {
|
|
29
32
|
language: optionalString(props["language"]) ?? "text",
|
|
30
33
|
theme: optionalString(props["theme"]) ?? config.code.theme,
|
|
31
34
|
tabSize: config.code.tabSize,
|
|
32
35
|
});
|
|
33
36
|
const available = layoutPanel(dimensions, config, titleFs, footerFs, title !== undefined && title !== "", hasFooter(config));
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}, highlighted.lines.length);
|
|
37
|
+
const bar = barRoom(config, available.width);
|
|
38
|
+
const gutter = gutterColumns(config, highlighted.lines.length);
|
|
39
|
+
const fitted = fitSnippet(highlighted, { ...available, y: available.y + bar, height: available.height - bar }, width, config, charWidthRatio(measure, config.code.fontFamily), gutter);
|
|
40
|
+
const dropped = highlighted.lines.length - fitted.lines.length;
|
|
41
|
+
warnIfTruncated(config, dimensions, { dropped, clipped: fitted.clipped }, highlighted.lines.length);
|
|
42
|
+
const lines = numberLines(fitted.lines, gutter, dropped);
|
|
39
43
|
// Shrink the panel down onto the snippet so it isn't left floating in dead
|
|
40
44
|
// space. On a landscape image especially, a wide panel holding a narrow
|
|
41
45
|
// block leaves the code marooned off to one side.
|
|
46
|
+
const bodyHeight = fitted.lines.length * fitted.step;
|
|
42
47
|
const panel = hugPanel(available, {
|
|
43
|
-
width: blockColumns(
|
|
44
|
-
height:
|
|
48
|
+
width: blockColumns(lines) * fitted.charWidth + fitted.padding * 2,
|
|
49
|
+
height: bar + bodyHeight + fitted.padding * 2,
|
|
45
50
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
// Code reads from the left edge, as it does in an editor. Indentation is
|
|
52
|
+
// carried by each token's column, so the snippet keeps its shape.
|
|
53
|
+
const originX = panel.x + fitted.padding;
|
|
54
|
+
const originY = panel.y + bar + (panel.height - bar - bodyHeight) / 2;
|
|
55
|
+
const body = codeBody(lines, {
|
|
56
|
+
originX,
|
|
57
|
+
originY,
|
|
51
58
|
fontSize: fitted.fontSize,
|
|
52
59
|
charWidth: fitted.charWidth,
|
|
53
60
|
step: fitted.step,
|
|
54
61
|
fontFamily: config.code.fontFamily,
|
|
55
62
|
foreground: highlighted.foreground,
|
|
56
63
|
});
|
|
64
|
+
const marks = codeMarks(props, fitted.lines, {
|
|
65
|
+
// Past the gutter, since a mark names columns of the code rather than
|
|
66
|
+
// of the grid the numbers share with it.
|
|
67
|
+
originX: originX + gutter * fitted.charWidth,
|
|
68
|
+
originY,
|
|
69
|
+
charWidth: fitted.charWidth,
|
|
70
|
+
fontSize: fitted.fontSize,
|
|
71
|
+
step: fitted.step,
|
|
72
|
+
band: { x: originX, width: panel.width - fitted.padding * 2 },
|
|
73
|
+
}, config);
|
|
57
74
|
const shadowOffset = Math.round(Math.min(width, height) * 0.01);
|
|
58
|
-
const plate = panelSvg(panel, highlighted.background, Math.max(1, shadowOffset));
|
|
75
|
+
const plate = panelSvg(panel, highlighted.background, Math.max(1, shadowOffset), config);
|
|
59
76
|
return (codeHeading(title, titleBand(panel, dimensions, titleFs), titleFs, config) +
|
|
60
77
|
plate +
|
|
78
|
+
windowBar(panel, bar, props, config, measure) +
|
|
79
|
+
marks +
|
|
61
80
|
body +
|
|
62
81
|
codeFooter(dimensions, footerFs, config));
|
|
63
82
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/code/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/code/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,11 @@ export interface FittedCode {
|
|
|
16
16
|
/**
|
|
17
17
|
* Fit a highlighted snippet into the panel it has been allotted: choose the
|
|
18
18
|
* font size, then drop and clip whatever still does not fit.
|
|
19
|
+
*
|
|
20
|
+
* `gutter` is columns reserved to the left of the code, for line numbers. It
|
|
21
|
+
* is counted in characters rather than pixels because that is what it is: the
|
|
22
|
+
* numbers sit on the same monospace grid, so the space they take follows
|
|
23
|
+
* whatever font size the fitting settles on.
|
|
19
24
|
*/
|
|
20
|
-
export declare function fitSnippet(highlighted: HighlightedCode, available: Panel, imageWidth: number, config: ResolvedConfig, charWidthRatio: number): FittedCode;
|
|
25
|
+
export declare function fitSnippet(highlighted: HighlightedCode, available: Panel, imageWidth: number, config: ResolvedConfig, charWidthRatio: number, gutter?: number): FittedCode;
|
|
21
26
|
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/templates/code/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/templates/code/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,MAAM,SAAI,GACT,UAAU,CA6BZ"}
|
|
@@ -3,15 +3,20 @@ import { fitFontSize, fitLines } from "./fit.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Fit a highlighted snippet into the panel it has been allotted: choose the
|
|
5
5
|
* font size, then drop and clip whatever still does not fit.
|
|
6
|
+
*
|
|
7
|
+
* `gutter` is columns reserved to the left of the code, for line numbers. It
|
|
8
|
+
* is counted in characters rather than pixels because that is what it is: the
|
|
9
|
+
* numbers sit on the same monospace grid, so the space they take follows
|
|
10
|
+
* whatever font size the fitting settles on.
|
|
6
11
|
*/
|
|
7
|
-
export function fitSnippet(highlighted, available, imageWidth, config, charWidthRatio) {
|
|
12
|
+
export function fitSnippet(highlighted, available, imageWidth, config, charWidthRatio, gutter = 0) {
|
|
8
13
|
const inner = Math.round(Math.min(available.width, available.height) * 0.07);
|
|
9
14
|
const codeWidth = Math.max(1, available.width - inner * 2);
|
|
10
15
|
const codeHeight = Math.max(1, available.height - inner * 2);
|
|
11
|
-
const fontSize = fitFontSize(highlighted, { width: codeWidth, height: codeHeight }, imageWidth, config, charWidthRatio);
|
|
16
|
+
const fontSize = fitFontSize({ ...highlighted, longestLine: highlighted.longestLine + gutter }, { width: codeWidth, height: codeHeight }, imageWidth, config, charWidthRatio);
|
|
12
17
|
const charWidth = fontSize * charWidthRatio;
|
|
13
18
|
const step = fontSize * config.code.lineHeight;
|
|
14
|
-
const { lines, clipped } = clipLines(fitLines(highlighted.lines, codeHeight, step), Math.max(1, Math.floor(codeWidth / charWidth)));
|
|
19
|
+
const { lines, clipped } = clipLines(fitLines(highlighted.lines, codeHeight, step), Math.max(1, Math.floor(codeWidth / charWidth) - gutter));
|
|
15
20
|
// Padding reads best proportional to the text rather than the panel, since a
|
|
16
21
|
// snippet fitted down to a small size wants tighter margins. Only ever
|
|
17
22
|
// shrink, so the code area the font was fitted against stays valid.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/templates/code/layout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBjD
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/templates/code/layout.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBjD;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CACxB,WAA4B,EAC5B,SAAgB,EAChB,UAAkB,EAClB,MAAsB,EACtB,cAAsB,EACtB,MAAM,GAAG,CAAC;IAEV,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,WAAW,CAC1B,EAAE,GAAG,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,GAAG,MAAM,EAAE,EACjE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,EACxC,UAAU,EACV,MAAM,EACN,cAAc,CACf,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;IAC5C,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;IAE/C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,CAClC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAC7C,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,CACxD,CAAC;IAEF,6EAA6E;IAC7E,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,EAC3C,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CACzB,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MarkSpan } from "./locate.js";
|
|
2
|
+
/** Where the code sits, so a mark can be put over the right characters. */
|
|
3
|
+
export interface MarkMetrics {
|
|
4
|
+
/** Where column zero of the code is, past the gutter. */
|
|
5
|
+
readonly originX: number;
|
|
6
|
+
readonly originY: number;
|
|
7
|
+
readonly charWidth: number;
|
|
8
|
+
readonly fontSize: number;
|
|
9
|
+
readonly step: number;
|
|
10
|
+
/** Across, for a mark that takes a whole line rather than a span of one. */
|
|
11
|
+
readonly band: {
|
|
12
|
+
readonly x: number;
|
|
13
|
+
readonly width: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A mark over one span of code: a box around the characters, or a band across
|
|
18
|
+
* the line where the post named no columns.
|
|
19
|
+
*
|
|
20
|
+
* The box is stroked and the band is filled, which is the difference between
|
|
21
|
+
* pointing at something and highlighting it. Both take the palette's warm
|
|
22
|
+
* accent by default, so a mark is the one thing on the image that is neither
|
|
23
|
+
* the code theme's colours nor the site's brand.
|
|
24
|
+
*/
|
|
25
|
+
export declare function markSvg(span: MarkSpan, metrics: MarkMetrics, color: string): string;
|
|
26
|
+
//# sourceMappingURL=draw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw.d.ts","sourceRoot":"","sources":["../../../../src/templates/code/mark/draw.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,GACZ,MAAM,CA2BR"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { box } from "../../../layout/index.js";
|
|
2
|
+
/** Clear space around the marked characters, as a fraction of the size. */
|
|
3
|
+
const padScale = 0.16;
|
|
4
|
+
/** The band a line's glyphs are drawn in, which is what a mark encloses. */
|
|
5
|
+
function lineRect(span, metrics) {
|
|
6
|
+
const { originY, step, fontSize } = metrics;
|
|
7
|
+
const pad = fontSize * padScale;
|
|
8
|
+
return {
|
|
9
|
+
y: Math.round(originY + span.line * step + (step - fontSize) / 2 - pad),
|
|
10
|
+
height: Math.round(fontSize + pad * 2),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A mark over one span of code: a box around the characters, or a band across
|
|
15
|
+
* the line where the post named no columns.
|
|
16
|
+
*
|
|
17
|
+
* The box is stroked and the band is filled, which is the difference between
|
|
18
|
+
* pointing at something and highlighting it. Both take the palette's warm
|
|
19
|
+
* accent by default, so a mark is the one thing on the image that is neither
|
|
20
|
+
* the code theme's colours nor the site's brand.
|
|
21
|
+
*/
|
|
22
|
+
export function markSvg(span, metrics, color) {
|
|
23
|
+
const { originX, charWidth, fontSize } = metrics;
|
|
24
|
+
const { y, height } = lineRect(span, metrics);
|
|
25
|
+
const fill = span.color ?? color;
|
|
26
|
+
if (span.length === undefined) {
|
|
27
|
+
return box({ x: metrics.band.x, y, width: metrics.band.width, height }, { radius: Math.round(fontSize * 0.2), fill, fillOpacity: 0.16 });
|
|
28
|
+
}
|
|
29
|
+
const pad = charWidth * padScale;
|
|
30
|
+
return box({
|
|
31
|
+
x: Math.round(originX + span.column * charWidth - pad),
|
|
32
|
+
y,
|
|
33
|
+
width: Math.round(span.length * charWidth + pad * 2),
|
|
34
|
+
height,
|
|
35
|
+
}, {
|
|
36
|
+
radius: Math.round(fontSize * 0.2),
|
|
37
|
+
stroke: fill,
|
|
38
|
+
strokeWidth: Math.max(1, Math.round(fontSize * 0.08)),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=draw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw.js","sourceRoot":"","sources":["../../../../src/templates/code/mark/draw.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAe/C,2EAA2E;AAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC;AAEtB,4EAA4E;AAC5E,SAAS,QAAQ,CACf,IAAc,EACd,OAAoB;IAEpB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,GAAG,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEhC,OAAO;QACL,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACvE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC;KACvC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,IAAc,EACd,OAAoB,EACpB,KAAa;IAEb,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACjD,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;IAEjC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,CACR,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAC3D,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,SAAS,GAAG,QAAQ,CAAC;IAEjC,OAAO,GAAG,CACR;QACE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC;QACtD,CAAC;QACD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;QACpD,MAAM;KACP,EACD;QACE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC;QAClC,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;KACtD,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CodeToken } from "../../../highlight/index.js";
|
|
2
|
+
import type { MetaImageProps, ResolvedConfig } from "../../../types.js";
|
|
3
|
+
import type { MarkMetrics } from "./draw.js";
|
|
4
|
+
export type { MarkMetrics } from "./draw.js";
|
|
5
|
+
/**
|
|
6
|
+
* What a post asked to have marked on its snippet, drawn over the code.
|
|
7
|
+
*
|
|
8
|
+
* A mark that cannot be placed is reported rather than dropped quietly. There
|
|
9
|
+
* are three ways to get one, and an author cannot tell them apart from the
|
|
10
|
+
* image: the text is not in the snippet at all, or it is on a line the fitting
|
|
11
|
+
* dropped, or it was past the width and got clipped. The message says the
|
|
12
|
+
* marks were not found, and the truncation warning beside it says whether
|
|
13
|
+
* there was room for them.
|
|
14
|
+
*/
|
|
15
|
+
export declare function codeMarks(props: MetaImageProps, lines: readonly (readonly CodeToken[])[], metrics: MarkMetrics, config: ResolvedConfig): string;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/templates/code/mark/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,EACxC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,cAAc,GACrB,MAAM,CA0BR"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { markSvg } from "./draw.js";
|
|
2
|
+
import { locateMark } from "./locate.js";
|
|
3
|
+
import { readMarks } from "./read.js";
|
|
4
|
+
/**
|
|
5
|
+
* What a post asked to have marked on its snippet, drawn over the code.
|
|
6
|
+
*
|
|
7
|
+
* A mark that cannot be placed is reported rather than dropped quietly. There
|
|
8
|
+
* are three ways to get one, and an author cannot tell them apart from the
|
|
9
|
+
* image: the text is not in the snippet at all, or it is on a line the fitting
|
|
10
|
+
* dropped, or it was past the width and got clipped. The message says the
|
|
11
|
+
* marks were not found, and the truncation warning beside it says whether
|
|
12
|
+
* there was room for them.
|
|
13
|
+
*/
|
|
14
|
+
export function codeMarks(props, lines, metrics, config) {
|
|
15
|
+
// Widened because this arrives from a post's frontmatter: the declared type
|
|
16
|
+
// is what a project means to write, not what the file holds.
|
|
17
|
+
const declared = props["mark"];
|
|
18
|
+
const missing = [];
|
|
19
|
+
let drawn = "";
|
|
20
|
+
for (const mark of readMarks(declared, config)) {
|
|
21
|
+
const span = locateMark(mark, lines);
|
|
22
|
+
if (span === undefined) {
|
|
23
|
+
missing.push(mark.text ?? `line ${String(mark.line ?? 0)}`);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
drawn += markSvg(span, metrics, config.colors.brandWarm);
|
|
27
|
+
}
|
|
28
|
+
if (missing.length > 0) {
|
|
29
|
+
config.onWarning(`code mark ${missing.map((name) => JSON.stringify(name)).join(", ")}` +
|
|
30
|
+
` not found in the snippet as drawn.`);
|
|
31
|
+
}
|
|
32
|
+
return drawn;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/templates/code/mark/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CACvB,KAAqB,EACrB,KAAwC,EACxC,OAAoB,EACpB,MAAsB;IAEtB,4EAA4E;IAC5E,6DAA6D;IAC7D,MAAM,QAAQ,GAAY,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,EAAE,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAErC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QAED,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,SAAS,CACd,aAAa,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACnE,qCAAqC,CACxC,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CodeToken } from "../../../highlight/index.js";
|
|
2
|
+
import type { CodeMark } from "./read.js";
|
|
3
|
+
/** Where a mark landed on the character grid, once it was found. */
|
|
4
|
+
export interface MarkSpan {
|
|
5
|
+
/** Zero-based, into the lines being drawn. */
|
|
6
|
+
readonly line: number;
|
|
7
|
+
readonly column: number;
|
|
8
|
+
/** Characters, or `undefined` for the whole line. */
|
|
9
|
+
readonly length: number | undefined;
|
|
10
|
+
readonly color: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Turn a declared mark into grid coordinates, or nothing where it names
|
|
14
|
+
* something the image does not show.
|
|
15
|
+
*
|
|
16
|
+
* A mark naming a line and no column is the whole line, which is the band an
|
|
17
|
+
* editor draws rather than a box around a word.
|
|
18
|
+
*/
|
|
19
|
+
export declare function locateMark(mark: CodeMark, lines: readonly (readonly CodeToken[])[]): MarkSpan | undefined;
|
|
20
|
+
//# sourceMappingURL=locate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locate.d.ts","sourceRoot":"","sources":["../../../../src/templates/code/mark/locate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,oEAAoE;AACpE,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAsCD;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,GACvC,QAAQ,GAAG,SAAS,CAyBtB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One line as plain text, rebuilt from the tokens by putting each back at its
|
|
3
|
+
* own column.
|
|
4
|
+
*
|
|
5
|
+
* The tokens are what survived highlighting, fitting and clipping, so this is
|
|
6
|
+
* the line as it will be drawn rather than as it was written. Searching what
|
|
7
|
+
* is drawn is the point: a mark on a line that was dropped has nowhere to go,
|
|
8
|
+
* and finding it in the original snippet would only mean drawing a box in the
|
|
9
|
+
* wrong place.
|
|
10
|
+
*/
|
|
11
|
+
function lineText(tokens) {
|
|
12
|
+
let text = "";
|
|
13
|
+
for (const token of tokens) {
|
|
14
|
+
text = text.padEnd(token.column, " ") + token.text;
|
|
15
|
+
}
|
|
16
|
+
return text;
|
|
17
|
+
}
|
|
18
|
+
/** The first line holding the text, and where on it. */
|
|
19
|
+
function findText(text, lines) {
|
|
20
|
+
for (const [line, tokens] of lines.entries()) {
|
|
21
|
+
const column = lineText(tokens).indexOf(text);
|
|
22
|
+
if (column !== -1) {
|
|
23
|
+
return { line, column };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Turn a declared mark into grid coordinates, or nothing where it names
|
|
30
|
+
* something the image does not show.
|
|
31
|
+
*
|
|
32
|
+
* A mark naming a line and no column is the whole line, which is the band an
|
|
33
|
+
* editor draws rather than a box around a word.
|
|
34
|
+
*/
|
|
35
|
+
export function locateMark(mark, lines) {
|
|
36
|
+
const color = mark.color;
|
|
37
|
+
if (mark.text !== undefined) {
|
|
38
|
+
const found = findText(mark.text, lines);
|
|
39
|
+
return found === undefined
|
|
40
|
+
? undefined
|
|
41
|
+
: { ...found, length: mark.length ?? mark.text.length, color };
|
|
42
|
+
}
|
|
43
|
+
const line = (mark.line ?? 0) - 1;
|
|
44
|
+
if (line < 0 || line >= lines.length) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return mark.column === undefined
|
|
48
|
+
? { line, column: 0, length: undefined, color }
|
|
49
|
+
: {
|
|
50
|
+
line,
|
|
51
|
+
column: mark.column - 1,
|
|
52
|
+
length: mark.length ?? 1,
|
|
53
|
+
color,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=locate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locate.js","sourceRoot":"","sources":["../../../../src/templates/code/mark/locate.ts"],"names":[],"mappings":"AAaA;;;;;;;;;GASG;AACH,SAAS,QAAQ,CAAC,MAA4B;IAC5C,IAAI,IAAI,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wDAAwD;AACxD,SAAS,QAAQ,CACf,IAAY,EACZ,KAAwC;IAExC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,IAAc,EACd,KAAwC;IAExC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAEzC,OAAO,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS;QAC9B,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE;QAC/C,CAAC,CAAC;YACE,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC;YACxB,KAAK;SACN,CAAC;AACR,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ResolvedConfig } from "../../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* One thing a post asked to have marked on its snippet.
|
|
4
|
+
*
|
|
5
|
+
* `text` names it by what it says, which is what frontmatter usually wants: it
|
|
6
|
+
* survives the snippet being edited above the line, and it is what somebody
|
|
7
|
+
* would type. `line` and `column` name it by where it is, for the times the
|
|
8
|
+
* same text appears twice or the thing worth marking is a whole line.
|
|
9
|
+
*/
|
|
10
|
+
export interface CodeMark {
|
|
11
|
+
readonly text?: string;
|
|
12
|
+
/** One-based, as an editor counts. */
|
|
13
|
+
readonly line?: number;
|
|
14
|
+
/** One-based. Omit it, with no `text`, to mark the whole line. */
|
|
15
|
+
readonly column?: number;
|
|
16
|
+
/** Characters from `column`. Defaults to what `text` is, or the line. */
|
|
17
|
+
readonly length?: number;
|
|
18
|
+
/** Defaults to the palette's warm accent. */
|
|
19
|
+
readonly color?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The marks a post declared: one, or a list of them.
|
|
23
|
+
*
|
|
24
|
+
* Anything that is neither a string nor an object saying where to look is a
|
|
25
|
+
* mistake in the frontmatter, and it is reported rather than dropped. A mark
|
|
26
|
+
* that goes missing is invisible in the finished image, so nothing else would
|
|
27
|
+
* ever say the post asked for one.
|
|
28
|
+
*/
|
|
29
|
+
export declare function readMarks(declared: unknown, config: ResolvedConfig): readonly CodeMark[];
|
|
30
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../../src/templates/code/mark/read.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AA8CD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,cAAc,GACrB,SAAS,QAAQ,EAAE,CAuBrB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { optionalString } from "../../../props.js";
|
|
2
|
+
function number(value) {
|
|
3
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
4
|
+
? value
|
|
5
|
+
: undefined;
|
|
6
|
+
}
|
|
7
|
+
/** One declared mark, read field by field the way a badge is. */
|
|
8
|
+
function markFromProps(declared) {
|
|
9
|
+
const read = (key) => key in declared ? declared[key] : undefined;
|
|
10
|
+
const text = optionalString(read("text"));
|
|
11
|
+
const line = number(read("line"));
|
|
12
|
+
if ((text === undefined || text === "") && line === undefined) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const column = number(read("column"));
|
|
16
|
+
const length = number(read("length"));
|
|
17
|
+
const color = optionalString(read("color"));
|
|
18
|
+
return {
|
|
19
|
+
...(text !== undefined && text !== "" && { text }),
|
|
20
|
+
...(line !== undefined && { line }),
|
|
21
|
+
...(column !== undefined && { column }),
|
|
22
|
+
...(length !== undefined && { length }),
|
|
23
|
+
...(color !== undefined && { color }),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** A string is the text to find, and an object is read for its fields. */
|
|
27
|
+
function markFromValue(declared) {
|
|
28
|
+
const text = optionalString(declared);
|
|
29
|
+
if (text !== undefined) {
|
|
30
|
+
return text === "" ? undefined : { text };
|
|
31
|
+
}
|
|
32
|
+
return typeof declared === "object" && declared !== null
|
|
33
|
+
? markFromProps(declared)
|
|
34
|
+
: undefined;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The marks a post declared: one, or a list of them.
|
|
38
|
+
*
|
|
39
|
+
* Anything that is neither a string nor an object saying where to look is a
|
|
40
|
+
* mistake in the frontmatter, and it is reported rather than dropped. A mark
|
|
41
|
+
* that goes missing is invisible in the finished image, so nothing else would
|
|
42
|
+
* ever say the post asked for one.
|
|
43
|
+
*/
|
|
44
|
+
export function readMarks(declared, config) {
|
|
45
|
+
if (declared === undefined) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const values = Array.isArray(declared) ? declared : [declared];
|
|
49
|
+
const marks = [];
|
|
50
|
+
for (const value of values) {
|
|
51
|
+
const mark = markFromValue(value);
|
|
52
|
+
if (mark === undefined) {
|
|
53
|
+
config.onWarning(`code mark ${JSON.stringify(value)} says nothing to mark:` +
|
|
54
|
+
` give it text to find, or a line to draw across.`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
marks.push(mark);
|
|
58
|
+
}
|
|
59
|
+
return marks;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../../../src/templates/code/mark/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResolvedConfig } from "../../types.js";
|
|
1
2
|
import type { Panel } from "./panel.js";
|
|
2
3
|
/**
|
|
3
4
|
* Shrink a panel onto its content, keeping it centred in the space it was
|
|
@@ -12,6 +13,11 @@ export declare function hugPanel(available: Panel, wanted: {
|
|
|
12
13
|
* The panel itself: a drop shadow, then the theme-coloured surface it sits on.
|
|
13
14
|
* The surface is stroked rather than left flat, so a dark theme still has an
|
|
14
15
|
* edge against a dark background.
|
|
16
|
+
*
|
|
17
|
+
* A panel the background shows through casts no shadow. The shadow is the same
|
|
18
|
+
* rectangle offset a few pixels, so a translucent surface shows most of it as
|
|
19
|
+
* a dark wash across the panel, which reads as a smudge rather than as depth.
|
|
20
|
+
* A pane of glass is not a raised card, and this is the difference.
|
|
15
21
|
*/
|
|
16
|
-
export declare function panelSvg(available: Panel, background: string, shadowOffset: number): string;
|
|
22
|
+
export declare function panelSvg(available: Panel, background: string, shadowOffset: number, config: ResolvedConfig): string;
|
|
17
23
|
//# sourceMappingURL=plate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plate.d.ts","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,KAAK,EAChB,MAAM,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC1D,KAAK,CAmBP;AAED
|
|
1
|
+
{"version":3,"file":"plate.d.ts","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,KAAK,EAChB,MAAM,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC1D,KAAK,CAmBP;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,MAAM,CAcR"}
|
|
@@ -21,14 +21,24 @@ export function hugPanel(available, wanted) {
|
|
|
21
21
|
* The panel itself: a drop shadow, then the theme-coloured surface it sits on.
|
|
22
22
|
* The surface is stroked rather than left flat, so a dark theme still has an
|
|
23
23
|
* edge against a dark background.
|
|
24
|
+
*
|
|
25
|
+
* A panel the background shows through casts no shadow. The shadow is the same
|
|
26
|
+
* rectangle offset a few pixels, so a translucent surface shows most of it as
|
|
27
|
+
* a dark wash across the panel, which reads as a smudge rather than as depth.
|
|
28
|
+
* A pane of glass is not a raised card, and this is the difference.
|
|
24
29
|
*/
|
|
25
|
-
export function panelSvg(available, background, shadowOffset) {
|
|
30
|
+
export function panelSvg(available, background, shadowOffset, config) {
|
|
31
|
+
const { panelOpacity, borderColor, borderOpacity } = config.code;
|
|
32
|
+
// A full-opacity surface says nothing about its opacity, which keeps the
|
|
33
|
+
// common case's output to what the template actually decided.
|
|
26
34
|
return panel(available, {
|
|
27
35
|
radius: available.radius,
|
|
28
36
|
fill: background,
|
|
29
|
-
stroke:
|
|
30
|
-
strokeOpacity:
|
|
31
|
-
|
|
37
|
+
stroke: borderColor,
|
|
38
|
+
strokeOpacity: borderOpacity,
|
|
39
|
+
...(panelOpacity < 1
|
|
40
|
+
? { fillOpacity: panelOpacity }
|
|
41
|
+
: { shadow: shadowOffset }),
|
|
32
42
|
});
|
|
33
43
|
}
|
|
34
44
|
//# sourceMappingURL=plate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plate.js","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"plate.js","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI9C;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,SAAgB,EAChB,MAA2D;IAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,SAAS,CAAC,KAAK,EACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CACvE,CAAC;IACF,uEAAuE;IACvE,uEAAuE;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB,SAAS,CAAC,MAAM,EAChB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAC9D,CAAC;IAEF,OAAO;QACL,GAAG,SAAS;QACZ,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1D,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5D,KAAK;QACL,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CACtB,SAAgB,EAChB,UAAkB,EAClB,YAAoB,EACpB,MAAsB;IAEtB,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAEjE,yEAAyE;IACzE,8DAA8D;IAC9D,OAAO,KAAK,CAAC,SAAS,EAAE;QACtB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,WAAW;QACnB,aAAa,EAAE,aAAa;QAC5B,GAAG,CAAC,YAAY,GAAG,CAAC;YAClB,CAAC,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE;YAC/B,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import type { ResolvedConfig } from "../types.js";
|
|
1
|
+
import type { Dimensions, ResolvedConfig } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The size the line along the bottom is drawn at.
|
|
4
|
+
*
|
|
5
|
+
* Every template asks for it here rather than working it out, which is what
|
|
6
|
+
* stops the twelve of them drifting apart. It is one number for the footer,
|
|
7
|
+
* the byline and the attribution alike, since they are all the same line.
|
|
8
|
+
*/
|
|
9
|
+
export declare function footerFontSize(dimensions: Dimensions): number;
|
|
2
10
|
/**
|
|
3
11
|
* Where and how a template wants its footer drawn. Every template places the
|
|
4
12
|
* footer differently; what they share is that a config with no footer, or an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/templates/footer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../src/templates/footer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAkB9D;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAO7D;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,eAAe,GACzB,MAAM,CAeR"}
|
package/dist/templates/footer.js
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import { baselineFor, textElement } from "../layout/index.js";
|
|
2
|
+
/** The footer's size, as a fraction of the image's height. */
|
|
3
|
+
const footerScale = 0.036;
|
|
4
|
+
/**
|
|
5
|
+
* The least it may be, as a fraction of the image's width.
|
|
6
|
+
*
|
|
7
|
+
* Height alone is what the footer used to be measured against, and it left the
|
|
8
|
+
* landscape sizes with the smallest text on the least of it: at 1200x630 the
|
|
9
|
+
* line came out at 20px against the square's 38px, on an image a feed scales
|
|
10
|
+
* to the same width. Width is what legibility tracks, for the reason the code
|
|
11
|
+
* template's font-size bounds are fractions of it, so this is the floor that
|
|
12
|
+
* stops a wide image having a footer nobody can read. The square is above it
|
|
13
|
+
* and keeps the proportions it had.
|
|
14
|
+
*/
|
|
15
|
+
const footerWidthFloor = 0.026;
|
|
16
|
+
/**
|
|
17
|
+
* The size the line along the bottom is drawn at.
|
|
18
|
+
*
|
|
19
|
+
* Every template asks for it here rather than working it out, which is what
|
|
20
|
+
* stops the twelve of them drifting apart. It is one number for the footer,
|
|
21
|
+
* the byline and the attribution alike, since they are all the same line.
|
|
22
|
+
*/
|
|
23
|
+
export function footerFontSize(dimensions) {
|
|
24
|
+
return Math.round(Math.max(dimensions.height * footerScale, dimensions.width * footerWidthFloor));
|
|
25
|
+
}
|
|
2
26
|
/**
|
|
3
27
|
* The baseline of a footer sitting on the bottom margin.
|
|
4
28
|
*
|