diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index f11c2906dcb..c7296f85d62 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -17,6 +17,7 @@ All changes included in 1.7: ## Website projects - ([#11701](https://github.com/quarto-dev/quarto-cli/issues/11701)): Wrap HTML emitted by EJS templates in `{=html}` blocks to avoid memory blowup issues with Pandoc's parser. +- ([#12134](https://github.com/quarto-dev/quarto-cli/issues/12134)): Forward `logo.small` images in `_brand.yml` files to a website `favicon`. ## Blog projects @@ -25,6 +26,7 @@ All changes included in 1.7: ## Book projects - ([#11520](https://github.com/quarto-dev/quarto-cli/issues/11520)): Book's cover image now escapes lightbox treatment, which was incorrectly applied to it when `lightbox: true` was set in the book's configuration. +- ([#12134](https://github.com/quarto-dev/quarto-cli/issues/12134)): Forward `logo.small` images in `_brand.yml` files to the `favicon` of the book's website. ## `quarto check` diff --git a/src/core/brand/brand.ts b/src/core/brand/brand.ts index d291fd4348a..b6292c40f7a 100644 --- a/src/core/brand/brand.ts +++ b/src/core/brand/brand.ts @@ -283,3 +283,11 @@ export class Brand { } } } + +export const getFavicon = (brand: Brand): string | undefined => { + const logoInfo = brand.getLogo("small"); + if (!logoInfo) { + return undefined; + } + return logoInfo.light.path; +}; diff --git a/src/project/types/book/book-config.ts b/src/project/types/book/book-config.ts index a66081bb3a8..05847a80ab2 100644 --- a/src/project/types/book/book-config.ts +++ b/src/project/types/book/book-config.ts @@ -125,6 +125,7 @@ import { import { projectType } from "../project-types.ts"; import { BookRenderItem, BookRenderItemType } from "./book-types.ts"; import { isAbsoluteRef } from "../../../core/http.ts"; +import { getFavicon } from "../../../core/brand/brand.ts"; export async function bookProjectConfig( project: ProjectContext, @@ -141,6 +142,12 @@ export async function bookProjectConfig( if (book) { site[kSiteTitle] = book[kSiteTitle]; site[kSiteFavicon] = book[kSiteFavicon]; + if (!site[kSiteFavicon]) { + const brand = await project.resolveBrand(); + if (brand) { + site[kSiteFavicon] = getFavicon(brand); + } + } site[kSiteUrl] = book[kSiteUrl]; site[kSitePath] = book[kSitePath]; site[kSiteRepoUrl] = book[kSiteRepoUrl]; diff --git a/src/project/types/website/website.ts b/src/project/types/website/website.ts index c5248dd64ae..07ecb45aa8b 100644 --- a/src/project/types/website/website.ts +++ b/src/project/types/website/website.ts @@ -90,6 +90,7 @@ import { kFieldCategories } from "./listing/website-listing-shared.ts"; import { pandocNativeStr } from "../../../core/pandoc/codegen.ts"; import { asArray } from "../../../core/array.ts"; import { canonicalizeTitlePostprocessor } from "../../../format/html/format-html-title.ts"; +import { getFavicon } from "../../../core/brand/brand.ts"; export const kSiteTemplateDefault = "default"; export const kSiteTemplateBlog = "blog"; @@ -178,7 +179,13 @@ export const websiteProjectType: ProjectType = { } // dependency for favicon if we have one - const favicon = websiteConfigString(kSiteFavicon, project.config); + let favicon = websiteConfigString(kSiteFavicon, project.config); + if (!favicon) { + const brand = await project.resolveBrand(); + if (brand) { + favicon = getFavicon(brand); + } + } if (favicon) { const offset = projectOffset(project, source); extras.html = extras.html || {}; diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/.gitignore b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/.gitignore new file mode 100644 index 00000000000..075b2542afb --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_brand.yml b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_brand.yml new file mode 100644 index 00000000000..acdfd043211 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_brand.yml @@ -0,0 +1,2 @@ +logo: + small: logos/small.png diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_quarto.yml b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_quarto.yml new file mode 100644 index 00000000000..af340dc56bc --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/_quarto.yml @@ -0,0 +1,25 @@ +project: + type: book + +book: + title: "brand-icon-small-favicon-book" + author: "Norah Jones" + date: "2/21/2025" + chapters: + - index.qmd + - intro.qmd + - summary.qmd + - references.qmd + +bibliography: references.bib + +format: + html: + theme: + - cosmo + - brand + pdf: + documentclass: scrreprt + + + diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/cover.png b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/cover.png new file mode 100644 index 00000000000..e1f5bc61d11 Binary files /dev/null and b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/cover.png differ diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd new file mode 100644 index 00000000000..06ec2006de2 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd @@ -0,0 +1,14 @@ +--- +_quarto: + tests: + html: + ensureFileRegexMatches: + - [''] + - [] +--- + +# Preface {.unnumbered} + +This is a Quarto book. + +To learn more about Quarto books visit . diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/intro.qmd b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/intro.qmd new file mode 100644 index 00000000000..efcf1721e9d --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/intro.qmd @@ -0,0 +1,5 @@ +# Introduction + +This is a book created from markdown and executable code. + +See @knuth84 for additional discussion of literate programming. diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.bib b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.bib new file mode 100644 index 00000000000..0220dbdf2e2 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.bib @@ -0,0 +1,19 @@ +@article{knuth84, + author = {Knuth, Donald E.}, + title = {Literate Programming}, + year = {1984}, + issue_date = {May 1984}, + publisher = {Oxford University Press, Inc.}, + address = {USA}, + volume = {27}, + number = {2}, + issn = {0010-4620}, + url = {https://doi.org/10.1093/comjnl/27.2.97}, + doi = {10.1093/comjnl/27.2.97}, + journal = {Comput. J.}, + month = may, + pages = {97–111}, + numpages = {15} +} + + diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.qmd b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.qmd new file mode 100644 index 00000000000..925f7c49464 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/references.qmd @@ -0,0 +1,4 @@ +# References {.unnumbered} + +::: {#refs} +::: diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/summary.qmd b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/summary.qmd new file mode 100644 index 00000000000..b450ab7d0e3 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/summary.qmd @@ -0,0 +1,3 @@ +# Summary + +In summary, this book has no content whatsoever. diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/.gitignore b/tests/docs/smoke-all/brand/logo/website-favicon/.gitignore new file mode 100644 index 00000000000..075b2542afb --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/_brand.yml b/tests/docs/smoke-all/brand/logo/website-favicon/_brand.yml new file mode 100644 index 00000000000..1c74182234f --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/_brand.yml @@ -0,0 +1,2 @@ +logo: + small: logos/small.png diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/_quarto.yml b/tests/docs/smoke-all/brand/logo/website-favicon/_quarto.yml new file mode 100644 index 00000000000..448df0081f2 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/_quarto.yml @@ -0,0 +1,21 @@ +project: + type: website + +website: + title: "test-brand-favicon" + navbar: + left: + - href: index.qmd + text: Home + - about.qmd + +format: + html: + theme: + - cosmo + - brand + css: styles.css + toc: true + + + diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/about.qmd b/tests/docs/smoke-all/brand/logo/website-favicon/about.qmd new file mode 100644 index 00000000000..07c5e7f9d13 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/about.qmd @@ -0,0 +1,5 @@ +--- +title: "About" +--- + +About this site diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd b/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd new file mode 100644 index 00000000000..f20e6354104 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd @@ -0,0 +1,13 @@ +--- +title: "test-brand-favicon" +_quarto: + tests: + html: + ensureFileRegexMatches: + - [''] + - [] +--- + +This is a Quarto website. + +To learn more about Quarto websites visit . diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/logos/small.png b/tests/docs/smoke-all/brand/logo/website-favicon/logos/small.png new file mode 100644 index 00000000000..fb4fbfd3f2a Binary files /dev/null and b/tests/docs/smoke-all/brand/logo/website-favicon/logos/small.png differ diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/styles.css b/tests/docs/smoke-all/brand/logo/website-favicon/styles.css new file mode 100644 index 00000000000..2ddf50c7b42 --- /dev/null +++ b/tests/docs/smoke-all/brand/logo/website-favicon/styles.css @@ -0,0 +1 @@ +/* css styles */