{"version":3,"file":"index.cjs","sources":["../../src/vitepress/index.ts"],"sourcesContent":["import type { Nodes } from 'hast'\n\nimport type { HeadConfig, TransformContext } from 'vitepress'\nimport { defu } from 'defu'\nimport { select, selectAll } from 'hast-util-select'\nimport { toText } from 'hast-util-to-text'\nimport RehypeParse from 'rehype-parse'\nimport RetextStringify from 'retext-stringify'\nimport { unified } from 'unified'\nimport { remove } from 'unist-util-remove'\nimport { removePosition } from 'unist-util-remove-position'\n\nfunction RehypeRetext(option: { selector: string, removeSelectors: string[] }): (tree: Nodes) => void {\n  return (nodes) => {\n    const vpDocElement = select(option.selector, nodes)\n    if (!vpDocElement)\n      return\n    if (vpDocElement.children.length === 0)\n      return\n\n    for (const selector of option.removeSelectors) {\n      const elements = selectAll(selector, vpDocElement)\n      if (elements)\n        remove(vpDocElement, elements)\n    }\n\n    removePosition(vpDocElement)\n    if (nodes.type !== 'root' && nodes.type !== 'element')\n      return\n\n    const text = toText(vpDocElement)\n      .replaceAll(/(\\n){2,}/g, ' ')\n\n    nodes.children = [{ type: 'text', value: text }]\n  }\n}\n\ninterface TransformHeadMetaOptions {\n  /**\n   * Max length of the excerpt in characters for the meta description.\n   *\n   * @default 200\n   */\n  length?: number\n  /**\n   * CSS selector for the content element.\n   *\n   * @default '#VPContent div.content main .vp-doc div'\n   */\n  contentSelector?: string\n  /**\n   * CSS selector for the content element to remove.\n   *\n   * @default ['h1','.nolebase-page-properties-container']\n   */\n  removeContentSelector?: string[]\n  /**\n   * Whether to use the tagline from the frontmatter for the home layout.\n   */\n  useTaglineForHomeLayout?: boolean\n  /**\n   * Handle the excerpt before adding it to the head.\n   */\n  handleExcerpt?: (excerpt: string, context: Readonly<TransformContext>) => Promise<string>\n}\n\nfunction getMeta(head: HeadConfig[], fromKey: string, withValue: string): HeadConfig | undefined {\n  return head.find(([key, attrs]) => key === 'meta' && attrs[fromKey] === withValue)\n}\n\nfunction updateMetaOrCreateMeta(head: HeadConfig[], fromKey: string, withValue: string, asContent: string): HeadConfig[] {\n  const meta = head.find(([key, attrs]) => key === 'meta' && attrs[fromKey] === withValue)\n  if (meta) {\n    meta[1].content = asContent\n    return head\n  }\n\n  head.push(['meta', { [fromKey]: withValue, content: asContent }])\n  return head\n}\n\nexport function transformHeadMeta(options?: TransformHeadMetaOptions): (head: HeadConfig[], context: Readonly<TransformContext>) => Promise<HeadConfig[] | void> {\n  const opts = defu(options, {\n    length: 200,\n    contentSelector: '#VPContent div.content main .vp-doc div',\n    removeContentSelector: [\n      'h1',\n      'h2',\n      'h3',\n      'h4',\n      'h5',\n      'h6',\n      '.vp-nolebase-page-properties-container',\n      '.vp-nolebase-git-changelog-history-container',\n      '.vp-nolebase-git-changelog-contributors-container',\n    ],\n    useTaglineForHomeLayout: true,\n  })\n\n  return async (head: HeadConfig[], context: Readonly<TransformContext>) => {\n    const result = (await unified()\n      .data({ settings: { fragment: true } })\n      .use(RehypeParse)\n      .use(RehypeRetext, {\n        selector: opts.contentSelector,\n        removeSelectors: opts.removeContentSelector,\n      })\n      .use(RetextStringify)\n      .process(context.content))\n      .toString()\n\n    let excerpt = result.slice(0, opts.length).trim()\n    // if result is longer than 200 characters, add ellipsis\n    if (result.length > opts.length)\n      excerpt += '...'\n\n    if (context.pageData.frontmatter?.layout === 'home' && opts.useTaglineForHomeLayout)\n      excerpt = context.pageData.frontmatter?.hero?.tagline ?? context.siteConfig.site.description\n    if (opts.handleExcerpt && typeof opts.handleExcerpt === 'function') {\n      const handledResult = opts.handleExcerpt(excerpt, context)\n      if (handledResult && typeof handledResult === 'string')\n        excerpt = handledResult\n      else if (handledResult instanceof Promise)\n        excerpt = await handledResult\n    }\n\n    const ogTitle = getMeta(head, 'property', 'og:title')\n    if (!ogTitle && context.pageData.title)\n      head = updateMetaOrCreateMeta(head, 'property', 'og:title', context.pageData.title)\n\n    head = updateMetaOrCreateMeta(head, 'name', 'description', excerpt)\n    head = updateMetaOrCreateMeta(head, 'property', 'og:description', excerpt)\n    head = updateMetaOrCreateMeta(head, 'property', 'twitter:description', excerpt)\n\n    return head\n  }\n}\n"],"names":["select","selectAll","remove","removePosition","toText","defu","unified","RehypeParse","RetextStringify"],"mappings":";;;;;;;;;;;;;;;;AAYA,SAAS,aAAa,MAAgF,EAAA;AACpG,EAAA,OAAO,CAAC,KAAU,KAAA;AAChB,IAAA,MAAM,YAAe,GAAAA,qBAAA,CAAO,MAAO,CAAA,QAAA,EAAU,KAAK,CAAA;AAClD,IAAA,IAAI,CAAC,YAAA;AACH,MAAA;AACF,IAAI,IAAA,YAAA,CAAa,SAAS,MAAW,KAAA,CAAA;AACnC,MAAA;AAEF,IAAW,KAAA,MAAA,QAAA,IAAY,OAAO,eAAiB,EAAA;AAC7C,MAAM,MAAA,QAAA,GAAWC,wBAAU,CAAA,QAAA,EAAU,YAAY,CAAA;AACjD,MAAI,IAAA,QAAA;AACF,QAAAC,sBAAA,CAAO,cAAc,QAAQ,CAAA;AAAA;AAGjC,IAAAC,sCAAA,CAAe,YAAY,CAAA;AAC3B,IAAA,IAAI,KAAM,CAAA,IAAA,KAAS,MAAU,IAAA,KAAA,CAAM,IAAS,KAAA,SAAA;AAC1C,MAAA;AAEF,IAAA,MAAM,OAAOC,qBAAO,CAAA,YAAY,CAC7B,CAAA,UAAA,CAAW,aAAa,GAAG,CAAA;AAE9B,IAAA,KAAA,CAAM,WAAW,CAAC,EAAE,MAAM,MAAQ,EAAA,KAAA,EAAO,MAAM,CAAA;AAAA,GACjD;AACF;AA+BA,SAAS,OAAA,CAAQ,IAAoB,EAAA,OAAA,EAAiB,SAA2C,EAAA;AAC/F,EAAA,OAAO,IAAK,CAAA,IAAA,CAAK,CAAC,CAAC,GAAK,EAAA,KAAK,CAAM,KAAA,GAAA,KAAQ,MAAU,IAAA,KAAA,CAAM,OAAO,CAAA,KAAM,SAAS,CAAA;AACnF;AAEA,SAAS,sBAAuB,CAAA,IAAA,EAAoB,OAAiB,EAAA,SAAA,EAAmB,SAAiC,EAAA;AACvH,EAAA,MAAM,IAAO,GAAA,IAAA,CAAK,IAAK,CAAA,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,GAAQ,KAAA,MAAA,IAAU,KAAM,CAAA,OAAO,MAAM,SAAS,CAAA;AACvF,EAAA,IAAI,IAAM,EAAA;AACR,IAAK,IAAA,CAAA,CAAC,EAAE,OAAU,GAAA,SAAA;AAClB,IAAO,OAAA,IAAA;AAAA;AAGT,EAAK,IAAA,CAAA,IAAA,CAAK,CAAC,MAAA,EAAQ,EAAE,CAAC,OAAO,GAAG,SAAW,EAAA,OAAA,EAAS,SAAU,EAAC,CAAC,CAAA;AAChE,EAAO,OAAA,IAAA;AACT;AAEO,SAAS,kBAAkB,OAA+H,EAAA;AAC/J,EAAM,MAAA,IAAA,GAAOC,UAAK,OAAS,EAAA;AAAA,IACzB,MAAQ,EAAA,GAAA;AAAA,IACR,eAAiB,EAAA,yCAAA;AAAA,IACjB,qBAAuB,EAAA;AAAA,MACrB,IAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,wCAAA;AAAA,MACA,8CAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,uBAAyB,EAAA;AAAA,GAC1B,CAAA;AAED,EAAO,OAAA,OAAO,MAAoB,OAAwC,KAAA;AACxE,IAAA,MAAM,UAAU,MAAMC,eAAA,EACnB,CAAA,IAAA,CAAK,EAAE,QAAU,EAAA,EAAE,QAAU,EAAA,IAAA,IAAQ,CAAA,CACrC,IAAIC,oBAAW,CAAA,CACf,IAAI,YAAc,EAAA;AAAA,MACjB,UAAU,IAAK,CAAA,eAAA;AAAA,MACf,iBAAiB,IAAK,CAAA;AAAA,KACvB,EACA,GAAI,CAAAC,wBAAe,EACnB,OAAQ,CAAA,OAAA,CAAQ,OAAO,CAAA,EACvB,QAAS,EAAA;AAEZ,IAAA,IAAI,UAAU,MAAO,CAAA,KAAA,CAAM,GAAG,IAAK,CAAA,MAAM,EAAE,IAAK,EAAA;AAEhD,IAAI,IAAA,MAAA,CAAO,SAAS,IAAK,CAAA,MAAA;AACvB,MAAW,OAAA,IAAA,KAAA;AAEb,IAAA,IAAI,OAAQ,CAAA,QAAA,CAAS,WAAa,EAAA,MAAA,KAAW,UAAU,IAAK,CAAA,uBAAA;AAC1D,MAAA,OAAA,GAAU,QAAQ,QAAS,CAAA,WAAA,EAAa,MAAM,OAAW,IAAA,OAAA,CAAQ,WAAW,IAAK,CAAA,WAAA;AACnF,IAAA,IAAI,IAAK,CAAA,aAAA,IAAiB,OAAO,IAAA,CAAK,kBAAkB,UAAY,EAAA;AAClE,MAAA,MAAM,aAAgB,GAAA,IAAA,CAAK,aAAc,CAAA,OAAA,EAAS,OAAO,CAAA;AACzD,MAAI,IAAA,aAAA,IAAiB,OAAO,aAAkB,KAAA,QAAA;AAC5C,QAAU,OAAA,GAAA,aAAA;AAAA,WAAA,IACH,aAAyB,YAAA,OAAA;AAChC,QAAA,OAAA,GAAU,MAAM,aAAA;AAAA;AAGpB,IAAA,MAAM,OAAU,GAAA,OAAA,CAAQ,IAAM,EAAA,UAAA,EAAY,UAAU,CAAA;AACpD,IAAI,IAAA,CAAC,OAAW,IAAA,OAAA,CAAQ,QAAS,CAAA,KAAA;AAC/B,MAAA,IAAA,GAAO,uBAAuB,IAAM,EAAA,UAAA,EAAY,UAAY,EAAA,OAAA,CAAQ,SAAS,KAAK,CAAA;AAEpF,IAAA,IAAA,GAAO,sBAAuB,CAAA,IAAA,EAAM,MAAQ,EAAA,aAAA,EAAe,OAAO,CAAA;AAClE,IAAA,IAAA,GAAO,sBAAuB,CAAA,IAAA,EAAM,UAAY,EAAA,gBAAA,EAAkB,OAAO,CAAA;AACzE,IAAA,IAAA,GAAO,sBAAuB,CAAA,IAAA,EAAM,UAAY,EAAA,qBAAA,EAAuB,OAAO,CAAA;AAE9E,IAAO,OAAA,IAAA;AAAA,GACT;AACF;;;;"}