diff --git a/src/command/render/output-typst.ts b/src/command/render/output-typst.ts index eb9ba2d2a2..83c3810d5e 100644 --- a/src/command/render/output-typst.ts +++ b/src/command/render/output-typst.ts @@ -8,6 +8,7 @@ import { dirname, join, normalize, relative } from "path/mod.ts"; import { ensureDirSync } from "fs/mod.ts"; import { + kFontPaths, kKeepTyp, kOutputExt, kOutputFile, @@ -23,6 +24,7 @@ import { typstCompile, validateRequiredTypstVersion, } from "../../core/typst.ts"; +import { asArray } from "../../core/array.ts"; export function useTypstPdfOutputRecipe( format: Format, @@ -58,7 +60,12 @@ export function typstPdfOutputRecipe( // run typst await validateRequiredTypstVersion(); const pdfOutput = join(inputDir, inputStem + ".pdf"); - const result = await typstCompile(input, pdfOutput, options.flags?.quiet); + const result = await typstCompile( + input, + pdfOutput, + options.flags?.quiet, + asArray(format.metadata?.[kFontPaths]) as string[], + ); if (!result.success) { throw new Error(); } diff --git a/src/config/constants.ts b/src/config/constants.ts index 3a72915b76..c2373b3b61 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -131,6 +131,8 @@ export const kQuartoRequired = "quarto-required"; export const kPreviewMode = "preview-mode"; export const kPreviewModeRaw = "raw"; +export const kFontPaths = "font-paths"; + export const kHtmlTableProcessing = "html-table-processing"; export const kIdentifierDefaultsKeys = [ diff --git a/src/core/typst.ts b/src/core/typst.ts index 0002c10e25..cfc60358e9 100644 --- a/src/core/typst.ts +++ b/src/core/typst.ts @@ -19,21 +19,36 @@ export function typstBinaryPath() { architectureToolsPath("typst"); } +function fontPathsArgs(fontPaths?: string[]) { + // orders matter and fontPathsQuarto should be first for our template to work + const fontPathsQuarto = ["--font-path", resourcePath("formats/typst/fonts")]; + const fontPathsEnv = Deno.env.get("TYPST_FONT_PATHS"); + let fontExtrasArgs: string[] = []; + if (fontPaths && fontPaths.length > 0) { + fontExtrasArgs = fontPaths.map((p) => ["--font-path", p]).flat(); + } else if (fontPathsEnv) { + // Env var is used only if not specified in config by user + // to respect Typst behavior where `--font-path` has precedence over env var + return fontExtrasArgs = ["--font-path", fontPathsEnv]; + } + + return fontPathsQuarto.concat(fontExtrasArgs); +} + export async function typstCompile( input: string, output: string, quiet = false, + fontPaths?: string[], ) { if (!quiet) { typstProgress(input, output); } - const cmd = [ typstBinaryPath(), "compile", input, - "--font-path", - resourcePath("formats/typst/fonts"), + ...fontPathsArgs(fontPaths), output, ]; const result = await execProcess({ cmd }); diff --git a/src/resources/editor/tools/vs-code.mjs b/src/resources/editor/tools/vs-code.mjs index 583ba63b33..197df2c5fa 100644 --- a/src/resources/editor/tools/vs-code.mjs +++ b/src/resources/editor/tools/vs-code.mjs @@ -13440,6 +13440,21 @@ var require_yaml_intelligence_resources = __commonJS({ long: "The math font options for use with `xelatex` or `lualatex` allowing\nany options available through [`fontspec`](https://ctan.org/pkg/fontspec).\n" } }, + { + name: "font-paths", + schema: { + maybeArrayOf: "string" + }, + tags: { + formats: [ + "typst" + ] + }, + description: { + short: "Adds additional directories to search for fonts when compiling with Typst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom path \ncan be specified to add directories that should be scanned for fonts.\nSetting this configuration will take precedence over any path set in TYPST_FONT_PATHS environment variable.\n" + } + }, { name: "CJKoptions", schema: { @@ -21275,6 +21290,10 @@ var require_yaml_intelligence_resources = __commonJS({ short: "The mode to use when previewing this document.", long: "The mode to use when previewing this document. To disable any special\npreviewing features, pass raw as the preview-mode." }, + { + short: "Adds additional directories to search for fonts when compiling with\nTypst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + }, { short: "Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.", long: 'Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.\nIf the value is set to true, 1b:2005 will\nbe used as default.\nTo successfully generate PDF/A the required ICC color profiles have\nto be available and the content and all included files (such as images)\nhave to be standard conforming. The ICC profiles and output intent may\nbe specified using the variables pdfaiccprofile and\npdfaintent. See also ConTeXt PDFA for more\ndetails.' @@ -22226,7 +22245,11 @@ var require_yaml_intelligence_resources = __commonJS({ }, "Disambiguating year suffix in author-date styles (e.g. \u201Ca\u201D in \u201CDoe,\n1999a\u201D).", "Manuscript configuration", - "internal-schema-hack" + "internal-schema-hack", + { + short: "Adds additional directories to search for fonts when compiling with\nTypst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + } ], "schema/external-schemas.yml": [ { @@ -22450,12 +22473,12 @@ var require_yaml_intelligence_resources = __commonJS({ mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 178122, + _internalId: 178550, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 178114, + _internalId: 178542, type: "enum", enum: [ "png", @@ -22471,7 +22494,7 @@ var require_yaml_intelligence_resources = __commonJS({ exhaustiveCompletions: true }, theme: { - _internalId: 178121, + _internalId: 178549, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/web-worker.js b/src/resources/editor/tools/yaml/web-worker.js index f963cf3976..f45d12c7e2 100644 --- a/src/resources/editor/tools/yaml/web-worker.js +++ b/src/resources/editor/tools/yaml/web-worker.js @@ -13441,6 +13441,21 @@ try { long: "The math font options for use with `xelatex` or `lualatex` allowing\nany options available through [`fontspec`](https://ctan.org/pkg/fontspec).\n" } }, + { + name: "font-paths", + schema: { + maybeArrayOf: "string" + }, + tags: { + formats: [ + "typst" + ] + }, + description: { + short: "Adds additional directories to search for fonts when compiling with Typst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom path \ncan be specified to add directories that should be scanned for fonts.\nSetting this configuration will take precedence over any path set in TYPST_FONT_PATHS environment variable.\n" + } + }, { name: "CJKoptions", schema: { @@ -21276,6 +21291,10 @@ try { short: "The mode to use when previewing this document.", long: "The mode to use when previewing this document. To disable any special\npreviewing features, pass raw as the preview-mode." }, + { + short: "Adds additional directories to search for fonts when compiling with\nTypst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + }, { short: "Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.", long: 'Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.\nIf the value is set to true, 1b:2005 will\nbe used as default.\nTo successfully generate PDF/A the required ICC color profiles have\nto be available and the content and all included files (such as images)\nhave to be standard conforming. The ICC profiles and output intent may\nbe specified using the variables pdfaiccprofile and\npdfaintent. See also ConTeXt PDFA for more\ndetails.' @@ -22227,7 +22246,11 @@ try { }, "Disambiguating year suffix in author-date styles (e.g. \u201Ca\u201D in \u201CDoe,\n1999a\u201D).", "Manuscript configuration", - "internal-schema-hack" + "internal-schema-hack", + { + short: "Adds additional directories to search for fonts when compiling with\nTypst.", + long: "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + } ], "schema/external-schemas.yml": [ { @@ -22451,12 +22474,12 @@ try { mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 178122, + _internalId: 178550, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 178114, + _internalId: 178542, type: "enum", enum: [ "png", @@ -22472,7 +22495,7 @@ try { exhaustiveCompletions: true }, theme: { - _internalId: 178121, + _internalId: 178549, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json index 2aa0ceab8b..101cadc2a9 100644 --- a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json +++ b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json @@ -6412,6 +6412,21 @@ "long": "The math font options for use with `xelatex` or `lualatex` allowing\nany options available through [`fontspec`](https://ctan.org/pkg/fontspec).\n" } }, + { + "name": "font-paths", + "schema": { + "maybeArrayOf": "string" + }, + "tags": { + "formats": [ + "typst" + ] + }, + "description": { + "short": "Adds additional directories to search for fonts when compiling with Typst.", + "long": "Locally, Typst uses installed system fonts. In addition, some custom path \ncan be specified to add directories that should be scanned for fonts.\nSetting this configuration will take precedence over any path set in TYPST_FONT_PATHS environment variable.\n" + } + }, { "name": "CJKoptions", "schema": { @@ -14247,6 +14262,10 @@ "short": "The mode to use when previewing this document.", "long": "The mode to use when previewing this document. To disable any special\npreviewing features, pass raw as the preview-mode." }, + { + "short": "Adds additional directories to search for fonts when compiling with\nTypst.", + "long": "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + }, { "short": "Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.", "long": "Adds the necessary setup to the document preamble to generate PDF/A\nof the type specified.\nIf the value is set to true, 1b:2005 will\nbe used as default.\nTo successfully generate PDF/A the required ICC color profiles have\nto be available and the content and all included files (such as images)\nhave to be standard conforming. The ICC profiles and output intent may\nbe specified using the variables pdfaiccprofile and\npdfaintent. See also ConTeXt PDFA for more\ndetails." @@ -15198,7 +15217,11 @@ }, "Disambiguating year suffix in author-date styles (e.g. “a” in “Doe,\n1999a”).", "Manuscript configuration", - "internal-schema-hack" + "internal-schema-hack", + { + "short": "Adds additional directories to search for fonts when compiling with\nTypst.", + "long": "Locally, Typst uses installed system fonts. In addition, some custom\npath can be specified to add directories that should be scanned for\nfonts. Setting this configuration will take precedence over any path set\nin TYPST_FONT_PATHS environment variable." + } ], "schema/external-schemas.yml": [ { @@ -15422,12 +15445,12 @@ "mermaid": "%%" }, "handlers/mermaid/schema.yml": { - "_internalId": 178122, + "_internalId": 178550, "type": "object", "description": "be an object", "properties": { "mermaid-format": { - "_internalId": 178114, + "_internalId": 178542, "type": "enum", "enum": [ "png", @@ -15443,7 +15466,7 @@ "exhaustiveCompletions": true }, "theme": { - "_internalId": 178121, + "_internalId": 178549, "type": "anyOf", "anyOf": [ { diff --git a/src/resources/schema/document-fonts.yml b/src/resources/schema/document-fonts.yml index 616d43d142..4cd13b8106 100644 --- a/src/resources/schema/document-fonts.yml +++ b/src/resources/schema/document-fonts.yml @@ -179,6 +179,18 @@ The math font options for use with `xelatex` or `lualatex` allowing any options available through [`fontspec`](https://ctan.org/pkg/fontspec). +- name: font-paths + schema: + maybeArrayOf: string + tags: + formats: [typst] + description: + short: "Adds additional directories to search for fonts when compiling with Typst." + long: | + Locally, Typst uses installed system fonts. In addition, some custom path + can be specified to add directories that should be scanned for fonts. + Setting this configuration will take precedence over any path set in TYPST_FONT_PATHS environment variable. + - name: CJKoptions schema: maybeArrayOf: string diff --git a/tests/docs/smoke-all/typst/custom-fonts.qmd b/tests/docs/smoke-all/typst/custom-fonts.qmd new file mode 100644 index 0000000000..9419a248e9 --- /dev/null +++ b/tests/docs/smoke-all/typst/custom-fonts.qmd @@ -0,0 +1,16 @@ +--- +title: font typst +format: + typst: + mainfont: "Agbalumo" + font-paths: myfonts +#TODO: How to test the PDF for correct font usage ? +--- + +# Content + +This is a sentence + +::: {.callout-note} +Where the icon should be ok +::: diff --git a/tests/docs/smoke-all/typst/myfonts/Agbalumo-Regular.ttf b/tests/docs/smoke-all/typst/myfonts/Agbalumo-Regular.ttf new file mode 100644 index 0000000000..bc6168e55c Binary files /dev/null and b/tests/docs/smoke-all/typst/myfonts/Agbalumo-Regular.ttf differ