Skip to content

Commit edf4f8d

Browse files
typst: continue to have path be optional in logo
and properly extend this to {light,dark} with also optional path this is kind of silly but this is how typst logo is historically so if typst logo now takes light, dark then those also have optional path i guess it's also proof that none of the other formats really need path this does not extend to enabling dark brand in a typst document only through the logo. that will fail to resolve a logo and you'll need to enable dark brand in brand
1 parent 27832d1 commit edf4f8d

File tree

7 files changed

+260
-6
lines changed

7 files changed

+260
-6
lines changed

src/core/brand/brand.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ import { join, relative } from "../../deno_ral/path.ts";
3333
import { warnOnce } from "../log.ts";
3434
import { isCssColorName } from "../css/color-names.ts";
3535
import { assert } from "testing/asserts";
36+
import {
37+
LogoLightDarkSpecifierPathOptional,
38+
LogoOptionsPathOptional,
39+
LogoSpecifier,
40+
LogoSpecifierPathOptional,
41+
} from "../../resources/types/schema-types.ts";
3642

3743
type ProcessedBrandData = {
3844
color: Record<string, string>;
@@ -379,6 +385,62 @@ export function resolveLogo(
379385
};
380386
}
381387

388+
// this a typst workaround but might as well write it as a proper function
389+
export function fillLogoPaths(
390+
brand: LightDarkBrand | undefined,
391+
spec: LogoLightDarkSpecifierPathOptional | undefined,
392+
order: BrandNamedLogo[],
393+
): LogoLightDarkSpecifier | undefined {
394+
function findLogoSize(
395+
mode: "light" | "dark",
396+
): string | undefined {
397+
if (brand?.[mode]) {
398+
for (const size of order) {
399+
if (brand[mode].processedData.logo[size]) {
400+
return size;
401+
}
402+
}
403+
}
404+
return undefined;
405+
}
406+
function resolveMode(
407+
mode: "light" | "dark",
408+
spec: LogoSpecifierPathOptional | undefined,
409+
): LogoSpecifier | undefined {
410+
if (!spec) {
411+
return undefined;
412+
}
413+
if (!spec || typeof spec === "string") {
414+
return spec;
415+
} else if (spec.path) {
416+
return spec as LogoOptions;
417+
} else {
418+
const size = findLogoSize(mode) ||
419+
findLogoSize(mode === "light" ? "dark" : "light");
420+
if (size) {
421+
return {
422+
path: size,
423+
...spec,
424+
};
425+
}
426+
}
427+
return undefined;
428+
}
429+
if (!spec || typeof spec === "string") {
430+
return spec;
431+
}
432+
if ("light" in spec || "dark" in spec) {
433+
return {
434+
light: resolveMode("light", spec.light),
435+
dark: resolveMode("dark", spec.dark),
436+
};
437+
}
438+
return {
439+
light: resolveMode("light", spec as LogoOptionsPathOptional),
440+
dark: resolveMode("dark", spec as LogoOptionsPathOptional),
441+
};
442+
}
443+
382444
function splitColorLightDark(
383445
bcld: BrandColorLightDark,
384446
): LightDarkColor {

src/format/typst/format-typst.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ import {
3131
import { formatResourcePath } from "../../core/resources.ts";
3232
import { createFormat } from "../formats-shared.ts";
3333
import { hasLevelOneHeadings as hasL1Headings } from "../../core/lib/markdown-analysis/level-one-headings.ts";
34-
import { LogoLightDarkSpecifier } from "../../resources/types/schema-types.ts";
35-
import { resolveLogo } from "../../core/brand/brand.ts";
34+
import {
35+
BrandNamedLogo,
36+
LogoLightDarkSpecifier,
37+
} from "../../resources/types/schema-types.ts";
38+
import { fillLogoPaths, resolveLogo } from "../../core/brand/brand.ts";
39+
import { LogoLightDarkSpecifierPathOptional } from "../../resources/types/zod/schema-types.ts";
3640

3741
export function typstFormat(): Format {
3842
return createFormat("Typst", "pdf", {
@@ -82,13 +86,18 @@ export function typstFormat(): Format {
8286
}
8387

8488
const brand = format.render.brand;
85-
const logoSpec = format.metadata[kLogo] as LogoLightDarkSpecifier;
86-
format.metadata[kLogo] = resolveLogo(brand, logoSpec, [
89+
const logoSpec = format
90+
.metadata[kLogo] as LogoLightDarkSpecifierPathOptional;
91+
const sizeOrder: BrandNamedLogo[] = [
8792
"small",
8893
"medium",
8994
"large",
90-
]);
91-
95+
];
96+
// temporary: if document logo has object or light/dark objects
97+
// without path, do our own findLogo to add the path
98+
// typst is the exception not needing path but we'll probably deprecate this
99+
const logo = fillLogoPaths(brand, logoSpec, sizeOrder);
100+
format.metadata[kLogo] = resolveLogo(brand, logo, sizeOrder);
92101
// force columns to wrap and move any 'columns' setting to metadata
93102
const columns = format.pandoc[kColumns];
94103
if (columns) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: "Logo with Directional Padding"
3+
format:
4+
typst:
5+
keep-typ: true
6+
logo:
7+
location: center-middle
8+
padding-top: 30px
9+
padding-right: 50px
10+
padding-bottom: 10px
11+
padding-left: 20px
12+
width: 180px
13+
brand:
14+
logo:
15+
large: quarto/quarto.png
16+
_quarto:
17+
tests:
18+
typst:
19+
ensureTypstFileRegexMatches:
20+
-
21+
- '#set page\(background: align\(center\+horizon, box\(inset: \(bottom: 7.5pt, left: 15pt, right: 37.5pt, top: 22.5pt\), image\("quarto(/|\\\\)quarto.png", width: 135pt\)\)\)\)'
22+
- []
23+
---
24+
25+
{{< lipsum 4 >}}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: "Light/Dark Logo with Directional Padding (Dark Mode)"
3+
format:
4+
typst:
5+
keep-typ: true
6+
brand-mode: dark
7+
logo:
8+
light:
9+
location: left-middle
10+
padding-top: 25px
11+
padding-right: 15px
12+
padding-bottom: 25px
13+
padding-left: 35px
14+
width: 220px
15+
dark:
16+
location: right-middle
17+
padding-top: 40px
18+
padding-right: 30px
19+
padding-bottom: 20px
20+
padding-left: 10px
21+
width: 160px
22+
brand:
23+
logo:
24+
large: quarto/quarto.png
25+
# note: we will not get proper resolution of the above dark logo
26+
# unless brand.yml dark mode is enabled. this is ok
27+
color:
28+
foreground:
29+
light: "#112288"
30+
dark: "#ccd2b2"
31+
background:
32+
light: "#ccff88"
33+
dark: "#0d0519"
34+
_quarto:
35+
tests:
36+
typst:
37+
ensureTypstFileRegexMatches:
38+
-
39+
- '#set page\(background: align\(right\+horizon, box\(inset: \(bottom: 15pt, left: 7.5pt, right: 22.5pt, top: 30pt\), image\("quarto(/|\\\\)quarto.png", width: 120pt\)\)\)\)'
40+
- []
41+
---
42+
43+
{{< lipsum 4 >}}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: "Light/Dark Logo with Directional Padding"
3+
format:
4+
typst:
5+
keep-typ: true
6+
logo:
7+
light:
8+
location: left-middle
9+
padding-top: 25px
10+
padding-right: 15px
11+
padding-bottom: 25px
12+
padding-left: 35px
13+
width: 220px
14+
dark:
15+
location: right-middle
16+
padding-top: 40px
17+
padding-right: 30px
18+
padding-bottom: 20px
19+
padding-left: 10px
20+
width: 160px
21+
brand:
22+
logo:
23+
large: quarto/quarto.png
24+
# note: we will not get proper resolution of the above dark logo
25+
# unless brand.yml dark mode is enabled. this is ok
26+
color:
27+
foreground:
28+
light: "#112288"
29+
dark: "#ccd2b2"
30+
background:
31+
light: "#ccff88"
32+
dark: "#0d0519"
33+
_quarto:
34+
tests:
35+
typst:
36+
ensureTypstFileRegexMatches:
37+
-
38+
- '#set page\(background: align\(left\+horizon, box\(inset: \(bottom: 18.75pt, left: 26.25pt, right: 11.25pt, top: 18.75pt\), image\("quarto(/|\\\\)quarto.png", width: 165pt\)\)\)\)'
39+
- []
40+
---
41+
42+
{{< lipsum 4 >}}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
title: "Light/Dark Logo Variants Dark Mode"
3+
format:
4+
typst:
5+
keep-typ: true
6+
brand-mode: dark
7+
logo:
8+
light:
9+
location: left-top
10+
padding: 24px
11+
width: 250px
12+
dark:
13+
location: right-bottom
14+
padding: 40px
15+
width: 200px
16+
brand:
17+
logo:
18+
large: quarto/quarto.png
19+
# note: we will not get proper resolution of the above dark logo
20+
# unless brand.yml dark mode is enabled. this is ok
21+
color:
22+
foreground:
23+
light: "#112288"
24+
dark: "#ccd2b2"
25+
background:
26+
light: "#ccff88"
27+
dark: "#0d0519"
28+
_quarto:
29+
tests:
30+
typst:
31+
ensureTypstFileRegexMatches:
32+
-
33+
- '#set page\(background: align\(right\+bottom, box\(inset: 30pt, image\("quarto(/|\\\\)quarto.png", width: 150pt\)\)\)\)'
34+
- []
35+
---
36+
37+
{{< lipsum 4 >}}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: "Light/Dark Logo Variants"
3+
format:
4+
typst:
5+
keep-typ: true
6+
logo:
7+
light:
8+
location: left-top
9+
padding: 24px
10+
width: 250px
11+
dark:
12+
location: right-bottom
13+
padding: 40px
14+
width: 200px
15+
brand:
16+
logo:
17+
large: quarto/quarto.png
18+
# note: we will not get proper resolution of the above dark logo
19+
# unless brand.yml dark mode is enabled. this is ok
20+
color:
21+
foreground:
22+
light: "#112288"
23+
dark: "#ccd2b2"
24+
background:
25+
light: "#ccff88"
26+
dark: "#0d0519"
27+
_quarto:
28+
tests:
29+
typst:
30+
ensureTypstFileRegexMatches:
31+
-
32+
- '#set page\(background: align\(left\+top, box\(inset: 18pt, image\("quarto(/|\\\\)quarto.png", width: 187.5pt\)\)\)\)'
33+
- []
34+
---
35+
36+
{{< lipsum 4 >}}

0 commit comments

Comments
 (0)