text: import { visit } from 'unist-util-visit';
  import fs from 'fs';
  import path from 'path';
  import Cite from 'citation-js';
  import parse5 from 'parse5';
  import { fromParse5 } from 'hast-util-from-parse5';
  
  /**
   * Captures normal citation in square bracket and in-text citation
   * Citation key start should start with a letter, digit, or _,
   * and contains only alphanumerics and single internal punctuation characters (:.#$%&-+?<>~/),
   *
   * e.g. [-@wadler1990], [@hughes1989, sec 3.4], [see @wadler1990; and @hughes1989, pp. 4]
   * and @wadler1990
   *
   * Group #1 - citation term without [] bracket e.g. -@wadler1990
   * Group #2 - in-text citation term e.g. @wadler1990
   *
   * \[([^[\]]*@[^[\]]+)\] for group #1
   * (?!\b)@([a-zA-Z0-9_][a-zA-Z0-9_:.#$%&\-+?<>~]*) for group #2
   * Use (?!\b) to avoid email like address e.g. xyx@google.com
   * */
  const citeExtractorRe = /\[([^[\]]*@[^[\]]+)\]|(?!\b)(@[a-zA-Z0-9_][a-zA-Z0-9_:.#$%&\-+?<>~]*)/;
  const citeKeyRe = /@([a-zA-Z0-9_][a-zA-Z0-9_:.#$%&\-+?<>~]*)/g;
  const citeBracketRe = /\[.*\]/;
  
  /**
   * @typedef CiteItem
   *   Cite item to be passed into citeproc-js
   * @property {string} [id]
   *   The id field is required
   * @property {string} [locator]
   *   A string identifying a page number or other pinpoint location or range within the resource;
   * @property {string} [label]
   *   Path to file
   * @property {string} [prefix]
   *   A string to print before this cite item
   * @property {string} [suffix]
   *   A string to print after this cite item
   * @property {boolean} [suppress-author]
   *   If true, author names will not be included in the citation output for this cite
   * @property {boolean} [author-only]
   *   If true, only the author name will be included in the citation output for this cite
   */
  const locatorMapping = {
    book: 'book',
    'bk.': 'book',
    'bks.': 'book',
    chapter: 'chapter',
    'chap.': 'chapter',
    'chaps.': 'chapter',
    column: 'column',
    'col.': 'column',
    'cols.': 'column',
    figure: 'figure',
    'fig.': 'figure',
    'figs.': 'figure',
    folio: 'folio',
    'fol.': 'folio',
    'fols.': 'folio',
    number: 'number',
    'no.': 'number',
    'nos.': 'number',
    line: 'line',
    'l.': 'line',
    'll.': 'line',
    note: 'note',
    'n.': 'note',
    'nn.': 'note',
    opus: 'opus',
    'op.': 'opus',
    'opp.': 'opus',
    page: 'page',
    'p.': 'page',
    'pp.': 'page',
    paragraph: 'paragraph',
    'para.': 'paragraph',
    'paras.': 'paragraph',
    part: 'part',
    'pt.': 'part',
    'pts.': 'part',
    section: 'section',
    'sec.': 'section',
    'secs.': 'section',
    'sub verbo': 'sub verbo',
    's.v.': 'sub verbo',
    's.vv.': 'sub verbo',
    verse: 'verse',
    'v.': 'verse',
    'vv.': 'verse',
    volume: 'volume',
    'vol.': 'volume',
    'vols.': 'volume',
    '¶': 'paragraph',
    '¶¶': 'paragraph',
    '§': 'section',
    '§§': 'section'
  };
  /**
   * Parses a given citation string and return properties and entries required for cite-proc.
   * Adapted from https://github.com/Zettlr/Citr/blob/master/lib/citr.ts
   *
   * @param {string} citeString Cite string in the form of '[@item]' or '@item'
   * @return {[Object, CiteItem[]]} [properties, entries]
   */
  
  const parseCitation = citeString => {
    /** @type {CiteItem[]} */
    let entries = [];
    let properties;
  
    if (citeBracketRe.test(citeString)) {
      properties = {
        noteIndex: 0
      }; // Handle citations in the form of [@item1; @item2]
  
      const citeItems = citeString.substr(1, citeString.length - 2).split(';');
  
      for (const citeItem of citeItems) {
        // Prefix is the portion before @ e.g. [see @item1] or an empty string
        let prefix = '';
        let locator = '';
        let label = 'page';
        let suffix = '';
        const citeChunk = citeItem.split('@');
  
        if (citeChunk.length === 1) {
          throw new Error('Cite key should be in the form of @key');
        } else if (citeChunk.length > 2) {
          throw new Error('More than one cite key @ detected, please separate keys with ;');
        }
  
        prefix += citeChunk[0];
        prefix = prefix.trim(); // If [-@item1], suppress author
  
        let suppressAuthor = citeItem.indexOf('@') > 0 && citeItem[citeItem.indexOf('@') - 1] === '-';
        if (suppressAuthor) prefix = prefix.substr(0, prefix.length - 1).trim(); // The citation key can be terminated with a comma or space
  
        let commaIndex = citeChunk[1].indexOf(',') + 1; // If the commaIndex is 0, this means there was no comma - check for space
  
        if (commaIndex === 0) commaIndex = citeChunk[1].indexOf(' ') + 1; // Pass undefined to extract everything
  
        if (commaIndex <= 0) commaIndex = undefined;
        const citeKey = citeItem.substr(citeItem.indexOf('@'), commaIndex).match(citeKeyRe)[0]; // We are left with the locator, suffix and label
  
        let afterKey = citeItem.split('@')[1].substr(citeKey.length).trim();
        if (afterKey[0] === ',') afterKey = afterKey.substr(1).trim(); // Locator should be in the form of 11-22, 33
        // Would not work form roman numerals or alphabetical sections
  
        const locatorMatch = afterKey.match(/(\d|-| |,)+/g);
  
        if (locatorMatch !== null) {
          locator = locatorMatch[0].trim(); // String before the locator is taken to be the label
          // Use heuristic from https://pandoc.org/MANUAL.html#citation-syntax to convert locator label to valid
          // Label has to be one of the following: https://docs.citationstyles.org/en/stable/specification.html#locators
  
          label = afterKey.split(locator)[0].trim();
          label = locatorMapping[label] || 'page'; // String after the locator is taken to be the suffix
  
          suffix = afterKey.split(locator)[1].trim();
        } else {
          // If no locator is found, entire string is assumed to be the suffix
          suffix = afterKey.trim();
        }
  
        entries.push({
          // Get the first capture group which returns the citekey without @
          id: [...citeItem.matchAll(citeKeyRe)][0][1],
          locator,
          label,
          prefix,
          suffix,
          'suppress-author': suppressAuthor
        });
      }
    } else {
      // Single item in the form of @item1
      // See https://citeproc-js.readthedocs.io/en/latest/running.html#special-citation-forms
      properties = {
        noteIndex: 0,
        mode: 'composite'
      };
      entries = [citeString].map(str => ({
        id: [...str.matchAll(citeKeyRe)][0][1]
      }));
    }
  
    return [properties, entries];
  };
  
  var mla = `<?xml version="1.0" encoding="utf-8"?>
  <style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never" page-range-format="minimal-two">
    <info>
      <title>Modern Language Association 9th edition</title>
      <title-short>MLA</title-short>
      <id>http://www.zotero.org/styles/modern-language-association</id>
      <link href="http://www.zotero.org/styles/modern-language-association" rel="self"/>
      <link href="http://style.mla.org" rel="documentation"/>
      <author>
        <name>Sebastian Karcher</name>
      </author>
      <category citation-format="author"/>
      <category field="generic-base"/>
      <summary>This style adheres to the MLA 9th edition handbook. Follows the structure of references as outlined in the MLA Manual closely</summary>
      <updated>2021-07-13T20:05:10+00:00</updated>
      <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
    </info>
    <locale xml:lang="en">
      <date form="text">
        <date-part name="day" suffix=" "/>
        <date-part name="month" suffix=" " form="short"/>
        <date-part name="year"/>
      </date>
      <terms>
        <term name="month-01" form="short">Jan.</term>
        <term name="month-02" form="short">Feb.</term>
        <term name="month-03" form="short">Mar.</term>
        <term name="month-04" form="short">Apr.</term>
        <term name="month-05" form="short">May</term>
        <term name="month-06" form="short">June</term>
        <term name="month-07" form="short">July</term>
        <term name="month-08" form="short">Aug.</term>
        <term name="month-09" form="short">Sept.</term>
        <term name="month-10" form="short">Oct.</term>
        <term name="month-11" form="short">Nov.</term>
        <term name="month-12" form="short">Dec.</term>
        <term name="translator" form="short">trans.</term>
      </terms>
    </locale>
    <macro name="author">
      <names variable="author">
        <name name-as-sort-order="first" and="text" delimiter-precedes-last="always" delimiter-precedes-et-al="always" initialize="false" initialize-with=". "/>
        <label form="long" prefix=", "/>
        <substitute>
          <names variable="editor"/>
          <names variable="translator"/>
          <text macro="title"/>
        </substitute>
      </names>
    </macro>
    <macro name="author-short">
      <group delimiter=", ">
        <names variable="author">
          <name form="short" initialize-with=". " and="text"/>
          <substitute>
            <names variable="editor"/>
            <names variable="translator"/>
            <text macro="title-short"/>
          </substitute>
        </names>
        <choose>
          <if disambiguate="true">
            <text macro="title-short"/>
          </if>
        </choose>
      </group>
    </macro>
    <macro name="title">
      <choose>
        <if variable="container-title" match="any">
          <text variable="title" quotes="true" text-case="title"/>
        </if>
        <else>
          <text variable="title" font-style="italic" text-case="title"/>
        </else>
      </choose>
    </macro>
    <macro name="title-short">
      <choose>
        <if variable="container-title" match="any">
          <text variable="title" form="short" quotes="true" text-case="title"/>
        </if>
        <else>
          <text variable="title" form="short" font-style="italic" text-case="title"/>
        </else>
      </choose>
    </macro>
    <macro name="container-title">
      <text variable="container-title" font-style="italic" text-case="title"/>
    </macro>
    <macro name="other-contributors">
      <choose>
        <if variable="container-title" match="any">
          <group delimiter=", ">
            <names variable="container-author" delimiter=", ">
              <label form="verb" suffix=" "/>
              <name and="text"/>
            </names>
            <names variable="editor translator" delimiter=", ">
              <label form="verb" suffix=" "/>
              <name and="text"/>
            </names>
            <names variable="director illustrator interviewer" delimiter=", ">
              <label form="verb" suffix=" "/>
              <name and="text"/>
            </names>
          </group>
        </if>
        <else>
          <group delimiter=", ">
            <names variable="container-author" delimiter=", ">
              <label form="verb" suffix=" " text-case="capitalize-first"/>
              <name and="text"/>
            </names>
            <names variable="editor translator" delimiter=", ">
              <label form="verb" suffix=" " text-case="capitalize-first"/>
              <name and="text"/>
            </names>
            <names variable="director illustrator interviewer" delimiter=", ">
              <label form="verb" suffix=" " text-case="capitalize-first"/>
              <name and="text"/>
            </names>
          </group>
        </else>
      </choose>
    </macro>
    <macro name="version">
      <group delimiter=", ">
        <choose>
          <if is-numeric="edition">
            <group delimiter=" ">
              <number variable="edition" form="ordinal"/>
              <text term="edition" form="short"/>
            </group>
          </if>
          <else>
            <text variable="edition" text-case="capitalize-first"/>
          </else>
        </choose>
        <text variable="version"/>
      </group>
    </macro>
    <macro name="volume-lowercase">
      <group delimiter=" ">
        <text term="volume" form="short"/>
        <text variable="volume"/>
      </group>
    </macro>
    <macro name="number">
      <group delimiter=", ">
        <group>
          <choose>
            <!--lowercase if we have a preceding element-->
            <if variable="edition container-title" match="any">
              <text macro="volume-lowercase"/>
            </if>
            <!--other contributors preceding the volume-->
            <else-if variable="author" match="all">
              <choose>
                <if variable="editor translator container-author illustrator interviewer director" match="any">
                  <text macro="volume-lowercase"/>
                </if>
              </choose>
            </else-if>
            <else-if variable="editor" match="all">
              <choose>
                <if variable="translator container-author illustrator interviewer director" match="any">
                  <text macro="volume-lowercase"/>
                </if>
              </choose>
            </else-if>
            <else-if variable="container-author illustrator interviewer director" match="any">
              <text macro="volume-lowercase"/>
            </else-if>
            <else>
              <group delimiter=" ">
                <text term="volume" form="short" text-case="capitalize-first"/>
                <text variable="volume"/>
              </group>
            </else>
          </choose>
        </group>
        <group delimiter=" ">
          <text term="issue" form="short"/>
          <text variable="issue"/>
        </group>
        <choose>
          <if type="report">
            <text variable="genre"/>
          </if>
        </choose>
        <text variable="number"/>
      </group>
    </macro>
    <macro name="publisher">
      <text variable="publisher"/>
    </macro>
    <macro name="publication-date">
      <choose>
        <if type="book chapter paper-conference motion_picture" match="any">
          <date variable="issued" form="numeric" date-parts="year"/>
        </if>
        <else-if type="article-journal article-magazine" match="any">
          <date variable="issued" form="text" date-parts="year-month"/>
        </else-if>
        <else-if type="speech" match="none">
          <date variable="issued" form="text"/>
        </else-if>
      </choose>
    </macro>
    <macro name="location">
      <group delimiter=", ">
        <group delimiter=" ">
          <label variable="page" form="short"/>
          <text variable="page"/>
        </group>
        <choose>
          <if variable="source" match="none">
            <text macro="URI"/>
          </if>
        </choose>
      </group>
    </macro>
    <macro name="container2-title">
      <group delimiter=", ">
        <choose>
          <if type="speech">
            <text variable="event"/>
            <date variable="event-date" form="text"/>
            <text variable="event-place"/>
          </if>
        </choose>
        <text variable="archive"/>
        <text variable="archive-place"/>
        <text variable="archive_location"/>
      </group>
    </macro>
    <macro name="container2-location">
      <choose>
        <if variable="source">
          <choose>
            <if variable="DOI URL" match="any">
              <group delimiter=", ">
                <text variable="source" font-style="italic"/>
                <text macro="URI"/>
              </group>
            </if>
          </choose>
        </if>
      </choose>
    </macro>
    <macro name="URI">
      <choose>
        <if variable="DOI">
          <text variable="DOI" prefix="https://doi.org/"/>
        </if>
        <else>
          <text variable="URL"/>
        </else>
      </choose>
    </macro>
    <macro name="accessed">
      <!--using accessed where we don't have an issued date; follows recommendation on p. 53 -->
      <choose>
        <if variable="issued" match="none">
          <group delimiter=" ">
            <text term="accessed" text-case="capitalize-first"/>
            <date variable="accessed" form="text"/>
          </group>
        </if>
      </choose>
    </macro>
    <citation et-al-min="3" et-al-use-first="1" disambiguate-add-names="true" disambiguate-add-givenname="true">
      <layout prefix="(" suffix=")" delimiter="; ">
        <choose>
          <if locator="page line" match="any">
            <group delimiter=" ">
              <text macro="author-short"/>
              <text variable="locator"/>
            </group>
          </if>
          <else>
            <group delimiter=", ">
              <text macro="author-short"/>
              <group>
                <label variable="locator" form="short"/>
                <text variable="locator"/>
              </group>
            </group>
          </else>
        </choose>
      </layout>
    </citation>
    <bibliography hanging-indent="true" et-al-min="3" et-al-use-first="1" line-spacing="2" entry-spacing="0" subsequent-author-substitute="---">
      <sort>
        <key macro="author"/>
        <key variable="title"/>
      </sort>
      <layout suffix=".">
        <group delimiter=". ">
          <text macro="author"/>
          <text macro="title"/>
          <date variable="original-date" form="numeric" date-parts="year"/>
          <group delimiter=", ">
            <!---This group corresponds to MLA's "Container 1"-->
            <text macro="container-title"/>
            <text macro="other-contributors"/>
            <text macro="version"/>
            <text macro="number"/>
            <text macro="publisher"/>
            <text macro="publication-date"/>
            <text macro="location"/>
          </group>
          <group delimiter=", ">
            <!---This group corresponds to MLA's "Container 2"-->
            <!--currently just using this one for archival info-->
            <text macro="container2-title"/>
            <text macro="container2-location"/>
          </group>
          <text macro="accessed"/>
        </group>
      </layout>
    </bibliography>
  </style>`;
  
  var chicago = `<?xml version="1.0" encoding="utf-8"?>
  <style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="display-and-sort" page-range-format="chicago">
    <info>
      <title>Chicago Manual of Style 17th edition (author-date)</title>
      <id>http://www.zotero.org/styles/chicago-author-date</id>
      <link href="http://www.zotero.org/styles/chicago-author-date" rel="self"/>
      <link href="http://www.chicagomanualofstyle.org/tools_citationguide.html" rel="documentation"/>
      <author>
        <name>Julian Onions</name>
        <email>julian.onions@gmail.com</email>
      </author>
      <contributor>
        <name>Sebastian Karcher</name>
      </contributor>
      <contributor>
        <name>Richard Karnesky</name>
        <email>karnesky+zotero@gmail.com</email>
        <uri>http://arc.nucapt.northwestern.edu/Richard_Karnesky</uri>
      </contributor>
      <contributor>
        <name>Andrew Dunning</name>
        <email>andrew.dunning@utoronto.ca</email>
        <uri>https://orcid.org/0000-0003-0464-5036</uri>
      </contributor>
      <contributor>
        <name>Matthew Roth</name>
        <email>matthew.g.roth@yale.edu</email>
        <uri> https://orcid.org/0000-0001-7902-6331</uri>
      </contributor>
      <contributor>
        <name>Brenton M. Wiernik</name>
      </contributor>
      <category citation-format="author-date"/>
      <category field="generic-base"/>
      <summary>The author-date variant of the Chicago style</summary>
      <updated>2018-01-24T12:00:00+00:00</updated>
      <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
    </info>
    <locale xml:lang="en">
      <terms>
        <term name="editor" form="verb-short">ed.</term>
        <term name="container-author" form="verb">by</term>
        <term name="translator" form="verb-short">trans.</term>
        <term name="editortranslator" form="verb">edited and translated by</term>
        <term name="translator" form="short">trans.</term>
      </terms>
    </locale>
    <macro name="secondary-contributors">
      <choose>
        <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="none">
          <group delimiter=". ">
            <names variable="editor translator" delimiter=". ">
              <label form="verb" text-case="capitalize-first" suffix=" "/>
              <name and="text" delimiter=", "/>
            </names>
            <names variable="director" delimiter=". ">
              <label form="verb" text-case="capitalize-first" suffix=" "/>
              <name and="text" delimiter=", "/>
            </names>
          </group>
        </if>
      </choose>
    </macro>
    <macro name="container-contributors">
      <choose>
        <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
          <group prefix=", " delimiter=", ">
            <names variable="container-author" delimiter=", ">
              <label form="verb" suffix=" "/>
              <name and="text" delimiter=", "/>
            </names>
            <names variable="editor translator" delimiter=", ">
              <label form="verb" suffix=" "/>
              <name and="text" delimiter=", "/>
            </names>
          </group>
        </if>
      </choose>
    </macro>
    <macro name="editor">
      <names variable="editor">
        <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
        <label form="short" prefix=", "/>
      </names>
    </macro>
    <macro name="translator">
      <names variable="translator">
        <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
        <label form="short" prefix=", "/>
      </names>
    </macro>
    <macro name="recipient">
      <choose>
        <if type="personal_communication">
          <choose>
            <if variable="genre">
              <text variable="genre" text-case="capitalize-first"/>
            </if>
            <else>
              <text term="letter" text-case="capitalize-first"/>
            </else>
          </choose>
        </if>
      </choose>
      <names variable="recipient" delimiter=", ">
        <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
        <name and="text" delimiter=", "/>
      </names>
    </macro>
    <macro name="substitute-title">
      <choose>
        <if type="article-magazine article-newspaper review review-book" match="any">
          <text macro="container-title"/>
        </if>
      </choose>
    </macro>
    <macro name="contributors">
      <group delimiter=". ">
        <names variable="author">
          <name and="text" name-as-sort-order="first" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
          <label form="short" prefix=", "/>
          <substitute>
            <names variable="editor"/>
            <names variable="translator"/>
            <names variable="director"/>
            <text macro="substitute-title"/>
            <text macro="title"/>
          </substitute>
        </names>
        <text macro="recipient"/>
      </group>
    </macro>
    <macro name="contributors-short">
      <names variable="author">
        <name form="short" and="text" delimiter=", " initialize-with=". "/>
        <substitute>
          <names variable="editor"/>
          <names variable="translator"/>
          <names variable="director"/>
          <text macro="substitute-title"/>
          <text macro="title"/>
        </substitute>
      </names>
    </macro>
    <macro name="interviewer">
      <names variable="interviewer" delimiter=", ">
        <label form="verb" prefix=" " text-case="capitalize-first" suffix=" "/>
        <name and="text" delimiter=", "/>
      </names>
    </macro>
    <macro name="archive">
      <group delimiter=". ">
        <text variable="archive_location" text-case="capitalize-first"/>
        <text variable="archive"/>
        <text variable="archive-place"/>
      </group>
    </macro>
    <macro name="access">
      <group delimiter=". ">
        <choose>
          <if type="graphic report" match="any">
            <text macro="archive"/>
          </if>
          <else-if type="article-journal bill book chapter legal_case legislation motion_picture paper-conference" match="none">
            <text macro="archive"/>
          </else-if>
        </choose>
        <choose>
          <if type="webpage post-weblog" match="any">
            <date variable="issued" form="text"/>
          </if>
        </choose>
        <choose>
          <if variable="issued" match="none">
            <group delimiter=" ">
              <text term="accessed" text-case="capitalize-first"/>
              <date variable="accessed" form="text"/>
            </group>
          </if>
        </choose>
        <choose>
          <if type="legal_case" match="none">
            <choose>
              <if variable="DOI">
                <text variable="DOI" prefix="https://doi.org/"/>
              </if>
              <else>
                <text variable="URL"/>
              </else>
            </choose>
          </if>
        </choose>
      </group>
    </macro>
    <macro name="title">
      <choose>
        <if variable="title" match="none">
          <choose>
            <if type="personal_communication" match="none">
              <text variable="genre" text-case="capitalize-first"/>
            </if>
          </choose>
        </if>
        <else-if type="bill book graphic legislation motion_picture song" match="any">
          <text variable="title" text-case="title" font-style="italic"/>
          <group prefix=" (" suffix=")" delimiter=" ">
            <text term="version"/>
            <text variable="version"/>
          </group>
        </else-if>
        <else-if variable="reviewed-author">
          <choose>
            <if variable="reviewed-title">
              <group delimiter=". ">
                <text variable="title" text-case="title" quotes="true"/>
                <group delimiter=", ">
                  <text variable="reviewed-title" text-case="title" font-style="italic" prefix="Review of "/>
                  <names variable="reviewed-author">
                    <label form="verb-short" text-case="lowercase" suffix=" "/>
                    <name and="text" delimiter=", "/>
                  </names>
                </group>
              </group>
            </if>
            <else>
              <group delimiter=", ">
                <text variable="title" text-case="title" font-style="italic" prefix="Review of "/>
                <names variable="reviewed-author">
                  <label form="verb-short" text-case="lowercase" suffix=" "/>
                  <name and="text" delimiter=", "/>
                </names>
              </group>
            </else>
          </choose>
        </else-if>
        <else-if type="legal_case interview patent" match="any">
          <text variable="title"/>
        </else-if>
        <else>
          <text variable="title" text-case="title" quotes="true"/>
        </else>
      </choose>
    </macro>
    <macro name="edition">
      <choose>
        <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
          <choose>
            <if is-numeric="edition">
              <group delimiter=" " prefix=". ">
                <number variable="edition" form="ordinal"/>
                <text term="edition" form="short" strip-periods="true"/>
              </group>
            </if>
            <else>
              <text variable="edition" text-case="capitalize-first" prefix=". "/>
            </else>
          </choose>
        </if>
        <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
          <choose>
            <if is-numeric="edition">
              <group delimiter=" " prefix=", ">
                <number variable="edition" form="ordinal"/>
                <text term="edition" form="short"/>
              </group>
            </if>
            <else>
              <text variable="edition" prefix=", "/>
            </else>
          </choose>
        </else-if>
      </choose>
    </macro>
    <macro name="locators">
      <choose>
        <if type="article-journal">
          <choose>
            <if variable="volume">
              <text variable="volume" prefix=" "/>
              <group prefix=" (" suffix=")">
                <choose>
                  <if variable="issue">
                    <text variable="issue"/>
                  </if>
                  <else>
                    <date variable="issued">
                      <date-part name="month"/>
                    </date>
                  </else>
                </choose>
              </group>
            </if>
            <else-if variable="issue">
              <group delimiter=" " prefix=", ">
                <text term="issue" form="short"/>
                <text variable="issue"/>
                <date variable="issued" prefix="(" suffix=")">
                  <date-part name="month"/>
                </date>
              </group>
            </else-if>
            <else>
              <date variable="issued" prefix=", ">
                <date-part name="month"/>
              </date>
            </else>
          </choose>
        </if>
        <else-if type="legal_case">
          <text variable="volume" prefix=", "/>
          <text variable="container-title" prefix=" "/>
          <text variable="page" prefix=" "/>
        </else-if>
        <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
          <group prefix=". " delimiter=". ">
            <group>
              <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
              <number variable="volume" form="numeric"/>
            </group>
            <group>
              <number variable="number-of-volumes" form="numeric"/>
              <text term="volume" form="short" prefix=" " plural="true"/>
            </group>
          </group>
        </else-if>
        <else-if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
          <choose>
            <if variable="page" match="none">
              <group prefix=". ">
                <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
                <number variable="volume" form="numeric"/>
              </group>
            </if>
          </choose>
        </else-if>
      </choose>
    </macro>
    <macro name="locators-chapter">
      <choose>
        <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
          <choose>
            <if variable="page">
              <group prefix=", ">
                <text variable="volume" suffix=":"/>
                <text variable="page"/>
              </group>
            </if>
          </choose>
        </if>
      </choose>
    </macro>
    <macro name="locators-article">
      <choose>
        <if type="article-newspaper">
          <group prefix=", " delimiter=", ">
            <group delimiter=" ">
              <text variable="edition"/>
              <text term="edition"/>
            </group>
            <group>
              <text term="section" form="short" suffix=" "/>
              <text variable="section"/>
            </group>
          </group>
        </if>
        <else-if type="article-journal">
          <choose>
            <if variable="volume issue" match="any">
              <text variable="page" prefix=": "/>
            </if>
            <else>
              <text variable="page" prefix=", "/>
            </else>
          </choose>
        </else-if>
      </choose>
    </macro>
    <macro name="point-locators">
      <choose>
        <if variable="locator">
          <choose>
            <if locator="page" match="none">
              <choose>
                <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
                  <choose>
                    <if variable="volume">
                      <group>
                        <text term="volume" form="short" suffix=" "/>
                        <number variable="volume" form="numeric"/>
                        <label variable="locator" form="short" prefix=", " suffix=" "/>
                      </group>
                    </if>
                    <else>
                      <label variable="locator" form="short" suffix=" "/>
                    </else>
                  </choose>
                </if>
                <else>
                  <label variable="locator" form="short" suffix=" "/>
                </else>
              </choose>
            </if>
            <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
              <number variable="volume" form="numeric" suffix=":"/>
            </else-if>
          </choose>
          <text variable="locator"/>
        </if>
      </choose>
    </macro>
    <macro name="container-prefix">
      <text term="in" text-case="capitalize-first"/>
    </macro>
    <macro name="container-title">
      <choose>
        <if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="any">
          <text macro="container-prefix" suffix=" "/>
        </if>
      </choose>
      <choose>
        <if type="webpage">
          <text variable="container-title" text-case="title"/>
        </if>
        <else-if type="legal_case" match="none">
          <group delimiter=" ">
            <text variable="container-title" text-case="title" font-style="italic"/>
            <choose>
              <if type="post-weblog">
                <text value="(blog)"/>
              </if>
            </choose>
          </group>
        </else-if>
      </choose>
    </macro>
    <macro name="publisher">
      <group delimiter=": ">
        <text variable="publisher-place"/>
        <text variable="publisher"/>
      </group>
    </macro>
    <macro name="date">
      <choose>
        <if variable="issued">
          <group delimiter=" ">
            <date variable="original-date" form="text" date-parts="year" prefix="(" suffix=")"/>
            <date variable="issued">
              <date-part name="year"/>
            </date>
          </group>
        </if>
        <else-if variable="status">
          <text variable="status" text-case="capitalize-first"/>
        </else-if>
        <else>
          <text term="no date" form="short"/>
        </else>
      </choose>
    </macro>
    <macro name="date-in-text">
      <choose>
        <if variable="issued">
          <group delimiter=" ">
            <date variable="original-date" form="text" date-parts="year" prefix="[" suffix="]"/>
            <date variable="issued">
              <date-part name="year"/>
            </date>
          </group>
        </if>
        <else-if variable="status">
          <text variable="status"/>
        </else-if>
        <else>
          <text term="no date" form="short"/>
        </else>
      </choose>
    </macro>
    <macro name="day-month">
      <date variable="issued">
        <date-part name="month"/>
        <date-part name="day" prefix=" "/>
      </date>
    </macro>
    <macro name="collection-title">
      <choose>
        <if match="none" type="article-journal">
          <choose>
            <if match="none" is-numeric="collection-number">
              <group delimiter=", ">
                <text variable="collection-title" text-case="title"/>
                <text variable="collection-number"/>
              </group>
            </if>
            <else>
              <group delimiter=" ">
                <text variable="collection-title" text-case="title"/>
                <text variable="collection-number"/>
              </group>
            </else>
          </choose>
        </if>
      </choose>
    </macro>
    <macro name="collection-title-journal">
      <choose>
        <if type="article-journal">
          <group delimiter=" ">
            <text variable="collection-title"/>
            <text variable="collection-number"/>
          </group>
        </if>
      </choose>
    </macro>
    <macro name="event">
      <group delimiter=" ">
        <choose>
          <if variable="genre">
            <text term="presented at"/>
          </if>
          <else>
            <text term="presented at" text-case="capitalize-first"/>
          </else>
        </choose>
        <text variable="event"/>
      </group>
    </macro>
    <macro name="description">
      <choose>
        <if variable="interviewer" type="interview" match="any">
          <group delimiter=". ">
            <text macro="interviewer"/>
            <text variable="medium" text-case="capitalize-first"/>
          </group>
        </if>
        <else-if type="patent">
          <group delimiter=" " prefix=". ">
            <text variable="authority"/>
            <text variable="number"/>
          </group>
        </else-if>
        <else>
          <text variable="medium" text-case="capitalize-first" prefix=". "/>
        </else>
      </choose>
      <choose>
        <if variable="title" match="none"/>
        <else-if type="thesis personal_communication speech" match="any"/>
        <else>
          <group delimiter=" " prefix=". ">
            <text variable="genre" text-case="capitalize-first"/>
            <choose>
              <if type="report">
                <text variable="number"/>
              </if>
            </choose>
          </group>
        </else>
      </choose>
    </macro>
    <macro name="issue">
      <choose>
        <if type="legal_case">
          <text variable="authority" prefix=". "/>
        </if>
        <else-if type="speech">
          <group prefix=". " delimiter=", ">
            <group delimiter=" ">
              <text variable="genre" text-case="capitalize-first"/>
              <text macro="event"/>
            </group>
            <text variable="event-place"/>
            <text macro="day-month"/>
          </group>
        </else-if>
        <else-if type="article-newspaper article-magazine personal_communication" match="any">
          <date variable="issued" form="text" prefix=", "/>
        </else-if>
        <else-if type="patent">
          <group delimiter=", " prefix=", ">
            <group delimiter=" ">
              <!--Needs Localization-->
              <text value="filed"/>
              <date variable="submitted" form="text"/>
            </group>
            <group delimiter=" ">
              <choose>
                <if variable="issued submitted" match="all">
                  <text term="and"/>
                </if>
              </choose>
              <!--Needs Localization-->
              <text value="issued"/>
              <date variable="issued" form="text"/>
            </group>
          </group>
        </else-if>
        <else-if type="article-journal" match="any"/>
        <else>
          <group prefix=". " delimiter=", ">
            <choose>
              <if type="thesis">
                <text variable="genre" text-case="capitalize-first"/>
              </if>
            </choose>
            <text macro="publisher"/>
          </group>
        </else>
      </choose>
    </macro>
    <citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="primary-name" collapse="year" after-collapse-delimiter="; ">
      <layout prefix="(" suffix=")" delimiter="; ">
        <group delimiter=", ">
          <choose>
            <if variable="issued accessed" match="any">
              <group delimiter=" ">
                <text macro="contributors-short"/>
                <text macro="date-in-text"/>
              </group>
            </if>
            <!---comma before forthcoming and n.d.-->
            <else>
              <group delimiter=", ">
                <text macro="contributors-short"/>
                <text macro="date-in-text"/>
              </group>
            </else>
          </choose>
          <text macro="point-locators"/>
        </group>
      </layout>
    </citation>
    <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="&#8212;&#8212;&#8212;" entry-spacing="0">
      <sort>
        <key macro="contributors"/>
        <key variable="issued"/>
        <key variable="title"/>
      </sort>
      <layout suffix=".">
        <group delimiter=". ">
          <text macro="contributors"/>
          <text macro="date"/>
          <text macro="title"/>
        </group>
        <text macro="description"/>
        <text macro="secondary-contributors" prefix=". "/>
        <text macro="container-title" prefix=". "/>
        <text macro="container-contributors"/>
        <text macro="edition"/>
        <text macro="locators-chapter"/>
        <text macro="collection-title-journal" prefix=", " suffix=", "/>
        <text macro="locators"/>
        <text macro="collection-title" prefix=". "/>
        <text macro="issue"/>
        <text macro="locators-article"/>
        <text macro="access" prefix=". "/>
      </layout>
    </bibliography>
  </style>`;
  
  /**
   * @typedef {import('hast').Node} Node
   * @typedef {import('hast').Parent} Parent
   * @typedef {import('hast').Root} Root
   * @typedef {import('unist-util-visit').Visitor<Node>} Visitor
   * @typedef {import('./parse-citation').CiteItem} CiteItem
   * @typedef Options
   *   Configuration.
   * @property {string} [bibliography]
   *   Name of bibtex or CSL-JSON file
   * @property {string} [path]
   *   Required, path to file. Will be joined with `options.bibliography` and `options.csl`, if provided.
   * @property {'apa'|'vancouver'|'harvard1'|'chicago'|'mla'|string} [csl]
   *   One of 'apa', 'vancouver', 'harvard1', 'chicago', 'mla' or name of the local csl file
   * @property {string} [lang]
   *   Locale to use in formatting citations. Defaults to en.
   * @property {boolean} [suppressBibliography]
   *   By default, biliography is inserted after the entire markdown file.
   *   If the file contains `[^Ref]`, the biliography will be inserted there instead.
   * @property {string[]} [noCite]
   *   Citation IDs (@item1) to include in the bibliography even if they are not cited in the document
   */
  const defaultPath = process.cwd(); // Citation.js comes with apa, harvard1 and vancouver
  
  const config = Cite.plugins.config.get('@csl');
  config.templates.add('mla', mla);
  config.templates.add('chicago', chicago);
  const defaultCsl = ['apa', 'vancouver', 'harvard1', 'chicago', 'mla'];
  let citeFormat = 'apa';
  const permittedTags = ['div', 'p', 'span', 'li'];
  
  const customCslConfig = (path, csl) => {
    if (defaultCsl.includes(csl)) {
      citeFormat = csl;
    } else if (fs.existsSync(path)) {
      config.templates.add(csl, fs.readFileSync(path, 'utf8'));
    } else {
      throw new Error('Invalid csl name or path');
    }
  };
  /**
   * Generate citation using citeproc
   * This accounts for prev citations and additional properties
   *
   * @param {*} citeproc
   * @param {CiteItem[]} entries
   * @param {string} citationId
   * @param {any[]} citationPre
   * @param {*} [properties={ noteIndex: 0 }]
   * @return {*}
   */
  
  
  const genCitation = (citeproc, entries, citationId, citationPre, properties = {
    noteIndex: 0
  }) => {
    const c = citeproc.processCitationCluster({
      citationID: citationId,
      citationItems: entries,
      properties: properties
    }, citationPre.length > 0 ? citationPre : [], []); // c = [ { bibchange: true, citation_errors: [] }, [ [ 0, '(1)', 'CITATION-1' ] ]]
  
    const result = c[1].filter(x => x[2] === citationId); // Coerce to html to parse HTML code e.g. &#38; and return text node
  
    const p5ast = parse5.parseFragment(`<div>${result[0][1]}</div>`);
    const citeNode = fromParse5(p5ast).children[0];
    const textNode = citeNode.children[0];
    return textNode;
  };
  /**
   * Generate bibliography in html and convert it to hast
   *
   * @param {*} citeproc
   */
  
  
  const genBiblioNode = citeproc => {
    const [, bibBody] = citeproc.makeBibliography();
    const bibliography = '<div id="refs" class="references csl-bib-body">\n' + bibBody.join('') + '</div>';
    const p5ast = parse5.parseFragment(bibliography);
    const biblioNode = fromParse5(p5ast).children[0];
    return biblioNode;
  };
  /**
   * Rehype plugin that formats citations in markdown documents and insert bibliography in html format
   *
   *    [-@wadler1990]                              --> (1990)
   *    [@hughes1989, sec 3.4]                      --> (Hughes 1989, sec 3.4)
   *    [see @wadler1990; and @hughes1989, pp. 4]   --> (see Wadler 1990 and Hughes 1989, pp. 4)
   * @type {import('unified').Plugin<[Options?], Root>}
   */
  
  
  const rehypeCitation = (options = {}) => {
    return tree => {
      if (!options.bibliography) return;
      const bibtexFile = fs.readFileSync(path.join(options.path || defaultPath, options.bibliography), 'utf8');
      citeFormat = 'apa';
  
      if (options.csl) {
        customCslConfig(path.join(options.path || defaultPath, options.csl), options.csl);
      }
  
      const citations = new Cite(bibtexFile);
      const citationIds = citations.data.map(x => x.id);
      const citationPre = [];
      let citationId = 1;
      const citeproc = config.engine(citations.data, citeFormat, options.lang || 'en', 'html');
      visit(tree, 'text', (node, idx, parent) => {
        const match = node.value.match(citeExtractorRe); //@ts-ignore
  
        if (!match || !permittedTags.includes(parent.tagName)) return;
        const citeStartIdx = match.index;
        const citeEndIdx = match.index + match[0].length;
        const newChildren = []; // if preceding string
  
        if (citeStartIdx !== 0) {
          // create a new child node
          newChildren.push({
            type: 'text',
            value: node.value.slice(0, citeStartIdx)
          });
        }
  
        const [properties, entries] = parseCitation(match[0]); // If id is not in citation file (e.g. route alias or js package), abort process
  
        for (const citeItem of entries) {
          if (!citationIds.includes(citeItem.id)) return;
        }
  
        const citedTextNode = genCitation(citeproc, entries, `CITATION-${citationId}`, citationPre, properties); // Prepare citationPre and citationId for the next cite instance
  
        citationPre.push([`CITATION-${citationId}`, 0]);
        citationId = citationId + 1; // TODO: return html with link
  
        newChildren.push(citedTextNode); // if trailing string
  
        if (citeEndIdx < node.value.length) {
          newChildren.push({
            type: 'text',
            value: node.value.slice(citeEndIdx)
          });
        } // insert into the parent
  
  
        parent.children = [...parent.children.slice(0, idx), ...newChildren, ...parent.children.slice(idx + 1)];
      });
  
      if (options.noCite) {
        citeproc.updateItems(options.noCite.map(x => x.replace('@', '')));
      }
  
      if (!options.suppressBibliography && citeproc.registry.mylist.length >= 1) {
        const biblioNode = genBiblioNode(citeproc);
        let bilioInserted = false; // Insert it at ^ref, if not found insert it as the last element of the tree
  
        visit(tree, 'element', (node, idx, parent) => {
          if ((node.tagName === 'p' || node.tagName === 'div') && node.children[0].value === '[^ref]') {
            parent.children[idx] = biblioNode;
            bilioInserted = true;
          }
        });
  
        if (!bilioInserted) {
          tree.children.push(biblioNode);
        }
      }
    };
  };
  
  export { rehypeCitation as default };
  //# sourceMappingURL=rehype-citation.es.js.map
  