@kensio/colophon 2.1.0 → 2.3.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 +608 -34
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +67 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config.d.ts +12 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +43 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.js +34 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/defaults.d.ts +64 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +64 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +22 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +52 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/resolve.d.ts +24 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +66 -0
- package/dist/config/resolve.js.map +1 -0
- package/dist/config/size.d.ts +20 -0
- package/dist/config/size.d.ts.map +1 -0
- package/dist/config/size.js +46 -0
- package/dist/config/size.js.map +1 -0
- package/dist/config.d.ts +33 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +94 -4
- package/dist/config.js.map +1 -1
- package/dist/content/index.d.ts +5 -51
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +3 -115
- package/dist/content/index.js.map +1 -1
- package/dist/content/props.d.ts +15 -0
- package/dist/content/props.d.ts.map +1 -0
- package/dist/content/props.js +71 -0
- package/dist/content/props.js.map +1 -0
- package/dist/content/slug.d.ts +23 -0
- package/dist/content/slug.d.ts.map +1 -0
- package/dist/content/slug.js +52 -0
- package/dist/content/slug.js.map +1 -0
- package/dist/content/walk.d.ts +17 -0
- package/dist/content/walk.d.ts.map +1 -0
- package/dist/content/walk.js +57 -0
- package/dist/content/walk.js.map +1 -0
- package/dist/fonts/index.d.ts +10 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +11 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/fonts/materialise.d.ts +7 -0
- package/dist/fonts/materialise.d.ts.map +1 -0
- package/dist/fonts/materialise.js +47 -0
- package/dist/fonts/materialise.js.map +1 -0
- package/dist/fonts/resolve.d.ts +7 -0
- package/dist/fonts/resolve.d.ts.map +1 -0
- package/dist/fonts/resolve.js +50 -0
- package/dist/fonts/resolve.js.map +1 -0
- package/dist/fonts.d.ts +18 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +102 -0
- package/dist/fonts.js.map +1 -0
- package/dist/generate/extra.d.ts +16 -0
- package/dist/generate/extra.d.ts.map +1 -0
- package/dist/generate/extra.js +60 -0
- package/dist/generate/extra.js.map +1 -0
- package/dist/generate/index.d.ts +19 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +46 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/job.d.ts +35 -0
- package/dist/generate/job.d.ts.map +1 -0
- package/dist/generate/job.js +2 -0
- package/dist/generate/job.js.map +1 -0
- package/dist/generate/options.d.ts +56 -0
- package/dist/generate/options.d.ts.map +1 -0
- package/dist/generate/options.js +17 -0
- package/dist/generate/options.js.map +1 -0
- package/dist/generate/output-path.d.ts +12 -0
- package/dist/generate/output-path.d.ts.map +1 -0
- package/dist/generate/output-path.js +18 -0
- package/dist/generate/output-path.js.map +1 -0
- package/dist/generate/outputs.d.ts +28 -0
- package/dist/generate/outputs.d.ts.map +1 -0
- package/dist/generate/outputs.js +71 -0
- package/dist/generate/outputs.js.map +1 -0
- package/dist/generate/plan.d.ts +21 -0
- package/dist/generate/plan.d.ts.map +1 -0
- package/dist/generate/plan.js +72 -0
- package/dist/generate/plan.js.map +1 -0
- package/dist/generate/render-image.d.ts +11 -0
- package/dist/generate/render-image.d.ts.map +1 -0
- package/dist/generate/render-image.js +27 -0
- package/dist/generate/render-image.js.map +1 -0
- package/dist/generate.d.ts +27 -6
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +77 -15
- package/dist/generate.js.map +1 -1
- package/dist/highlight/color.d.ts +9 -0
- package/dist/highlight/color.d.ts.map +1 -0
- package/dist/highlight/color.js +15 -0
- package/dist/highlight/color.js.map +1 -0
- package/dist/highlight/grid.d.ts +14 -0
- package/dist/highlight/grid.d.ts.map +1 -0
- package/dist/highlight/grid.js +36 -0
- package/dist/highlight/grid.js.map +1 -0
- package/dist/highlight/index.d.ts +12 -0
- package/dist/highlight/index.d.ts.map +1 -0
- package/dist/highlight/index.js +31 -0
- package/dist/highlight/index.js.map +1 -0
- package/dist/highlight/language.d.ts +14 -0
- package/dist/highlight/language.d.ts.map +1 -0
- package/dist/highlight/language.js +42 -0
- package/dist/highlight/language.js.map +1 -0
- package/dist/highlight/normalise.d.ts +17 -0
- package/dist/highlight/normalise.d.ts.map +1 -0
- package/dist/highlight/normalise.js +37 -0
- package/dist/highlight/normalise.js.map +1 -0
- package/dist/highlight/types.d.ts +40 -0
- package/dist/highlight/types.d.ts.map +1 -0
- package/dist/highlight/types.js +2 -0
- package/dist/highlight/types.js.map +1 -0
- package/dist/highlight.d.ts +10 -0
- package/dist/highlight.d.ts.map +1 -1
- package/dist/highlight.js +25 -2
- package/dist/highlight.js.map +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/manifest/build.d.ts +14 -0
- package/dist/manifest/build.d.ts.map +1 -0
- package/dist/manifest/build.js +43 -0
- package/dist/manifest/build.js.map +1 -0
- package/dist/manifest/index.d.ts +27 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +31 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/order.d.ts +12 -0
- package/dist/manifest/order.d.ts.map +1 -0
- package/dist/manifest/order.js +17 -0
- package/dist/manifest/order.js.map +1 -0
- package/dist/manifest/page.d.ts +24 -0
- package/dist/manifest/page.d.ts.map +1 -0
- package/dist/manifest/page.js +55 -0
- package/dist/manifest/page.js.map +1 -0
- package/dist/meta/html.d.ts +14 -0
- package/dist/meta/html.d.ts.map +1 -0
- package/dist/meta/html.js +24 -0
- package/dist/meta/html.js.map +1 -0
- package/dist/meta/index.d.ts +11 -0
- package/dist/meta/index.d.ts.map +1 -0
- package/dist/meta/index.js +11 -0
- package/dist/meta/index.js.map +1 -0
- package/dist/meta/tags.d.ts +21 -0
- package/dist/meta/tags.d.ts.map +1 -0
- package/dist/meta/tags.js +72 -0
- package/dist/meta/tags.js.map +1 -0
- package/dist/meta/url.d.ts +15 -0
- package/dist/meta/url.d.ts.map +1 -0
- package/dist/meta/url.js +34 -0
- package/dist/meta/url.js.map +1 -0
- package/dist/placement/check.d.ts +16 -0
- package/dist/placement/check.d.ts.map +1 -0
- package/dist/placement/check.js +40 -0
- package/dist/placement/check.js.map +1 -0
- package/dist/placement/index.d.ts +29 -0
- package/dist/placement/index.d.ts.map +1 -0
- package/dist/placement/index.js +61 -0
- package/dist/placement/index.js.map +1 -0
- package/dist/placement/relative.d.ts +31 -0
- package/dist/placement/relative.d.ts.map +1 -0
- package/dist/placement/relative.js +53 -0
- package/dist/placement/relative.js.map +1 -0
- package/dist/pool.d.ts +18 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +56 -0
- package/dist/pool.js.map +1 -0
- package/dist/render/index.d.ts +10 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +27 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/png.d.ts +10 -0
- package/dist/render/png.d.ts.map +1 -0
- package/dist/render/png.js +30 -0
- package/dist/render/png.js.map +1 -0
- package/dist/render/svg.d.ts +10 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/svg.js +20 -0
- package/dist/render/svg.js.map +1 -0
- package/dist/render/template.d.ts +9 -0
- package/dist/render/template.d.ts.map +1 -0
- package/dist/render/template.js +17 -0
- package/dist/render/template.js.map +1 -0
- package/dist/render.d.ts +6 -2
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +31 -10
- package/dist/render.js.map +1 -1
- package/dist/stamp/chunk.d.ts +16 -0
- package/dist/stamp/chunk.d.ts.map +1 -0
- package/dist/stamp/chunk.js +46 -0
- package/dist/stamp/chunk.js.map +1 -0
- package/dist/stamp/config-digest.d.ts +11 -0
- package/dist/stamp/config-digest.d.ts.map +1 -0
- package/dist/stamp/config-digest.js +43 -0
- package/dist/stamp/config-digest.js.map +1 -0
- package/dist/stamp/digest.d.ts +8 -0
- package/dist/stamp/digest.d.ts.map +1 -0
- package/dist/stamp/digest.js +20 -0
- package/dist/stamp/digest.js.map +1 -0
- package/dist/stamp/index.d.ts +20 -0
- package/dist/stamp/index.d.ts.map +1 -0
- package/dist/stamp/index.js +40 -0
- package/dist/stamp/index.js.map +1 -0
- package/dist/stamp/read.d.ts +7 -0
- package/dist/stamp/read.d.ts.map +1 -0
- package/dist/stamp/read.js +62 -0
- package/dist/stamp/read.js.map +1 -0
- package/dist/stamp.d.ts +29 -0
- package/dist/stamp.d.ts.map +1 -0
- package/dist/stamp.js +198 -0
- package/dist/stamp.js.map +1 -0
- package/dist/templates/banner/badge.d.ts +7 -0
- package/dist/templates/banner/badge.d.ts.map +1 -0
- package/dist/templates/banner/badge.js +24 -0
- package/dist/templates/banner/badge.js.map +1 -0
- package/dist/templates/banner/index.d.ts +9 -0
- package/dist/templates/banner/index.d.ts.map +1 -0
- package/dist/templates/banner/index.js +66 -0
- package/dist/templates/banner/index.js.map +1 -0
- package/dist/templates/banner/lines.d.ts +27 -0
- package/dist/templates/banner/lines.d.ts.map +1 -0
- package/dist/templates/banner/lines.js +46 -0
- package/dist/templates/banner/lines.js.map +1 -0
- package/dist/templates/card/index.d.ts +7 -0
- package/dist/templates/card/index.d.ts.map +1 -0
- package/dist/templates/card/index.js +43 -0
- package/dist/templates/card/index.js.map +1 -0
- package/dist/templates/card/lines.d.ts +17 -0
- package/dist/templates/card/lines.d.ts.map +1 -0
- package/dist/templates/card/lines.js +32 -0
- package/dist/templates/card/lines.js.map +1 -0
- package/dist/templates/code/chrome.d.ts +9 -0
- package/dist/templates/code/chrome.d.ts.map +1 -0
- package/dist/templates/code/chrome.js +32 -0
- package/dist/templates/code/chrome.js.map +1 -0
- package/dist/templates/code/clip.d.ts +18 -0
- package/dist/templates/code/clip.d.ts.map +1 -0
- package/dist/templates/code/clip.js +44 -0
- package/dist/templates/code/clip.js.map +1 -0
- package/dist/templates/code/ellipsis.d.ts +3 -0
- package/dist/templates/code/ellipsis.d.ts.map +1 -0
- package/dist/templates/code/ellipsis.js +3 -0
- package/dist/templates/code/ellipsis.js.map +1 -0
- package/dist/templates/code/fit.d.ts +27 -0
- package/dist/templates/code/fit.d.ts.map +1 -0
- package/dist/templates/code/fit.js +59 -0
- package/dist/templates/code/fit.js.map +1 -0
- package/dist/templates/code/index.d.ts +12 -0
- package/dist/templates/code/index.d.ts.map +1 -0
- package/dist/templates/code/index.js +64 -0
- package/dist/templates/code/index.js.map +1 -0
- package/dist/templates/code/layout.d.ts +21 -0
- package/dist/templates/code/layout.d.ts.map +1 -0
- package/dist/templates/code/layout.js +21 -0
- package/dist/templates/code/layout.js.map +1 -0
- package/dist/templates/code/panel.d.ts +17 -0
- package/dist/templates/code/panel.d.ts.map +1 -0
- package/dist/templates/code/panel.js +20 -0
- package/dist/templates/code/panel.js.map +1 -0
- package/dist/templates/code/plate.d.ts +15 -0
- package/dist/templates/code/plate.d.ts.map +1 -0
- package/dist/templates/code/plate.js +32 -0
- package/dist/templates/code/plate.js.map +1 -0
- package/dist/templates/code/spans.d.ts +19 -0
- package/dist/templates/code/spans.d.ts.map +1 -0
- package/dist/templates/code/spans.js +36 -0
- package/dist/templates/code/spans.js.map +1 -0
- package/dist/templates/code/warn.d.ts +11 -0
- package/dist/templates/code/warn.d.ts.map +1 -0
- package/dist/templates/code/warn.js +24 -0
- package/dist/templates/code/warn.js.map +1 -0
- package/dist/templates/code.d.ts.map +1 -1
- package/dist/templates/code.js +101 -29
- package/dist/templates/code.js.map +1 -1
- package/dist/templates/footer.d.ts +21 -0
- package/dist/templates/footer.d.ts.map +1 -0
- package/dist/templates/footer.js +25 -0
- package/dist/templates/footer.js.map +1 -0
- package/dist/templates/index.d.ts +3 -3
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +6 -6
- package/dist/templates/index.js.map +1 -1
- package/dist/text/element.d.ts +18 -0
- package/dist/text/element.d.ts.map +1 -0
- package/dist/text/element.js +19 -0
- package/dist/text/element.js.map +1 -0
- package/dist/text/escape.d.ts +5 -0
- package/dist/text/escape.d.ts.map +1 -0
- package/dist/text/escape.js +12 -0
- package/dist/text/escape.js.map +1 -0
- package/dist/text/index.d.ts +7 -0
- package/dist/text/index.d.ts.map +1 -0
- package/dist/text/index.js +5 -0
- package/dist/text/index.js.map +1 -0
- package/dist/text/stack.d.ts +24 -0
- package/dist/text/stack.d.ts.map +1 -0
- package/dist/text/stack.js +18 -0
- package/dist/text/stack.js.map +1 -0
- package/dist/text/wrap.d.ts +12 -0
- package/dist/text/wrap.d.ts.map +1 -0
- package/dist/text/wrap.js +33 -0
- package/dist/text/wrap.js.map +1 -0
- package/dist/types.d.ts +345 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/check.d.ts +13 -0
- package/dist/validate/check.d.ts.map +1 -0
- package/dist/validate/check.js +34 -0
- package/dist/validate/check.js.map +1 -0
- package/dist/validate/index.d.ts +15 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +41 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/keys.d.ts +58 -0
- package/dist/validate/keys.d.ts.map +1 -0
- package/dist/validate/keys.js +166 -0
- package/dist/validate/keys.js.map +1 -0
- package/dist/validate/overrides.d.ts +5 -0
- package/dist/validate/overrides.d.ts.map +1 -0
- package/dist/validate/overrides.js +43 -0
- package/dist/validate/overrides.js.map +1 -0
- package/dist/validate/placement.d.ts +10 -0
- package/dist/validate/placement.d.ts.map +1 -0
- package/dist/validate/placement.js +38 -0
- package/dist/validate/placement.js.map +1 -0
- package/dist/validate/sizes.d.ts +9 -0
- package/dist/validate/sizes.d.ts.map +1 -0
- package/dist/validate/sizes.js +27 -0
- package/dist/validate/sizes.js.map +1 -0
- package/dist/validate/suggest.d.ts +10 -0
- package/dist/validate/suggest.d.ts.map +1 -0
- package/dist/validate/suggest.js +55 -0
- package/dist/validate/suggest.js.map +1 -0
- package/dist/validate/values.d.ts +21 -0
- package/dist/validate/values.d.ts.map +1 -0
- package/dist/validate/values.js +57 -0
- package/dist/validate/values.js.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +300 -0
- package/dist/validate.js.map +1 -0
- package/package.json +14 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/card/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAmB;QACnD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAEtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,SAAS,CACrB,KAAK,EACL,KAAK,GAAG,GAAG,GAAG,CAAC,EACf,OAAO,EACP,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAC3B,CAAC;QAEF,MAAM,MAAM,GACV,MAAM;YACN,GAAG;YACH,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,WAAW,CACxB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,EACnE,GAAG,EACH,MAAM,CACP,CAAC;QAEF,MAAM,IAAI,GAAG,KAAK;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACnB,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE;YACrB,CAAC,EAAE,OAAO;YACV,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG;YAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;YAC9B,WAAW,EAAE,IAAI,CAAC,OAAO;YACzB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH;aACA,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE;YACnC,CAAC,EAAE,OAAO;YACV,CAAC,EAAE,MAAM,GAAG,GAAG;YACf,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,OAAO,IAAI,GAAG,MAAM,CAAC;IACvB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MetaImageProps } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* One line of the card's centred text block.
|
|
4
|
+
*/
|
|
5
|
+
export interface CardLine {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly fontSize: number;
|
|
8
|
+
readonly fontWeight: number;
|
|
9
|
+
readonly opacity: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The card's text block: the wrapped title, then the wrapped subtitle. No
|
|
13
|
+
* gaps between the groups — the card is the quieter layout, and the change of
|
|
14
|
+
* size and weight is enough to separate them.
|
|
15
|
+
*/
|
|
16
|
+
export declare function cardLines(props: MetaImageProps, contentWidth: number, titleFs: number, subFs: number): CardLine[];
|
|
17
|
+
//# sourceMappingURL=lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../../../src/templates/card/lines.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,QAAQ,EAAE,CA+BZ"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { estimateCharsPerLine, wrapText } from "../../text/index.js";
|
|
2
|
+
import { optionalString } from "../props.js";
|
|
3
|
+
const maxTitleLines = 3;
|
|
4
|
+
const maxSubtitleLines = 3;
|
|
5
|
+
/**
|
|
6
|
+
* The card's text block: the wrapped title, then the wrapped subtitle. No
|
|
7
|
+
* gaps between the groups — the card is the quieter layout, and the change of
|
|
8
|
+
* size and weight is enough to separate them.
|
|
9
|
+
*/
|
|
10
|
+
export function cardLines(props, contentWidth, titleFs, subFs) {
|
|
11
|
+
const title = optionalString(props.title) ?? "";
|
|
12
|
+
const subtitle = optionalString(props.subtitle);
|
|
13
|
+
const titleLines = wrapText(title, estimateCharsPerLine(contentWidth, titleFs, 0.58)).slice(0, maxTitleLines);
|
|
14
|
+
const subtitleLines = subtitle === undefined || subtitle === ""
|
|
15
|
+
? []
|
|
16
|
+
: wrapText(subtitle, estimateCharsPerLine(contentWidth, subFs, 0.52)).slice(0, maxSubtitleLines);
|
|
17
|
+
return [
|
|
18
|
+
...titleLines.map((text) => ({
|
|
19
|
+
text,
|
|
20
|
+
fontSize: titleFs,
|
|
21
|
+
fontWeight: 800,
|
|
22
|
+
opacity: 1,
|
|
23
|
+
})),
|
|
24
|
+
...subtitleLines.map((text) => ({
|
|
25
|
+
text,
|
|
26
|
+
fontSize: subFs,
|
|
27
|
+
fontWeight: 500,
|
|
28
|
+
opacity: 0.85,
|
|
29
|
+
})),
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../../src/templates/card/lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAY3B;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,KAAqB,EACrB,YAAoB,EACpB,OAAe,EACf,KAAa;IAEb,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,QAAQ,CACzB,KAAK,EACL,oBAAoB,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,CAClD,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAE1B,MAAM,aAAa,GACjB,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QACvC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,QAAQ,CACN,QAAQ,EACR,oBAAoB,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAChD,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAEnC,OAAO;QACL,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI;YACJ,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC9B,IAAI;YACJ,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Dimensions, ResolvedConfig } from "../../types.js";
|
|
2
|
+
import type { Panel } from "./panel.js";
|
|
3
|
+
/**
|
|
4
|
+
* The optional title, centred just above the panel.
|
|
5
|
+
*/
|
|
6
|
+
export declare function codeHeading(title: string | undefined, panel: Panel, fontSize: number, imageWidth: number, config: ResolvedConfig): string;
|
|
7
|
+
/** The configured footer, centred along the bottom of the image. */
|
|
8
|
+
export declare function codeFooter(dimensions: Dimensions, fontSize: number, config: ResolvedConfig): string;
|
|
9
|
+
//# sourceMappingURL=chrome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../../src/templates/code/chrome.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GACrB,MAAM,CAeR;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CACxB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,MAAM,CAUR"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { textElement } from "../../text/index.js";
|
|
2
|
+
import { footerElement } from "../footer.js";
|
|
3
|
+
/**
|
|
4
|
+
* The optional title, centred just above the panel.
|
|
5
|
+
*/
|
|
6
|
+
export function codeHeading(title, panel, fontSize, imageWidth, config) {
|
|
7
|
+
if (title === undefined || title === "") {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
10
|
+
return textElement(title, {
|
|
11
|
+
x: Math.round(imageWidth / 2),
|
|
12
|
+
y: panel.y - Math.round(fontSize * 0.42),
|
|
13
|
+
fontFamily: config.fontFamily,
|
|
14
|
+
fontSize,
|
|
15
|
+
fontWeight: 700,
|
|
16
|
+
fill: config.colors.foreground,
|
|
17
|
+
fillOpacity: 0.95,
|
|
18
|
+
anchor: "middle",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** The configured footer, centred along the bottom of the image. */
|
|
22
|
+
export function codeFooter(dimensions, fontSize, config) {
|
|
23
|
+
const { width, height } = dimensions;
|
|
24
|
+
return footerElement(config, {
|
|
25
|
+
x: Math.round(width / 2),
|
|
26
|
+
y: height - Math.round(Math.min(width, height) * 0.05),
|
|
27
|
+
fontSize,
|
|
28
|
+
opacity: 0.78,
|
|
29
|
+
anchor: "middle",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=chrome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome.js","sourceRoot":"","sources":["../../../src/templates/code/chrome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,KAAyB,EACzB,KAAY,EACZ,QAAgB,EAChB,UAAkB,EAClB,MAAsB;IAEtB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,EAAE;QACxB,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;QAC7B,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ;QACR,UAAU,EAAE,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;QAC9B,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;AACL,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CACxB,UAAsB,EACtB,QAAgB,EAChB,MAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IAErC,OAAO,aAAa,CAAC,MAAM,EAAE;QAC3B,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;QACxB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACtD,QAAQ;QACR,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CodeToken } from "../../highlight/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Clip a line to the columns that fit, ending it with an ellipsis. The font
|
|
4
|
+
* size is floored for legibility, so a wide enough snippet can still overrun
|
|
5
|
+
* the panel — clipping keeps it inside instead of bleeding off the image.
|
|
6
|
+
*
|
|
7
|
+
* Returns the line unchanged when it already fits, so the caller can count the
|
|
8
|
+
* clipped lines by identity.
|
|
9
|
+
*/
|
|
10
|
+
export declare function clipLine(tokens: readonly CodeToken[], maxColumns: number): readonly CodeToken[];
|
|
11
|
+
/**
|
|
12
|
+
* Clip every line to the panel width, and count how many had to give ground.
|
|
13
|
+
*/
|
|
14
|
+
export declare function clipLines(lines: readonly (readonly CodeToken[])[], maxColumns: number): {
|
|
15
|
+
lines: readonly (readonly CodeToken[])[];
|
|
16
|
+
clipped: number;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=clip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip.d.ts","sourceRoot":"","sources":["../../../src/templates/code/clip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,UAAU,EAAE,MAAM,GACjB,SAAS,SAAS,EAAE,CA0BtB;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,EACxC,UAAU,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAc/D"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ellipsis } from "./ellipsis.js";
|
|
2
|
+
/**
|
|
3
|
+
* Clip a line to the columns that fit, ending it with an ellipsis. The font
|
|
4
|
+
* size is floored for legibility, so a wide enough snippet can still overrun
|
|
5
|
+
* the panel — clipping keeps it inside instead of bleeding off the image.
|
|
6
|
+
*
|
|
7
|
+
* Returns the line unchanged when it already fits, so the caller can count the
|
|
8
|
+
* clipped lines by identity.
|
|
9
|
+
*/
|
|
10
|
+
export function clipLine(tokens, maxColumns) {
|
|
11
|
+
const last = tokens.at(-1);
|
|
12
|
+
if (last === undefined || last.column + last.text.length <= maxColumns) {
|
|
13
|
+
return tokens;
|
|
14
|
+
}
|
|
15
|
+
const clipped = [];
|
|
16
|
+
for (const token of tokens) {
|
|
17
|
+
if (token.column >= maxColumns) {
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
const room = maxColumns - token.column;
|
|
21
|
+
if (token.text.length <= room) {
|
|
22
|
+
clipped.push(token);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
clipped.push({ ...token, text: token.text.slice(0, room - 1) + ellipsis });
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
return clipped;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Clip every line to the panel width, and count how many had to give ground.
|
|
32
|
+
*/
|
|
33
|
+
export function clipLines(lines, maxColumns) {
|
|
34
|
+
let clipped = 0;
|
|
35
|
+
const fitted = lines.map((tokens) => {
|
|
36
|
+
const line = clipLine(tokens, maxColumns);
|
|
37
|
+
if (line !== tokens) {
|
|
38
|
+
clipped += 1;
|
|
39
|
+
}
|
|
40
|
+
return line;
|
|
41
|
+
});
|
|
42
|
+
return { lines: fitted, clipped };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=clip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip.js","sourceRoot":"","sources":["../../../src/templates/code/clip.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,MAA4B,EAC5B,UAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QACvE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;QAEvC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC;QAC3E,MAAM;IACR,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CACvB,KAAwC,EACxC,UAAkB;IAElB,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAE1C,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ellipsis.d.ts","sourceRoot":"","sources":["../../../src/templates/code/ellipsis.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,eAAO,MAAM,QAAQ,WAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ellipsis.js","sourceRoot":"","sources":["../../../src/templates/code/ellipsis.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CodeToken, HighlightedCode } from "../../highlight/index.js";
|
|
2
|
+
import type { ResolvedConfig } from "../../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pick the largest font size that fits the snippet in the panel on both axes,
|
|
5
|
+
* clamped to the configured bounds.
|
|
6
|
+
*
|
|
7
|
+
* The bounds are fractions of the image *width*, not its height: a share image
|
|
8
|
+
* is scaled to fit the width of whatever feed shows it, so width is what
|
|
9
|
+
* decides whether the code ends up legible. Keying the floor to height would
|
|
10
|
+
* let a landscape image render the same snippet at half the size of its square
|
|
11
|
+
* counterpart.
|
|
12
|
+
*/
|
|
13
|
+
export declare function fitFontSize(highlighted: HighlightedCode, codeWidth: number, codeHeight: number, imageWidth: number, config: ResolvedConfig): number;
|
|
14
|
+
/**
|
|
15
|
+
* Width of the laid-out block in characters, measured from the lines actually
|
|
16
|
+
* being drawn. Narrower than the snippet's longest line whenever that line was
|
|
17
|
+
* dropped or clipped, which keeps the panel hugged tight to what is visible.
|
|
18
|
+
*/
|
|
19
|
+
export declare function blockColumns(lines: readonly (readonly CodeToken[])[]): number;
|
|
20
|
+
/**
|
|
21
|
+
* Drop lines that cannot fit at the chosen font size, marking the truncation
|
|
22
|
+
* with an ellipsis line so the image never silently misrepresents the snippet.
|
|
23
|
+
* The marker takes the indentation of the first dropped line, so it reads as
|
|
24
|
+
* part of the block rather than as a stray mark in the left margin.
|
|
25
|
+
*/
|
|
26
|
+
export declare function fitLines(lines: readonly (readonly CodeToken[])[], codeHeight: number, step: number): readonly (readonly CodeToken[])[];
|
|
27
|
+
//# sourceMappingURL=fit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/templates/code/fit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GACrB,MAAM,CAWR;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,GAAG,MAAM,CAY7E;AAaD;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,EACxC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAWnC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ellipsis } from "./ellipsis.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pick the largest font size that fits the snippet in the panel on both axes,
|
|
4
|
+
* clamped to the configured bounds.
|
|
5
|
+
*
|
|
6
|
+
* The bounds are fractions of the image *width*, not its height: a share image
|
|
7
|
+
* is scaled to fit the width of whatever feed shows it, so width is what
|
|
8
|
+
* decides whether the code ends up legible. Keying the floor to height would
|
|
9
|
+
* let a landscape image render the same snippet at half the size of its square
|
|
10
|
+
* counterpart.
|
|
11
|
+
*/
|
|
12
|
+
export function fitFontSize(highlighted, codeWidth, codeHeight, imageWidth, config) {
|
|
13
|
+
const { charWidthRatio, lineHeight, maxFontScale, minFontScale } = config.code;
|
|
14
|
+
const byWidth = codeWidth / (Math.max(1, highlighted.longestLine) * charWidthRatio);
|
|
15
|
+
const byHeight = codeHeight / (Math.max(1, highlighted.lines.length) * lineHeight);
|
|
16
|
+
const fitted = Math.min(byWidth, byHeight, imageWidth * maxFontScale);
|
|
17
|
+
return Math.max(1, Math.floor(Math.max(fitted, imageWidth * minFontScale)));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Width of the laid-out block in characters, measured from the lines actually
|
|
21
|
+
* being drawn. Narrower than the snippet's longest line whenever that line was
|
|
22
|
+
* dropped or clipped, which keeps the panel hugged tight to what is visible.
|
|
23
|
+
*/
|
|
24
|
+
export function blockColumns(lines) {
|
|
25
|
+
let columns = 0;
|
|
26
|
+
for (const tokens of lines) {
|
|
27
|
+
const last = tokens.at(-1);
|
|
28
|
+
if (last !== undefined) {
|
|
29
|
+
columns = Math.max(columns, last.column + last.text.length);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return columns;
|
|
33
|
+
}
|
|
34
|
+
function ellipsisToken(column) {
|
|
35
|
+
return {
|
|
36
|
+
text: ellipsis,
|
|
37
|
+
column,
|
|
38
|
+
color: undefined,
|
|
39
|
+
opacity: 0.6,
|
|
40
|
+
bold: false,
|
|
41
|
+
italic: false,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Drop lines that cannot fit at the chosen font size, marking the truncation
|
|
46
|
+
* with an ellipsis line so the image never silently misrepresents the snippet.
|
|
47
|
+
* The marker takes the indentation of the first dropped line, so it reads as
|
|
48
|
+
* part of the block rather than as a stray mark in the left margin.
|
|
49
|
+
*/
|
|
50
|
+
export function fitLines(lines, codeHeight, step) {
|
|
51
|
+
const maxLines = Math.max(1, Math.floor(codeHeight / step));
|
|
52
|
+
if (lines.length <= maxLines) {
|
|
53
|
+
return lines;
|
|
54
|
+
}
|
|
55
|
+
const kept = lines.slice(0, maxLines - 1);
|
|
56
|
+
const dropped = lines.slice(maxLines - 1).find((line) => line.length > 0);
|
|
57
|
+
return [...kept, [ellipsisToken(dropped?.[0]?.column ?? 0)]];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=fit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.js","sourceRoot":"","sources":["../../../src/templates/code/fit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,WAA4B,EAC5B,SAAiB,EACjB,UAAkB,EAClB,UAAkB,EAClB,MAAsB;IAEtB,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,GAC9D,MAAM,CAAC,IAAI,CAAC;IAEd,MAAM,OAAO,GACX,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC;IACtE,MAAM,QAAQ,GACZ,UAAU,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwC;IACnE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM;QACN,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,GAAG;QACZ,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,KAAK;KACd,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAwC,EACxC,UAAkB,EAClB,IAAY;IAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;IAE5D,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE1E,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Template } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Syntax-highlighted code snippet on a rounded panel over the configured
|
|
4
|
+
* background. Reads `code` and `language` from the props (as the original
|
|
5
|
+
* `image_text` / `image_lexer` frontmatter did), with an optional `title`
|
|
6
|
+
* above the panel and the configured footer below it.
|
|
7
|
+
*
|
|
8
|
+
* Highlighting uses Shiki, so token colours come from a real VS Code theme
|
|
9
|
+
* rather than being approximated.
|
|
10
|
+
*/
|
|
11
|
+
export declare const codeTemplate: Template;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;AAW/C;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,QAuE1B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { highlightCode } from "../../highlight/index.js";
|
|
2
|
+
import { hasFooter } from "../footer.js";
|
|
3
|
+
import { optionalString } from "../props.js";
|
|
4
|
+
import { codeFooter, codeHeading } from "./chrome.js";
|
|
5
|
+
import { blockColumns } from "./fit.js";
|
|
6
|
+
import { fitSnippet } from "./layout.js";
|
|
7
|
+
import { layoutPanel } from "./panel.js";
|
|
8
|
+
import { hugPanel, panelSvg } from "./plate.js";
|
|
9
|
+
import { codeBody } from "./spans.js";
|
|
10
|
+
import { warnIfTruncated } from "./warn.js";
|
|
11
|
+
/**
|
|
12
|
+
* Syntax-highlighted code snippet on a rounded panel over the configured
|
|
13
|
+
* background. Reads `code` and `language` from the props (as the original
|
|
14
|
+
* `image_text` / `image_lexer` frontmatter did), with an optional `title`
|
|
15
|
+
* above the panel and the configured footer below it.
|
|
16
|
+
*
|
|
17
|
+
* Highlighting uses Shiki, so token colours come from a real VS Code theme
|
|
18
|
+
* rather than being approximated.
|
|
19
|
+
*/
|
|
20
|
+
export const codeTemplate = {
|
|
21
|
+
name: "code",
|
|
22
|
+
async render({ props, config, dimensions }) {
|
|
23
|
+
const { width, height } = dimensions;
|
|
24
|
+
const title = optionalString(props.title);
|
|
25
|
+
const titleFs = Math.round(height * 0.045);
|
|
26
|
+
const footerFs = Math.round(height * 0.032);
|
|
27
|
+
const highlighted = await highlightCode(optionalString(props["code"]) ?? "", {
|
|
28
|
+
language: optionalString(props["language"]) ?? "text",
|
|
29
|
+
theme: optionalString(props["theme"]) ?? config.code.theme,
|
|
30
|
+
tabSize: config.code.tabSize,
|
|
31
|
+
});
|
|
32
|
+
const available = layoutPanel(dimensions, config, titleFs, footerFs, title !== undefined && title !== "", hasFooter(config));
|
|
33
|
+
const fitted = fitSnippet(highlighted, available, width, config);
|
|
34
|
+
warnIfTruncated(config, dimensions, {
|
|
35
|
+
dropped: highlighted.lines.length - fitted.lines.length,
|
|
36
|
+
clipped: fitted.clipped,
|
|
37
|
+
}, highlighted.lines.length);
|
|
38
|
+
// Shrink the panel down onto the snippet so it isn't left floating in dead
|
|
39
|
+
// space — on a landscape image especially, a wide panel holding a narrow
|
|
40
|
+
// block leaves the code marooned off to one side.
|
|
41
|
+
const panel = hugPanel(available, {
|
|
42
|
+
width: blockColumns(fitted.lines) * fitted.charWidth + fitted.padding * 2,
|
|
43
|
+
height: fitted.lines.length * fitted.step + fitted.padding * 2,
|
|
44
|
+
});
|
|
45
|
+
const body = codeBody(fitted.lines, {
|
|
46
|
+
// Code reads from the left edge, as it does in an editor. Indentation is
|
|
47
|
+
// carried by each token's column, so the snippet keeps its shape.
|
|
48
|
+
originX: panel.x + fitted.padding,
|
|
49
|
+
originY: panel.y + (panel.height - fitted.lines.length * fitted.step) / 2,
|
|
50
|
+
fontSize: fitted.fontSize,
|
|
51
|
+
charWidth: fitted.charWidth,
|
|
52
|
+
step: fitted.step,
|
|
53
|
+
fontFamily: config.code.fontFamily,
|
|
54
|
+
foreground: highlighted.foreground,
|
|
55
|
+
});
|
|
56
|
+
const shadowOffset = Math.round(Math.min(width, height) * 0.01);
|
|
57
|
+
const plate = panelSvg(panel, highlighted.background, Math.max(1, shadowOffset));
|
|
58
|
+
return (codeHeading(title, panel, titleFs, width, config) +
|
|
59
|
+
plate +
|
|
60
|
+
body +
|
|
61
|
+
codeFooter(dimensions, footerFs, config));
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/code/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CodeToken, HighlightedCode } from "../../highlight/index.js";
|
|
2
|
+
import type { ResolvedConfig } from "../../types.js";
|
|
3
|
+
import type { Panel } from "./panel.js";
|
|
4
|
+
/**
|
|
5
|
+
* A snippet sized to the space it has: the lines that survived, the grid they
|
|
6
|
+
* are drawn on, and how many of them had to be clipped to get there.
|
|
7
|
+
*/
|
|
8
|
+
export interface FittedCode {
|
|
9
|
+
readonly lines: readonly (readonly CodeToken[])[];
|
|
10
|
+
readonly clipped: number;
|
|
11
|
+
readonly fontSize: number;
|
|
12
|
+
readonly charWidth: number;
|
|
13
|
+
readonly step: number;
|
|
14
|
+
readonly padding: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fit a highlighted snippet into the panel it has been allotted: choose the
|
|
18
|
+
* font size, then drop and clip whatever still does not fit.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fitSnippet(highlighted: HighlightedCode, available: Panel, imageWidth: number, config: ResolvedConfig): FittedCode;
|
|
21
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +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;;;GAGG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GACrB,UAAU,CA6BZ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { clipLines } from "./clip.js";
|
|
2
|
+
import { fitFontSize, fitLines } from "./fit.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fit a highlighted snippet into the panel it has been allotted: choose the
|
|
5
|
+
* font size, then drop and clip whatever still does not fit.
|
|
6
|
+
*/
|
|
7
|
+
export function fitSnippet(highlighted, available, imageWidth, config) {
|
|
8
|
+
const inner = Math.round(Math.min(available.width, available.height) * 0.07);
|
|
9
|
+
const codeWidth = Math.max(1, available.width - inner * 2);
|
|
10
|
+
const codeHeight = Math.max(1, available.height - inner * 2);
|
|
11
|
+
const fontSize = fitFontSize(highlighted, codeWidth, codeHeight, imageWidth, config);
|
|
12
|
+
const charWidth = fontSize * config.code.charWidthRatio;
|
|
13
|
+
const step = fontSize * config.code.lineHeight;
|
|
14
|
+
const { lines, clipped } = clipLines(fitLines(highlighted.lines, codeHeight, step), Math.max(1, Math.floor(codeWidth / charWidth)));
|
|
15
|
+
// Padding reads best proportional to the text, not the panel — a snippet
|
|
16
|
+
// fitted down to a small size wants tighter margins. Only ever shrink, so
|
|
17
|
+
// the code area the font was fitted against stays valid.
|
|
18
|
+
const padding = Math.max(Math.min(inner, Math.round(fontSize * 1.6)), Math.round(inner * 0.35));
|
|
19
|
+
return { lines, clipped, fontSize, charWidth, step, padding };
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +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;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,WAA4B,EAC5B,SAAgB,EAChB,UAAkB,EAClB,MAAsB;IAEtB,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,WAAW,EACX,SAAS,EACT,UAAU,EACV,UAAU,EACV,MAAM,CACP,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;IACxD,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,CAAC,CAC/C,CAAC;IAEF,yEAAyE;IACzE,0EAA0E;IAC1E,yDAAyD;IACzD,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,17 @@
|
|
|
1
|
+
import type { Dimensions, ResolvedConfig } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The rounded plate the snippet is drawn on.
|
|
4
|
+
*/
|
|
5
|
+
export interface Panel {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
readonly width: number;
|
|
9
|
+
readonly height: number;
|
|
10
|
+
readonly radius: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Place the code panel within the image, leaving room above for a title and
|
|
14
|
+
* below for a footer when either is present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function layoutPanel(dimensions: Dimensions, config: ResolvedConfig, titleFontSize: number, footerFontSize: number, hasTitle: boolean, hasFooter: boolean): Panel;
|
|
17
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../../src/templates/code/panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,OAAO,GACjB,KAAK,CAgBP"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Place the code panel within the image, leaving room above for a title and
|
|
3
|
+
* below for a footer when either is present.
|
|
4
|
+
*/
|
|
5
|
+
export function layoutPanel(dimensions, config, titleFontSize, footerFontSize, hasTitle, hasFooter) {
|
|
6
|
+
const { width, height } = dimensions;
|
|
7
|
+
const shorter = Math.min(width, height);
|
|
8
|
+
const pad = Math.round(shorter * 0.05);
|
|
9
|
+
const gap = Math.round(shorter * 0.028);
|
|
10
|
+
const top = pad + (hasTitle ? titleFontSize + gap : 0);
|
|
11
|
+
const bottom = height - pad - (hasFooter ? footerFontSize + gap : 0);
|
|
12
|
+
return {
|
|
13
|
+
x: pad,
|
|
14
|
+
y: top,
|
|
15
|
+
width: width - pad * 2,
|
|
16
|
+
height: Math.max(1, bottom - top),
|
|
17
|
+
radius: Math.round(shorter * config.code.cornerScale),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/templates/code/panel.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,UAAsB,EACtB,MAAsB,EACtB,aAAqB,EACrB,cAAsB,EACtB,QAAiB,EACjB,SAAkB;IAElB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;IAExC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,OAAO;QACL,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,CAAC;QACtB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;QACjC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;KACtD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Panel } from "./panel.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shrink a panel onto its content, keeping it centred in the space it was
|
|
4
|
+
* allotted. Both axes are floored so a small snippet still gets a panel with
|
|
5
|
+
* presence rather than a letterbox slot or a narrow strip.
|
|
6
|
+
*/
|
|
7
|
+
export declare function hugPanel(available: Panel, wanted: {
|
|
8
|
+
readonly width: number;
|
|
9
|
+
readonly height: number;
|
|
10
|
+
}): Panel;
|
|
11
|
+
/**
|
|
12
|
+
* The panel itself: a drop shadow, then the theme-coloured surface it sits on.
|
|
13
|
+
*/
|
|
14
|
+
export declare function panelSvg(panel: Panel, background: string, shadowOffset: number): string;
|
|
15
|
+
//# sourceMappingURL=plate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plate.d.ts","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AAAA,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;;GAEG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,MAAM,CAaR"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shrink a panel onto its content, keeping it centred in the space it was
|
|
3
|
+
* allotted. Both axes are floored so a small snippet still gets a panel with
|
|
4
|
+
* presence rather than a letterbox slot or a narrow strip.
|
|
5
|
+
*/
|
|
6
|
+
export function hugPanel(available, wanted) {
|
|
7
|
+
const width = Math.min(available.width, Math.max(Math.round(wanted.width), Math.round(available.width * 0.55)));
|
|
8
|
+
// Floor relative to the panel's own width, so shrinking never leaves a
|
|
9
|
+
// sliver, and never taller than the space the font was fitted against.
|
|
10
|
+
const height = Math.min(available.height, Math.max(Math.round(wanted.height), Math.round(width * 0.25)));
|
|
11
|
+
return {
|
|
12
|
+
...available,
|
|
13
|
+
x: available.x + Math.round((available.width - width) / 2),
|
|
14
|
+
y: available.y + Math.round((available.height - height) / 2),
|
|
15
|
+
width,
|
|
16
|
+
height,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The panel itself: a drop shadow, then the theme-coloured surface it sits on.
|
|
21
|
+
*/
|
|
22
|
+
export function panelSvg(panel, background, shadowOffset) {
|
|
23
|
+
const shadow = `<rect x="${String(panel.x)}" y="${String(panel.y + shadowOffset)}"` +
|
|
24
|
+
` width="${String(panel.width)}" height="${String(panel.height)}"` +
|
|
25
|
+
` rx="${String(panel.radius)}" fill="#000000" fill-opacity="0.22"/>`;
|
|
26
|
+
const surface = `<rect x="${String(panel.x)}" y="${String(panel.y)}"` +
|
|
27
|
+
` width="${String(panel.width)}" height="${String(panel.height)}"` +
|
|
28
|
+
` rx="${String(panel.radius)}" fill="${background}"` +
|
|
29
|
+
` stroke="#ffffff" stroke-opacity="0.12"/>`;
|
|
30
|
+
return shadow + surface;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=plate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plate.js","sourceRoot":"","sources":["../../../src/templates/code/plate.ts"],"names":[],"mappings":"AAEA;;;;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;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAY,EACZ,UAAkB,EAClB,YAAoB;IAEpB,MAAM,MAAM,GACV,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG;QACpE,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;QAClE,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,wCAAwC,CAAC;IAEvE,MAAM,OAAO,GACX,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;QACrD,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;QAClE,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,UAAU,GAAG;QACpD,2CAA2C,CAAC;IAE9C,OAAO,MAAM,GAAG,OAAO,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CodeToken } from "../../highlight/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Where and how the snippet's character grid is drawn.
|
|
4
|
+
*/
|
|
5
|
+
export interface GridMetrics {
|
|
6
|
+
readonly originX: number;
|
|
7
|
+
readonly originY: number;
|
|
8
|
+
readonly fontSize: number;
|
|
9
|
+
readonly charWidth: number;
|
|
10
|
+
readonly step: number;
|
|
11
|
+
readonly fontFamily: string;
|
|
12
|
+
readonly foreground: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The snippet as one `<text>` element per line, each token positioned
|
|
16
|
+
* absolutely from its character column so indentation survives SVG text flow.
|
|
17
|
+
*/
|
|
18
|
+
export declare function codeBody(lines: readonly (readonly CodeToken[])[], metrics: GridMetrics): string;
|
|
19
|
+
//# sourceMappingURL=spans.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spans.d.ts","sourceRoot":"","sources":["../../../src/templates/code/spans.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AA2B1D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,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,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,EACxC,OAAO,EAAE,WAAW,GACnB,MAAM,CAyBR"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { escapeXml } from "../../text/index.js";
|
|
2
|
+
/** Fraction of the font size the baseline sits below the glyph box top. */
|
|
3
|
+
const ascentRatio = 0.78;
|
|
4
|
+
function tokenSpan(token, x, charWidth, foreground) {
|
|
5
|
+
const fill = token.color ?? foreground;
|
|
6
|
+
const opacity = token.opacity === undefined
|
|
7
|
+
? ""
|
|
8
|
+
: ` fill-opacity="${String(token.opacity)}"`;
|
|
9
|
+
const weight = token.bold ? ` font-weight="700"` : "";
|
|
10
|
+
const style = token.italic ? ` font-style="italic"` : "";
|
|
11
|
+
return (`<tspan x="${String(Math.round(x + token.column * charWidth))}"` +
|
|
12
|
+
` fill="${fill}"${opacity}${weight}${style}>` +
|
|
13
|
+
`${escapeXml(token.text)}</tspan>`);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The snippet as one `<text>` element per line, each token positioned
|
|
17
|
+
* absolutely from its character column so indentation survives SVG text flow.
|
|
18
|
+
*/
|
|
19
|
+
export function codeBody(lines, metrics) {
|
|
20
|
+
const { originX, originY, fontSize, charWidth, step } = metrics;
|
|
21
|
+
return lines
|
|
22
|
+
.map((tokens, index) => {
|
|
23
|
+
if (tokens.length === 0) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
const baseline = Math.round(originY + index * step + (step - fontSize) / 2 + fontSize * ascentRatio);
|
|
27
|
+
const spans = tokens
|
|
28
|
+
.map((token) => tokenSpan(token, originX, charWidth, metrics.foreground))
|
|
29
|
+
.join("");
|
|
30
|
+
return (`<text y="${String(baseline)}" xml:space="preserve"` +
|
|
31
|
+
` font-family="${escapeXml(metrics.fontFamily)}"` +
|
|
32
|
+
` font-size="${String(fontSize)}">${spans}</text>`);
|
|
33
|
+
})
|
|
34
|
+
.join("");
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=spans.js.map
|