UNPKG

remark-docx

Version:

remark plugin to compile markdown to docx (Microsoft Word, Office Open XML).

1 lines 6.44 kB
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/plugins/latex/index.ts"],"sourcesContent":["import type { RemarkDocxPlugin } from \"../../types\";\nimport { Paragraph, XmlAttributeComponent, XmlComponent } from \"docx\";\nimport { mml2omml } from \"mathml2omml\";\nimport { XMLParser } from \"fast-xml-parser\";\nimport { mathjax } from \"@mathjax/src/js/mathjax.js\";\nimport { TeX } from \"@mathjax/src/js/input/tex.js\";\nimport { SerializedMmlVisitor } from \"@mathjax/src/js/core/MmlTree/SerializedMmlVisitor.js\";\nimport { STATE } from \"@mathjax/src/js/core/MathItem.js\";\nimport { liteAdaptor } from \"@mathjax/src/js/adaptors/liteAdaptor.js\";\nimport { RegisterHTMLHandler } from \"@mathjax/src/js/handlers/html.js\";\n// import { source } from \"@mathjax/src/components/js/source.js\";\nimport { Loader } from \"@mathjax/src/js/components/loader.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/noerrors/noerrors.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/ams/ams.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/boldsymbol/boldsymbol.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/newcommand/newcommand.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/textmacros/textmacros.js\";\nimport \"@mathjax/src/components/js/input/tex/extensions/unicode/unicode.js\";\n\n// https://devblogs.microsoft.com/math-in-office/officemath/\n\nclass MathAttributeComponent extends XmlAttributeComponent<\n Record<string, any>\n> {}\n\nclass MathXmlComponent extends XmlComponent {\n constructor(\n rootKey: string,\n children: (MathXmlComponent | string)[],\n attrs?: Record<string, any>,\n ) {\n super(rootKey);\n if (attrs) {\n const mathAttrs: Record<string, any> = {};\n for (const [k, v] of Object.entries(attrs)) {\n if (k.startsWith(\"m:\")) {\n mathAttrs[k] = v;\n }\n }\n this.root.push(new MathAttributeComponent(mathAttrs));\n }\n if (children.length) {\n this.root.push(...children);\n }\n }\n}\n\ninterface XmlText {\n \"#text\": string | number | boolean;\n}\ninterface XmlAttr {\n [key: string]: string | number | boolean;\n}\ninterface XmlElement {\n [key: string]: typeof key extends \":@\" ? XmlAttr : XmlNode[];\n}\ntype XmlNode = XmlElement | XmlText;\n\nconst isXmlText = (o: XmlNode): o is XmlText => \"#text\" in o;\n\nconst buildElement = (o: XmlElement): XmlComponent | null => {\n const attrs = o[\":@\"];\n let tagName = \"\";\n let children: XmlNode[] | undefined;\n for (const k of Object.keys(o)) {\n if (k !== \":@\") {\n tagName = k;\n children = o[k];\n break;\n }\n }\n\n if (tagName.startsWith(\"m:\")) {\n const mathChildren: (MathXmlComponent | string)[] = [];\n for (const n of children ?? []) {\n if (isXmlText(n)) {\n const text = n[\"#text\"];\n mathChildren.push(String(text));\n } else {\n const c = buildElement(n);\n if (c) {\n mathChildren.push(c);\n }\n }\n }\n return new MathXmlComponent(tagName, mathChildren, attrs);\n }\n\n return null;\n};\n\n/**\n * A plugin to render LaTeX inside \"math\" and \"inlineMath\" nodes\n */\nexport const latexPlugin = (): RemarkDocxPlugin => {\n // https://github.com/mathjax/MathJax-demos-node/blob/master/mjs/mixed/tex2mml\n // https://github.com/mathjax/MathJax-src/blob/master/components/mjs/input/tex/tex.js\n // https://github.com/mathjax/MathJax-src/blob/master/ts/components/startup.ts#L490\n // https://github.com/mathjax/MathJax-src/blob/master/testsuite/src/setupTex.ts#L162\n RegisterHTMLHandler(liteAdaptor() as any);\n\n const load = [\n \"[tex]/noerrors\",\n \"[tex]/ams\",\n \"[tex]/newcommand\",\n \"[tex]/boldsymbol\",\n \"[tex]/textmacros\",\n \"[tex]/unicode\",\n ];\n const packages = [\"base\"].concat(load.map((name) => name.slice(6)));\n Loader.preLoaded(...load);\n\n const tex = new TeX({ packages });\n const doc = mathjax.document(\"\", { InputJax: tex });\n const visitor = new SerializedMmlVisitor();\n\n const parser = new XMLParser({\n ignoreAttributes: false,\n preserveOrder: true,\n attributeNamePrefix: \"\",\n });\n\n const parseLatex = (value: string): XmlComponent | null => {\n const node = doc.convert(value, { end: STATE[\"CONVERT\"] });\n const mathml = visitor.visitTree(node);\n const omml = mml2omml(mathml);\n const obj = parser.parse(omml);\n return buildElement(obj[0]);\n };\n\n return async () => {\n return {\n math: ({ value }) => {\n const math = parseLatex(value);\n if (!math) {\n return null;\n }\n return new Paragraph({\n children: [math],\n });\n },\n inlineMath: ({ value }) => {\n return parseLatex(value);\n },\n };\n };\n};\n"],"mappings":"s8BAqBA,IAAM,EAAN,cAAqC,EAAA,qBAEnC,CAAC,EAEG,EAAN,cAA+B,EAAA,YAAa,CAC1C,YACE,EACA,EACA,EACA,CAEA,GADA,MAAM,CAAO,EACT,EAAO,CACT,IAAM,EAAiC,CAAC,EACxC,IAAK,GAAM,CAAC,EAAG,KAAM,OAAO,QAAQ,CAAK,EACnC,EAAE,WAAW,IAAI,IACnB,EAAU,GAAK,GAGnB,KAAK,KAAK,KAAK,IAAI,EAAuB,CAAS,CAAC,CACtD,CACI,EAAS,QACX,KAAK,KAAK,KAAK,GAAG,CAAQ,CAE9B,CACF,EAaM,EAAa,GAA6B,UAAW,EAErD,EAAgB,GAAuC,CAC3D,IAAM,EAAQ,EAAE,MACZ,EAAU,GACV,EACJ,IAAK,IAAM,KAAK,OAAO,KAAK,CAAC,EAC3B,GAAI,IAAM,KAAM,CACd,EAAU,EACV,EAAW,EAAE,GACb,KACF,CAGF,GAAI,EAAQ,WAAW,IAAI,EAAG,CAC5B,IAAM,EAA8C,CAAC,EACrD,IAAK,IAAM,KAAK,GAAY,CAAC,EAC3B,GAAI,EAAU,CAAC,EAAG,CAChB,IAAM,EAAO,EAAE,SACf,EAAa,KAAK,OAAO,CAAI,CAAC,CAChC,KAAO,CACL,IAAM,EAAI,EAAa,CAAC,EACpB,GACF,EAAa,KAAK,CAAC,CAEvB,CAEF,OAAO,IAAI,EAAiB,EAAS,EAAc,CAAK,CAC1D,CAEA,OAAO,IACT,EAKa,MAAsC,EAKjD,EAAA,EAAA,sBAAA,EAAA,EAAA,aAAgC,CAAQ,EAExC,IAAM,EAAO,CACX,iBACA,YACA,mBACA,mBACA,mBACA,eACF,EACM,EAAW,CAAC,MAAM,EAAE,OAAO,EAAK,IAAK,GAAS,EAAK,MAAM,CAAC,CAAC,CAAC,EAClE,EAAA,OAAO,UAAU,GAAG,CAAI,EAExB,IAAM,EAAM,IAAI,EAAA,IAAI,CAAE,UAAS,CAAC,EAC1B,EAAM,EAAA,QAAQ,SAAS,GAAI,CAAE,SAAU,CAAI,CAAC,EAC5C,EAAU,IAAI,EAAA,qBAEd,EAAS,IAAI,EAAA,UAAU,CAC3B,iBAAkB,GAClB,cAAe,GACf,oBAAqB,EACvB,CAAC,EAEK,EAAc,GAAuC,CACzD,IAAM,EAAO,EAAI,QAAQ,EAAO,CAAE,IAAK,EAAA,MAAM,OAAW,CAAC,EAEnD,GAAA,EAAA,EAAA,UADS,EAAQ,UAAU,CACX,CAAM,EAE5B,OAAO,EADK,EAAO,MAAM,CACL,EAAI,EAAE,CAC5B,EAEA,OAAO,UACE,CACL,MAAO,CAAE,WAAY,CACnB,IAAM,EAAO,EAAW,CAAK,EAI7B,OAHK,EAGE,IAAI,EAAA,UAAU,CACnB,SAAU,CAAC,CAAI,CACjB,CAAC,EAJQ,IAKX,EACA,YAAa,CAAE,WACN,EAAW,CAAK,CAE3B,EAEJ"}