Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/toc-body-side #5325

Merged
merged 14 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 12 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
3 changes: 3 additions & 0 deletions news/changelog-1.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

- Add support for setting the Giscus light/dark themes. ([#4820](https://github.com/quarto-dev/quarto-cli/issues/4820))

## Table of Contents - side and body
- Add support for `body-right` and `body-left` layouts for Website Table of Contents ([#3473](https://github.com/quarto-dev/quarto-cli/issues/3473))

## Languages

- Add Slovak translation (thanks @tom67)
Expand Down
14 changes: 12 additions & 2 deletions src/format/html/format-html-bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,19 @@ function bootstrapHtmlPostprocessor(
}

// move the toc if there is a sidebar
const toc = doc.querySelector('nav[role="doc-toc"]');
let toc = doc.querySelector('nav[role="doc-toc"]');

const tocTarget = doc.getElementById("quarto-toc-target");

const useDoubleToc = (format.metadata[kTocLocation] as string)?.includes('-body') ?? false;

if (toc && tocTarget) {
if(useDoubleToc) {
const clonedToc = toc.cloneNode(true);
toc.id = "TOC-body";
toc = clonedToc as Element;
}

// activate selection behavior for this
toc.classList.add("toc-active");

Expand All @@ -294,7 +303,8 @@ function bootstrapHtmlPostprocessor(
}
}
// add nav-link class to the TOC links
const tocLinks = doc.querySelectorAll('nav[role="doc-toc"] > ul a');
const tocLinks = doc.querySelectorAll('nav#TOC[role="doc-toc"] > ul a');

for (let i = 0; i < tocLinks.length; i++) {
// Mark the toc links as nav-links
const tocLink = tocLinks[i] as Element;
Expand Down
15 changes: 9 additions & 6 deletions src/resources/editor/tools/vs-code.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17247,7 +17247,9 @@ var require_yaml_intelligence_resources = __commonJS({
enum: [
"body",
"left",
"right"
"right",
"left-body",
"right-body"
]
},
default: "right",
Expand All @@ -17256,7 +17258,10 @@ var require_yaml_intelligence_resources = __commonJS({
"$html-doc"
]
},
description: "Location for table of contents (`body`, `left`, or `right` (default)).\n"
description: {
short: "Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').\n",
long: "Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').\n`body` - Show the Table of Contents in the center body of the document.\n`left` - Show the Table of Contents in left margin of the document.\n`left` - Show the Table of Contents in right margin of the document.\n`left-body` - Show two Tables of Contents in both the center body and the left margin of the document.\n`right-body` - Show two Tables of Contents in both the center body and the right margin of the document.\n"
}
},
{
name: "toc-title",
Expand Down Expand Up @@ -28077,10 +28082,8 @@ function postProcessAnnotation(parse) {
if (parse.components.length === 1 && parse.start === parse.components[0].start && parse.end === parse.components[0].end) {
return postProcessAnnotation(parse.components[0]);
} else {
return {
...parse,
components: parse.components.map(postProcessAnnotation)
};
parse.components = parse.components.map(postProcessAnnotation);
allenmanning marked this conversation as resolved.
Show resolved Hide resolved
return parse;
}
}
function jsYamlParseLenient(yml) {
Expand Down
15 changes: 9 additions & 6 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.

Original file line number Diff line number Diff line change
Expand Up @@ -10223,7 +10223,9 @@
"enum": [
"body",
"left",
"right"
"right",
"left-body",
"right-body"
]
},
"default": "right",
Expand All @@ -10232,7 +10234,10 @@
"$html-doc"
]
},
"description": "Location for table of contents (`body`, `left`, or `right` (default)).\n"
"description": {
"short": "Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').\n",
"long": "Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').\n`body` - Show the Table of Contents in the center body of the document.\n`left` - Show the Table of Contents in left margin of the document.\n`left` - Show the Table of Contents in right margin of the document.\n`left-body` - Show two Tables of Contents in both the center body and the left margin of the document.\n`right-body` - Show two Tables of Contents in both the center body and the right margin of the document.\n"
}
},
{
"name": "toc-title",
Expand Down
11 changes: 8 additions & 3 deletions src/resources/formats/html/templates/before-body-article.ejs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<div id="quarto-content" class="page-columns page-rows-contents page-layout-<%- pageLayout %><%- tocLocation === "left" ? " toc-left" : ""%>">
<%
const navbarTocLeft = tocLocation === "left" || tocLocation === "left-body";
const navbarTocRight = tocLocation === "right" || tocLocation === "right-body";
%>

<% if (tocLocation === "left") { %>
<div id="quarto-content" class="page-columns page-rows-contents page-layout-<%- pageLayout %><%- (navbarTocLeft) ? " toc-left" : ""%>">

<% if (navbarTocLeft) { %>
<div id="quarto-sidebar-toc-left" class="sidebar toc-left">
<div id="quarto-toc-target"></div>
</div>
<% } %>

<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
<% if (tocLocation === "right") { %>
<% if (navbarTocRight) { %>
<div id="quarto-toc-target"></div>
<% } %>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/resources/projects/website/templates/nav-before-body.ejs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<%
const navbarToolsClass = (nav.navbar && nav.navbar.right) ? 'quarto-navbar-tools' : 'quarto-navbar-tools ms-auto';
const navbarTocLeft = nav['toc-location'] === "left" || nav['toc-location'] === "left-body";
const navbarTocRight = nav['toc-location'] === "right" || nav['toc-location'] === "right-body";
%>


Expand Down Expand Up @@ -85,14 +87,14 @@ if (nav.layout === "article" || nav.layout === "full") {
<div id="quarto-content" class="quarto-container<%- gridClasses %> page-layout-<%- nav.layout %><%- nav.navbar ? ' page-navbar': ''%>">

<!-- sidebar -->
<% if (nav.sidebar || nav['toc-location'] === "left") { %>
<% partial('sidebar.ejs', { sidebar: nav.sidebar, sidebarStyle: nav.sidebarStyle, navbar: !!nav.navbar, toc: nav['toc-location'] === "left", language: nav.language }) %>
<% if (nav.sidebar || navbarTocLeft) { %>
<% partial('sidebar.ejs', { sidebar: nav.sidebar, sidebarStyle: nav.sidebarStyle, navbar: !!nav.navbar, toc: navbarTocLeft, language: nav.language }) %>
<% } %>

<!-- margin-sidebar -->
<% if (nav.layout === "article" || nav.layout === "full") { %>
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
<% if (nav.hasToc && nav['toc-location'] === "right") { %>
<% if (nav.hasToc && navbarTocRight) { %>
<div id="quarto-toc-target"></div>
<% } %>
</div>
Expand Down
15 changes: 11 additions & 4 deletions src/resources/schema/document-toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@

- name: toc-location
schema:
enum: ["body", "left", "right"]
enum: ["body", "left", "right", "left-body", "right-body"]
default: "right"
tags:
formats: [$html-doc]
allenmanning marked this conversation as resolved.
Show resolved Hide resolved
description: |
Location for table of contents (`body`, `left`, or `right` (default)).

description:
short: |
Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').
long: |
Location for table of contents (`body`, `left`, `right` (default), 'left-body', 'right-body').
`body` - Show the Table of Contents in the center body of the document.
`left` - Show the Table of Contents in left margin of the document.
`left` - Show the Table of Contents in right margin of the document.
`left-body` - Show two Tables of Contents in both the center body and the left margin of the document.
`right-body` - Show two Tables of Contents in both the center body and the right margin of the document.
- name: toc-title
schema: string
tags:
Expand Down
2 changes: 2 additions & 0 deletions tests/docs/smoke-all/issues/3473-toc-side-body/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.html
*_files/
66 changes: 66 additions & 0 deletions tests/docs/smoke-all/issues/3473-toc-side-body/body.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: 3473-toc-side-body
format:
html:
toc: true
toc-location: body
toc-title: Contents
toc-expand: 5
toc-depth: 4
_quarto:
tests:
html:
ensureHtmlElements:
-
- "nav#TOC"
-
- "nav#TOC.toc-active"
- "nav#TOC-body"
---

# Section 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

# Section 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

## Section 2.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

### Section 2.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

#### Section 2.1.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

##### Section 2.1.1.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.


# Section 3
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
64 changes: 64 additions & 0 deletions tests/docs/smoke-all/issues/3473-toc-side-body/left-body.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: 3473-toc-left-body
format:
html:
toc: true
toc-location: left-body
toc-title: Contents
toc-expand: 5
toc-depth: 4
_quarto:
tests:
html:
ensureHtmlElements:
-
- "nav#TOC.toc-active"
- "nav#TOC-body"
---

# Section 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

# Section 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

## Section 2.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

### Section 2.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

#### Section 2.1.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.

##### Section 2.1.1.1.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.


# Section 3
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam dapibus mattis malesuada. Sed fringilla posuere ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos.
Loading