Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ All changes included in 1.7:

## `html` format

- ([#12277](https://github.com/quarto-dev/quarto-cli/pull/12277)): Provide light and dark plot and table renderings with `renderings: [light,dark]`
- ([#11860](https://github.com/quarto-dev/quarto-cli/issues/11860)): ES6 modules that import other local JS modules in documents with `embed-resources: true` are now correctly embedded.
- ([#1325](https://github.com/quarto-dev/quarto-cli/issues/1325)): Dark Mode pages should not flash light on reload. (Nor should Light Mode pages flash dark.)

## `pdf` format

Expand Down
42 changes: 27 additions & 15 deletions src/command/render/pandoc-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export async function resolveSassBundles(
// Note that the other bundle provides light
targets[0].attribs = {
...targets[0].attribs,
...attribForThemeStyle("light", defaultStyle),
...attribForThemeStyle("light"),
};

// Provide a dark bundle for this
Expand All @@ -144,14 +144,19 @@ export async function resolveSassBundles(
bundle.key = bundle.key + "-dark";
return bundle;
});
targets.push({
const darkTarget = {
name: `${dependency}-dark.min.css`,
bundles: darkBundles as any,
attribs: {
"append-hash": "true",
...attribForThemeStyle("dark", defaultStyle),
...attribForThemeStyle("dark"),
},
});
};
if (defaultStyle === "dark") {
targets.push(darkTarget);
} else {
targets.unshift(darkTarget);
}

hasDarkStyles = true;
}
Expand Down Expand Up @@ -256,6 +261,18 @@ export async function resolveSassBundles(
}

// Resolve generated quarto css variables
if (hasDarkStyles && defaultStyle !== "dark") {
// Put dark stylesheet first if light is default (for NoJS)
extras = await resolveQuartoSyntaxHighlighting(
inputDir,
extras,
format,
project,
"dark",
defaultStyle,
);
}

extras = await resolveQuartoSyntaxHighlighting(
inputDir,
extras,
Expand All @@ -265,8 +282,8 @@ export async function resolveSassBundles(
defaultStyle,
);

if (hasDarkStyles) {
// Provide dark variables for this
if (hasDarkStyles && defaultStyle === "dark") {
// Put dark stylesheet second if dark is default (for NoJS)
extras = await resolveQuartoSyntaxHighlighting(
inputDir,
extras,
Expand Down Expand Up @@ -303,7 +320,7 @@ async function resolveQuartoSyntaxHighlighting(
extras = cloneDeep(extras);

// If we're using default highlighting, use theme darkness to select highlight style
const mediaAttr = attribForThemeStyle(style, defaultStyle);
const mediaAttr = attribForThemeStyle(style);
if (style === "default") {
if (extras.html?.[kTextHighlightingMode] === "dark") {
style = "dark";
Expand Down Expand Up @@ -559,28 +576,23 @@ const kVariablesRegex =
/\/\*\! quarto-variables-start \*\/([\S\s]*)\/\*\! quarto-variables-end \*\//g;

// Attributes for the style tag
// Note that we default disable the dark mode and rely on JS to enable it
function attribForThemeStyle(
style: "dark" | "light" | "default",
defaultStyle?: "dark" | "light",
): Record<string, string> {
const colorModeAttrs = (mode: string, disabled: boolean) => {
const colorModeAttrs = (mode: string) => {
const attr: Record<string, string> = {
class: `quarto-color-scheme${
mode === "dark" ? " quarto-color-alternate" : ""
}`,
};
if (disabled) {
attr.rel = "prefetch";
}
return attr;
};

switch (style) {
case "dark":
return colorModeAttrs("dark", defaultStyle !== "dark");
return colorModeAttrs("dark");
case "light":
return colorModeAttrs("light", false);
return colorModeAttrs("light");
case "default":
default:
return {};
Expand Down
12 changes: 12 additions & 0 deletions src/format/html/format-html-bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,18 @@ function bootstrapHtmlFinalizer(format: Format, flags: PandocFlags) {
}
}

// start body with light or dark class for proper display when JS is disabled
let initialLightDarkClass = "quarto-light";
// some logic duplicated from resolveThemeLayer
const theme = format.metadata.theme;
if (theme && !Array.isArray(theme) && typeof theme === "object") {
const keys = Object.keys(theme);
if(keys.length > 1 && keys[0] === "dark") {
initialLightDarkClass = "quarto-dark";
}
}
doc.body.classList.add(initialLightDarkClass);

// If there is no margin content and no toc in the right margin
// then lower the z-order so everything else can get on top
// of the sidebar
Expand Down
29 changes: 18 additions & 11 deletions src/format/html/format-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
kFigResponsive,
kFilterParams,
kHeaderIncludes,
kIncludeBeforeBody,
kIncludeAfterBody,
kIncludeInHeader,
kLinkExternalFilter,
Expand Down Expand Up @@ -501,28 +502,33 @@ export async function htmlFormatExtras(
renderEjs(
formatResourcePath("html", join("hypothesis", "hypothesis.ejs")),
{ hypothesis: options.hypothesis },
),
)
);
includeInHeader.push(hypothesisHeader);
}

// after body
// before and after body
const includeBeforeBody: string[] = [];
const includeAfterBody: string[] = [];

// add main orchestion script if we have any options enabled
const quartoHtmlRequired = Object.keys(options).some((option) =>
!!options[option]
);
if (quartoHtmlRequired) {
// html orchestration script
const quartoHtmlScript = temp.createFile();
const renderedHtml = renderEjs(
formatResourcePath("html", join("templates", "quarto-html.ejs")),
options,
);
if (renderedHtml.trim() !== "") {
Deno.writeTextFileSync(quartoHtmlScript, renderedHtml);
includeAfterBody.push(quartoHtmlScript);
for(const {dest, ejsfile} of [
{dest: includeBeforeBody, ejsfile: "quarto-html-before-body.ejs"},
{dest: includeAfterBody, ejsfile: "quarto-html-after-body.ejs"}
]) {
const quartoHtmlScript = temp.createFile();
const renderedHtml = renderEjs(
formatResourcePath("html", join("templates", ejsfile)),
options,
);
if (renderedHtml.trim() !== "") {
Deno.writeTextFileSync(quartoHtmlScript, renderedHtml);
dest.push(quartoHtmlScript);
}
}
}

Expand Down Expand Up @@ -636,6 +642,7 @@ export async function htmlFormatExtras(
const metadata: Metadata = {};
return {
[kIncludeInHeader]: includeInHeader,
[kIncludeBeforeBody]: includeBeforeBody,
[kIncludeAfterBody]: includeAfterBody,
metadata,
templateContext,
Expand Down
37 changes: 32 additions & 5 deletions src/resources/editor/tools/vs-code.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7041,6 +7041,13 @@ var require_yaml_intelligence_resources = __commonJS({
schema: "string",
description: "Classes to apply to cell container"
},
{
name: "renderings",
schema: {
arrayOf: "string"
},
description: "Array of rendering names"
},
{
name: "tags",
tags: {
Expand Down Expand Up @@ -19887,6 +19894,13 @@ var require_yaml_intelligence_resources = __commonJS({
},
errorMessage: "type key not supported at project type-level. Use `project: type: ...` instead.",
description: "internal-schema-hack"
},
{
name: "engines",
schema: {
arrayOf: "string"
},
description: "List execution engines you want to give priority when determining which engine should render a notebook. If two engines have support for a notebook, the one listed earlier will be chosen. Quarto's default order is 'knitr', 'jupyter', 'markdown', 'julia'."
}
],
"schema/schema.yml": [
Expand Down Expand Up @@ -23967,7 +23981,9 @@ var require_yaml_intelligence_resources = __commonJS({
},
"Disambiguating year suffix in author-date styles (e.g.&nbsp;\u201Ca\u201D in \u201CDoe,\n1999a\u201D).",
"Manuscript configuration",
"internal-schema-hack"
"internal-schema-hack",
"Array of rendering names",
"List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019."
],
"schema/external-schemas.yml": [
{
Expand Down Expand Up @@ -24196,12 +24212,12 @@ var require_yaml_intelligence_resources = __commonJS({
mermaid: "%%"
},
"handlers/mermaid/schema.yml": {
_internalId: 194269,
_internalId: 194327,
type: "object",
description: "be an object",
properties: {
"mermaid-format": {
_internalId: 194261,
_internalId: 194319,
type: "enum",
enum: [
"png",
Expand All @@ -24217,7 +24233,7 @@ var require_yaml_intelligence_resources = __commonJS({
exhaustiveCompletions: true
},
theme: {
_internalId: 194268,
_internalId: 194326,
type: "anyOf",
anyOf: [
{
Expand Down Expand Up @@ -33253,11 +33269,22 @@ var jupyterEngineSchema = defineCached(
},
"engine-jupyter"
);
var juliaEnginesSchema = defineCached(
// deno-lint-ignore require-await
async () => {
return {
schema: makeEngineSchema("julia"),
errorHandlers: []
};
},
"engine-julia"
);
async function getEngineOptionsSchema() {
const obj = {
markdown: await markdownEngineSchema(),
knitr: await knitrEngineSchema(),
jupyter: await jupyterEngineSchema()
jupyter: await jupyterEngineSchema(),
julia: await juliaEnginesSchema()
};
return obj;
}
Expand Down
37 changes: 32 additions & 5 deletions src/resources/editor/tools/yaml/web-worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading