Skip to content

Commit 1d00926

Browse files
committed
Add notebook-links
1 parent f28bdd4 commit 1d00926

File tree

5 files changed

+95
-58
lines changed

5 files changed

+95
-58
lines changed

src/config/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const kResources = "resources";
3939
export const kFormatResources = "format-resources";
4040

4141
export const kFormatLinks = "format-links";
42+
export const kNotebookLinks = "notebook-links";
4243

4344
export const kKeepHidden = "keep-hidden";
4445

@@ -166,6 +167,7 @@ export const kRenderDefaultsKeys = [
166167
kLinkExternalFilter,
167168
kFormatResources,
168169
kFormatLinks,
170+
kNotebookLinks,
169171
];
170172

171173
// language fields

src/config/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ import {
128128
kMathml,
129129
kMergeIncludes,
130130
kMermaidFormat,
131+
kNotebookLinks,
131132
kNumberOffset,
132133
kNumberSections,
133134
kOutput,
@@ -396,6 +397,7 @@ export interface FormatRender {
396397
[kSelfContainedMath]?: boolean;
397398
[kFormatResources]?: string[];
398399
[kFormatLinks]?: boolean | string[];
400+
[kNotebookLinks]?: boolean | "inline" | "global";
399401
}
400402

401403
export interface FormatExecute {

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

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
kHtmlMathMethod,
2020
kIncludeInHeader,
2121
kLinkCitations,
22+
kNotebookLinks,
2223
kQuartoTemplateParams,
2324
kRelatedFormatsTitle,
2425
kRelatedNotebooksTitle,
@@ -327,7 +328,9 @@ function bootstrapHtmlPostprocessor(
327328
}
328329

329330
// Look for included / embedded notebooks and include those
330-
processNotebookEmbeds(doc, format, resources);
331+
if (format.render[kNotebookLinks] !== false) {
332+
processNotebookEmbeds(doc, format, resources);
333+
}
331334

332335
// default treatment for computational tables
333336
const addTableClasses = (table: Element, computational = false) => {
@@ -540,6 +543,11 @@ function processNotebookEmbeds(
540543
format: Format,
541544
resources: string[],
542545
) {
546+
const inline = format.render[kNotebookLinks] === "inline" ||
547+
format.render[kNotebookLinks] === true;
548+
const global = format.render[kNotebookLinks] === "global" ||
549+
format.render[kNotebookLinks] === true;
550+
543551
const notebookDivNodes = doc.querySelectorAll("[data-notebook]");
544552
if (notebookDivNodes.length > 0) {
545553
const nbPaths: { path: string; title: string; filename: string }[] = [];
@@ -560,75 +568,79 @@ function processNotebookEmbeds(
560568
nbPaths.push(nbPath);
561569

562570
// Add a decoration to this div node
563-
const id = "nblink-" + count++;
564-
565-
const nbLinkEl = doc.createElement("a");
566-
nbLinkEl.classList.add("quarto-notebook-link");
567-
nbLinkEl.setAttribute("id", `${id}`);
568-
nbLinkEl.setAttribute("href", nbPath.path);
569-
nbLinkEl.setAttribute("download", nbPath.filename);
570-
nbLinkEl.appendChild(
571-
doc.createTextNode(
572-
`${format.language[kSourceNotebookPrefix]}: ${nbPath.title}`,
573-
),
574-
);
571+
if (inline) {
572+
const id = "nblink-" + count++;
573+
574+
const nbLinkEl = doc.createElement("a");
575+
nbLinkEl.classList.add("quarto-notebook-link");
576+
nbLinkEl.setAttribute("id", `${id}`);
577+
nbLinkEl.setAttribute("href", nbPath.path);
578+
nbLinkEl.setAttribute("download", nbPath.filename);
579+
nbLinkEl.appendChild(
580+
doc.createTextNode(
581+
`${format.language[kSourceNotebookPrefix]}: ${nbPath.title}`,
582+
),
583+
);
575584

576-
// If there is a figure caption, place the source after that
577-
// otherwise just place it at the bottom of the notebook div
578-
const nbParentEl = nbDivEl.parentElement;
579-
if (nbParentEl?.tagName.toLocaleLowerCase() === "figure") {
580-
const figCapEl = nbDivEl.parentElement?.querySelector("figcaption");
581-
if (figCapEl) {
582-
figCapEl.after(nbLinkEl);
585+
// If there is a figure caption, place the source after that
586+
// otherwise just place it at the bottom of the notebook div
587+
const nbParentEl = nbDivEl.parentElement;
588+
if (nbParentEl?.tagName.toLocaleLowerCase() === "figure") {
589+
const figCapEl = nbDivEl.parentElement?.querySelector("figcaption");
590+
if (figCapEl) {
591+
figCapEl.after(nbLinkEl);
592+
} else {
593+
nbDivEl.appendChild(nbLinkEl);
594+
}
583595
} else {
584596
nbDivEl.appendChild(nbLinkEl);
585597
}
586-
} else {
587-
nbDivEl.appendChild(nbLinkEl);
588598
}
589599
}
590600
});
591601

592-
const containerEl = doc.createElement("div");
593-
containerEl.classList.add("quarto-alternate-notebooks");
602+
if (global) {
603+
const containerEl = doc.createElement("div");
604+
containerEl.classList.add("quarto-alternate-notebooks");
594605

595-
const heading = doc.createElement("h2");
596-
if (format.language[kRelatedNotebooksTitle]) {
597-
heading.innerText = format.language[kRelatedNotebooksTitle];
598-
}
599-
containerEl.appendChild(heading);
600-
601-
const formatList = doc.createElement("ul");
602-
containerEl.appendChild(formatList);
603-
ld.uniqBy(nbPaths, (nbPath: { path: string; title?: string }) => {
604-
return nbPath.path;
605-
}).forEach((nbPath) => {
606-
const li = doc.createElement("li");
607-
608-
const link = doc.createElement("a");
609-
link.setAttribute("href", nbPath.path);
610-
link.setAttribute("download", nbPath.filename);
611-
612-
const icon = doc.createElement("i");
613-
icon.classList.add("bi");
614-
icon.classList.add(`bi-journal-code`);
615-
link.appendChild(icon);
616-
link.appendChild(
617-
doc.createTextNode(nbPath.title),
618-
);
606+
const heading = doc.createElement("h2");
607+
if (format.language[kRelatedNotebooksTitle]) {
608+
heading.innerText = format.language[kRelatedNotebooksTitle];
609+
}
610+
containerEl.appendChild(heading);
619611

620-
li.appendChild(link);
621-
formatList.appendChild(li);
612+
const formatList = doc.createElement("ul");
613+
containerEl.appendChild(formatList);
614+
ld.uniqBy(nbPaths, (nbPath: { path: string; title?: string }) => {
615+
return nbPath.path;
616+
}).forEach((nbPath) => {
617+
const li = doc.createElement("li");
618+
619+
const link = doc.createElement("a");
620+
link.setAttribute("href", nbPath.path);
621+
link.setAttribute("download", nbPath.filename);
622+
623+
const icon = doc.createElement("i");
624+
icon.classList.add("bi");
625+
icon.classList.add(`bi-journal-code`);
626+
link.appendChild(icon);
627+
link.appendChild(
628+
doc.createTextNode(nbPath.title),
629+
);
622630

623-
resources.push(nbPath.path);
624-
});
625-
let dlLinkTarget = doc.querySelector(`nav[role="doc-toc"]`);
626-
if (dlLinkTarget === null) {
627-
dlLinkTarget = doc.querySelector("#quarto-margin-sidebar");
628-
}
631+
li.appendChild(link);
632+
formatList.appendChild(li);
629633

630-
if (dlLinkTarget) {
631-
dlLinkTarget.appendChild(containerEl);
634+
resources.push(nbPath.path);
635+
});
636+
let dlLinkTarget = doc.querySelector(`nav[role="doc-toc"]`);
637+
if (dlLinkTarget === null) {
638+
dlLinkTarget = doc.querySelector("#quarto-margin-sidebar");
639+
}
640+
641+
if (dlLinkTarget) {
642+
dlLinkTarget.appendChild(containerEl);
643+
}
632644
}
633645
}
634646
}

src/format/html/format-html.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ import {
2020
kCodeLink,
2121
kFigResponsive,
2222
kFilterParams,
23+
kFormatLinks,
2324
kHeaderIncludes,
2425
kIncludeAfterBody,
2526
kIncludeInHeader,
2627
kLinkExternalFilter,
2728
kLinkExternalIcon,
2829
kLinkExternalNewwindow,
30+
kNotebookLinks,
2931
kTheme,
3032
} from "../../config/constants.ts";
3133

@@ -94,6 +96,10 @@ export function htmlFormat(
9496
return mergeConfigs(
9597
createHtmlFormat("HTML", figwidth, figheight),
9698
{
99+
render: {
100+
[kNotebookLinks]: true,
101+
[kFormatLinks]: true,
102+
},
97103
resolveFormat: (format: Format) => {
98104
if (format.metadata[kMinimal] === true) {
99105
if (format.metadata[kFigResponsive] === undefined) {

src/resources/schema/document-links.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,18 @@
3939
4040
Pass `false` to disable the display of format lengths or pass a list of format names for which you'd
4141
like links to be shown.
42+
43+
- name: notebook-links
44+
tags:
45+
formats: [$html-doc]
46+
schema:
47+
anyOf:
48+
- boolean
49+
- enum: [inline, global]
50+
description:
51+
short: "Controls the display of links to notebooks that provided embedded content or are created from documents."
52+
long: |
53+
Controls the display of links to notebooks that provided embedded content or are created from documents.
54+
55+
Specify `false` to disable linking to source Notebooks. Specify `inline` to show links to source notebooks beneath the content they provide.
56+
Specify `global` to show a set of global links to source notebooks.

0 commit comments

Comments
 (0)