Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix em
  • Loading branch information
kellyjosephprice committed May 28, 2024
commit c6f8bea661d2e77fc59e697adb3c3caed13dbb9a
87 changes: 87 additions & 0 deletions __tests__/transformers/rehype-toc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { compile } from '../../index';
import { h } from 'hastscript';

describe('rehype-toc transformer', () => {
it('parses out a toc with max depth of 2', () => {
const md = `
# Title

## Subheading

### Third

## Second Subheading
`;
const module = compile(md);
// @ts-expect-error
const { ast } = module.data.toc;

const expected = h('ul', undefined, [
h('li', undefined, h('p', undefined, 'Title')),
h(
'li',
undefined,
h(
'ul',
undefined,
h('li', undefined, h('p', undefined, 'Subheading')),
h('li', undefined, h('p', undefined, 'Second Subheading')),
),
),
]);

// @ts-expect-error
expect(ast).toStrictEqualExceptPosition(expected);
});

it('compiles the toc into a vfile', () => {
const md = `
# Title

## Subheading

### Third

## Second Subheading
`;
const module = compile(md);
// @ts-expect-error
const { vfile } = module.data.toc;

// @ts-ignore
expect(vfile.value).toMatch(/use strict/);
});

it.only('parses a toc from components', () => {
const md = `
# Title

<CommonInfo />

## Subheading
`;
const components = {
CommonInfo: compile('## Common Heading'),
};
const module = compile(md, { components });
// @ts-expect-error
const { ast } = module.data.toc;

const expected = h('ul', undefined, [
h('li', undefined, h('p', undefined, 'Title')),
h(
'li',
undefined,
h(
'ul',
undefined,
h('li', undefined, h('p', undefined, 'Common Heading')),
h('li', undefined, h('p', undefined, 'Subheading')),
),
),
]);

// @ts-expect-error
expect(ast).toStrictEqualExceptPosition(expected);
});
});
14 changes: 8 additions & 6 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const compile = (text: string, opts: CompileOpts = {}) => {
'arguments[0].imports.React',
);

console.log(vfile);
return vfile;
};

Expand All @@ -139,19 +140,20 @@ export const run = async (stringOrFile: string | VFileWithToc, _opts: RunOpts =

const file = await exec(vfile);
const Content = file.default;
const { default: Toc } = 'toc' in vfile.data ? await exec(vfile.data.toc) : { default: null };
const { default: Toc } = 'toc' in vfile.data ? await exec(vfile.data.toc.vfile) : { default: null };

return {
default: () => (
<Contexts terms={terms} variables={variables} baseUrl={baseUrl}>
<Content />
</Contexts>
),
toc: () => (
<Components.TableOfContents>
<Toc />
</Components.TableOfContents>
),
toc: () =>
Toc && (
<Components.TableOfContents>
<Toc />
</Components.TableOfContents>
),
};
};

Expand Down
19 changes: 8 additions & 11 deletions processor/transform/rehype-toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@ import { Transformer } from 'unified';
import { Root, Element } from 'hast';

import { h } from 'hastscript';
import { CompiledComponents, VFileWithToc } from '../../types';
import { MdxJsxFlowElement } from 'mdast-util-mdx';

type Heading = Element & {
tagName: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
};
import { CompiledComponents, HastHeading, VFileWithToc } from '../../types';

const MAX_DEPTH = 2;
const getDepth = (el: Heading) => parseInt(el.tagName.match(/^h(\d)/)[1]);
const getDepth = (el: HastHeading) => parseInt(el.tagName.match(/^h(\d)/)[1]);

interface Options {
components?: CompiledComponents;
}

const rehypeToc = ({ components }: Options): Transformer<Root, Root> => {
const rehypeToc = ({ components = {} }: Options): Transformer<Root, Root> => {
return (tree: Root, file: VFileWithToc): void => {
file.data.toc = {};

const headings = tree.children
.filter(
child =>
Expand All @@ -26,11 +23,11 @@ const rehypeToc = ({ components }: Options): Transformer<Root, Root> => {
)
.flatMap(node =>
node.type === 'mdxJsxFlowElement' ? components[node.name].data.toc.headings : node,
) as Heading[];
) as HastHeading[];

if (!headings.length) return;
file.data.toc.headings = headings;

file.data.toc = { headings };
if (!headings.length) return;

const min = Math.min(...headings.map(getDepth));
const ast = h('ul');
Expand Down
13 changes: 8 additions & 5 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,19 @@ declare module 'mdast' {
}
}

type HastHeading = Element & {
tagName: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
depth: number;
};

type VFileWithToc = VFile & {
data: VFile['data'] & {
toc?: {
ast?: Root;
ast?: Root | Element;
vfile?: VFile;
heainds?: Heading[];
headings?: HastHeading[];
};
};
};

interface CompiledComponents {
components: Record<string, VFileWithToc>;
}
interface CompiledComponents extends Record<string, VFileWithToc> {}