Skip to content

Commit a3b7f50

Browse files
feat: add title props to plain (#1036)
[![PR App][icn]][demo] | Ref RM-11201 :-------------------:|:----------: ## 🧰 Changes Adds the `title` prop from our built ins to `plain` This will make content in the `title` indexable in the main app. ## 🧬 QA & Testing - [Broken on production][prod]. - [Working in this PR app][demo]. [demo]: https://markdown-pr-PR_NUMBER.herokuapp.com [prod]: https://SUBDOMAIN.readme.io [icn]: https://user-images.githubusercontent.com/886627/160426047-1bee9488-305a-4145-bb2b-09d8b757d38a.svg
1 parent 4616fb3 commit a3b7f50

File tree

5 files changed

+107
-34
lines changed

5 files changed

+107
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { hast, plain } from '../../../index';
2+
3+
describe('plain compiler', () => {
4+
it('should include the title of Accordion', () => {
5+
const mdx = `
6+
<Accordion title="Title">
7+
Body
8+
</Accordion>
9+
`;
10+
11+
expect(plain(hast(mdx))).toContain('Title Body');
12+
});
13+
14+
it('should include the title of Card', () => {
15+
const mdx = `
16+
<Card title="Title">
17+
Body
18+
</Card>
19+
`;
20+
21+
expect(plain(hast(mdx))).toContain('Title Body');
22+
});
23+
24+
it('should include the title of Tab', () => {
25+
const mdx = `
26+
<Tab title="Title">
27+
Body
28+
</Tab>
29+
`;
30+
31+
expect(plain(hast(mdx))).toContain('Title Body');
32+
});
33+
});

lib/hast.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import astProcessor, { rehypePlugins, MdastOpts } from './ast-processor';
22
import remarkRehype from 'remark-rehype';
3-
import { injectComponents } from '../processor/transform';
3+
import { injectComponents, mdxToHast } from '../processor/transform';
44
import { MdastComponents } from '../types';
55
import mdast from './mdast';
66

@@ -10,7 +10,11 @@ const hast = (text: string, opts: MdastOpts = {}) => {
1010
return memo;
1111
}, {});
1212

13-
const processor = astProcessor(opts).use(injectComponents({ components })).use(remarkRehype).use(rehypePlugins);
13+
const processor = astProcessor(opts)
14+
.use(injectComponents({ components }))
15+
.use(mdxToHast)
16+
.use(remarkRehype)
17+
.use(rehypePlugins);
1418

1519
return processor.runSync(processor.parse(text));
1620
};

lib/plain.ts

+33-26
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,39 @@ function one(node: Nodes, opts: Options) {
2121
if ('tagName' in node) {
2222
if (STRIP_TAGS.includes(node.tagName)) return '';
2323

24-
if (node.tagName === 'html-block') {
25-
if (!node.properties.html) return '';
26-
return all(hast(node.properties.html.toString()), opts);
27-
}
28-
29-
if (node.tagName === 'rdme-callout') {
30-
const { icon, title } = node.properties;
31-
32-
const children = node?.children?.slice(title ? 1 : 0);
33-
const body = children ? all({ type: 'root', children }, opts) : '';
34-
35-
return [icon, ' ', title, title && body && ': ', body].filter(Boolean).join('');
36-
}
37-
38-
if (node.tagName === 'readme-glossary-item') {
39-
return node.properties.term;
40-
}
41-
42-
if (node.tagName === 'readme-variable') {
43-
const key = node.properties.variable.toString();
44-
const val = opts.variables[key];
45-
return val || `<<${key}>>`;
46-
}
47-
48-
if (node.tagName === 'img') {
49-
return node.properties?.title || '';
24+
switch (node.tagName) {
25+
case 'html-block': {
26+
if (!node.properties.html) return '';
27+
return all(hast(node.properties.html.toString()), opts);
28+
}
29+
case 'rdme-callout': {
30+
const { icon, title } = node.properties;
31+
32+
const children = node?.children?.slice(title ? 1 : 0);
33+
const body = children ? all({ type: 'root', children }, opts) : '';
34+
35+
return [icon, ' ', title, title && body && ': ', body].filter(Boolean).join('');
36+
}
37+
case 'readme-glossary-item': {
38+
return node.properties.term;
39+
}
40+
case 'readme-variable': {
41+
const key = node.properties.variable.toString();
42+
const val = opts.variables[key];
43+
return val || `<<${key}>>`;
44+
}
45+
case 'img': {
46+
return node.properties?.title || '';
47+
}
48+
case 'Accordion':
49+
case 'Card':
50+
case 'Tab': {
51+
const title = node.properties?.title || '';
52+
const children = node?.children;
53+
const body = children ? all({ type: 'root', children }, opts) : '';
54+
55+
return [title, body].filter(Boolean).join(' ');
56+
}
5057
}
5158
}
5259

processor/transform/index.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,26 @@ import embedTransformer from './embeds';
44
import imageTransformer from './images';
55
import gemojiTransformer from './gemoji+';
66

7+
import compatabilityTransfomer from './compatability';
78
import divTransformer from './div';
89
import injectComponents from './inject-components';
10+
import mdxToHast from './mdx-to-hast';
11+
import mermaidTransformer from './mermaid';
912
import readmeComponentsTransformer from './readme-components';
1013
import readmeToMdx from './readme-to-mdx';
11-
import variablesTransformer from './variables';
1214
import tablesToJsx from './tables-to-jsx';
13-
import compatabilityTransfomer from './compatability';
14-
import mermaidTransformer from './mermaid';
15+
import variablesTransformer from './variables';
1516

1617
export {
1718
compatabilityTransfomer,
1819
divTransformer,
20+
injectComponents,
21+
mdxToHast,
22+
mermaidTransformer,
1923
readmeComponentsTransformer,
2024
readmeToMdx,
21-
injectComponents,
22-
variablesTransformer,
2325
tablesToJsx,
24-
mermaidTransformer,
26+
variablesTransformer,
2527
};
2628

2729
export const defaultTransforms = {

processor/transform/mdx-to-hast.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { visit } from 'unist-util-visit';
2+
import { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx';
3+
import { Transform } from 'mdast-util-from-markdown';
4+
import { Parents } from 'mdast';
5+
import { getAttrs, isMDXElement } from '../utils';
6+
import * as Components from '../../components';
7+
8+
const setData = (node: MdxJsxFlowElement | MdxJsxTextElement, index: number, parent: Parents) => {
9+
if (!node.name) return;
10+
if (!(node.name in Components)) return;
11+
12+
parent.children[index] = {
13+
...node,
14+
data: {
15+
hName: node.name,
16+
hProperties: getAttrs(node),
17+
},
18+
};
19+
};
20+
21+
const mdxToHast = (): Transform => tree => {
22+
visit(tree, isMDXElement, setData);
23+
24+
return tree;
25+
};
26+
27+
export default mdxToHast;

0 commit comments

Comments
 (0)