Skip to content

Commit 1c0d65b

Browse files
authored
Merge pull request #4760 from quarto-dev/feature/grid-content-mode
Add support for `content-mode` in the grid system
2 parents c3b708b + aec8efc commit 1c0d65b

File tree

7 files changed

+167
-79
lines changed

7 files changed

+167
-79
lines changed

src/config/constants.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,13 @@ export const kCrossrefChaptersAppendix = "chapters-appendix";
513513
export const kCrossrefChaptersAlpha = "chapters-alpha";
514514
export const kCrossrefChapterId = "chapter-id";
515515

516+
export const kGrid = "grid";
517+
export const kContentMode = "content-mode";
518+
export const kAuto = "auto";
519+
export const kStandardContent = "standard";
520+
export const kFullContent = "full";
521+
export const kSlimContent = "slim";
522+
516523
export const kFigResponsive = "fig-responsive";
517524
export const kOutputLocation = "output-location";
518525

src/format/html/format-html-bootstrap.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import { formatResourcePath } from "../../core/resources.ts";
1313
import { findParent } from "../../core/html.ts";
1414

1515
import {
16+
kContentMode,
1617
kDisplayName,
1718
kExtensionName,
1819
kFormatLinks,
20+
kGrid,
1921
kHtmlMathMethod,
2022
kIncludeInHeader,
2123
kLinkCitations,
@@ -630,23 +632,41 @@ function bootstrapHtmlFinalizer(format: Format, flags: PandocFlags) {
630632
if (rightSidebar && !hasRightContent && !hasMarginContent && !hasToc) {
631633
rightSidebar.remove();
632634
}
633-
const hasColumnElements = getColumnLayoutElements(doc).length > 0;
634635

635-
if (hasColumnElements) {
636-
if (hasLeftContent && hasMarginContent) {
637-
// Slim down the content area so there are sizable margins
638-
// for the column element
639-
doc.body.classList.add("slimcontent");
640-
} else if (hasRightContent || hasMarginContent || fullLayout || hasToc) {
641-
// Use the default layout, so don't add any classes
636+
// Set the content mode for the grid system
637+
const gridObj = format.metadata[kGrid] as Metadata;
638+
let contentMode = "auto";
639+
if (gridObj) {
640+
contentMode =
641+
gridObj[kContentMode] as ("auto" | "standard" | "full" | "slim");
642+
}
643+
644+
if (contentMode === undefined || contentMode === "auto") {
645+
const hasColumnElements = getColumnLayoutElements(doc).length > 0;
646+
if (hasColumnElements) {
647+
if (hasLeftContent && hasMarginContent) {
648+
// Slim down the content area so there are sizable margins
649+
// for the column element
650+
doc.body.classList.add("slimcontent");
651+
} else if (
652+
hasRightContent || hasMarginContent || fullLayout || hasToc
653+
) {
654+
// Use the default layout, so don't add any classes
655+
} else {
656+
doc.body.classList.add("fullcontent");
657+
}
642658
} else {
643-
doc.body.classList.add("fullcontent");
659+
if (!hasRightContent && !hasMarginContent && !hasToc) {
660+
doc.body.classList.add("fullcontent");
661+
} else {
662+
// Use the deafult layout, don't add any classes
663+
}
644664
}
645665
} else {
646-
if (!hasRightContent && !hasMarginContent && !hasToc) {
666+
if (contentMode === "slim") {
667+
doc.body.classList.add("slimcontent");
668+
} else if (contentMode === "full") {
647669
doc.body.classList.add("fullcontent");
648-
} else {
649-
// Use the deafult layout, don't add any classes
650670
}
651671
}
652672

src/format/html/format-html-scss.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { outputVariable, SassVariable, sassVariable } from "../../core/sass.ts";
2222

2323
import { Format, SassBundle, SassLayer } from "../../config/types.ts";
2424
import { Metadata } from "../../config/types.ts";
25-
import { kTheme } from "../../config/constants.ts";
25+
import { kGrid, kTheme } from "../../config/constants.ts";
2626

2727
import {
2828
kPageFooter,
@@ -456,7 +456,7 @@ function pandocVariablesToThemeDefaults(
456456
});
457457

458458
// Resolve any grid variables
459-
const gridObj = metadata["grid"] as Metadata;
459+
const gridObj = metadata[kGrid] as Metadata;
460460
if (gridObj) {
461461
add(explicitVars, "grid-sidebar-width", gridObj["sidebar-width"]);
462462
add(explicitVars, "grid-margin-width", gridObj["margin-width"]);

src/resources/editor/tools/vs-code.mjs

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13916,6 +13916,15 @@ var require_yaml_intelligence_resources = __commonJS({
1391613916
object: {
1391713917
closed: true,
1391813918
properties: {
13919+
"content-mode": {
13920+
enum: [
13921+
"auto",
13922+
"standard",
13923+
"full",
13924+
"slim"
13925+
],
13926+
description: "Defines whether to use the standard, slim, or full content grid or to automatically select the most appropriate content grid."
13927+
},
1391913928
"sidebar-width": {
1392013929
string: {
1392113930
description: "The base width of the sidebar (left) column in an HTML page."
@@ -19258,10 +19267,6 @@ var require_yaml_intelligence_resources = __commonJS({
1925819267
"Specify a default profile and profile groups",
1925919268
"Default profile to apply if QUARTO_PROFILE is not defined.",
1926019269
"Define a profile group for which at least one profile is always\nactive.",
19261-
{
19262-
short: "Location of output relative to the code that generated it\n(<code>default</code>, <code>fragment</code>, <code>slide</code>,\n<code>column</code>, or <code>column-location</code>)",
19263-
long: "Location of output relative to the code that generated it. The\npossible values are as follows:"
19264-
},
1926519270
{
1926619271
short: "Unique label for code cell",
1926719272
long: "Unique label for code cell. Used when other code needs to refer to\nthe cell (e.g.&nbsp;for cross references <code>fig-samples</code> or\n<code>tbl-summary</code>)"
@@ -19414,6 +19419,10 @@ var require_yaml_intelligence_resources = __commonJS({
1941419419
"Include errors in the output (note that this implies that errors\nexecuting code will not halt processing of the document).",
1941519420
"Catch all for preventing any output (code or results) from being\nincluded in output.",
1941619421
"Panel type for cell output (<code>tabset</code>, <code>input</code>,\n<code>sidebar</code>, <code>fill</code>, <code>center</code>)",
19422+
{
19423+
short: "Location of output relative to the code that generated it\n(<code>default</code>, <code>fragment</code>, <code>slide</code>,\n<code>column</code>, or <code>column-location</code>)",
19424+
long: "Location of output relative to the code that generated it. The\npossible values are as follows:"
19425+
},
1941719426
"Include messages in rendered output.",
1941819427
{
1941919428
short: "How to display text results",
@@ -19930,6 +19939,7 @@ var require_yaml_intelligence_resources = __commonJS({
1993019939
short: "Properties of the grid system used to layout Quarto HTML pages.",
1993119940
long: ""
1993219941
},
19942+
"Defines whether to use the standard, slim, or full content grid or to\nautomatically select the most appropriate content grid.",
1993319943
"The base width of the sidebar (left) column in an HTML page.",
1993419944
"The base width of the margin (right) column in an HTML page.",
1993519945
"The base width of the body (center) column in an HTML page.",
@@ -20233,6 +20243,10 @@ var require_yaml_intelligence_resources = __commonJS({
2023320243
short: "Use a smaller default font for slide content",
2023420244
long: "<code>true</code> to use a smaller default font for slide content.\nThis can also be set per-slide by including the <code>.smaller</code>\nclass on the slide title."
2023520245
},
20246+
{
20247+
short: "Location of output relative to the code that generated it\n(<code>default</code>, <code>fragment</code>, <code>slide</code>,\n<code>column</code>, or <code>column-location</code>)",
20248+
long: "Location of output relative to the code that generated it. The\npossible values are as follows:"
20249+
},
2023620250
"Flags if the presentation is running in an embedded mode",
2023720251
"The display mode that will be used to show slides",
2023820252
"For slides with a single top-level image, automatically stretch it to\nfill the slide.",
@@ -21255,12 +21269,12 @@ var require_yaml_intelligence_resources = __commonJS({
2125521269
mermaid: "%%"
2125621270
},
2125721271
"handlers/mermaid/schema.yml": {
21258-
_internalId: 151940,
21272+
_internalId: 152136,
2125921273
type: "object",
2126021274
description: "be an object",
2126121275
properties: {
2126221276
"mermaid-format": {
21263-
_internalId: 151932,
21277+
_internalId: 152128,
2126421278
type: "enum",
2126521279
enum: [
2126621280
"png",
@@ -21276,7 +21290,7 @@ var require_yaml_intelligence_resources = __commonJS({
2127621290
exhaustiveCompletions: true
2127721291
},
2127821292
theme: {
21279-
_internalId: 151939,
21293+
_internalId: 152135,
2128021294
type: "anyOf",
2128121295
anyOf: [
2128221296
{
@@ -30377,36 +30391,44 @@ function parseShortcodeCapture(capture) {
3037730391
const rawParams = [];
3037830392
const name = nameMatch[0];
3037930393
let paramStr = capture.slice(name.length).trim();
30380-
const paramName = "([a-zA-Z0-9_-]+)";
30381-
const paramValue1 = `([^"'\\s]+)`;
30382-
const paramValue2 = `"([^"]*)"`;
30383-
const paramValue3 = `'([^']*)'`;
30384-
const paramValue = `(?:${paramValue1})|(?:${paramValue2})|(?:${paramValue3})`;
30385-
const paramNameAndValue = `(?:${paramName}\\s*=\\s*${paramValue1})|(?:${paramName}\\s*=\\s*${paramValue2})|(?:${paramName}\\s*=\\s*${paramValue3})`;
30386-
const paramRe = new RegExp(`(?:${paramValue}|${paramNameAndValue})`);
3038730394
while (paramStr.length) {
30388-
const paramMatch = paramStr.match(paramRe);
30395+
let paramMatch;
30396+
paramMatch = paramStr.match(/^[a-zA-Z0-9_-]+="[^"]*"/);
30397+
if (!paramMatch) {
30398+
paramMatch = paramStr.match(/^[a-zA-Z0-9_-]+='[^']*'/);
30399+
}
3038930400
if (!paramMatch) {
30390-
throw new Error("invalid shortcode: " + capture);
30401+
paramMatch = paramStr.match(/^[a-zA-Z0-9_-]+=[^"'\s]+/);
3039130402
}
30392-
const captures = paramMatch.slice(1).filter((x) => x !== void 0);
30393-
if (captures.length === 1) {
30394-
params.push(captures[0]);
30403+
if (paramMatch) {
30404+
const [name2, value] = paramMatch[0].split("=");
30405+
namedParams[name2] = value;
3039530406
rawParams.push({
30396-
value: captures[0]
30407+
name: name2,
30408+
value
3039730409
});
30398-
} else if (captures.length === 2) {
30399-
namedParams[captures[0]] = captures[1];
30410+
paramStr = paramStr.slice(paramMatch[0].length).trim();
30411+
continue;
30412+
}
30413+
paramMatch = paramStr.match(/^[^"'\s]+/);
30414+
if (paramMatch) {
30415+
params.push(paramMatch[0]);
3040030416
rawParams.push({
30401-
name: captures[0],
30402-
value: captures[1]
30417+
value: paramMatch[0]
3040330418
});
30404-
} else {
30405-
throw new Error(
30406-
"Internal Error, could not determine correct shortcode capture for " + capture
30407-
);
30419+
paramStr = paramStr.slice(paramMatch[0].length).trim();
30420+
continue;
30421+
}
30422+
paramMatch = paramStr.match(/^"[^"]*"/) || paramStr.match(/^'[^']*'/);
30423+
if (paramMatch) {
30424+
params.push(paramMatch[0].slice(1, -1));
30425+
rawParams.push({
30426+
value: paramMatch[0].slice(1, -1)
30427+
});
30428+
paramStr = paramStr.slice(paramMatch[0].length).trim();
30429+
continue;
3040830430
}
30409-
paramStr = paramStr.slice(paramMatch[0].length).trim();
30431+
throw new Error("invalid shortcode: " + capture);
3041030432
}
3041130433
return { name, params, namedParams, rawParams };
3041230434
}

src/resources/editor/tools/yaml/web-worker.js

Lines changed: 51 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)