{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/plugins/shiki/index.ts"],"sourcesContent":["import { Paragraph, TextRun } from \"docx\";\nimport type { RemarkDocxPlugin } from \"../../types\";\nimport {\n  createHighlighter,\n  type BundledLanguage,\n  type BundledTheme,\n} from \"shiki\";\nimport { visit } from \"unist-util-visit\";\nimport type { FontStyle } from \"shiki/textmate\";\nimport { warnOnce } from \"../../utils\";\n\n/**\n * Format to 6 disit hex\n */\nconst formatHex = (str: string): string => {\n  // #RGB\n  if (str.length === 4) {\n    const r = str[1]!;\n    const g = str[2]!;\n    const b = str[3]!;\n    return str[0]! + r + r + g + g + b + b;\n  }\n  // #RRGGBBAA\n  if (str.length === 9) {\n    return str.slice(0, 7);\n  }\n  return str;\n};\n\nexport interface ShikiPluginOptions {\n  /**\n   * https://shiki.style/themes\n   */\n  theme: BundledTheme;\n}\n\n/**\n * A plugin to render \"code\" nodes, with syntax highlighting powered by shiki.\n */\nexport const shikiPlugin = ({\n  theme,\n}: ShikiPluginOptions): RemarkDocxPlugin => {\n  let highlighter: Awaited<ReturnType<typeof createHighlighter>> | undefined;\n  const langs = new Set<string>();\n  const failedLangs = new Set<string>();\n\n  return async ({ root }) => {\n    const newLangs: string[] = [];\n\n    visit(root, \"code\", ({ lang }) => {\n      if (lang) {\n        if (!langs.has(lang)) {\n          langs.add(lang);\n          newLangs.push(lang);\n        }\n      }\n    });\n\n    if (!highlighter) {\n      highlighter = await createHighlighter({\n        themes: [theme],\n        langs: [],\n      });\n    }\n    await Promise.all(\n      newLangs.map(async (l) => {\n        try {\n          await highlighter!.loadLanguage(l as BundledLanguage);\n        } catch (e) {\n          failedLangs.add(l);\n          warnOnce(String(e));\n        }\n      }),\n    );\n\n    return {\n      code: ({ value, lang }) => {\n        if (!lang || failedLangs.has(lang)) {\n          return null;\n        }\n        const res = highlighter!.codeToTokens(value, {\n          lang: lang as BundledLanguage,\n          theme,\n        });\n        let { bg, fg } = res;\n        if (fg) {\n          fg = formatHex(fg);\n        }\n        if (bg) {\n          bg = formatHex(bg);\n        }\n\n        return res.tokens.map((r) => {\n          return new Paragraph({\n            shading: {\n              type: \"clear\",\n              color: \"auto\",\n              fill: bg,\n            },\n            children: r.map(({ content, bgColor, color, fontStyle }) => {\n              if (color) {\n                color = formatHex(color);\n              }\n              if (bgColor) {\n                bgColor = formatHex(bgColor);\n              }\n              return new TextRun({\n                text: content,\n                color: color ?? fg,\n                shading: bgColor\n                  ? {\n                      type: \"clear\",\n                      color: \"auto\",\n                      fill: bgColor,\n                    }\n                  : undefined,\n                bold: fontStyle === (2 satisfies FontStyle.Bold),\n                italics: fontStyle === (1 satisfies FontStyle.Italic),\n                underline:\n                  fontStyle === (4 satisfies FontStyle.Underline)\n                    ? { type: \"single\", color: fg }\n                    : undefined,\n                strike: fontStyle === (8 satisfies FontStyle.Strikethrough),\n              });\n            }),\n          });\n        });\n      },\n    };\n  };\n};\n"],"mappings":"sLAcA,IAAM,EAAa,GAAwB,CAEzC,GAAI,EAAI,SAAW,EAAG,CACpB,IAAM,EAAI,EAAI,GACR,EAAI,EAAI,GACR,EAAI,EAAI,GACd,OAAO,EAAI,GAAM,EAAI,EAAI,EAAI,EAAI,EAAI,CACvC,CAKA,OAHI,EAAI,SAAW,EACV,EAAI,MAAM,EAAG,CAAC,EAEhB,CACT,EAYa,GAAe,CAC1B,WAC0C,CAC1C,IAAI,EACE,EAAQ,IAAI,IACZ,EAAc,IAAI,IAExB,OAAO,MAAO,CAAE,UAAW,CACzB,IAAM,EAAqB,CAAC,EA4B5B,OA1BA,EAAA,EAAA,OAAM,EAAM,QAAS,CAAE,UAAW,CAC5B,IACG,EAAM,IAAI,CAAI,IACjB,EAAM,IAAI,CAAI,EACd,EAAS,KAAK,CAAI,GAGxB,CAAC,EAED,AACE,IAAc,MAAA,EAAA,EAAA,mBAAwB,CACpC,OAAQ,CAAC,CAAK,EACd,MAAO,CAAC,CACV,CAAC,EAEH,MAAM,QAAQ,IACZ,EAAS,IAAI,KAAO,IAAM,CACxB,GAAI,CACF,MAAM,EAAa,aAAa,CAAoB,CACtD,OAAS,EAAG,CACV,EAAY,IAAI,CAAC,EACjB,EAAA,EAAS,OAAO,CAAC,CAAC,CACpB,CACF,CAAC,CACH,EAEO,CACL,MAAO,CAAE,QAAO,UAAW,CACzB,GAAI,CAAC,GAAQ,EAAY,IAAI,CAAI,EAC/B,OAAO,KAET,IAAM,EAAM,EAAa,aAAa,EAAO,CACrC,OACN,OACF,CAAC,EACG,CAAE,KAAI,MAAO,EAQjB,MAPA,CACE,IAAK,EAAU,CAAE,EAEnB,AACE,IAAK,EAAU,CAAE,EAGZ,EAAI,OAAO,IAAK,GACd,IAAI,EAAA,UAAU,CACnB,QAAS,CACP,KAAM,QACN,MAAO,OACP,KAAM,CACR,EACA,SAAU,EAAE,KAAK,CAAE,UAAS,UAAS,QAAO,gBAC1C,AACE,IAAQ,EAAU,CAAK,EAEzB,AACE,IAAU,EAAU,CAAO,EAEtB,IAAI,EAAA,QAAQ,CACjB,KAAM,EACN,MAAO,GAAS,EAChB,QAAS,EACL,CACE,KAAM,QACN,MAAO,OACP,KAAM,CACR,EACA,IAAA,GACJ,KAAM,IAAe,EACrB,QAAS,IAAe,EACxB,UACE,IAAe,EACX,CAAE,KAAM,SAAU,MAAO,CAAG,EAC5B,IAAA,GACN,OAAQ,IAAe,CACzB,CAAC,EACF,CACH,CAAC,CACF,CACH,CACF,CACF,CACF"}