diff --git a/.changeset/khaki-poems-hunt.md b/.changeset/khaki-poems-hunt.md new file mode 100644 index 000000000..5ce0a2cc0 --- /dev/null +++ b/.changeset/khaki-poems-hunt.md @@ -0,0 +1,7 @@ +--- +'myst-transforms': patch +'myst-cli': patch +'mystmd': patch +--- + +Translate mermaid and math code blocks by default. diff --git a/docs/diagrams.md b/docs/diagrams.md index 7c00a2b09..c302c9122 100644 --- a/docs/diagrams.md +++ b/docs/diagrams.md @@ -20,3 +20,7 @@ flowchart LR D <--> J[JATS] ``` ```` + +:::{note} +Both GitHub and JupyterLab ([#101](https://github.com/jupyter/enhancement-proposals/pull/101)) support the translation of a code-block ` ```mermaid ` to a mermaid diagram directly, this can also be used by default in MyST. +::: diff --git a/packages/myst-transforms/src/basic.ts b/packages/myst-transforms/src/basic.ts index 641a6e801..ab4429e14 100644 --- a/packages/myst-transforms/src/basic.ts +++ b/packages/myst-transforms/src/basic.ts @@ -8,15 +8,16 @@ import { admonitionBlockquoteTransform, admonitionHeadersTransform } from './adm import { blockMetadataTransform, blockNestingTransform } from './blocks.js'; import { htmlIdsTransform } from './htmlIds.js'; import { imageAltTextTransform } from './images.js'; -import { mathCodeBlockTransform, mathLabelTransform, mathNestingTransform } from './math.js'; +import { mathLabelTransform, mathNestingTransform } from './math.js'; import { blockquoteTransform } from './blockquote.js'; +import { codeBlockToDirectiveTransform } from './code.js'; export function basicTransformations(tree: Root, file: VFile) { // lifting roles and directives must happen before the mystTarget transformation liftMystDirectivesAndRolesTransform(tree); // Some specifics about the ordering are noted below captionParagraphTransform(tree); - mathCodeBlockTransform(tree, file); + codeBlockToDirectiveTransform(tree, file, { translate: ['math', 'mermaid'] }); mathNestingTransform(tree, file); // Math labelling should happen before the target-transformation mathLabelTransform(tree, file); diff --git a/packages/myst-transforms/src/code.ts b/packages/myst-transforms/src/code.ts index 832f550ab..c90fda576 100644 --- a/packages/myst-transforms/src/code.ts +++ b/packages/myst-transforms/src/code.ts @@ -2,6 +2,7 @@ import type { Plugin } from 'unified'; import type { Root } from 'mdast'; import type { Code } from 'myst-spec'; import { selectAll } from 'unist-util-select'; +import type { GenericNode } from 'myst-common'; import { fileWarn } from 'myst-common'; import type { VFile } from 'vfile'; @@ -30,3 +31,30 @@ export function codeTransform(mdast: Root, file: VFile, opts?: Options) { export const codePlugin: Plugin<[Options?], Root, Root> = (opts) => (tree, file) => { codeTransform(tree, file, opts); }; + +type CodeBlockTransformOptions = { + translate: (string | { lang: string; directive?: string })[]; +}; + +export function codeBlockToDirectiveTransform( + tree: Root, + file: VFile, + opts?: CodeBlockTransformOptions, +) { + if (!opts || !opts.translate || opts.translate.length === 0) return; + const nodes = selectAll('code', tree) as Code[]; + nodes.forEach((node) => { + if (!node.lang) return; + const res = opts.translate.find( + (t) => t === node.lang || (typeof t !== 'string' && t.lang === node.lang), + ); + if (!res) return; + (node as GenericNode).type = typeof res === 'string' ? res : res.directive || res.lang; + delete node.lang; + }); +} + +export const codeBlockToDirectivePlugin: Plugin<[CodeBlockTransformOptions?], Root, Root> = + (opts) => (tree, file) => { + codeBlockToDirectiveTransform(tree, file, opts); + }; diff --git a/packages/myst-transforms/src/math.spec.ts b/packages/myst-transforms/src/math.spec.ts index d7aac24b5..ed80b8f6b 100644 --- a/packages/myst-transforms/src/math.spec.ts +++ b/packages/myst-transforms/src/math.spec.ts @@ -1,7 +1,8 @@ import { describe, expect, test } from 'vitest'; import { unified } from 'unified'; import { VFile } from 'vfile'; -import { mathTransform, mathPlugin, mathNestingTransform, mathCodeBlockTransform } from './math'; +import { mathTransform, mathPlugin, mathNestingTransform } from './math'; +import { codeBlockToDirectiveTransform } from './code'; const ARRAY_ALIGN = `\\begin{align*} L= @@ -129,7 +130,7 @@ describe('Test math code block transformation', () => { test('Block paragraph', () => { const file = new VFile(); const mdast = { children: [{ type: 'code', lang: 'math', value: 'Ax = b' }] } as any; - mathCodeBlockTransform(mdast, file); + codeBlockToDirectiveTransform(mdast, file, { translate: ['math'] }); expect(mdast.children[0].type).toBe('math'); expect(mdast.children[0].lang).toBeUndefined(); expect(mdast.children[0].value).toBe('Ax = b'); diff --git a/packages/myst-transforms/src/math.ts b/packages/myst-transforms/src/math.ts index e2a9d733e..db20a3f7a 100644 --- a/packages/myst-transforms/src/math.ts +++ b/packages/myst-transforms/src/math.ts @@ -239,15 +239,6 @@ export function mathLabelTransform(tree: Root, file: VFile) { }); } -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function mathCodeBlockTransform(tree: Root, file: VFile) { - const nodes = selectAll('code[lang="math"]', tree) as Code[]; - nodes.forEach((node) => { - (node as unknown as Math).type = 'math'; - delete node.lang; - }); -} - export function mathTransform(tree: Root, file: VFile, opts?: Options) { const nodes = selectAll('math,inlineMath', tree) as (Math | InlineMath)[]; nodes.forEach((node) => { @@ -255,10 +246,6 @@ export function mathTransform(tree: Root, file: VFile, opts?: Options) { }); } -export const mathCodeBlockPlugin: Plugin<[], Root, Root> = () => (tree, file) => { - mathCodeBlockTransform(tree, file); -}; - export const mathNestingPlugin: Plugin<[], Root, Root> = () => (tree, file) => { mathNestingTransform(tree, file); };