{"version":3,"file":"generator.mjs","sources":["../../src/regex.js","../../src/parse-citation.js","../../src/utils.js","../../src/html-transform-browser.js","../../src/generator.js","../../src/gen-citation.js","../../src/gen-biblio.js","../../src/gen-footnote.js"],"sourcesContent":["// Regex adapted from https://github.com/Zettlr/Zettlr/blob/develop/source/common/util/extract-citations.ts\n\n/**\n * Citation detection: The first alternative matches \"full\" citations surrounded\n * by square brackets, whereas the second one matches in-text citations,\n * optionally with suffixes.\n *\n * * Group 1 matches regular \"full\" citations\n * * Group 2 matches in-text citations (not surrounded by brackets)\n * * Group 3 matches optional square-brackets suffixes to group 2 matches\n *\n * For more information, see https://pandoc.org/MANUAL.html#extension-citations\n *\n * @var {RegExp}\n */\nexport const citationRE =\n /(?:\\[([^[\\]]*@[^[\\]]+)\\])|(?<=\\s|^|(-))(?:@([\\p{L}\\d_][^\\s]*[\\p{L}\\d_]|\\{.+\\})(?:\\s+\\[(.*?)\\])?)/u\n\n/**\n * I hate everything at this. This can match every single possible variation on\n * whatever the f*** you can possibly do within square brackets according to the\n * documentation. I opted for named groups for these because otherwise I have no\n * idea what I have been doing here.\n *\n * * Group prefix: Contains the prefix, ends with a dash if we should suppress the author\n * * Group citekey: Contains the actual citekey, can be surrounded in curly brackets\n * * Group explicitLocator: Contains an explicit locator statement. If given, we MUST ignore any form of locator in the suffix\n * * Group explicitLocatorInSuffix: Same as above, but not concatenated to the citekey\n * * Group suffix: Contains the suffix, but may start with a locator (if explicitLocator and explicitLocatorInSuffix are not given)\n *\n * @var {RegExp}\n */\nexport const fullCitationRE =\n /(?.+)?(?:@(?[\\p{L}\\d_][^\\s{]*[\\p{L}\\d_]|\\{.+\\}))(?:\\{(?.*)\\})?(?:,\\s+(?:\\{(?.*)\\})?(?.*))?/u\n\n/**\n * This regular expression matches locator ranges, like the following:\n *\n * * 23-45, and further (here it matches up to, not including the comma)\n * * 45\n * * 15423\n * * 14235-12532\n * * 12-34, 23, 56\n * * 12, 23-14, 23\n * * 12, 54, 12-23\n * * 1, 1-4\n * * 3\n * * NEW NEW NEW: Now also matches Roman numerals as sometimes used in forewords!\n *\n * @var {RegExp}\n */\nexport const locatorRE = /^(?:[\\d, -]*\\d|[ivxlcdm, -]*[ivxlcdm])/i\n","/**\n * @typedef {import('./types').CiteItem} CiteItem\n * @typedef {import('./types').CiteItemSuffix} CiteItemSuffix\n */\n\nimport { fullCitationRE, locatorRE } from './regex.js'\n\n/**\n * The locatorLabels have been sourced from the Citr library. Basically it's just\n * a map with valid CSL locator labels and an array of possible natural labels\n * which a user might want to write (instead of the standardized labels).\n *\n * @var {{ [key: string]: string[] }}}\n */\nconst locatorLabels = {\n book: ['Buch', 'Bücher', 'B.', 'book', 'books', 'bk.', 'bks.', 'livre', 'livres', 'liv.'],\n chapter: ['Kapitel', 'Kap.', 'chapter', 'chapters', 'chap.', 'chaps', 'chapitre', 'chapitres'],\n column: ['Spalte', 'Spalten', 'Sp.', 'column', 'columns', 'col.', 'cols', 'colonne', 'colonnes'],\n figure: ['Abbildung', 'Abbildungen', 'Abb.', 'figure', 'figures', 'fig.', 'figs'],\n folio: ['Blatt', 'Blätter', 'Fol.', 'folio', 'folios', 'fol.', 'fols', 'fᵒ', 'fᵒˢ'],\n issue: [\n 'Nummer',\n 'Nummern',\n 'Nr.',\n 'number',\n 'numbers',\n 'no.',\n 'nos.',\n 'numéro',\n 'numéros',\n 'nᵒ',\n 'nᵒˢ',\n ],\n line: ['Zeile', 'Zeilen', 'Z', 'line', 'lines', 'l.', 'll.', 'ligne', 'lignes'],\n note: ['Note', 'Noten', 'N.', 'note', 'notes', 'n.', 'nn.'],\n opus: ['Opus', 'Opera', 'op.', 'opus', 'opera', 'opp.'],\n page: ['Seite', 'Seiten', 'S.', 'page', 'pages', 'p.', 'pp.'],\n paragraph: [\n 'Absatz',\n 'Absätze',\n 'Abs.',\n '¶',\n '¶¶',\n 'paragraph',\n 'paragraphs',\n 'para.',\n 'paras',\n 'paragraphe',\n 'paragraphes',\n 'paragr.',\n ],\n part: ['Teil', 'Teile', 'part', 'parts', 'pt.', 'pts', 'partie', 'parties', 'part.'],\n section: [\n 'Abschnitt',\n 'Abschnitte',\n 'Abschn.',\n '§',\n '§§',\n 'section',\n 'sections',\n 'sec.',\n 'secs',\n 'sect.',\n ],\n 'sub verbo': ['sub verbo', 'sub verbis', 's. v.', 's. vv.', 's.v.', 's.vv.'],\n verse: ['Vers', 'Verse', 'V.', 'verse', 'verses', 'v.', 'vv.', 'verset', 'versets'],\n volume: ['Band', 'Bände', 'Bd.', 'Bde.', 'volume', 'volumes', 'vol.', 'vols.'],\n}\n\n/**\n * Parses a given citation string and return entries and isComposite flag required for cite-proc.\n * Adapted from https://github.com/Zettlr/Zettlr/blob/develop/source/common/util/extract-citations.ts\n *\n * @param {RegExpMatchArray} regexMatch Cite string in the form of '[@item]' or '@item'\n * @return {[CiteItem[], boolean]} [entries, isComposite]\n */\nexport const parseCitation = (regexMatch) => {\n /** @type {CiteItem[]} */\n let entries = []\n let isComposite = false\n const fullCitation = regexMatch[1]\n const inTextSuppressAuthor = regexMatch[2]\n const inTextCitation = regexMatch[3]\n const optionalSuffix = regexMatch[4]\n\n if (fullCitation !== undefined) {\n // Handle citations in the form of [@item1; @item2]\n for (const citationPart of fullCitation.split(';')) {\n const match = fullCitationRE.exec(citationPart.trim())\n if (match === null) {\n continue // Faulty citation\n }\n // Prefix is the portion before @ e.g. [see @item1] or an empty string\n // We explicitly cast groups since we have groups in our RegExp and as\n // such the groups object will be set.\n /** @type {CiteItem} */\n const thisCitation = {\n id: match.groups.citekey.replace(/{(.+)}/, '$1'),\n prefix: undefined,\n locator: undefined,\n label: 'page',\n 'suppress-author': false,\n suffix: undefined,\n }\n\n // First, deal with the prefix. The speciality here is that it can\n // indicate if we should suppress the author.\n const rawPrefix = match.groups.prefix\n if (rawPrefix !== undefined) {\n thisCitation['suppress-author'] = rawPrefix.trim().endsWith('-')\n if (thisCitation['suppress-author']) {\n thisCitation.prefix = rawPrefix.substring(0, rawPrefix.trim().length - 1).trim()\n } else {\n thisCitation.prefix = rawPrefix.trim()\n }\n }\n\n // Second, deal with the suffix. This one can be much more tricky than\n // the prefix. We have three alternatives where the locator may be\n // present: If we have an explicitLocator or an explicitLocatorInSuffix,\n // we should extract the locator from there and leave the actual suffix\n // untouched. Only if those two alternatives are not present, then we\n // have a look at the rawSuffix and extract a (potential) locator.\n const explicitLocator = match.groups.explicitLocator\n const explicitLocatorInSuffix = match.groups.explicitLocatorInSuffix\n const rawSuffix = match.groups.suffix\n\n let suffixToParse\n let containsLocator = true\n if (explicitLocator === undefined && explicitLocatorInSuffix === undefined) {\n // Potential locator in rawSuffix. Only in this case should we overwrite\n // the suffix (hence the same if-condition below)\n suffixToParse = rawSuffix\n containsLocator = false\n } else if (explicitLocatorInSuffix !== undefined || explicitLocator !== undefined) {\n suffixToParse = explicitLocator !== undefined ? explicitLocator : explicitLocatorInSuffix\n thisCitation.suffix = rawSuffix?.trim()\n }\n\n const { label, locator, suffix } = parseSuffix(suffixToParse, containsLocator)\n thisCitation.locator = locator\n\n if (label !== undefined) {\n thisCitation.label = label\n }\n\n if (explicitLocator === undefined && explicitLocatorInSuffix === undefined) {\n thisCitation.suffix = suffix\n } else if (suffix !== undefined && thisCitation.locator !== undefined) {\n // If we're here, we should not change the suffix, but parseSuffix may\n // have put something into the suffix return. If we're here, that will\n // definitely be a part of the locator.\n thisCitation.locator += suffix\n }\n\n entries.push(thisCitation)\n }\n } else {\n // We have an in-text citation, so we can take a shortcut\n isComposite = true\n entries.push({\n prefix: undefined,\n id: inTextCitation.replace(/{(.+)}/, '$1'),\n 'suppress-author': inTextSuppressAuthor !== undefined,\n ...parseSuffix(optionalSuffix, false), // Populate more depending on the suffix\n })\n }\n return [entries, isComposite]\n}\n\n/**\n * This takes a suffix and extracts optional label and locator from this. Pass\n * true for the containsLocator property to indicate to this function that what\n * it got was not a regular suffix with an optional locator, but an explicit\n * locator so it knows it just needs to look for an optional label.\n *\n * @param {string} suffix The suffix to parse\n * @param {boolean} containsLocator If true, forces parseSuffix to return a locator\n *\n * @return {CiteItemSuffix} An object containing three optional properties locator, label, or suffix.\n */\nfunction parseSuffix(suffix, containsLocator) {\n /** @type {CiteItemSuffix} */\n const retValue = {\n locator: undefined,\n label: 'page',\n suffix: undefined,\n }\n\n if (suffix === undefined) {\n return retValue\n }\n\n // Make sure the suffix does not start or end with spaces\n suffix = suffix.trim()\n\n // If there is a label, the suffix must start with it\n for (const label in locatorLabels) {\n for (const natural of locatorLabels[label]) {\n if (suffix.toLowerCase().startsWith(natural.toLowerCase())) {\n retValue.label = label\n if (containsLocator) {\n // The suffix actually is the full locator, we just had to extract\n // the label from it. There is no remaining suffix.\n retValue.locator = suffix.substr(natural.length).trim()\n } else {\n // The caller indicated that this is a regular suffix, so we must also\n // extract the locator from what is left after label extraction.\n retValue.suffix = suffix.substr(natural.length).trim()\n const match = locatorRE.exec(retValue.suffix)\n if (match !== null) {\n retValue.locator = match[0] // Extract the full match\n retValue.suffix = retValue.suffix.substr(match[0].length).trim()\n }\n }\n\n return retValue // Early exit\n }\n }\n }\n\n // If we're here, there was no explicit label given, but the caller has indicated\n // that this suffix MUST contain a locator. This means that the whole suffix is\n // the locator.\n if (containsLocator) {\n retValue.locator = suffix\n } else {\n // The caller has not indicated that the whole suffix is the locator, so it\n // can be at the beginning. We only accept simple page/number ranges here.\n // For everything, the user should please be more specific.\n const match = locatorRE.exec(suffix)\n if (match !== null) {\n retValue.locator = match[0] // Full match is the locator\n retValue.suffix = suffix.substr(match[0].length).trim() // The rest is the suffix.\n }\n }\n\n return retValue\n}\n","import fetch from 'cross-fetch'\n\nexport const isNode = typeof window === 'undefined'\n\nexport const readFile = async (path) => {\n if (isValidHttpUrl(path)) {\n try {\n const response = await fetch(path)\n return await response.text()\n } catch (error) {\n throw new Error(`Cannot fetch bibliography URL: ${error}.`)\n }\n } else {\n if (isNode) {\n try {\n return import('fs').then((fs) => fs.readFileSync(path, 'utf8'))\n } catch (error) {\n throw new Error(`Cannot read non valid URL in node env.`)\n }\n }\n }\n}\n\n/**\n * Check if valid URL\n * https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url\n *\n * @param {string} str\n * @return {boolean}\n */\nexport const isValidHttpUrl = (str) => {\n let url\n\n try {\n url = new URL(str)\n } catch (_) {\n return false\n }\n\n return url.protocol === 'http:' || url.protocol === 'https:' || url.protocol === 'blob:'\n}\n\n/**\n * Get bibliography by merging options and vfile data\n *\n * @param {import('./generator.js').Options} options\n * @param {import('vfile').VFile} file\n */\nexport const getBibliography = async (options, file) => {\n /** @type {string[]} */\n let bibliography = []\n const frontmatterBibliography = getFrontmatterField(file, 'bibliography')\n if (options.bibliography) {\n bibliography =\n typeof options.bibliography === 'string' ? [options.bibliography] : options.bibliography\n } else if (frontmatterBibliography) {\n bibliography =\n typeof frontmatterBibliography === 'string'\n ? [frontmatterBibliography]\n : frontmatterBibliography\n }\n // If local path, get absolute path\n for (let i = 0; i < bibliography.length; i++) {\n if (!isValidHttpUrl(bibliography[i])) {\n // Case options.path is provided and non empty\n if (options.path) {\n // if node env we construct the full path using options.path\n if (isNode) {\n bibliography[i] = await import('path').then((path) =>\n path.join(options.path, bibliography[i])\n )\n // else we throw as it's non valid http url\n } else {\n throw new Error(`Cannot read non valid bibliography URL.`)\n }\n // Case options.path is empt\n } else {\n // if node env we construct the full path using default `process.cwd`\n if (isNode) {\n bibliography[i] = await import('path').then((path) =>\n path.join(file.cwd, bibliography[i])\n )\n // else as it's a non valid http url we throw as a base url must be provided using options.path\n } else {\n throw new Error(\n `Non valid bibliography URL: Provide a full valid path for biblio ${bibliography[i]} or set an appropriate \"options.path\"`\n )\n }\n }\n }\n }\n\n return bibliography\n}\n\n/**\n * Load CSL - supports predefined name from config.templates.data or http, file path (nodejs)\n *\n * @param {*} Cite cite object from citation-js\n * @param {string} format CSL name e.g. apa or file path to CSL file\n * @param {string} root optional root path\n */\nexport const loadCSL = async (Cite, format, root = '') => {\n const config = Cite.plugins.config.get('@csl')\n if (!Object.keys(config.templates.data).includes(format)) {\n const cslName = `customCSL-${Math.random().toString(36).slice(2, 7)}`\n let cslPath = ''\n if (isValidHttpUrl(format)) cslPath = format\n else {\n if (isNode) cslPath = await import('path').then((path) => path.join(root, format))\n }\n try {\n config.templates.add(cslName, await readFile(cslPath))\n } catch (err) {\n throw new Error(`Input CSL option, ${format}, is invalid or is an unknown file.`)\n }\n return cslName\n } else {\n return format\n }\n}\n\n/**\n * Load locale - supports predefined name from config.locales.data or http, file path (nodejs)\n *\n * @param {*} Cite cite object from citation-js\n * @param {string} format locale name\n * @param {string} root optional root path\n */\nexport const loadLocale = async (Cite, format, root = '') => {\n const config = Cite.plugins.config.get('@csl')\n if (!Object.keys(config.locales.data).includes(format)) {\n let localePath = ''\n if (isValidHttpUrl(format)) localePath = format\n else {\n if (isNode) localePath = await import('path').then((path) => path.join(root, format))\n }\n try {\n const file = await readFile(localePath)\n const xmlLangRe = /xml:lang=\"(.+)\"/\n const localeName = file.match(xmlLangRe)[1]\n config.locales.add(localeName, file)\n return localeName\n } catch (err) {\n throw new Error(`Input locale option, ${format}, is invalid or is an unknown file.`)\n }\n } else {\n return format\n }\n}\n\n/**\n * Get citation format\n *\n * @param {*} citeproc citeproc\n * @returns string\n */\nexport const getCitationFormat = (citeproc) => {\n const info = citeproc.cslXml.dataObj.children[0]\n const node = info.children.find((x) => x['attrs'] && x['attrs']['citation-format'])\n // citation-format takes 5 possible values\n // https://docs.citationstyles.org/en/stable/specification.html#toc-entry-14\n /** @type {'author-date' | 'author' | 'numeric' | 'note' | 'label'} */\n const citationFormat = node['attrs']['citation-format']\n return citationFormat\n}\n\n/**\n * Get registry objects that matches a list of relevantIds\n * If sorted is false, retrieve registry item in the order of the given relevantIds\n *\n * @param {*} citeproc citeproc\n * @param {string[]} relevantIds\n * @param {boolean} sorted\n * @return {*} registry objects that matches Ids, in the correct order\n */\nexport const getSortedRelevantRegistryItems = (citeproc, relevantIds, sorted) => {\n const res = []\n if (sorted) {\n // If sorted follow registry order\n for (const item of citeproc.registry.reflist) {\n if (relevantIds.includes(item.id)) res.push(item)\n }\n } else {\n // Otherwise follow the relevantIds\n for (const id of relevantIds) {\n res.push(citeproc.registry.reflist.find((x) => x.id === id))\n }\n }\n return res\n}\n\n/**\n * Split a string into two parts based on a given index position\n *\n * @param {string} str\n * @param {number} index\n * @return {string[]}\n */\nexport const split = (str, index) => {\n return [str.slice(0, index), str.slice(index)]\n}\n\n/**\n * Check if two registry objects belong to the same author\n * Currently only checks on family name\n *\n * @param {*} item registry object\n * @param {*} item2 registry object\n * @return {boolean}\n */\nexport const isSameAuthor = (item, item2) => {\n const authorList = item.ref.author\n const authorList2 = item2.ref.author\n if (authorList.length !== authorList2.length) return false\n for (let i = 0; i < authorList.length; i++) {\n if (authorList[i].family !== authorList2[i].family) return false\n }\n return true\n}\n\n/**\n * @typedef {Object} FrontmatterSource\n * @property {Record} [matter]\n * @property {Record} [frontmatter]\n * @property {{ frontmatter?: Record }} [astro]\n */\n\n/**\n * @param {{ data?: FrontmatterSource }} file\n * @param {string} fieldName\n * @returns {any}\n */\nexport const getFrontmatterField = (file, fieldName) => {\n if (!file || !file.data) {\n return undefined\n }\n\n const sources = [file.data.matter, file.data.frontmatter, file.data.astro?.frontmatter]\n\n for (const source of sources) {\n if (source && fieldName in source) {\n return source[fieldName]\n }\n }\n\n return undefined\n}\n\n/**\n * Get bibliography entry text for a citation ID\n *\n * @param {*} citeproc citeproc engine\n * @param {string} id citation ID\n * @return {string} formatted bibliography entry without HTML tags\n */\nexport const getBibliographyEntryText = (citeproc, id) => {\n try {\n // Save the current state\n const originalItemIds = [...citeproc.registry.mylist]\n\n // Since creating bibliography affects the state we need to save the current state and restore it\n citeproc.updateItems([id])\n const bibOutput = citeproc.makeBibliography([id])\n if (!bibOutput || !bibOutput[1] || bibOutput[1].length === 0) {\n citeproc.updateItems(originalItemIds)\n return ''\n }\n\n // Get the text\n let entryText = bibOutput[1][0].replace(/<[^>]*>/g, '')\n entryText = entryText.replace(/\\s+/g, ' ').trim()\n\n // Restore the original state\n citeproc.updateItems(originalItemIds)\n\n return entryText\n } catch (error) {\n console.error('Error getting bibliography entry text:', error)\n return ''\n }\n}\n","import { fromDom } from 'hast-util-from-dom'\n\n/**\n * Convert HTML to HAST node\n *\n * @param {string} html\n */\nexport const htmlToHast = (html) => {\n const frag = document.createRange().createContextualFragment(html)\n return fromDom(frag).children[0]\n}\n","/**\n * @typedef {import('hast').Node} Node\n * @typedef {import('hast').Parent} Parent\n * @typedef {import('hast').Root} Root\n * @typedef {import('hast').Element} Element\n * @typedef {import('unist-util-visit').Visitor} Visitor\n * @typedef {import('./types').CiteItem} CiteItem\n * @typedef {import('./types').Mode} Mode\n * @typedef {import('./types').Options} Options\n */\n\nimport { visit } from 'unist-util-visit'\nimport fetch from 'cross-fetch'\nimport { parseCitation } from './parse-citation.js'\nimport { genCitation } from './gen-citation.js'\nimport { genBiblioNode } from './gen-biblio.js'\nimport { genFootnoteSection } from './gen-footnote.js'\nimport { citationRE } from './regex.js'\nimport {\n isNode,\n isValidHttpUrl,\n readFile,\n getBibliography,\n loadCSL,\n loadLocale,\n getCitationFormat,\n getFrontmatterField,\n} from './utils.js'\n\nconst defaultCiteFormat = 'apa'\nconst permittedTags = ['div', 'p', 'span', 'li', 'td', 'th']\nconst idRoot = 'CITATION'\n\n/**\n * Rehype plugin that formats citations in markdown documents and insert bibliography in html format\n *\n * [-@wadler1990] --> (1990)\n * [@hughes1989, sec 3.4] --> (Hughes 1989, sec 3.4)\n * [see @wadler1990; and @hughes1989, pp. 4] --> (see Wadler 1990 and Hughes 1989, pp. 4)\n *\n * @param {*} Cite cite object from citation-js configured with the required CSLs\n * @return {import('unified').Plugin<[Options?], Root>}\n */\nconst rehypeCitationGenerator = (Cite) => {\n return (options = {}) => {\n return async (tree, file) => {\n /** @type {string[]} */\n let bibtexFile = []\n const inputCiteformat =\n /** @type {string} */\n options.csl || getFrontmatterField(file, 'csl') || defaultCiteFormat\n const noCite =\n /** @type {string[] | false} */\n options.noCite || getFrontmatterField(file, 'noCite') || false\n const inputLang = options.lang || 'en-US'\n const config = Cite.plugins.config.get('@csl')\n const citeFormat = await loadCSL(Cite, inputCiteformat, options.path)\n const lang = await loadLocale(Cite, inputLang, options.path)\n\n let bibliography = await getBibliography(options, file)\n if (bibliography.length === 0) {\n return\n }\n\n for (let i = 0; i < bibliography.length; i++) {\n /**\n * getBibibliography is building full path/url safely in both node and browser\n * If it's a valid http url, we can try to fetch safely \n * else we can try to read from file system safely \n */\n if (isValidHttpUrl(bibliography[i])) {\n try {\n const response = await fetch(bibliography[i])\n bibtexFile.push(await response.text())\n } catch (error) {\n throw new Error(`Cannot fetch bibliography URL: ${error}.`)\n }\n } else {\n try {\n bibtexFile.push(await readFile(bibliography[i]))\n } catch (error) {\n throw new Error(`Cannot read non valid bibliography URL in node env.`)\n }\n }\n }\n const citations = new Cite(bibtexFile, { generateGraph: false })\n const citationIds = citations.data.map((x) => x.id)\n const citationPre = []\n const citationDict = {}\n let citationId = 1\n const citeproc = config.engine(citations.data, citeFormat, lang, 'html')\n /** @type {Mode} */\n const mode = citeproc.opt.xclass\n const citationFormat = getCitationFormat(citeproc)\n let parsedEntries = []\n visit(tree, 'text', (node, idx, parent) => {\n const match = node.value.match(citationRE)\n if (!match || ('tagName' in parent && !permittedTags.includes(parent.tagName))) return\n let citeStartIdx = match.index\n let citeEndIdx = match.index + match[0].length\n // If we have an in-text citation and we should suppress the author, the\n // match.index does NOT include the positive lookbehind, so we have to manually\n // shift \"from\" to one before.\n if (match[2] !== undefined) {\n citeStartIdx--\n }\n const newChildren = []\n // if preceding string\n if (citeStartIdx !== 0) {\n // create a new child node\n newChildren.push({\n type: 'text',\n value: node.value.slice(0, citeStartIdx),\n })\n }\n\n const [entries, isComposite] = parseCitation(match)\n parsedEntries = entries\n\n // If id is not in citation file (e.g. route alias or js package), abort process\n for (const citeItem of entries) {\n if (!citationIds.includes(citeItem.id)) return\n }\n const [citedText, citedTextNode] = genCitation(\n citeproc,\n mode,\n entries,\n idRoot,\n citationId,\n citationPre,\n options,\n isComposite,\n citationFormat\n )\n citationDict[citationId] = citedText\n\n // Prepare citationPre and citationId for the next cite instance\n citationPre.push([`${idRoot}-${citationId}`, 0])\n citationId = citationId + 1\n\n newChildren.push(citedTextNode)\n\n // if trailing string\n if (citeEndIdx < node.value.length) {\n newChildren.push({\n type: 'text',\n value: node.value.slice(citeEndIdx),\n })\n }\n\n // insert into the parent\n // @ts-ignore\n parent.children = [\n ...parent.children.slice(0, idx),\n ...newChildren,\n ...parent.children.slice(idx + 1),\n ]\n })\n\n if (noCite) {\n if (noCite.length === 1 && noCite[0] === '@*') {\n citeproc.updateItems(citationIds)\n } else {\n const mergedIds = citations.data\n .filter((x) => noCite.map((x) => x.replace('@', '')).includes(x['citation-key']))\n .map((x) => x.id)\n .concat(parsedEntries.map((x) => x.id))\n\n citeproc.updateItems(mergedIds)\n }\n }\n\n if (\n citeproc.registry.mylist.length >= 1 &&\n (!options.suppressBibliography || options.inlineBibClass?.length > 0)\n ) {\n const biblioNode = genBiblioNode(citeproc)\n let bilioInserted = false\n\n const biblioMap = {}\n biblioNode.children\n .filter((node) => node.properties?.className?.includes('csl-entry'))\n .forEach((node) => {\n const citekey = node.properties.id.split('-').slice(1).join('-')\n biblioMap[citekey] = { ...node }\n biblioMap[citekey].properties = { id: 'inlinebib-' + citekey }\n })\n\n // Insert it at ^ref, if not found insert it as the last element of the tree\n visit(tree, 'element', (node, idx, parent) => {\n // Add inline bibliography\n if (\n options.inlineBibClass?.length > 0 &&\n node.properties?.id?.toString().startsWith('citation-')\n ) {\n // id is citation--nash1951--nash1950--1\n const [, ...citekeys] = node.properties.id.toString().split('--')\n const citationID = citekeys.pop()\n\n /** @type {Element} */\n const inlineBibNode = {\n type: 'element',\n tagName: 'div',\n properties: {\n className: options.inlineBibClass,\n id: `inlineBib--${citekeys.join('--')}--${citationID}`,\n },\n children: citekeys.map((citekey) => {\n const aBibNode = biblioMap[citekey]\n aBibNode.properties = {\n class: 'inline-entry',\n id: `inline--${citekey}--${citationID}`,\n }\n return aBibNode\n }),\n }\n parent.children.push(inlineBibNode)\n }\n\n // Add bibliography\n if (\n !options.suppressBibliography &&\n (node.tagName === 'p' || node.tagName === 'div') &&\n node.children.length >= 1 &&\n node.children[0].type === 'text' &&\n node.children[0].value === '[^ref]'\n ) {\n parent.children[idx] = biblioNode\n bilioInserted = true\n }\n })\n\n if (!options.suppressBibliography && !bilioInserted) {\n tree.children.push(biblioNode)\n }\n }\n\n let footnoteSection\n visit(tree, 'element', (node, index, parent) => {\n if (node.tagName === 'section' && node.properties.dataFootnotes) {\n footnoteSection = node\n parent.children.splice(index, 1)\n }\n })\n\n // Need to adjust footnote numbering based on existing ones already assigned\n // And insert them into the footnote section (if exists)\n // Footnote comes after bibliography\n if (mode === 'note' && Object.keys(citationDict).length > 0) {\n /** @type {{type: 'citation' | 'existing', oldId: string}[]} */\n let fnArray = []\n let index = 1\n visit(tree, 'element', (node) => {\n if (node.tagName === 'sup' && node.children[0].type === 'element') {\n let nextNode = node.children[0]\n if (nextNode.tagName === 'a') {\n /** @type {{href: string, id: string}} */ // @ts-ignore\n const { href, id } = nextNode.properties\n if (href.includes('fn') && id.includes('fnref')) {\n const oldId = href.split('-').pop()\n fnArray.push({\n type: href.includes('cite') ? 'citation' : 'existing',\n oldId,\n })\n // Update ref number\n nextNode.properties.href = `#user-content-fn-${index}`\n nextNode.properties.id = `user-content-fnref-${index}`\n // @ts-ignore\n nextNode.children[0].value = index.toString()\n index += 1\n }\n }\n }\n })\n // @ts-ignore\n const newFootnoteSection = genFootnoteSection(citationDict, fnArray, footnoteSection)\n tree.children.push(newFootnoteSection)\n } else {\n if (footnoteSection) tree.children.push(footnoteSection)\n }\n }\n }\n}\n\nexport default rehypeCitationGenerator\n","/**\n * @typedef {import('./types').CiteItem} CiteItem\n * @typedef {import('./types').Mode} Mode\n * @typedef {import('./types').Options} Options\n */\n\nimport {\n getSortedRelevantRegistryItems,\n split,\n isSameAuthor,\n getBibliographyEntryText,\n} from './utils.js'\nimport { htmlToHast } from './html-transform-node.js'\n\n/**\n * Generate citation using citeproc\n * This accounts for prev citations and additional properties\n *\n * @param {*} citeproc\n * @param {Mode} mode\n * @param {CiteItem[]} entries\n * @param {string} citationIdRoot\n * @param {number} citationId\n * @param {any[]} citationPre\n * @param {Options} options\n * @param {boolean} isComposite\n * @param {import('./types').CitationFormat} citationFormat\n * @return {[string, string]}\n */\nexport const genCitation = (\n citeproc,\n mode,\n entries,\n citationIdRoot,\n citationId,\n citationPre,\n options,\n isComposite,\n citationFormat\n) => {\n const { inlineClass, linkCitations, showTooltips = false, tooltipAttribute = 'title' } = options\n const key = `${citationIdRoot}-${citationId}`\n const c = citeproc.processCitationCluster(\n {\n citationID: key,\n citationItems: entries,\n properties:\n mode === 'in-text'\n ? { noteIndex: 0, mode: isComposite ? 'composite' : '' }\n : { noteIndex: citationId, mode: isComposite ? 'composite' : '' },\n },\n citationPre.length > 0 ? citationPre : [],\n []\n )\n\n const citationText = c[1].find((x) => x[2] === key)[1]\n const ids = `citation--${entries.map((x) => x.id.toLowerCase()).join('--')}--${citationId}`\n\n // Generate tooltip map for each entry if enabled\n const tooltipMap = {}\n if (showTooltips) {\n entries.forEach((entry) => {\n const entryText = getBibliographyEntryText(citeproc, entry.id)\n // Escape quotes and HTML entities for attribute value\n tooltipMap[entry.id.toLowerCase()] = entryText.replace(/\"/g, '"').replace(/&/g, '&')\n })\n }\n\n // Wrapper tooltip for the span element (combined tooltip for all entries)\n const wrapperTooltipAttr = showTooltips\n ? ` ${tooltipAttribute}=\"${entries.map((e) => tooltipMap[e.id.toLowerCase()]).join('; ')}\"`\n : ''\n\n if (mode === 'note') {\n return [\n citationText,\n htmlToHast(\n `${citationId}`\n ),\n ]\n } else if (linkCitations && citationFormat === 'numeric') {\n // e.g. [1, 2]\n let i = 0\n const refIds = entries.map((e) => e.id)\n const output = citationText.replace(/\\d+/g, function (d) {\n const refId = refIds[i].toLowerCase()\n const tooltipAttr = showTooltips ? ` ${tooltipAttribute}=\"${tooltipMap[refId]}\"` : ''\n const url = `${d}`\n i++\n return url\n })\n\n return [\n citationText,\n htmlToHast(`${output}`),\n ]\n } else if (linkCitations && citationFormat === 'author-date') {\n // E.g. (see Nash, 1950, pp. 12–13, 1951); (Nash, 1950; Xie, 2016)\n if (entries.length === 1) {\n // Do not link bracket\n const refId = entries[0].id.toLowerCase()\n const tooltipAttr = showTooltips ? ` ${tooltipAttribute}=\"${tooltipMap[refId]}\"` : ''\n\n const output = isComposite\n ? `${citationText}`\n : `${citationText.slice(0, 1)}${citationText.slice(\n 1,\n -1\n )}${citationText.slice(-1)}`\n\n return [\n citationText,\n htmlToHast(`${output}`),\n ]\n } else {\n // Retrieve the items in the correct order and attach link each of them\n const refIds = entries.map((e) => e.id)\n const results = getSortedRelevantRegistryItems(citeproc, refIds, citeproc.opt.sort_citations)\n const output = []\n let str = citationText\n\n for (const [i, item] of results.entries()) {\n // Need to compare author. If same just match on date.\n const id = item.id\n let citeMatch = item.ambig\n // If author is the same as the previous, some styles like apa collapse the author\n if (i > 0 && isSameAuthor(results[i - 1], item) && str.indexOf(citeMatch) === -1) {\n // Just match on year\n citeMatch = item.ref.issued.year.toString()\n }\n const startPos = str.indexOf(citeMatch)\n const [start, rest] = split(str, startPos)\n output.push(start) // Irrelevant parts\n\n const refId = id.toLowerCase()\n const tooltipAttr = showTooltips ? ` ${tooltipAttribute}=\"${tooltipMap[refId]}\"` : ''\n const url = `${rest.substring(\n 0,\n citeMatch.length\n )}`\n\n output.push(url)\n str = rest.substring(citeMatch.length)\n }\n output.push(str)\n return [\n citationText,\n htmlToHast(\n `${output.join('')}`\n ),\n ]\n }\n } else {\n return [\n citationText,\n htmlToHast(\n `${citationText}`\n ),\n ]\n }\n}\n","import { htmlToHast } from './html-transform-node.js'\n\n/**\n * Generate bibliography in html and convert it to hast\n *\n * @param {*} citeproc\n */\nexport const genBiblioNode = (citeproc) => {\n const [params, bibBody] = citeproc.makeBibliography()\n const bibliography =\n '
\\n' + bibBody.join('') + '
'\n const biblioNode = htmlToHast(bibliography)\n\n // Add citekey id to each bibliography entry.\n biblioNode.children\n .filter((node) => node.properties?.className?.includes('csl-entry'))\n .forEach((node, i) => {\n const citekey = params.entry_ids[i][0].toLowerCase()\n node.properties = node.properties || {}\n node.properties.id = 'bib-' + citekey\n })\n return biblioNode\n}\n","/**\n * @typedef {import('hast').Element} Element\n * @typedef {import('hast').ElementContent} ElementContent\n */\n\nimport { htmlToHast } from './html-transform-node.js'\n\n/**\n * Create new footnote section node based on footnoteArray mappings\n *\n * @param {{int: string}} citationDict\n * @param {{type: 'citation' | 'existing', oldId: string}[]} footnoteArray\n * @param {Element | undefined} footnoteSection\n * @return {Element}\n */\nexport const genFootnoteSection = (citationDict, footnoteArray, footnoteSection) => {\n /** @type {Element} */\n const list = {\n type: 'element',\n tagName: 'ol',\n properties: {},\n children: [{ type: 'text', value: '\\n' }],\n }\n let oldFootnoteList\n if (footnoteSection) {\n /** @type {Element} */ // @ts-ignore - for some reason, the type does not narrow even after filtering\n oldFootnoteList = footnoteSection.children.filter(n => (n.type == \"element\")).find((n) => (n.tagName === 'ol'))\n }\n for (const [idx, item] of footnoteArray.entries()) {\n const { type, oldId } = item\n if (type === 'citation') {\n list.children.push({\n type: 'element',\n tagName: 'li',\n properties: { id: `user-content-fn-${idx + 1}` },\n children: [\n {\n type: 'element',\n tagName: 'p',\n properties: {},\n children: [\n htmlToHast(`${citationDict[oldId]}`),\n {\n type: 'element',\n tagName: 'a',\n properties: {\n href: `#user-content-fnref-${idx + 1}`,\n dataFootnoteBackref: true,\n className: ['data-footnote-backref'],\n ariaLabel: 'Back to content',\n },\n children: [{ type: 'text', value: '↩' }],\n },\n ],\n },\n { type: 'text', value: '\\n' },\n ],\n })\n } else if (type === 'existing') {\n // @ts-ignore\n const liNode = oldFootnoteList.children.find(\n (n) => n.tagName === 'li' && n.properties.id === `user-content-fn-${oldId}`\n )\n liNode.properties.id = `user-content-fn-${idx + 1}`\n const aNode = liNode.children[1].children.find((n) => n.tagName === 'a')\n aNode.properties.href = `#user-content-fnref-${idx + 1}`\n list.children.push(liNode)\n }\n }\n\n /** @type {Element} */\n const newfootnoteSection = {\n type: 'element',\n tagName: 'section',\n properties: { dataFootnotes: true, className: ['footnotes'] },\n children: [\n {\n type: 'element',\n tagName: 'h2',\n properties: { className: ['sr-only'], id: 'footnote-label' },\n children: [{ type: 'text', value: 'Footnotes' }],\n },\n { type: 'text', value: '\\n' },\n list,\n ],\n }\n return newfootnoteSection\n}\n"],"names":["citationRE","fullCitationRE","_wrapRegExp","prefix","citekey","explicitLocator","explicitLocatorInSuffix","suffix","locatorRE","locatorLabels","book","chapter","column","figure","folio","issue","line","note","opus","page","paragraph","part","section","verse","volume","parseSuffix","containsLocator","retValue","locator","undefined","label","trim","natural","toLowerCase","startsWith","substr","length","match","exec","readFile","async","isValidHttpUrl","path","response","fetch","text","error","Error","str","url","URL","_","protocol","split","index","slice","isSameAuthor","item","item2","authorList","ref","author","authorList2","i","family","getFrontmatterField","file","fieldName","_file$data$astro","data","sources","matter","frontmatter","astro","source","htmlToHast","html","frag","document","createRange","createContextualFragment","fromDom","children","permittedTags","idRoot","rehypeCitationGenerator","Cite","options","tree","_options$inlineBibCla","bibtexFile","inputCiteformat","csl","noCite","inputLang","lang","config","plugins","get","citeFormat","format","root","Object","keys","templates","includes","cslName","Math","random","toString","cslPath","add","err","loadCSL","locales","localePath","localeName","loadLocale","bibliography","frontmatterBibliography","getBibliography","push","citations","generateGraph","citationIds","map","x","id","citationPre","citationDict","citationId","citeproc","engine","mode","opt","xclass","citationFormat","cslXml","dataObj","find","getCitationFormat","footnoteSection","parsedEntries","visit","node","idx","parent","value","tagName","citeStartIdx","citeEndIdx","newChildren","type","entries","isComposite","regexMatch","fullCitation","inTextSuppressAuthor","inTextCitation","optionalSuffix","citationPart","thisCitation","groups","replace","rawPrefix","endsWith","substring","rawSuffix","suffixToParse","_extends","parseCitation","citeItem","citedText","citedTextNode","genCitation","citationIdRoot","inlineClass","linkCitations","showTooltips","tooltipAttribute","key","citationText","processCitationCluster","citationID","citationItems","properties","noteIndex","ids","join","tooltipMap","forEach","entry","entryText","getBibliographyEntryText","originalItemIds","registry","mylist","updateItems","bibOutput","makeBibliography","console","wrapperTooltipAttr","e","refIds","output","d","refId","tooltipAttr","results","getSortedRelevantRegistryItems","relevantIds","sorted","res","reflist","sort_citations","citeMatch","ambig","indexOf","issued","year","startPos","start","rest","mergedIds","filter","concat","suppressBibliography","inlineBibClass","biblioNode","params","bibBody","_node$properties","className","entry_ids","genBiblioNode","bilioInserted","biblioMap","_options$inlineBibCla2","_node$properties2","citekeys","pop","inlineBibNode","aBibNode","class","dataFootnotes","splice","fnArray","nextNode","href","oldId","newFootnoteSection","genFootnoteSection","footnoteArray","list","oldFootnoteList","n","dataFootnoteBackref","ariaLabel","liNode","newfootnoteSection"],"mappings":"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"}