Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/render/defaults.ts
3584 views
1
/*
2
* defaults.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { extname } from "../../deno_ral/path.ts";
8
import { stringify } from "../../core/yaml.ts";
9
10
import * as ld from "../../core/lodash.ts";
11
12
import { FormatPandoc, QuartoFilter } from "../../config/types.ts";
13
import { isLatexOutput } from "../../config/format.ts";
14
15
import {
16
kEmbedResources,
17
kFilters,
18
kFrom,
19
kIncludeAfterBody,
20
kIncludeBeforeBody,
21
kIncludeInHeader,
22
kNumberDepth,
23
kOutputFile,
24
kQuartoFilters,
25
kSelfContained,
26
kStandalone,
27
kTemplate,
28
kTo,
29
} from "../../config/constants.ts";
30
31
import { kPatchedTemplateExt } from "./template.ts";
32
import { PandocOptions } from "./types.ts";
33
import { quartoMainFilter, resolveFilters } from "./filters.ts";
34
import { TempContext } from "../../core/temp.ts";
35
36
export async function generateDefaults(
37
options: PandocOptions,
38
): Promise<FormatPandoc | undefined> {
39
let allDefaults: FormatPandoc | undefined;
40
41
if (options.format.pandoc) {
42
allDefaults = {
43
...(options.format.pandoc || {}),
44
variables: {
45
...(options.format.pandoc?.variables || {}),
46
},
47
} as FormatPandoc;
48
49
// resolve filters
50
const resolvedFilters = await resolveFilters(
51
[
52
...(allDefaults[kFilters] || []),
53
],
54
options,
55
allDefaults,
56
);
57
if (resolvedFilters) {
58
allDefaults[kFilters] = resolvedFilters.quartoFilters;
59
// forward the filter spec with everything to pandoc via metadata
60
options.format.metadata[kQuartoFilters] = resolvedFilters;
61
}
62
63
// If we're rendering Latex, forward the number-depth to pandoc (it handles numbering)
64
if (isLatexOutput(options.format.pandoc)) {
65
if (options.format.metadata[kNumberDepth] !== undefined) {
66
allDefaults.variables = allDefaults.variables || {};
67
allDefaults.variables["secnumdepth"] =
68
options.format.metadata[kNumberDepth];
69
}
70
}
71
72
return allDefaults;
73
} else {
74
return undefined;
75
}
76
}
77
78
export async function writeDefaultsFile(
79
defaults: FormatPandoc,
80
temp: TempContext,
81
) {
82
const defaultsStr = "---\n" +
83
stringify(defaults as Record<string, unknown>, {
84
indent: 2,
85
lineWidth: -1,
86
sortKeys: false,
87
skipInvalid: true,
88
});
89
const defaultsFile = temp.createFile(
90
{ prefix: "quarto-defaults", suffix: ".yml" },
91
);
92
await Deno.writeTextFile(defaultsFile, defaultsStr);
93
return defaultsFile;
94
}
95
96
export function pandocDefaultsMessage(
97
pandoc: FormatPandoc,
98
sysFilters: string[],
99
debug?: boolean,
100
) {
101
const kDebugOnly = [
102
kIncludeInHeader,
103
kIncludeBeforeBody,
104
kIncludeAfterBody,
105
];
106
const kOrder = [
107
kTo,
108
kFrom,
109
kOutputFile,
110
kTemplate,
111
kStandalone,
112
kEmbedResources,
113
kSelfContained,
114
];
115
const defaults: FormatPandoc = {};
116
kOrder.forEach((key) => {
117
if (Object.keys(pandoc).includes(key)) {
118
// deno-lint-ignore no-explicit-any
119
(defaults as any)[key] = (pandoc as any)[key];
120
}
121
});
122
Object.keys(pandoc).forEach((key) => {
123
if (!kOrder.includes(key) && (debug || !kDebugOnly.includes(key))) {
124
// deno-lint-ignore no-explicit-any
125
(defaults as any)[key] = (pandoc as any)[key];
126
}
127
});
128
129
const filtersContains = (filters: QuartoFilter[], filter: QuartoFilter) => {
130
return filters.find((sysFilter) => {
131
const sysPath = typeof sysFilter === "string"
132
? sysFilter
133
: sysFilter.path;
134
const filterPath = typeof filter === "string" ? filter : filter.path;
135
return sysPath === filterPath;
136
});
137
};
138
139
// simplify crossref filter
140
if (defaults.filters?.length) {
141
defaults.filters = defaults.filters
142
.filter((filter) => {
143
return filter !== quartoMainFilter() &&
144
filtersContains(sysFilters, filter);
145
});
146
if (defaults.filters?.length === 0) {
147
delete defaults.filters;
148
}
149
}
150
151
// remove template if it's patched
152
if (defaults.template && extname(defaults.template) === kPatchedTemplateExt) {
153
delete defaults.template;
154
}
155
156
// TODO / HACK: suppress writer if it is coming from an extension
157
if (defaults.writer) {
158
if (
159
defaults.writer.match(/(?:^|[\\/])_extensions[\\/]/) ||
160
defaults.writer.match(/(?:^|[\\/])extensions[\\/]quarto[\\/]/)
161
) {
162
delete defaults.writer;
163
}
164
}
165
166
return stringify(defaults as Record<string, unknown>);
167
}
168
169