Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/render/crossref.ts
3584 views
1
/*
2
* crossref.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import {
8
kListings,
9
kNumberDepth,
10
kNumberOffset,
11
kNumberSections,
12
} from "../../config/constants.ts";
13
import { FormatPandoc } from "../../config/types.ts";
14
import { PandocFlags } from "../../config/types.ts";
15
import { Metadata } from "../../config/types.ts";
16
17
import { PandocOptions } from "./types.ts";
18
import {
19
crossrefIndexForOutputFile,
20
kCrossrefIndexFile,
21
kCrossrefInputType,
22
} from "../../project/project-crossrefs.ts";
23
import { pandocMetadataPath } from "./render-paths.ts";
24
import { isMultiFileBookFormat } from "../../project/types/book/book-shared.ts";
25
import { projectIsBook } from "../../project/project-shared.ts";
26
27
export function crossrefFilterActive(options: PandocOptions) {
28
return options.format.metadata.crossref !== false;
29
}
30
31
export function crossrefFilterParams(
32
options: PandocOptions,
33
defaults?: FormatPandoc,
34
) {
35
const flags = options.flags;
36
const metadata = options.format.metadata;
37
const kCrossrefFilterParams = [kListings, kNumberSections, kNumberOffset];
38
const params: Metadata = {};
39
kCrossrefFilterParams.forEach((option) => {
40
let value = crossrefOption(option, flags, defaults);
41
if (value) {
42
// validation
43
if (option === kNumberOffset) {
44
// coerce scalar number-offset to array
45
if (typeof value === "number") {
46
value = [value];
47
}
48
// validate we have an array
49
if (
50
!Array.isArray(value) || value.some((num) => !Number.isInteger(num))
51
) {
52
throw new Error(
53
"Invalid value for number-offset (should be an array of numbers)",
54
);
55
}
56
// implies number-sections
57
if (defaults?.[kNumberSections] === undefined) {
58
params[kNumberSections] = true;
59
}
60
}
61
params[option] = value;
62
}
63
});
64
65
// Read the number depth
66
params[kNumberDepth] = metadata?.[kNumberDepth];
67
68
// always create crossref index for projects
69
if (!options.project?.isSingleFile) {
70
// if its a book then only write for multi-file (as otherwise all of the
71
// crossref entries will end in a single index file)
72
if (
73
!projectIsBook(options.project) || isMultiFileBookFormat(options.format)
74
) {
75
params[kCrossrefIndexFile] = pandocMetadataPath(
76
crossrefIndexForOutputFile(
77
options.project!.dir,
78
options.source,
79
options.output,
80
),
81
);
82
}
83
84
// caller may have requested that a crossref index be written
85
} else {
86
const crossrefIndex = Deno.env.get("QUARTO_CROSSREF_INDEX_PATH");
87
if (crossrefIndex) {
88
params[kCrossrefIndexFile] = pandocMetadataPath(crossrefIndex);
89
}
90
}
91
92
// caller may have requested a special input type
93
const crossrefInputType = Deno.env.get("QUARTO_CROSSREF_INPUT_TYPE");
94
if (crossrefInputType) {
95
params[kCrossrefInputType] = crossrefInputType;
96
}
97
98
return params;
99
}
100
101
function crossrefOption(
102
name: string,
103
flags?: PandocFlags,
104
defaults?: FormatPandoc,
105
) {
106
if (flags && Object.keys(flags).includes(name)) {
107
// deno-lint-ignore no-explicit-any
108
return (flags as any)[name];
109
} else if (Object.keys(defaults || {}).includes(name)) {
110
// deno-lint-ignore no-explicit-any
111
return (defaults as any)[name];
112
} else {
113
return undefined;
114
}
115
}
116
117