diff --git a/__tests__/transformers/readme-components.test.ts b/__tests__/transformers/readme-components.test.ts index 531481cd8..8ab7f9e7e 100644 --- a/__tests__/transformers/readme-components.test.ts +++ b/__tests__/transformers/readme-components.test.ts @@ -7,6 +7,7 @@ describe('Readme Components Transformer', () => { { md: '', type: 'code-tabs' }, { md: '', type: 'image' }, { md: '', type: 'table' }, + { md: '', type: 'tutorial-tile' }, ]; it.each(nodes)('transforms $md into a(n) $type node', ({ md, type }) => { diff --git a/__tests__/transformers/readme-to-mdx.test.ts b/__tests__/transformers/readme-to-mdx.test.ts new file mode 100644 index 000000000..868f53bd0 --- /dev/null +++ b/__tests__/transformers/readme-to-mdx.test.ts @@ -0,0 +1,25 @@ +import { mdx } from '../../index'; + +describe('readme-to-mdx transformer', () => { + it('converts a tutorial tile to MDX', () => { + const ast = { + type: 'root', + children: [ + { + type: 'tutorial-tile', + backgroundColor: 'red', + emoji: '🦉', + id: 'test-id', + link: 'http://example.com', + slug: 'test-id', + title: 'Test', + }, + ], + }; + + expect(mdx(ast)).toMatchInlineSnapshot(` + " + " + `); + }); +}); diff --git a/enums.ts b/enums.ts index b30ca4c3a..b6a448c10 100644 --- a/enums.ts +++ b/enums.ts @@ -1,12 +1,13 @@ export enum NodeTypes { callout = 'rdme-callout', codeTabs = 'code-tabs', + embed = 'embed', emoji = 'gemoji', + glossary = 'readme-glossary-item', + htmlBlock = 'html-block', i = 'i', image = 'image', - htmlBlock = 'html-block', - embed = 'embed', - variable = 'readme-variable', - glossary = 'readme-glossary-item', reusableContent = 'reusable-content', + tutorialTile = 'tutorial-tile', + variable = 'readme-variable', } diff --git a/index.tsx b/index.tsx index 3d9bfaf54..997b7972d 100644 --- a/index.tsx +++ b/index.tsx @@ -14,7 +14,7 @@ import * as Components from './components'; import { getHref } from './components/Anchor'; import { options } from './options'; -import transformers, { readmeComponentsTransformer } from './processor/transform'; +import transformers, { readmeComponentsTransformer, readmeToMdx } from './processor/transform'; import compilers from './processor/compile'; import MdxSyntaxError from './errors/mdx-syntax-error'; import { GlossaryTerm } from './contexts/GlossaryTerms'; @@ -118,7 +118,9 @@ export const reactTOC = (text: string, opts = {}) => { }; export const mdx = (tree: any, opts = {}) => { - return remark().use(remarkMdx).use(remarkGfm).use(compilers).stringify(tree, opts); + const processor = remark().use(remarkMdx).use(remarkGfm).use(readmeToMdx).use(compilers); + + return processor.stringify(processor.runSync(tree), opts); }; export const html = (text: string, opts = {}) => { diff --git a/package-lock.json b/package-lock.json index 45047198a..38f3081fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "prettier": "^3.2.5", "puppeteer": "^19.8.3", "react-router-dom": "^6.22.3", - "sass": "^1.77.2", + "sass": "^1.77.3", "sass-loader": "^13.2.2", "semantic-release": "^22.0.12", "stream-browserify": "^3.0.0", @@ -26293,9 +26293,9 @@ "devOptional": true }, "node_modules/sass": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", - "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "version": "1.77.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.3.tgz", + "integrity": "sha512-WJHo+jmFp0dwRuymPmIovuxHaBntcCyja5hCB0yYY9wWrViEp4kF5Cdai98P72v6FzroPuABqu+ddLMbQWmwzA==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", diff --git a/package.json b/package.json index b5380b8a7..fc57002c8 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "prettier": "^3.2.5", "puppeteer": "^19.8.3", "react-router-dom": "^6.22.3", - "sass": "^1.77.2", + "sass": "^1.77.3", "sass-loader": "^13.2.2", "semantic-release": "^22.0.12", "stream-browserify": "^3.0.0", diff --git a/processor/transform/index.ts b/processor/transform/index.ts index 2537cc078..a21239ed5 100644 --- a/processor/transform/index.ts +++ b/processor/transform/index.ts @@ -3,7 +3,8 @@ import codeTabsTransfromer from './code-tabs'; import embedTransformer from './embeds'; import gemojiTransformer from './gemoji+'; import readmeComponentsTransformer from './readme-components'; +import readmeToMdx from './readme-to-mdx'; -export { readmeComponentsTransformer }; +export { readmeComponentsTransformer, readmeToMdx }; export default [calloutTransformer, codeTabsTransfromer, embedTransformer, gemojiTransformer]; diff --git a/processor/transform/readme-components.ts b/processor/transform/readme-components.ts index 1b49734f3..27ccae654 100644 --- a/processor/transform/readme-components.ts +++ b/processor/transform/readme-components.ts @@ -16,6 +16,7 @@ const types = { Variable: NodeTypes['variable'], td: 'tableCell', tr: 'tableRow', + TutorialTile: NodeTypes.tutorialTile, }; const attributes = (jsx: MdxJsxFlowElement | MdxJsxTextElement) => diff --git a/processor/transform/readme-to-mdx.ts b/processor/transform/readme-to-mdx.ts new file mode 100644 index 000000000..f8cc9507f --- /dev/null +++ b/processor/transform/readme-to-mdx.ts @@ -0,0 +1,31 @@ +import { NodeTypes } from '../../enums'; +import { Transform } from 'mdast-util-from-markdown'; +import { MdxJsxAttribute } from 'mdast-util-mdx-jsx'; + +import { visit } from 'unist-util-visit'; + +const readmeToMdx = (): Transform => tree => { + visit(tree, NodeTypes.tutorialTile, (tile, index, parent) => { + const attributes: MdxJsxAttribute[] = ['backgroundColor', 'emoji', 'id', 'link', 'slug', 'title'].map(name => { + const value = tile[name]; + delete tile[name]; + + return { + type: 'mdxJsxAttribute', + name, + value, + }; + }); + + parent.children.splice(index, 1, { + type: 'mdxJsxFlowElement', + name: 'TutorialTile', + attributes, + children: [], + }); + }); + + return tree; +}; + +export default readmeToMdx; diff --git a/types.d.ts b/types.d.ts index a5d400515..deb7f03c5 100644 --- a/types.d.ts +++ b/types.d.ts @@ -53,12 +53,23 @@ interface FaEmoji extends Literal { type: NodeTypes.i; } +interface TutorialTile extends Node { + backgroundColor: string; + emoji: string; + id: string; + link: string; + slug: string; + title: string; + type: NodeTypes.tutorialTile; +} + declare module 'mdast' { interface BlockContentMap { [NodeTypes.callout]: Callout; [NodeTypes.codeTabs]: CodeTabs; [NodeTypes.embed]: Embed; [NodeTypes.htmlBlock]: HTMLBlock; + [NodeTypes.tutorialTile]: TutorialTile; } interface PhrasingContentMap { @@ -72,5 +83,6 @@ declare module 'mdast' { [NodeTypes.embed]: Embed; [NodeTypes.emoji]: Gemoji; [NodeTypes.i]: FaEmoji; + [NodeTypes.tutorialTile]: TutorialTile; } }