Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
508408f
feat:add outputs node
agoose77 Apr 1, 2025
128aa43
chore: add changeset
agoose77 Mar 7, 2025
c87a7a4
fix: drop style change
agoose77 Mar 7, 2025
bf9fa61
fix: only label first code and outputs
agoose77 Mar 7, 2025
3eba5d3
fix: handle IDs
agoose77 Mar 7, 2025
ad8ed3e
fix: return type
agoose77 Mar 7, 2025
195182a
fix: selectAll → select
agoose77 Mar 7, 2025
c715602
refactor: move user expression lowering into function
agoose77 Apr 1, 2025
a5553a3
refactor: nest declaration
agoose77 Apr 1, 2025
32c5915
fix: rename outputs
agoose77 Apr 1, 2025
6458808
refactor: simplify conditions
agoose77 Apr 1, 2025
8c34d46
test: fix tests
agoose77 Apr 1, 2025
d94742d
fix: outputs for JATS
agoose77 Apr 2, 2025
41753bf
fix: use outputs- for all prefixes
agoose77 Apr 2, 2025
42687fb
fix: outputs for JATS
agoose77 Apr 2, 2025
8400eb8
refactor: simplify test for code cells
agoose77 Apr 2, 2025
d3d7a40
fix: early exit non-matplotlib
agoose77 Apr 2, 2025
b86544f
test: partially fix JATS test
agoose77 Apr 2, 2025
6b169e2
fix: final JATS test
agoose77 Apr 2, 2025
05f79b9
test: fix myst-execute tests
agoose77 Apr 2, 2025
f8671d1
test: fix test titles
agoose77 Apr 2, 2025
dc23b0c
test: fix missing children
agoose77 Apr 2, 2025
92bad01
test: more fixes
agoose77 Apr 2, 2025
4d074ac
test: fix test titles
agoose77 Apr 2, 2025
7933f3f
fix: handle visibility properly
agoose77 Apr 2, 2025
7afbe46
fix: update test cases
agoose77 Apr 2, 2025
fccf681
🪪 adding id to outputs enables in-browser compute for figures and embeds
stevejpurves Jun 25, 2025
d9c7445
feat:
agoose77 Apr 10, 2025
8607772
docs: add note about precedence
agoose77 Apr 10, 2025
5ed0c94
chore: add changeset
agoose77 Apr 4, 2025
f5a8def
chore: add changeset
agoose77 Apr 4, 2025
38c6351
fix: reorder xform
agoose77 Apr 11, 2025
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
10 changes: 10 additions & 0 deletions .changeset/ten-bats-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"mystmd": minor
"myst-directives": patch
"myst-transforms": patch
"myst-spec-ext": patch
"myst-execute": patch
"myst-cli": patch
---

Add support for new Outputs node
5 changes: 5 additions & 0 deletions .changeset/weak-bananas-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"myst-cli": patch
---

Move kernel execution transform earlier in pipeline
10 changes: 7 additions & 3 deletions packages/myst-cli/src/process/mdast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
transformFilterOutputStreams,
transformLiftCodeBlocksInJupytext,
transformMystXRefs,
liftOutputs,
} from '../transforms/index.js';
import type { ImageExtensions } from '../utils/resolveExtension.js';
import { logMessagesFromVFile } from '../utils/logging.js';
Expand Down Expand Up @@ -194,6 +195,12 @@ export async function transformMdast(
log: session.log,
});
}
transformRenderInlineExpressions(mdast, vfile);
await transformOutputsToCache(session, mdast, kind, { minifyMaxCharacters });
liftOutputs(session, mdast, vfile, {
parseMyst: (content: string) => parseMyst(session, content, file),
});
transformFilterOutputStreams(mdast, vfile, frontmatter.settings);

const pipe = unified()
.use(reconstructHtmlPlugin) // We need to group and link the HTML first
Expand Down Expand Up @@ -238,9 +245,6 @@ export async function transformMdast(
// Combine file-specific citation renderers with project renderers from bib files
const fileCitationRenderer = combineCitationRenderers(cache, ...rendererFiles);

transformRenderInlineExpressions(mdast, vfile);
await transformOutputsToCache(session, mdast, kind, { minifyMaxCharacters });
transformFilterOutputStreams(mdast, vfile, frontmatter.settings);
transformCitations(session, file, mdast, fileCitationRenderer, references);
await unified()
.use(codePlugin, { lang: frontmatter?.kernelspec?.language })
Expand Down
44 changes: 24 additions & 20 deletions packages/myst-cli/src/process/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ export async function processNotebook(
return mdast;
}

/**
* Embed the Jupyter output data for a user expression into the AST
*/
function embedInlineExpressions(
userExpressions: IUserExpressionMetadata[] | undefined,
block: GenericNode,
) {
const inlineNodes = selectAll('inlineExpression', block) as InlineExpression[];
inlineNodes.forEach((inlineExpression) => {
const data = findExpression(userExpressions, inlineExpression.value);
if (!data) return;
inlineExpression.result = data.result as unknown as Record<string, unknown>;
});
}

export async function processNotebookFull(
session: ISession,
file: string,
Expand Down Expand Up @@ -136,17 +151,7 @@ export async function processNotebookFull(
return acc.concat(...cellMdast.children);
}
const block = blockParent(cell, cellMdast.children) as GenericNode;

// Embed expression results into expression
const userExpressions = block.data?.[metadataSection] as
| IUserExpressionMetadata[]
| undefined;
const inlineNodes = selectAll('inlineExpression', block) as InlineExpression[];
inlineNodes.forEach((inlineExpression) => {
const data = findExpression(userExpressions, inlineExpression.value);
if (!data) return;
inlineExpression.result = data.result as unknown as Record<string, unknown>;
});
embedInlineExpressions(block.data?.[metadataSection], block);
return acc.concat(block);
}
if (cell.cell_type === CELL_TYPES.raw) {
Expand All @@ -165,17 +170,16 @@ export async function processNotebookFull(
value: ensureString(cell.source),
};

// Embed outputs in an output block
const output: { type: 'output'; id: string; data: IOutput[] } = {
type: 'output',
const outputs = {
type: 'outputs',
id: nanoid(),
data: [],
children: (cell.outputs as IOutput[]).map((output) => ({
type: 'output',
jupyter_data: output,
children: [],
})),
};

if (cell.outputs && (cell.outputs as IOutput[]).length > 0) {
output.data = cell.outputs as IOutput[];
}
return acc.concat(blockParent(cell, [code, output]));
return acc.concat(blockParent(cell, [code, outputs]));
}
return acc;
},
Expand Down
36 changes: 21 additions & 15 deletions packages/myst-cli/src/transforms/code.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ function build_mdast(tags: string[], has_output: boolean) {
],
};
if (has_output) {
mdast.children[0].children.push({ type: 'output' });
mdast.children[0].children.push({
type: 'outputs',
children: [{ type: 'output', children: [] }],
});
}
return mdast;
}
Expand Down Expand Up @@ -261,7 +264,7 @@ describe('propagateBlockDataToCode', () => {
const mdast = build_mdast([tag], has_output);
propagateBlockDataToCode(new Session(), new VFile(), mdast);
let result = '';
const outputNode = mdast.children[0].children[1];
const outputsNode = mdast.children[0].children[1];
switch (target) {
case 'cell':
result = mdast.children[0].visibility;
Expand All @@ -270,12 +273,14 @@ describe('propagateBlockDataToCode', () => {
result = mdast.children[0].children[0].visibility;
break;
case 'output':
if (!has_output && target == 'output') {
expect(outputNode).toEqual(undefined);
if (!has_output) {
expect(outputsNode).toEqual(undefined);
continue;
}
result = outputNode.visibility;
result = outputsNode.visibility;
break;
default:
throw new Error();
}
expect(result).toEqual(action);
}
Expand All @@ -290,18 +295,18 @@ describe('propagateBlockDataToCode', () => {
propagateBlockDataToCode(new Session(), new VFile(), mdast);
const blockNode = mdast.children[0];
const codeNode = mdast.children[0].children[0];
const outputNode = mdast.children[0].children[1];
const outputsNode = mdast.children[0].children[1];
expect(blockNode.visibility).toEqual(action);
expect(codeNode.visibility).toEqual(action);
if (has_output) {
expect(outputNode.visibility).toEqual(action);
expect(outputsNode.visibility).toEqual(action);
} else {
expect(outputNode).toEqual(undefined);
expect(outputsNode).toEqual(undefined);
}
}
}
});
it('placeholder creates image node child of output', async () => {
it('placeholder creates image node child of outputs', async () => {
const mdast: any = {
type: 'root',
children: [
Expand All @@ -313,7 +318,8 @@ describe('propagateBlockDataToCode', () => {
executable: true,
},
{
type: 'output',
type: 'outputs',
children: [],
},
],
data: {
Expand All @@ -323,12 +329,12 @@ describe('propagateBlockDataToCode', () => {
],
};
propagateBlockDataToCode(new Session(), new VFile(), mdast);
const outputNode = mdast.children[0].children[1];
expect(outputNode.children?.length).toEqual(1);
expect(outputNode.children[0].type).toEqual('image');
expect(outputNode.children[0].placeholder).toBeTruthy();
const outputsNode = mdast.children[0].children[1];
expect(outputsNode.children?.length).toEqual(1);
expect(outputsNode.children[0].type).toEqual('image');
expect(outputsNode.children[0].placeholder).toBeTruthy();
});
it('placeholder passes with no output', async () => {
it('placeholder passes with no outputs', async () => {
const mdast: any = {
type: 'root',
children: [
Expand Down
17 changes: 8 additions & 9 deletions packages/myst-cli/src/transforms/code.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { GenericNode, GenericParent } from 'myst-common';
import { NotebookCellTags, RuleId, fileError, fileWarn } from 'myst-common';
import type { Image, Output } from 'myst-spec-ext';
import type { Image, Outputs } from 'myst-spec-ext';
import { select, selectAll } from 'unist-util-select';
import yaml from 'js-yaml';
import type { VFile } from 'vfile';
Expand Down Expand Up @@ -156,10 +156,9 @@ export function propagateBlockDataToCode(session: ISession, vfile: VFile, mdast:
const blocks = selectAll('block', mdast) as GenericNode[];
blocks.forEach((block) => {
if (!block.data) return;
const outputNode = select('output', block) as Output | null;
if (block.data.placeholder && outputNode) {
if (!outputNode.children) outputNode.children = [];
outputNode.children.push({
const outputsNode = select('outputs', block) as Outputs | null;
if (block.data.placeholder && outputsNode) {
outputsNode.children.push({
type: 'image',
placeholder: true,
url: block.data.placeholder as string,
Expand Down Expand Up @@ -195,18 +194,18 @@ export function propagateBlockDataToCode(session: ISession, vfile: VFile, mdast:
if (codeNode) codeNode.visibility = 'remove';
break;
case NotebookCellTags.hideOutput:
if (outputNode) outputNode.visibility = 'hide';
if (outputsNode) outputsNode.visibility = 'hide';
break;
case NotebookCellTags.removeOutput:
if (outputNode) outputNode.visibility = 'remove';
if (outputsNode) outputsNode.visibility = 'remove';
break;
default:
session.log.debug(`tag '${tag}' is not valid in code-cell tags'`);
}
});
if (!block.visibility) block.visibility = 'show';
if (codeNode && !codeNode.visibility) codeNode.visibility = 'show';
if (outputNode && !outputNode.visibility) outputNode.visibility = 'show';
if (outputsNode && !outputsNode.visibility) outputsNode.visibility = 'show';
});
}

Expand All @@ -233,7 +232,7 @@ export function transformLiftCodeBlocksInJupytext(mdast: GenericParent) {
child.type === 'block' &&
child.children?.length === 2 &&
child.children?.[0].type === 'code' &&
child.children?.[1].type === 'output'
child.children?.[1].type === 'outputs'
) {
newBlocks.push(child as GenericParent);
newBlocks.push({ type: 'block', children: [] });
Expand Down
Loading
Loading