summaryrefslogtreecommitdiff
path: root/support/texlab/src/citeproc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
committerNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
commitf1261b349e875b842745b63258c3e338cb1fe3bf (patch)
treeb5d402b3e80818cde2c079a42249f3dcb9732247 /support/texlab/src/citeproc
parent58aa1ac09b1d9e4769d0a0661cf12e2b2db41b14 (diff)
CTAN sync 202105230300
Diffstat (limited to 'support/texlab/src/citeproc')
-rw-r--r--support/texlab/src/citeproc/apa.csl1526
-rw-r--r--support/texlab/src/citeproc/bibutils.rs188
-rw-r--r--support/texlab/src/citeproc/mod.rs213
-rw-r--r--support/texlab/src/citeproc/name/mod.rs278
-rw-r--r--support/texlab/src/citeproc/name/parser.lalrpop150
-rw-r--r--support/texlab/src/citeproc/ris.rs466
6 files changed, 0 insertions, 2821 deletions
diff --git a/support/texlab/src/citeproc/apa.csl b/support/texlab/src/citeproc/apa.csl
deleted file mode 100644
index 8454246a98..0000000000
--- a/support/texlab/src/citeproc/apa.csl
+++ /dev/null
@@ -1,1526 +0,0 @@
-<?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="expanded">
- <info>
- <title>American Psychological Association 6th edition</title>
- <title-short>APA</title-short>
- <id>http://www.zotero.org/styles/apa</id>
- <link href="http://www.zotero.org/styles/apa" rel="self"/>
- <link href="http://owl.english.purdue.edu/owl/resource/560/01/" rel="documentation"/>
- <author>
- <name>Simon Kornblith</name>
- <email>simon@simonster.com</email>
- </author>
- <author>
- <name> Brenton M. Wiernik</name>
- <email>zotero@wiernik.org</email>
- </author>
- <contributor>
- <name>Bruce D'Arcus</name>
- </contributor>
- <contributor>
- <name>Curtis M. Humphrey</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>Sebastian Karcher</name>
- </contributor>
- <category citation-format="author-date"/>
- <category field="psychology"/>
- <category field="generic-base"/>
- <updated>2016-09-28T13:09:49+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="editortranslator" form="short">
- <single>ed. &amp; trans.</single>
- <multiple>eds. &amp; trans.</multiple>
- </term>
- <term name="translator" form="short">trans.</term>
- <term name="interviewer" form="short">interviewer</term>
- <term name="circa" form="short">ca.</term>
- <term name="collection-editor" form="short">series ed.</term>
- </terms>
- </locale>
- <locale xml:lang="es">
- <terms>
- <term name="from">de</term>
- </terms>
- </locale>
- <locale xml:lang="de">
- <terms>
- <term name="et-al">et al.</term>
- </terms>
- </locale>
- <locale xml:lang="da">
- <terms>
- <term name="et-al">et al.</term>
- </terms>
- </locale>
- <locale xml:lang="nn">
- <terms>
- <term name="et-al">et al.</term>
- </terms>
- </locale>
- <locale xml:lang="nb">
- <terms>
- <term name="et-al">et al.</term>
- </terms>
- </locale>
- <macro name="container-contributors-booklike">
- <choose>
- <if variable="container-title">
- <names variable="editor translator" delimiter=", &amp; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=" (" text-case="title" suffix=")"/>
- <substitute>
- <names variable="editorial-director"/>
- <names variable="collection-editor"/>
- <names variable="container-author"/>
- </substitute>
- </names>
- </if>
- </choose>
- </macro>
- <macro name="container-contributors">
- <choose>
- <!-- book is here to catch software with container titles -->
- <if type="book broadcast chapter entry entry-dictionary entry-encyclopedia graphic map personal_communication report speech" match="any">
- <text macro="container-contributors-booklike"/>
- </if>
- <else-if type="paper-conference">
- <choose>
- <if variable="collection-editor container-author editor" match="any">
- <text macro="container-contributors-booklike"/>
- </if>
- </choose>
- </else-if>
- </choose>
- </macro>
- <macro name="secondary-contributors-booklike">
- <group delimiter="; ">
- <choose>
- <if variable="title">
- <names variable="interviewer">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </if>
- </choose>
- <choose>
- <if variable="container-title" match="none">
- <group delimiter="; ">
- <names variable="container-author">
- <label form="verb-short" suffix=" " text-case="title"/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- <names variable="editor translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </if>
- </choose>
- </group>
- </macro>
- <macro name="secondary-contributors">
- <choose>
- <!-- book is here to catch software with container titles -->
- <if type="book broadcast chapter entry entry-dictionary entry-encyclopedia graphic map report" match="any">
- <text macro="secondary-contributors-booklike"/>
- </if>
- <else-if type="personal_communication">
- <group delimiter="; ">
- <group delimiter=" ">
- <choose>
- <if variable="genre" match="any">
- <text variable="genre" text-case="capitalize-first"/>
- </if>
- <else>
- <text term="letter" text-case="capitalize-first"/>
- </else>
- </choose>
- <names variable="recipient" delimiter=", ">
- <label form="verb" suffix=" "/>
- <name and="symbol" delimiter=", "/>
- </names>
- </group>
- <text variable="medium" text-case="capitalize-first"/>
- <choose>
- <if variable="container-title" match="none">
- <names variable="editor translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </if>
- </choose>
- </group>
- </else-if>
- <else-if type="song">
- <choose>
- <if variable="original-author composer" match="any">
- <group delimiter="; ">
- <!-- Replace prefix with performer label as that becomes available -->
- <names variable="author" prefix="Recorded by ">
- <label form="verb" text-case="title"/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- <names variable="translator">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </if>
- </choose>
- </else-if>
- <else-if type="article-journal article-magazine article-newspaper" match="any">
- <group delimiter="; ">
- <choose>
- <if variable="title">
- <names variable="interviewer" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </if>
- </choose>
- <names variable="translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </else-if>
- <else-if type="paper-conference">
- <choose>
- <if variable="collection-editor editor" match="any">
- <text macro="secondary-contributors-booklike"/>
- </if>
- <else>
- <group delimiter="; ">
- <choose>
- <if variable="title">
- <names variable="interviewer" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </if>
- </choose>
- <names variable="translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </else>
- </choose>
- </else-if>
- <else>
- <group delimiter="; ">
- <choose>
- <if variable="title">
- <names variable="interviewer">
- <name and="symbol" initialize-with=". " delimiter="; "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </if>
- </choose>
- <names variable="editor translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </else>
- </choose>
- </macro>
- <macro name="author">
- <choose>
- <if type="song">
- <names variable="composer" delimiter=", ">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <substitute>
- <names variable="original-author"/>
- <names variable="author"/>
- <names variable="translator">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <group delimiter=" ">
- <text macro="title"/>
- <text macro="description"/>
- <text macro="format"/>
- </group>
- </substitute>
- </names>
- </if>
- <else-if type="treaty"/>
- <else>
- <names variable="author" delimiter=", ">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <substitute>
- <names variable="illustrator"/>
- <names variable="composer"/>
- <names variable="director">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="long" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <choose>
- <if variable="container-title">
- <choose>
- <if type="book entry entry-dictionary entry-encyclopedia">
- <text macro="title"/>
- </if>
- <else>
- <names variable="translator"/>
- </else>
- </choose>
- <names variable="translator">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- </if>
- </choose>
- <names variable="editor translator" delimiter=", ">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <names variable="editorial-director">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <names variable="collection-editor">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <choose>
- <if type="report">
- <text variable="publisher"/>
- </if>
- </choose>
- <group delimiter=" ">
- <text macro="title"/>
- <text macro="description"/>
- <text macro="format"/>
- </group>
- </substitute>
- </names>
- </else>
- </choose>
- </macro>
- <macro name="author-short">
- <choose>
- <if type="patent" variable="number" match="all">
- <text macro="patent-number"/>
- </if>
- <else-if type="treaty">
- <text variable="title" form="short"/>
- </else-if>
- <else-if type="personal_communication">
- <choose>
- <if variable="archive DOI publisher URL" match="none">
- <group delimiter=", ">
- <names variable="author">
- <name and="symbol" delimiter=", " initialize-with=". "/>
- <substitute>
- <text variable="title" form="short" quotes="true"/>
- </substitute>
- </names>
- <!-- This should be localized -->
- <text value="personal communication"/>
- </group>
- </if>
- <else>
- <names variable="author" delimiter=", ">
- <name form="short" and="symbol" delimiter=", " initialize-with=". "/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- <choose>
- <if variable="container-title">
- <text variable="title" form="short" quotes="true"/>
- </if>
- <else>
- <text variable="title" form="short" font-style="italic"/>
- </else>
- </choose>
- <text macro="format-short" prefix="[" suffix="]"/>
- </substitute>
- </names>
- </else>
- </choose>
- </else-if>
- <else-if type="song">
- <names variable="composer" delimiter=", ">
- <name form="short" and="symbol" delimiter=", " initialize-with=". "/>
- <substitute>
- <names variable="original-author"/>
- <names variable="author"/>
- <names variable="translator"/>
- <choose>
- <if variable="container-title">
- <text variable="title" form="short" quotes="true"/>
- </if>
- <else>
- <text variable="title" form="short" font-style="italic"/>
- </else>
- </choose>
- <text macro="format-short" prefix="[" suffix="]"/>
- </substitute>
- </names>
- </else-if>
- <else>
- <names variable="author" delimiter=", ">
- <name form="short" and="symbol" delimiter=", " initialize-with=". "/>
- <substitute>
- <names variable="illustrator"/>
- <names variable="composer"/>
- <names variable="director"/>
- <choose>
- <if variable="container-title">
- <choose>
- <if type="book entry entry-dictionary entry-encyclopedia">
- <text variable="title" form="short" quotes="true"/>
- </if>
- <else>
- <names variable="translator"/>
- </else>
- </choose>
- </if>
- </choose>
- <names variable="editor"/>
- <names variable="editorial-director"/>
- <names variable="translator"/>
- <choose>
- <if type="report" variable="publisher" match="all">
- <text variable="publisher"/>
- </if>
- <else-if type="legal_case">
- <text variable="title" font-style="italic"/>
- </else-if>
- <else-if type="bill legislation" match="any">
- <text variable="title" form="short"/>
- </else-if>
- <else-if variable="reviewed-author" type="review review-book" match="any">
- <text macro="format-short" prefix="[" suffix="]"/>
- </else-if>
- <else-if type="post post-weblog webpage" variable="container-title" match="any">
- <text variable="title" form="short" quotes="true"/>
- </else-if>
- <else>
- <text variable="title" form="short" font-style="italic"/>
- </else>
- </choose>
- <text macro="format-short" prefix="[" suffix="]"/>
- </substitute>
- </names>
- </else>
- </choose>
- </macro>
- <macro name="patent-number">
- <!-- authority: U.S. ; genre: patent ; number: 123,445 -->
- <group delimiter=" ">
- <text variable="authority"/>
- <choose>
- <if variable="genre">
- <text variable="genre" text-case="capitalize-first"/>
- </if>
- <else>
- <!-- This should be localized -->
- <text value="patent" text-case="capitalize-first"/>
- </else>
- </choose>
- <group delimiter=" ">
- <text term="issue" form="short" text-case="capitalize-first"/>
- <text variable="number"/>
- </group>
- </group>
- </macro>
- <macro name="access">
- <choose>
- <if type="bill legal_case legislation" match="any"/>
- <else-if variable="DOI" match="any">
- <text variable="DOI" prefix="https://doi.org/"/>
- </else-if>
- <else-if variable="URL">
- <group delimiter=" ">
- <text term="retrieved" text-case="capitalize-first"/>
- <choose>
- <if type="post post-weblog webpage" match="any">
- <date variable="accessed" form="text" suffix=","/>
- </if>
- </choose>
- <text term="from"/>
- <choose>
- <if type="report">
- <choose>
- <if variable="author editor translator" match="any">
- <!-- This should be localized -->
- <text variable="publisher" suffix=" website:"/>
- </if>
- </choose>
- </if>
- <else-if type="post post-weblog webpage" match="any">
- <!-- This should be localized -->
- <text variable="container-title" suffix=" website:"/>
- </else-if>
- </choose>
- <text variable="URL"/>
- </group>
- </else-if>
- <else-if variable="archive">
- <choose>
- <if type="article article-journal article-magazine article-newspaper dataset paper-conference report speech thesis" match="any">
- <!-- This section is for electronic database locations. Physical archives for these and other item types are called in 'publisher' macro -->
- <choose>
- <if variable="archive-place" match="none">
- <group delimiter=" ">
- <text term="retrieved" text-case="capitalize-first"/>
- <text term="from"/>
- <text variable="archive" suffix="."/>
- <text variable="archive_location" prefix="(" suffix=")"/>
- </group>
- </if>
- <else>
- <text macro="publisher" suffix="."/>
- </else>
- </choose>
- </if>
- <else>
- <text macro="publisher" suffix="."/>
- </else>
- </choose>
- </else-if>
- <else>
- <text macro="publisher" suffix="."/>
- </else>
- </choose>
- </macro>
- <macro name="title">
- <choose>
- <if type="treaty">
- <group delimiter=", ">
- <text variable="title" text-case="title"/>
- <names variable="author">
- <name initialize-with="." form="short" delimiter="-"/>
- </names>
- </group>
- </if>
- <else-if type="patent" variable="number" match="all">
- <text macro="patent-number" font-style="italic"/>
- </else-if>
- <else-if variable="title">
- <choose>
- <if variable="version" type="book" match="all">
- <!---This is a hack until we have a software type -->
- <text variable="title"/>
- </if>
- <else-if variable="reviewed-author reviewed-title" type="review review-book" match="any">
- <choose>
- <if variable="reviewed-title">
- <choose>
- <if type="post post-weblog webpage" variable="container-title" match="any">
- <text variable="title"/>
- </if>
- <else>
- <text variable="title" font-style="italic"/>
- </else>
- </choose>
- </if>
- </choose>
- </else-if>
- <else-if type="post post-weblog webpage" variable="container-title" match="any">
- <text variable="title"/>
- </else-if>
- <else>
- <text variable="title" font-style="italic"/>
- </else>
- </choose>
- </else-if>
- <else-if variable="interviewer" type="interview" match="any">
- <names variable="interviewer">
- <label form="verb-short" suffix=" " text-case="capitalize-first"/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- </else-if>
- </choose>
- </macro>
- <!-- APA has four descriptive sections following the title: -->
- <!-- (description), [format], container, event -->
- <macro name="description">
- <group prefix="(" suffix=")">
- <choose>
- <!-- book is here to catch software with container titles -->
- <if type="book report" match="any">
- <choose>
- <if variable="container-title">
- <text macro="secondary-contributors"/>
- </if>
- <else>
- <group delimiter="; ">
- <text macro="description-report"/>
- <text macro="secondary-contributors"/>
- </group>
- </else>
- </choose>
- </if>
- <else-if type="thesis">
- <group delimiter="; ">
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <choose>
- <!-- In APA journals, the university of a thesis is always cited, even if another locator is given -->
- <if variable="DOI URL archive" match="any">
- <text variable="publisher"/>
- </if>
- </choose>
- </group>
- <text macro="locators"/>
- <text macro="secondary-contributors"/>
- </group>
- </else-if>
- <else-if type="book interview manuscript motion_picture musical_score pamphlet post-weblog speech webpage" match="any">
- <group delimiter="; ">
- <text macro="locators"/>
- <text macro="secondary-contributors"/>
- </group>
- </else-if>
- <else-if type="song">
- <choose>
- <if variable="container-title" match="none">
- <text macro="locators"/>
- </if>
- </choose>
- </else-if>
- <else-if type="article dataset figure" match="any">
- <choose>
- <if variable="container-title">
- <text macro="secondary-contributors"/>
- </if>
- <else>
- <group delimiter="; ">
- <text macro="locators"/>
- <text macro="secondary-contributors"/>
- </group>
- </else>
- </choose>
- </else-if>
- <else-if type="bill legislation legal_case patent treaty personal_communication" match="none">
- <text macro="secondary-contributors"/>
- </else-if>
- </choose>
- </group>
- </macro>
- <macro name="format">
- <group prefix="[" suffix="]">
- <choose>
- <if variable="reviewed-author reviewed-title" type="review review-book" match="any">
- <group delimiter=", ">
- <choose>
- <if variable="genre">
- <!-- Delimiting by , rather than "of" to avoid incorrect grammar -->
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <choose>
- <if variable="reviewed-title">
- <text variable="reviewed-title" font-style="italic"/>
- </if>
- <else>
- <!-- Assume `title` is title of reviewed work -->
- <text variable="title" font-style="italic"/>
- </else>
- </choose>
- </group>
- </if>
- <else>
- <!-- This should be localized -->
- <group delimiter=" ">
- <text value="Review of"/>
- <choose>
- <if variable="reviewed-title">
- <text variable="reviewed-title" font-style="italic"/>
- </if>
- <else>
- <!-- Assume `title` is title of reviewed work -->
- <text variable="title" font-style="italic"/>
- </else>
- </choose>
- </group>
- </else>
- </choose>
- <names variable="reviewed-author">
- <label form="verb-short" suffix=" "/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- </group>
- </if>
- <else>
- <text macro="format-short"/>
- </else>
- </choose>
- </group>
- </macro>
- <macro name="format-short">
- <choose>
- <if variable="reviewed-author reviewed-title" type="review review-book" match="any">
- <choose>
- <if variable="reviewed-title" match="none">
- <choose>
- <if variable="genre">
- <!-- Delimiting by , rather than "of" to avoid incorrect grammar -->
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <text variable="title" form="short" font-style="italic"/>
- </group>
- </if>
- <else>
- <!-- This should be localized -->
- <group delimiter=" ">
- <text value="Review of"/>
- <text variable="title" form="short" font-style="italic"/>
- </group>
- </else>
- </choose>
- </if>
- <else>
- <text variable="title" form="short" quotes="true"/>
- </else>
- </choose>
- </if>
- <else-if type="speech thesis" match="any">
- <text variable="medium" text-case="capitalize-first"/>
- </else-if>
- <!-- book is here to catch software with container titles -->
- <else-if type="book report" match="any">
- <choose>
- <if variable="container-title" match="none">
- <text macro="format-report"/>
- </if>
- </choose>
- </else-if>
- <else-if type="manuscript pamphlet" match="any">
- <text variable="medium" text-case="capitalize-first"/>
- </else-if>
- <else-if type="personal_communication">
- <text macro="secondary-contributors"/>
- </else-if>
- <else-if type="song">
- <group delimiter="; ">
- <text macro="secondary-contributors"/>
- <choose>
- <if variable="container-title" match="none">
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <text variable="medium" text-case="capitalize-first"/>
- </group>
- </if>
- </choose>
- </group>
- </else-if>
- <else-if type="paper-conference">
- <group delimiter=", ">
- <choose>
- <if variable="collection-editor editor issue page volume" match="any">
- <text variable="genre" text-case="capitalize-first"/>
- </if>
- </choose>
- <text variable="medium" text-case="capitalize-first"/>
- </group>
- </else-if>
- <else-if type="bill legislation legal_case patent treaty" match="none">
- <choose>
- <if variable="genre medium" match="any">
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <text variable="medium" text-case="capitalize-first"/>
- </group>
- </if>
- <else-if type="dataset">
- <!-- This should be localized -->
- <text value="Data set"/>
- </else-if>
- </choose>
- </else-if>
- </choose>
- </macro>
- <macro name="description-report">
- <choose>
- <if variable="number">
- <group delimiter="; ">
- <group delimiter=" ">
- <text variable="genre" text-case="title"/>
- <!-- Replace with term="number" if that becomes available -->
- <text term="issue" form="short" text-case="capitalize-first"/>
- <text variable="number"/>
- </group>
- <text macro="locators"/>
- </group>
- </if>
- <else>
- <text macro="locators"/>
- </else>
- </choose>
- </macro>
- <macro name="format-report">
- <choose>
- <if variable="number">
- <text variable="medium" text-case="capitalize-first"/>
- </if>
- <else>
- <group delimiter=", ">
- <text variable="genre" text-case="capitalize-first"/>
- <text variable="medium" text-case="capitalize-first"/>
- </group>
- </else>
- </choose>
- </macro>
- <macro name="archive">
- <group delimiter=". ">
- <group delimiter=", ">
- <choose>
- <if type="manuscript">
- <text variable="genre"/>
- </if>
- </choose>
- <group delimiter=" ">
- <!-- Replace "archive" with "archive_collection" as that becomes available -->
- <text variable="archive"/>
- <text variable="archive_location" prefix="(" suffix=")"/>
- </group>
- </group>
- <group delimiter=", ">
- <!-- Move "archive" here when "archive_collection" becomes available -->
- <text variable="archive-place"/>
- </group>
- </group>
- </macro>
- <macro name="publisher">
- <choose>
- <if type="manuscript pamphlet" match="any">
- <choose>
- <if variable="archive archive_location archive-place" match="any">
- <group delimiter=". ">
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
- <text macro="archive"/>
- </group>
- </if>
- <else>
- <group delimiter=", ">
- <text variable="genre"/>
- <text variable="publisher"/>
- <text variable="publisher-place"/>
- </group>
- </else>
- </choose>
- </if>
- <else-if type="thesis" match="any">
- <group delimiter=". ">
- <group delimiter=", ">
- <text variable="publisher"/>
- <text variable="publisher-place"/>
- </group>
- <text macro="archive"/>
- </group>
- </else-if>
- <else-if type="patent">
- <group delimiter=". ">
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
- <text macro="archive"/>
- </group>
- </else-if>
- <else-if type="article-journal article-magazine article-newspaper" match="any">
- <text macro="archive"/>
- </else-if>
- <else-if type="post post-weblog webpage" match="none">
- <group delimiter=". ">
- <choose>
- <if variable="event">
- <choose>
- <!-- Only print publisher info if published in a proceedings -->
- <if variable="collection-editor editor issue page volume" match="any">
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
- </if>
- </choose>
- </if>
- <else>
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
- </else>
- </choose>
- <text macro="archive"/>
- </group>
- </else-if>
- </choose>
- </macro>
- <macro name="event">
- <choose>
- <if variable="event" type="speech paper-conference" match="any">
- <choose>
- <!-- Don't print event info if published in a proceedings -->
- <if variable="collection-editor editor issue page volume" match="none">
- <group delimiter=" ">
- <text variable="genre" text-case="capitalize-first"/>
- <group delimiter=" ">
- <choose>
- <if variable="genre">
- <text term="presented at"/>
- </if>
- <else>
- <text term="presented at" text-case="capitalize-first"/>
- </else>
- </choose>
- <group delimiter=", ">
- <text variable="event"/>
- <text variable="event-place"/>
- </group>
- </group>
- </group>
- </if>
- </choose>
- </if>
- </choose>
- </macro>
- <macro name="issued">
- <choose>
- <if type="bill legal_case legislation" match="any"/>
- <else-if variable="issued">
- <group>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- <text variable="year-suffix"/>
- <choose>
- <if type="speech">
- <date variable="issued" delimiter=" ">
- <date-part prefix=", " name="month"/>
- </date>
- </if>
- <else-if type="article article-magazine article-newspaper broadcast interview pamphlet personal_communication post post-weblog treaty webpage" match="any">
- <date variable="issued">
- <date-part prefix=", " name="month"/>
- <date-part prefix=" " name="day"/>
- </date>
- </else-if>
- <else-if type="paper-conference">
- <choose>
- <if variable="container-title" match="none">
- <date variable="issued">
- <date-part prefix=", " name="month"/>
- <date-part prefix=" " name="day"/>
- </date>
- </if>
- </choose>
- </else-if>
- <!-- Only year: article-journal chapter entry entry-dictionary entry-encyclopedia dataset figure graphic motion_picture manuscript map musical_score paper-conference [published] patent report review review-book song thesis -->
- </choose>
- </group>
- </else-if>
- <else-if variable="status">
- <group>
- <text variable="status" text-case="lowercase"/>
- <text variable="year-suffix" prefix="-"/>
- </group>
- </else-if>
- <else>
- <group>
- <text term="no date" form="short"/>
- <text variable="year-suffix" prefix="-"/>
- </group>
- </else>
- </choose>
- </macro>
- <macro name="issued-sort">
- <choose>
- <if type="article article-magazine article-newspaper broadcast interview pamphlet personal_communication post post-weblog speech treaty webpage" match="any">
- <date variable="issued">
- <date-part name="year"/>
- <date-part name="month"/>
- <date-part name="day"/>
- </date>
- </if>
- <else>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- </macro>
- <macro name="issued-year">
- <group>
- <choose>
- <if type="personal_communication">
- <choose>
- <if variable="archive DOI publisher URL" match="none">
- <!-- These variables indicate that the letter is retrievable by the reader. If not, then use the APA in-text-only personal communication format -->
- <date variable="issued" form="text"/>
- </if>
- <else>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- </if>
- <else>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- <text variable="year-suffix"/>
- </group>
- </macro>
- <macro name="issued-citation">
- <choose>
- <if variable="issued">
- <group delimiter="/">
- <choose>
- <if is-uncertain-date="original-date">
- <group prefix="[" suffix="]" delimiter=" ">
- <text term="circa" form="short"/>
- <date variable="original-date">
- <date-part name="year"/>
- </date>
- </group>
- </if>
- <else>
- <date variable="original-date">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- <choose>
- <if is-uncertain-date="issued">
- <group prefix="[" suffix="]" delimiter=" ">
- <text term="circa" form="short"/>
- <text macro="issued-year"/>
- </group>
- </if>
- <else>
- <text macro="issued-year"/>
- </else>
- </choose>
- </group>
- </if>
- <else-if variable="status">
- <text variable="status" text-case="lowercase"/>
- <text variable="year-suffix" prefix="-"/>
- </else-if>
- <else>
- <text term="no date" form="short"/>
- <text variable="year-suffix" prefix="-"/>
- </else>
- </choose>
- </macro>
- <macro name="original-date">
- <choose>
- <if type="bill legal_case legislation" match="any"/>
- <else-if type="speech">
- <date variable="original-date" delimiter=" ">
- <date-part name="month"/>
- <date-part name="year"/>
- </date>
- </else-if>
- <else-if type="article article-magazine article-newspaper broadcast interview pamphlet personal_communication post post-weblog treaty webpage" match="any">
- <date variable="original-date" form="text"/>
- </else-if>
- <else>
- <date variable="original-date">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- </macro>
- <macro name="original-published">
- <!--This should be localized -->
- <choose>
- <if type="bill legal_case legislation" match="any"/>
- <else-if type="interview motion_picture song" match="any">
- <text value="Original work recorded"/>
- </else-if>
- <else-if type="broadcast">
- <text value="Original work broadcast"/>
- </else-if>
- <else>
- <text value="Original work published"/>
- </else>
- </choose>
- </macro>
- <macro name="edition">
- <choose>
- <if is-numeric="edition">
- <group delimiter=" ">
- <number variable="edition" form="ordinal"/>
- <text term="edition" form="short"/>
- </group>
- </if>
- <else>
- <text variable="edition"/>
- </else>
- </choose>
- </macro>
- <macro name="locators">
- <choose>
- <if type="article-journal article-magazine figure review review-book" match="any">
- <group delimiter=", ">
- <group>
- <text variable="volume" font-style="italic"/>
- <text variable="issue" prefix="(" suffix=")"/>
- </group>
- <text variable="page"/>
- </group>
- </if>
- <else-if type="article-newspaper">
- <group delimiter=" ">
- <label variable="page" form="short"/>
- <text variable="page"/>
- </group>
- </else-if>
- <else-if type="paper-conference">
- <choose>
- <if variable="collection-editor editor" match="any">
- <text macro="locators-booklike"/>
- </if>
- <else>
- <group delimiter=", ">
- <group>
- <text variable="volume" font-style="italic"/>
- <text variable="issue" prefix="(" suffix=")"/>
- </group>
- <text variable="page"/>
- </group>
- </else>
- </choose>
- </else-if>
- <else-if type="bill broadcast interview legal_case legislation patent post post-weblog speech treaty webpage" match="none">
- <text macro="locators-booklike"/>
- </else-if>
- </choose>
- </macro>
- <macro name="locators-booklike">
- <group delimiter=", ">
- <text macro="edition"/>
- <group delimiter=" ">
- <text term="version" text-case="capitalize-first"/>
- <text variable="version"/>
- </group>
- <choose>
- <if variable="volume" match="any">
- <choose>
- <if is-numeric="volume" match="none"/>
- <else-if variable="collection-title">
- <choose>
- <if variable="editor translator" match="none">
- <choose>
- <if variable="collection-number">
- <group>
- <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
- <number variable="volume" form="numeric"/>
- </group>
- </if>
- </choose>
- </if>
- </choose>
- </else-if>
- <else>
- <group>
- <text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
- <number variable="volume" form="numeric"/>
- </group>
- </else>
- </choose>
- </if>
- <else>
- <group>
- <text term="volume" form="short" plural="true" text-case="capitalize-first" suffix=" "/>
- <number variable="number-of-volumes" form="numeric" prefix="1&#8211;"/>
- </group>
- </else>
- </choose>
- <group>
- <label variable="page" form="short" suffix=" "/>
- <text variable="page"/>
- </group>
- </group>
- </macro>
- <macro name="citation-locator">
- <group>
- <choose>
- <if locator="chapter">
- <label variable="locator" text-case="capitalize-first"/>
- </if>
- <else>
- <label variable="locator" form="short"/>
- </else>
- </choose>
- <text variable="locator" prefix=" "/>
- </group>
- </macro>
- <macro name="container">
- <choose>
- <if type="article article-journal article-magazine article-newspaper review review-book" match="any">
- <group delimiter=", ">
- <text macro="container-title"/>
- <text macro="locators"/>
- </group>
- <choose>
- <!--for advance online publication-->
- <if variable="issued">
- <choose>
- <if variable="page issue" match="none">
- <text variable="status" text-case="capitalize-first" prefix=". "/>
- </if>
- </choose>
- </if>
- </choose>
- </if>
- <else-if type="article dataset figure" match="any">
- <choose>
- <if variable="container-title">
- <group delimiter=", ">
- <text macro="container-title"/>
- <text macro="locators"/>
- </group>
- <choose>
- <!--for advance online publication-->
- <if variable="issued">
- <choose>
- <if variable="page issue" match="none">
- <text variable="status" text-case="capitalize-first" prefix=". "/>
- </if>
- </choose>
- </if>
- </choose>
- </if>
- </choose>
- </else-if>
- <!-- book is here to catch software with container titles -->
- <else-if type="book" variable="container-title" match="all">
- <group delimiter=" ">
- <text term="in" text-case="capitalize-first" suffix=" "/>
- <group delimiter=", ">
- <text macro="container-contributors"/>
- <group delimiter=" ">
- <text macro="container-title"/>
- <text macro="description-report" prefix="(" suffix=")"/>
- <text macro="format-report" prefix="[" suffix="]"/>
- </group>
- </group>
- </group>
- </else-if>
- <else-if type="report" variable="container-title" match="all">
- <group delimiter=" ">
- <text term="in" text-case="capitalize-first" suffix=" "/>
- <group delimiter=", ">
- <text macro="container-contributors"/>
- <group delimiter=" ">
- <text macro="container-title"/>
- <text macro="description-report" prefix="(" suffix=")"/>
- <text macro="format-report" prefix="[" suffix="]"/>
- </group>
- </group>
- </group>
- </else-if>
- <else-if type="song" variable="container-title" match="all">
- <group delimiter=" ">
- <text term="in" text-case="capitalize-first" suffix=" "/>
- <group delimiter=", ">
- <text macro="container-contributors"/>
- <group delimiter=" ">
- <text macro="container-title"/>
- <text macro="locators" prefix="(" suffix=")"/>
- <group delimiter=", " prefix="[" suffix="]">
- <text variable="genre" text-case="capitalize-first"/>
- <text variable="medium" text-case="capitalize-first"/>
- </group>
- </group>
- </group>
- </group>
- </else-if>
- <else-if type="paper-conference">
- <choose>
- <if variable="editor collection-editor container-author" match="any">
- <text macro="container-booklike"/>
- </if>
- <else>
- <group delimiter=", ">
- <text macro="container-title"/>
- <text macro="locators"/>
- </group>
- </else>
- </choose>
- </else-if>
- <else-if type="book">
- <choose>
- <!-- book and software should not cite collection-title, only container-title -->
- <if variable="container-title">
- <text macro="container-booklike"/>
- </if>
- </choose>
- </else-if>
- <else-if type="broadcast chapter entry entry-dictionary entry-encyclopedia graphic map speech" match="any">
- <text macro="container-booklike"/>
- </else-if>
- <else-if type="bill legal_case legislation treaty" match="any">
- <text macro="legal-cites"/>
- </else-if>
- </choose>
- </macro>
- <macro name="container-booklike">
- <choose>
- <if variable="container-title collection-title" match="any">
- <group delimiter=" ">
- <text term="in" text-case="capitalize-first"/>
- <group delimiter=", ">
- <text macro="container-contributors"/>
- <choose>
- <if variable="container-author editor translator" match="none">
- <group delimiter=". ">
- <group delimiter=": ">
- <text variable="collection-title" font-style="italic" text-case="title"/>
- <choose>
- <if variable="collection-title">
- <group delimiter=" ">
- <text term="volume" form="short" font-style="italic" text-case="capitalize-first"/>
- <number variable="collection-number" font-style="italic" form="numeric"/>
- <choose>
- <if variable="collection-number" match="none">
- <number variable="volume" font-style="italic" form="numeric"/>
- </if>
- </choose>
- </group>
- </if>
- </choose>
- </group>
- <!-- Replace with volume-title as that becomes available -->
- <group delimiter=": ">
- <text macro="container-title"/>
- <choose>
- <if variable="collection-title" is-numeric="volume" match="none">
- <group delimiter=" ">
- <text term="volume" form="short" font-style="italic" text-case="capitalize-first"/>
- <text variable="volume" font-style="italic"/>
- </group>
- </if>
- </choose>
- </group>
- </group>
- </if>
- <else>
- <!-- Replace with volume-title as that becomes available -->
- <group delimiter=": ">
- <text macro="container-title"/>
- <choose>
- <if is-numeric="volume" match="none">
- <group delimiter=" ">
- <text term="volume" form="short" font-style="italic" text-case="capitalize-first"/>
- <text variable="volume" font-style="italic"/>
- </group>
- </if>
- </choose>
- </group>
- </else>
- </choose>
- </group>
- <group delimiter="; " prefix="(" suffix=")">
- <text macro="locators"/>
- <names variable="container-author">
- <label form="verb-short" suffix=" " text-case="title"/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- </group>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="container-title">
- <choose>
- <if type="article article-journal article-magazine article-newspaper dataset" match="any">
- <text variable="container-title" font-style="italic" text-case="title"/>
- </if>
- <else-if type="paper-conference speech">
- <choose>
- <if variable="collection-editor container-author editor" match="any">
- <text variable="container-title" font-style="italic"/>
- </if>
- <else>
- <text variable="container-title" font-style="italic" text-case="title"/>
- </else>
- </choose>
- </else-if>
- <else-if type="bill legal_case legislation post-weblog webpage" match="none">
- <text variable="container-title" font-style="italic"/>
- </else-if>
- </choose>
- </macro>
- <macro name="legal-cites">
- <choose>
- <if type="legal_case">
- <group prefix=", " delimiter=" ">
- <group delimiter=" ">
- <choose>
- <if variable="container-title">
- <text variable="volume"/>
- <text variable="container-title"/>
- <group delimiter=" ">
- <!--change to label variable="section" as that becomes available -->
- <text term="section" form="symbol"/>
- <text variable="section"/>
- </group>
- <text variable="page"/>
- </if>
- <else>
- <group delimiter=" ">
- <choose>
- <if is-numeric="number">
- <!-- Replace with term="number" if that becomes available -->
- <text term="issue" form="short" text-case="capitalize-first"/>
- </if>
- </choose>
- <text variable="number"/>
- </group>
- </else>
- </choose>
- </group>
- <group prefix="(" suffix=")" delimiter=" ">
- <text variable="authority"/>
- <choose>
- <if variable="container-title" match="any">
- <!--Only print year for cases published in reporters-->
- <date variable="issued" form="numeric" date-parts="year"/>
- </if>
- <else>
- <date variable="issued" form="text"/>
- </else>
- </choose>
- </group>
- </group>
- </if>
- <else-if type="bill legislation" match="any">
- <group prefix=", " delimiter=" ">
- <group delimiter=", ">
- <choose>
- <if variable="number">
- <!--There's a public law number-->
- <text variable="number" prefix="Pub. L. No. "/>
- <group delimiter=" ">
- <!--change to label variable="section" as that becomes available -->
- <text term="section" form="symbol"/>
- <text variable="section"/>
- </group>
- <group delimiter=" ">
- <text variable="volume"/>
- <text variable="container-title"/>
- <text variable="page-first"/>
- </group>
- </if>
- <else>
- <group delimiter=" ">
- <text variable="volume"/>
- <text variable="container-title"/>
- <!--change to label variable="section" as that becomes available -->
- <text term="section" form="symbol"/>
- <text variable="section"/>
- </group>
- </else>
- </choose>
- </group>
- <date variable="issued" prefix="(" suffix=")">
- <date-part name="year"/>
- </date>
- </group>
- </else-if>
- <else-if type="treaty">
- <group delimiter=" ">
- <number variable="volume"/>
- <text variable="container-title"/>
- <text variable="page"/>
- </group>
- </else-if>
- </choose>
- </macro>
- <citation et-al-min="6" et-al-use-first="1" et-al-subsequent-min="3" et-al-subsequent-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" collapse="year" givenname-disambiguation-rule="primary-name">
- <sort>
- <key macro="author" names-min="8" names-use-first="6"/>
- <key macro="issued-sort"/>
- </sort>
- <layout prefix="(" suffix=")" delimiter="; ">
- <group delimiter=", ">
- <text macro="author-short"/>
- <text macro="issued-citation"/>
- <text macro="citation-locator"/>
- </group>
- </layout>
- </citation>
- <bibliography hanging-indent="true" et-al-min="8" et-al-use-first="6" et-al-use-last="true" entry-spacing="0" line-spacing="2">
- <sort>
- <key macro="author"/>
- <key macro="issued-sort" sort="ascending"/>
- <key macro="title"/>
- </sort>
- <layout>
- <group suffix=".">
- <group delimiter=". ">
- <text macro="author"/>
- <choose>
- <if is-uncertain-date="issued">
- <group prefix=" [" suffix="]" delimiter=" ">
- <text term="circa" form="short"/>
- <text macro="issued"/>
- </group>
- </if>
- <else>
- <text macro="issued" prefix=" (" suffix=")"/>
- </else>
- </choose>
- <group delimiter=" ">
- <text macro="title"/>
- <choose>
- <if variable="title interviewer" type="interview" match="any">
- <group delimiter=" ">
- <text macro="description"/>
- <text macro="format"/>
- </group>
- </if>
- <else>
- <group delimiter=" ">
- <text macro="format"/>
- <text macro="description"/>
- </group>
- </else>
- </choose>
- </group>
- <text macro="container"/>
- </group>
- <text macro="event" prefix=". "/>
- </group>
- <text macro="access" prefix=" "/>
- <choose>
- <if is-uncertain-date="original-date">
- <group prefix=" [" suffix="]" delimiter=" ">
- <text macro="original-published"/>
- <text term="circa" form="short"/>
- <text macro="original-date"/>
- </group>
- </if>
- <else-if variable="original-date">
- <group prefix=" (" suffix=")" delimiter=" ">
- <text macro="original-published"/>
- <text macro="original-date"/>
- </group>
- </else-if>
- </choose>
- </layout>
- </bibliography>
-</style> \ No newline at end of file
diff --git a/support/texlab/src/citeproc/bibutils.rs b/support/texlab/src/citeproc/bibutils.rs
deleted file mode 100644
index b69ed66ed1..0000000000
--- a/support/texlab/src/citeproc/bibutils.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-use bibutils_sys::{
- bibl, bibl_free, bibl_freeparams, bibl_init, bibl_initparams, bibl_read, bibl_write, fclose,
- fopen, param, BIBL_ADSABSOUT, BIBL_BIBLATEXIN, BIBL_BIBTEXIN, BIBL_BIBTEXOUT, BIBL_COPACIN,
- BIBL_EBIIN, BIBL_ENDNOTEIN, BIBL_ENDNOTEOUT, BIBL_ENDNOTEXMLIN, BIBL_ISIOUT, BIBL_MEDLINEIN,
- BIBL_MODSIN, BIBL_MODSOUT, BIBL_NBIBIN, BIBL_NBIBOUT, BIBL_OK, BIBL_RISIN, BIBL_RISOUT,
- BIBL_WORD2007OUT, BIBL_WORDIN, FILE,
-};
-use std::{ffi::CString, fs, mem::MaybeUninit, path::Path};
-use tempfile::tempdir;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum InputFormat {
- Bibtex,
- Biblatex,
- Copac,
- Ebi,
- Endnote,
- EndnoteXml,
- Medline,
- Mods,
- Nbib,
- Ris,
- Word,
-}
-
-impl InputFormat {
- fn read_mode(self) -> u32 {
- match self {
- Self::Bibtex => BIBL_BIBTEXIN,
- Self::Biblatex => BIBL_BIBLATEXIN,
- Self::Copac => BIBL_COPACIN,
- Self::Ebi => BIBL_EBIIN,
- Self::Endnote => BIBL_ENDNOTEIN,
- Self::EndnoteXml => BIBL_ENDNOTEXMLIN,
- Self::Medline => BIBL_MEDLINEIN,
- Self::Mods => BIBL_MODSIN,
- Self::Nbib => BIBL_NBIBIN,
- Self::Ris => BIBL_RISIN,
- Self::Word => BIBL_WORDIN,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum OutputFormat {
- Adsabs,
- Bibtex,
- Endnote,
- Isi,
- Mods,
- Nbib,
- Ris,
- Word2007,
-}
-
-impl OutputFormat {
- fn write_mode(self) -> u32 {
- match self {
- Self::Adsabs => BIBL_ADSABSOUT,
- Self::Bibtex => BIBL_BIBTEXOUT,
- Self::Endnote => BIBL_ENDNOTEOUT,
- Self::Isi => BIBL_ISIOUT,
- Self::Mods => BIBL_MODSOUT,
- Self::Nbib => BIBL_NBIBOUT,
- Self::Ris => BIBL_RISOUT,
- Self::Word2007 => BIBL_WORD2007OUT,
- }
- }
-}
-
-struct Context {
- inner: MaybeUninit<bibl>,
-}
-
-impl Context {
- fn new() -> Self {
- let mut inner = MaybeUninit::zeroed();
- unsafe {
- bibl_init(inner.as_mut_ptr());
- }
- Self { inner }
- }
-}
-
-impl Drop for Context {
- fn drop(&mut self) {
- unsafe {
- bibl_free(self.inner.as_mut_ptr());
- }
- }
-}
-
-unsafe impl Send for Context {}
-
-struct Params {
- inner: MaybeUninit<param>,
-}
-
-impl Params {
- fn new(from: InputFormat, to: OutputFormat) -> Self {
- let program = CString::new("texlab").unwrap();
- let mut inner = MaybeUninit::zeroed();
- unsafe {
- bibl_initparams(
- inner.as_mut_ptr(),
- from.read_mode() as i32,
- to.write_mode() as i32,
- program.as_ptr() as *mut std::os::raw::c_char,
- );
- }
- Self { inner }
- }
-}
-
-impl Drop for Params {
- fn drop(&mut self) {
- unsafe {
- bibl_freeparams(self.inner.as_mut_ptr());
- }
- }
-}
-
-unsafe impl Send for Params {}
-
-struct File {
- path: CString,
- handle: *mut FILE,
-}
-
-impl File {
- fn new<M: Into<Vec<u8>>>(path: &Path, mode: M) -> Self {
- let path = CString::new(path.to_str().unwrap()).unwrap();
- let mode = CString::new(mode).unwrap();
- let handle = unsafe { fopen(path.as_ptr(), mode.as_ptr()) };
- Self { path, handle }
- }
-}
-
-impl Drop for File {
- fn drop(&mut self) {
- unsafe {
- fclose(self.handle);
- }
- }
-}
-
-unsafe impl Send for File {}
-
-pub fn convert(input: &str, from: InputFormat, to: OutputFormat) -> Option<String> {
- let mut context = Context::new();
- let mut params = Params::new(from, to);
- let dir = tempdir().expect("failed to create a temporary directory");
-
- let input_path = dir.path().join("input");
- fs::write(&input_path, input).ok()?;
- let input_file = File::new(&input_path, "r");
- unsafe {
- let status = bibl_read(
- context.inner.as_mut_ptr(),
- input_file.handle,
- input_file.path.as_ptr() as *mut std::os::raw::c_char,
- params.inner.as_mut_ptr(),
- );
-
- if status != BIBL_OK as i32 {
- return None;
- }
- }
-
- let output_path = dir.path().join("output");
- let output_file = File::new(&output_path, "w");
- unsafe {
- let status = bibl_write(
- context.inner.as_mut_ptr(),
- output_file.handle,
- params.inner.as_mut_ptr(),
- );
-
- if status != BIBL_OK as i32 {
- return None;
- }
- }
-
- // Remove BOM
- let data = fs::read(&output_path).ok()?;
- let text = String::from_utf8_lossy(&data[3..]).into_owned();
- Some(text)
-}
diff --git a/support/texlab/src/citeproc/mod.rs b/support/texlab/src/citeproc/mod.rs
deleted file mode 100644
index 6def2ed8a4..0000000000
--- a/support/texlab/src/citeproc/mod.rs
+++ /dev/null
@@ -1,213 +0,0 @@
-mod bibutils;
-mod name;
-mod ris;
-
-use self::{
- bibutils::{InputFormat, OutputFormat},
- ris::{RisLibrary, RisReference},
-};
-use crate::{
- protocol::{BibtexFormattingOptions, MarkupContent, MarkupKind},
- syntax::bibtex,
-};
-use citeproc::prelude::*;
-use citeproc_db::PredefinedLocales;
-use once_cell::sync::Lazy;
-use regex::Regex;
-use std::sync::Arc;
-
-static APA_STYLE: &str = include_str!("apa.csl");
-
-static DOI_URL_PATTERN: &str = r#"https://doi.org/\[.*\]\(.*\)"#;
-
-static DOI_URL_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(DOI_URL_PATTERN).unwrap());
-
-pub fn render_citation(tree: &bibtex::Tree, key: &str) -> Option<MarkupContent> {
- let ris_reference = convert_to_ris(tree, key)?;
- let doi_url = get_doi_url_markdown(&ris_reference);
- let csl_reference: Reference = ris_reference.into();
- let html = generate_bibliography(csl_reference)?;
-
- let mut markdown = html2md::parse_html(&html).trim().to_owned();
- if markdown == "" {
- return None;
- }
-
- if let Some(doi_url) = doi_url {
- markdown = DOI_URL_REGEX
- .replace(&markdown, doi_url.as_str())
- .into_owned();
- }
-
- markdown = markdown
- .replace("..", ".")
- .replace("\\\'", "'")
- .replace("\\-", "-")
- .replace("\\\\textsubscript", "")
- .replace("\\\\textsuperscript", "");
- let content = MarkupContent {
- kind: MarkupKind::Markdown,
- value: markdown,
- };
- Some(content)
-}
-
-fn convert_to_ris(tree: &bibtex::Tree, key: &str) -> Option<RisReference> {
- let options = BibtexFormattingOptions {
- line_length: None,
- formatter: None,
- };
- let params = bibtex::FormattingParams {
- insert_spaces: true,
- tab_size: 4,
- options: &options,
- };
-
- let mut bib_code = String::new();
- tree.children(tree.root)
- .filter(|node| tree.as_string(*node).is_some())
- .map(|node| bibtex::format(tree, node, params))
- .for_each(|string| {
- bib_code.push_str(&string);
- bib_code.push('\n');
- });
-
- let entry = tree.entry_by_key(key)?;
- if let Some(crossref) = tree.crossref(entry) {
- bib_code.push_str(&bibtex::format(tree, crossref, params));
- bib_code.push('\n');
- }
-
- bib_code.push_str(&bibtex::format(tree, entry, params));
- bib_code.push('\n');
- bib_code = bib_code.replace("\\hypen", "-");
-
- let ris_code = bibutils::convert(&bib_code, InputFormat::Biblatex, OutputFormat::Ris)?;
- let ris_lib = RisLibrary::parse(ris_code.lines());
- ris_lib
- .references
- .into_iter()
- .find(|reference| reference.id.as_ref().map(AsRef::as_ref) == Some(key))
-}
-
-fn get_doi_url_markdown(ris_reference: &RisReference) -> Option<String> {
- ris_reference
- .doi
- .as_ref()
- .map(|doi| format!("[doi:{}](https://doi.org/{})", doi, doi))
-}
-
-fn generate_bibliography(reference: Reference) -> Option<String> {
- let locales = Arc::new(PredefinedLocales::bundled_en_us());
- let mut processor = Processor::new(APA_STYLE, locales, false, SupportedFormat::Html).unwrap();
- let cite = Cite::basic(&reference.id);
- let cluster = Cluster {
- id: 1,
- cites: vec![cite],
- };
- processor.insert_reference(reference);
- processor.init_clusters(vec![cluster]);
- processor
- .set_cluster_order(&[ClusterPosition {
- id: 1,
- note: Some(1),
- }])
- .unwrap();
- processor.get_bibliography().pop()
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use indoc::indoc;
-
- #[test]
- fn simple() {
- let tree = bibtex::open(indoc!(
- r#"
- @article{foo,
- author = {Foo Bar},
- title = {Baz Qux},
- year = {2020}
- }
- "#
- ));
-
- let actual_md = render_citation(&tree, "foo").unwrap();
-
- let expected_md = MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Bar, F. (2020). *Baz Qux*.".into(),
- };
-
- assert_eq!(actual_md, expected_md);
- }
-
- #[test]
- fn crossref() {
- let tree = bibtex::open(indoc!(
- r#"
- https://tex.stackexchange.com/questions/401138/what-is-the-bibtex-crossref-field-used-for
-
- @inproceedings{duck2015,
- author = {Duck, D.},
- title = {Duck tales},
- crossref = {ICRC2015},
- }
-
- @inproceedings{mouse2015,
- author = {Mouse, M.},
- title = {Mouse stories},
- crossref = {ICRC2015},
- }
-
- @proceedings{ICRC2015,
- title = "{Proceedings of the 34\textsuperscript{th} International Cosmic Ray Conference}",
- year = "2015",
- month = aug,
- }
- "#
- ));
-
- let actual_md = render_citation(&tree, "mouse2015").unwrap();
-
- let expected_md = MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Mouse, M. (2015). Mouse stories. In *Proceedings of the 34th International Cosmic Ray Conference*.".into(),
- };
-
- assert_eq!(actual_md, expected_md);
- }
-
- #[test]
- fn string() {
- let tree = bibtex::open(indoc!(
- r#"
- @string{author = "Foo Bar"}
- @article{foo,
- author = author,
- title = {Baz Qux},
- year = {2020}
- }
- "#
- ));
-
- let actual_md = render_citation(&tree, "foo").unwrap();
-
- let expected_md = MarkupContent {
- kind: MarkupKind::Markdown,
- value: "Bar, F. (2020). *Baz Qux*.".into(),
- };
-
- assert_eq!(actual_md, expected_md);
- }
-
- #[test]
- fn unknown_key() {
- let tree = bibtex::open("");
-
- let actual_md = render_citation(&tree, "foo");
-
- assert_eq!(actual_md, None);
- }
-}
diff --git a/support/texlab/src/citeproc/name/mod.rs b/support/texlab/src/citeproc/name/mod.rs
deleted file mode 100644
index ef97d30130..0000000000
--- a/support/texlab/src/citeproc/name/mod.rs
+++ /dev/null
@@ -1,278 +0,0 @@
-// Ported from: https://github.com/michel-kraemer/citeproc-java/blob/master/citeproc-java/grammars/InternalName.g4
-// Michel Kraemer
-// Apache License 2.0
-mod parser {
- #![allow(warnings)]
- include!(concat!(env!("OUT_DIR"), "/citeproc/name/parser.rs"));
-}
-
-use self::parser::NamesParser;
-use citeproc_io::Name;
-
-pub fn parse(input: &str) -> Vec<Name> {
- let parser = NamesParser::new();
- parser.parse(input).unwrap_or_else(|_| {
- vec![Name::Literal {
- literal: input.into(),
- }]
- })
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use citeproc_io::PersonName;
-
- #[test]
- fn family_only() {
- let name = Name::Person(PersonName {
- family: Some("Thompson".into()),
- given: None,
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Thompson"), vec![name]);
- }
-
- #[test]
- fn simple() {
- let name = Name::Person(PersonName {
- family: Some("Thompson".into()),
- given: Some("Ken".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Ken Thompson"), vec![name]);
- }
-
- #[test]
- fn middle_name() {
- let name = Name::Person(PersonName {
- family: Some("Ritchie".into()),
- given: Some("Dennis M.".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Dennis M. Ritchie"), vec![name]);
- }
-
- #[test]
- fn initials() {
- let name = Name::Person(PersonName {
- family: Some("Johnson".into()),
- given: Some("S. C.".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("S. C. Johnson"), vec![name]);
- }
-
- #[test]
- fn non_dropping_particle() {
- let name = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Michael van Gerwen"), vec![name]);
- }
-
- #[test]
- fn non_dropping_particle_family_only() {
- let name = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: None,
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("van Gerwen"), vec![name]);
- }
-
- #[test]
- fn comma() {
- let name = Name::Person(PersonName {
- family: Some("Thompson".into()),
- given: Some("Ken".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Thompson, Ken"), vec![name]);
- }
-
- #[test]
- fn comma_junior() {
- let name = Name::Person(PersonName {
- family: Some("Friedman".into()),
- given: Some("George".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: Some("Jr.".into()),
- });
- assert_eq!(parse("Friedman, Jr., George"), vec![name]);
- }
-
- #[test]
- fn comma_no_junior() {
- let name = Name::Person(PersonName {
- family: Some("Familya Familyb".into()),
- given: Some("Given".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Familya Familyb, Given"), vec![name]);
- }
-
- #[test]
- fn comma_initials() {
- let name = Name::Person(PersonName {
- family: Some("Ritchie".into()),
- given: Some("Dennis M.".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Ritchie, Dennis M."), vec![name]);
- }
-
- #[test]
- fn comma_non_dropping_particle() {
- let name = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("van Gerwen, Michael"), vec![name]);
- }
-
- #[test]
- fn comma_non_dropping_particles() {
- let name = Name::Person(PersonName {
- family: Some("Voort".into()),
- given: Some("Vincent".into()),
- non_dropping_particle: Some("Van der".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(parse("Van der Voort, Vincent"), vec![name]);
- }
-
- #[test]
- fn and() {
- let name1 = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- let name2 = Name::Person(PersonName {
- family: Some("Voort".into()),
- given: Some("Vincent".into()),
- non_dropping_particle: Some("van der".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(
- parse("Michael van Gerwen and Vincent van der Voort"),
- vec![name1, name2]
- );
- }
-
- #[test]
- fn and_comma1() {
- let name1 = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- let name2 = Name::Person(PersonName {
- family: Some("Voort".into()),
- given: Some("Vincent".into()),
- non_dropping_particle: Some("Van der".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(
- parse("van Gerwen, Michael and Van der Voort, Vincent"),
- vec![name1, name2]
- );
- }
-
- #[test]
- fn and_comma2() {
- let name1 = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- let name2 = Name::Person(PersonName {
- family: Some("Voort".into()),
- given: Some("Vincent".into()),
- non_dropping_particle: Some("van der".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(
- parse("van Gerwen, Michael and van der Voort, Vincent"),
- vec![name1, name2]
- );
- }
-
- #[test]
- fn and_comma_mix() {
- let name1 = Name::Person(PersonName {
- family: Some("Gerwen".into()),
- given: Some("Michael".into()),
- non_dropping_particle: Some("van".into()),
- dropping_particle: None,
- suffix: None,
- });
- let name2 = Name::Person(PersonName {
- family: Some("Voort".into()),
- given: Some("Vincent".into()),
- non_dropping_particle: Some("van der".into()),
- dropping_particle: None,
- suffix: None,
- });
- assert_eq!(
- parse("van Gerwen, Michael and Vincent van der Voort"),
- vec![name1, name2]
- );
- }
-
- #[test]
- fn junior() {
- let name = Name::Person(PersonName {
- family: Some("Friedman".into()),
- given: Some("George".into()),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: Some("Jr.".into()),
- });
- assert_eq!(parse("George Friedman, Jr."), vec![name]);
- }
-
- #[test]
- fn non_parseable() {
- let literal = "Jerry Peek and Tim O'Reilly and Mike Loukides and other authors of the Nutshell handbooks";
- let name = Name::Literal {
- literal: literal.into(),
- };
- assert_eq!(parse(literal), vec![name]);
- }
-}
diff --git a/support/texlab/src/citeproc/name/parser.lalrpop b/support/texlab/src/citeproc/name/parser.lalrpop
deleted file mode 100644
index e7bce8a302..0000000000
--- a/support/texlab/src/citeproc/name/parser.lalrpop
+++ /dev/null
@@ -1,150 +0,0 @@
-// Ported from: https://github.com/michel-kraemer/citeproc-java/blob/master/citeproc-java/grammars/InternalName.g4
-// Michel Kraemer
-// Apache License 2.0
-use citeproc_io::{Name, PersonName};
-use itertools::Itertools;
-
-grammar;
-
-pub Names: Vec<Name> = And<Name>;
-
-And<T>: Vec<T> = {
- <v:(<T> "and")*> <e:T?> => match e {
- None => v,
- Some(e) => {
- let mut v = v;
- v.push(e);
- v
- }
- }
-};
-
-Name: Name = {
- <np1:UWord+> <np2:Von> <fam:Last> "," <fst:First> => {
- let (fst1, fst2) = fst;
- let name = PersonName {
- family: Some(fam.join(" ")),
- given: fst2,
- non_dropping_particle: Some(format!("{} {}", np1.join(" "), np2)),
- dropping_particle: None,
- suffix: fst1,
- };
- Name::Person(name)
- },
- <np:Von> <fam:Last> "," <fst:First> => {
- let (fst1, fst2) = fst;
- let name = PersonName {
- family: Some(fam.join(" ")),
- given: fst2,
- non_dropping_particle: Some(np),
- dropping_particle: None,
- suffix: fst1,
- };
- Name::Person(name)
- },
- <last:Last> "," <fst:First> => {
- let (fst1, fst2) = fst;
- let first_text = format!(
- "{} {}",
- fst1.as_ref().map(|s| s.as_str()).unwrap_or_default(),
- fst2.as_ref().map(|s| s.as_str()).unwrap_or_default(),
- ).trim().to_owned();
-
- let name = if first_text == "Jr." {
- if last.len() == 1 {
- PersonName {
- family: Some(last.join(" ")),
- given: None,
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: Some(first_text),
- }
- } else {
- let mut last = last.into_iter();
- let given = last.next().map(ToOwned::to_owned);
- PersonName {
- family: Some(last.join(" ")),
- given,
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: Some(first_text),
- }
- }
- } else {
- PersonName {
- family: Some(last.join(" ")),
- given: fst2,
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: fst1,
- }
- };
- Name::Person(name)
- },
- <np:Von> <fam:Last> => {
- let name = PersonName {
- family: Some(fam.join(" ")),
- given: None,
- non_dropping_particle: Some(np),
- dropping_particle: None,
- suffix: None,
- };
- Name::Person(name)
- },
- <giv:UWord+> <np:Von> <fam:Last> => {
- let name = PersonName {
- family: Some(fam.join(" ")),
- given: Some(giv.join(" ")),
- non_dropping_particle: Some(np),
- dropping_particle: None,
- suffix: None,
- };
- Name::Person(name)
- },
- <giv:UWord+> <fam:Word> => {
- let name = PersonName {
- family: Some(fam.into()),
- given: Some(giv.join(" ")),
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- };
- Name::Person(name)
- },
- <fam:Word> => {
- let name = PersonName {
- family: Some(fam.into()),
- given: None,
- non_dropping_particle: None,
- dropping_particle: None,
- suffix: None,
- };
- Name::Person(name)
- },
-};
-
-First: (Option<String>, Option<String>) = {
- <a:Word*> "," <b:Word*> => (Some(a.join(" ")), Some(b.join(" "))),
- <a:Word*> => (None, Some(a.join(" "))),
-};
-
-Last: Vec<&'input str> = {
- LWord => vec![(<>)],
- UWord+ => (<>),
-};
-
-Von: String = {
- LWord => String::from(<>),
- <a:Von> <b:LWord> => format!("{} {}", a, b),
- <a:Von> <b:UWord+> <c:LWord> => format!("{} {} {}", a, b.join(" "), c),
-};
-
-Word: &'input str = {
- UWord => (<>),
- LWord => (<>),
-};
-
-
-UWord: &'input str = r"[A-Z\u00C0-\uFFFF(?][A-Z\u00C0-\uFFFF(?a-z\-)&/.]+" => (<>);
-
-LWord: &'input str = r"[a-z\-)&/.][A-Z\u00C0-\uFFFF(?a-z\-)&/.]+" => (<>);
diff --git a/support/texlab/src/citeproc/ris.rs b/support/texlab/src/citeproc/ris.rs
deleted file mode 100644
index 1cb5754aec..0000000000
--- a/support/texlab/src/citeproc/ris.rs
+++ /dev/null
@@ -1,466 +0,0 @@
-// Ported from: https://github.com/michel-kraemer/citeproc-java/tree/master/citeproc-java/templates
-// Michel Kraemer
-// Apache License 2.0
-use super::name;
-use citeproc_io::{Date, DateOrRange, Name, NumericValue, Reference};
-use csl::*;
-use fnv::FnvHashMap;
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
-#[serde(rename_all = "UPPERCASE")]
-pub enum RisType {
- Abst,
- Advs,
- Aggr,
- Ancient,
- Art,
- Bill,
- Blog,
- Book,
- Case,
- Chap,
- Chart,
- Clswk,
- Comp,
- Conf,
- Cpaper,
- Ctlg,
- Data,
- Dbase,
- Dict,
- Ebook,
- Echap,
- Edbook,
- Ejour,
- Elec,
- Encyc,
- Equa,
- Figure,
- Gen,
- Govdoc,
- Grant,
- Hear,
- Icomm,
- Inpr,
- Jfull,
- Jour,
- Legal,
- Manscpt,
- Map,
- Mgzn,
- Mpct,
- Multi,
- Music,
- News,
- Pamp,
- Pat,
- Pcomm,
- Rprt,
- Ser,
- Slide,
- Sound,
- Stand,
- Stat,
- Std,
- Thes,
- Unpb,
- Video,
-}
-
-impl RisType {
- pub fn parse(ty: &str) -> Option<Self> {
- let ty = format!("\"{}\"", ty);
- serde_json::from_str(&ty).ok()
- }
-
- pub fn csl(self) -> CslType {
- match self {
- Self::Abst => CslType::Article,
- Self::Advs => CslType::Article,
- Self::Aggr => CslType::Dataset,
- Self::Ancient => CslType::Article,
- Self::Art => CslType::Article,
- Self::Bill => CslType::Bill,
- Self::Blog => CslType::Webpage,
- Self::Book => CslType::Book,
- Self::Case => CslType::LegalCase,
- Self::Chap => CslType::Chapter,
- Self::Chart => CslType::Article,
- Self::Clswk => CslType::Article,
- Self::Comp => CslType::Article,
- Self::Conf => CslType::PaperConference,
- Self::Cpaper => CslType::PaperConference,
- Self::Ctlg => CslType::Book,
- Self::Data => CslType::Dataset,
- Self::Dbase => CslType::Dataset,
- Self::Dict => CslType::EntryDictionary,
- Self::Ebook => CslType::Book,
- Self::Echap => CslType::Chapter,
- Self::Edbook => CslType::Book,
- Self::Ejour => CslType::ArticleJournal,
- Self::Elec => CslType::Article,
- Self::Encyc => CslType::EntryEncyclopedia,
- Self::Equa => CslType::Article,
- Self::Figure => CslType::Figure,
- Self::Gen => CslType::Article,
- Self::Govdoc => CslType::Legislation,
- Self::Grant => CslType::Legislation,
- Self::Hear => CslType::Article,
- Self::Icomm => CslType::PersonalCommunication,
- Self::Inpr => CslType::PaperConference,
- Self::Jfull => CslType::ArticleJournal,
- Self::Jour => CslType::ArticleJournal,
- Self::Legal => CslType::Legislation,
- Self::Manscpt => CslType::Manuscript,
- Self::Map => CslType::Map,
- Self::Mgzn => CslType::ArticleMagazine,
- Self::Mpct => CslType::MotionPicture,
- Self::Multi => CslType::Webpage,
- Self::Music => CslType::Song,
- Self::News => CslType::ArticleNewspaper,
- Self::Pamp => CslType::Pamphlet,
- Self::Pat => CslType::Patent,
- Self::Pcomm => CslType::PersonalCommunication,
- Self::Rprt => CslType::Report,
- Self::Ser => CslType::Article,
- Self::Slide => CslType::Article,
- Self::Sound => CslType::Song,
- Self::Stand => CslType::Article,
- Self::Stat => CslType::Legislation,
- Self::Std => CslType::Article,
- Self::Thes => CslType::Thesis,
- Self::Unpb => CslType::Article,
- Self::Video => CslType::MotionPicture,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
-pub struct RisReference {
- pub id: Option<String>,
- pub ty: Option<RisType>,
- pub editors: Vec<String>,
- pub tertiary_authors: Vec<String>,
- pub subsidiary_authors: Vec<String>,
- pub abstrct: Option<String>,
- pub author_address: Option<String>,
- pub accession_number: Option<String>,
- pub authors: Vec<String>,
- pub book_or_conference: Option<String>,
- pub custom1: Option<String>,
- pub custom2: Option<String>,
- pub custom3: Option<String>,
- pub custom4: Option<String>,
- pub custom5: Option<String>,
- pub custom6: Option<String>,
- pub custom7: Option<String>,
- pub custom8: Option<String>,
- pub caption: Option<String>,
- pub call_number: Option<String>,
- pub place: Option<String>,
- pub date: Option<String>,
- pub name_of_database: Option<String>,
- pub doi: Option<String>,
- pub database_provider: Option<String>,
- pub end_page: Option<String>,
- pub edition: Option<String>,
- pub issue: Option<String>,
- pub journal: Option<String>,
- pub keywords: Vec<String>,
- pub file_attachments: Vec<String>,
- pub figure: Option<String>,
- pub language: Option<String>,
- pub label: Option<String>,
- pub number: Option<String>,
- pub type_of_work: Option<String>,
- pub notes: Vec<String>,
- pub number_of_volumes: Option<String>,
- pub original_publication: Option<String>,
- pub publisher: Option<String>,
- pub year: Option<String>,
- pub reviewed_item: Option<String>,
- pub research_notes: Option<String>,
- pub reprint_edition: Option<String>,
- pub section: Option<String>,
- pub isbn_or_issn: Option<String>,
- pub start_page: Option<String>,
- pub short_title: Option<String>,
- pub primary_title: Option<String>,
- pub secondardy_title: Option<String>,
- pub tertiary_title: Option<String>,
- pub translated_authors: Vec<String>,
- pub title: Option<String>,
- pub translated_title: Option<String>,
- pub url: Option<String>,
- pub volume: Option<String>,
- pub access_date: Option<String>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct RisLibrary {
- pub references: Vec<RisReference>,
-}
-
-impl RisLibrary {
- pub fn parse<'a, I: Iterator<Item = &'a str>>(lines: I) -> Self {
- let mut library = Self {
- references: Vec::new(),
- };
-
- let mut reference: RisReference = RisReference::default();
- for line in lines {
- let line = line.trim();
- if line == "" {
- continue;
- }
-
- if line == "ER -" {
- library.references.push(reference);
- reference = RisReference::default();
- continue;
- }
-
- let chars: Vec<_> = line.chars().collect();
- if chars.len() < 7 || chars[4] != '-' {
- continue;
- }
-
- let key: String = (&chars[..2]).iter().collect();
- let value: String = (&chars[6..]).iter().collect();
- match key.to_uppercase().as_str() {
- "TY" => reference.ty = RisType::parse(&value),
- "A2" => reference.editors.push(value),
- "A3" => reference.tertiary_authors.push(value),
- "A4" => reference.subsidiary_authors.push(value),
- "AB" => reference.abstrct = Some(value),
- "AD" => reference.author_address = Some(value),
- "AN" => reference.accession_number = Some(value),
- "AU" => reference.authors.push(value),
- "BT" => reference.book_or_conference = Some(value),
- "C1" => reference.custom1 = Some(value),
- "C2" => reference.custom2 = Some(value),
- "C3" => reference.custom3 = Some(value),
- "C4" => reference.custom4 = Some(value),
- "C5" => reference.custom5 = Some(value),
- "C6" => reference.custom6 = Some(value),
- "C7" => reference.custom7 = Some(value),
- "C8" => reference.custom8 = Some(value),
- "CA" => reference.caption = Some(value),
- "CN" => reference.call_number = Some(value),
- "CY" => reference.place = Some(value),
- "DA" => reference.date = Some(value),
- "DB" => reference.name_of_database = Some(value),
- "DO" => reference.doi = Some(value),
- "DP" => reference.database_provider = Some(value),
- "ED" => reference.editors.push(value),
- "EP" => reference.end_page = Some(value),
- "ET" => reference.edition = Some(value),
- "ID" => reference.id = Some(value),
- "IS" => reference.issue = Some(value),
- "JO" => reference.journal = Some(value),
- "J2" => reference.journal = Some(value),
- "KW" => reference.keywords.push(value),
- "L1" => reference.file_attachments.push(value),
- "L4" => reference.figure = Some(value),
- "LA" => reference.language = Some(value),
- "LB" => reference.label = Some(value),
- "M1" => reference.number = Some(value),
- "M3" => reference.type_of_work = Some(value),
- "N1" => reference.notes.push(value),
- "N2" => reference.abstrct = Some(value),
- "NV" => reference.number_of_volumes = Some(value),
- "OP" => reference.original_publication = Some(value),
- "PB" => reference.publisher = Some(value),
- "PY" => reference.year = Some(value),
- "RI" => reference.reviewed_item = Some(value),
- "RN" => reference.research_notes = Some(value),
- "RP" => reference.reprint_edition = Some(value),
- "SE" => reference.section = Some(value),
- "SN" => reference.isbn_or_issn = Some(value),
- "SP" => reference.start_page = Some(value),
- "ST" => reference.short_title = Some(value),
- "T1" => reference.primary_title = Some(value),
- "T2" => reference.secondardy_title = Some(value),
- "T3" => reference.tertiary_title = Some(value),
- "TA" => reference.translated_authors.push(value),
- "TI" => reference.title = Some(value),
- "TT" => reference.translated_title = Some(value),
- "U1" => reference.type_of_work = Some(value),
- "UR" => reference.url = Some(value),
- "VL" => reference.volume = Some(value),
- "Y2" => reference.access_date = Some(value),
- _ => (),
- }
- }
- library
- }
-}
-
-impl Into<Reference> for RisReference {
- fn into(self) -> Reference {
- let csl_type = self.ty.expect("RIS type is missing").csl();
- let mut date: FnvHashMap<DateVariable, DateOrRange> = FnvHashMap::default();
- let mut name: FnvHashMap<NameVariable, Vec<Name>> = FnvHashMap::default();
- let mut number: FnvHashMap<NumberVariable, NumericValue> = FnvHashMap::default();
- let mut ordinary: FnvHashMap<Variable, String> = FnvHashMap::default();
-
- if let Some(access_date) = self.access_date {
- date.insert(DateVariable::Accessed, parse_date_or_range(access_date));
- }
-
- name.insert(NameVariable::Author, parse_authors(self.authors));
- name.insert(NameVariable::Editor, parse_authors(self.editors));
-
- if let Some(container_title) = self
- .journal
- .or(self.name_of_database)
- .or(self.book_or_conference)
- {
- ordinary.insert(Variable::ContainerTitle, container_title.clone());
- ordinary.insert(Variable::CollectionTitle, container_title);
- }
-
- if let Some(value) = self.date.or(self.year) {
- let value = parse_date_or_range(value);
- date.insert(DateVariable::Issued, value.clone());
- date.insert(DateVariable::EventDate, value);
- }
-
- if let Some(url) = self.url {
- ordinary.insert(Variable::URL, url);
- }
-
- let notes = self.notes;
- ordinary.insert(
- Variable::Note,
- self.research_notes.unwrap_or_else(|| notes.join("\n")),
- );
-
- if let Some(issue) = self.issue {
- number.insert(NumberVariable::Issue, parse_number(issue));
- }
-
- if let Some(num) = self.number {
- number.insert(NumberVariable::Number, parse_number(num));
- }
-
- if let Some(place) = self.place {
- ordinary.insert(Variable::EventPlace, place.clone());
- ordinary.insert(Variable::PublisherPlace, place);
- }
-
- if let Some(abstrct) = self.abstrct {
- ordinary.insert(Variable::Abstract, abstrct);
- }
-
- if let Some(call_number) = self.call_number {
- ordinary.insert(Variable::CallNumber, call_number);
- }
-
- if let Some(doi) = self.doi {
- ordinary.insert(Variable::DOI, doi);
- }
-
- if let Some(edition) = self.edition {
- number.insert(NumberVariable::Edition, parse_number(edition));
- }
-
- if let Some(isbn_or_issn) = self.isbn_or_issn {
- ordinary.insert(Variable::ISBN, isbn_or_issn.clone());
- ordinary.insert(Variable::ISSN, isbn_or_issn);
- }
-
- ordinary.insert(Variable::Keyword, self.keywords.join(", "));
-
- if let Some(number_of_volumes) = self.number_of_volumes {
- number.insert(
- NumberVariable::NumberOfVolumes,
- parse_number(number_of_volumes),
- );
- }
-
- if let Some(original_publication) = self.original_publication {
- ordinary.insert(Variable::OriginalTitle, original_publication);
- }
-
- match (self.start_page, self.end_page) {
- (Some(start_page), Some(end_page)) => {
- number.insert(
- NumberVariable::Page,
- NumericValue::Str(format!("{}-{}", start_page, end_page)),
- );
- }
- (Some(page), None) | (None, Some(page)) => {
- number.insert(NumberVariable::Page, parse_number(page));
- }
- (None, None) => {}
- }
-
- if let Some(publisher) = self.publisher {
- ordinary.insert(Variable::Publisher, publisher);
- }
-
- if let Some(reviewed_item) = self.reviewed_item {
- ordinary.insert(Variable::ReviewedTitle, reviewed_item);
- }
-
- if let Some(section) = self.section {
- ordinary.insert(Variable::Section, section);
- }
-
- if let Some(short_title) = self.short_title {
- ordinary.insert(Variable::TitleShort, short_title);
- }
-
- if let Some(title) = self.title {
- ordinary.insert(Variable::Title, title);
- }
-
- if let Some(volume) = self.volume {
- number.insert(NumberVariable::Volume, parse_number(volume));
- }
-
- Reference {
- id: Atom::from(self.id.or(self.label).expect("RIS id is missing").as_str()),
- csl_type,
- language: None,
- name,
- number,
- date,
- ordinary,
- }
- }
-}
-
-fn parse_number(value: String) -> NumericValue {
- match value.parse() {
- Ok(value) => NumericValue::num(value),
- Err(_) => NumericValue::Str(value),
- }
-}
-
-fn parse_authors(authors: Vec<String>) -> Vec<Name> {
- authors
- .into_iter()
- .flat_map(|author| name::parse(&author))
- .collect()
-}
-
-fn parse_date_or_range(value: String) -> DateOrRange {
- parse_date(&value)
- .map(DateOrRange::Single)
- .unwrap_or_else(|| DateOrRange::Literal(value))
-}
-
-fn parse_date(value: &str) -> Option<Date> {
- let mut parts = value.split('/');
- let year: i32 = parts.next()?.parse().ok()?;
- match parts.next().and_then(|p| p.parse().ok()) {
- Some(month) => match parts.next().and_then(|p| p.parse().ok()) {
- Some(day) => Some(Date::new(year, month, day)),
- None => Some(Date::new(year, month, 0)),
- },
- None => Some(Date::new(year, 0, 0)),
- }
-}