Skip to content

Commit

Permalink
feat: docusaurus v3
Browse files Browse the repository at this point in the history
  • Loading branch information
Airkro committed Nov 16, 2023
1 parent bc06068 commit 303af06
Show file tree
Hide file tree
Showing 21 changed files with 2,890 additions and 530 deletions.
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module.exports = async () => {
'classic',
{
docs: {
remarkPlugins: [autoTabs, docCardList]
beforeDefaultRemarkPlugins: [autoTabs, docCardList]
}
}
]
Expand All @@ -42,11 +42,12 @@ module.exports = async () => {

### DocCardList

#### Options.placeholder
#### Options.version

- type: `string`
- minLength: 5
- default: `:docusaurus-doc-card-list`
- type: `integer`
- enum: [2, 3]
- default: 2
- description: Docusaurus version

Turn:

Expand Down Expand Up @@ -78,6 +79,13 @@ foo bar
- default: {}
- description: Will merge with default presets

#### Options.version

- type: `integer`
- enum: [2, 3]
- default: 2
- description: Docusaurus version

Turn:

````markdown
Expand All @@ -102,7 +110,7 @@ import TabItem from '@theme/TabItem';

## Tips

This plugin only compatible with `remark@^12` / `remark-mdx@1` or `docusaurus@2`.
This plugin only compatible with `docusaurus@2/remark@^12/mdx@1` and `docusaurus@3/remark@^13+/mdx@3+`.

## Related

Expand Down
207 changes: 171 additions & 36 deletions lib/auto-tabs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@ function isTab({ type, meta }, _, parent) {
);
}

function needImport(nodes, text) {
function matchStatement(value, target) {
return value === target || value === target.replaceAll("'", '"');
}

function needImport(version, nodes, target) {
return !nodes.some(
({ type, value }) => type === 'import' && value.includes(text),
({ type, value }) =>
(version === 2 ? type === 'import' : type === 'mdxjsEsm') &&
matchStatement(value, target),
);
}

function importStatement(value) {
return { type: 'import', value };
function importStatement(version, value, data) {
return version === 2
? { type: 'import', value }
: { type: 'mdxjsEsm', value, data };
}

const presets = {
Expand All @@ -29,8 +37,40 @@ const presets = {
yaml: 'YAML',
yml: 'YAML',
toml: 'TOML',
css: 'CSS',
};

function isEndItem(node, index, parent) {
if (
parent?.type !== 'root' ||
parent?.is === 'Tabs-tag' ||
node.is !== 'TabItem-tag'
) {
return false;
}

const next = parent.children[index + 1];

return !next || next.is !== 'TabItem-tag';
}

function isFirstItem(endIndex) {
return (node, index, parent) => {
if (
index > endIndex ||
parent?.type !== 'root' ||
parent?.is === 'Tabs-tag' ||
node.is !== 'TabItem-tag'
) {
return false;
}

const prev = parent.children[index - 1];

return !prev || prev.is !== 'TabItem-tag';
};
}

function isFirst(node, index, parent) {
if (parent?.type !== 'root') {
return false;
Expand All @@ -51,22 +91,21 @@ function isLast(node, index, parent) {
return false;
}

const prev = parent.children[index + 1];
const next = parent.children[index + 1];

return (
node.is === 'TabItem-end-tag' &&
(prev
? prev.is !== 'TabItem-begin-tag' && prev.is !== 'Tabs-end-tag'
: true)
(!next || (next.is !== 'TabItem-begin-tag' && next.is !== 'Tabs-end-tag'))
);
}

/* eslint-disable no-param-reassign */
export function autoTabs({ labels = {} } = {}) {
export function autoTabs({ labels = {}, version = 2 } = {}) {
assert(
labels && typeof labels === 'object' && !Array.isArray(labels),
new TypeError('`labels` should be object'),
);
assert([2, 3].includes(version), new TypeError('`version` should be 2 or 3'));

const allLabels = { ...presets, ...labels };

Expand All @@ -93,43 +132,139 @@ export function autoTabs({ labels = {} } = {}) {

node.meta = stringify(meta);

parent.children.splice(index + 1, 0, {
type: 'jsx',
is: 'TabItem-end-tag',
value: '</TabItem>',
});
if (version === 2) {
parent.children.splice(index + 1, 0, {
type: 'jsx',
is: 'TabItem-end-tag',
value: '</TabItem>',
});

parent.children.splice(index, 0, {
type: 'jsx',
is: 'TabItem-begin-tag',
value: `<TabItem label="${label}" value="${label}-${lang}">`,
});
parent.children.splice(index, 0, {
type: 'jsx',
is: 'TabItem-begin-tag',
value: `<TabItem label="${label}" value="${label}-${lang}">`,
});
} else {
parent.children[index] = {
type: 'mdxJsxFlowElement',
name: 'TabItem',
is: 'TabItem-tag',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'label',
value: label,
},
{
type: 'mdxJsxAttribute',
name: 'value',
value: `tab-${label}-${lang}`,
},
],
children: [
{ type: 'text', value: '' },
node,
{ type: 'text', value: '' },
],
};
}
});

visit(tree, isFirst, (node, index, parent) => {
haveTabs = true;
parent.children.splice(index, 0, {
type: 'jsx',
is: 'Tabs-begin-tag',
value: '<Tabs>',
if (version === 2) {
visit(tree, isFirst, (node, index, parent) => {
haveTabs = true;
parent.children.splice(index, 0, {
type: 'jsx',
is: 'Tabs-begin-tag',
value: '<Tabs>',
});
});
});

visit(tree, isLast, (node, index, parent) => {
parent.children.splice(index + 1, 0, {
type: 'jsx',
is: 'Tabs-end-tag',
value: '</Tabs>',
visit(tree, isLast, (node, index, parent) => {
parent.children.splice(index + 1, 0, {
type: 'jsx',
is: 'Tabs-end-tag',
value: '</Tabs>',
});
});
});
} else {
visit(tree, isEndItem, (node, endIndex, parent) => {
haveTabs = true;

if (haveTabs && needImport(tree.children, '@theme/Tabs')) {
tree.children.unshift(importStatement("import Tabs from '@theme/Tabs'"));
visit(tree, isFirstItem(endIndex), (_, startIndex) => {
const io = parent.children.splice(
startIndex,
endIndex - startIndex + 1,
);

parent.children.splice(startIndex, 0, {
type: 'mdxJsxFlowElement',
name: 'Tabs',
is: 'Tabs-tag',
children: io,
});
});
});
}

if (haveTabs && needImport(version, tree.children, '@theme/Tabs')) {
tree.children.unshift(
importStatement(version, "import Tabs from '@theme/Tabs';", {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'Tabs',
},
},
],
source: {
type: 'Literal',
value: '@theme/Tabs',
raw: "'@theme/Tabs'",
},
},
],
sourceType: 'module',
comments: [],
},
}),
);
}

if (haveTabItem && needImport(tree.children, '@theme/TabItem')) {
if (haveTabItem && needImport(version, tree.children, '@theme/TabItem')) {
tree.children.unshift(
importStatement("import TabItem from '@theme/TabItem';"),
importStatement(version, "import TabItem from '@theme/TabItem';", {
estree: {
type: 'Program',
body: [
{
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'TabItem',
},
},
],
source: {
type: 'Literal',
value: '@theme/TabItem',
raw: "'@theme/TabItem'",
},
},
],
sourceType: 'module',
},
}),
);
}
};
Expand Down
Loading

0 comments on commit 303af06

Please sign in to comment.