Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package/scripts/common/quarto
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ QUARTO_DENO_OPTIONS="--unstable-ffi --unstable-kv --no-config --no-lock ${QUARTO

# --enable-experimental-regexp-engine is required for /regex/l, https://github.com/quarto-dev/quarto-cli/issues/9737
if [ "$QUARTO_DENO_V8_OPTIONS" != "" ]; then
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192,${QUARTO_DENO_V8_OPTIONS}"
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192,--stack-trace-limit=100,${QUARTO_DENO_V8_OPTIONS}"
else
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192"
QUARTO_DENO_V8_OPTIONS="--enable-experimental-regexp-engine,--max-old-space-size=8192,--max-heap-size=8192,--stack-trace-limit=100"
fi

if [ "$QUARTO_DENO_EXTRA_OPTIONS" == "" ]; then
Expand Down
3 changes: 2 additions & 1 deletion src/command/preview/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export const previewCommand = new Command()
services.cleanup();
}
})();
const format = await previewFormat(file, flags.to, formats, project);
const format = await previewFormat(file, project, flags.to, formats);

// see if this is server: shiny document and if it is then forward to previewShiny
if (isHtmlOutput(parseFormatString(format).baseFormat)) {
Expand All @@ -314,6 +314,7 @@ export const previewCommand = new Command()
format,
pandocArgs: args,
watchInputs: options.watchInputs!,
project,
});
exitWithCleanup(result.code);
throw new Error(); // unreachable
Expand Down
6 changes: 2 additions & 4 deletions src/command/preview/preview-shiny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,16 @@ import {
} from "../../core/http.ts";
import { findOpenPort } from "../../core/port.ts";
import { handleHttpRequests } from "../../core/http-server.ts";
import { kLocalhost } from "../../core/port-consts.ts";
import { normalizePath } from "../../core/path.ts";
import { previewMonitorResources } from "../../core/quarto.ts";
import { renderServices } from "../render/render-services.ts";
import { RenderFlags } from "../render/types.ts";
import { notebookContext } from "../../render/notebook/notebook-context.ts";
import { isIpynbOutput } from "../../config/format.ts";

export interface PreviewShinyOptions extends RunOptions {
pandocArgs: string[];
watchInputs: boolean;
project?: ProjectContext;
project: ProjectContext;
}

export async function previewShiny(options: PreviewShinyOptions) {
Expand Down Expand Up @@ -128,8 +126,8 @@ function runPreviewControlService(
return normalizePath(options.input) === normalizePath(prevReq.path) &&
await previewRenderRequestIsCompatible(
prevReq,
options.format,
options.project,
options.format,
);
};

Expand Down
37 changes: 23 additions & 14 deletions src/command/preview/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import {
import { isJupyterNotebook } from "../../core/jupyter/jupyter.ts";
import { watchForFileChanges } from "../../core/watch.ts";
import { previewMonitorResources } from "../../core/quarto.ts";
import { exitWithCleanup } from "../../core/cleanup.ts";
import { exitWithCleanup, onCleanup } from "../../core/cleanup.ts";
import {
extensionFilesFromDirs,
inputExtensionDirs,
Expand Down Expand Up @@ -151,11 +151,15 @@ export async function preview(
) {
const nbContext = notebookContext();
// see if this is project file
const project = await projectContext(file, nbContext);
const project = (await projectContext(file, nbContext)) ||
(await singleFileProjectContext(file, nbContext));
onCleanup(() => {
project.cleanup();
});

// determine the target format if there isn't one in the command line args
// (current we force the use of an html or pdf based format)
const format = await previewFormat(file, flags.to, undefined, project);
const format = await previewFormat(file, project, flags.to, undefined);
setPreviewFormat(format, flags, pandocArgs);

// render for preview (create function we can pass to watcher then call it)
Expand Down Expand Up @@ -224,6 +228,7 @@ export async function preview(
options.port!,
reloader,
changeHandler.render,
project,
)
: project
? projectHtmlFileRequestHandler(
Expand All @@ -241,6 +246,7 @@ export async function preview(
result.format,
reloader,
changeHandler.render,
project,
);

// open browser if this is a browseable format
Expand Down Expand Up @@ -340,17 +346,17 @@ export function previewRenderRequest(

export async function previewRenderRequestIsCompatible(
request: PreviewRenderRequest,
project: ProjectContext,
format?: string,
project?: ProjectContext,
) {
if (request.version === 1) {
return true; // rstudio manages its own request compatibility state
} else {
const reqFormat = await previewFormat(
request.path,
project,
request.format,
undefined,
project,
);
return reqFormat === format;
}
Expand All @@ -359,20 +365,20 @@ export async function previewRenderRequestIsCompatible(
// determine the format to preview
export async function previewFormat(
file: string,
project: ProjectContext,
format?: string,
formats?: Record<string, Format>,
project?: ProjectContext,
) {
if (format) {
return format;
}
const nbContext = notebookContext();
project = project || (await singleFileProjectContext(file, nbContext));
// const nbContext = notebookContext();
// project = project || (await singleFileProjectContext(file, nbContext));
formats = formats ||
await withRenderServices(
nbContext,
project.notebookContext,
(services: RenderServices) =>
renderFormats(file, services, "all", project!),
renderFormats(file, services, "all", project),
);
format = Object.keys(formats)[0] || "html";
return format;
Expand Down Expand Up @@ -418,15 +424,14 @@ export async function renderForPreview(
pandocArgs: string[],
project?: ProjectContext,
): Promise<RenderForPreviewResult> {

// render
const renderResult = await render(file, {
services,
flags,
pandocArgs: pandocArgs,
previewServer: true,
setProjectDir: project !== undefined,
});
}, project);
if (renderResult.error) {
throw renderResult.error;
}
Expand Down Expand Up @@ -689,6 +694,7 @@ function htmlFileRequestHandler(
format: Format,
reloader: HttpDevServer,
renderHandler: (to?: string) => Promise<RenderForPreviewResult | undefined>,
context: ProjectContext,
) {
return httpFileRequestHandler(
htmlFileRequestHandlerOptions(
Expand All @@ -699,6 +705,7 @@ function htmlFileRequestHandler(
format,
reloader,
renderHandler,
context,
),
);
}
Expand All @@ -711,7 +718,7 @@ function htmlFileRequestHandlerOptions(
format: Format,
devserver: HttpDevServer,
renderHandler: (to?: string) => Promise<RenderForPreviewResult | undefined>,
project?: ProjectContext,
project: ProjectContext,
): HttpFileRequestOptions {
// if we an alternate format on the fly we need to do a full re-render
// to get the correct state back. this flag will be set whenever
Expand Down Expand Up @@ -742,7 +749,7 @@ function htmlFileRequestHandlerOptions(
prevReq &&
existsSync(prevReq.path) &&
normalizePath(prevReq.path) === normalizePath(inputFile) &&
await previewRenderRequestIsCompatible(prevReq, flags.to)
await previewRenderRequestIsCompatible(prevReq, project, flags.to)
) {
// don't wait for the promise so the
// caller gets an immediate reply
Expand Down Expand Up @@ -853,6 +860,7 @@ function pdfFileRequestHandler(
port: number,
reloader: HttpDevServer,
renderHandler: () => Promise<RenderForPreviewResult | undefined>,
project: ProjectContext,
) {
// start w/ the html handler (as we still need it's http reload injection)
const pdfOptions = htmlFileRequestHandlerOptions(
Expand All @@ -863,6 +871,7 @@ function pdfFileRequestHandler(
format,
reloader,
renderHandler,
project,
);

// pdf customizations
Expand Down
24 changes: 16 additions & 8 deletions src/command/render/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import { quartoConfig } from "../../core/quarto.ts";
import { metadataNormalizationFilterActive } from "./normalize.ts";
import { kCodeAnnotations } from "../../format/html/format-html-shared.ts";
import { projectOutputDir } from "../../project/project-shared.ts";
import { relative } from "../../deno_ral/path.ts";
import { basename, relative } from "../../deno_ral/path.ts";
import { citeIndexFilterParams } from "../../project/project-cites.ts";
import { debug } from "../../deno_ral/log.ts";
import { kJatsSubarticle } from "../../format/jats/format-jats-types.ts";
Expand Down Expand Up @@ -660,7 +660,11 @@ async function quartoFilterParams(
params[kHasResourcePath] = hasResourcePath;

// The source document
params[kQuartoSource] = options.source;
if (options.project.isSingleFile) {
params[kQuartoSource] = basename(options.source);
} else {
params[kQuartoSource] = options.source;
}

// profile as an array
params[kQuartoProfile.toLowerCase()] = activeProfiles();
Expand Down Expand Up @@ -860,7 +864,7 @@ async function resolveFilterExtension(
}

let pathToResolve: string | null = null;

if (typeof filter === "string") {
pathToResolve = filter;
} else if (typeof filter === "object" && filter.path) {
Expand All @@ -869,7 +873,9 @@ async function resolveFilterExtension(

if (pathToResolve) {
// The filter string points to an executable file which exists
if (existsSync(pathToResolve) && !Deno.statSync(pathToResolve).isDirectory) {
if (
existsSync(pathToResolve) && !Deno.statSync(pathToResolve).isDirectory
) {
return filter;
}

Expand All @@ -896,17 +902,19 @@ async function resolveFilterExtension(
if (typeof filter === "string") {
return extensionFilters;
} else if (isFilterEntryPoint(filter)) {
return extensionFilters.map(extFilter => {
return extensionFilters.map((extFilter) => {
if (typeof extFilter === "string") {
return {
type: extFilter.endsWith(".lua") ? "lua" : "json" as "lua" | "json",
type: extFilter.endsWith(".lua")
? "lua"
: "json" as "lua" | "json",
path: extFilter,
at: filter.at
at: filter.at,
};
} else {
return {
...extFilter,
at: filter.at
at: filter.at,
};
}
});
Expand Down
14 changes: 7 additions & 7 deletions src/command/render/render-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,23 @@ import { kTextPlain } from "../../core/mime.ts";
import { normalizePath } from "../../core/path.ts";
import { notebookContext } from "../../render/notebook/notebook-context.ts";
import { singleFileProjectContext } from "../../project/types/single-file/single-file.ts";
import { assert } from "testing/asserts";
import { ProjectContext } from "../../project/types.ts";

export async function render(
path: string,
options: RenderOptions,
pContext?: ProjectContext,
): Promise<RenderResult> {
// one time initialization of yaml validators
setInitializer(initYamlIntelligenceResourcesFromFilesystem);
await initState();

const nbContext = notebookContext();
const nbContext = pContext?.notebookContext || notebookContext();

// determine target context/files
let context = await projectContext(path, nbContext, options);
// let context = await projectContext(path, nbContext, options);
let context = pContext || (await projectContext(path, nbContext, options)) ||
(await singleFileProjectContext(path, nbContext, options));

// Create a synthetic project when --output-dir is used without a project file
// This creates a temporary .quarto directory to manage the render, which must
Expand All @@ -61,6 +64,7 @@ export async function render(

// set env var if requested
if (context && options.setProjectDir) {
// FIXME we can't set environment variables like this with asyncs flying around
Deno.env.set("QUARTO_PROJECT_DIR", context.dir);
}

Expand Down Expand Up @@ -98,10 +102,6 @@ export async function render(
// validate that we didn't get any project-only options
validateDocumentRenderFlags(options.flags);

assert(!context, "Expected no context here");
// NB: singleFileProjectContext is currently not fully-featured
context = await singleFileProjectContext(path, nbContext, options);

// otherwise it's just a file render
const result = await renderFiles(
[{ path }],
Expand Down
2 changes: 1 addition & 1 deletion src/command/serve/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const serveCommand = new Command()
(services: RenderServices) =>
renderFormats(input, services, undefined, context),
);
const format = await previewFormat(input, undefined, formats, context);
const format = await previewFormat(input, context, undefined, formats);

const result = await serve({
input,
Expand Down
18 changes: 17 additions & 1 deletion src/execute/jupyter/jupyter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,23 @@ title: "Title"
// of additional changes to our file handling code (without changes,
// our output files would be called $FILE.quarto.html, which
// is not what we want). So for now, we'll use .quarto_ipynb
const notebook = join(fileDir, fileStem + ".quarto_ipynb");
let counter: number | undefined = undefined;
let notebook = join(
fileDir,
`${fileStem}.quarto_ipynb${counter ? "_" + String(counter) : ""}`,
);

while (existsSync(notebook)) {
if (!counter) {
counter = 1;
} else {
++counter;
}
notebook = join(
fileDir,
`${fileStem}.quarto_ipynb${counter ? "_" + String(counter) : ""}`,
);
}
const target = {
source: file,
input: notebook,
Expand Down
Loading
Loading