Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/create/artifacts/document.ts
3587 views
1
/*
2
* document.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*
6
*/
7
8
import { ArtifactCreator, CreateContext } from "../cmd.ts";
9
import {
10
CreateDirective,
11
ejsData,
12
renderAndCopyArtifacts,
13
} from "./artifact-shared.ts";
14
15
import { Input } from "cliffy/prompt/mod.ts";
16
import { join } from "../../../deno_ral/path.ts";
17
18
import { safeExistsSync } from "../../../core/path.ts";
19
import { resourcePath } from "../../../core/resources.ts";
20
21
const kFormat = "format";
22
const kTitle = "title";
23
24
const kTypeDocument = "document";
25
26
export const documentArtifactCreator: ArtifactCreator = {
27
displayName: "Document",
28
type: kTypeDocument,
29
resolveOptions,
30
finalizeOptions,
31
nextPrompt,
32
createArtifact,
33
};
34
35
function resolveOptions(args: string[]): Record<string, unknown> {
36
// The first argument is the extension type
37
// The second argument is the name
38
const formatRaw = args.length > 0 ? args[0] : undefined;
39
const titleRaw = args.length > 1 ? args[1] : undefined;
40
41
const options: Record<string, unknown> = {};
42
43
// Populate the type data
44
if (formatRaw) {
45
options[kFormat] = formatRaw;
46
}
47
48
// Populate a directory, if provided
49
if (titleRaw) {
50
options[kTitle] = titleRaw;
51
}
52
53
return options;
54
}
55
56
function finalizeOptions(createOptions: CreateContext) {
57
// There should be a name
58
if (!createOptions.options.title) {
59
throw new Error("Required property 'title' is missing.");
60
}
61
62
// Form a template
63
const template = createOptions.options[kFormat];
64
65
// Provide a directory and title
66
return {
67
displayType: "document",
68
name: createOptions.options[kTitle],
69
directory: createOptions.cwd,
70
template,
71
options: createOptions.options,
72
} as CreateDirective;
73
}
74
75
function nextPrompt(
76
createOptions: CreateContext,
77
) {
78
// First ensure that there is a type
79
if (!createOptions.options[kFormat]) {
80
return {
81
name: kFormat,
82
message: "Format",
83
type: Input,
84
};
85
}
86
87
// Collect a title
88
if (!createOptions.options[kTitle]) {
89
return {
90
name: kTitle,
91
message: "Document Title",
92
type: Input,
93
};
94
}
95
}
96
97
async function createArtifact(
98
createDirective: CreateDirective,
99
quiet?: boolean,
100
) {
101
const fileName = await createDocument(createDirective, quiet);
102
103
return {
104
path: fileName,
105
openfiles: [fileName],
106
};
107
}
108
109
async function createDocument(
110
createDirective: CreateDirective,
111
quiet?: boolean,
112
) {
113
// The folder for this extension
114
const artifact = templateFolder(createDirective);
115
116
// The target directory
117
const target = createDirective.directory;
118
119
// Data for this extension
120
const data = await ejsData(createDirective);
121
if (createDirective.options[kFormat]) {
122
data[kFormat] = createDirective.options[kFormat] as string;
123
}
124
125
// Render or copy the artifact
126
const filesCreated = renderAndCopyArtifacts(
127
target,
128
artifact,
129
createDirective,
130
data,
131
quiet,
132
);
133
134
return filesCreated[0];
135
}
136
137
function templateFolder(createDirective: CreateDirective) {
138
const basePath = resourcePath(join("create", "documents"));
139
const formatSpecificPath = join(basePath, createDirective.template);
140
if (safeExistsSync(formatSpecificPath)) {
141
return formatSpecificPath;
142
} else {
143
return join(basePath, "default");
144
}
145
}
146
147