diff --git a/packages/ember-repl/addon/src/compile/formats.ts b/packages/ember-repl/addon/src/compile/formats.ts index b9113c833..e148335a8 100644 --- a/packages/ember-repl/addon/src/compile/formats.ts +++ b/packages/ember-repl/addon/src/compile/formats.ts @@ -90,6 +90,7 @@ export async function compileMD( importMap?: EvalImportMap; topLevelScope?: ScopeMap; remarkPlugins?: UnifiedPlugin[]; + rehypePlugins?: UnifiedPlugin[]; CopyComponent?: string; ShadowComponent?: string; } @@ -114,6 +115,7 @@ export async function compileMD( CopyComponent: options?.CopyComponent, ShadowComponent: options?.ShadowComponent, remarkPlugins: options?.remarkPlugins, + rehypePlugins: options?.rehypePlugins, }); rootTemplate = templateOnlyGlimdown; diff --git a/packages/ember-repl/addon/src/compile/index.ts b/packages/ember-repl/addon/src/compile/index.ts index 91f29f955..a2e9d8d4b 100644 --- a/packages/ember-repl/addon/src/compile/index.ts +++ b/packages/ember-repl/addon/src/compile/index.ts @@ -29,6 +29,7 @@ const SUPPORTED_FORMATS = ['glimdown', 'gjs', 'hbs']; interface GlimdownOptions extends Scope, Events { format: 'glimdown'; remarkPlugins?: UnifiedPlugin[]; + rehypePlugins?: UnifiedPlugin[]; CopyComponent?: string; ShadowComponent?: string; topLevelScope?: ScopeMap; diff --git a/packages/ember-repl/test-app/tests/rendering/markdown-test.gts b/packages/ember-repl/test-app/tests/rendering/markdown-test.gts index 8b88b12e2..361957ec0 100644 --- a/packages/ember-repl/test-app/tests/rendering/markdown-test.gts +++ b/packages/ember-repl/test-app/tests/rendering/markdown-test.gts @@ -239,5 +239,93 @@ module('Rendering | compile()', function (hooks) { assert.dom().containsText(text); }); + + test('adding a remark plugin', async function (assert) { + setupOnerror((e) => { + console.error(e); + assert.notOk('This should not error'); + }); + + let snippet = '# Hello'; + + let component: ComponentLike | undefined; + + await compile(snippet, { + format: 'glimdown', + onSuccess: (comp) => (component = comp), + onError: (e) => { + console.error(e); + assert.notOk('did not expect error'); + }, + onCompileStart: () => { + /* not used */ + }, + + remarkPlugins: [ + function noH1(/* options */) { + return (tree) => { + return visit(tree, ['heading'], function (node) { + if (!('depth' in node)) return; + + if (node.depth === 1) { + node.depth = 2; + } + + return 'skip'; + }); + }; + }, + ], + }); + + debugAssert(`[BUG]`, component); + + await render(component); + + assert.dom('h2').containsText('Hello'); + }); + test('adding a rehype plugin', async function (assert) { + setupOnerror((e) => { + console.error(e); + assert.notOk('This should not error'); + }); + + let snippet = '# Hello'; + + let component: ComponentLike | undefined; + + await compile(snippet, { + format: 'glimdown', + onSuccess: (comp) => (component = comp), + onError: (e) => { + console.error(e); + assert.notOk('did not expect error'); + }, + onCompileStart: () => { + /* not used */ + }, + rehypePlugins: [ + function noH1(/* options */) { + return (tree) => { + return visit(tree, ['element'], function (node) { + if (!('tagName' in node)) return; + + if (node.tagName === 'h1') { + node.tagName = 'h2'; + } + + return 'skip'; + }); + }; + }, + ], + }); + + debugAssert(`[BUG]`, component); + + await render(component); + + assert.dom('h2').containsText('Hello'); + }); }); });