@kensio/colophon 2.2.0 → 2.4.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 +62 -265
- package/dist/background.d.ts +7 -2
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +44 -1
- package/dist/background.js.map +1 -1
- 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 +65 -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 +54 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/resolve.d.ts +31 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +82 -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 +47 -0
- package/dist/config/size.js.map +1 -0
- package/dist/config.d.ts +27 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +78 -2
- 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 +11 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +12 -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 +69 -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 +13 -0
- package/dist/highlight/language.d.ts.map +1 -0
- package/dist/highlight/language.js +41 -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/image/index.d.ts +18 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +42 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/jpeg.d.ts +10 -0
- package/dist/image/jpeg.d.ts.map +1 -0
- package/dist/image/jpeg.js +57 -0
- package/dist/image/jpeg.js.map +1 -0
- package/dist/image/load.d.ts +4 -0
- package/dist/image/load.d.ts.map +1 -0
- package/dist/image/load.js +60 -0
- package/dist/image/load.js.map +1 -0
- package/dist/image/media.d.ts +10 -0
- package/dist/image/media.d.ts.map +1 -0
- package/dist/image/media.js +37 -0
- package/dist/image/media.js.map +1 -0
- package/dist/image/resolve.d.ts +13 -0
- package/dist/image/resolve.d.ts.map +1 -0
- package/dist/image/resolve.js +38 -0
- package/dist/image/resolve.js.map +1 -0
- package/dist/image/size.d.ts +22 -0
- package/dist/image/size.d.ts.map +1 -0
- package/dist/image/size.js +60 -0
- package/dist/image/size.js.map +1 -0
- package/dist/image/svg.d.ts +12 -0
- package/dist/image/svg.d.ts.map +1 -0
- package/dist/image/svg.js +61 -0
- package/dist/image/svg.js.map +1 -0
- package/dist/image/uri.d.ts +9 -0
- package/dist/image/uri.d.ts.map +1 -0
- package/dist/image/uri.js +22 -0
- package/dist/image/uri.js.map +1 -0
- package/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/layout/block.d.ts +37 -0
- package/dist/layout/block.d.ts.map +1 -0
- package/dist/layout/block.js +26 -0
- package/dist/layout/block.js.map +1 -0
- package/dist/layout/box.d.ts +20 -0
- package/dist/layout/box.d.ts.map +1 -0
- package/dist/layout/box.js +61 -0
- package/dist/layout/box.js.map +1 -0
- package/dist/layout/distribute.d.ts +15 -0
- package/dist/layout/distribute.d.ts.map +1 -0
- package/dist/layout/distribute.js +30 -0
- package/dist/layout/distribute.js.map +1 -0
- package/dist/layout/image.d.ts +42 -0
- package/dist/layout/image.d.ts.map +1 -0
- package/dist/layout/image.js +34 -0
- package/dist/layout/image.js.map +1 -0
- package/dist/layout/index.d.ts +40 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +30 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/lines.d.ts +45 -0
- package/dist/layout/lines.d.ts.map +1 -0
- package/dist/layout/lines.js +71 -0
- package/dist/layout/lines.js.map +1 -0
- package/dist/layout/measure.d.ts +11 -0
- package/dist/layout/measure.d.ts.map +1 -0
- package/dist/layout/measure.js +11 -0
- package/dist/layout/measure.js.map +1 -0
- package/dist/layout/panel.d.ts +20 -0
- package/dist/layout/panel.d.ts.map +1 -0
- package/dist/layout/panel.js +22 -0
- package/dist/layout/panel.js.map +1 -0
- package/dist/layout/row.d.ts +15 -0
- package/dist/layout/row.d.ts.map +1 -0
- package/dist/layout/row.js +20 -0
- package/dist/layout/row.js.map +1 -0
- package/dist/layout/scrim.d.ts +23 -0
- package/dist/layout/scrim.d.ts.map +1 -0
- package/dist/layout/scrim.js +38 -0
- package/dist/layout/scrim.js.map +1 -0
- package/dist/layout/stack.d.ts +14 -0
- package/dist/layout/stack.d.ts.map +1 -0
- package/dist/layout/stack.js +19 -0
- package/dist/layout/stack.js.map +1 -0
- package/dist/layout/types.d.ts +49 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +2 -0
- package/dist/layout/types.js.map +1 -0
- 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/measure/estimate.d.ts +10 -0
- package/dist/measure/estimate.d.ts.map +1 -0
- package/dist/measure/estimate.js +58 -0
- package/dist/measure/estimate.js.map +1 -0
- package/dist/measure/faces.d.ts +15 -0
- package/dist/measure/faces.d.ts.map +1 -0
- package/dist/measure/faces.js +70 -0
- package/dist/measure/faces.js.map +1 -0
- package/dist/measure/index.d.ts +16 -0
- package/dist/measure/index.d.ts.map +1 -0
- package/dist/measure/index.js +0 -0
- package/dist/measure/index.js.map +1 -0
- package/dist/measure/runs.d.ts +17 -0
- package/dist/measure/runs.d.ts.map +1 -0
- package/dist/measure/runs.js +39 -0
- package/dist/measure/runs.js.map +1 -0
- package/dist/measure/select.d.ts +13 -0
- package/dist/measure/select.d.ts.map +1 -0
- package/dist/measure/select.js +47 -0
- package/dist/measure/select.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/props.d.ts +7 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/props.js +17 -0
- package/dist/props.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 +12 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/svg.js +35 -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 +62 -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/attribution.d.ts +17 -0
- package/dist/templates/attribution.d.ts.map +1 -0
- package/dist/templates/attribution.js +39 -0
- package/dist/templates/attribution.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 +21 -0
- package/dist/templates/banner/badge.js.map +1 -0
- package/dist/templates/banner/index.d.ts +12 -0
- package/dist/templates/banner/index.d.ts.map +1 -0
- package/dist/templates/banner/index.js +68 -0
- package/dist/templates/banner/index.js.map +1 -0
- package/dist/templates/banner/lines.d.ts +22 -0
- package/dist/templates/banner/lines.d.ts.map +1 -0
- package/dist/templates/banner/lines.js +35 -0
- package/dist/templates/banner/lines.js.map +1 -0
- package/dist/templates/banner/version.d.ts +9 -0
- package/dist/templates/banner/version.d.ts.map +1 -0
- package/dist/templates/banner/version.js +21 -0
- package/dist/templates/banner/version.js.map +1 -0
- package/dist/templates/card/index.d.ts +10 -0
- package/dist/templates/card/index.d.ts.map +1 -0
- package/dist/templates/card/index.js +55 -0
- package/dist/templates/card/index.js.map +1 -0
- package/dist/templates/card/lines.d.ts +21 -0
- package/dist/templates/card/lines.d.ts.map +1 -0
- package/dist/templates/card/lines.js +36 -0
- package/dist/templates/card/lines.js.map +1 -0
- package/dist/templates/code/chrome.d.ts +13 -0
- package/dist/templates/code/chrome.d.ts.map +1 -0
- package/dist/templates/code/chrome.js +33 -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 +65 -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 +30 -0
- package/dist/templates/code/panel.d.ts.map +1 -0
- package/dist/templates/code/panel.js +52 -0
- package/dist/templates/code/panel.js.map +1 -0
- package/dist/templates/code/plate.d.ts +17 -0
- package/dist/templates/code/plate.d.ts.map +1 -0
- package/dist/templates/code/plate.js +34 -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/width.d.ts +10 -0
- package/dist/templates/code/width.d.ts.map +1 -0
- package/dist/templates/code/width.js +26 -0
- package/dist/templates/code/width.js.map +1 -0
- package/dist/templates/footer.d.ts +29 -0
- package/dist/templates/footer.d.ts.map +1 -0
- package/dist/templates/footer.js +35 -0
- package/dist/templates/footer.js.map +1 -0
- package/dist/templates/index.d.ts +4 -4
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +7 -7
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/logo.d.ts +15 -0
- package/dist/templates/logo.d.ts.map +1 -0
- package/dist/templates/logo.js +30 -0
- package/dist/templates/logo.js.map +1 -0
- package/dist/templates/measure.d.ts +11 -0
- package/dist/templates/measure.d.ts.map +1 -0
- package/dist/templates/measure.js +11 -0
- package/dist/templates/measure.js.map +1 -0
- package/dist/templates/props.d.ts +2 -2
- package/dist/templates/props.js +2 -2
- package/dist/templates/text.d.ts +37 -0
- package/dist/templates/text.d.ts.map +1 -0
- package/dist/templates/text.js +26 -0
- package/dist/templates/text.js.map +1 -0
- package/dist/text/break.d.ts +11 -0
- package/dist/text/break.d.ts.map +1 -0
- package/dist/text/break.js +30 -0
- package/dist/text/break.js.map +1 -0
- 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/fit.d.ts +30 -0
- package/dist/text/fit.d.ts.map +1 -0
- package/dist/text/fit.js +29 -0
- package/dist/text/fit.js.map +1 -0
- package/dist/text/index.d.ts +9 -0
- package/dist/text/index.d.ts.map +1 -0
- package/dist/text/index.js +6 -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 +22 -0
- package/dist/text/wrap.d.ts.map +1 -0
- package/dist/text/wrap.js +41 -0
- package/dist/text/wrap.js.map +1 -0
- package/dist/types.d.ts +458 -18
- 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 +42 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/keys.d.ts +75 -0
- package/dist/validate/keys.d.ts.map +1 -0
- package/dist/validate/keys.js +203 -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 +73 -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 +71 -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 +19 -6
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { byName } from "./order.js";
|
|
2
|
+
/** How landscape an image is. The most landscape one is what `widest` names. */
|
|
3
|
+
function ratio(job) {
|
|
4
|
+
return job.size.width / job.size.height;
|
|
5
|
+
}
|
|
6
|
+
/** Start a page off from the first job that draws it. */
|
|
7
|
+
export function startPage(job) {
|
|
8
|
+
return { jobs: [job], widest: job };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Add another size of the same page. Ties keep the size configured first,
|
|
12
|
+
* since `>` leaves the incumbent in place.
|
|
13
|
+
*/
|
|
14
|
+
export function addToPage(page, job) {
|
|
15
|
+
page.jobs.push(job);
|
|
16
|
+
if (ratio(job) > ratio(page.widest)) {
|
|
17
|
+
page.widest = job;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Reject two pages sharing a slug.
|
|
22
|
+
*
|
|
23
|
+
* The manifest is keyed by slug, so a site looking a page up would find
|
|
24
|
+
* whichever was written last. That is an image quietly belonging to the wrong
|
|
25
|
+
* post, which is worse than no manifest at all. Their images may well be
|
|
26
|
+
* distinct on disk, so nothing else in the build has any reason to complain.
|
|
27
|
+
*/
|
|
28
|
+
function assertOnePage(slug, page) {
|
|
29
|
+
const paths = [...new Set(page.jobs.map((job) => job.contentPath))];
|
|
30
|
+
if (paths.length > 1) {
|
|
31
|
+
throw new Error(`Two pages share the slug "${slug}": ${paths.join(" and ")}. The` +
|
|
32
|
+
` manifest is keyed by slug, so they cannot both be found. Give one a` +
|
|
33
|
+
` slug of its own, or use slugStrategy: "route".`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function toImage(job) {
|
|
37
|
+
return {
|
|
38
|
+
...(job.url !== undefined && { url: job.url }),
|
|
39
|
+
width: job.size.width,
|
|
40
|
+
height: job.size.height,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Finish a page: its images by size name, sorted, plus what they add up to. */
|
|
44
|
+
export function toPage(slug, page) {
|
|
45
|
+
assertOnePage(slug, page);
|
|
46
|
+
const title = page.widest.props.title;
|
|
47
|
+
return {
|
|
48
|
+
images: Object.fromEntries(page.jobs
|
|
49
|
+
.map((job) => [job.size.name, toImage(job)])
|
|
50
|
+
.toSorted(([a], [b]) => byName(a, b))),
|
|
51
|
+
widest: page.widest.size.name,
|
|
52
|
+
...(typeof title === "string" && title !== "" && { alt: title }),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/manifest/page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAepC,gFAAgF;AAChF,SAAS,KAAK,CAAC,GAAc;IAC3B,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1C,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,SAAS,CAAC,GAAc;IACtC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAe,EAAE,GAAc;IACvD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpB,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,IAAe;IAClD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAEpE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;YAC/D,sEAAsE;YACtE,iDAAiD,CACpD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAc;IAC7B,OAAO;QACL,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;QAC9C,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK;QACrB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,IAAe;IAClD,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IAEtC,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,WAAW,CACxB,IAAI,CAAC,IAAI;aACN,GAAG,CAAC,CAAC,GAAG,EAA2B,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;aACpE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACxC;QACD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;QAC7B,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Width of `text` when there is no font to measure it in, either because none
|
|
3
|
+
* were configured or because the stack names one the build did not load.
|
|
4
|
+
*
|
|
5
|
+
* It is a guess, and a build that wants text laid out to the pixel supplies
|
|
6
|
+
* the font as a file. What it is not is a guess a template has to make: the
|
|
7
|
+
* one ratio lives here, where the reason for it can be written down once.
|
|
8
|
+
*/
|
|
9
|
+
export declare function estimateWidth(text: string, fontSize: number, weight: number, ratio?: number): number;
|
|
10
|
+
//# sourceMappingURL=estimate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/measure/estimate.ts"],"names":[],"mappings":"AA8CA;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,SAAe,GACnB,MAAM,CAQR"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advance width to assume for proportional text, as a fraction of the font
|
|
3
|
+
* size. It is the average over the sort of text a share image carries, mostly
|
|
4
|
+
* lower-case Latin with spaces, for the sans-serif faces a site is likely to
|
|
5
|
+
* use. Nothing here is exact, which is the point of measuring instead.
|
|
6
|
+
*/
|
|
7
|
+
const defaultRatio = 0.52;
|
|
8
|
+
/**
|
|
9
|
+
* Characters that occupy a full em rather than a fraction of one: the CJK
|
|
10
|
+
* ranges, Hangul, kana, the fullwidth forms and emoji.
|
|
11
|
+
*
|
|
12
|
+
* Estimating these at the Latin ratio is what makes a Japanese title overflow
|
|
13
|
+
* by nearly half its width, and no per-template fudge factor can be right for
|
|
14
|
+
* both scripts at once. Widths of the scripts in between, such as Devanagari,
|
|
15
|
+
* are still guesses; those want a font file, which is what measuring is for.
|
|
16
|
+
*/
|
|
17
|
+
const wideRanges = [
|
|
18
|
+
[0x11_00, 0x11_5f], // Hangul Jamo
|
|
19
|
+
[0x2e_80, 0x30_3e], // CJK radicals and punctuation
|
|
20
|
+
[0x30_41, 0x33_ff], // Kana through the CJK compatibility forms
|
|
21
|
+
[0x34_00, 0x4d_bf], // CJK extension A
|
|
22
|
+
[0x4e_00, 0x9f_ff], // CJK unified ideographs
|
|
23
|
+
[0xa0_00, 0xa4_cf], // Yi
|
|
24
|
+
[0xac_00, 0xd7_a3], // Hangul syllables
|
|
25
|
+
[0xf9_00, 0xfa_ff], // CJK compatibility ideographs
|
|
26
|
+
[0xfe_30, 0xfe_4f], // CJK compatibility forms
|
|
27
|
+
[0xff_00, 0xff_60], // Fullwidth forms, but not the halfwidth kana after them
|
|
28
|
+
[0xff_e0, 0xff_e6], // Fullwidth currency and bar symbols
|
|
29
|
+
[0x1_f3_00, 0x1_fa_ff], // Emoji
|
|
30
|
+
[0x2_00_00, 0x3_ff_fd], // CJK extensions B onwards
|
|
31
|
+
];
|
|
32
|
+
function isWide(character) {
|
|
33
|
+
const point = character.codePointAt(0) ?? 0;
|
|
34
|
+
return wideRanges.some(([from, to]) => point >= from && point <= to);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* How much wider a face gets as its weight rises. A bold cut of a family runs
|
|
38
|
+
* around a tenth wider than its regular; heavier than bold, little more.
|
|
39
|
+
*/
|
|
40
|
+
function weightFactor(weight) {
|
|
41
|
+
return 1 + Math.min(Math.max(weight - 400, 0) / 400, 1) * 0.1;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Width of `text` when there is no font to measure it in, either because none
|
|
45
|
+
* were configured or because the stack names one the build did not load.
|
|
46
|
+
*
|
|
47
|
+
* It is a guess, and a build that wants text laid out to the pixel supplies
|
|
48
|
+
* the font as a file. What it is not is a guess a template has to make: the
|
|
49
|
+
* one ratio lives here, where the reason for it can be written down once.
|
|
50
|
+
*/
|
|
51
|
+
export function estimateWidth(text, fontSize, weight, ratio = defaultRatio) {
|
|
52
|
+
let ems = 0;
|
|
53
|
+
for (const character of text) {
|
|
54
|
+
ems += isWide(character) ? 1 : ratio;
|
|
55
|
+
}
|
|
56
|
+
return ems * fontSize * weightFactor(weight);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=estimate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/measure/estimate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B;;;;;;;;GAQG;AACH,MAAM,UAAU,GAA2C;IACzD,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc;IAClC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,+BAA+B;IACnD,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,2CAA2C;IAC/D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,kBAAkB;IACtC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,yBAAyB;IAC7C,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,KAAK;IACzB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB;IACvC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,+BAA+B;IACnD,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAC9C,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,yDAAyD;IAC7E,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,qCAAqC;IACzD,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,QAAQ;IAChC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,2BAA2B;CACpD,CAAC;AAEF,SAAS,MAAM,CAAC,SAAiB;IAC/B,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;AACvE,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,QAAgB,EAChB,MAAc,EACd,KAAK,GAAG,YAAY;IAEpB,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACvC,CAAC;IAED,OAAO,GAAG,GAAG,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Font } from "fontkit";
|
|
2
|
+
import type { FontSource, WarningHandler } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* One face loaded for measurement: the font itself, plus the family and weight
|
|
5
|
+
* it declares. Both are read from the file rather than from config, for the
|
|
6
|
+
* reason {@link FontSource} gives: the file is what the rasteriser matches on.
|
|
7
|
+
*/
|
|
8
|
+
export interface Face {
|
|
9
|
+
readonly family: string;
|
|
10
|
+
readonly weight: number;
|
|
11
|
+
readonly font: Font;
|
|
12
|
+
}
|
|
13
|
+
/** Every face the configured fonts hold, in the order they were configured. */
|
|
14
|
+
export declare function loadFaces(fonts: readonly FontSource[], onWarning: WarningHandler): Promise<readonly Face[]>;
|
|
15
|
+
//# sourceMappingURL=faces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faces.d.ts","sourceRoot":"","sources":["../../src/measure/faces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB;AAuFD,+EAA+E;AAC/E,wBAAsB,SAAS,CAC7B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAM1B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { create, open } from "fontkit";
|
|
2
|
+
/**
|
|
3
|
+
* Parsed faces, keyed by the font file's path. A build renders many images
|
|
4
|
+
* from one config, so without this every image would parse every font again.
|
|
5
|
+
*/
|
|
6
|
+
const byPath = new Map();
|
|
7
|
+
/**
|
|
8
|
+
* The same for fonts supplied as bytes, keyed by the array itself. A config
|
|
9
|
+
* holds one of these and hands it to every render, so identity is enough here
|
|
10
|
+
* and hashing the bytes would cost more than the parse it saves.
|
|
11
|
+
*/
|
|
12
|
+
const byData = new WeakMap();
|
|
13
|
+
/**
|
|
14
|
+
* What a face declares about itself. The types say both of these are always
|
|
15
|
+
* there, and a font file is data: one missing its name or its `OS/2` table
|
|
16
|
+
* would otherwise take the build down inside `selectFace`, rather than being
|
|
17
|
+
* measured as well as it can be. A face with no family name matches no stack,
|
|
18
|
+
* so it is only ever reached as the fallback that the first configured font is.
|
|
19
|
+
*/
|
|
20
|
+
function toFace(font) {
|
|
21
|
+
const declared = font;
|
|
22
|
+
return {
|
|
23
|
+
family: declared.familyName ?? "",
|
|
24
|
+
weight: declared["OS/2"]?.usWeightClass ?? 400,
|
|
25
|
+
font,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** A collection file holds several faces; a plain font file holds one. */
|
|
29
|
+
function facesOf(loaded) {
|
|
30
|
+
return "fonts" in loaded
|
|
31
|
+
? loaded.fonts.map((font) => toFace(font))
|
|
32
|
+
: [toFace(loaded)];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse one configured font for measurement, or report that it could not be.
|
|
36
|
+
*
|
|
37
|
+
* A file the rasteriser accepts and this cannot is rare, but it is not fatal:
|
|
38
|
+
* the image still renders, and its text is laid out from estimates instead. It
|
|
39
|
+
* is worth saying so, because wrapping that is quietly approximate is exactly
|
|
40
|
+
* what supplying a font file was meant to stop. The warning goes through the
|
|
41
|
+
* cache below, so a build says it once per file rather than once per image.
|
|
42
|
+
*/
|
|
43
|
+
async function load(font, onWarning) {
|
|
44
|
+
try {
|
|
45
|
+
return facesOf("data" in font ? create(Buffer.from(font.data)) : await open(font.path));
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
const name = "data" in font ? (font.family ?? "font data") : font.path;
|
|
49
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
50
|
+
onWarning(`could not read ${name} for text measurement, so text drawn in it is` +
|
|
51
|
+
` wrapped from estimates instead: ${reason}`);
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function cached(font, onWarning) {
|
|
56
|
+
if ("data" in font) {
|
|
57
|
+
const pending = byData.get(font.data) ?? load(font, onWarning);
|
|
58
|
+
byData.set(font.data, pending);
|
|
59
|
+
return pending;
|
|
60
|
+
}
|
|
61
|
+
const pending = byPath.get(font.path) ?? load(font, onWarning);
|
|
62
|
+
byPath.set(font.path, pending);
|
|
63
|
+
return pending;
|
|
64
|
+
}
|
|
65
|
+
/** Every face the configured fonts hold, in the order they were configured. */
|
|
66
|
+
export async function loadFaces(fonts, onWarning) {
|
|
67
|
+
const loaded = await Promise.all(fonts.map(async (font) => cached(font, onWarning)));
|
|
68
|
+
return loaded.flat();
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=faces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faces.js","sourceRoot":"","sources":["../../src/measure/faces.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAevC;;;GAGG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,GAAG,IAAI,OAAO,EAAwC,CAAC;AAEnE;;;;;;GAMG;AACH,SAAS,MAAM,CAAC,IAAU;IACxB,MAAM,QAAQ,GAAG,IAKhB,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,UAAU,IAAI,EAAE;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,IAAI,GAAG;QAC9C,IAAI;KACL,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,SAAS,OAAO,CAAC,MAAyC;IACxD,OAAO,OAAO,IAAI,MAAM;QACtB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,IAAI,CACjB,IAAgB,EAChB,SAAyB;IAEzB,IAAI,CAAC;QACH,OAAO,OAAO,CACZ,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CACxE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACvE,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,SAAS,CACP,kBAAkB,IAAI,+CAA+C;YACnE,oCAAoC,MAAM,EAAE,CAC/C,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CACb,IAAgB,EAChB,SAAyB;IAEzB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAA4B,EAC5B,SAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CACnD,CAAC;IAEF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MeasureText, ResolvedConfig } from "../types.js";
|
|
2
|
+
export type { Face } from "./faces.js";
|
|
3
|
+
/**
|
|
4
|
+
* A {@link MeasureText} for the fonts a build is rendering with.
|
|
5
|
+
*
|
|
6
|
+
* Widths are held per em and multiplied by the font size on the way out, which
|
|
7
|
+
* is what makes fitting text affordable: choosing a size means wrapping the
|
|
8
|
+
* same words several times over, and only the last multiplication differs.
|
|
9
|
+
* Text is unhinted at these sizes, so the scaling is exact rather than close.
|
|
10
|
+
*
|
|
11
|
+
* The cache lives for as long as the measurer, which is one image. Titles
|
|
12
|
+
* repeat across the sizes of an image and rarely between images, so a longer
|
|
13
|
+
* life would hold a build's worth of strings to save very little.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createMeasurer(config: ResolvedConfig): Promise<MeasureText>;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/measure/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAO1E,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA8CvC;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,WAAW,CAAC,CAgBtB"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/measure/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC;;;;;;;;GAQG;AACH,SAAS,OAAO,CACd,KAAsB,EACtB,KAAgB,EAChB,cAAuB;IAEvB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;IAEvC,OAAO,CACL,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC;QAC3C,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACxC,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,SAAS,CAChB,IAAY,EACZ,KAAgB,EAChB,KAAsB,EACtB,cAAuB;IAEvB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;IAEtD,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;QACrD,GAAG;YACD,GAAG,CAAC,IAAI,KAAK,SAAS;gBACpB,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC;gBACzD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExC,OAAO,CAAC,IAAY,EAAE,KAAgB,EAAU,EAAE;QAChD,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAClH,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,CAAC;QAED,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpB,OAAO,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Face } from "./faces.js";
|
|
2
|
+
/**
|
|
3
|
+
* A stretch of text and the face that will draw it, or no face where nothing
|
|
4
|
+
* loaded covers it and the width has to be estimated.
|
|
5
|
+
*/
|
|
6
|
+
export interface TextRun {
|
|
7
|
+
readonly text: string;
|
|
8
|
+
readonly face: Face | undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Advance width of `text` in `face`, as a multiple of the font size. */
|
|
11
|
+
export declare function emWidth(text: string, face: Face): number;
|
|
12
|
+
/**
|
|
13
|
+
* Split `text` into the longest runs that one face can draw. Text a build has
|
|
14
|
+
* supplied fonts for comes back as a single run, which is the common case.
|
|
15
|
+
*/
|
|
16
|
+
export declare function coverageRuns(text: string, primary: Face | undefined, faces: readonly Face[]): readonly TextRun[];
|
|
17
|
+
//# sourceMappingURL=runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/measure/runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACjC;AAED,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAExD;AA0BD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,SAAS,EACzB,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,SAAS,OAAO,EAAE,CAepB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Advance width of `text` in `face`, as a multiple of the font size. */
|
|
2
|
+
export function emWidth(text, face) {
|
|
3
|
+
return face.font.layout(text).advanceWidth / face.font.unitsPerEm;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The face that will draw one character: the one the style resolved to, or the
|
|
7
|
+
* first other loaded face holding a glyph for it. This is what the rasteriser
|
|
8
|
+
* does with a missing glyph, and measuring a Japanese title against a Latin
|
|
9
|
+
* face that has none of it would be worse than not measuring at all.
|
|
10
|
+
*/
|
|
11
|
+
function coveringFace(character, primary, faces) {
|
|
12
|
+
const point = character.codePointAt(0);
|
|
13
|
+
if (point === undefined) {
|
|
14
|
+
return primary;
|
|
15
|
+
}
|
|
16
|
+
if (primary?.font.hasGlyphForCodePoint(point) === true) {
|
|
17
|
+
return primary;
|
|
18
|
+
}
|
|
19
|
+
return faces.find((face) => face.font.hasGlyphForCodePoint(point));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Split `text` into the longest runs that one face can draw. Text a build has
|
|
23
|
+
* supplied fonts for comes back as a single run, which is the common case.
|
|
24
|
+
*/
|
|
25
|
+
export function coverageRuns(text, primary, faces) {
|
|
26
|
+
const runs = [];
|
|
27
|
+
for (const character of text) {
|
|
28
|
+
const face = coveringFace(character, primary, faces);
|
|
29
|
+
const last = runs.at(-1);
|
|
30
|
+
if (last === undefined || last.face !== face) {
|
|
31
|
+
runs.push({ text: character, face });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
runs[runs.length - 1] = { text: last.text + character, face };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return runs;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/measure/runs.ts"],"names":[],"mappings":"AAWA,yEAAyE;AACzE,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,IAAU;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CACnB,SAAiB,EACjB,OAAyB,EACzB,KAAsB;IAEtB,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACvD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,OAAyB,EACzB,KAAsB;IAEtB,MAAM,IAAI,GAAc,EAAE,CAAC;IAE3B,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Face } from "./faces.js";
|
|
2
|
+
/**
|
|
3
|
+
* The families named by a CSS-style stack, in order and unquoted, so that
|
|
4
|
+
* `'"JetBrains Mono", Menlo, monospace'` becomes three names to try.
|
|
5
|
+
*/
|
|
6
|
+
export declare function familyNames(stack: string): readonly string[];
|
|
7
|
+
/**
|
|
8
|
+
* The face a style resolves to, or `undefined` when the stack names nothing
|
|
9
|
+
* that was loaded. Families are tried in the order the stack lists them, which
|
|
10
|
+
* is what a stack means.
|
|
11
|
+
*/
|
|
12
|
+
export declare function selectFace(faces: readonly Face[], stack: string, weight: number): Face | undefined;
|
|
13
|
+
//# sourceMappingURL=select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/measure/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAU5D;AA4BD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,IAAI,GAAG,SAAS,CAUlB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The families named by a CSS-style stack, in order and unquoted, so that
|
|
3
|
+
* `'"JetBrains Mono", Menlo, monospace'` becomes three names to try.
|
|
4
|
+
*/
|
|
5
|
+
export function familyNames(stack) {
|
|
6
|
+
return stack
|
|
7
|
+
.split(",")
|
|
8
|
+
.map((name) => name
|
|
9
|
+
.trim()
|
|
10
|
+
.replaceAll(/^["']|["']$/g, "")
|
|
11
|
+
.trim())
|
|
12
|
+
.filter((name) => name !== "");
|
|
13
|
+
}
|
|
14
|
+
/** Faces belonging to one family, matched as the rasteriser matches them. */
|
|
15
|
+
function inFamily(faces, family) {
|
|
16
|
+
const wanted = family.toLowerCase();
|
|
17
|
+
return faces.filter((face) => face.family.toLowerCase() === wanted);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The face nearest the requested weight. A family supplying only a regular cut
|
|
21
|
+
* is drawn in that cut by the rasteriser rather than being emboldened, so
|
|
22
|
+
* measuring the nearest weight is measuring what will actually appear.
|
|
23
|
+
*/
|
|
24
|
+
function nearestWeight(faces, weight) {
|
|
25
|
+
let best = faces[0];
|
|
26
|
+
for (const face of faces) {
|
|
27
|
+
if (Math.abs(face.weight - weight) < Math.abs(best.weight - weight)) {
|
|
28
|
+
best = face;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return best;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The face a style resolves to, or `undefined` when the stack names nothing
|
|
35
|
+
* that was loaded. Families are tried in the order the stack lists them, which
|
|
36
|
+
* is what a stack means.
|
|
37
|
+
*/
|
|
38
|
+
export function selectFace(faces, stack, weight) {
|
|
39
|
+
for (const family of familyNames(stack)) {
|
|
40
|
+
const [first, ...rest] = inFamily(faces, family);
|
|
41
|
+
if (first !== undefined) {
|
|
42
|
+
return nearestWeight([first, ...rest], weight);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/measure/select.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI;SACD,IAAI,EAAE;SACN,UAAU,CAAC,cAAc,EAAE,EAAE,CAAC;SAC9B,IAAI,EAAE,CACV;SACA,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,6EAA6E;AAC7E,SAAS,QAAQ,CAAC,KAAsB,EAAE,MAAc;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CACpB,KAAiC,EACjC,MAAc;IAEd,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;YACpE,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAsB,EACtB,KAAa,EACb,MAAc;IAEd,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEjD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,aAAa,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Manifest, MetaTagOptions } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The social meta tags for one page, rendered as HTML.
|
|
4
|
+
*
|
|
5
|
+
* The same tags as {@link metaTags}, for a template that writes strings rather
|
|
6
|
+
* than a component that spreads attributes. Content is escaped: alt text comes
|
|
7
|
+
* from a post's title, and a title containing an apostrophe or an ampersand is
|
|
8
|
+
* ordinary rather than exotic.
|
|
9
|
+
*
|
|
10
|
+
* Newline-separated and with no trailing newline, so it drops into a `<head>`
|
|
11
|
+
* at whatever indentation the template is already using.
|
|
12
|
+
*/
|
|
13
|
+
export declare function metaTagsHtml(manifest: Manifest, slug: string, options?: MetaTagOptions): string;
|
|
14
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/meta/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAW,cAAc,EAAE,MAAM,aAAa,CAAC;AAWrE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,CAIR"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { escapeXml } from "../text/escape.js";
|
|
2
|
+
import { metaTags } from "./tags.js";
|
|
3
|
+
/** One tag as HTML, with whichever naming attribute it carries. */
|
|
4
|
+
function toHtml(tag) {
|
|
5
|
+
const [attribute, name] = "property" in tag ? ["property", tag.property] : ["name", tag.name];
|
|
6
|
+
return `<meta ${attribute}="${escapeXml(name)}" content="${escapeXml(tag.content)}">`;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The social meta tags for one page, rendered as HTML.
|
|
10
|
+
*
|
|
11
|
+
* The same tags as {@link metaTags}, for a template that writes strings rather
|
|
12
|
+
* than a component that spreads attributes. Content is escaped: alt text comes
|
|
13
|
+
* from a post's title, and a title containing an apostrophe or an ampersand is
|
|
14
|
+
* ordinary rather than exotic.
|
|
15
|
+
*
|
|
16
|
+
* Newline-separated and with no trailing newline, so it drops into a `<head>`
|
|
17
|
+
* at whatever indentation the template is already using.
|
|
18
|
+
*/
|
|
19
|
+
export function metaTagsHtml(manifest, slug, options) {
|
|
20
|
+
return metaTags(manifest, slug, options)
|
|
21
|
+
.map((tag) => toHtml(tag))
|
|
22
|
+
.join("\n");
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/meta/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,mEAAmE;AACnE,SAAS,MAAM,CAAC,GAAY;IAC1B,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,GACrB,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAEtE,OAAO,SAAS,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AACxF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,IAAY,EACZ,OAAwB;IAExB,OAAO,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC;SACrC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SACzB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Social meta tags, built from the manifest a build wrote.
|
|
3
|
+
*
|
|
4
|
+
* Importable on its own as `@kensio/colophon/meta`: emitting tags reads a JSON
|
|
5
|
+
* file and needs none of the rendering machinery, and a site's templates
|
|
6
|
+
* should not load a rasteriser and a syntax highlighter to write a `<head>`.
|
|
7
|
+
*/
|
|
8
|
+
export { metaTagsHtml } from "./html.js";
|
|
9
|
+
export { metaTags } from "./tags.js";
|
|
10
|
+
export { absoluteUrl } from "./url.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/meta/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Social meta tags, built from the manifest a build wrote.
|
|
3
|
+
*
|
|
4
|
+
* Importable on its own as `@kensio/colophon/meta`: emitting tags reads a JSON
|
|
5
|
+
* file and needs none of the rendering machinery, and a site's templates
|
|
6
|
+
* should not load a rasteriser and a syntax highlighter to write a `<head>`.
|
|
7
|
+
*/
|
|
8
|
+
export { metaTagsHtml } from "./html.js";
|
|
9
|
+
export { metaTags } from "./tags.js";
|
|
10
|
+
export { absoluteUrl } from "./url.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/meta/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Manifest, MetaTag, MetaTagOptions } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The social meta tags for one page of a {@link Manifest}.
|
|
4
|
+
*
|
|
5
|
+
* Generating the image is half the job: a site still has to write the tags,
|
|
6
|
+
* and every site ends up with slightly different results: a missing width, a
|
|
7
|
+
* relative URL a crawler cannot resolve, or a large card promising an image
|
|
8
|
+
* that is square.
|
|
9
|
+
*
|
|
10
|
+
* A page the manifest does not have gets no tags rather than an error. Not
|
|
11
|
+
* every page has a share image, and a props mapper returning `undefined` is
|
|
12
|
+
* how a site says so, so a template asking about one should not have to know
|
|
13
|
+
* in advance.
|
|
14
|
+
*
|
|
15
|
+
* Alt text is emitted for both platforms when the page has any. Twitter reads
|
|
16
|
+
* its own `twitter:image:alt` rather than falling back to the Open Graph one,
|
|
17
|
+
* so leaving it out would mean no alt text on the platform, which is most of
|
|
18
|
+
* the reason for carrying it this far.
|
|
19
|
+
*/
|
|
20
|
+
export declare function metaTags(manifest: Manifest, slug: string, options?: MetaTagOptions): readonly MetaTag[];
|
|
21
|
+
//# sourceMappingURL=tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/meta/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAGR,OAAO,EACP,cAAc,EACf,MAAM,aAAa,CAAC;AA4CrB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,SAAS,OAAO,EAAE,CA2BpB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { absoluteUrl } from "./url.js";
|
|
2
|
+
/**
|
|
3
|
+
* How landscape an image has to be for a large Twitter card.
|
|
4
|
+
*
|
|
5
|
+
* `summary_large_image` is specified for 2:1 and the Open Graph landscape is
|
|
6
|
+
* 1.91:1, so both clear this; a 1:1 square and a 4:3 do not, and are shown
|
|
7
|
+
* better by `summary` than by a large card that crops them. Choosing between
|
|
8
|
+
* the two is a check every site writes for itself, usually by hardcoding the
|
|
9
|
+
* answer for whichever image it happens to have.
|
|
10
|
+
*/
|
|
11
|
+
const largeCardRatio = 1.5;
|
|
12
|
+
/** The image a page's tags describe: the most landscape one it has. */
|
|
13
|
+
function chooseImage(slug, page) {
|
|
14
|
+
const image = page.images[page.widest];
|
|
15
|
+
if (image === undefined) {
|
|
16
|
+
throw new Error(`The manifest page "${slug}" names "${page.widest}" as its widest` +
|
|
17
|
+
` image but has no image by that name.`);
|
|
18
|
+
}
|
|
19
|
+
return image;
|
|
20
|
+
}
|
|
21
|
+
/** The URL to point at, or a complaint that there is none to point at. */
|
|
22
|
+
function imageUrl(slug, image, options) {
|
|
23
|
+
if (image.url === undefined) {
|
|
24
|
+
throw new Error(`The manifest has no URL for "${slug}", so there is nothing to point a` +
|
|
25
|
+
` meta tag at. Set placement.urlBase, which is what records one.`);
|
|
26
|
+
}
|
|
27
|
+
return absoluteUrl(image.url, options?.baseUrl);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The social meta tags for one page of a {@link Manifest}.
|
|
31
|
+
*
|
|
32
|
+
* Generating the image is half the job: a site still has to write the tags,
|
|
33
|
+
* and every site ends up with slightly different results: a missing width, a
|
|
34
|
+
* relative URL a crawler cannot resolve, or a large card promising an image
|
|
35
|
+
* that is square.
|
|
36
|
+
*
|
|
37
|
+
* A page the manifest does not have gets no tags rather than an error. Not
|
|
38
|
+
* every page has a share image, and a props mapper returning `undefined` is
|
|
39
|
+
* how a site says so, so a template asking about one should not have to know
|
|
40
|
+
* in advance.
|
|
41
|
+
*
|
|
42
|
+
* Alt text is emitted for both platforms when the page has any. Twitter reads
|
|
43
|
+
* its own `twitter:image:alt` rather than falling back to the Open Graph one,
|
|
44
|
+
* so leaving it out would mean no alt text on the platform, which is most of
|
|
45
|
+
* the reason for carrying it this far.
|
|
46
|
+
*/
|
|
47
|
+
export function metaTags(manifest, slug, options) {
|
|
48
|
+
const page = manifest.pages[slug];
|
|
49
|
+
if (page === undefined) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const image = chooseImage(slug, page);
|
|
53
|
+
const url = imageUrl(slug, image, options);
|
|
54
|
+
const isLarge = image.width / image.height >= largeCardRatio;
|
|
55
|
+
return [
|
|
56
|
+
{ property: "og:image", content: url },
|
|
57
|
+
{ property: "og:image:width", content: String(image.width) },
|
|
58
|
+
{ property: "og:image:height", content: String(image.height) },
|
|
59
|
+
...(page.alt === undefined
|
|
60
|
+
? []
|
|
61
|
+
: [{ property: "og:image:alt", content: page.alt }]),
|
|
62
|
+
{
|
|
63
|
+
name: "twitter:card",
|
|
64
|
+
content: isLarge ? "summary_large_image" : "summary",
|
|
65
|
+
},
|
|
66
|
+
{ name: "twitter:image", content: url },
|
|
67
|
+
...(page.alt === undefined
|
|
68
|
+
? []
|
|
69
|
+
: [{ name: "twitter:image:alt", content: page.alt }]),
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/meta/tags.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,uEAAuE;AACvE,SAAS,WAAW,CAAC,IAAY,EAAE,IAAkB;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,YAAY,IAAI,CAAC,MAAM,iBAAiB;YAChE,uCAAuC,CAC1C,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,SAAS,QAAQ,CACf,IAAY,EACZ,KAAoB,EACpB,OAAmC;IAEnC,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,gCAAgC,IAAI,mCAAmC;YACrE,iEAAiE,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,QAAQ,CACtB,QAAkB,EAClB,IAAY,EACZ,OAAwB;IAExB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,cAAc,CAAC;IAE7D,OAAO;QACL,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE;QACtC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAC5D,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAC9D,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACtD;YACE,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;SACrD;QACD,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,EAAE;QACvC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;KACxD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve an image URL against the site's base.
|
|
3
|
+
*
|
|
4
|
+
* Open Graph wants an absolute URL: a crawler reads the tag out of the page
|
|
5
|
+
* and has nothing to resolve a relative one against. A manifest holds whatever
|
|
6
|
+
* the placement's `urlBase` said, which is usually site-relative, so this is
|
|
7
|
+
* where the two halves meet.
|
|
8
|
+
*
|
|
9
|
+
* A URL that names its own scheme is returned untouched, since a placement
|
|
10
|
+
* pointing at a CDN has said everything there is to say. A scheme-relative one
|
|
11
|
+
* (`//cdn`) has not: it is relative to the page's scheme, which is exactly what
|
|
12
|
+
* a crawler reading the tag elsewhere does not have, so it borrows the base's.
|
|
13
|
+
*/
|
|
14
|
+
export declare function absoluteUrl(url: string, baseUrl: string | undefined): string;
|
|
15
|
+
//# sourceMappingURL=url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/meta/url.ts"],"names":[],"mappings":"AAWA;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAa5E"}
|