Skip to content

Commit 41501dd

Browse files
committed
Project Types can tinker with output files
This allows manuscript projects to provide a more nuanced output file for its notebooks.
1 parent d2d46fb commit 41501dd

File tree

5 files changed

+36
-20
lines changed

5 files changed

+36
-20
lines changed

src/project/project-index.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
* Copyright (C) 2020-2022 Posit Software, PBC
55
*/
66

7-
import { dirname, isAbsolute, join, relative } from "path/mod.ts";
7+
import { basename, dirname, isAbsolute, join, relative } from "path/mod.ts";
88
import { existsSync } from "fs/mod.ts";
99

1010
import * as ld from "../core/lodash.ts";
1111

12-
import { ProjectContext } from "./types.ts";
12+
import { kProjectType, ProjectContext } from "./types.ts";
1313
import { Metadata } from "../config/types.ts";
1414
import { Format } from "../config/types.ts";
1515
import { PartitionedMarkdown } from "../core/pandoc/types.ts";
@@ -34,6 +34,7 @@ import {
3434
} from "./types/website/website-config.ts";
3535
import { kDefaultProjectFileContents } from "./types/project-default.ts";
3636
import { formatOutputFile } from "../core/render.ts";
37+
import { projectType } from "./types/project-types.ts";
3738

3839
export interface InputTargetIndex extends Metadata {
3940
title?: string;
@@ -247,8 +248,16 @@ export async function resolveInputTarget(
247248
if (index) {
248249
const formats = formatsPreferHtml(index.formats) as Record<string, Format>;
249250
const format = Object.values(formats)[0];
251+
252+
// lookup the project type
253+
const projType = projectType(project.config?.project?.[kProjectType]);
254+
const projOutputFile = projType.outputFile
255+
? projType.outputFile(href, format, project)
256+
: undefined;
257+
250258
const [hrefDir, hrefStem] = dirAndStem(href);
251-
const outputFile = formatOutputFile(format) || `${hrefStem}.html`;
259+
const outputFile = projOutputFile || formatOutputFile(format) ||
260+
`${hrefStem}.html`;
252261
const outputHref = pathWithForwardSlashes(
253262
(absolute ? "/" : "") + join(hrefDir, outputFile),
254263
);

src/project/types/manuscript/manuscript-render.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ export const manuscriptRenderer = (
164164
onFilterContexts: (
165165
file: string,
166166
contexts: Record<string, RenderContext>,
167-
files: RenderFile[],
168-
options: RenderOptions,
167+
_files: RenderFile[],
168+
_options: RenderOptions,
169169
) => {
170170
const isValidNotebookOutput = (to: string) => {
171171
return [isJatsOutput, (format: string) => {
@@ -175,19 +175,6 @@ export const manuscriptRenderer = (
175175
});
176176
};
177177

178-
// if the render file list doesn't contain any article, and there is a custom too
179-
// (so this is an attemp to render only manuscript notebooks), throw error
180-
if (
181-
options.flags?.to && !isValidNotebookOutput(options.flags.to) &&
182-
!files.find((renderFile) => {
183-
return isArticle(renderFile.path, context, manuscriptConfig);
184-
})
185-
) {
186-
throw new Error(
187-
"Notebooks within manuscript projects can only be rendered as a part of rendering the article or as an HTML or JATS preview.",
188-
);
189-
}
190-
191178
// Articles can be any format, notebooks can only be HTML or JATS
192179
if (isNotebook(file)) {
193180
const outContexts: Record<string, RenderContext> = {};

src/project/types/manuscript/manuscript.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import { logProgress } from "../../../core/log.ts";
7878
import { formatLanguage } from "../../../core/language.ts";
7979
import { manuscriptRenderer } from "./manuscript-render.ts";
8080
import { isRStudioPreview } from "../../../core/platform.ts";
81+
import { outputFile } from "../../../render/notebook/notebook-contributor-html.ts";
8182

8283
const kMecaIcon = "archive";
8384
const kOutputDir = "_manuscript";
@@ -258,6 +259,20 @@ export const manuscriptProjectType: ProjectType = {
258259
},
259260
pandocRenderer: manuscriptRenderer,
260261
outputDir: kOutputDir,
262+
outputFile: (input: string, format: Format, project: ProjectContext) => {
263+
const manuscriptConfig = project.config
264+
?.[kManuscriptType] as ResolvedManuscriptConfig;
265+
266+
// Enable this stuff only if this is not the notebook view of an article
267+
if (
268+
!isArticleManuscript(input, format, project, manuscriptConfig) &&
269+
isHtmlOutput(format.pandoc)
270+
) {
271+
return outputFile(input);
272+
} else {
273+
return undefined;
274+
}
275+
},
261276
cleanOutputDir: true,
262277
incrementalFormatPreviewing: true,
263278
filterParams: async (options: PandocOptions) => {
@@ -452,7 +467,7 @@ export const manuscriptProjectType: ProjectType = {
452467

453468
return Promise.resolve(extras);
454469
},
455-
previewSkipUnmodified: false,
470+
previewSkipUnmodified: true,
456471
renderResultFinalOutput: (
457472
renderResults: RenderResult,
458473
) => {

src/project/types/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ export interface ProjectType {
3131
) => Promise<ProjectConfig>;
3232
libDir?: string;
3333
outputDir?: string;
34+
outputFile?: (
35+
input: string,
36+
format: Format,
37+
project: ProjectContext,
38+
) => string | undefined;
3439
filterOutputFile?: (file: string) => string;
3540
cleanOutputDir?: boolean;
3641
formatLibDirs?: () => string[];

src/render/notebook/notebook-contributor-html.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const htmlNotebookContributor: NotebookContributor = {
4949
outputFile,
5050
};
5151

52-
function outputFile(
52+
export function outputFile(
5353
nbAbsPath: string,
5454
): string {
5555
return `${basename(nbAbsPath)}.html`;

0 commit comments

Comments
 (0)