Skip to content

Commit

Permalink
create mdx-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
erickzhao committed May 16, 2024
1 parent 52a24af commit bb38618
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 154 deletions.
7 changes: 2 additions & 5 deletions src/transformers/api-labels.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Parent } from 'unist';
import { visitParents } from 'unist-util-visit-parents';
import { Data as HastData } from 'hast';
import { Emphasis, PhrasingContent, Text } from 'mdast';
import { Emphasis } from 'mdast';
import { isText } from '../util/mdx-utils';

/**
* This transformer adds badge styling to our raw API documentation.
Expand Down Expand Up @@ -63,7 +64,3 @@ function visitor(node: Emphasis) {
}
}
}

function isText(node: PhrasingContent): node is Text {
return node.type === 'text';
}
14 changes: 3 additions & 11 deletions src/transformers/api-options-class.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Node, Parent } from 'unist';
import { InlineCode, ListItem, Paragraph } from 'mdast';
import { Parent } from 'unist';
import { ListItem } from 'mdast';
import { Data as HastData } from 'hast';
import { visitParents } from 'unist-util-visit-parents';
import { isOptions, isParagraph } from '../util/mdx-utils';

/**
* This transformer adds the class="electron-api-options-list"
Expand Down Expand Up @@ -41,12 +42,3 @@ function visitor(node: ListItem) {
node.data = hastProperties;
}
}

function isParagraph(node: Node): node is Paragraph {
return node.type === 'paragraph';
}

function isOptions(node: Node): node is InlineCode {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return node.type === 'inlineCode' && (node as any).value === 'options';
}
73 changes: 15 additions & 58 deletions src/transformers/api-structure-previews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ import { visitParents } from 'unist-util-visit-parents';
import fs from 'fs';
import path from 'path';
import { Node, Parent } from 'unist';
import type {
Definition,
InlineCode,
Link,
LinkReference,
Nodes,
Text,
} from 'mdast';
import type { InlineCode, Link, LinkReference, Nodes, Text } from 'mdast';
import { gfmTableToMarkdown } from 'mdast-util-gfm-table';
import { frontmatterToMarkdown } from 'mdast-util-frontmatter';
import { toMarkdown } from 'mdast-util-to-markdown';
import { MdxJsxFlowElement } from 'mdast-util-mdx-jsx';
import type { VFile } from 'vfile';
import {
getJSXImport,
isDefinition,
isInlineCode,
isLink,
isLinkReference,
isText,
} from '../util/mdx-utils';

const fileContent = new Map<
string,
Expand Down Expand Up @@ -81,38 +82,9 @@ async function transformer(tree: Parent, file: VFile) {
modifiers.clear();
visitParents(tree, checkLinksandDefinitions, replaceLinkWithPreview);
visitParents(tree, isStructureLinkReference, replaceLinkWithPreview);
const importNode = getJSXImport('APIStructurePreview');
if (modifiers.size) {
tree.children.unshift({
type: 'mdxjsEsm',
value:
"import APIStructurePreview from '@site/src/components/APIStructurePreview'",
data: {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'APIStructurePreview',
},
},
],
source: {
type: 'Literal',
value: '@site/src/components/APIStructurePreview',
raw: "'@site/src/components/APIStructurePreview'",
},
},
],
sourceType: 'module',
comments: [],
},
},
} as unknown as MdxJsxFlowElement);
tree.children.unshift(importNode);
await Promise.all(Array.from(modifiers));
}
}
Expand Down Expand Up @@ -214,9 +186,10 @@ function replaceLinkWithPreview(node: Link | LinkReference) {
// replace the raw link file with our JSX component.
// See src/components/APIStructurePreview.jsx for implementation.
if (
Array.isArray(node.children) &&
node.children.length > 0 &&
isTextOrInlineCode(node.children[0])
(Array.isArray(node.children) &&
node.children.length > 0 &&
isText(node.children[0])) ||
isInlineCode(node.children[0])
) {
modifiers.add(
promise
Expand Down Expand Up @@ -257,19 +230,3 @@ function replaceLinkWithPreview(node: Link | LinkReference) {
);
}
}

function isDefinition(node: Node): node is Definition {
return node.type === 'definition';
}

function isLink(node: Node): node is Link {
return node.type === 'link';
}

function isLinkReference(node: Node): node is LinkReference {
return node.type === 'linkReference';
}

function isTextOrInlineCode(node: Node): node is Text | InlineCode {
return node.type === 'text' || node.type === 'inlineCode';
}
42 changes: 2 additions & 40 deletions src/transformers/fiddle-embedder.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Node, Parent } from 'unist';
import { Code } from 'mdast';
import { MdxjsEsm } from 'mdast-util-mdxjs-esm';
import { MdxJsxFlowElement } from 'mdast-util-mdx-jsx';

import { visitParents, ActionTuple, SKIP } from 'unist-util-visit-parents';
import path from 'path';
import fs from 'fs-extra';
import latestVersion from 'latest-version';
import { getJSXImport, isCode, isImport } from '../util/mdx-utils';

let _version = '';
async function getVersion() {
Expand Down Expand Up @@ -40,36 +39,7 @@ function matchFiddleBlock(node: Node): node is Code {
);
}

const importNode = {
type: 'mdxjsEsm',
value: "import FiddleEmbed from '@site/src/components/FiddleEmbed'",
data: {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'FiddleEmbed',
},
},
],
source: {
type: 'Literal',
value: '@site/src/components/FiddleEmbed',
raw: "'@site/src/components/FiddleEmbed'",
},
},
],
sourceType: 'module',
comments: [],
},
},
};
const importNode = getJSXImport('FiddleEmbed');

async function transformer(tree: Parent) {
let needImport = false;
Expand Down Expand Up @@ -225,11 +195,3 @@ async function transformer(tree: Parent) {
return children;
}
}

function isImport(node: Node): node is MdxjsEsm {
return node.type === 'mdxjsEsm';
}

function isCode(node: Node): node is Code {
return node.type === 'code';
}
42 changes: 2 additions & 40 deletions src/transformers/js-code-blocks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Node, Parent } from 'unist';
import { Code } from 'mdast';
import { MdxjsEsm } from 'mdast-util-mdxjs-esm';

import { visitParents, ActionTuple, SKIP } from 'unist-util-visit-parents';
import { getJSXImport, isCode, isImport } from '../util/mdx-utils';

const CJS_PREAMBLE = '// CommonJS\n';
const MJS_PREAMBLE = '// ESM\n';
Expand All @@ -20,44 +20,13 @@ function matchMjsCodeBlock(node: Node): node is Code {
return isCode(node) && node.lang === 'mjs';
}

const importNode = {
type: 'mdxjsEsm',
value: "import JsCodeBlock from '@site/src/components/JsCodeBlock'",
data: {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'JsCodeBlock',
},
},
],
source: {
type: 'Literal',
value: '@site/src/components/JsCodeBlock',
raw: "'@site/src/components/JsCodeBlock'",
},
},
],
sourceType: 'module',
comments: [],
},
},
};

async function transformer(tree: Parent) {
let needImport = false;
visitParents(tree, matchCjsCodeBlock, maybeGenerateJsCodeBlock);
visitParents(tree, 'mdxjsEsm', checkForJsCodeBlockImport);

if (needImport) {
tree.children.unshift(importNode);
tree.children.unshift(getJSXImport('JsCodeBlock'));
}

function checkForJsCodeBlockImport(node: Node) {
Expand Down Expand Up @@ -132,10 +101,3 @@ async function transformer(tree: Parent) {
return [SKIP, idx + 1];
}
}
function isImport(node: Node): node is MdxjsEsm {
return node.type === 'mdxjsEsm';
}

function isCode(node: Node): node is Code {
return node.type === 'code';
}
97 changes: 97 additions & 0 deletions src/util/mdx-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
PhrasingContent,
Text,
Paragraph,
InlineCode,
LinkReference,
Link,
Definition,
Code,
} from 'mdast';
import { MdxjsEsm } from 'mdast-util-mdxjs-esm';
import { Node } from 'unist';

export function isCode(node: Node): node is Code {
return node.type === 'code';
}

export function isDefinition(node: Node): node is Definition {
return node.type === 'definition';
}

export function isImport(node: Node): node is MdxjsEsm {
return node.type === 'mdxjsEsm';
}

export function isInlineCode(node: Node): node is InlineCode {
return node.type === 'inlineCode';
}

export function isLink(node: Node): node is Link {
return node.type === 'link';
}

export function isLinkReference(node: Node): node is LinkReference {
return node.type === 'linkReference';
}

export function isOptions(node: Node): node is InlineCode {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return node.type === 'inlineCode' && (node as any).value === 'options';
}

export function isParagraph(node: Node): node is Paragraph {
return node.type === 'paragraph';
}

export function isText(node: PhrasingContent): node is Text {
return node.type === 'text';
}

/**
* Imports a component from `@site/src/components`.
*
* @example
*
* To import the default exported `JsCodeBlock` React component from
* `src/components/JsCodeBlock.tsx`, import the name of the component with no file extension:
*
* ```js
* getJSXImport('JsCodeBlock')
* ```
*
* @param componentName name of the TSX file
* @returns MDX AST
*/
export function getJSXImport(componentName: string): MdxjsEsm {
return {
type: 'mdxjsEsm',
value: `import ${componentName} from '@site/src/components/${componentName}'`,
data: {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: componentName,
},
},
],
source: {
type: 'Literal',
value: `@site/src/components/${componentName}`,
raw: `'@site/src/components/${componentName}'`,
},
},
],
sourceType: 'module',
comments: [],
},
},
};
}

0 comments on commit bb38618

Please sign in to comment.