rendercv-ts 0.1.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/LICENSE +26 -0
- package/README.md +112 -0
- package/assets/fonts/EB Garamond/EBGaramond-Bold.ttf +0 -0
- package/assets/fonts/EB Garamond/EBGaramond-BoldItalic.ttf +0 -0
- package/assets/fonts/EB Garamond/EBGaramond-Italic.ttf +0 -0
- package/assets/fonts/EB Garamond/EBGaramond-Regular.ttf +0 -0
- package/assets/fonts/Fontin/Fontin-Bold.otf +0 -0
- package/assets/fonts/Fontin/Fontin-Italic.otf +0 -0
- package/assets/fonts/Fontin/Fontin-Regular.otf +0 -0
- package/assets/fonts/Gentium Book Plus/GentiumBookPlus-Bold.ttf +0 -0
- package/assets/fonts/Gentium Book Plus/GentiumBookPlus-BoldItalic.ttf +0 -0
- package/assets/fonts/Gentium Book Plus/GentiumBookPlus-Italic.ttf +0 -0
- package/assets/fonts/Gentium Book Plus/GentiumBookPlus-Regular.ttf +0 -0
- package/assets/fonts/Lato/Lato-Bold.ttf +0 -0
- package/assets/fonts/Lato/Lato-BoldItalic.ttf +0 -0
- package/assets/fonts/Lato/Lato-Italic.ttf +0 -0
- package/assets/fonts/Lato/Lato-Regular.ttf +0 -0
- package/assets/fonts/Raleway/Raleway-Bold.ttf +0 -0
- package/assets/fonts/Raleway/Raleway-BoldItalic.ttf +0 -0
- package/assets/fonts/Raleway/Raleway-Italic.ttf +0 -0
- package/assets/fonts/Raleway/Raleway-Regular.ttf +0 -0
- package/assets/fonts/Source Sans 3/SourceSans3-Bold.ttf +0 -0
- package/assets/fonts/Source Sans 3/SourceSans3-BoldItalic.ttf +0 -0
- package/assets/fonts/Source Sans 3/SourceSans3-Italic.ttf +0 -0
- package/assets/fonts/Source Sans 3/SourceSans3-Regular.ttf +0 -0
- package/assets/fonts/Ubuntu/Ubuntu-Bold.ttf +0 -0
- package/assets/fonts/Ubuntu/Ubuntu-BoldItalic.ttf +0 -0
- package/assets/fonts/Ubuntu/Ubuntu-Italic.ttf +0 -0
- package/assets/fonts/Ubuntu/Ubuntu-Regular.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Black.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Bold.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-ExtraBold.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-ExtraLight.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Light.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Medium.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Regular.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-SemiBold.ttf +0 -0
- package/assets/fonts/Vazirmatn/Vazirmatn-Thin.ttf +0 -0
- package/assets/fonts/XCharter/XCharter-Bold.otf +0 -0
- package/assets/fonts/XCharter/XCharter-BoldItalic.otf +0 -0
- package/assets/fonts/XCharter/XCharter-Italic.otf +0 -0
- package/assets/fonts/XCharter/XCharter-Regular.otf +0 -0
- package/assets/wasm/typst_ts_renderer_bg.wasm +0 -0
- package/assets/wasm/typst_ts_web_compiler_bg.wasm +0 -0
- package/dist/asset_paths-Q3SHUESH.js +12 -0
- package/dist/asset_paths-Q3SHUESH.js.map +1 -0
- package/dist/chunk-CJBTP63L.js +94 -0
- package/dist/chunk-CJBTP63L.js.map +1 -0
- package/dist/chunk-EVM6BVMO.js +16 -0
- package/dist/chunk-EVM6BVMO.js.map +1 -0
- package/dist/chunk-QZVXUQ72.js +91 -0
- package/dist/chunk-QZVXUQ72.js.map +1 -0
- package/dist/chunk-VZSMPOAA.js +1012 -0
- package/dist/chunk-VZSMPOAA.js.map +1 -0
- package/dist/font_cache-BZENGUJA.js +84 -0
- package/dist/font_cache-BZENGUJA.js.map +1 -0
- package/dist/font_registry-TJ7PJJTJ.js +183 -0
- package/dist/font_registry-TJ7PJJTJ.js.map +1 -0
- package/dist/index.cjs +9979 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +195 -0
- package/dist/index.d.ts +195 -0
- package/dist/index.js +8396 -0
- package/dist/index.js.map +1 -0
- package/dist/renderer/worker/pdf_worker.cjs +1518 -0
- package/dist/renderer/worker/pdf_worker.cjs.map +1 -0
- package/dist/renderer/worker/pdf_worker.d.cts +24 -0
- package/dist/renderer/worker/pdf_worker.d.ts +24 -0
- package/dist/renderer/worker/pdf_worker.js +51 -0
- package/dist/renderer/worker/pdf_worker.js.map +1 -0
- package/dist/typst_font_cache-LYHXH5UA.js +60 -0
- package/dist/typst_font_cache-LYHXH5UA.js.map +1 -0
- package/dist/typst_setup-SW3GQFSL.js +30 -0
- package/dist/typst_setup-SW3GQFSL.js.map +1 -0
- package/dist/typst_setup-WebjDI32.d.cts +266 -0
- package/dist/typst_setup-WebjDI32.d.ts +266 -0
- package/package.json +80 -0
|
@@ -0,0 +1,1518 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __glob = (map) => (path2) => {
|
|
9
|
+
var fn = map[path2];
|
|
10
|
+
if (fn) return fn();
|
|
11
|
+
throw new Error("Module not found in bundle: " + path2);
|
|
12
|
+
};
|
|
13
|
+
var __esm = (fn, res) => function __init() {
|
|
14
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
15
|
+
};
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
|
|
38
|
+
// src/renderer/assets/rendercv_typst/icons.typ?raw
|
|
39
|
+
var icons_default;
|
|
40
|
+
var init_icons = __esm({
|
|
41
|
+
"src/renderer/assets/rendercv_typst/icons.typ?raw"() {
|
|
42
|
+
icons_default = '// Auto-generated by scripts/generate-connection-icons.mjs \u2014 do not edit.\n\n#let rendercv-icon-map = (\n "envelope": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M2 4h20v16H2V4zm2 2v.01L12 13l8-6.99V6H4zm16 10V8.5l-8 5.5-8-5.5V16h16z\\"/></svg>",\n "phone": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.3 0 .7-.2 1L6.6 10.8z\\"/></svg>",\n "link": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M3.9 12c0-1.7 1.3-3 3-3h4V7H6.9C4.2 7 2 9.2 2 11.9c0 2.7 2.2 4.9 4.9 4.9H11v-2H6.9c-1.7 0-3-1.3-3-3zm16.2-5H13v2h4.1c1.7 0 3 1.3 3 3s-1.3 3-3 3H13v2h7.1c2.7 0 4.9-2.2 4.9-4.9 0-2.7-2.2-4.9-4.8-4.9zM8 11h8v2H8v-2z\\"/></svg>",\n "location-dot": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M12 2C8.1 2 5 5.1 5 9c0 5.2 7 13 7 13s7-7.8 7-13c0-3.9-3.1-7-7-7zm0 9.5A2.5 2.5 0 1 1 12 6a2.5 2.5 0 0 1 0 5.5z\\"/></svg>",\n "linkedin": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 1 1 0-4.124 2.062 2.062 0 0 1 0 4.124zM7.119 20.452H3.555V9h3.564v11.452z\\"/></svg>",\n "github": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\\"/></svg>",\n "gitlab": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"m23.6004 9.5927-.0337-.0862L20.3.9814a.851.851 0 0 0-.3362-.405.8748.8748 0 0 0-.9997.0539.8748.8748 0 0 0-.29.4399l-2.2055 6.748H7.5375l-2.2057-6.748a.8573.8573 0 0 0-.29-.4412.8748.8748 0 0 0-.9997-.0537.8585.8585 0 0 0-.3362.4049L.4332 9.5015l-.0325.0862a6.0657 6.0657 0 0 0 2.0119 7.0105l.0113.0087.03.0213 4.976 3.7264 2.462 1.8633 1.4995 1.1321a1.0085 1.0085 0 0 0 1.2197 0l1.4995-1.1321 2.4619-1.8633 5.006-3.7489.0125-.01a6.0682 6.0682 0 0 0 2.0094-7.003z\\"/></svg>",\n "imdb": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M22.3781 0H1.6218C.7411.0583.0587.7437.0018 1.5953l-.001 20.783c.0585.8761.7125 1.543 1.5559 1.6191A.337.337 0 0 0 1.6016 24h20.7971a.4579.4579 0 0 0 .0437-.002c.8727-.0768 1.5568-.8271 1.5568-1.7085V1.7098c0-.8914-.696-1.6416-1.584-1.7078A.3294.3294 0 0 0 22.3781 0zm0 .496a1.2144 1.2144 0 0 1 1.1252 1.2139v20.5797c0 .6377-.4875 1.1602-1.1045 1.2145H1.6016c-.5967-.0543-1.0645-.5297-1.1053-1.1258V1.6284C.5371 1.0185 1.0184.5364 1.6217.496h20.7564zM4.7954 8.2603v7.3636H2.8899V8.2603h1.9055zm6.5367 0v7.3636H9.6707v-4.9704l-.6711 4.9704H7.813l-.6986-4.8618-.0066 4.8618h-1.668V8.2603h2.468c.0748.4476.1492.9694.2307 1.5734l.2712 1.8713.4407-3.4447h2.4817zm2.9772 1.3289c.0742.0404.122.108.1417.2034.0279.0953.0345.3118.0345.6442v2.8548c0 .4881-.0345.7867-.0955.8954-.0609.1152-.2304.1695-.5018.1695V9.5211c.204 0 .3457.0205.4211.0681zm-.0211 6.0347c.4543 0 .8006-.0265 1.0245-.0742.2304-.0477.4204-.1357.5694-.2648.1556-.1218.2642-.298.3251-.5219.0611-.2238.1021-.6648.1021-1.3224v-2.5832c0-.6986-.0271-1.1668-.0742-1.4039-.041-.237-.1431-.4543-.3126-.6437-.1695-.1973-.4198-.3324-.7456-.421-.3191-.0808-.8542-.1285-1.7694-.1285h-1.4244v7.3636h2.3051zm5.14-1.7827c0 .3523-.0199.5762-.0544.6708-.033.0947-.1894.1424-.3046.1424-.1086 0-.19-.0477-.2238-.1351-.041-.0887-.0609-.2986-.0609-.6238v-1.9469c0-.3324.0199-.5423.0543-.6237.0338-.0808.1086-.122.2171-.122.1153 0 .2709.0412.3114.1425.041.0947.0609.2986.0609.6032v1.8926zm-2.4747-5.5809v7.3636h1.7157l.1152-.4675c.1556.1894.3251.3324.5152.4271.1828.0881.4608.1357.678.1357.3047 0 .5629-.0748.7802-.237.2165-.1562.3589-.3462.4198-.5628.0543-.2173.0887-.543.0887-.9841v-2.0675c0-.4409-.0139-.7324-.0344-.8681-.0199-.1357-.0742-.2781-.1695-.4204-.1021-.1425-.2437-.251-.4272-.3325-.1834-.0742-.3999-.1152-.6576-.1152-.2172 0-.4952.0477-.6846.1285-.1835.0887-.353.2238-.5086.4007V8.2603h-1.8309z\\"/></svg>",\n "instagram": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077\\"/></svg>",\n "mastodon": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z\\"/></svg>",\n "orcid": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0zM7.369 4.378c.525 0 .947.431.947.947s-.422.947-.947.947a.95.95 0 0 1-.947-.947c0-.525.422-.947.947-.947zm-.722 3.038h1.444v10.041H6.647V7.416zm3.562 0h3.9c3.712 0 5.344 2.653 5.344 5.025 0 2.578-2.016 5.025-5.325 5.025h-3.919V7.416zm1.444 1.303v7.444h2.297c3.272 0 4.022-2.484 4.022-3.722 0-2.016-1.284-3.722-4.097-3.722h-2.222z\\"/></svg>",\n "stack-overflow": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M15.725 0l-1.72 1.277 6.39 8.588 1.716-1.277L15.725 0zm-3.94 3.418l-1.369 1.644 8.225 6.85 1.369-1.644-8.225-6.85zm-3.15 4.465l-.905 1.94 9.702 4.517.904-1.94-9.701-4.517zm-1.85 4.86l-.44 2.093 10.473 2.201.44-2.092-10.473-2.203zM1.89 15.47V24h19.19v-8.53h-2.133v6.397H4.021v-6.396H1.89zm4.265 2.133v2.13h10.66v-2.13H6.154Z\\"/></svg>",\n "researchgate": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M19.586 0c-.818 0-1.508.19-2.073.565-.563.377-.97.936-1.213 1.68a3.193 3.193 0 0 0-.112.437 8.365 8.365 0 0 0-.078.53 9 9 0 0 0-.05.727c-.01.282-.013.621-.013 1.016a31.121 31.123 0 0 0 .014 1.017 9 9 0 0 0 .05.727 7.946 7.946 0 0 0 .077.53h-.005a3.334 3.334 0 0 0 .113.438c.245.743.65 1.303 1.214 1.68.565.376 1.256.564 2.075.564.8 0 1.536-.213 2.105-.603.57-.39.94-.916 1.175-1.65.076-.235.135-.558.177-.93a10.9 10.9 0 0 0 .043-1.207v-.82c0-.095-.047-.142-.14-.142h-3.064c-.094 0-.14.047-.14.141v.956c0 .094.046.14.14.14h1.666c.056 0 .084.03.084.086 0 .36 0 .62-.036.865-.038.244-.1.447-.147.606-.108.385-.348.664-.638.876-.29.212-.738.35-1.227.35-.545 0-.901-.15-1.21-.353-.306-.203-.517-.454-.67-.915a3.136 3.136 0 0 1-.147-.762 17.366 17.367 0 0 1-.034-.656c-.01-.26-.014-.572-.014-.939a26.401 26.403 0 0 1 .014-.938 15.821 15.822 0 0 1 .035-.656 3.19 3.19 0 0 1 .148-.76 1.89 1.89 0 0 1 .742-1.01c.344-.244.593-.352 1.137-.352.508 0 .815.096 1.144.303.33.207.528.492.764.925.047.094.111.118.198.07l1.044-.43c.075-.048.09-.115.042-.199a3.549 3.549 0 0 0-.466-.742 3 3 0 0 0-.679-.607 3.313 3.313 0 0 0-.903-.41A4.068 4.068 0 0 0 19.586 0zM8.217 5.836c-1.69 0-3.036.086-4.297.086-1.146 0-2.291 0-3.007-.029v.831l1.088.2c.744.144 1.174.488 1.174 2.264v11.288c0 1.777-.43 2.12-1.174 2.263l-1.088.2v.832c.773-.029 2.12-.086 3.465-.086 1.29 0 2.951.057 3.667.086v-.831l-1.49-.2c-.773-.115-1.174-.487-1.174-2.264v-4.784c.688.057 1.29.057 2.206.057 1.748 3.123 3.41 5.472 4.355 6.56.86 1.032 2.177 1.691 3.839 1.691.487 0 1.003-.086 1.318-.23v-.744c-1.031 0-2.063-.716-2.808-1.518-1.26-1.376-2.95-3.582-4.355-6.074 2.32-.545 4.04-2.722 4.04-4.9 0-3.208-2.492-4.698-5.758-4.698zm-.515 1.29c2.406 0 3.839 1.26 3.839 3.552 0 2.263-1.547 3.782-4.097 3.782-.974 0-1.404-.03-2.063-.086v-7.19c.66-.059 1.547-.059 2.32-.059z\\"/></svg>",\n "youtube": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\\"/></svg>",\n "graduation-cap": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M12 3 1 9l4 2.2V17c0 .6.4 1 1 1h12c.6 0 1-.4 1-1v-5.8L23 9 12 3zm0 2.2 6.5 3.6L12 12.4 5.5 8.8 12 5.2zM7 17v-4.8l5 2.8 5-2.8V17H7z\\"/></svg>",\n "telegram": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\\"/></svg>",\n "whatsapp": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z\\"/></svg>",\n "code": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M8.7 15.9 4.8 12l3.9-3.9L7 6.3 2.3 11 7 15.7l1.7-1.8zm6.6 0 1.7 1.8L21.7 12l-4.7-4.7-1.7 1.8L19.2 12l-3.9 3.9z\\"/></svg>",\n "x-twitter": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z\\"/></svg>",\n "bluesky": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026\\"/></svg>",\n "reddit": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z\\"/></svg>",\n "external-link": "<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"__FILL__\\" d=\\"M14 3h7v7h-2V6.4l-9.2 9.2-1.4-1.4L17.6 5H14V3zM5 5h6v2H7v10h10v-4h2v6H5V5z\\"/></svg>",\n)\n\n#let rendercv-icon(name, size: 0.9em, fill: rgb(0, 0, 0)) = {\n let svg-template = rendercv-icon-map.at(name, default: rendercv-icon-map.at("link"))\n let svg = svg-template.replace("__FILL__", fill.to-hex())\n box(\n image(bytes(svg), format: "svg", width: size, height: size, alt: ""),\n width: size,\n height: size,\n baseline: 22%,\n )\n}\n';
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// src/renderer/assets/rendercv_typst/lib.typ?raw
|
|
47
|
+
var lib_default;
|
|
48
|
+
var init_lib = __esm({
|
|
49
|
+
"src/renderer/assets/rendercv_typst/lib.typ?raw"() {
|
|
50
|
+
lib_default = `#import "icons.typ": rendercv-icon
|
|
51
|
+
|
|
52
|
+
// State to hold rendercv configuration for use by components
|
|
53
|
+
#let rendercv-config = state("rendercv-config", (:))
|
|
54
|
+
|
|
55
|
+
// Direction-aware inset: maps logical start/end to physical left/right.
|
|
56
|
+
// Must be called from within a \`context\` scope.
|
|
57
|
+
#let directional-inset(start: 0cm, end: 0cm) = {
|
|
58
|
+
let is-rtl = rendercv-config.get().at("is-rtl")
|
|
59
|
+
if is-rtl {
|
|
60
|
+
(left: end, right: start)
|
|
61
|
+
} else {
|
|
62
|
+
(left: start, right: end)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#let headline(headline) = {
|
|
67
|
+
metadata("skip-content-area")
|
|
68
|
+
context {
|
|
69
|
+
let config = rendercv-config.get()
|
|
70
|
+
let typography-font-size-headline = config.at("typography-font-size-headline")
|
|
71
|
+
let typography-font-family-headline = config.at("typography-font-family-headline")
|
|
72
|
+
let typography-bold-headline = config.at("typography-bold-headline")
|
|
73
|
+
let colors-headline = config.at("colors-headline")
|
|
74
|
+
let typography-small-caps-headline = config.at("typography-small-caps-headline")
|
|
75
|
+
let header-alignment = config.at("header-alignment")
|
|
76
|
+
let header-space-below-headline = config.at("header-space-below-headline")
|
|
77
|
+
set text(
|
|
78
|
+
fill: colors-headline,
|
|
79
|
+
font: typography-font-family-headline,
|
|
80
|
+
size: typography-font-size-headline,
|
|
81
|
+
weight: if typography-bold-headline { 700 } else { 400 },
|
|
82
|
+
)
|
|
83
|
+
set align(header-alignment)
|
|
84
|
+
block(
|
|
85
|
+
if typography-small-caps-headline { smallcaps(headline) } else { headline },
|
|
86
|
+
width: 100%,
|
|
87
|
+
height: auto,
|
|
88
|
+
)
|
|
89
|
+
v(header-space-below-headline, weak: true)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#let connections(..connections) = {
|
|
94
|
+
metadata("skip-content-area")
|
|
95
|
+
|
|
96
|
+
context {
|
|
97
|
+
let config = rendercv-config.get()
|
|
98
|
+
let typography-line-spacing = config.at("typography-line-spacing")
|
|
99
|
+
let header-connections-space-between-connections = config.at("header-connections-space-between-connections")
|
|
100
|
+
let header-connections-separator = config.at("header-connections-separator")
|
|
101
|
+
let page-left-margin = config.at("page-left-margin")
|
|
102
|
+
let page-right-margin = config.at("page-right-margin")
|
|
103
|
+
let header-space-below-connections = config.at("header-space-below-connections")
|
|
104
|
+
let section-titles-space-above = config.at("section-titles-space-above")
|
|
105
|
+
let colors-connections = config.at("colors-connections")
|
|
106
|
+
let typography-font-family-connections = config.at("typography-font-family-connections")
|
|
107
|
+
let typography-font-size-connections = config.at("typography-font-size-connections")
|
|
108
|
+
let typography-small-caps-connections = config.at("typography-small-caps-connections")
|
|
109
|
+
let typography-bold-connections = config.at("typography-bold-connections")
|
|
110
|
+
let header-alignment = config.at("header-alignment")
|
|
111
|
+
|
|
112
|
+
set par(spacing: 0pt, leading: typography-line-spacing * 1.7, justify: false)
|
|
113
|
+
set text(
|
|
114
|
+
fill: colors-connections,
|
|
115
|
+
font: typography-font-family-connections,
|
|
116
|
+
size: typography-font-size-connections,
|
|
117
|
+
weight: if typography-bold-connections { 700 } else { 400 },
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
let separator = (
|
|
121
|
+
h(header-connections-space-between-connections / 2, weak: true)
|
|
122
|
+
+ header-connections-separator
|
|
123
|
+
+ h(header-connections-space-between-connections / 2, weak: true)
|
|
124
|
+
)
|
|
125
|
+
let separator-width = (
|
|
126
|
+
measure(header-connections-separator).width + header-connections-space-between-connections
|
|
127
|
+
)
|
|
128
|
+
if connections.pos().len() > 0 {
|
|
129
|
+
set align(header-alignment)
|
|
130
|
+
box(
|
|
131
|
+
{
|
|
132
|
+
layout(size => {
|
|
133
|
+
let line-width = 0cm
|
|
134
|
+
for (i, connection) in connections.pos().enumerate() {
|
|
135
|
+
let connection-body = if typography-small-caps-connections { smallcaps(connection) } else { connection }
|
|
136
|
+
let connection-width = measure(connection-body).width
|
|
137
|
+
let is-last = i == connections.pos().len() - 1
|
|
138
|
+
|
|
139
|
+
// Check if adding this connection + separator would exceed the line
|
|
140
|
+
if (
|
|
141
|
+
line-width + connection-width + separator-width > size.width and line-width > 0cm
|
|
142
|
+
) {
|
|
143
|
+
linebreak()
|
|
144
|
+
line-width = 0cm
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Add separator only if we're not at the start of a line
|
|
148
|
+
if line-width > 0cm {
|
|
149
|
+
separator
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
box(connection-body, width: auto)
|
|
153
|
+
line-width = line-width + connection-width + (if line-width > 0cm { separator-width } else { 0cm })
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
},
|
|
157
|
+
width: 100%,
|
|
158
|
+
height: auto,
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
v(header-space-below-connections - section-titles-space-above)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#let original-link = link
|
|
166
|
+
#let link(dest, body, icon: none, if-underline: none, if-color: none) = context {
|
|
167
|
+
let config = rendercv-config.get()
|
|
168
|
+
let links-underline = config.at("links-underline")
|
|
169
|
+
let links-show-external-link-icon = config.at("links-show-external-link-icon")
|
|
170
|
+
let typography-font-size-body = config.at("typography-font-size-body")
|
|
171
|
+
let colors-links = config.at("colors-links")
|
|
172
|
+
|
|
173
|
+
let icon = icon
|
|
174
|
+
if icon == none {
|
|
175
|
+
if links-show-external-link-icon {
|
|
176
|
+
icon = true
|
|
177
|
+
} else {
|
|
178
|
+
icon = false
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
let if-underline = if-underline
|
|
182
|
+
if if-underline == none {
|
|
183
|
+
if links-underline {
|
|
184
|
+
if-underline = true
|
|
185
|
+
} else {
|
|
186
|
+
if-underline = false
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
let if-color = if-color
|
|
190
|
+
if if-color == none {
|
|
191
|
+
if-color = true
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let body = [#if if-underline [#underline(body)] else [#body]]
|
|
195
|
+
if icon {
|
|
196
|
+
let ext-icon-content = rendercv-icon("external-link", size: 0.65em)
|
|
197
|
+
let icon-width = measure(ext-icon-content).width
|
|
198
|
+
// Zero-height box reserves horizontal space but doesn't affect line height
|
|
199
|
+
// or baseline. place() renders the icon out of flow, positioned above the
|
|
200
|
+
// baseline to align visually with text.
|
|
201
|
+
let ext-icon = box(
|
|
202
|
+
width: icon-width,
|
|
203
|
+
height: 0pt,
|
|
204
|
+
baseline: 0pt,
|
|
205
|
+
place(dy: -0.75em, ext-icon-content),
|
|
206
|
+
)
|
|
207
|
+
// Wrap body in box to create BiDi isolation \u2014 the box becomes a neutral
|
|
208
|
+
// atomic inline, so the paragraph direction controls the icon's placement.
|
|
209
|
+
body = [#box[#body]#h(typography-font-size-body / 4)#ext-icon]
|
|
210
|
+
}
|
|
211
|
+
body = [#if if-color [#set text(fill: colors-links);#body] else [#body]]
|
|
212
|
+
original-link(dest, body)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Box around body creates BiDi isolation \u2014 the icon and body are both neutral
|
|
216
|
+
// atomic inlines, so the paragraph direction controls their relative order.
|
|
217
|
+
#let connection-with-icon(icon-name, body) = context {
|
|
218
|
+
let config = rendercv-config.get()
|
|
219
|
+
let colors-connections = config.at("colors-connections")
|
|
220
|
+
let typography-font-size-connections = config.at("typography-font-size-connections")
|
|
221
|
+
let icon-size = typography-font-size-connections * 0.85
|
|
222
|
+
|
|
223
|
+
box(width: auto, baseline: 18%)[
|
|
224
|
+
#rendercv-icon(icon-name, size: icon-size, fill: colors-connections)
|
|
225
|
+
#h(0.1em, weak: true)
|
|
226
|
+
#box(baseline: 0pt)[#body]
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
#let content-area(content) = context {
|
|
231
|
+
let config = rendercv-config.get()
|
|
232
|
+
let entries-side-space = config.at("entries-side-space")
|
|
233
|
+
let entries-date-and-location-width = config.at("entries-date-and-location-width")
|
|
234
|
+
let entries-space-between-columns = config.at("entries-space-between-columns")
|
|
235
|
+
let entries-allow-page-break = config.at("entries-allow-page-break")
|
|
236
|
+
let sections-space-between-text-based-entries = config.at("sections-space-between-text-based-entries")
|
|
237
|
+
let section-titles-type = config.at("section-titles-type")
|
|
238
|
+
let typography-line-spacing = config.at("typography-line-spacing")
|
|
239
|
+
let justify = config.at("justify")
|
|
240
|
+
let entries-highlights-bullet = config.at("entries-highlights-bullet")
|
|
241
|
+
let entries-highlights-nested-bullet = config.at("entries-highlights-nested-bullet")
|
|
242
|
+
let entries-highlights-space-between-bullet-and-text = config.at(
|
|
243
|
+
"entries-highlights-space-between-bullet-and-text",
|
|
244
|
+
)
|
|
245
|
+
let start-align = config.at("start-align")
|
|
246
|
+
|
|
247
|
+
let start-space = entries-side-space
|
|
248
|
+
if section-titles-type == "moderncv" {
|
|
249
|
+
start-space = (
|
|
250
|
+
start-space + entries-date-and-location-width + entries-space-between-columns
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
set par(
|
|
255
|
+
spacing: sections-space-between-text-based-entries + typography-line-spacing,
|
|
256
|
+
leading: typography-line-spacing,
|
|
257
|
+
justify: justify,
|
|
258
|
+
)
|
|
259
|
+
set align(start-align)
|
|
260
|
+
set enum(
|
|
261
|
+
spacing: sections-space-between-text-based-entries + typography-line-spacing,
|
|
262
|
+
)
|
|
263
|
+
set list(
|
|
264
|
+
marker: (entries-highlights-bullet, entries-highlights-nested-bullet),
|
|
265
|
+
indent: 0cm,
|
|
266
|
+
spacing: sections-space-between-text-based-entries + typography-line-spacing,
|
|
267
|
+
body-indent: entries-highlights-space-between-bullet-and-text,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
block(
|
|
271
|
+
content,
|
|
272
|
+
breakable: entries-allow-page-break,
|
|
273
|
+
below: sections-space-between-text-based-entries + typography-line-spacing,
|
|
274
|
+
inset: directional-inset(start: start-space, end: entries-side-space),
|
|
275
|
+
width: 100%,
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
#let summary(summary) = {
|
|
280
|
+
context {
|
|
281
|
+
let config = rendercv-config.get()
|
|
282
|
+
let entries-summary-space-left = config.at("entries-summary-space-left")
|
|
283
|
+
let entries-summary-space-above = config.at("entries-summary-space-above")
|
|
284
|
+
let typography-line-spacing = config.at("typography-line-spacing")
|
|
285
|
+
block(
|
|
286
|
+
summary,
|
|
287
|
+
inset: directional-inset(start: entries-summary-space-left),
|
|
288
|
+
above: entries-summary-space-above + typography-line-spacing,
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
#let regular-entry(main-column, date-and-location-column, main-column-second-row: none) = {
|
|
294
|
+
metadata("skip-content-area")
|
|
295
|
+
|
|
296
|
+
context {
|
|
297
|
+
let config = rendercv-config.get()
|
|
298
|
+
let section-titles-type = config.at("section-titles-type")
|
|
299
|
+
let entries-date-and-location-width = config.at("entries-date-and-location-width")
|
|
300
|
+
let entries-space-between-columns = config.at("entries-space-between-columns")
|
|
301
|
+
let entries-highlights-bullet = config.at("entries-highlights-bullet")
|
|
302
|
+
let entries-highlights-nested-bullet = config.at("entries-highlights-nested-bullet")
|
|
303
|
+
let entries-highlights-space-between-items = config.at(
|
|
304
|
+
"entries-highlights-space-between-items",
|
|
305
|
+
)
|
|
306
|
+
let entries-highlights-space-between-bullet-and-text = config.at(
|
|
307
|
+
"entries-highlights-space-between-bullet-and-text",
|
|
308
|
+
)
|
|
309
|
+
let entries-highlights-space-above = config.at("entries-highlights-space-above")
|
|
310
|
+
let typography-line-spacing = config.at("typography-line-spacing")
|
|
311
|
+
let entries-allow-page-break = config.at("entries-allow-page-break")
|
|
312
|
+
let sections-space-between-regular-entries = config.at("sections-space-between-regular-entries")
|
|
313
|
+
let entries-side-space = config.at("entries-side-space")
|
|
314
|
+
let justify = config.at("justify")
|
|
315
|
+
let typography-date-and-location-column-alignment = config.at("typography-date-and-location-column-alignment")
|
|
316
|
+
let entries-highlights-space-left = config.at("entries-highlights-space-left")
|
|
317
|
+
let start-align = config.at("start-align")
|
|
318
|
+
|
|
319
|
+
set list(
|
|
320
|
+
marker: (entries-highlights-bullet, entries-highlights-nested-bullet),
|
|
321
|
+
indent: entries-highlights-space-left,
|
|
322
|
+
spacing: entries-highlights-space-between-items + typography-line-spacing,
|
|
323
|
+
body-indent: entries-highlights-space-between-bullet-and-text,
|
|
324
|
+
)
|
|
325
|
+
let list-depth = state("list-depth", 0)
|
|
326
|
+
show list.item: i => {
|
|
327
|
+
list-depth.update(d => d + 1)
|
|
328
|
+
i
|
|
329
|
+
list-depth.update(d => d - 1)
|
|
330
|
+
}
|
|
331
|
+
show list: l => {
|
|
332
|
+
context if list-depth.get() == 1 {
|
|
333
|
+
v(entries-highlights-space-above)
|
|
334
|
+
}
|
|
335
|
+
context if list-depth.get() == 2 {
|
|
336
|
+
v(entries-highlights-space-between-items)
|
|
337
|
+
}
|
|
338
|
+
l
|
|
339
|
+
}
|
|
340
|
+
set par(
|
|
341
|
+
spacing: typography-line-spacing,
|
|
342
|
+
leading: typography-line-spacing,
|
|
343
|
+
justify: justify,
|
|
344
|
+
)
|
|
345
|
+
block(
|
|
346
|
+
{
|
|
347
|
+
if section-titles-type == "moderncv" {
|
|
348
|
+
grid(
|
|
349
|
+
columns: (entries-date-and-location-width, 1fr),
|
|
350
|
+
column-gutter: entries-space-between-columns,
|
|
351
|
+
align: (typography-date-and-location-column-alignment, start-align),
|
|
352
|
+
[
|
|
353
|
+
#date-and-location-column
|
|
354
|
+
],
|
|
355
|
+
[
|
|
356
|
+
#main-column
|
|
357
|
+
|
|
358
|
+
#main-column-second-row
|
|
359
|
+
],
|
|
360
|
+
)
|
|
361
|
+
} else {
|
|
362
|
+
if repr(main-column) != "[ ]" or repr(date-and-location-column) != "[ ]" {
|
|
363
|
+
grid(
|
|
364
|
+
columns: (1fr, entries-date-and-location-width),
|
|
365
|
+
column-gutter: entries-space-between-columns,
|
|
366
|
+
align: (start-align, typography-date-and-location-column-alignment),
|
|
367
|
+
main-column, date-and-location-column,
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
set align(start-align)
|
|
371
|
+
main-column-second-row
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
breakable: entries-allow-page-break,
|
|
375
|
+
below: sections-space-between-regular-entries + typography-line-spacing,
|
|
376
|
+
inset: (
|
|
377
|
+
left: entries-side-space,
|
|
378
|
+
right: entries-side-space,
|
|
379
|
+
),
|
|
380
|
+
width: 100%,
|
|
381
|
+
)
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
#let education-entry(main-column, date-and-location-column, degree-column: none, main-column-second-row: none) = {
|
|
386
|
+
metadata("skip-content-area")
|
|
387
|
+
|
|
388
|
+
context {
|
|
389
|
+
let config = rendercv-config.get()
|
|
390
|
+
let entries-space-between-columns = config.at("entries-space-between-columns")
|
|
391
|
+
let entries-degree-width = config.at("entries-degree-width")
|
|
392
|
+
let start-align = config.at("start-align")
|
|
393
|
+
|
|
394
|
+
regular-entry(
|
|
395
|
+
if degree-column != none {
|
|
396
|
+
grid(
|
|
397
|
+
columns: (entries-degree-width, 1fr),
|
|
398
|
+
column-gutter: entries-space-between-columns,
|
|
399
|
+
align: (start-align, auto),
|
|
400
|
+
[
|
|
401
|
+
#degree-column
|
|
402
|
+
],
|
|
403
|
+
[
|
|
404
|
+
#main-column
|
|
405
|
+
],
|
|
406
|
+
)
|
|
407
|
+
} else {
|
|
408
|
+
main-column
|
|
409
|
+
},
|
|
410
|
+
date-and-location-column,
|
|
411
|
+
main-column-second-row: if main-column-second-row != none and repr(main-column-second-row) != "[ ]" {
|
|
412
|
+
[
|
|
413
|
+
#block(
|
|
414
|
+
main-column-second-row,
|
|
415
|
+
inset: directional-inset(
|
|
416
|
+
start: if degree-column != none { entries-degree-width + entries-space-between-columns } else { 0cm },
|
|
417
|
+
),
|
|
418
|
+
)
|
|
419
|
+
]
|
|
420
|
+
} else { none },
|
|
421
|
+
)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
#let reversed-numbered-entries(entries) = {
|
|
426
|
+
set enum(reversed: true)
|
|
427
|
+
entries
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
#let rendercv(
|
|
431
|
+
doc,
|
|
432
|
+
name: "John Doe",
|
|
433
|
+
title: "John Doe's CV",
|
|
434
|
+
footer: context { "Page " + str(here().page()) + " of " + str(counter(page).final().first()) + "" },
|
|
435
|
+
top-note: "Last updated in " + datetime.today().display(),
|
|
436
|
+
locale-catalog-language: "en",
|
|
437
|
+
text-direction: ltr,
|
|
438
|
+
page-size: "us-letter",
|
|
439
|
+
page-top-margin: 0.7in,
|
|
440
|
+
page-bottom-margin: 0.7in,
|
|
441
|
+
page-left-margin: 0.7in,
|
|
442
|
+
page-right-margin: 0.7in,
|
|
443
|
+
page-show-footer: true,
|
|
444
|
+
page-show-top-note: true,
|
|
445
|
+
colors-body: rgb(0, 0, 0),
|
|
446
|
+
colors-name: rgb(0, 79, 144),
|
|
447
|
+
colors-headline: rgb(0, 79, 144),
|
|
448
|
+
colors-connections: rgb(0, 79, 144),
|
|
449
|
+
colors-section-titles: rgb(0, 79, 144),
|
|
450
|
+
colors-links: rgb(0, 79, 144),
|
|
451
|
+
colors-footer: rgb(128, 128, 128),
|
|
452
|
+
colors-top-note: rgb(128, 128, 128),
|
|
453
|
+
typography-line-spacing: 0.6em,
|
|
454
|
+
typography-alignment: "justified",
|
|
455
|
+
typography-date-and-location-column-alignment: right,
|
|
456
|
+
typography-font-family-body: "Raleway",
|
|
457
|
+
typography-font-family-name: "Raleway",
|
|
458
|
+
typography-font-family-headline: "Raleway",
|
|
459
|
+
typography-font-family-connections: "Raleway",
|
|
460
|
+
typography-font-family-section-titles: "Raleway",
|
|
461
|
+
typography-font-size-body: 10pt,
|
|
462
|
+
typography-font-size-name: 30pt,
|
|
463
|
+
typography-font-size-headline: 10pt,
|
|
464
|
+
typography-font-size-connections: 10pt,
|
|
465
|
+
typography-font-size-section-titles: 1.4em,
|
|
466
|
+
typography-small-caps-name: false,
|
|
467
|
+
typography-small-caps-headline: false,
|
|
468
|
+
typography-small-caps-connections: false,
|
|
469
|
+
typography-small-caps-section-titles: false,
|
|
470
|
+
typography-bold-name: false,
|
|
471
|
+
typography-bold-headline: false,
|
|
472
|
+
typography-bold-connections: false,
|
|
473
|
+
typography-bold-section-titles: false,
|
|
474
|
+
links-underline: false,
|
|
475
|
+
links-show-external-link-icon: false,
|
|
476
|
+
header-alignment: left,
|
|
477
|
+
header-photo-width: 3.5cm,
|
|
478
|
+
header-space-below-name: 0.7cm,
|
|
479
|
+
header-space-below-headline: 0.7cm,
|
|
480
|
+
header-space-below-connections: 0.7cm,
|
|
481
|
+
header-connections-hyperlink: true,
|
|
482
|
+
header-connections-show-icons: true,
|
|
483
|
+
header-connections-display-urls-instead-of-usernames: false,
|
|
484
|
+
header-connections-separator: "",
|
|
485
|
+
header-connections-space-between-connections: 0.5cm,
|
|
486
|
+
section-titles-type: "with_full_line",
|
|
487
|
+
section-titles-line-thickness: 0.5pt,
|
|
488
|
+
section-titles-space-above: 0.5cm,
|
|
489
|
+
section-titles-space-below: 0.3cm,
|
|
490
|
+
sections-allow-page-break: true,
|
|
491
|
+
sections-space-between-text-based-entries: 0.3em,
|
|
492
|
+
sections-space-between-regular-entries: 1.2em,
|
|
493
|
+
entries-date-and-location-width: 4.15cm,
|
|
494
|
+
entries-side-space: 0.2cm,
|
|
495
|
+
entries-space-between-columns: 0.1cm,
|
|
496
|
+
entries-allow-page-break: false,
|
|
497
|
+
entries-short-second-row: false,
|
|
498
|
+
entries-degree-width: 1cm,
|
|
499
|
+
entries-summary-space-left: 0cm,
|
|
500
|
+
entries-summary-space-above: 0.12cm,
|
|
501
|
+
entries-highlights-bullet: "\u2022",
|
|
502
|
+
entries-highlights-nested-bullet: "\u2022",
|
|
503
|
+
entries-highlights-space-left: 0cm,
|
|
504
|
+
entries-highlights-space-above: 0.12cm,
|
|
505
|
+
entries-highlights-space-between-items: 0.12cm,
|
|
506
|
+
entries-highlights-space-between-bullet-and-text: 0.5em,
|
|
507
|
+
date: datetime(
|
|
508
|
+
year: 2025,
|
|
509
|
+
month: 12,
|
|
510
|
+
day: 5,
|
|
511
|
+
),
|
|
512
|
+
) = [
|
|
513
|
+
#let (justify, hyphenate) = (
|
|
514
|
+
"justified": (true, true),
|
|
515
|
+
"left": (false, false),
|
|
516
|
+
"justified-with-no-hyphenation": (true, false),
|
|
517
|
+
).at(typography-alignment)
|
|
518
|
+
|
|
519
|
+
#let is-rtl = text-direction == rtl
|
|
520
|
+
#let start-align = if is-rtl { right } else { left }
|
|
521
|
+
#let end-align = if is-rtl { left } else { right }
|
|
522
|
+
|
|
523
|
+
// Initialize state with all configuration parameters
|
|
524
|
+
#rendercv-config.update((
|
|
525
|
+
// Direction
|
|
526
|
+
text-direction: text-direction,
|
|
527
|
+
is-rtl: is-rtl,
|
|
528
|
+
start-align: start-align,
|
|
529
|
+
// Page
|
|
530
|
+
page-left-margin: page-left-margin,
|
|
531
|
+
page-right-margin: page-right-margin,
|
|
532
|
+
// Colors
|
|
533
|
+
colors-body: colors-body,
|
|
534
|
+
colors-name: colors-name,
|
|
535
|
+
colors-headline: colors-headline,
|
|
536
|
+
colors-connections: colors-connections,
|
|
537
|
+
colors-section-titles: colors-section-titles,
|
|
538
|
+
colors-links: colors-links,
|
|
539
|
+
colors-footer: colors-footer,
|
|
540
|
+
colors-top-note: colors-top-note,
|
|
541
|
+
// Typography
|
|
542
|
+
typography-line-spacing: typography-line-spacing,
|
|
543
|
+
typography-alignment: typography-alignment,
|
|
544
|
+
typography-date-and-location-column-alignment: typography-date-and-location-column-alignment,
|
|
545
|
+
typography-font-family-body: typography-font-family-body,
|
|
546
|
+
typography-font-family-name: typography-font-family-name,
|
|
547
|
+
typography-font-family-headline: typography-font-family-headline,
|
|
548
|
+
typography-font-family-connections: typography-font-family-connections,
|
|
549
|
+
typography-font-family-section-titles: typography-font-family-section-titles,
|
|
550
|
+
typography-font-size-body: typography-font-size-body,
|
|
551
|
+
typography-font-size-name: typography-font-size-name,
|
|
552
|
+
typography-font-size-headline: typography-font-size-headline,
|
|
553
|
+
typography-font-size-connections: typography-font-size-connections,
|
|
554
|
+
typography-font-size-section-titles: typography-font-size-section-titles,
|
|
555
|
+
typography-small-caps-name: typography-small-caps-name,
|
|
556
|
+
typography-small-caps-headline: typography-small-caps-headline,
|
|
557
|
+
typography-small-caps-connections: typography-small-caps-connections,
|
|
558
|
+
typography-small-caps-section-titles: typography-small-caps-section-titles,
|
|
559
|
+
typography-bold-name: typography-bold-name,
|
|
560
|
+
typography-bold-headline: typography-bold-headline,
|
|
561
|
+
typography-bold-connections: typography-bold-connections,
|
|
562
|
+
typography-bold-section-titles: typography-bold-section-titles,
|
|
563
|
+
// Links
|
|
564
|
+
links-underline: links-underline,
|
|
565
|
+
links-show-external-link-icon: links-show-external-link-icon,
|
|
566
|
+
// Header
|
|
567
|
+
header-alignment: header-alignment,
|
|
568
|
+
header-photo-width: header-photo-width,
|
|
569
|
+
header-space-below-name: header-space-below-name,
|
|
570
|
+
header-space-below-headline: header-space-below-headline,
|
|
571
|
+
header-space-below-connections: header-space-below-connections,
|
|
572
|
+
header-connections-hyperlink: header-connections-hyperlink,
|
|
573
|
+
header-connections-show-icons: header-connections-show-icons,
|
|
574
|
+
header-connections-display-urls-instead-of-usernames: header-connections-display-urls-instead-of-usernames,
|
|
575
|
+
header-connections-separator: header-connections-separator,
|
|
576
|
+
header-connections-space-between-connections: header-connections-space-between-connections,
|
|
577
|
+
// Section titles
|
|
578
|
+
section-titles-type: section-titles-type,
|
|
579
|
+
section-titles-line-thickness: section-titles-line-thickness,
|
|
580
|
+
section-titles-space-above: section-titles-space-above,
|
|
581
|
+
section-titles-space-below: section-titles-space-below,
|
|
582
|
+
// Sections
|
|
583
|
+
sections-allow-page-break: sections-allow-page-break,
|
|
584
|
+
sections-space-between-regular-entries: sections-space-between-regular-entries,
|
|
585
|
+
sections-space-between-text-based-entries: sections-space-between-text-based-entries,
|
|
586
|
+
// Entries
|
|
587
|
+
entries-date-and-location-width: entries-date-and-location-width,
|
|
588
|
+
entries-side-space: entries-side-space,
|
|
589
|
+
entries-space-between-columns: entries-space-between-columns,
|
|
590
|
+
entries-allow-page-break: entries-allow-page-break,
|
|
591
|
+
entries-summary-space-left: entries-summary-space-left,
|
|
592
|
+
entries-summary-space-above: entries-summary-space-above,
|
|
593
|
+
entries-highlights-bullet: entries-highlights-bullet,
|
|
594
|
+
entries-highlights-nested-bullet: entries-highlights-nested-bullet,
|
|
595
|
+
entries-highlights-space-left: entries-highlights-space-left,
|
|
596
|
+
entries-highlights-space-above: entries-highlights-space-above,
|
|
597
|
+
entries-highlights-space-between-items: entries-highlights-space-between-items,
|
|
598
|
+
entries-highlights-space-between-bullet-and-text: entries-highlights-space-between-bullet-and-text,
|
|
599
|
+
entries-degree-width: entries-degree-width,
|
|
600
|
+
// Internal computed values
|
|
601
|
+
justify: justify,
|
|
602
|
+
))
|
|
603
|
+
|
|
604
|
+
// Metadata:
|
|
605
|
+
#set document(author: name, title: title, date: date)
|
|
606
|
+
|
|
607
|
+
// Page:
|
|
608
|
+
#set page(
|
|
609
|
+
margin: (
|
|
610
|
+
top: page-top-margin,
|
|
611
|
+
bottom: page-bottom-margin,
|
|
612
|
+
left: page-left-margin,
|
|
613
|
+
right: page-right-margin,
|
|
614
|
+
),
|
|
615
|
+
paper: page-size,
|
|
616
|
+
footer: if page-show-footer and footer != none and footer != "" {
|
|
617
|
+
text(
|
|
618
|
+
fill: colors-footer,
|
|
619
|
+
align(center, [#footer]),
|
|
620
|
+
size: 0.9em,
|
|
621
|
+
)
|
|
622
|
+
} else {
|
|
623
|
+
none
|
|
624
|
+
},
|
|
625
|
+
footer-descent: 0% - 0.6em + page-bottom-margin / 2,
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
// Text:
|
|
629
|
+
#set text(
|
|
630
|
+
font: typography-font-family-body,
|
|
631
|
+
size: typography-font-size-body,
|
|
632
|
+
lang: locale-catalog-language,
|
|
633
|
+
dir: text-direction,
|
|
634
|
+
hyphenate: hyphenate,
|
|
635
|
+
fill: colors-body,
|
|
636
|
+
// Disable ligatures for better ATS compatibility:
|
|
637
|
+
ligatures: true,
|
|
638
|
+
)
|
|
639
|
+
|
|
640
|
+
// Main heading (name):
|
|
641
|
+
#show heading.where(level: 1): it => [
|
|
642
|
+
#set par(spacing: 0pt)
|
|
643
|
+
#set align(header-alignment)
|
|
644
|
+
#set text(
|
|
645
|
+
font: typography-font-family-name,
|
|
646
|
+
size: typography-font-size-name,
|
|
647
|
+
fill: colors-name,
|
|
648
|
+
weight: if typography-bold-name { 700 } else { 400 },
|
|
649
|
+
)
|
|
650
|
+
#let body
|
|
651
|
+
#if typography-small-caps-name {
|
|
652
|
+
body = [#smallcaps(it.body)]
|
|
653
|
+
} else {
|
|
654
|
+
body = [#it.body]
|
|
655
|
+
}
|
|
656
|
+
#body
|
|
657
|
+
// Vertical space after the name
|
|
658
|
+
#v(header-space-below-name, weak: true)
|
|
659
|
+
]
|
|
660
|
+
|
|
661
|
+
// Section titles:
|
|
662
|
+
#show heading.where(level: 2): it => [
|
|
663
|
+
#let is-centered = section-titles-type in ("centered_without_line", "centered_with_partial_line", "centered_with_centered_partial_line", "centered_with_full_line")
|
|
664
|
+
#set align(if is-centered { center } else { start-align })
|
|
665
|
+
#set text(size: (1em / 1.2)) // reset
|
|
666
|
+
#set text(
|
|
667
|
+
font: typography-font-family-section-titles,
|
|
668
|
+
size: (typography-font-size-section-titles),
|
|
669
|
+
weight: if typography-bold-section-titles { 700 } else { 400 },
|
|
670
|
+
fill: colors-section-titles,
|
|
671
|
+
)
|
|
672
|
+
#let section-title = (
|
|
673
|
+
if typography-small-caps-section-titles [
|
|
674
|
+
#smallcaps(it.body)
|
|
675
|
+
] else [
|
|
676
|
+
#it.body
|
|
677
|
+
]
|
|
678
|
+
)
|
|
679
|
+
// Vertical space above the section title
|
|
680
|
+
#v(section-titles-space-above, weak: true)
|
|
681
|
+
|
|
682
|
+
#block(
|
|
683
|
+
breakable: false,
|
|
684
|
+
width: 100%,
|
|
685
|
+
[
|
|
686
|
+
#if section-titles-type == "moderncv" [
|
|
687
|
+
#grid(
|
|
688
|
+
columns: (entries-date-and-location-width + entries-side-space, 1fr),
|
|
689
|
+
column-gutter: entries-space-between-columns,
|
|
690
|
+
align: (end-align, start-align),
|
|
691
|
+
[
|
|
692
|
+
#align(horizon, box(
|
|
693
|
+
width: 1fr,
|
|
694
|
+
height: section-titles-line-thickness,
|
|
695
|
+
fill: colors-section-titles,
|
|
696
|
+
))
|
|
697
|
+
],
|
|
698
|
+
[
|
|
699
|
+
#section-title
|
|
700
|
+
],
|
|
701
|
+
)
|
|
702
|
+
] else if section-titles-type == "centered_without_line" [
|
|
703
|
+
#section-title
|
|
704
|
+
] else if section-titles-type == "centered_with_partial_line" [
|
|
705
|
+
#grid(
|
|
706
|
+
columns: (1fr, auto, 1fr),
|
|
707
|
+
align: (bottom, center + bottom, bottom),
|
|
708
|
+
column-gutter: 0.3em,
|
|
709
|
+
[#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)],
|
|
710
|
+
[#section-title],
|
|
711
|
+
[#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)],
|
|
712
|
+
)
|
|
713
|
+
] else if section-titles-type == "centered_with_centered_partial_line" [
|
|
714
|
+
#grid(
|
|
715
|
+
columns: (1fr, auto, 1fr),
|
|
716
|
+
align: (horizon, center, horizon),
|
|
717
|
+
column-gutter: 0.3em,
|
|
718
|
+
[#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)],
|
|
719
|
+
[#section-title],
|
|
720
|
+
[#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)],
|
|
721
|
+
)
|
|
722
|
+
] else if section-titles-type == "centered_with_full_line" [
|
|
723
|
+
#section-title
|
|
724
|
+
#v(typography-font-size-body * 0.3)
|
|
725
|
+
#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)
|
|
726
|
+
] else [
|
|
727
|
+
#section-title
|
|
728
|
+
#if section-titles-type == "with_partial_line" [
|
|
729
|
+
#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)
|
|
730
|
+
] else if section-titles-type == "with_full_line" [
|
|
731
|
+
|
|
732
|
+
#v(typography-font-size-body * 0.3)
|
|
733
|
+
#box(width: 1fr, height: section-titles-line-thickness, fill: colors-section-titles)
|
|
734
|
+
]
|
|
735
|
+
]
|
|
736
|
+
],
|
|
737
|
+
)
|
|
738
|
+
|
|
739
|
+
// Vertical space after the section title
|
|
740
|
+
#v(section-titles-space-below - 0.5em)
|
|
741
|
+
]
|
|
742
|
+
|
|
743
|
+
// Top note:
|
|
744
|
+
#if page-show-top-note and top-note != none and top-note != "" {
|
|
745
|
+
let dx = if is-rtl { entries-side-space } else { -entries-side-space }
|
|
746
|
+
place(
|
|
747
|
+
top + end-align,
|
|
748
|
+
dy: -page-top-margin / 2,
|
|
749
|
+
dx: dx,
|
|
750
|
+
text(
|
|
751
|
+
[#top-note],
|
|
752
|
+
fill: colors-top-note,
|
|
753
|
+
size: 0.9em,
|
|
754
|
+
),
|
|
755
|
+
)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// From: https://github.com/typst/typst/issues/2666
|
|
759
|
+
#let group-sections(content) = {
|
|
760
|
+
let sections = ()
|
|
761
|
+
let preamble = () // Content before any heading
|
|
762
|
+
|
|
763
|
+
for element in content.children {
|
|
764
|
+
if element.func() == heading {
|
|
765
|
+
// Push a new section
|
|
766
|
+
sections.push((element, ()))
|
|
767
|
+
} else if sections.len() > 0 {
|
|
768
|
+
// Add to current section
|
|
769
|
+
sections.last().at(1).push(element)
|
|
770
|
+
} else {
|
|
771
|
+
// No heading yet - this is preamble content
|
|
772
|
+
preamble.push(element)
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// Join the content in each section
|
|
777
|
+
let result = sections.map(it => {
|
|
778
|
+
let (title, content) = it
|
|
779
|
+
(title, content.join())
|
|
780
|
+
})
|
|
781
|
+
|
|
782
|
+
// Return both preamble and sections
|
|
783
|
+
(preamble: preamble.join(), sections: result)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#set par(spacing: 0cm)
|
|
787
|
+
|
|
788
|
+
#let grouped = group-sections(doc)
|
|
789
|
+
|
|
790
|
+
// Render preamble content (before any heading)
|
|
791
|
+
#if grouped.preamble != none and grouped.preamble.func() != parbreak [
|
|
792
|
+
#block(breakable: sections-allow-page-break)[
|
|
793
|
+
#grouped.preamble
|
|
794
|
+
]
|
|
795
|
+
]
|
|
796
|
+
|
|
797
|
+
// Render sections as before
|
|
798
|
+
#for (section-title, section-content) in grouped.sections [
|
|
799
|
+
#section-title
|
|
800
|
+
#let should-skip = {
|
|
801
|
+
let skip = false
|
|
802
|
+
if section-content != none and section-content.has("children") {
|
|
803
|
+
for child in section-content.children {
|
|
804
|
+
if child.func() == metadata and child.value == "skip-content-area" {
|
|
805
|
+
skip = true
|
|
806
|
+
break
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
skip
|
|
811
|
+
}
|
|
812
|
+
#if section-content != none and section-content.func() != parbreak [
|
|
813
|
+
#block(breakable: sections-allow-page-break)[
|
|
814
|
+
#if should-skip [
|
|
815
|
+
#section-content
|
|
816
|
+
] else [
|
|
817
|
+
#content-area(section-content)
|
|
818
|
+
]
|
|
819
|
+
]
|
|
820
|
+
]
|
|
821
|
+
]
|
|
822
|
+
]
|
|
823
|
+
`;
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
// src/renderer/assets/rendercv_typst/typst.toml?raw
|
|
828
|
+
var typst_default;
|
|
829
|
+
var init_typst = __esm({
|
|
830
|
+
"src/renderer/assets/rendercv_typst/typst.toml?raw"() {
|
|
831
|
+
typst_default = '[package]\nname = "rendercv"\nversion = "0.3.0"\nentrypoint = "lib.typ"\nauthors = ["Sina Atalay <dev@atalay.biz>"]\nlicense = "MIT"\ndescription = "Resume builder for academics and engineers"\nrepository = "https://github.com/rendercv/rendercv"\nkeywords = ["rendercv", "cv", "resume", "curriculum-vitae"]\ncategories = ["cv"]\ndisciplines = []\ncompiler = "0.14.0"\nexclude = ["examples/*.pdf"]\n\n[template]\npath = "template"\nentrypoint = "main.typ"\nthumbnail = "thumbnail.png"\n';
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
// import("../assets/fonts/**/*?binary") in src/renderer/fonts/load_bundled_font.ts
|
|
836
|
+
var globImport_assets_fonts_binary;
|
|
837
|
+
var init_ = __esm({
|
|
838
|
+
'import("../assets/fonts/**/*?binary") in src/renderer/fonts/load_bundled_font.ts'() {
|
|
839
|
+
globImport_assets_fonts_binary = __glob({});
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
// src/renderer/fonts/load_bundled_font.ts
|
|
844
|
+
function configureBrowserFonts(baseUrl = "/fonts") {
|
|
845
|
+
fontsUrlConfigured = true;
|
|
846
|
+
browserFontsBaseUrl = baseUrl.replace(/\/$/, "");
|
|
847
|
+
}
|
|
848
|
+
function isFontsUrlConfigured() {
|
|
849
|
+
return fontsUrlConfigured;
|
|
850
|
+
}
|
|
851
|
+
function isNodeRuntime() {
|
|
852
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
853
|
+
}
|
|
854
|
+
async function resolveNodeFontsRoot() {
|
|
855
|
+
if (nodeFontsRoot !== void 0) {
|
|
856
|
+
return nodeFontsRoot;
|
|
857
|
+
}
|
|
858
|
+
if (!isNodeRuntime()) {
|
|
859
|
+
nodeFontsRoot = null;
|
|
860
|
+
return null;
|
|
861
|
+
}
|
|
862
|
+
const [{ existsSync: existsSync2 }, path2, { fileURLToPath }] = await Promise.all([
|
|
863
|
+
import("fs"),
|
|
864
|
+
import("path"),
|
|
865
|
+
import("url")
|
|
866
|
+
]);
|
|
867
|
+
const cwd = process.cwd();
|
|
868
|
+
const moduleDir = path2.dirname(fileURLToPath(import_meta.url));
|
|
869
|
+
const candidates = [
|
|
870
|
+
path2.resolve(moduleDir, "../assets/fonts"),
|
|
871
|
+
path2.resolve(moduleDir, "../../assets/fonts"),
|
|
872
|
+
path2.resolve(moduleDir, "../../../assets/fonts"),
|
|
873
|
+
path2.join(cwd, "assets/fonts"),
|
|
874
|
+
path2.join(cwd, "node_modules/rendercv-ts/assets/fonts"),
|
|
875
|
+
path2.join(cwd, "rendercv-ts/assets/fonts"),
|
|
876
|
+
path2.join(cwd, "src/renderer/assets/fonts"),
|
|
877
|
+
path2.join(cwd, "rendercv-ts/src/renderer/assets/fonts")
|
|
878
|
+
];
|
|
879
|
+
for (const candidate of candidates) {
|
|
880
|
+
if (existsSync2(candidate)) {
|
|
881
|
+
nodeFontsRoot = candidate;
|
|
882
|
+
return candidate;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
nodeFontsRoot = null;
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
async function loadBundledFontPath(relativePath) {
|
|
889
|
+
const cached = fontFileCache.get(relativePath);
|
|
890
|
+
if (cached) {
|
|
891
|
+
return cached;
|
|
892
|
+
}
|
|
893
|
+
const fontsRoot = await resolveNodeFontsRoot();
|
|
894
|
+
let bytes;
|
|
895
|
+
if (fontsRoot) {
|
|
896
|
+
const [{ readFile }, path2] = await Promise.all([
|
|
897
|
+
import("fs/promises"),
|
|
898
|
+
import("path")
|
|
899
|
+
]);
|
|
900
|
+
bytes = new Uint8Array(await readFile(path2.join(fontsRoot, relativePath)));
|
|
901
|
+
} else if (typeof window !== "undefined") {
|
|
902
|
+
const response = await fetch(
|
|
903
|
+
`${browserFontsBaseUrl}/${relativePath.split("/").map(encodeURIComponent).join("/")}`
|
|
904
|
+
);
|
|
905
|
+
if (!response.ok) {
|
|
906
|
+
throw new Error(`Failed to load font: ${relativePath} (${response.status})`);
|
|
907
|
+
}
|
|
908
|
+
bytes = new Uint8Array(await response.arrayBuffer());
|
|
909
|
+
} else {
|
|
910
|
+
const mod = await globImport_assets_fonts_binary(`../assets/fonts/${relativePath}?binary`);
|
|
911
|
+
bytes = mod.default;
|
|
912
|
+
}
|
|
913
|
+
fontFileCache.set(relativePath, bytes);
|
|
914
|
+
return bytes;
|
|
915
|
+
}
|
|
916
|
+
async function loadBundledFontPaths(paths) {
|
|
917
|
+
return Promise.all(paths.map((relativePath) => loadBundledFontPath(relativePath)));
|
|
918
|
+
}
|
|
919
|
+
var import_meta, fontFileCache, nodeFontsRoot, browserFontsBaseUrl, fontsUrlConfigured;
|
|
920
|
+
var init_load_bundled_font = __esm({
|
|
921
|
+
"src/renderer/fonts/load_bundled_font.ts"() {
|
|
922
|
+
"use strict";
|
|
923
|
+
init_();
|
|
924
|
+
import_meta = {};
|
|
925
|
+
fontFileCache = /* @__PURE__ */ new Map();
|
|
926
|
+
browserFontsBaseUrl = "/fonts";
|
|
927
|
+
fontsUrlConfigured = false;
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
// src/renderer/asset_paths.ts
|
|
932
|
+
var asset_paths_exports = {};
|
|
933
|
+
__export(asset_paths_exports, {
|
|
934
|
+
configureDefaultAssets: () => configureDefaultAssets,
|
|
935
|
+
resolveBundledAssetPaths: () => resolveBundledAssetPaths
|
|
936
|
+
});
|
|
937
|
+
function resolveBundledAssetPaths(origin = "") {
|
|
938
|
+
const base = origin.replace(/\/$/, "");
|
|
939
|
+
return {
|
|
940
|
+
wasmBaseUrl: `${base}/wasm`,
|
|
941
|
+
fontsBaseUrl: `${base}/fonts`
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
function isNodeRuntime2() {
|
|
945
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
946
|
+
}
|
|
947
|
+
async function resolvePublishAssetsRoot() {
|
|
948
|
+
if (!isNodeRuntime2()) {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
951
|
+
const [{ existsSync: existsSync2 }, path2, { fileURLToPath }] = await Promise.all([
|
|
952
|
+
import("fs"),
|
|
953
|
+
import("path"),
|
|
954
|
+
import("url")
|
|
955
|
+
]);
|
|
956
|
+
const moduleDir = path2.dirname(fileURLToPath(import_meta2.url));
|
|
957
|
+
const cwd = process.cwd();
|
|
958
|
+
const candidates = [
|
|
959
|
+
path2.resolve(moduleDir, "../../assets"),
|
|
960
|
+
path2.resolve(moduleDir, "../assets"),
|
|
961
|
+
path2.join(cwd, "assets"),
|
|
962
|
+
path2.join(cwd, "node_modules/rendercv-ts/assets"),
|
|
963
|
+
path2.join(cwd, "rendercv-ts/assets")
|
|
964
|
+
];
|
|
965
|
+
for (const candidate of candidates) {
|
|
966
|
+
if (existsSync2(path2.join(candidate, "wasm")) && existsSync2(path2.join(candidate, "fonts"))) {
|
|
967
|
+
return candidate;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return null;
|
|
971
|
+
}
|
|
972
|
+
async function injectWasmFromDisk(assetsRoot) {
|
|
973
|
+
const [{ readFile }, path2] = await Promise.all([import("fs/promises"), import("path")]);
|
|
974
|
+
const wasmDir = path2.join(assetsRoot, "wasm");
|
|
975
|
+
const [compiler, renderer] = await Promise.all([
|
|
976
|
+
readFile(path2.join(wasmDir, "typst_ts_web_compiler_bg.wasm")),
|
|
977
|
+
readFile(path2.join(wasmDir, "typst_ts_renderer_bg.wasm"))
|
|
978
|
+
]);
|
|
979
|
+
setBrowserWasmBytes(compiler.buffer, renderer.buffer);
|
|
980
|
+
}
|
|
981
|
+
async function configureDefaultAssets(options) {
|
|
982
|
+
if (assetsConfigured) {
|
|
983
|
+
return resolveBundledAssetPaths(options?.origin ?? getBrowserOrigin());
|
|
984
|
+
}
|
|
985
|
+
const assetsRoot = await resolvePublishAssetsRoot();
|
|
986
|
+
let wasmLoadedFromDisk = false;
|
|
987
|
+
if (assetsRoot && isNodeRuntime2()) {
|
|
988
|
+
await injectWasmFromDisk(assetsRoot);
|
|
989
|
+
wasmLoadedFromDisk = true;
|
|
990
|
+
}
|
|
991
|
+
const origin = options?.origin ?? getBrowserOrigin();
|
|
992
|
+
const paths = resolveBundledAssetPaths(origin);
|
|
993
|
+
if (typeof window !== "undefined" && origin) {
|
|
994
|
+
if (!isWasmUrlConfigured() && !wasmLoadedFromDisk) {
|
|
995
|
+
configureBrowserWasm(paths.wasmBaseUrl);
|
|
996
|
+
}
|
|
997
|
+
if (!isFontsUrlConfigured() && !assetsRoot) {
|
|
998
|
+
configureBrowserFonts(paths.fontsBaseUrl);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
assetsConfigured = true;
|
|
1002
|
+
return paths;
|
|
1003
|
+
}
|
|
1004
|
+
function getBrowserOrigin() {
|
|
1005
|
+
if (typeof window === "undefined") {
|
|
1006
|
+
return "";
|
|
1007
|
+
}
|
|
1008
|
+
return window.location?.origin ?? "";
|
|
1009
|
+
}
|
|
1010
|
+
var import_meta2, assetsConfigured;
|
|
1011
|
+
var init_asset_paths = __esm({
|
|
1012
|
+
"src/renderer/asset_paths.ts"() {
|
|
1013
|
+
"use strict";
|
|
1014
|
+
init_load_bundled_font();
|
|
1015
|
+
init_typst_setup();
|
|
1016
|
+
import_meta2 = {};
|
|
1017
|
+
assetsConfigured = false;
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
// src/renderer/assets/font_manifest.ts
|
|
1022
|
+
async function loadBundledFontPaths2(paths) {
|
|
1023
|
+
return loadBundledFontPaths(paths);
|
|
1024
|
+
}
|
|
1025
|
+
var FONT_FAMILY_ALIASES, bundledFontsByFamily;
|
|
1026
|
+
var init_font_manifest = __esm({
|
|
1027
|
+
"src/renderer/assets/font_manifest.ts"() {
|
|
1028
|
+
"use strict";
|
|
1029
|
+
init_load_bundled_font();
|
|
1030
|
+
FONT_FAMILY_ALIASES = {
|
|
1031
|
+
"Vazirmatn Variable": "Vazirmatn"
|
|
1032
|
+
};
|
|
1033
|
+
bundledFontsByFamily = {
|
|
1034
|
+
"EB Garamond": [
|
|
1035
|
+
"EB Garamond/EBGaramond-Bold.ttf",
|
|
1036
|
+
"EB Garamond/EBGaramond-BoldItalic.ttf",
|
|
1037
|
+
"EB Garamond/EBGaramond-Italic.ttf",
|
|
1038
|
+
"EB Garamond/EBGaramond-Regular.ttf"
|
|
1039
|
+
],
|
|
1040
|
+
"Fontin": [
|
|
1041
|
+
"Fontin/Fontin-Bold.otf",
|
|
1042
|
+
"Fontin/Fontin-Italic.otf",
|
|
1043
|
+
"Fontin/Fontin-Regular.otf"
|
|
1044
|
+
],
|
|
1045
|
+
"Gentium Book Plus": [
|
|
1046
|
+
"Gentium Book Plus/GentiumBookPlus-Bold.ttf",
|
|
1047
|
+
"Gentium Book Plus/GentiumBookPlus-BoldItalic.ttf",
|
|
1048
|
+
"Gentium Book Plus/GentiumBookPlus-Italic.ttf",
|
|
1049
|
+
"Gentium Book Plus/GentiumBookPlus-Regular.ttf"
|
|
1050
|
+
],
|
|
1051
|
+
"Lato": [
|
|
1052
|
+
"Lato/Lato-Bold.ttf",
|
|
1053
|
+
"Lato/Lato-BoldItalic.ttf",
|
|
1054
|
+
"Lato/Lato-Italic.ttf",
|
|
1055
|
+
"Lato/Lato-Regular.ttf"
|
|
1056
|
+
],
|
|
1057
|
+
"Raleway": [
|
|
1058
|
+
"Raleway/Raleway-Bold.ttf",
|
|
1059
|
+
"Raleway/Raleway-BoldItalic.ttf",
|
|
1060
|
+
"Raleway/Raleway-Italic.ttf",
|
|
1061
|
+
"Raleway/Raleway-Regular.ttf"
|
|
1062
|
+
],
|
|
1063
|
+
"Source Sans 3": [
|
|
1064
|
+
"Source Sans 3/SourceSans3-Bold.ttf",
|
|
1065
|
+
"Source Sans 3/SourceSans3-BoldItalic.ttf",
|
|
1066
|
+
"Source Sans 3/SourceSans3-Italic.ttf",
|
|
1067
|
+
"Source Sans 3/SourceSans3-Regular.ttf"
|
|
1068
|
+
],
|
|
1069
|
+
"Ubuntu": [
|
|
1070
|
+
"Ubuntu/Ubuntu-Bold.ttf",
|
|
1071
|
+
"Ubuntu/Ubuntu-BoldItalic.ttf",
|
|
1072
|
+
"Ubuntu/Ubuntu-Italic.ttf",
|
|
1073
|
+
"Ubuntu/Ubuntu-Regular.ttf"
|
|
1074
|
+
],
|
|
1075
|
+
"Vazirmatn": [
|
|
1076
|
+
"Vazirmatn/Vazirmatn-Black.ttf",
|
|
1077
|
+
"Vazirmatn/Vazirmatn-Bold.ttf",
|
|
1078
|
+
"Vazirmatn/Vazirmatn-ExtraBold.ttf",
|
|
1079
|
+
"Vazirmatn/Vazirmatn-ExtraLight.ttf",
|
|
1080
|
+
"Vazirmatn/Vazirmatn-Light.ttf",
|
|
1081
|
+
"Vazirmatn/Vazirmatn-Medium.ttf",
|
|
1082
|
+
"Vazirmatn/Vazirmatn-Regular.ttf",
|
|
1083
|
+
"Vazirmatn/Vazirmatn-SemiBold.ttf",
|
|
1084
|
+
"Vazirmatn/Vazirmatn-Thin.ttf"
|
|
1085
|
+
],
|
|
1086
|
+
"XCharter": [
|
|
1087
|
+
"XCharter/XCharter-Bold.otf",
|
|
1088
|
+
"XCharter/XCharter-BoldItalic.otf",
|
|
1089
|
+
"XCharter/XCharter-Italic.otf",
|
|
1090
|
+
"XCharter/XCharter-Regular.otf"
|
|
1091
|
+
]
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
// src/renderer/fonts/typst_font_cache.ts
|
|
1097
|
+
var typst_font_cache_exports = {};
|
|
1098
|
+
__export(typst_font_cache_exports, {
|
|
1099
|
+
fetchTypstFontBytes: () => fetchTypstFontBytes
|
|
1100
|
+
});
|
|
1101
|
+
function isNodeRuntime3() {
|
|
1102
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
1103
|
+
}
|
|
1104
|
+
function getCacheDir() {
|
|
1105
|
+
if (cacheDir !== void 0) {
|
|
1106
|
+
return cacheDir;
|
|
1107
|
+
}
|
|
1108
|
+
if (!isNodeRuntime3()) {
|
|
1109
|
+
cacheDir = null;
|
|
1110
|
+
return null;
|
|
1111
|
+
}
|
|
1112
|
+
const dir = import_node_path.default.join(process.cwd(), ".rendercv-cache", "typst-fonts", CACHE_VERSION);
|
|
1113
|
+
try {
|
|
1114
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
1115
|
+
cacheDir = dir;
|
|
1116
|
+
return dir;
|
|
1117
|
+
} catch {
|
|
1118
|
+
cacheDir = null;
|
|
1119
|
+
return null;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
function cacheFilePath(url) {
|
|
1123
|
+
const dir = getCacheDir();
|
|
1124
|
+
if (!dir) {
|
|
1125
|
+
return null;
|
|
1126
|
+
}
|
|
1127
|
+
const hash = (0, import_node_crypto.createHash)("sha256").update(url).digest("hex").slice(0, 16);
|
|
1128
|
+
const base = import_node_path.default.basename(url);
|
|
1129
|
+
return import_node_path.default.join(dir, `${hash}-${base}`);
|
|
1130
|
+
}
|
|
1131
|
+
async function fetchTypstFontBytes(url) {
|
|
1132
|
+
const cachedPath = cacheFilePath(url);
|
|
1133
|
+
if (cachedPath && (0, import_node_fs.existsSync)(cachedPath)) {
|
|
1134
|
+
return new Uint8Array((0, import_node_fs.readFileSync)(cachedPath));
|
|
1135
|
+
}
|
|
1136
|
+
const response = await fetch(url);
|
|
1137
|
+
if (!response.ok) {
|
|
1138
|
+
throw new Error(`Font file fetch failed (${response.status}): ${url}`);
|
|
1139
|
+
}
|
|
1140
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
1141
|
+
if (cachedPath) {
|
|
1142
|
+
try {
|
|
1143
|
+
(0, import_node_fs.writeFileSync)(cachedPath, bytes);
|
|
1144
|
+
} catch {
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
return bytes;
|
|
1148
|
+
}
|
|
1149
|
+
var import_node_crypto, import_node_fs, import_node_path, CACHE_VERSION, cacheDir;
|
|
1150
|
+
var init_typst_font_cache = __esm({
|
|
1151
|
+
"src/renderer/fonts/typst_font_cache.ts"() {
|
|
1152
|
+
"use strict";
|
|
1153
|
+
import_node_crypto = require("crypto");
|
|
1154
|
+
import_node_fs = require("fs");
|
|
1155
|
+
import_node_path = __toESM(require("path"), 1);
|
|
1156
|
+
CACHE_VERSION = "v1";
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
|
|
1160
|
+
// src/renderer/fonts/font_registry.ts
|
|
1161
|
+
var font_registry_exports = {};
|
|
1162
|
+
__export(font_registry_exports, {
|
|
1163
|
+
loadBaseFontsForTypst: () => loadBaseFontsForTypst,
|
|
1164
|
+
loadFontsForTypst: () => loadFontsForTypst,
|
|
1165
|
+
modelFontCacheKey: () => modelFontCacheKey
|
|
1166
|
+
});
|
|
1167
|
+
function normalizeFamilyName(family) {
|
|
1168
|
+
return family.trim();
|
|
1169
|
+
}
|
|
1170
|
+
function collectFontFamilies(model) {
|
|
1171
|
+
const typography = model.design.typography;
|
|
1172
|
+
const families = /* @__PURE__ */ new Set();
|
|
1173
|
+
const add = (value) => {
|
|
1174
|
+
if (value) {
|
|
1175
|
+
families.add(normalizeFamilyName(value));
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
add(typography.font_family.body);
|
|
1179
|
+
add(typography.font_family.name);
|
|
1180
|
+
add(typography.font_family.headline);
|
|
1181
|
+
add(typography.font_family.connections);
|
|
1182
|
+
add(typography.font_family.section_titles);
|
|
1183
|
+
return [...families];
|
|
1184
|
+
}
|
|
1185
|
+
function modelFontCacheKey(model) {
|
|
1186
|
+
return collectFontFamilies(model).sort().join(";");
|
|
1187
|
+
}
|
|
1188
|
+
function resolveBundledFolder(family) {
|
|
1189
|
+
return FONT_FAMILY_ALIASES[family] ?? family;
|
|
1190
|
+
}
|
|
1191
|
+
function bundledPathsForFamilies(families) {
|
|
1192
|
+
const paths = /* @__PURE__ */ new Set();
|
|
1193
|
+
for (const family of families) {
|
|
1194
|
+
const folder = resolveBundledFolder(family);
|
|
1195
|
+
for (const path2 of bundledFontsByFamily[folder] ?? []) {
|
|
1196
|
+
paths.add(path2);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
return [...paths].sort();
|
|
1200
|
+
}
|
|
1201
|
+
async function fetchRemoteFontBytes(url) {
|
|
1202
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
1203
|
+
const { fetchTypstFontBytes: fetchTypstFontBytes2 } = await Promise.resolve().then(() => (init_typst_font_cache(), typst_font_cache_exports));
|
|
1204
|
+
return fetchTypstFontBytes2(url);
|
|
1205
|
+
}
|
|
1206
|
+
const response = await fetch(url);
|
|
1207
|
+
if (!response.ok) {
|
|
1208
|
+
throw new Error(`Font file fetch failed (${response.status}): ${url}`);
|
|
1209
|
+
}
|
|
1210
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
1211
|
+
}
|
|
1212
|
+
async function loadTypstTextFontBytes() {
|
|
1213
|
+
if (!typstTextFontBytesPromise) {
|
|
1214
|
+
typstTextFontBytesPromise = Promise.all(
|
|
1215
|
+
TYPST_TEXT_FONTS.map(
|
|
1216
|
+
(fileName) => fetchRemoteFontBytes(`${TYPST_TEXT_FONT_PREFIX}${fileName}`)
|
|
1217
|
+
)
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
return typstTextFontBytesPromise;
|
|
1221
|
+
}
|
|
1222
|
+
async function loadBundledFontBytesForFamilies(families) {
|
|
1223
|
+
const paths = bundledPathsForFamilies(families);
|
|
1224
|
+
if (paths.length === 0) {
|
|
1225
|
+
return [];
|
|
1226
|
+
}
|
|
1227
|
+
return loadBundledFontPaths2(paths);
|
|
1228
|
+
}
|
|
1229
|
+
async function loadBaseFontsForTypst() {
|
|
1230
|
+
return loadTypstTextFontBytes();
|
|
1231
|
+
}
|
|
1232
|
+
async function loadFontsForTypst(model) {
|
|
1233
|
+
const key = modelFontCacheKey(model);
|
|
1234
|
+
let promise = bundledFontBytesByKey.get(key);
|
|
1235
|
+
if (!promise) {
|
|
1236
|
+
promise = (async () => {
|
|
1237
|
+
const families = collectFontFamilies(model);
|
|
1238
|
+
const [typstTextFonts, themeFonts] = await Promise.all([
|
|
1239
|
+
loadTypstTextFontBytes(),
|
|
1240
|
+
loadBundledFontBytesForFamilies(families)
|
|
1241
|
+
]);
|
|
1242
|
+
return [...typstTextFonts, ...themeFonts];
|
|
1243
|
+
})();
|
|
1244
|
+
bundledFontBytesByKey.set(key, promise);
|
|
1245
|
+
}
|
|
1246
|
+
return promise;
|
|
1247
|
+
}
|
|
1248
|
+
var TYPST_TEXT_FONT_PREFIX, TYPST_TEXT_FONTS, typstTextFontBytesPromise, bundledFontBytesByKey;
|
|
1249
|
+
var init_font_registry = __esm({
|
|
1250
|
+
"src/renderer/fonts/font_registry.ts"() {
|
|
1251
|
+
"use strict";
|
|
1252
|
+
init_font_manifest();
|
|
1253
|
+
TYPST_TEXT_FONT_PREFIX = "https://cdn.jsdelivr.net/gh/typst/typst-assets@v0.13.1/files/fonts/";
|
|
1254
|
+
TYPST_TEXT_FONTS = [
|
|
1255
|
+
"DejaVuSansMono-Bold.ttf",
|
|
1256
|
+
"DejaVuSansMono-BoldOblique.ttf",
|
|
1257
|
+
"DejaVuSansMono-Oblique.ttf",
|
|
1258
|
+
"DejaVuSansMono.ttf",
|
|
1259
|
+
"LibertinusSerif-Bold.otf",
|
|
1260
|
+
"LibertinusSerif-BoldItalic.otf",
|
|
1261
|
+
"LibertinusSerif-Italic.otf",
|
|
1262
|
+
"LibertinusSerif-Regular.otf",
|
|
1263
|
+
"LibertinusSerif-Semibold.otf",
|
|
1264
|
+
"LibertinusSerif-SemiboldItalic.otf",
|
|
1265
|
+
"NewCM10-Bold.otf",
|
|
1266
|
+
"NewCM10-BoldItalic.otf",
|
|
1267
|
+
"NewCM10-Italic.otf",
|
|
1268
|
+
"NewCM10-Regular.otf",
|
|
1269
|
+
"NewCMMath-Bold.otf",
|
|
1270
|
+
"NewCMMath-Book.otf",
|
|
1271
|
+
"NewCMMath-Regular.otf"
|
|
1272
|
+
];
|
|
1273
|
+
typstTextFontBytesPromise = null;
|
|
1274
|
+
bundledFontBytesByKey = /* @__PURE__ */ new Map();
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
// src/renderer/typst_setup.ts
|
|
1279
|
+
function configureBrowserWasm(baseUrl = "/wasm") {
|
|
1280
|
+
wasmUrlConfigured = true;
|
|
1281
|
+
browserWasmBaseUrl = baseUrl.replace(/\/$/, "");
|
|
1282
|
+
browserWasmBytes = null;
|
|
1283
|
+
browserWasmPromise = null;
|
|
1284
|
+
}
|
|
1285
|
+
function isWasmUrlConfigured() {
|
|
1286
|
+
return wasmUrlConfigured;
|
|
1287
|
+
}
|
|
1288
|
+
function setBrowserWasmBytes(compiler, renderer) {
|
|
1289
|
+
browserWasmBytes = { compiler, renderer };
|
|
1290
|
+
browserWasmPromise = Promise.resolve();
|
|
1291
|
+
}
|
|
1292
|
+
async function ensureBrowserWasm() {
|
|
1293
|
+
if (typeof window === "undefined") {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
if (browserWasmBytes) {
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
if (!browserWasmPromise) {
|
|
1300
|
+
browserWasmPromise = (async () => {
|
|
1301
|
+
const fetchWasm = async (name) => {
|
|
1302
|
+
const response = await fetch(`${browserWasmBaseUrl}/${name}`);
|
|
1303
|
+
if (!response.ok) {
|
|
1304
|
+
throw new Error(`Failed to load Typst WASM: ${name} (${response.status})`);
|
|
1305
|
+
}
|
|
1306
|
+
return response.arrayBuffer();
|
|
1307
|
+
};
|
|
1308
|
+
const [compiler, renderer] = await Promise.all([
|
|
1309
|
+
fetchWasm("typst_ts_web_compiler_bg.wasm"),
|
|
1310
|
+
fetchWasm("typst_ts_renderer_bg.wasm")
|
|
1311
|
+
]);
|
|
1312
|
+
browserWasmBytes = { compiler, renderer };
|
|
1313
|
+
})();
|
|
1314
|
+
}
|
|
1315
|
+
await browserWasmPromise;
|
|
1316
|
+
}
|
|
1317
|
+
function browserCompilerInitOptions() {
|
|
1318
|
+
if (!browserWasmBytes) {
|
|
1319
|
+
return {};
|
|
1320
|
+
}
|
|
1321
|
+
return { getModule: () => browserWasmBytes.compiler };
|
|
1322
|
+
}
|
|
1323
|
+
function browserRendererInitOptions() {
|
|
1324
|
+
if (!browserWasmBytes) {
|
|
1325
|
+
return {};
|
|
1326
|
+
}
|
|
1327
|
+
return { getModule: () => browserWasmBytes.renderer };
|
|
1328
|
+
}
|
|
1329
|
+
function createBundledPackageRegistry() {
|
|
1330
|
+
const registry = new BundledPackageRegistry();
|
|
1331
|
+
registry.register("rendercv", RENDERCV_PACKAGE_VERSION);
|
|
1332
|
+
return registry;
|
|
1333
|
+
}
|
|
1334
|
+
function readPackageVersion(typstToml) {
|
|
1335
|
+
const match = typstToml.match(/^\s*version\s*=\s*"([^"]+)"/m);
|
|
1336
|
+
if (!match) {
|
|
1337
|
+
throw new Error("Could not find version in bundled typst.toml");
|
|
1338
|
+
}
|
|
1339
|
+
return match[1];
|
|
1340
|
+
}
|
|
1341
|
+
function encodeText(text) {
|
|
1342
|
+
return new TextEncoder().encode(text);
|
|
1343
|
+
}
|
|
1344
|
+
function packageFilePath(name, version, file) {
|
|
1345
|
+
return `/preview/${name}/${version}/${file}`;
|
|
1346
|
+
}
|
|
1347
|
+
function registerPackage(compiler, name, version, files) {
|
|
1348
|
+
for (const [file, content] of Object.entries(files)) {
|
|
1349
|
+
compiler.mapShadow(packageFilePath(name, version, file), encodeText(content));
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
function registerRendercvPackage(compiler) {
|
|
1353
|
+
registerPackage(compiler, "rendercv", RENDERCV_PACKAGE_VERSION, RENDERCV_PACKAGE_FILES);
|
|
1354
|
+
}
|
|
1355
|
+
async function createRuntime() {
|
|
1356
|
+
await ensureBrowserWasm();
|
|
1357
|
+
const compilerWasmOptions = browserCompilerInitOptions();
|
|
1358
|
+
const rendererWasmOptions = browserRendererInitOptions();
|
|
1359
|
+
const compiler = (0, import_typst.createTypstCompiler)();
|
|
1360
|
+
await compiler.init({
|
|
1361
|
+
...compilerWasmOptions,
|
|
1362
|
+
beforeBuild: [
|
|
1363
|
+
import_typst.initOptions.disableDefaultFontAssets(),
|
|
1364
|
+
import_typst.initOptions.withPackageRegistry(createBundledPackageRegistry())
|
|
1365
|
+
]
|
|
1366
|
+
});
|
|
1367
|
+
registerRendercvPackage(compiler);
|
|
1368
|
+
const renderer = (0, import_typst.createTypstRenderer)();
|
|
1369
|
+
await renderer.init(rendererWasmOptions);
|
|
1370
|
+
return { compiler, renderer };
|
|
1371
|
+
}
|
|
1372
|
+
async function applyFontBytesToCompiler(compiler, fontBytes) {
|
|
1373
|
+
await ensureBrowserWasm();
|
|
1374
|
+
const fontBuilder = (0, import_typst.createTypstFontBuilder)();
|
|
1375
|
+
await fontBuilder.init(browserCompilerInitOptions());
|
|
1376
|
+
for (const bytes of fontBytes) {
|
|
1377
|
+
if (bytes.length > 0) {
|
|
1378
|
+
await fontBuilder.addFontData(bytes);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
await fontBuilder.build(async (resolver) => {
|
|
1382
|
+
compiler.setFonts(resolver);
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
async function getTypstRuntime() {
|
|
1386
|
+
if (!runtimePromise) {
|
|
1387
|
+
runtimePromise = (async () => {
|
|
1388
|
+
const { configureDefaultAssets: configureDefaultAssets2 } = await Promise.resolve().then(() => (init_asset_paths(), asset_paths_exports));
|
|
1389
|
+
await configureDefaultAssets2();
|
|
1390
|
+
return createRuntime();
|
|
1391
|
+
})();
|
|
1392
|
+
}
|
|
1393
|
+
return runtimePromise;
|
|
1394
|
+
}
|
|
1395
|
+
async function resolveFontBytesForModel(model) {
|
|
1396
|
+
const { loadFontsForTypst: loadFontsForTypst2, modelFontCacheKey: modelFontCacheKey2 } = await Promise.resolve().then(() => (init_font_registry(), font_registry_exports));
|
|
1397
|
+
const key = modelFontCacheKey2(model);
|
|
1398
|
+
if (cachedFontModelKey === key && cachedFontBytes) {
|
|
1399
|
+
return cachedFontBytes;
|
|
1400
|
+
}
|
|
1401
|
+
cachedFontBytes = await loadFontsForTypst2(model);
|
|
1402
|
+
cachedFontModelKey = key;
|
|
1403
|
+
return cachedFontBytes;
|
|
1404
|
+
}
|
|
1405
|
+
async function ensureFontsForModel(model) {
|
|
1406
|
+
const runtime = await getTypstRuntime();
|
|
1407
|
+
const fontBytes = await resolveFontBytesForModel(model);
|
|
1408
|
+
await applyFontBytesToCompiler(runtime.compiler, fontBytes);
|
|
1409
|
+
}
|
|
1410
|
+
async function prepareTypstCompilation(typstSource, options) {
|
|
1411
|
+
const runtime = await getTypstRuntime();
|
|
1412
|
+
await runtime.compiler.resetShadow();
|
|
1413
|
+
registerRendercvPackage(runtime.compiler);
|
|
1414
|
+
if (options?.model) {
|
|
1415
|
+
await ensureFontsForModel(options.model);
|
|
1416
|
+
} else if (cachedFontBytes === null) {
|
|
1417
|
+
const { loadBaseFontsForTypst: loadBaseFontsForTypst2 } = await Promise.resolve().then(() => (init_font_registry(), font_registry_exports));
|
|
1418
|
+
cachedFontBytes = await loadBaseFontsForTypst2();
|
|
1419
|
+
cachedFontModelKey = "bundled-only";
|
|
1420
|
+
await applyFontBytesToCompiler(runtime.compiler, cachedFontBytes);
|
|
1421
|
+
} else {
|
|
1422
|
+
await applyFontBytesToCompiler(runtime.compiler, cachedFontBytes);
|
|
1423
|
+
}
|
|
1424
|
+
runtime.compiler.addSource(MAIN_TYP_PATH, typstSource);
|
|
1425
|
+
if (options?.photoName && options.photoBytes) {
|
|
1426
|
+
runtime.compiler.mapShadow(`/${options.photoName}`, options.photoBytes);
|
|
1427
|
+
}
|
|
1428
|
+
return { compiler: runtime.compiler, mainFilePath: MAIN_TYP_PATH };
|
|
1429
|
+
}
|
|
1430
|
+
var import_typst, RENDERCV_PACKAGE_VERSION, MAIN_TYP_PATH, TYPST_ROOT, runtimePromise, cachedFontBytes, cachedFontModelKey, browserWasmBaseUrl, browserWasmBytes, browserWasmPromise, wasmUrlConfigured, BundledPackageRegistry, RENDERCV_PACKAGE_FILES;
|
|
1431
|
+
var init_typst_setup = __esm({
|
|
1432
|
+
"src/renderer/typst_setup.ts"() {
|
|
1433
|
+
"use strict";
|
|
1434
|
+
import_typst = require("@myriaddreamin/typst.ts");
|
|
1435
|
+
init_icons();
|
|
1436
|
+
init_lib();
|
|
1437
|
+
init_typst();
|
|
1438
|
+
RENDERCV_PACKAGE_VERSION = readPackageVersion(typst_default);
|
|
1439
|
+
MAIN_TYP_PATH = "/main.typ";
|
|
1440
|
+
TYPST_ROOT = "/";
|
|
1441
|
+
runtimePromise = null;
|
|
1442
|
+
cachedFontBytes = null;
|
|
1443
|
+
cachedFontModelKey = null;
|
|
1444
|
+
browserWasmBaseUrl = "/wasm";
|
|
1445
|
+
browserWasmBytes = null;
|
|
1446
|
+
browserWasmPromise = null;
|
|
1447
|
+
wasmUrlConfigured = false;
|
|
1448
|
+
BundledPackageRegistry = class {
|
|
1449
|
+
packages = /* @__PURE__ */ new Set();
|
|
1450
|
+
register(name, version) {
|
|
1451
|
+
this.packages.add(`${name}/${version}`);
|
|
1452
|
+
}
|
|
1453
|
+
resolve(spec, _context) {
|
|
1454
|
+
if (spec.namespace !== "preview") {
|
|
1455
|
+
return void 0;
|
|
1456
|
+
}
|
|
1457
|
+
const key = `${spec.name}/${spec.version}`;
|
|
1458
|
+
if (!this.packages.has(key)) {
|
|
1459
|
+
return void 0;
|
|
1460
|
+
}
|
|
1461
|
+
return `/preview/${spec.name}/${spec.version}`;
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1464
|
+
RENDERCV_PACKAGE_FILES = {
|
|
1465
|
+
"typst.toml": typst_default,
|
|
1466
|
+
"lib.typ": lib_default,
|
|
1467
|
+
"icons.typ": icons_default
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
});
|
|
1471
|
+
|
|
1472
|
+
// src/renderer/worker/pdf_worker.ts
|
|
1473
|
+
var pdf_worker_exports = {};
|
|
1474
|
+
__export(pdf_worker_exports, {
|
|
1475
|
+
MAIN_TYP_PATH: () => MAIN_TYP_PATH
|
|
1476
|
+
});
|
|
1477
|
+
module.exports = __toCommonJS(pdf_worker_exports);
|
|
1478
|
+
init_typst_setup();
|
|
1479
|
+
async function compilePdfInWorker(request) {
|
|
1480
|
+
const { compiler, mainFilePath } = await prepareTypstCompilation(request.typstSource, {
|
|
1481
|
+
photoName: request.photoName,
|
|
1482
|
+
photoBytes: request.photoBytes,
|
|
1483
|
+
model: request.model
|
|
1484
|
+
});
|
|
1485
|
+
return compiler.runWithWorld({ mainFilePath, root: TYPST_ROOT }, async (world) => {
|
|
1486
|
+
const pdfResult = await world.pdf({ diagnostics: "full" });
|
|
1487
|
+
if (!pdfResult.result?.length) {
|
|
1488
|
+
const message = pdfResult.diagnostics?.map((d) => "message" in d ? d.message : String(d)).join("\n") ?? "Typst compiler returned empty PDF bytes";
|
|
1489
|
+
throw new Error(message);
|
|
1490
|
+
}
|
|
1491
|
+
return pdfResult.result;
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
self.onmessage = (event) => {
|
|
1495
|
+
const request = event.data;
|
|
1496
|
+
if (request.type !== "compile-pdf") {
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
void (async () => {
|
|
1500
|
+
try {
|
|
1501
|
+
const pdf = await compilePdfInWorker(request);
|
|
1502
|
+
const response = {
|
|
1503
|
+
type: "compile-pdf-result",
|
|
1504
|
+
id: request.id,
|
|
1505
|
+
pdf
|
|
1506
|
+
};
|
|
1507
|
+
self.postMessage(response, { transfer: [pdf.buffer] });
|
|
1508
|
+
} catch (error) {
|
|
1509
|
+
const response = {
|
|
1510
|
+
type: "compile-pdf-error",
|
|
1511
|
+
id: request.id,
|
|
1512
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1513
|
+
};
|
|
1514
|
+
self.postMessage(response);
|
|
1515
|
+
}
|
|
1516
|
+
})();
|
|
1517
|
+
};
|
|
1518
|
+
//# sourceMappingURL=pdf_worker.cjs.map
|