Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/format/jats/format-jats.ts
6471 views
1
/*
2
* format-jats.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import {
8
kDefaultImageExtension,
9
kIncludeAfterBody,
10
kLinkCitations,
11
kNotebookSubarticles,
12
kQuartoInternal,
13
kResources,
14
kVariant,
15
} from "../../config/constants.ts";
16
import { Format, Metadata, PandocFlags } from "../../config/types.ts";
17
import { ProjectContext } from "../../project/types.ts";
18
import { createFormat } from "../formats-shared.ts";
19
20
import { formatResourcePath } from "../../core/resources.ts";
21
import { RenderServices } from "../../command/render/types.ts";
22
import {
23
jatsDtd,
24
JatsRenderSubArticle,
25
jatsTagset,
26
kJatsSubarticle,
27
kLintXml,
28
kSubArticles,
29
xmlPlaceholder,
30
} from "./format-jats-types.ts";
31
32
import { join } from "../../deno_ral/path.ts";
33
import { warning } from "../../deno_ral/log.ts";
34
import {
35
reformatXmlPostProcessor,
36
renderSubarticlePostProcessor,
37
} from "./format-jats-postprocess.ts";
38
39
const kJatsExtended = "jats-extended";
40
const kJatsDtd = "jats-dtd";
41
const kElementsVariant = "+element_citations";
42
43
export function jatsFormat(displayName: string, ext: string): Format {
44
return createFormat(displayName, ext, {
45
pandoc: {
46
standalone: true,
47
[kDefaultImageExtension]: "png",
48
},
49
render: {
50
[kVariant]: kElementsVariant,
51
},
52
formatExtras: (
53
input: string,
54
_markdown: string,
55
_flags: PandocFlags,
56
format: Format,
57
_libDir: string,
58
services: RenderServices,
59
_offset: string | undefined,
60
project: ProjectContext,
61
quiet?: boolean,
62
) => {
63
// Provide a template and partials
64
const templateDir = formatResourcePath("jats", "pandoc");
65
const partials = [
66
"front.xml",
67
"authors.xml",
68
"institution.xml",
69
"affiliation.xml",
70
"name.xml",
71
];
72
const templateContext = {
73
template: join(templateDir, "template.xml"),
74
partials: partials.map((partial) => join(templateDir, partial)),
75
};
76
77
// Which tagset we're using
78
const tagset = jatsTagset(format.identifier["base-format"] || "jats");
79
80
const metadataOverride = {
81
// Link citations produces `xrefs` for the citations to the references in the bibliography so
82
// must be enabled
83
[kLinkCitations]: true,
84
};
85
// If this has been explicitly disabled, warn the user that the setting is being ignored
86
if (format.metadata[kLinkCitations] === false) {
87
warning(
88
"JATS formats require that `link-citations` is enabled to emit well formed JATS. Explicitly set value is being ignored.",
89
);
90
}
91
92
// Gather post process that we need
93
const postprocessors = [];
94
95
const internalMetadata = format.metadata[kQuartoInternal] as
96
| Metadata
97
| undefined;
98
99
// Share resources with external
100
const afterBody: string[] = [];
101
const subArticleResources: string[] = [];
102
if (internalMetadata && !format.metadata[kJatsSubarticle]) {
103
const subArticles = (internalMetadata[
104
kSubArticles
105
]) as Array<JatsRenderSubArticle> | undefined;
106
107
if (subArticles && format.render[kNotebookSubarticles] !== false) {
108
const placeholderFile = services.temp.createFile({
109
suffix: ".placeholder.xml",
110
});
111
const placeholders: string[] = [];
112
subArticles.forEach((subArticle) => {
113
// Inject a placeholder
114
const placeholder = xmlPlaceholder(
115
subArticle.token,
116
subArticle.input,
117
);
118
placeholders.push(placeholder);
119
});
120
Deno.writeTextFileSync(placeholderFile, placeholders.join("\n"));
121
afterBody.push(placeholderFile);
122
123
// Render subarticles and place them in the root article in the correct position
124
if (subArticles.length > 0 && !format.metadata[kJatsSubarticle]) {
125
postprocessors.push(
126
renderSubarticlePostProcessor(
127
input,
128
format,
129
subArticles,
130
services,
131
project,
132
quiet,
133
),
134
);
135
}
136
}
137
}
138
139
// Lint the XML
140
if (format.metadata[kLintXml] !== false) {
141
postprocessors.push(reformatXmlPostProcessor);
142
}
143
144
return {
145
[kIncludeAfterBody]: afterBody,
146
metadata: {
147
[kQuartoInternal]: {
148
// These signal the template with flags controlling the tagset to be output
149
[kJatsExtended]: tagset === "archiving" || tagset === "publishing",
150
[kJatsDtd]: jatsDtd(tagset),
151
},
152
[kResources]: subArticleResources,
153
},
154
templateContext,
155
metadataOverride,
156
postprocessors,
157
};
158
},
159
});
160
}
161
162