Skip to content

Commit

Permalink
Merge pull request #740 from quarto-dev/feature/break-quarto-md-compo…
Browse files Browse the repository at this point in the history
…nents

Feature: quarto directives
  • Loading branch information
jjallaire authored Apr 27, 2022
2 parents 97ed4d2 + 125251f commit 126461f
Show file tree
Hide file tree
Showing 35 changed files with 1,605 additions and 282 deletions.
2 changes: 1 addition & 1 deletion src/command/render/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function outputRecipe(
if (format.render[kKeepYaml]) {
completeActions.push(() => {
// read yaml and output markdown
const inputMd = partitionYamlFrontMatter(context.target.markdown);
const inputMd = partitionYamlFrontMatter(context.target.markdown.value);
if (inputMd) {
const outputFile = join(dirname(context.target.input), recipe.output);
const output = Deno.readTextFileSync(outputFile);
Expand Down
38 changes: 35 additions & 3 deletions src/command/render/render-contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ import { createTempContext } from "../../core/temp.ts";
import { fileExecutionEngineAndTarget } from "../../execute/engine.ts";
import { removePandocTo } from "./flags.ts";
import { filesDirLibDir } from "./render-paths.ts";
import { isJupyterNotebook } from "../../core/jupyter/jupyter.ts";
import { LanguageCellHandlerOptions } from "../../core/handlers/types.ts";
import { handleLanguageCells } from "../../core/handlers/base.ts";

export async function resolveFormatsFromMetadata(
metadata: Metadata,
Expand Down Expand Up @@ -202,21 +205,50 @@ export async function renderContexts(

// return contexts
const contexts: Record<string, RenderContext> = {};
Object.keys(formats).forEach((format: string) => {
for (const format of Object.keys(formats)) {
// set format
contexts[format] = {
const context: RenderContext = {
target,
options,
engine,
format: formats[format],
project,
libDir: libDir!,
};
contexts[format] = context;

// at this point we have enough to fix up the target and engine
// in case that's needed.

if (!isJupyterNotebook(context.target.source)) {
// this is not a jupyter notebook input,
// so we can run pre-engine handlers

const preEngineCellHandlerOptions: LanguageCellHandlerOptions = {
name: "", // this gets filled out by handleLanguageCells later.
temp: options.temp,
format: context.format,
markdown: context.target.markdown,
source: context.target.source,
stage: "pre-engine",
};

const { markdown, results } = await handleLanguageCells(
preEngineCellHandlerOptions,
);

context.target.markdown = markdown;

if (results) {
context.target.preEngineExecuteResults = results;
}
}

// if this isn't for execute then cleanup context
if (!forExecute && engine.executeTargetSkipped) {
engine.executeTargetSkipped(target, formats[format]);
}
});
}
return contexts;
}

Expand Down
98 changes: 57 additions & 41 deletions src/command/render/render-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { isHtmlCompatible } from "../../config/format.ts";
import { mergeConfigs } from "../../core/config.ts";
import { setDateLocale } from "../../core/date.ts";
import { initDenoDom } from "../../core/deno-dom.ts";
import { HandlerContextResults } from "../../core/handlers/types.ts";
import { handleLanguageCells, languages } from "../../core/handlers/base.ts";
import { LanguageCellHandlerOptions } from "../../core/handlers/types.ts";
import { asMappedString, mappedDiff } from "../../core/mapped-text.ts";
Expand Down Expand Up @@ -69,6 +70,8 @@ import {
kProjectFreezeDir,
removeFreezeResults,
} from "./freeze.ts";
import { isJupyterNotebook } from "../../core/jupyter/jupyter.ts";
import { MappedString } from "../../core/lib/text-types.ts";

export async function renderExecute(
context: RenderContext,
Expand Down Expand Up @@ -266,7 +269,6 @@ export async function renderFiles(
target.markdown,
engine.name,
error,
file.path,
);
if (validationResult.length) {
throw new RenderInvalidYAMLError();
Expand All @@ -276,8 +278,38 @@ export async function renderFiles(
}
}

const mergeHandlerResults = (
results: HandlerContextResults | undefined,
executeResult: MappedExecuteResult,
context: RenderContext,
) => {
if (results === undefined) {
return;
}
if (executeResult.includes) {
executeResult.includes = mergeConfigs(
executeResult.includes,
results.includes,
);
} else {
executeResult.includes = results.includes;
}
const extras = resolveDependencies(
results.extras,
dirname(context.target.source),
context.libDir,
tempContext,
);
if (extras[kIncludeInHeader]) {
executeResult.includes[kIncludeInHeader] = [
...(executeResult.includes[kIncludeInHeader] || []),
...(extras[kIncludeInHeader] || []),
];
}
};

for (const format of Object.keys(contexts)) {
const context = contexts[format];
const context = ld.cloneDeep(contexts[format]) as RenderContext; // since we're going to mutate it...

// Set the date locale for this render
// Used for date formatting
Expand Down Expand Up @@ -322,62 +354,46 @@ export async function renderFiles(

// recover source map from diff and create a mappedExecuteResult
// for markdown processing pre-pandoc with mapped strings
const source = Deno.readTextFileSync(context.target.source);
const mappedMarkdown = mappedDiff(
asMappedString(source),
baseExecuteResult.markdown,
);
let mappedMarkdown: MappedString;

if (!isJupyterNotebook(context.target.source)) {
mappedMarkdown = mappedDiff(
context.target.markdown,
baseExecuteResult.markdown,
);
} else {
mappedMarkdown = asMappedString(baseExecuteResult.markdown);
}

const resourceFiles: string[] = [];
if (baseExecuteResult.resourceFiles) {
resourceFiles.push(...baseExecuteResult.resourceFiles);
}

const mappedExecuteResult: MappedExecuteResult = {
...baseExecuteResult,
markdown: mappedMarkdown,
};

const languageCellHandlerOptions: LanguageCellHandlerOptions = {
name: "", // will be filled out by handleLanguageCells internally
temp: tempContext,
name: "",
format: recipe.format,
markdown: mappedMarkdown,
source: context.target.source,
libDir: context.libDir,
project: context.project,
stage: "post-engine",
};

// handle language cells
const { markdown, results } = await handleLanguageCells(
mappedExecuteResult,
languageCellHandlerOptions,
);
// merge cell language results
mappedExecuteResult.markdown = markdown;

if (results) {
if (mappedExecuteResult.includes) {
mappedExecuteResult.includes = mergeConfigs(
mappedExecuteResult.includes,
results.includes,
);
} else {
mappedExecuteResult.includes = results.includes;
}
const extras = resolveDependencies(
results.extras,
dirname(context.target.source),
context.libDir,
tempContext,
);
if (extras[kIncludeInHeader]) {
mappedExecuteResult.includes[kIncludeInHeader] = [
...(mappedExecuteResult.includes[kIncludeInHeader] || []),
...(extras[kIncludeInHeader] || []),
];
}
}
const mappedExecuteResult: MappedExecuteResult = {
...baseExecuteResult,
markdown,
};

mergeHandlerResults(
context.target.preEngineExecuteResults,
mappedExecuteResult,
context,
);
mergeHandlerResults(results, mappedExecuteResult, context);

// process ojs
const { executeResult, resourceFiles: ojsResourceFiles } =
Expand Down
14 changes: 14 additions & 0 deletions src/core/encode-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* encode-metadata.ts
*
* Copyright (C) 2022 by RStudio, PBC
*
*/
import { encode as base64Encode } from "encoding/base64.ts";

export function encodeMetadata(
metadata: Record<string, unknown>,
): string {
const encoded = base64Encode(JSON.stringify(metadata));
return `\n\n\`<!-- quarto-file-metadata: ${encoded} -->\`{=html}\n\n\`\`\`{=html}\n<!-- quarto-file-metadata: ${encoded} -->\n\`\`\`\n\n`;
}
Loading

0 comments on commit 126461f

Please sign in to comment.