Skip to content

Commit

Permalink
Refactor htmlToMd.ts: Split prepareHandlers function (Qiskit#943)
Browse files Browse the repository at this point in the history
Part of Qiskit#845

This PR refactors the `htmlToMd.ts` script. It splits the
`prepareHandlers` function into some helper functions to simplify the
logic and improve the readability.
  • Loading branch information
arnaucasau authored Mar 1, 2024
1 parent e497785 commit 27f8821
Showing 1 changed file with 95 additions and 68 deletions.
163 changes: 95 additions & 68 deletions scripts/lib/api/htmlToMd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import rehypeRemark from "rehype-remark";
import remarkStringify from "remark-stringify";
import remarkGfm from "remark-gfm";
import { last, first, without, initial, tail } from "lodash";
import { defaultHandlers, Handle, toMdast, all } from "hast-util-to-mdast";
import { defaultHandlers, Handle, toMdast, all, H } from "hast-util-to-mdast";
import { toText } from "hast-util-to-text";
import remarkMath from "remark-math";
import remarkMdx from "remark-mdx";
import { MdxJsxFlowElement } from "mdast-util-mdx-jsx";
import { visit } from "unist-util-visit";
import { Emphasis, Root } from "mdast";
import { Emphasis, Root, Content } from "mdast";

import { processHtml } from "./processHtml";
import { HtmlToMdResult } from "./HtmlToMdResult";
Expand Down Expand Up @@ -102,14 +102,14 @@ function prepareHandlers(meta: Metadata): Record<string, Handle> {
return buildMathExpression(node, "inlineMath");
}

if (node.properties.id && node.properties.className?.includes("target")) {
if (
node.properties.id &&
(node.properties.className?.includes("target") ||
node.children.length === 0)
) {
return [buildSpanId(node.properties.id), ...all(h, node)];
}

if (node.properties.id && node.children.length === 0) {
return buildSpanId(node.properties.id);
}

return all(h, node);
},
pre(h, node: any) {
Expand All @@ -125,65 +125,16 @@ function prepareHandlers(meta: Metadata): Record<string, Handle> {
return defaultHandlers.div(h, node);
},
dt(h, node: any) {
if (meta.apiType === "class" || meta.apiType === "module") {
return [
h(node, "strong", {
type: "strong",
children: all(h, node),
}),
{ type: "text", value: " " },
];
}
return h(node, "heading", {
type: "heading",
depth: 2,
children: all(h, node),
});
return buildDt(h, node, meta.apiType);
},
div(h, node: any): any {
const nodeClasses = node.properties.className ?? [];

if (nodeClasses.includes("admonition")) {
const titleNode = node.children.find(
(child: any) =>
child.properties.className?.includes("admonition-title"),
);

let type = "note";
if (nodeClasses.includes("warning")) {
type = "caution";
} else if (nodeClasses.includes("important")) {
type = "danger";
}
return buildAdmonition(node, nodeClasses, handlers);
}

const otherChildren = without(node.children, titleNode);
return buildAdmonition({
title: toText(titleNode),
type,
children: otherChildren.map((node: any) =>
toMdast(node, { handlers }),
),
});
} else if (nodeClasses.includes("deprecated")) {
const root = node.children[0];
const titleNode = root.children.find(
(child: any) =>
child.properties.className?.includes("versionmodified"),
);
const title = toText(titleNode).trim().replace(/:$/, "");
const otherChildren = without(root.children, titleNode);
return buildAdmonition({
title,
type: "danger",
children: [
{
type: "paragraph",
children: otherChildren.map((node: any) =>
toMdast(node, { handlers }),
),
},
],
});
if (nodeClasses.includes("deprecated")) {
return buildDeprecatedAdmonition(node, handlers);
}

return defaultHandlers.div(h, node);
Expand Down Expand Up @@ -224,20 +175,58 @@ function removeEmphasisSpaces(
}
}

function buildAdmonition(options: {
title: string;
type: string;
children: Array<any>;
}): MdxJsxFlowElement {
const { title, type, children } = options;
function findNodeWithProperty(nodeList: any[], propertyName: string) {
return nodeList.find(
(child: any) => child.properties.className?.includes(propertyName),
);
}

function buildDt(
h: H,
node: any,
apiType?: string,
): void | Content | Content[] {
if (apiType === "class" || apiType === "module") {
return [
h(node, "strong", {
type: "strong",
children: all(h, node),
}),
{ type: "text", value: " " },
];
}
return h(node, "heading", {
type: "heading",
depth: 2,
children: all(h, node),
});
}

function buildAdmonition(
node: any,
nodeClasses: string[],
handlers: Record<string, Handle>,
): MdxJsxFlowElement {
const titleNode = findNodeWithProperty(node.children, "admonition-title");
const children: Array<any> = without(node.children, titleNode).map(
(node: any) => toMdast(node, { handlers }),
);

let type = "note";
if (nodeClasses.includes("warning")) {
type = "caution";
} else if (nodeClasses.includes("important")) {
type = "danger";
}

return {
type: "mdxJsxFlowElement",
name: "Admonition",
attributes: [
{
type: "mdxJsxAttribute",
name: "title",
value: title,
value: toText(titleNode),
},
{
type: "mdxJsxAttribute",
Expand All @@ -249,6 +238,44 @@ function buildAdmonition(options: {
};
}

function buildDeprecatedAdmonition(
node: any,
handlers: Record<string, Handle>,
): MdxJsxFlowElement {
const titleNode = findNodeWithProperty(
node.children[0].children,
"versionmodified",
);
const title = toText(titleNode).trim().replace(/:$/, "");
const otherChildren: Array<any> = without(
node.children[0].children,
titleNode,
).map((node: any) => toMdast(node, { handlers }));

return {
type: "mdxJsxFlowElement",
name: "Admonition",
attributes: [
{
type: "mdxJsxAttribute",
name: "title",
value: title,
},
{
type: "mdxJsxAttribute",
name: "type",
value: "danger",
},
],
children: [
{
type: "paragraph",
children: otherChildren,
},
],
};
}

function buildSpanId(id: string): MdxJsxFlowElement {
return {
type: "mdxJsxFlowElement",
Expand Down

0 comments on commit 27f8821

Please sign in to comment.