mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
252 lines
5.9 KiB
TypeScript
252 lines
5.9 KiB
TypeScript
import type {
|
|
AttributeInterface,
|
|
ClassInterface,
|
|
DocstringSection,
|
|
FunctionInterface,
|
|
ModuleInterface,
|
|
ParameterInterface,
|
|
} from '@/generated';
|
|
|
|
export type OutputFile = {
|
|
path: string;
|
|
frontmatter: Record<string, unknown>;
|
|
content: string;
|
|
};
|
|
|
|
export interface ConvertOptions {
|
|
baseUrl?: string;
|
|
}
|
|
|
|
export function convert(mod: ModuleInterface, options: ConvertOptions = {}): OutputFile[] {
|
|
const files: OutputFile[] = [];
|
|
const content: string[] = [];
|
|
const tabs: string[] = [];
|
|
const tabContents: string[] = [];
|
|
|
|
if (mod.description) content.push(encodeText(mod.description));
|
|
for (const attr of mod.attributes) {
|
|
content.push(convertAttribute(attr));
|
|
}
|
|
|
|
if (Object.keys(mod.classes).length > 0) {
|
|
tabs.push('Class');
|
|
const lines: string[] = [];
|
|
for (const cls of Object.values(mod.classes)) {
|
|
files.push(...convertClass(cls));
|
|
|
|
lines.push(
|
|
element('Card', {
|
|
title: cls.name,
|
|
href: getHref(cls, options),
|
|
}),
|
|
);
|
|
}
|
|
|
|
tabContents.push(element('Cards', undefined, lines.join('\n')));
|
|
}
|
|
|
|
if (Object.keys(mod.functions).length > 0) {
|
|
tabs.push('Functions');
|
|
const lines: string[] = [];
|
|
for (const func of Object.values(mod.functions)) {
|
|
lines.push(convertFunction(func));
|
|
}
|
|
tabContents.push(lines.join('\n'));
|
|
}
|
|
|
|
if (Object.keys(mod.modules).length > 0) {
|
|
tabs.push('Modules');
|
|
const lines: string[] = [];
|
|
for (const submod of Object.values(mod.modules)) {
|
|
files.push(...convert(submod, options));
|
|
|
|
lines.push(
|
|
element('Card', {
|
|
href: getHref(submod, options),
|
|
title: submod.name,
|
|
}),
|
|
);
|
|
}
|
|
tabContents.push(element('Cards', undefined, lines.join('\n')));
|
|
}
|
|
|
|
if (tabs.length > 0) {
|
|
content.push(
|
|
element(
|
|
'Tabs',
|
|
{
|
|
items: tabs,
|
|
},
|
|
tabContents.map((content, i) => element('Tab', { value: tabs[i] }, content)).join('\n'),
|
|
),
|
|
);
|
|
}
|
|
|
|
files.push({
|
|
path: [...mod.path.split('.'), 'index.mdx'].join('/'),
|
|
frontmatter: {
|
|
title: mod.name,
|
|
},
|
|
content: content.join('\n\n'),
|
|
});
|
|
|
|
return files;
|
|
}
|
|
|
|
function convertClass(cls: ClassInterface): OutputFile[] {
|
|
const content: string[] = [];
|
|
const files: OutputFile[] = [];
|
|
|
|
if (cls.description) content.push(encodeText(cls.description));
|
|
|
|
if (cls.attributes.length > 0) {
|
|
content.push(heading(2, 'Attributes'));
|
|
}
|
|
|
|
for (const attr of cls.attributes) {
|
|
content.push(convertAttribute(attr));
|
|
}
|
|
|
|
if (Object.keys(cls.functions).length > 0) {
|
|
content.push(heading(2, 'Functions'));
|
|
|
|
for (const func of Object.values(cls.functions)) {
|
|
content.push(convertFunction(func));
|
|
}
|
|
}
|
|
|
|
files.push({
|
|
path: cls.path.replaceAll('.', '/') + '.mdx',
|
|
frontmatter: {
|
|
title: cls.name,
|
|
},
|
|
content: content.join('\n\n'),
|
|
});
|
|
return files;
|
|
}
|
|
|
|
function convertFunction(func: FunctionInterface) {
|
|
return element(
|
|
'PyFunction',
|
|
{
|
|
name: func.name,
|
|
type: func.signature,
|
|
},
|
|
[
|
|
func.description ? encodeText(func.description) : null,
|
|
convertDoc(func.docstring ?? []),
|
|
func.source.length > 0
|
|
? element('PySourceCode', undefined, codeblock('python', func.source))
|
|
: null,
|
|
func.parameters.length > 0
|
|
? element('div', undefined, func.parameters.map(convertParameter).join('\n'))
|
|
: null,
|
|
element(
|
|
'PyFunctionReturn',
|
|
{
|
|
type: func.returns.annotation,
|
|
},
|
|
[func.returns.description ? encodeText(func.returns.description) : null]
|
|
.filter(Boolean)
|
|
.join('\n'),
|
|
),
|
|
]
|
|
.filter(Boolean)
|
|
.join('\n\n'),
|
|
);
|
|
}
|
|
|
|
function convertParameter(param: ParameterInterface) {
|
|
const lines: string[] = [];
|
|
if (param.description)
|
|
lines.push(
|
|
typeof param.description === 'string' ? param.description : convertDoc(param.description),
|
|
);
|
|
|
|
return element(
|
|
'PyParameter',
|
|
{ name: param.name, type: param.annotation, value: param.value },
|
|
lines.join('\n'),
|
|
);
|
|
}
|
|
|
|
function convertAttribute(attribute: AttributeInterface) {
|
|
return element(
|
|
'PyAttribute',
|
|
{
|
|
name: attribute.name,
|
|
type: attribute.annotation,
|
|
value: attribute.value,
|
|
},
|
|
[attribute.description ? convertDoc(attribute.description) : null].filter(Boolean).join('\n'),
|
|
);
|
|
}
|
|
|
|
function convertDoc(docstring: DocstringSection[]) {
|
|
const lines: string[] = [];
|
|
for (const item of docstring) {
|
|
if (item.kind === 'text') {
|
|
lines.push(encodeText(item.value as string));
|
|
}
|
|
|
|
if (item.kind === 'admonition') {
|
|
const value = item.value as { annotation: string; description: string };
|
|
lines.push(
|
|
element(
|
|
'Callout',
|
|
{
|
|
title: item.title,
|
|
type: value.annotation,
|
|
},
|
|
encodeText(item.value.description),
|
|
),
|
|
);
|
|
}
|
|
if (item.kind === 'code') {
|
|
console.log(item.value);
|
|
}
|
|
}
|
|
|
|
return lines.join('\n\n');
|
|
}
|
|
|
|
function heading(depth: number, content: string) {
|
|
return ['#'.repeat(depth), content].join(' ');
|
|
}
|
|
|
|
function codeblock(meta: string, code: string) {
|
|
const delimit = '```';
|
|
return `${delimit}${meta}\n${code.replaceAll(delimit, '\\' + delimit)}\n${delimit}`;
|
|
}
|
|
|
|
function element(name: string, props: Record<string, unknown> = {}, children?: string) {
|
|
const propsStr: string[] = [];
|
|
for (const key in props) {
|
|
propsStr.push(`${key}={${JSON.stringify(props[key])}}`);
|
|
}
|
|
|
|
if (children)
|
|
return `<${name} ${propsStr.join(' ')}>
|
|
|
|
${children}
|
|
|
|
</${name}>`;
|
|
|
|
return `<${name} ${propsStr.join(' ')} />`;
|
|
}
|
|
|
|
function getHref(
|
|
ele: ModuleInterface | FunctionInterface | ClassInterface,
|
|
options: ConvertOptions,
|
|
) {
|
|
const { baseUrl = '/' } = options;
|
|
|
|
return (
|
|
'/' + [...baseUrl.split('/'), ...ele.path.split('.')].filter((v) => v.length > 0).join('/')
|
|
);
|
|
}
|
|
|
|
function encodeText(v: string) {
|
|
return v.replaceAll('<', '\\<').replaceAll('{', '\\{').replaceAll('}', '\\}');
|
|
}
|