Skip to content

Commit 7538c8a

Browse files
normalizeLogo + findLogo = resolveLogo
we were not able to handle the case where document overrides only dark or light logo under the previous structure, because it needs to look at size order also fold in brand and document.logo undefined cases
1 parent 16359c6 commit 7538c8a

File tree

5 files changed

+100
-150
lines changed

5 files changed

+100
-150
lines changed

src/core/brand/brand.ts

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -282,21 +282,40 @@ export const getFavicon = (brand: Brand): string | undefined => {
282282
return logoInfo.path;
283283
};
284284

285-
export async function normalizeLogoSpec(
285+
export function resolveLogo(
286286
brand: LightDarkBrand | undefined,
287-
spec: LogoLightDarkSpecifier,
288-
): Promise<NormalizedLogoLightDarkSpecifier> {
289-
const resolveLogo = (mode: "light" | "dark", name: string) => {
287+
spec: LogoLightDarkSpecifier | undefined,
288+
order: BrandNamedLogo[],
289+
): NormalizedLogoLightDarkSpecifier | undefined {
290+
const resolveBrandLogo = (
291+
mode: "light" | "dark",
292+
name: string,
293+
): LogoOptions => {
290294
const logo = brand?.[mode]?.processedData?.logo;
291295
return logo &&
292-
((Zod.BrandNamedLogo.options.includes(name as BrandNamedLogo) &&
293-
logo[name as BrandNamedLogo]) || logo.images[name]);
296+
((Zod.BrandNamedLogo.options.includes(name as BrandNamedLogo) &&
297+
logo[name as BrandNamedLogo]) || logo.images[name]) ||
298+
{ path: name };
294299
};
300+
function findLogo(
301+
mode: "light" | "dark",
302+
order: BrandNamedLogo[],
303+
): LogoOptions | undefined {
304+
if (brand?.[mode]) {
305+
for (const size of order) {
306+
const logo = brand[mode].processedData.logo[size];
307+
if (logo) {
308+
return logo;
309+
}
310+
}
311+
}
312+
return undefined;
313+
}
295314
const resolveLogoOptions = (
296315
mode: "light" | "dark",
297316
logo: LogoOptions,
298317
): LogoOptions => {
299-
const logo2 = resolveLogo(mode, logo.path);
318+
const logo2 = resolveBrandLogo(mode, logo.path);
300319
if (logo2) {
301320
const { path: _, ...rest } = logo;
302321
return {
@@ -306,10 +325,16 @@ export async function normalizeLogoSpec(
306325
}
307326
return logo;
308327
};
328+
if (!spec) {
329+
return {
330+
light: findLogo("light", order),
331+
dark: findLogo("dark", order),
332+
};
333+
}
309334
if (typeof spec === "string") {
310335
return {
311-
light: resolveLogo("light", spec) || { path: spec },
312-
dark: resolveLogo("light", spec) || { path: spec },
336+
light: resolveBrandLogo("light", spec),
337+
dark: resolveBrandLogo("light", spec),
313338
};
314339
}
315340
if ("path" in spec) {
@@ -319,42 +344,26 @@ export async function normalizeLogoSpec(
319344
};
320345
}
321346
let light, dark;
322-
if (spec.light) {
323-
if (typeof spec.light === "string") {
324-
light = resolveLogo("light", spec.light) || { path: spec.light };
325-
} else {
326-
light = resolveLogoOptions("light", spec.light);
327-
}
347+
if (!spec.light) {
348+
light = findLogo("light", order);
349+
} else if (typeof spec.light === "string") {
350+
light = resolveBrandLogo("light", spec.light);
351+
} else {
352+
light = resolveLogoOptions("light", spec.light);
328353
}
329-
if (spec.dark) {
330-
if (typeof spec.dark === "string") {
331-
dark = resolveLogo("dark", spec.dark) || { path: spec.dark };
332-
} else {
333-
dark = resolveLogoOptions("dark", spec.dark);
334-
}
354+
if (!spec.dark) {
355+
dark = findLogo("dark", order);
356+
} else if (typeof spec.dark === "string") {
357+
dark = resolveBrandLogo("dark", spec.dark);
358+
} else {
359+
dark = resolveLogoOptions("dark", spec.dark);
335360
}
336361
return {
337362
light,
338363
dark,
339364
};
340365
}
341366

342-
export function findLogo(
343-
brand: LightDarkBrand,
344-
mode: "light" | "dark",
345-
order: BrandNamedLogo[],
346-
): LogoOptions | undefined {
347-
if (brand[mode]) {
348-
for (const size of order) {
349-
const logo = brand[mode].processedData.logo[size];
350-
if (logo) {
351-
return logo;
352-
}
353-
}
354-
}
355-
return undefined;
356-
}
357-
358367
function splitColorLightDark(
359368
bcld: BrandColorLightDark,
360369
): LightDarkColor {

src/format/dashboard/format-dashboard.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
kSassBundles,
2929
Metadata,
3030
} from "../../config/types.ts";
31+
import { LogoLightDarkSpecifier } from "../../resources/types/zod/schema-types.ts";
3132
import { PandocFlags } from "../../config/types.ts";
3233
import { mergeConfigs } from "../../core/config.ts";
3334
import { Document, Element } from "../../core/deno-dom.ts";
@@ -65,7 +66,7 @@ import { processToolbars } from "./format-dashboard-toolbar.ts";
6566
import { processDatatables } from "./format-dashboard-tables.ts";
6667
import { assert } from "testing/asserts";
6768
import { brandBootstrapSassBundles } from "../../core/sass/brand.ts";
68-
import { findLogo, normalizeLogoSpec } from "../../core/brand/brand.ts";
69+
import { resolveLogo } from "../../core/brand/brand.ts";
6970

7071
const kDashboardClz = "quarto-dashboard";
7172

@@ -122,17 +123,19 @@ export function dashboardFormat() {
122123
}
123124

124125
const brand = await project.resolveBrand(input);
125-
if (format.metadata[kLogo]) {
126-
format.metadata[kLogo] = await normalizeLogoSpec(
127-
brand,
128-
format.metadata[kLogo],
129-
);
130-
console.log("logo", format.metadata[kLogo]);
131-
} else if (brand) {
132-
const light = findLogo(brand, "light", ["small", "medium", "large"]);
133-
const dark = findLogo(brand, "dark", ["small", "medium", "large"]);
134-
format.metadata[kLogo] = { light, dark };
126+
let logoSpec = format.metadata[kLogo] as LogoLightDarkSpecifier;
127+
if (typeof logoSpec === "string" && format.metadata[kLogoAlt]) {
128+
logoSpec = {
129+
path: logoSpec,
130+
alt: format.metadata[kLogoAlt] as string,
131+
};
135132
}
133+
format.metadata[kLogo] = resolveLogo(brand, logoSpec, [
134+
"small",
135+
"medium",
136+
"large",
137+
]);
138+
console.log("dash logo", format.metadata[kLogo]);
136139

137140
const extras: FormatExtras = await baseHtmlFormat.formatExtras(
138141
input,

src/project/types/website/website-shared.ts

Lines changed: 31 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { Format, FormatExtras } from "../../../config/types.ts";
4747
import { kPageTitle, kTitle, kTitlePrefix } from "../../../config/constants.ts";
4848
import { md5HashAsync } from "../../../core/hash.ts";
4949
export { type NavigationFooter } from "../../types.ts";
50-
import { normalizeLogoSpec } from "../../../core/brand/brand.ts";
50+
import { resolveLogo } from "../../../core/brand/brand.ts";
5151

5252
export interface Navigation {
5353
navbar?: Navbar;
@@ -127,17 +127,21 @@ export async function websiteNavigationConfig(project: ProjectContext) {
127127
} else if (typeof navbar !== "object") {
128128
navbar = undefined;
129129
}
130-
if (navbar && navbar.logo) {
131-
let logo = navbar.logo;
130+
131+
// note no document-level customization of brand logo #11309
132+
const projectBrand = await project.resolveBrand();
133+
if (navbar) {
134+
let navLogo = navbar.logo;
132135
if (navbar[kLogoAlt]) {
133-
if (typeof logo === "string") {
134-
logo = { path: logo, alt: navbar[kLogoAlt] };
136+
if (typeof navLogo === "string") {
137+
navLogo = { path: navLogo, alt: navbar[kLogoAlt] };
135138
}
136139
}
137-
138-
// note no document-level customization of brand logo #11309
139-
const brand = await project.resolveBrand();
140-
navbar.logo = await normalizeLogoSpec(brand, logo);
140+
navbar.logo = resolveLogo(projectBrand, navLogo, [
141+
"small",
142+
"medium",
143+
"large",
144+
]);
141145
}
142146
// read sidebar
143147
const sidebar = websiteConfig(kSiteSidebar, project.config);
@@ -162,37 +166,39 @@ export async function websiteNavigationConfig(project: ProjectContext) {
162166
sidebars[0].tools = [];
163167
}
164168

165-
if (sidebars[0].logo) {
166-
let logo = sidebars[0].logo;
169+
let sideLogo = sidebars[0].logo;
170+
if (sideLogo) {
167171
if (sidebars[0][kLogoAlt]) {
168172
const alt = sidebars[0][kLogoAlt];
169-
if (typeof logo === "string") {
170-
logo = { path: logo, alt };
173+
if (typeof sideLogo === "string") {
174+
sideLogo = { path: sideLogo, alt };
171175
}
172176
// possible but absurd
173-
// else if ("path" in logo) {
174-
// logo = { ...logo, alt };
177+
// else if ("path" in sideLogo) {
178+
// sideLogo = { ...sideLogo, alt };
175179
// } else {
176-
// logo = {
177-
// light: !logo.light ? undefined : typeof logo.light === "string"
180+
// sideLogo = {
181+
// light: !sideLogo.light ? undefined : typeof sideLogo.light === "string"
178182
// ? {
179-
// path: logo.light,
183+
// path: sideLogo.light,
180184
// alt,
181185
// }
182-
// : { ...logo.light, alt },
183-
// dark: !logo.dark ? undefined : typeof logo.dark === "string"
186+
// : { ...sideLogo.light, alt },
187+
// dark: !sideLogo.dark ? undefined : typeof sideLogo.dark === "string"
184188
// ? {
185-
// path: logo.dark,
189+
// path: sideLogo.dark,
186190
// alt,
187191
// }
188-
// : { ...logo.dark, alt },
192+
// : { ...sideLogo.dark, alt },
189193
// };
190194
// }
191195
}
192-
// note no document-level customization of brand logo #11309
193-
const brand = await project.resolveBrand();
194-
sidebars[0].logo = await normalizeLogoSpec(brand, logo);
195196
}
197+
sidebars[0].logo = resolveLogo(projectBrand, sideLogo, [
198+
"medium",
199+
"small",
200+
"large",
201+
]);
196202

197203
// convert contents: auto into items
198204
for (const sb of sidebars) {
@@ -210,47 +216,6 @@ export async function websiteNavigationConfig(project: ProjectContext) {
210216
}
211217
}
212218

213-
const projectBrand = await project.resolveBrand();
214-
if (
215-
projectBrand?.light?.processedData.logo && sidebars?.[0]
216-
) {
217-
if (sidebars[0].logo === undefined) {
218-
const light = projectBrand.light.processedData.logo.medium ??
219-
projectBrand.light.processedData.logo.small ??
220-
projectBrand.light.processedData.logo.large;
221-
const dark = projectBrand.dark && (
222-
projectBrand.dark.processedData.logo.medium ??
223-
projectBrand.dark.processedData.logo.small ??
224-
projectBrand.dark.processedData.logo.large
225-
);
226-
if (light || dark) {
227-
sidebars[0].logo = {
228-
light,
229-
dark,
230-
};
231-
}
232-
}
233-
}
234-
235-
if (
236-
projectBrand?.light?.processedData.logo && navbar
237-
) {
238-
if (navbar.logo === undefined) {
239-
const light = projectBrand.light.processedData.logo.small ??
240-
projectBrand.light.processedData.logo.medium ??
241-
projectBrand.light.processedData.logo.large;
242-
const dark = projectBrand.dark?.processedData.logo.small ??
243-
projectBrand.dark?.processedData.logo.medium ??
244-
projectBrand.dark?.processedData.logo.large;
245-
if (light || dark) {
246-
navbar.logo = {
247-
light,
248-
dark,
249-
};
250-
}
251-
}
252-
}
253-
254219
// if there is more than one sidebar then propagate options from the
255220
// first sidebar to the others
256221
if (sidebars && sidebars.length > 1) {

src/resources/filters/quarto-post/dashboard.lua

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -737,41 +737,14 @@ function render_dashboard()
737737
return doc
738738
end
739739
end
740+
}, {
741+
Meta = function(meta)
742+
-- weird that i need to forward this here.
743+
-- i'd prefer to directly change the pandoc metadata in ts
744+
-- but i couldn't figure it out
745+
meta.logo = param('logo')
746+
return meta
747+
end
740748
}
741-
-- , {
742-
-- -- todo: dark mode
743-
-- Meta = function(meta)
744-
-- local logo = meta.logo
745-
-- local resolved
746-
-- if logo then
747-
-- if pandoc.utils.type(logo) == 'Inlines' then
748-
-- resolved = _quarto.modules.brand.get_logo('light', logo[1].text)
749-
-- elseif type(logo) == 'table' then
750-
-- local brandLogo = _quarto.modules.brand.get_logo('light', logo.path[1].text)
751-
-- if brandLogo then
752-
-- resolved = {
753-
-- path = brandLogo.path,
754-
-- alt = logo.alt or brandLogo.alt
755-
-- }
756-
-- else
757-
-- resolved = {
758-
-- path = logo.path,
759-
-- alt = logo.alt
760-
-- }
761-
-- end
762-
-- end
763-
-- else
764-
-- resolved = _quarto.modules.brand.get_logo('light', 'small')
765-
-- or _quarto.modules.brand.get_logo('light', 'medium')
766-
-- or _quarto.modules.brand.get_logo('light', 'large')
767-
-- end
768-
-- if resolved then
769-
-- meta.logo = resolved.path
770-
-- meta['logo-alt'] = resolved.alt
771-
-- end
772-
773-
-- return meta
774-
-- end
775-
-- }
776749
}
777750
end

src/resources/formats/dashboard/_nav-container.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
<div class="navbar-brand-container">
2+
<div class="navbar-brand-container">
33
$if(logo.light)$ <a href="#"><img src="$logo.light.path$" alt="$logo.light.alt$" class="navbar-logo light-content d-inline-block"></a>$endif$
44
$if(logo.dark)$ <a href="#"><img src="$logo.dark.path$" alt="$logo.dark.alt$" class="navbar-logo dark-content d-inline-block"></a>$endif$
55
<div class="navbar-title">

0 commit comments

Comments
 (0)