Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/project/project-crossrefs.ts
6446 views
1
/*
2
* project-crossrefs.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { ensureDirSync, existsSync } from "../deno_ral/fs.ts";
8
9
import { basename, isAbsolute, join, relative } from "../deno_ral/path.ts";
10
import {
11
kCrossref,
12
kCrossrefChapterId,
13
kCrossrefChaptersAlpha,
14
kCrossrefChaptersAppendix,
15
} from "../config/constants.ts";
16
import { Metadata } from "../config/types.ts";
17
import { pathWithForwardSlashes } from "../core/path.ts";
18
import { shortUuid } from "../core/uuid.ts";
19
20
import { projectScratchPath } from "./project-scratch.ts";
21
22
export const kCrossrefIndexFile = "crossref-index-file";
23
export const kCrossrefInputType = "crossref-input-type";
24
export const kCrossrefResolveRefs = "crossref-resolve-refs";
25
26
const kCrossrefIndexDir = "xref";
27
28
type CrossrefIndex = Record<string, Record<string, string>>;
29
30
export function crossrefIndexForOutputFile(
31
projectDir: string,
32
input: string,
33
output: string,
34
) {
35
// ensure we are dealing with a project relative path to the input
36
// that uses forward slashes
37
if (isAbsolute(input)) {
38
input = relative(projectDir, input);
39
}
40
input = pathWithForwardSlashes(input);
41
42
// read (or create) main index
43
const crossrefDir = projectScratchPath(projectDir, kCrossrefIndexDir);
44
ensureDirSync(crossrefDir);
45
const mainIndexFile = join(crossrefDir, "INDEX");
46
const mainIndex: CrossrefIndex = existsSync(mainIndexFile)
47
? JSON.parse(Deno.readTextFileSync(mainIndexFile))
48
: {};
49
50
// ensure this input/output has an index entry
51
// (generate and rewrite index file if not)
52
const outputBaseFile = basename(output);
53
if (mainIndex[input]?.[outputBaseFile] === undefined) {
54
if (mainIndex[input] === undefined) {
55
mainIndex[input] = {};
56
}
57
mainIndex[input][outputBaseFile] = shortUuid();
58
Deno.writeTextFileSync(
59
mainIndexFile,
60
JSON.stringify(mainIndex, undefined, 2),
61
);
62
}
63
64
// return the file path
65
return join(crossrefDir, mainIndex[input]?.[outputBaseFile]);
66
}
67
68
export function deleteCrossrefMetadata(metadata: Metadata) {
69
const crossref = metadata[kCrossref] as Metadata;
70
if (crossref) {
71
delete crossref[kCrossrefChaptersAppendix];
72
delete crossref[kCrossrefChaptersAlpha];
73
delete crossref[kCrossrefChapterId];
74
if (Object.keys(crossref).length === 0) {
75
delete metadata[kCrossref];
76
}
77
}
78
}
79
80