summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-08-19 03:00:56 +0000
committerNorbert Preining <norbert@preining.info>2022-08-19 03:00:56 +0000
commit1772be123f1cfa713b25548f6fec135e7ab339a3 (patch)
tree1ba6586dc52536e962cb28380567183f6f90bbc1
parent982d5e88b736a798b356bf5cabe5e6c9b115f182 (diff)
CTAN sync 202208190300
-rw-r--r--FILES.byname483
-rw-r--r--FILES.byname.gzbin2447565 -> 2447738 bytes
-rw-r--r--FILES.last07days508
-rw-r--r--biblio/citation-style-language/CHANGELOG.md22
-rw-r--r--biblio/citation-style-language/DEPENDS.txt10
-rw-r--r--biblio/citation-style-language/README.md2
-rw-r--r--biblio/citation-style-language/american-chemical-society.csl21
-rw-r--r--biblio/citation-style-language/american-medical-association.csl13
-rw-r--r--biblio/citation-style-language/american-sociological-association.csl28
-rw-r--r--biblio/citation-style-language/apa.csl34
-rw-r--r--biblio/citation-style-language/chicago-author-date.csl24
-rw-r--r--biblio/citation-style-language/chicago-fullnote-bibliography.csl2
-rw-r--r--biblio/citation-style-language/chicago-note-bibliography.csl2
-rw-r--r--biblio/citation-style-language/citation-style-language-doc.pdfbin219427 -> 220489 bytes
-rw-r--r--biblio/citation-style-language/citation-style-language-doc.tex48
-rw-r--r--biblio/citation-style-language/citation-style-language.sty146
-rw-r--r--biblio/citation-style-language/citeproc-bib-data.json2349
-rw-r--r--biblio/citation-style-language/citeproc-bib-data.lua1759
-rw-r--r--biblio/citation-style-language/citeproc-bib.lua27
-rw-r--r--[-rwxr-xr-x]biblio/citation-style-language/citeproc-cli.lua (renamed from biblio/citation-style-language/citeproc)18
-rw-r--r--biblio/citation-style-language/citeproc-context.lua335
-rw-r--r--biblio/citation-style-language/citeproc-element.lua744
-rw-r--r--biblio/citation-style-language/citeproc-engine.lua2023
-rw-r--r--biblio/citation-style-language/citeproc-formats.lua211
-rw-r--r--biblio/citation-style-language/citeproc-ir-node.lua153
-rw-r--r--biblio/citation-style-language/citeproc-latex-core.lua (renamed from biblio/citation-style-language/csl-core.lua)132
-rw-r--r--biblio/citation-style-language/citeproc-latex.lua150
-rw-r--r--biblio/citation-style-language/citeproc-lua.1 (renamed from biblio/citation-style-language/citeproc.1)6
-rwxr-xr-xbiblio/citation-style-language/citeproc-lua.lua12
-rw-r--r--biblio/citation-style-language/citeproc-node-choose.lua330
-rw-r--r--biblio/citation-style-language/citeproc-node-date.lua671
-rw-r--r--biblio/citation-style-language/citeproc-node-group.lua37
-rw-r--r--biblio/citation-style-language/citeproc-node-label.lua142
-rw-r--r--biblio/citation-style-language/citeproc-node-layout.lua243
-rw-r--r--biblio/citation-style-language/citeproc-node-locale.lua280
-rw-r--r--biblio/citation-style-language/citeproc-node-names.lua1374
-rw-r--r--biblio/citation-style-language/citeproc-node-number.lua118
-rw-r--r--biblio/citation-style-language/citeproc-node-sort.lua213
-rw-r--r--biblio/citation-style-language/citeproc-node-style.lua573
-rw-r--r--biblio/citation-style-language/citeproc-node-text.lua330
-rw-r--r--biblio/citation-style-language/citeproc-output.lua1534
-rw-r--r--biblio/citation-style-language/citeproc-richtext.lua779
-rw-r--r--biblio/citation-style-language/citeproc-util.lua309
-rw-r--r--biblio/citation-style-language/citeproc.lua2
-rw-r--r--biblio/citation-style-language/csl-locales-en-GB.xml20
-rw-r--r--biblio/citation-style-language/csl-locales-en-US.xml20
-rw-r--r--biblio/citation-style-language/csl-locales-fr-FR.xml395
-rw-r--r--biblio/citation-style-language/csl.lua143
-rw-r--r--biblio/citation-style-language/harvard-cite-them-right.csl13
-rw-r--r--biblio/citation-style-language/ieee.csl2
-rw-r--r--biblio/citation-style-language/modern-language-association.csl4
-rw-r--r--biblio/citation-style-language/nature.csl26
-rw-r--r--biblio/citation-style-language/vancouver.csl2
-rw-r--r--graphics/pgf/contrib/fancyqr/README.md36
-rw-r--r--graphics/pgf/contrib/fancyqr/fancyqr-doc.pdfbin0 -> 248260 bytes
-rw-r--r--graphics/pgf/contrib/fancyqr/fancyqr-doc.tex87
-rw-r--r--graphics/pgf/contrib/fancyqr/fancyqr.sty235
-rw-r--r--graphics/pgf/contrib/fancyqr/qr-example.tex25
-rw-r--r--macros/texinfo/latest/texinfo.tex404
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl2
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb241
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.md52
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha5122
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc14
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.xzbin2399360 -> 2397372 bytes
-rw-r--r--systems/win32/miktex/tm/packages/next/pr.ini8
-rw-r--r--systems/win32/miktex/tm/packages/pr.ini8
-rw-r--r--timestamp2
68 files changed, 10909 insertions, 6979 deletions
diff --git a/FILES.byname b/FILES.byname
index 766586f702..5e96684943 100644
--- a/FILES.byname
+++ b/FILES.byname
@@ -1788,105 +1788,108 @@
1995/06/20 | 49681 | biblio/bibtex/vms/bibtex.vms-changes
1995/04/14 | 620 | biblio/bibtex/vms/link_bibtex.com
1995/04/14 | 1316 | biblio/bibtex/vms/make_bibtex.com
-2022/03/21 | 9898 | biblio/citation-style-language/american-chemical-society.csl
-2022/03/21 | 10684 | biblio/citation-style-language/american-medical-association.csl
-2022/03/21 | 8052 | biblio/citation-style-language/american-political-science-association.csl
-2022/03/21 | 10503 | biblio/citation-style-language/american-sociological-association.csl
-2022/03/21 | 69389 | biblio/citation-style-language/apa.csl
-2022/03/21 | 1142 | biblio/citation-style-language/CHANGELOG.md
-2022/03/21 | 22195 | biblio/citation-style-language/chicago-author-date.csl
-2022/03/21 | 47520 | biblio/citation-style-language/chicago-fullnote-bibliography.csl
-2022/03/21 | 45970 | biblio/citation-style-language/chicago-note-bibliography.csl
-2022/03/21 | 219427 | biblio/citation-style-language/citation-style-language-doc.pdf
-2022/03/21 | 13296 | biblio/citation-style-language/citation-style-language-doc.tex
-2022/03/21 | 29414 | biblio/citation-style-language/citation-style-language.sty
-2022/03/21 | 4815 | biblio/citation-style-language/citeproc
-2022/03/21 | 605 | biblio/citation-style-language/citeproc.1
-2022/03/21 | 61229 | biblio/citation-style-language/citeproc-bib-data.json
-2022/03/21 | 14177 | biblio/citation-style-language/citeproc-bib.lua
-2022/03/21 | 10421 | biblio/citation-style-language/citeproc-element.lua
-2022/03/21 | 11279 | biblio/citation-style-language/citeproc-engine.lua
-2022/03/21 | 7287 | biblio/citation-style-language/citeproc-formats.lua
-2022/03/21 | 411 | biblio/citation-style-language/citeproc.lua
-2022/03/21 | 3504 | biblio/citation-style-language/citeproc-node-choose.lua
-2022/03/21 | 10463 | biblio/citation-style-language/citeproc-node-date.lua
-2022/03/21 | 826 | biblio/citation-style-language/citeproc-node-group.lua
-2022/03/21 | 3110 | biblio/citation-style-language/citeproc-node-label.lua
-2022/03/21 | 6840 | biblio/citation-style-language/citeproc-node-layout.lua
-2022/03/21 | 3183 | biblio/citation-style-language/citeproc-node-locale.lua
-2022/03/21 | 20062 | biblio/citation-style-language/citeproc-node-names.lua
-2022/03/21 | 2491 | biblio/citation-style-language/citeproc-node-number.lua
-2022/03/21 | 1476 | biblio/citation-style-language/citeproc-nodes.lua
-2022/03/21 | 5080 | biblio/citation-style-language/citeproc-node-sort.lua
-2022/03/21 | 5163 | biblio/citation-style-language/citeproc-node-style.lua
-2022/03/21 | 6204 | biblio/citation-style-language/citeproc-node-text.lua
-2022/03/21 | 20541 | biblio/citation-style-language/citeproc-richtext.lua
-2022/03/21 | 17094 | biblio/citation-style-language/citeproc-util.lua
-2022/03/21 | 7765 | biblio/citation-style-language/csl-core.lua
-2022/03/21 | 21433 | biblio/citation-style-language/csl-locales-af-ZA.xml
-2022/03/21 | 19817 | biblio/citation-style-language/csl-locales-ar.xml
-2022/03/21 | 24466 | biblio/citation-style-language/csl-locales-bg-BG.xml
-2022/03/21 | 21302 | biblio/citation-style-language/csl-locales-ca-AD.xml
-2022/03/21 | 21579 | biblio/citation-style-language/csl-locales-cs-CZ.xml
-2022/03/21 | 21576 | biblio/citation-style-language/csl-locales-cy-GB.xml
-2022/03/21 | 21470 | biblio/citation-style-language/csl-locales-da-DK.xml
-2022/03/21 | 22218 | biblio/citation-style-language/csl-locales-de-AT.xml
-2022/03/21 | 21681 | biblio/citation-style-language/csl-locales-de-CH.xml
-2022/03/21 | 22143 | biblio/citation-style-language/csl-locales-de-DE.xml
-2022/03/21 | 23024 | biblio/citation-style-language/csl-locales-el-GR.xml
-2022/03/21 | 22355 | biblio/citation-style-language/csl-locales-en-GB.xml
-2022/03/21 | 22510 | biblio/citation-style-language/csl-locales-en-US.xml
-2022/03/21 | 21406 | biblio/citation-style-language/csl-locales-es-CL.xml
-2022/03/21 | 21327 | biblio/citation-style-language/csl-locales-es-ES.xml
-2022/03/21 | 22434 | biblio/citation-style-language/csl-locales-es-MX.xml
-2022/03/21 | 21261 | biblio/citation-style-language/csl-locales-et-EE.xml
-2022/03/21 | 21512 | biblio/citation-style-language/csl-locales-eu.xml
-2022/03/21 | 22337 | biblio/citation-style-language/csl-locales-fa-IR.xml
-2022/03/21 | 21623 | biblio/citation-style-language/csl-locales-fi-FI.xml
-2022/03/21 | 22098 | biblio/citation-style-language/csl-locales-fr-CA.xml
-2022/03/21 | 22101 | biblio/citation-style-language/csl-locales-fr-FR.xml
-2022/03/21 | 21822 | biblio/citation-style-language/csl-locales-he-IL.xml
-2022/03/21 | 24345 | biblio/citation-style-language/csl-locales-hi-IN.xml
-2022/03/21 | 21363 | biblio/citation-style-language/csl-locales-hr-HR.xml
-2022/03/21 | 21466 | biblio/citation-style-language/csl-locales-hu-HU.xml
-2022/03/21 | 21654 | biblio/citation-style-language/csl-locales-id-ID.xml
-2022/03/21 | 21469 | biblio/citation-style-language/csl-locales-is-IS.xml
-2022/03/21 | 23360 | biblio/citation-style-language/csl-locales-it-IT.xml
-2022/03/21 | 21482 | biblio/citation-style-language/csl-locales-ja-JP.xml
-2022/03/21 | 21966 | biblio/citation-style-language/csl-locales-km-KH.xml
-2022/03/21 | 21414 | biblio/citation-style-language/csl-locales-ko-KR.xml
-2022/03/21 | 21302 | biblio/citation-style-language/csl-locales-la.xml
-2022/03/21 | 22752 | biblio/citation-style-language/csl-locales-lt-LT.xml
-2022/03/21 | 23553 | biblio/citation-style-language/csl-locales-lv-LV.xml
-2022/03/21 | 21941 | biblio/citation-style-language/csl-locales-mn-MN.xml
-2022/03/21 | 21323 | biblio/citation-style-language/csl-locales-nb-NO.xml
-2022/03/21 | 22358 | biblio/citation-style-language/csl-locales-nl-NL.xml
-2022/03/21 | 21301 | biblio/citation-style-language/csl-locales-nn-NO.xml
-2022/03/21 | 21446 | biblio/citation-style-language/csl-locales-pl-PL.xml
-2022/03/21 | 22542 | biblio/citation-style-language/csl-locales-pt-BR.xml
-2022/03/21 | 22454 | biblio/citation-style-language/csl-locales-pt-PT.xml
-2022/03/21 | 21462 | biblio/citation-style-language/csl-locales-ro-RO.xml
-2022/03/21 | 25715 | biblio/citation-style-language/csl-locales-ru-RU.xml
-2022/03/21 | 21574 | biblio/citation-style-language/csl-locales-sk-SK.xml
-2022/03/21 | 21330 | biblio/citation-style-language/csl-locales-sl-SI.xml
-2022/03/21 | 22122 | biblio/citation-style-language/csl-locales-sr-RS.xml
-2022/03/21 | 21715 | biblio/citation-style-language/csl-locales-sv-SE.xml
-2022/03/21 | 23467 | biblio/citation-style-language/csl-locales-th-TH.xml
-2022/03/21 | 21635 | biblio/citation-style-language/csl-locales-tr-TR.xml
-2022/03/21 | 20747 | biblio/citation-style-language/csl-locales-uk-UA.xml
-2022/03/21 | 21812 | biblio/citation-style-language/csl-locales-vi-VN.xml
-2022/03/21 | 19056 | biblio/citation-style-language/csl-locales-zh-CN.xml
-2022/03/21 | 19423 | biblio/citation-style-language/csl-locales-zh-TW.xml
-2022/03/21 | 3443 | biblio/citation-style-language/csl.lua
-2022/03/21 | 8128 | biblio/citation-style-language/elsevier-harvard.csl
-2022/03/21 | 10619 | biblio/citation-style-language/harvard-cite-them-right.csl
-2022/03/21 | 15413 | biblio/citation-style-language/ieee.csl
-2022/03/21 | 16054 | biblio/citation-style-language/modern-humanities-research-association.csl
-2022/03/21 | 11226 | biblio/citation-style-language/modern-language-association.csl
-2022/03/21 | 4534 | biblio/citation-style-language/nature.csl
-2022/03/21 | 1669 | biblio/citation-style-language/README.md
-2022/03/21 | 11927 | biblio/citation-style-language/vancouver.csl
-2022/03/21 | 555431 | biblio/citation-style-language.zip
+2022/08/19 | 10019 | biblio/citation-style-language/american-chemical-society.csl
+2022/08/19 | 11034 | biblio/citation-style-language/american-medical-association.csl
+2022/08/19 | 8052 | biblio/citation-style-language/american-political-science-association.csl
+2022/08/19 | 11060 | biblio/citation-style-language/american-sociological-association.csl
+2022/08/19 | 69907 | biblio/citation-style-language/apa.csl
+2022/08/19 | 2145 | biblio/citation-style-language/CHANGELOG.md
+2022/08/19 | 23079 | biblio/citation-style-language/chicago-author-date.csl
+2022/08/19 | 47520 | biblio/citation-style-language/chicago-fullnote-bibliography.csl
+2022/08/19 | 45970 | biblio/citation-style-language/chicago-note-bibliography.csl
+2022/08/19 | 220489 | biblio/citation-style-language/citation-style-language-doc.pdf
+2022/08/19 | 13278 | biblio/citation-style-language/citation-style-language-doc.tex
+2022/08/19 | 31273 | biblio/citation-style-language/citation-style-language.sty
+2022/08/19 | 40700 | biblio/citation-style-language/citeproc-bib-data.lua
+2022/08/19 | 14024 | biblio/citation-style-language/citeproc-bib.lua
+2022/08/19 | 4797 | biblio/citation-style-language/citeproc-cli.lua
+2022/08/19 | 8425 | biblio/citation-style-language/citeproc-context.lua
+2022/08/19 | 14833 | biblio/citation-style-language/citeproc-element.lua
+2022/08/19 | 61972 | biblio/citation-style-language/citeproc-engine.lua
+2022/08/19 | 2993 | biblio/citation-style-language/citeproc-ir-node.lua
+2022/08/19 | 7685 | biblio/citation-style-language/citeproc-latex-core.lua
+2022/08/19 | 3696 | biblio/citation-style-language/citeproc-latex.lua
+2022/08/19 | 411 | biblio/citation-style-language/citeproc.lua
+2022/08/19 | 617 | biblio/citation-style-language/citeproc-lua.1
+2022/08/19 | 240 | biblio/citation-style-language/citeproc-lua.lua
+2022/08/19 | 7308 | biblio/citation-style-language/citeproc-node-choose.lua
+2022/08/19 | 13585 | biblio/citation-style-language/citeproc-node-date.lua
+2022/08/19 | 904 | biblio/citation-style-language/citeproc-node-group.lua
+2022/08/19 | 2655 | biblio/citation-style-language/citeproc-node-label.lua
+2022/08/19 | 1702 | biblio/citation-style-language/citeproc-node-layout.lua
+2022/08/19 | 6100 | biblio/citation-style-language/citeproc-node-locale.lua
+2022/08/19 | 33702 | biblio/citation-style-language/citeproc-node-names.lua
+2022/08/19 | 1675 | biblio/citation-style-language/citeproc-node-number.lua
+2022/08/19 | 1476 | biblio/citation-style-language/citeproc-nodes.lua
+2022/08/19 | 6283 | biblio/citation-style-language/citeproc-node-sort.lua
+2022/08/19 | 15617 | biblio/citation-style-language/citeproc-node-style.lua
+2022/08/19 | 5498 | biblio/citation-style-language/citeproc-node-text.lua
+2022/08/19 | 44466 | biblio/citation-style-language/citeproc-output.lua
+2022/08/19 | 21517 | biblio/citation-style-language/citeproc-util.lua
+2022/08/19 | 21433 | biblio/citation-style-language/csl-locales-af-ZA.xml
+2022/08/19 | 19817 | biblio/citation-style-language/csl-locales-ar.xml
+2022/08/19 | 24466 | biblio/citation-style-language/csl-locales-bg-BG.xml
+2022/08/19 | 21302 | biblio/citation-style-language/csl-locales-ca-AD.xml
+2022/08/19 | 21579 | biblio/citation-style-language/csl-locales-cs-CZ.xml
+2022/08/19 | 21576 | biblio/citation-style-language/csl-locales-cy-GB.xml
+2022/08/19 | 21470 | biblio/citation-style-language/csl-locales-da-DK.xml
+2022/08/19 | 22218 | biblio/citation-style-language/csl-locales-de-AT.xml
+2022/08/19 | 21681 | biblio/citation-style-language/csl-locales-de-CH.xml
+2022/08/19 | 22143 | biblio/citation-style-language/csl-locales-de-DE.xml
+2022/08/19 | 23024 | biblio/citation-style-language/csl-locales-el-GR.xml
+2022/08/19 | 22472 | biblio/citation-style-language/csl-locales-en-GB.xml
+2022/08/19 | 22627 | biblio/citation-style-language/csl-locales-en-US.xml
+2022/08/19 | 21406 | biblio/citation-style-language/csl-locales-es-CL.xml
+2022/08/19 | 21327 | biblio/citation-style-language/csl-locales-es-ES.xml
+2022/08/19 | 22434 | biblio/citation-style-language/csl-locales-es-MX.xml
+2022/08/19 | 21261 | biblio/citation-style-language/csl-locales-et-EE.xml
+2022/08/19 | 21512 | biblio/citation-style-language/csl-locales-eu.xml
+2022/08/19 | 22337 | biblio/citation-style-language/csl-locales-fa-IR.xml
+2022/08/19 | 21623 | biblio/citation-style-language/csl-locales-fi-FI.xml
+2022/08/19 | 22098 | biblio/citation-style-language/csl-locales-fr-CA.xml
+2022/08/19 | 22356 | biblio/citation-style-language/csl-locales-fr-FR.xml
+2022/08/19 | 21822 | biblio/citation-style-language/csl-locales-he-IL.xml
+2022/08/19 | 24345 | biblio/citation-style-language/csl-locales-hi-IN.xml
+2022/08/19 | 21363 | biblio/citation-style-language/csl-locales-hr-HR.xml
+2022/08/19 | 21466 | biblio/citation-style-language/csl-locales-hu-HU.xml
+2022/08/19 | 21654 | biblio/citation-style-language/csl-locales-id-ID.xml
+2022/08/19 | 21469 | biblio/citation-style-language/csl-locales-is-IS.xml
+2022/08/19 | 23360 | biblio/citation-style-language/csl-locales-it-IT.xml
+2022/08/19 | 21482 | biblio/citation-style-language/csl-locales-ja-JP.xml
+2022/08/19 | 21966 | biblio/citation-style-language/csl-locales-km-KH.xml
+2022/08/19 | 21414 | biblio/citation-style-language/csl-locales-ko-KR.xml
+2022/08/19 | 21302 | biblio/citation-style-language/csl-locales-la.xml
+2022/08/19 | 22752 | biblio/citation-style-language/csl-locales-lt-LT.xml
+2022/08/19 | 23553 | biblio/citation-style-language/csl-locales-lv-LV.xml
+2022/08/19 | 21941 | biblio/citation-style-language/csl-locales-mn-MN.xml
+2022/08/19 | 21323 | biblio/citation-style-language/csl-locales-nb-NO.xml
+2022/08/19 | 22358 | biblio/citation-style-language/csl-locales-nl-NL.xml
+2022/08/19 | 21301 | biblio/citation-style-language/csl-locales-nn-NO.xml
+2022/08/19 | 21446 | biblio/citation-style-language/csl-locales-pl-PL.xml
+2022/08/19 | 22542 | biblio/citation-style-language/csl-locales-pt-BR.xml
+2022/08/19 | 22454 | biblio/citation-style-language/csl-locales-pt-PT.xml
+2022/08/19 | 21462 | biblio/citation-style-language/csl-locales-ro-RO.xml
+2022/08/19 | 25715 | biblio/citation-style-language/csl-locales-ru-RU.xml
+2022/08/19 | 21574 | biblio/citation-style-language/csl-locales-sk-SK.xml
+2022/08/19 | 21330 | biblio/citation-style-language/csl-locales-sl-SI.xml
+2022/08/19 | 22122 | biblio/citation-style-language/csl-locales-sr-RS.xml
+2022/08/19 | 21715 | biblio/citation-style-language/csl-locales-sv-SE.xml
+2022/08/19 | 23467 | biblio/citation-style-language/csl-locales-th-TH.xml
+2022/08/19 | 21635 | biblio/citation-style-language/csl-locales-tr-TR.xml
+2022/08/19 | 20747 | biblio/citation-style-language/csl-locales-uk-UA.xml
+2022/08/19 | 21812 | biblio/citation-style-language/csl-locales-vi-VN.xml
+2022/08/19 | 19056 | biblio/citation-style-language/csl-locales-zh-CN.xml
+2022/08/19 | 19423 | biblio/citation-style-language/csl-locales-zh-TW.xml
+2022/08/19 | 196 | biblio/citation-style-language/DEPENDS.txt
+2022/08/19 | 8128 | biblio/citation-style-language/elsevier-harvard.csl
+2022/08/19 | 10723 | biblio/citation-style-language/harvard-cite-them-right.csl
+2022/08/19 | 15413 | biblio/citation-style-language/ieee.csl
+2022/08/19 | 16054 | biblio/citation-style-language/modern-humanities-research-association.csl
+2022/08/19 | 11209 | biblio/citation-style-language/modern-language-association.csl
+2022/08/19 | 5288 | biblio/citation-style-language/nature.csl
+2022/08/19 | 1673 | biblio/citation-style-language/README.md
+2022/08/19 | 11958 | biblio/citation-style-language/vancouver.csl
+2022/08/18 | 577055 | biblio/citation-style-language.zip
2022/02/06 | 3110 | biblio/pbibtex/pbibtex-base/cpp.awk
2022/02/06 | 1009 | biblio/pbibtex/pbibtex-base/generate.sh
2022/02/06 | 22422 | biblio/pbibtex/pbibtex-base/jabbrv.bst
@@ -5264,7 +5267,7 @@
1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp
1990/10/02 | 812 | dviware/vutex/vaxvms.ins
1990/10/02 | 127576 | dviware/vutex/vutex.web
-2022/08/17 | 89208 | FILES.last07days
+2022/08/18 | 95093 | FILES.last07days
2021/07/24 | 1139410 | fonts/aboensis/Aboensis.glyphs
2021/07/24 | 18907382 | fonts/aboensis/aboensis.pdf
2021/07/24 | 137860 | fonts/aboensis/Aboensis-Regular.otf
@@ -158429,6 +158432,12 @@
2021/07/17 | 313369 | graphics/pgf/contrib/easing/easing.pdf
2021/07/17 | 399 | graphics/pgf/contrib/easing/README
2021/07/17 | 319237 | graphics/pgf/contrib/easing.zip
+2022/08/18 | 248260 | graphics/pgf/contrib/fancyqr/fancyqr-doc.pdf
+2022/08/18 | 4485 | graphics/pgf/contrib/fancyqr/fancyqr-doc.tex
+2022/08/18 | 10265 | graphics/pgf/contrib/fancyqr/fancyqr.sty
+2022/08/18 | 813 | graphics/pgf/contrib/fancyqr/qr-example.tex
+2022/08/18 | 3582 | graphics/pgf/contrib/fancyqr/README.md
+2022/08/18 | 251020 | graphics/pgf/contrib/fancyqr.zip
2013/02/27 | 17141 | graphics/pgf/contrib/fast-diagram/fast-diagram.sty
2013/02/27 | 1050633 | graphics/pgf/contrib/fast-diagram/help.pdf
2013/02/27 | 1437 | graphics/pgf/contrib/fast-diagram/help.tex
@@ -188723,7 +188732,7 @@
2022/06/20 | 140748 | info/yet-another-guide-latex2e/Yet-Another-Guide-LaTeX2e_v1.tex
2022/06/20 | 899385 | info/yet-another-guide-latex2e.zip
2021/02/04 | 4944311 | install/biblio/bibtex/contrib/gost.tds.zip
-2022/03/21 | 559357 | install/biblio/citation-style-language.tds.zip
+2022/08/19 | 580030 | install/biblio/citation-style-language.tds.zip
2013/11/06 | 795801 | install/fonts/accanthis.tds.zip
2009/05/23 | 246025 | install/fonts/ae.tds.zip
2019/10/12 | 38525845 | install/fonts/alegreya.tds.zip
@@ -276442,7 +276451,7 @@
2021/05/03 | 629 | support/TeX4ht/doc/README
2020/08/24 | 358454 | support/TeX4ht/doc/TeX4ht-doc.tex
2021/05/11 | 262 | support/TeX4ht/README
-2022/08/11 | 199643 | support/TeX4ht/source/ChangeLog
+2022/08/17 | 200199 | support/TeX4ht/source/ChangeLog
2021/05/03 | 1375 | support/TeX4ht/source/checklog.lua
2021/05/03 | 1189 | support/TeX4ht/source/common-code.tex
2021/05/03 | 2727 | support/TeX4ht/source/common-info.tex
@@ -276450,11 +276459,11 @@
2021/05/06 | 15 | support/TeX4ht/source/extra-bin/vcss
2021/05/06 | 15 | support/TeX4ht/source/extra-bin/xmllint
2022/08/07 | 27321 | support/TeX4ht/source/Makefile
-2022/06/20 | 8082 | support/TeX4ht/source/mktex4ht-cnf.tex
+2022/08/17 | 8111 | support/TeX4ht/source/mktex4ht-cnf.tex
2021/05/03 | 1121 | support/TeX4ht/source/README
2021/05/03 | 1744 | support/TeX4ht/source/t1fontmake.lua
2021/05/03 | 297 | support/TeX4ht/source/t1fontsample.tex
-2022/08/07 | 1127331 | support/TeX4ht/source/tex4ht-4ht.tex
+2022/08/17 | 1128043 | support/TeX4ht/source/tex4ht-4ht.tex
2021/05/03 | 7127 | support/TeX4ht/source/tex4ht-auto-script.tex
2021/05/16 | 1539 | support/TeX4ht/source/tex4ht-bibtex2.tex
2022/06/05 | 21307 | support/TeX4ht/source/tex4ht-cond4ht.tex
@@ -276480,7 +276489,7 @@
2021/05/03 | 14218 | support/TeX4ht/source/tex4ht-htcmd.tex
2021/05/03 | 70683 | support/TeX4ht/source/tex4ht-html0.tex
2021/05/03 | 164748 | support/TeX4ht/source/tex4ht-html32.tex
-2022/05/22 | 617510 | support/TeX4ht/source/tex4ht-html4.tex
+2022/08/17 | 617532 | support/TeX4ht/source/tex4ht-html4.tex
2022/08/11 | 11077 | support/TeX4ht/source/tex4ht-html5.tex
2021/06/17 | 648233 | support/TeX4ht/source/tex4ht-html-speech.tex
2021/05/03 | 59483 | support/TeX4ht/source/tex4ht-html-speech-xtpipes.tex
@@ -277780,10 +277789,10 @@
2007/07/22 | 600 | support/wp2latex/readme.1st
2021/08/01 | 7401 | support/wp2latex/readme.txt
2020/02/11 | 305310 | support/wp2latex/wp2latex-3.87.deb
-2020/10/12 | 3641715 | support/wp2latex/wp2latex-3.92.zip
+2021/01/23 | 3690318 | support/wp2latex/wp2latex-3.93.zip
2018/01/26 | 45297 | support/wp2latex/wp2latex.doc.htm
2018/01/26 | 7259 | support/wp2latex/wp2latex.faq
-2020/10/11 | 1642418 | support/wp2latex/WP2LaTeX_Installer-3.92.exe
+2021/01/23 | 1635025 | support/wp2latex/WP2LaTeX_Installer-3.93b.exe
2021/08/01 | 1241 | support/wp2latex/wp2latex.lsm
2018/01/26 | 35145 | support/wp2latex/wp2latex_pas-2.3.zip
2000/02/22 | 481 | support/wsuipa2tipa/README
@@ -284422,14 +284431,14 @@
2019/02/28 | 377000 | systems/texlive/tlnet/archive/examdesign.doc.r15878.tar.xz
2019/02/28 | 10780 | systems/texlive/tlnet/archive/examdesign.r15878.tar.xz
2019/02/28 | 29924 | systems/texlive/tlnet/archive/examdesign.source.r15878.tar.xz
-2021/03/02 | 515428 | systems/texlive/tlnet/archive/exam.doc.r58023.tar.xz
+2022/08/18 | 524800 | systems/texlive/tlnet/archive/exam.doc.r64134.tar.xz
2019/02/28 | 820032 | systems/texlive/tlnet/archive/exam-n.doc.r42755.tar.xz
2019/02/28 | 11804 | systems/texlive/tlnet/archive/exam-n.r42755.tar.xz
2019/02/28 | 34424 | systems/texlive/tlnet/archive/exam-n.source.r42755.tar.xz
2020/05/25 | 379128 | systems/texlive/tlnet/archive/examplep.doc.r55265.tar.xz
2020/05/25 | 33788 | systems/texlive/tlnet/archive/examplep.r55265.tar.xz
2019/02/28 | 5516 | systems/texlive/tlnet/archive/example.r33398.tar.xz
-2021/03/02 | 49904 | systems/texlive/tlnet/archive/exam.r58023.tar.xz
+2022/08/18 | 49900 | systems/texlive/tlnet/archive/exam.r64134.tar.xz
2022/01/24 | 313712 | systems/texlive/tlnet/archive/exam-randomizechoices.doc.r61719.tar.xz
2022/01/24 | 5624 | systems/texlive/tlnet/archive/exam-randomizechoices.r61719.tar.xz
2022/08/16 | 1739528 | systems/texlive/tlnet/archive/exam-zh.doc.r64123.tar.xz
@@ -284726,9 +284735,9 @@
2019/02/28 | 496576 | systems/texlive/tlnet/archive/fitbox.doc.r50088.tar.xz
2019/02/28 | 2228 | systems/texlive/tlnet/archive/fitbox.r50088.tar.xz
2019/02/28 | 5812 | systems/texlive/tlnet/archive/fitbox.source.r50088.tar.xz
-2021/10/19 | 729804 | systems/texlive/tlnet/archive/fithesis.doc.r60795.tar.xz
-2021/10/19 | 791532 | systems/texlive/tlnet/archive/fithesis.r60795.tar.xz
-2021/10/19 | 44752 | systems/texlive/tlnet/archive/fithesis.source.r60795.tar.xz
+2022/08/18 | 730120 | systems/texlive/tlnet/archive/fithesis.doc.r64135.tar.xz
+2022/08/18 | 792156 | systems/texlive/tlnet/archive/fithesis.r64135.tar.xz
+2022/08/18 | 45332 | systems/texlive/tlnet/archive/fithesis.source.r64135.tar.xz
2019/02/28 | 212644 | systems/texlive/tlnet/archive/fix2col.doc.r38770.tar.xz
2019/02/28 | 2684 | systems/texlive/tlnet/archive/fix2col.r38770.tar.xz
2019/02/28 | 6376 | systems/texlive/tlnet/archive/fix2col.source.r38770.tar.xz
@@ -285644,8 +285653,8 @@
2021/11/28 | 6640 | systems/texlive/tlnet/archive/hep-title.source.r61173.tar.xz
2020/04/16 | 100060 | systems/texlive/tlnet/archive/hepunits.doc.r54758.tar.xz
2020/04/16 | 1804 | systems/texlive/tlnet/archive/hepunits.r54758.tar.xz
-2022/08/15 | 63056 | systems/texlive/tlnet/archive/hereapplies.doc.r64117.tar.xz
-2022/08/15 | 3216 | systems/texlive/tlnet/archive/hereapplies.r64117.tar.xz
+2022/08/18 | 64028 | systems/texlive/tlnet/archive/hereapplies.doc.r64136.tar.xz
+2022/08/18 | 3748 | systems/texlive/tlnet/archive/hereapplies.r64136.tar.xz
2019/02/28 | 596 | systems/texlive/tlnet/archive/here.doc.r16135.tar.xz
2019/02/28 | 896 | systems/texlive/tlnet/archive/here.r16135.tar.xz
2019/02/28 | 213100 | systems/texlive/tlnet/archive/he-she.doc.r41359.tar.xz
@@ -289779,8 +289788,8 @@
2019/02/28 | 378272 | systems/texlive/tlnet/archive/productbox.doc.r20886.tar.xz
2019/02/28 | 4944 | systems/texlive/tlnet/archive/productbox.r20886.tar.xz
2019/02/28 | 15512 | systems/texlive/tlnet/archive/productbox.source.r20886.tar.xz
-2022/08/03 | 10015344 | systems/texlive/tlnet/archive/profcollege.doc.r64032.tar.xz
-2022/08/03 | 1210836 | systems/texlive/tlnet/archive/profcollege.r64032.tar.xz
+2022/08/18 | 10136040 | systems/texlive/tlnet/archive/profcollege.doc.r64137.tar.xz
+2022/08/18 | 1211724 | systems/texlive/tlnet/archive/profcollege.r64137.tar.xz
2022/04/27 | 134096 | systems/texlive/tlnet/archive/proflabo.doc.r63147.tar.xz
2022/04/27 | 2748 | systems/texlive/tlnet/archive/proflabo.r63147.tar.xz
2022/08/17 | 855220 | systems/texlive/tlnet/archive/proflycee.doc.r64130.tar.xz
@@ -291650,14 +291659,14 @@
2022/02/27 | 108804 | systems/texlive/tlnet/archive/tex4ht.amd64-freebsd.r62206.tar.xz
2022/02/27 | 87364 | systems/texlive/tlnet/archive/tex4ht.amd64-netbsd.r62220.tar.xz
2022/04/21 | 69948 | systems/texlive/tlnet/archive/tex4ht.armhf-linux.r63092.tar.xz
-2022/08/12 | 136384 | systems/texlive/tlnet/archive/tex4ht.doc.r64099.tar.xz
+2022/08/18 | 136388 | systems/texlive/tlnet/archive/tex4ht.doc.r64138.tar.xz
2022/03/01 | 58328 | systems/texlive/tlnet/archive/tex4ht.i386-cygwin.r62282.tar.xz
2022/02/27 | 93760 | systems/texlive/tlnet/archive/tex4ht.i386-freebsd.r62206.tar.xz
2022/02/27 | 91280 | systems/texlive/tlnet/archive/tex4ht.i386-linux.r62210.tar.xz
2022/02/27 | 76200 | systems/texlive/tlnet/archive/tex4ht.i386-netbsd.r62220.tar.xz
2022/02/27 | 83964 | systems/texlive/tlnet/archive/tex4ht.i386-solaris.r62206.tar.xz
-2022/08/12 | 952476 | systems/texlive/tlnet/archive/tex4ht.r64099.tar.xz
-2022/08/12 | 1272264 | systems/texlive/tlnet/archive/tex4ht.source.r64099.tar.xz
+2022/08/18 | 952684 | systems/texlive/tlnet/archive/tex4ht.r64138.tar.xz
+2022/08/18 | 1274892 | systems/texlive/tlnet/archive/tex4ht.source.r64138.tar.xz
2022/02/28 | 184748 | systems/texlive/tlnet/archive/tex4ht.universal-darwin.r62258.tar.xz
2022/02/27 | 57768 | systems/texlive/tlnet/archive/tex4ht.win32.r62199.tar.xz
2022/03/01 | 58016 | systems/texlive/tlnet/archive/tex4ht.x86_64-cygwin.r62279.tar.xz
@@ -291892,7 +291901,7 @@
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.amd64-freebsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.amd64-netbsd.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.armhf-linux.r55172.tar.xz
-2022/08/17 | 419496 | systems/texlive/tlnet/archive/texlive-scripts.doc.r64126.tar.xz
+2022/08/18 | 419376 | systems/texlive/tlnet/archive/texlive-scripts.doc.r64133.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.aarch64-linux.r53577.tar.xz
2020/01/27 | 924 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-freebsd.r53577.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-netbsd.r53577.tar.xz
@@ -291916,7 +291925,7 @@
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-linux.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.i386-netbsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-solaris.r55172.tar.xz
-2022/08/17 | 113524 | systems/texlive/tlnet/archive/texlive-scripts.r64126.tar.xz
+2022/08/18 | 113500 | systems/texlive/tlnet/archive/texlive-scripts.r64133.tar.xz
2021/02/25 | 572 | systems/texlive/tlnet/archive/texlive-scripts.universal-darwin.r57908.tar.xz
2022/04/19 | 36296 | systems/texlive/tlnet/archive/texlive-scripts.win32.r63068.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-cygwin.r55172.tar.xz
@@ -293741,16 +293750,16 @@
2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz
2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz
2022/07/17 | 124404 | systems/texlive/tlnet/install-tl
-2022/08/17 | 5831896 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2022/08/17 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2022/08/18 | 5831895 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2022/08/18 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2021/04/11 | 4945 | systems/texlive/tlnet/install-tl-windows.bat
-2022/08/17 | 20436545 | systems/texlive/tlnet/install-tl-windows.exe
-2022/08/17 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2022/08/17 | 25516446 | systems/texlive/tlnet/install-tl.zip
-2022/08/17 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2022/08/18 | 20433402 | systems/texlive/tlnet/install-tl-windows.exe
+2022/08/18 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2022/08/18 | 25516427 | systems/texlive/tlnet/install-tl.zip
+2022/08/18 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
2022/04/03 | 1229 | systems/texlive/tlnet/README.md
2022/04/03 | 0 | systems/texlive/tlnet/TEXLIVE_2022
2022/02/28 | 7791 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg
@@ -293760,7 +293769,7 @@
2022/02/28 | 1280 | systems/texlive/tlnet/tlpkg/gpg/trustdb.gpg
2022/05/27 | 49794 | systems/texlive/tlnet/tlpkg/installer/config.guess
2010/11/11 | 11651 | systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt
-2022/08/16 | 7321 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+2022/08/17 | 7221 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2022/07/21 | 222477 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt
2020/04/15 | 2606592 | systems/texlive/tlnet/tlpkg/installer/curl/curl.exe
2017/04/16 | 2629 | systems/texlive/tlnet/tlpkg/installer/installer-options.txt
@@ -293803,12 +293812,12 @@
2021/05/16 | 20371 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm
2021/12/21 | 5429 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm
2021/12/21 | 27582 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm
-2022/08/17 | 17582689 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2022/08/17 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2022/08/18 | 17582691 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2022/08/18 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
2022/04/18 | 86658 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm
-2022/08/17 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2022/08/17 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2022/08/17 | 2397600 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2022/08/18 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2022/08/18 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2022/08/18 | 2399360 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
2021/12/21 | 58848 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm
2022/08/01 | 42206 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm
2021/12/21 | 16130 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm
@@ -299081,7 +299090,7 @@
2020/10/03 | 318630 | systems/win32/miktex/tm/packages/filehook.tar.lzma
2012/12/04 | 924573 | systems/win32/miktex/tm/packages/fileinfo.tar.lzma
2011/09/21 | 281409 | systems/win32/miktex/tm/packages/filemod.tar.lzma
-2022/08/17 | 659342 | systems/win32/miktex/tm/packages/files.csv.lzma
+2022/08/18 | 659342 | systems/win32/miktex/tm/packages/files.csv.lzma
2001/05/14 | 5617 | systems/win32/miktex/tm/packages/finbib.tar.lzma
2015/10/20 | 44379 | systems/win32/miktex/tm/packages/findhyph.tar.lzma
2011/10/21 | 89323 | systems/win32/miktex/tm/packages/fink.tar.lzma
@@ -300763,9 +300772,9 @@
2018/01/12 | 157226 | systems/win32/miktex/tm/packages/miktex-zip-bin-x64.tar.lzma
2022/07/26 | 39695 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma
2022/08/13 | 43580 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma
-2022/08/17 | 289560 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2022/08/17 | 1482162 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2022/08/17 | 1364924 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2022/08/18 | 289514 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2022/08/18 | 1483018 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2022/08/18 | 1364956 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
2022/07/26 | 13519 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma
2022/08/13 | 14417 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma
2016/07/15 | 35914 | systems/win32/miktex/tm/packages/mil3.tar.lzma
@@ -301006,102 +301015,102 @@
2018/04/09 | 400132 | systems/win32/miktex/tm/packages/newunicodechar.tar.lzma
2011/09/19 | 101312 | systems/win32/miktex/tm/packages/newvbtm.tar.lzma
2021/03/17 | 232249 | systems/win32/miktex/tm/packages/newverbs.tar.lzma
-2022/08/17 | 659852 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2022/08/17 | 57317 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2022/08/17 | 1161751 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
-2022/08/17 | 31585 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2022/08/17 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2022/08/17 | 65130 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2022/08/17 | 95467 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2022/08/17 | 77209 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2022/08/17 | 31561 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
-2022/08/17 | 394142 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2022/08/17 | 37050 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
-2022/08/17 | 57505 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2022/08/17 | 270464 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2022/08/17 | 196212 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2022/08/17 | 103245 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
-2022/08/17 | 24210 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2022/08/17 | 481892 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2022/08/17 | 52037 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2022/08/17 | 325978 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2022/08/17 | 45793 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
-2022/08/17 | 135465 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2022/08/17 | 1458151 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2022/08/17 | 112979 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2022/08/17 | 48851 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2022/08/17 | 28509 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2022/08/17 | 63239 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2022/08/17 | 155431 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2022/08/17 | 79062 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
-2022/08/17 | 81448 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
-2022/08/17 | 295943 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
-2022/08/17 | 25118 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2022/08/17 | 112877 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
-2022/08/17 | 73262 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2022/08/17 | 115580 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2022/08/17 | 43888 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2022/08/17 | 565081 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2022/08/17 | 247205 | systems/win32/miktex/tm/packages/next/miktex-hitex-bin-x64.tar.lzma
-2022/08/17 | 169677 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
-2022/08/17 | 109650 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2022/08/17 | 18382 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2022/08/17 | 30570 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
-2022/08/17 | 682213 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2022/08/17 | 599105 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
-2022/08/17 | 527570 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2022/08/17 | 103596 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2022/08/17 | 2023133 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2022/08/17 | 74099 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2022/08/17 | 32072 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
-2022/08/17 | 8824 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2022/08/17 | 209137 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
-2022/08/17 | 286684 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2022/08/17 | 104921 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
-2022/08/17 | 140012 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2022/08/17 | 325483 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2022/08/17 | 181723 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2022/08/17 | 55319 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2022/08/17 | 35228 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2022/08/17 | 43616 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2022/08/17 | 48037 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2022/08/17 | 52369 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
-2022/08/17 | 213846 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2022/08/17 | 41179 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2022/08/17 | 824994 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
-2022/08/17 | 203418 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2022/08/17 | 245151 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2022/08/17 | 88483 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2022/08/17 | 1323744 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2022/08/17 | 23949 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
-2022/08/17 | 37507 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2022/08/17 | 72978 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2022/08/17 | 58633 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2022/08/17 | 769650 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
-2022/08/17 | 1503052 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2022/08/17 | 52627 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2022/08/17 | 63801 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
-2022/08/17 | 27464 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2022/08/17 | 18510 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2022/08/17 | 70939 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2022/08/17 | 173177 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2022/08/17 | 68146 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
-2022/08/17 | 107436 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2022/08/17 | 2821670 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
-2022/08/17 | 62359 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2022/08/17 | 41189 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2022/08/17 | 33861 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2022/08/17 | 73684 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2022/08/17 | 352464 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
-2022/08/17 | 57501 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2022/08/17 | 630433 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2022/08/17 | 43527 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2022/08/17 | 289497 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2022/08/17 | 1481405 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2022/08/17 | 1364461 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2022/08/17 | 14433 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2022/08/18 | 659852 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2022/08/18 | 57316 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2022/08/18 | 1161753 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2022/08/18 | 31587 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2022/08/18 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2022/08/18 | 65131 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2022/08/18 | 95468 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2022/08/18 | 77211 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2022/08/18 | 31563 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2022/08/18 | 394143 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2022/08/18 | 37051 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2022/08/18 | 57503 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2022/08/18 | 270467 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2022/08/18 | 196213 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2022/08/18 | 103246 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2022/08/18 | 24207 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2022/08/18 | 481893 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2022/08/18 | 52037 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2022/08/18 | 325980 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2022/08/18 | 45794 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2022/08/18 | 135465 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2022/08/18 | 1458151 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2022/08/18 | 112980 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2022/08/18 | 48852 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2022/08/18 | 28510 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2022/08/18 | 63240 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2022/08/18 | 155431 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2022/08/18 | 79063 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2022/08/18 | 81448 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2022/08/18 | 295944 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2022/08/18 | 25118 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2022/08/18 | 112878 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2022/08/18 | 73263 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2022/08/18 | 115580 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2022/08/18 | 43887 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2022/08/18 | 565082 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2022/08/18 | 247208 | systems/win32/miktex/tm/packages/next/miktex-hitex-bin-x64.tar.lzma
+2022/08/18 | 169678 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2022/08/18 | 109651 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2022/08/18 | 18382 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2022/08/18 | 30570 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2022/08/18 | 682214 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2022/08/18 | 599103 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2022/08/18 | 527569 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2022/08/18 | 103598 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2022/08/18 | 2023132 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2022/08/18 | 74099 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2022/08/18 | 32073 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2022/08/18 | 8825 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2022/08/18 | 209139 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2022/08/18 | 286685 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2022/08/18 | 104920 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2022/08/18 | 140012 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2022/08/18 | 325483 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2022/08/18 | 181724 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2022/08/18 | 55320 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2022/08/18 | 35231 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2022/08/18 | 43618 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2022/08/18 | 48038 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2022/08/18 | 52369 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2022/08/18 | 213847 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2022/08/18 | 41179 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2022/08/18 | 824995 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2022/08/18 | 203420 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2022/08/18 | 245151 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2022/08/18 | 88483 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2022/08/18 | 1323744 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2022/08/18 | 23948 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2022/08/18 | 37506 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2022/08/18 | 72978 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2022/08/18 | 58634 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2022/08/18 | 769652 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
+2022/08/18 | 1503053 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2022/08/18 | 52628 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2022/08/18 | 63803 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2022/08/18 | 27465 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2022/08/18 | 18511 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2022/08/18 | 70939 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2022/08/18 | 173177 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2022/08/18 | 68147 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2022/08/18 | 107437 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2022/08/18 | 2821671 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2022/08/18 | 62359 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2022/08/18 | 41190 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2022/08/18 | 33862 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2022/08/18 | 73685 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2022/08/18 | 352464 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2022/08/18 | 57501 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2022/08/18 | 630436 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2022/08/18 | 43527 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2022/08/18 | 289517 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2022/08/18 | 1480825 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2022/08/18 | 1364365 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2022/08/18 | 14433 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2019/03/12 | 1412 | systems/win32/miktex/tm/packages/nextpage.tar.lzma
-2022/08/17 | 1172 | systems/win32/miktex/tm/packages/next/pr.ini
+2022/08/18 | 1172 | systems/win32/miktex/tm/packages/next/pr.ini
2018/07/06 | 145915 | systems/win32/miktex/tm/packages/nexus-otf.tar.lzma
2017/03/30 | 191149 | systems/win32/miktex/tm/packages/nfssext-cfr.tar.lzma
2012/12/20 | 612251 | systems/win32/miktex/tm/packages/nicefilelist.tar.lzma
@@ -301590,7 +301599,7 @@
2022/02/22 | 6917 | systems/win32/miktex/tm/packages/preview.tar.lzma
2019/06/20 | 375963 | systems/win32/miktex/tm/packages/prftree.tar.lzma
2021/04/23 | 274028 | systems/win32/miktex/tm/packages/principia.tar.lzma
-2022/08/17 | 933 | systems/win32/miktex/tm/packages/pr.ini
+2022/08/18 | 933 | systems/win32/miktex/tm/packages/pr.ini
2010/09/27 | 248469 | systems/win32/miktex/tm/packages/printlen.tar.lzma
2008/06/17 | 77313 | systems/win32/miktex/tm/packages/proba.tar.lzma
2017/07/12 | 988486 | systems/win32/miktex/tm/packages/probsoln.tar.lzma
@@ -303529,7 +303538,7 @@
2004/06/04 | 404 | tds/tds.sed
2004/06/23 | 65418 | tds/tds.tex
2019/05/29 | 304264 | tds.zip
-2022/08/18 | 186 | timestamp
+2022/08/19 | 186 | timestamp
2002/08/26 | 61898 | usergrps/dante/antrag.pdf
2002/08/26 | 118217 | usergrps/dante/antrag.ps
2022/02/28 | 917 | usergrps/dante/dtk/doc/beispiel.bib
diff --git a/FILES.byname.gz b/FILES.byname.gz
index 712b8678b3..39453ea6d4 100644
--- a/FILES.byname.gz
+++ b/FILES.byname.gz
Binary files differ
diff --git a/FILES.last07days b/FILES.last07days
index 26cc067371..9d4a18f0ba 100644
--- a/FILES.last07days
+++ b/FILES.last07days
@@ -1,3 +1,240 @@
+2022/08/19 | 904 | biblio/citation-style-language/citeproc-node-group.lua
+2022/08/19 | 8425 | biblio/citation-style-language/citeproc-context.lua
+2022/08/19 | 8128 | biblio/citation-style-language/elsevier-harvard.csl
+2022/08/19 | 8052 | biblio/citation-style-language/american-political-science-association.csl
+2022/08/19 | 7685 | biblio/citation-style-language/citeproc-latex-core.lua
+2022/08/19 | 7308 | biblio/citation-style-language/citeproc-node-choose.lua
+2022/08/19 | 69907 | biblio/citation-style-language/apa.csl
+2022/08/19 | 6283 | biblio/citation-style-language/citeproc-node-sort.lua
+2022/08/19 | 61972 | biblio/citation-style-language/citeproc-engine.lua
+2022/08/19 | 617 | biblio/citation-style-language/citeproc-lua.1
+2022/08/19 | 6100 | biblio/citation-style-language/citeproc-node-locale.lua
+2022/08/19 | 580030 | install/biblio/citation-style-language.tds.zip
+2022/08/19 | 5498 | biblio/citation-style-language/citeproc-node-text.lua
+2022/08/19 | 5288 | biblio/citation-style-language/nature.csl
+2022/08/19 | 4797 | biblio/citation-style-language/citeproc-cli.lua
+2022/08/19 | 47520 | biblio/citation-style-language/chicago-fullnote-bibliography.csl
+2022/08/19 | 45970 | biblio/citation-style-language/chicago-note-bibliography.csl
+2022/08/19 | 44466 | biblio/citation-style-language/citeproc-output.lua
+2022/08/19 | 411 | biblio/citation-style-language/citeproc.lua
+2022/08/19 | 40700 | biblio/citation-style-language/citeproc-bib-data.lua
+2022/08/19 | 3696 | biblio/citation-style-language/citeproc-latex.lua
+2022/08/19 | 33702 | biblio/citation-style-language/citeproc-node-names.lua
+2022/08/19 | 31273 | biblio/citation-style-language/citation-style-language.sty
+2022/08/19 | 2993 | biblio/citation-style-language/citeproc-ir-node.lua
+2022/08/19 | 2655 | biblio/citation-style-language/citeproc-node-label.lua
+2022/08/19 | 25715 | biblio/citation-style-language/csl-locales-ru-RU.xml
+2022/08/19 | 24466 | biblio/citation-style-language/csl-locales-bg-BG.xml
+2022/08/19 | 24345 | biblio/citation-style-language/csl-locales-hi-IN.xml
+2022/08/19 | 240 | biblio/citation-style-language/citeproc-lua.lua
+2022/08/19 | 23553 | biblio/citation-style-language/csl-locales-lv-LV.xml
+2022/08/19 | 23467 | biblio/citation-style-language/csl-locales-th-TH.xml
+2022/08/19 | 23360 | biblio/citation-style-language/csl-locales-it-IT.xml
+2022/08/19 | 23079 | biblio/citation-style-language/chicago-author-date.csl
+2022/08/19 | 23024 | biblio/citation-style-language/csl-locales-el-GR.xml
+2022/08/19 | 22752 | biblio/citation-style-language/csl-locales-lt-LT.xml
+2022/08/19 | 22627 | biblio/citation-style-language/csl-locales-en-US.xml
+2022/08/19 | 22542 | biblio/citation-style-language/csl-locales-pt-BR.xml
+2022/08/19 | 22472 | biblio/citation-style-language/csl-locales-en-GB.xml
+2022/08/19 | 22454 | biblio/citation-style-language/csl-locales-pt-PT.xml
+2022/08/19 | 22434 | biblio/citation-style-language/csl-locales-es-MX.xml
+2022/08/19 | 22358 | biblio/citation-style-language/csl-locales-nl-NL.xml
+2022/08/19 | 22356 | biblio/citation-style-language/csl-locales-fr-FR.xml
+2022/08/19 | 22337 | biblio/citation-style-language/csl-locales-fa-IR.xml
+2022/08/19 | 22218 | biblio/citation-style-language/csl-locales-de-AT.xml
+2022/08/19 | 22143 | biblio/citation-style-language/csl-locales-de-DE.xml
+2022/08/19 | 22122 | biblio/citation-style-language/csl-locales-sr-RS.xml
+2022/08/19 | 22098 | biblio/citation-style-language/csl-locales-fr-CA.xml
+2022/08/19 | 220489 | biblio/citation-style-language/citation-style-language-doc.pdf
+2022/08/19 | 21966 | biblio/citation-style-language/csl-locales-km-KH.xml
+2022/08/19 | 21941 | biblio/citation-style-language/csl-locales-mn-MN.xml
+2022/08/19 | 21822 | biblio/citation-style-language/csl-locales-he-IL.xml
+2022/08/19 | 21812 | biblio/citation-style-language/csl-locales-vi-VN.xml
+2022/08/19 | 21715 | biblio/citation-style-language/csl-locales-sv-SE.xml
+2022/08/19 | 21681 | biblio/citation-style-language/csl-locales-de-CH.xml
+2022/08/19 | 21654 | biblio/citation-style-language/csl-locales-id-ID.xml
+2022/08/19 | 21635 | biblio/citation-style-language/csl-locales-tr-TR.xml
+2022/08/19 | 21623 | biblio/citation-style-language/csl-locales-fi-FI.xml
+2022/08/19 | 21579 | biblio/citation-style-language/csl-locales-cs-CZ.xml
+2022/08/19 | 21576 | biblio/citation-style-language/csl-locales-cy-GB.xml
+2022/08/19 | 21574 | biblio/citation-style-language/csl-locales-sk-SK.xml
+2022/08/19 | 21517 | biblio/citation-style-language/citeproc-util.lua
+2022/08/19 | 21512 | biblio/citation-style-language/csl-locales-eu.xml
+2022/08/19 | 21482 | biblio/citation-style-language/csl-locales-ja-JP.xml
+2022/08/19 | 21470 | biblio/citation-style-language/csl-locales-da-DK.xml
+2022/08/19 | 21469 | biblio/citation-style-language/csl-locales-is-IS.xml
+2022/08/19 | 21466 | biblio/citation-style-language/csl-locales-hu-HU.xml
+2022/08/19 | 21462 | biblio/citation-style-language/csl-locales-ro-RO.xml
+2022/08/19 | 2145 | biblio/citation-style-language/CHANGELOG.md
+2022/08/19 | 21446 | biblio/citation-style-language/csl-locales-pl-PL.xml
+2022/08/19 | 21433 | biblio/citation-style-language/csl-locales-af-ZA.xml
+2022/08/19 | 21414 | biblio/citation-style-language/csl-locales-ko-KR.xml
+2022/08/19 | 21406 | biblio/citation-style-language/csl-locales-es-CL.xml
+2022/08/19 | 21363 | biblio/citation-style-language/csl-locales-hr-HR.xml
+2022/08/19 | 21330 | biblio/citation-style-language/csl-locales-sl-SI.xml
+2022/08/19 | 21327 | biblio/citation-style-language/csl-locales-es-ES.xml
+2022/08/19 | 21323 | biblio/citation-style-language/csl-locales-nb-NO.xml
+2022/08/19 | 21302 | biblio/citation-style-language/csl-locales-la.xml
+2022/08/19 | 21302 | biblio/citation-style-language/csl-locales-ca-AD.xml
+2022/08/19 | 21301 | biblio/citation-style-language/csl-locales-nn-NO.xml
+2022/08/19 | 21261 | biblio/citation-style-language/csl-locales-et-EE.xml
+2022/08/19 | 20747 | biblio/citation-style-language/csl-locales-uk-UA.xml
+2022/08/19 | 19817 | biblio/citation-style-language/csl-locales-ar.xml
+2022/08/19 | 196 | biblio/citation-style-language/DEPENDS.txt
+2022/08/19 | 19423 | biblio/citation-style-language/csl-locales-zh-TW.xml
+2022/08/19 | 19056 | biblio/citation-style-language/csl-locales-zh-CN.xml
+2022/08/19 | 1702 | biblio/citation-style-language/citeproc-node-layout.lua
+2022/08/19 | 1675 | biblio/citation-style-language/citeproc-node-number.lua
+2022/08/19 | 1673 | biblio/citation-style-language/README.md
+2022/08/19 | 16054 | biblio/citation-style-language/modern-humanities-research-association.csl
+2022/08/19 | 15617 | biblio/citation-style-language/citeproc-node-style.lua
+2022/08/19 | 15413 | biblio/citation-style-language/ieee.csl
+2022/08/19 | 14833 | biblio/citation-style-language/citeproc-element.lua
+2022/08/19 | 1476 | biblio/citation-style-language/citeproc-nodes.lua
+2022/08/19 | 14024 | biblio/citation-style-language/citeproc-bib.lua
+2022/08/19 | 13585 | biblio/citation-style-language/citeproc-node-date.lua
+2022/08/19 | 13278 | biblio/citation-style-language/citation-style-language-doc.tex
+2022/08/19 | 11958 | biblio/citation-style-language/vancouver.csl
+2022/08/19 | 11209 | biblio/citation-style-language/modern-language-association.csl
+2022/08/19 | 11060 | biblio/citation-style-language/american-sociological-association.csl
+2022/08/19 | 11034 | biblio/citation-style-language/american-medical-association.csl
+2022/08/19 | 10723 | biblio/citation-style-language/harvard-cite-them-right.csl
+2022/08/19 | 10019 | biblio/citation-style-language/american-chemical-society.csl
+2022/08/18 | 95468 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2022/08/18 | 952684 | systems/texlive/tlnet/archive/tex4ht.r64138.tar.xz
+2022/08/18 | 933 | systems/win32/miktex/tm/packages/pr.ini
+2022/08/18 | 88483 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2022/08/18 | 8825 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2022/08/18 | 824995 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2022/08/18 | 81448 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2022/08/18 | 813 | graphics/pgf/contrib/fancyqr/qr-example.tex
+2022/08/18 | 792156 | systems/texlive/tlnet/archive/fithesis.r64135.tar.xz
+2022/08/18 | 79063 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2022/08/18 | 77211 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2022/08/18 | 769652 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
+2022/08/18 | 74099 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2022/08/18 | 73685 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2022/08/18 | 73263 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2022/08/18 | 730120 | systems/texlive/tlnet/archive/fithesis.doc.r64135.tar.xz
+2022/08/18 | 72978 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2022/08/18 | 70939 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2022/08/18 | 682214 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2022/08/18 | 68147 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2022/08/18 | 659852 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2022/08/18 | 659342 | systems/win32/miktex/tm/packages/files.csv.lzma
+2022/08/18 | 65131 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2022/08/18 | 64028 | systems/texlive/tlnet/archive/hereapplies.doc.r64136.tar.xz
+2022/08/18 | 63803 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2022/08/18 | 63240 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2022/08/18 | 630436 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2022/08/18 | 62359 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2022/08/18 | 599103 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2022/08/18 | 58634 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2022/08/18 | 5831895 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2022/08/18 | 577055 | biblio/citation-style-language.zip
+2022/08/18 | 57503 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2022/08/18 | 57501 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2022/08/18 | 57316 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2022/08/18 | 565082 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2022/08/18 | 55320 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2022/08/18 | 527569 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2022/08/18 | 52628 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2022/08/18 | 524800 | systems/texlive/tlnet/archive/exam.doc.r64134.tar.xz
+2022/08/18 | 52369 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2022/08/18 | 52037 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2022/08/18 | 49900 | systems/texlive/tlnet/archive/exam.r64134.tar.xz
+2022/08/18 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2022/08/18 | 48852 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2022/08/18 | 481893 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2022/08/18 | 48038 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2022/08/18 | 45794 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2022/08/18 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2022/08/18 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2022/08/18 | 45332 | systems/texlive/tlnet/archive/fithesis.source.r64135.tar.xz
+2022/08/18 | 4485 | graphics/pgf/contrib/fancyqr/fancyqr-doc.tex
+2022/08/18 | 43887 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2022/08/18 | 43618 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2022/08/18 | 43527 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2022/08/18 | 419376 | systems/texlive/tlnet/archive/texlive-scripts.doc.r64133.tar.xz
+2022/08/18 | 41190 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2022/08/18 | 41179 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2022/08/18 | 394143 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2022/08/18 | 37506 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2022/08/18 | 3748 | systems/texlive/tlnet/archive/hereapplies.r64136.tar.xz
+2022/08/18 | 37051 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2022/08/18 | 3582 | graphics/pgf/contrib/fancyqr/README.md
+2022/08/18 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2022/08/18 | 352464 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2022/08/18 | 35231 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2022/08/18 | 33862 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2022/08/18 | 325980 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2022/08/18 | 325483 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2022/08/18 | 32073 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2022/08/18 | 31587 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2022/08/18 | 31563 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2022/08/18 | 30570 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2022/08/18 | 295944 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2022/08/18 | 289517 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2022/08/18 | 289514 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2022/08/18 | 286685 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2022/08/18 | 28510 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2022/08/18 | 2821671 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2022/08/18 | 27465 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2022/08/18 | 270467 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2022/08/18 | 25516427 | systems/texlive/tlnet/install-tl.zip
+2022/08/18 | 25118 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2022/08/18 | 251020 | graphics/pgf/contrib/fancyqr.zip
+2022/08/18 | 248260 | graphics/pgf/contrib/fancyqr/fancyqr-doc.pdf
+2022/08/18 | 247208 | systems/win32/miktex/tm/packages/next/miktex-hitex-bin-x64.tar.lzma
+2022/08/18 | 245151 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2022/08/18 | 24207 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2022/08/18 | 2399360 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2022/08/18 | 23948 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2022/08/18 | 213847 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2022/08/18 | 209139 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2022/08/18 | 20433402 | systems/texlive/tlnet/install-tl-windows.exe
+2022/08/18 | 203420 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2022/08/18 | 2023132 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2022/08/18 | 196213 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2022/08/18 | 18511 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2022/08/18 | 18382 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2022/08/18 | 181724 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2022/08/18 | 17582691 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2022/08/18 | 173177 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2022/08/18 | 169678 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2022/08/18 | 155431 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2022/08/18 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2022/08/18 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2022/08/18 | 1503053 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2022/08/18 | 1483018 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2022/08/18 | 1480825 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2022/08/18 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2022/08/18 | 1458151 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2022/08/18 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2022/08/18 | 14433 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2022/08/18 | 140012 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2022/08/18 | 1364956 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2022/08/18 | 1364365 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2022/08/18 | 136388 | systems/texlive/tlnet/archive/tex4ht.doc.r64138.tar.xz
+2022/08/18 | 135465 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2022/08/18 | 1323744 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2022/08/18 | 1274892 | systems/texlive/tlnet/archive/tex4ht.source.r64138.tar.xz
+2022/08/18 | 1211724 | systems/texlive/tlnet/archive/profcollege.r64137.tar.xz
+2022/08/18 | 1172 | systems/win32/miktex/tm/packages/next/pr.ini
+2022/08/18 | 1161753 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2022/08/18 | 115580 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2022/08/18 | 113500 | systems/texlive/tlnet/archive/texlive-scripts.r64133.tar.xz
+2022/08/18 | 112980 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2022/08/18 | 112878 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2022/08/18 | 109651 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2022/08/18 | 107437 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2022/08/18 | 104920 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2022/08/18 | 103598 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2022/08/18 | 103246 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2022/08/18 | 10265 | graphics/pgf/contrib/fancyqr/fancyqr.sty
+2022/08/18 | 10136040 | systems/texlive/tlnet/archive/profcollege.doc.r64137.tar.xz
2022/08/17 | 9955 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-color.pdf
2022/08/17 | 9945 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-czech-color.eps
2022/08/17 | 9931 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-czech.eps
@@ -6,13 +243,11 @@
2022/08/17 | 9661 | macros/luatex/generic/luavlna/luavlna-doc.tex
2022/08/17 | 9654 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-czech.eps
2022/08/17 | 95 | macros/latex/contrib/fithesis/style/mu/pharm.ins
-2022/08/17 | 95467 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
2022/08/17 | 9528 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-czech-color.eps
2022/08/17 | 9514 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-czech.eps
2022/08/17 | 93 | macros/latex/contrib/fithesis/style/mu/phil.ins
2022/08/17 | 93 | macros/latex/contrib/fithesis/style/mu/fsps.ins
2022/08/17 | 93 | macros/latex/contrib/fithesis/style/mu/econ.ins
-2022/08/17 | 933 | systems/win32/miktex/tm/packages/pr.ini
2022/08/17 | 92320 | macros/luatex/generic/luavlna/luavlna-doc.pdf
2022/08/17 | 91 | macros/latex/contrib/fithesis/style/mu/sci.ins
2022/08/17 | 91 | macros/latex/contrib/fithesis/style/mu/ped.ins
@@ -23,9 +258,7 @@
2022/08/17 | 8995 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-czech-color.eps
2022/08/17 | 8981 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-czech.eps
2022/08/17 | 893 | macros/latex/contrib/fithesis/locale/english.ins
-2022/08/17 | 88483 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
2022/08/17 | 88348 | macros/latex/contrib/fithesis/fithesis.dtx
-2022/08/17 | 8824 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
2022/08/17 | 8817716 | macros/latex/contrib/profcollege/doc/ProfCollege-doc.pdf
2022/08/17 | 87 | macros/latex/contrib/fithesis/style/base.ins
2022/08/17 | 8732 | macros/latex/contrib/fithesis/style/mu/med.dtx
@@ -33,34 +266,24 @@
2022/08/17 | 867213 | macros/latex/contrib/profcollege/latex/ProfCollege.sty
2022/08/17 | 855220 | systems/texlive/tlnet/archive/proflycee.doc.r64130.tar.xz
2022/08/17 | 845 | macros/latex/contrib/fithesis/locale/czech.ins
-2022/08/17 | 824994 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
-2022/08/17 | 81448 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2022/08/17 | 8111 | support/TeX4ht/source/mktex4ht-cnf.tex
2022/08/17 | 8082 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-czech-color.eps
2022/08/17 | 8068 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-czech.eps
-2022/08/17 | 79062 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
2022/08/17 | 7740 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-czech-color.eps
2022/08/17 | 7726 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-czech.eps
-2022/08/17 | 77209 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2022/08/17 | 769650 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
2022/08/17 | 767427 | macros/latex/contrib/fithesis/fithesis.pdf
2022/08/17 | 7560 | systems/texlive/tlnet/archive/pygmentex.r64131.tar.xz
2022/08/17 | 74997 | macros/latex/contrib/fithesis/style/mu/base.dtx
-2022/08/17 | 74099 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2022/08/17 | 73684 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2022/08/17 | 73262 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2022/08/17 | 72978 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
2022/08/17 | 7256 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-czech.eps
2022/08/17 | 7245 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-czech-color.eps
+2022/08/17 | 7221 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2022/08/17 | 7188 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil-czech-color.eps
2022/08/17 | 7174 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil-czech.eps
2022/08/17 | 715568 | systems/texlive/tlnet/archive/pygmentex.doc.r64131.tar.xz
-2022/08/17 | 70939 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
2022/08/17 | 705 | macros/luatex/generic/luavlna/luavlna-predegrees.lua
2022/08/17 | 7015 | macros/latex/contrib/fithesis/style/mu/fsps.dtx
2022/08/17 | 6917 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-english-color.eps
2022/08/17 | 6905 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-english.eps
-2022/08/17 | 682213 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2022/08/17 | 68146 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
2022/08/17 | 6778 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-czech-color.eps
2022/08/17 | 6765 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-czech-color.eps
2022/08/17 | 6764 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-czech.eps
@@ -69,39 +292,17 @@
2022/08/17 | 6734 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-czech-color.eps
2022/08/17 | 6720 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-czech.eps
2022/08/17 | 662 | macros/latex/contrib/fithesis/style/base.dtx
-2022/08/17 | 659852 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2022/08/17 | 659342 | systems/win32/miktex/tm/packages/files.csv.lzma
-2022/08/17 | 65130 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2022/08/17 | 63801 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
2022/08/17 | 6364 | macros/latex/contrib/fithesis/style/mu/law.dtx
-2022/08/17 | 63239 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
2022/08/17 | 63156 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci.eps
-2022/08/17 | 630433 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2022/08/17 | 62359 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2022/08/17 | 599105 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2022/08/17 | 617532 | support/TeX4ht/source/tex4ht-html4.tex
2022/08/17 | 595510 | macros/latex/contrib/fithesis/logo/mu/fithesis-base.eps
2022/08/17 | 588830 | macros/latex/contrib/exam.zip
-2022/08/17 | 58633 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2022/08/17 | 5831896 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2022/08/17 | 57505 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2022/08/17 | 57501 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2022/08/17 | 57317 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
2022/08/17 | 569182 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss.eps
-2022/08/17 | 565081 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2022/08/17 | 55319 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
2022/08/17 | 53503 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-color.eps
-2022/08/17 | 527570 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2022/08/17 | 52627 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2022/08/17 | 52369 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
2022/08/17 | 5215 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-english-color.eps
-2022/08/17 | 52037 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
2022/08/17 | 5201 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-english.eps
2022/08/17 | 5106 | macros/latex/contrib/fithesis/style/mu/phil.dtx
-2022/08/17 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
-2022/08/17 | 48851 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
2022/08/17 | 485896 | systems/texlive/tlnet/archive/lt3luabridge.doc.r64128.tar.xz
-2022/08/17 | 481892 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2022/08/17 | 48037 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
2022/08/17 | 4793 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-english-color.eps
2022/08/17 | 4779 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-english.eps
2022/08/17 | 46 | macros/luatex/generic/luavlna/luavlna.4ht
@@ -114,12 +315,7 @@
2022/08/17 | 4600 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-czech.pdf
2022/08/17 | 45934 | macros/latex/contrib/fithesis/logo/mu/fithesis-law.eps
2022/08/17 | 4591 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-english-color.eps
-2022/08/17 | 45793 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
2022/08/17 | 4577 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-english.eps
-2022/08/17 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2022/08/17 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2022/08/17 | 4558 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-english-color.eps
2022/08/17 | 4544 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-english.eps
2022/08/17 | 4524 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-english-color.eps
@@ -130,15 +326,9 @@
2022/08/17 | 449 | macros/luatex/generic/luavlna/luavlna-csplain-langs.lua
2022/08/17 | 4398 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-czech-color.pdf
2022/08/17 | 4393 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-czech.pdf
-2022/08/17 | 43888 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2022/08/17 | 43616 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2022/08/17 | 43527 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
2022/08/17 | 4289 | macros/luatex/generic/luavlna/luavlna.tex
2022/08/17 | 420604 | systems/texlive/tlnet/archive/msu-thesis.doc.r64129.tar.xz
-2022/08/17 | 419496 | systems/texlive/tlnet/archive/texlive-scripts.doc.r64126.tar.xz
2022/08/17 | 4119 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-czech-color.pdf
-2022/08/17 | 41189 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2022/08/17 | 41179 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
2022/08/17 | 4113 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-czech.pdf
2022/08/17 | 41114 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-color.pdf
2022/08/17 | 41093 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm.pdf
@@ -148,7 +338,6 @@
2022/08/17 | 4002 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-czech.pdf
2022/08/17 | 4000 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-english.eps
2022/08/17 | 3953 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-english-color.eps
-2022/08/17 | 394142 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
2022/08/17 | 3939 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-english.eps
2022/08/17 | 3866 | macros/latex/contrib/fithesis/style/mu/ped.dtx
2022/08/17 | 38432 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-color.eps
@@ -163,28 +352,17 @@
2022/08/17 | 3776 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-czech.pdf
2022/08/17 | 3771 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-english-color.pdf
2022/08/17 | 3767 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-english.pdf
-2022/08/17 | 37507 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
2022/08/17 | 3742 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-english-color.eps
2022/08/17 | 3728 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-english.eps
-2022/08/17 | 37050 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
2022/08/17 | 3702 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-czech-color.pdf
2022/08/17 | 3697 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-czech.pdf
2022/08/17 | 3631 | macros/latex/contrib/fithesis/README.md
2022/08/17 | 3611 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-english-color.eps
2022/08/17 | 3597 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-english.eps
-2022/08/17 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2022/08/17 | 352464 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
-2022/08/17 | 35228 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2022/08/17 | 33861 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
2022/08/17 | 3320 | macros/luatex/generic/luavlna/README.md
2022/08/17 | 3307 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-english-color.pdf
2022/08/17 | 3303 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-english.pdf
-2022/08/17 | 325978 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2022/08/17 | 325483 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2022/08/17 | 32072 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
2022/08/17 | 3189 | macros/latex/contrib/fithesis/style/mu/fss.dtx
-2022/08/17 | 31585 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2022/08/17 | 31561 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
2022/08/17 | 31390 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps.eps
2022/08/17 | 3131 | macros/luatex/generic/luavlna/luavlna-langno.lua
2022/08/17 | 3128 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil-english-color.pdf
@@ -196,43 +374,27 @@
2022/08/17 | 3069 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-english.pdf
2022/08/17 | 3068 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-english-color.pdf
2022/08/17 | 3063 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-english.pdf
-2022/08/17 | 30570 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
2022/08/17 | 30559 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ.eps
2022/08/17 | 3033 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-english-color.pdf
2022/08/17 | 3027 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-english.pdf
2022/08/17 | 29847 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-color.eps
-2022/08/17 | 295943 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
2022/08/17 | 2948 | systems/texlive/tlnet/archive/lt3luabridge.r64128.tar.xz
2022/08/17 | 29260 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi.eps
2022/08/17 | 2902 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-english-color.pdf
2022/08/17 | 289 | macros/luatex/generic/luavlna/luavlna-si.lua
-2022/08/17 | 289560 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
2022/08/17 | 2894 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-english.pdf
-2022/08/17 | 289497 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
2022/08/17 | 286 | macros/latex/contrib/fithesis/style/mu/base.ins
-2022/08/17 | 286684 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
2022/08/17 | 2852 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-english-color.pdf
-2022/08/17 | 28509 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
2022/08/17 | 2849 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-english.pdf
2022/08/17 | 28441 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil.eps
-2022/08/17 | 2821670 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
2022/08/17 | 2808 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-english-color.pdf
2022/08/17 | 2804 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-english.pdf
2022/08/17 | 279 | macros/latex/contrib/fithesis/fithesis.ins
-2022/08/17 | 27464 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
2022/08/17 | 2732 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-english-color.pdf
2022/08/17 | 2727 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-english.pdf
-2022/08/17 | 270464 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2022/08/17 | 25516446 | systems/texlive/tlnet/install-tl.zip
2022/08/17 | 25396 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci.pdf
2022/08/17 | 25297 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-color.eps
-2022/08/17 | 25118 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2022/08/17 | 247205 | systems/win32/miktex/tm/packages/next/miktex-hitex-bin-x64.tar.lzma
-2022/08/17 | 245151 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
2022/08/17 | 24328 | macros/latex/contrib/fithesis/logo/mu/fithesis-sci-color.pdf
-2022/08/17 | 24210 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2022/08/17 | 2397600 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
-2022/08/17 | 23949 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
2022/08/17 | 23708 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil-color.eps
2022/08/17 | 23539 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped.eps
2022/08/17 | 23529 | macros/latex/contrib/fithesis/logo/mu/fithesis-med.eps
@@ -240,76 +402,40 @@
2022/08/17 | 2218015 | macros/latex/contrib/profcollege/doc/ProfCollege-doc.zip
2022/08/17 | 217 | macros/luatex/generic/luavlna/luavlna-presi.lua
2022/08/17 | 2175294 | install/macros/latex/contrib/fithesis.tds.zip
-2022/08/17 | 213846 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
2022/08/17 | 21247 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-color.eps
-2022/08/17 | 209137 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
2022/08/17 | 2056051 | macros/latex/contrib/fithesis.zip
2022/08/17 | 204 | macros/luatex/generic/luavlna/luavlna-sufdegrees.lua
-2022/08/17 | 20436545 | systems/texlive/tlnet/install-tl-windows.exe
-2022/08/17 | 203418 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
2022/08/17 | 20324 | macros/latex/contrib/fithesis/locale/czech.dtx
-2022/08/17 | 2023133 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
2022/08/17 | 20058 | macros/latex/contrib/fithesis/locale/slovak.dtx
-2022/08/17 | 196212 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2022/08/17 | 200199 | support/TeX4ht/source/ChangeLog
2022/08/17 | 19569 | macros/latex/contrib/fithesis/logo/mu/fithesis-med-color.eps
2022/08/17 | 19363 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped-color.eps
-2022/08/17 | 18510 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2022/08/17 | 18382 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
2022/08/17 | 18339 | macros/latex/contrib/fithesis/logo/mu/fithesis-law.pdf
-2022/08/17 | 181723 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
2022/08/17 | 1760 | macros/latex/contrib/fithesis/LICENSE.tex
-2022/08/17 | 17582689 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
2022/08/17 | 17579 | macros/latex/contrib/fithesis/logo/mu/fithesis-law-color.pdf
-2022/08/17 | 173177 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2022/08/17 | 169677 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
2022/08/17 | 15892 | macros/latex/contrib/fithesis/logo/mu/fithesis-base.pdf
-2022/08/17 | 155431 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2022/08/17 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2022/08/17 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
2022/08/17 | 15264 | macros/latex/contrib/fithesis/locale/english.dtx
2022/08/17 | 15062 | macros/latex/contrib/fithesis/logo/mu/fithesis-base-color.pdf
-2022/08/17 | 1503052 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2022/08/17 | 1482162 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2022/08/17 | 1481405 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2022/08/17 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
2022/08/17 | 1459 | macros/luatex/generic/luavlna/luavlna.sty
-2022/08/17 | 1458151 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
2022/08/17 | 14512 | systems/texlive/tlnet/archive/proflycee.r64130.tar.xz
-2022/08/17 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2022/08/17 | 14433 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
-2022/08/17 | 140012 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2022/08/17 | 1364924 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
-2022/08/17 | 1364461 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2022/08/17 | 135465 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2022/08/17 | 1323744 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
2022/08/17 | 13150370 | macros/latex/contrib/profcollege.zip
2022/08/17 | 12838 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ.pdf
2022/08/17 | 12347 | macros/luatex/generic/luavlna/luavlna.lua
2022/08/17 | 12305 | macros/latex/contrib/fithesis/logo/mu/fithesis-econ-color.pdf
2022/08/17 | 12083 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil.pdf
2022/08/17 | 12007 | macros/latex/contrib/fithesis/style/mu/econ.dtx
-2022/08/17 | 1172 | systems/win32/miktex/tm/packages/next/pr.ini
2022/08/17 | 11709 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi-color.pdf
2022/08/17 | 11634 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps.pdf
-2022/08/17 | 1161751 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
2022/08/17 | 11596 | macros/latex/contrib/fithesis/logo/mu/fithesis-phil-color.pdf
-2022/08/17 | 115580 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
2022/08/17 | 11529 | macros/latex/contrib/fithesis/logo/mu/fithesis-fi.pdf
2022/08/17 | 11492 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss.pdf
2022/08/17 | 11356 | systems/texlive/tlnet/archive/msu-thesis.r64129.tar.xz
-2022/08/17 | 113524 | systems/texlive/tlnet/archive/texlive-scripts.r64126.tar.xz
-2022/08/17 | 112979 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2022/08/17 | 112877 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2022/08/17 | 1128043 | support/TeX4ht/source/tex4ht-4ht.tex
2022/08/17 | 11199 | macros/latex/contrib/fithesis/logo/mu/fithesis-fsps-color.pdf
-2022/08/17 | 109650 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
2022/08/17 | 10758 | macros/latex/contrib/fithesis/logo/mu/fithesis-fss-color.pdf
-2022/08/17 | 107436 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
2022/08/17 | 10494 | macros/latex/contrib/fithesis/logo/mu/fithesis-med.pdf
-2022/08/17 | 104921 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
2022/08/17 | 104682 | macros/luatex/generic/luavlna.zip
2022/08/17 | 10396 | macros/latex/contrib/fithesis/logo/mu/fithesis-ped.pdf
-2022/08/17 | 103596 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2022/08/17 | 103245 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
2022/08/17 | 101310 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm-color.eps
2022/08/17 | 101282 | macros/latex/contrib/fithesis/logo/mu/fithesis-pharm.eps
2022/08/16 | 9602 | graphics/pgf/contrib/tikz-ext/doc/tikz-ext-manual-en-library-misc.tex
@@ -319,7 +445,6 @@
2022/08/16 | 823 | graphics/pgf/contrib/tikz-ext/doc/tikz-ext-manual.tex
2022/08/16 | 784594 | macros/latex/contrib/pygmentex.zip
2022/08/16 | 773 | macros/latex/contrib/pygmentex/README
-2022/08/16 | 7321 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2022/08/16 | 7188 | macros/latex/contrib/msu-thesis/samples/MSU-thesis-template.tex
2022/08/16 | 69999 | macros/latex/contrib/hereapplies.zip
2022/08/16 | 689500 | systems/texlive/tlnet/archive/xduts.doc.r64124.tar.xz
@@ -390,7 +515,6 @@
2022/08/15 | 736 | macros/latex/contrib/proflycee/doc/perroquet.csv
2022/08/15 | 707491 | macros/xetex/latex/xduts/xduts.pdf
2022/08/15 | 69340 | macros/xetex/latex/exam-zh/tex/exam-zh.cls
-2022/08/15 | 63056 | systems/texlive/tlnet/archive/hereapplies.doc.r64117.tar.xz
2022/08/15 | 62157 | macros/latex/contrib/proflycee/tex/ProfLycee.sty
2022/08/15 | 62108 | macros/latex/contrib/elegantbook/elegantbook-cn.tex
2022/08/15 | 5868 | graphics/pgf/contrib/tikz-ext/doc/tikz-ext-manual-en-library-paths.ortho.tex
@@ -402,7 +526,6 @@
2022/08/15 | 431480 | systems/texlive/tlnet/archive/armtex.doc.r64119.tar.xz
2022/08/15 | 38903 | macros/latex/contrib/elegantbook/elegantbook-en.tex
2022/08/15 | 32 | macros/latex/contrib/proflycee/doc/basique.csv
-2022/08/15 | 3216 | systems/texlive/tlnet/archive/hereapplies.r64117.tar.xz
2022/08/15 | 3061 | macros/latex/contrib/elegantbook/README.md
2022/08/15 | 2947940 | macros/latex/contrib/elegantbook.zip
2022/08/15 | 2861 | macros/xetex/latex/xduts/README.md
@@ -712,7 +835,6 @@
2022/08/12 | 9861 | macros/latex/contrib/ucs/data/uni-148.def
2022/08/12 | 9831 | macros/latex/contrib/ucs/data/uni-30.def
2022/08/12 | 9571 | macros/latex/contrib/ucs/config/pifont.ucf
-2022/08/12 | 952476 | systems/texlive/tlnet/archive/tex4ht.r64099.tar.xz
2022/08/12 | 9515 | macros/latex/contrib/ucs/data/uni-37.def
2022/08/12 | 9504 | macros/latex/contrib/ucs/config/math.ucf
2022/08/12 | 9412 | macros/latex/contrib/ucs/data/uni-250.def
@@ -980,7 +1102,6 @@
2022/08/12 | 13691 | macros/latex/contrib/ucs/data/uni-114.def
2022/08/12 | 13690 | macros/latex/contrib/ucs/data/uni-105.def
2022/08/12 | 13680 | macros/latex/contrib/ucs/data/uni-107.def
-2022/08/12 | 136384 | systems/texlive/tlnet/archive/tex4ht.doc.r64099.tar.xz
2022/08/12 | 1353 | macros/latex/contrib/ucs/data/uni-182.def
2022/08/12 | 13517 | dviware/dvisvgm/tests/data/Makefile.in
2022/08/12 | 13472 | macros/latex/contrib/ucs/data/uni-97.def
@@ -1002,7 +1123,6 @@
2022/08/12 | 12804 | macros/latex/contrib/ucs/data/uni-142.def
2022/08/12 | 12764 | macros/latex/contrib/ucs/data/uni-249.def
2022/08/12 | 12752 | macros/latex/contrib/ucs/data/uni-141.def
-2022/08/12 | 1272264 | systems/texlive/tlnet/archive/tex4ht.source.r64099.tar.xz
2022/08/12 | 12677 | macros/latex/contrib/ucs/data/uni-151.def
2022/08/12 | 12660 | macros/latex/contrib/ucs/data/uni-120.def
2022/08/12 | 12651 | macros/latex/contrib/ucs/data/uni-115.def
@@ -1062,147 +1182,3 @@
2022/08/12 | 10122 | macros/latex/contrib/ucs/data/uni-147.def
2022/08/12 | 10028 | macros/latex/contrib/ucs/data/uni-48.def
2022/08/12 | 10001 | macros/latex/contrib/ucs/data/uni-146.def
-2022/08/11 | 97323 | macros/latex/contrib/fixdif/fixdif.pdf
-2022/08/11 | 962390 | systems/win32/miktex/tm/packages/postnotes__doc.tar.lzma
-2022/08/11 | 9021 | systems/win32/miktex/tm/packages/ptex2pdf__doc.tar.lzma
-2022/08/11 | 90135 | systems/win32/miktex/tm/packages/xecjk__source.tar.lzma
-2022/08/11 | 8933 | systems/win32/miktex/tm/packages/projlib__doc.tar.lzma
-2022/08/11 | 890197 | systems/win32/miktex/tm/packages/l3backend__doc.tar.lzma
-2022/08/11 | 84332 | macros/latex/contrib/create-theorem/create-theorem-doc.pdf
-2022/08/11 | 83300 | systems/texlive/tlnet/archive/luatexja.source.r64092.tar.xz
-2022/08/11 | 8252 | systems/win32/miktex/tm/packages/texlogsieve__source.tar.lzma
-2022/08/11 | 81419 | systems/win32/miktex/tm/packages/proflycee__source.tar.lzma
-2022/08/11 | 79649 | systems/win32/miktex/tm/packages/tagpdf__source.tar.lzma
-2022/08/11 | 7936874 | systems/win32/miktex/tm/packages/profcollege__doc.tar.lzma
-2022/08/11 | 787 | macros/latex/contrib/fixdif/README.md
-2022/08/11 | 7751 | systems/win32/miktex/tm/packages/customdice__source.tar.lzma
-2022/08/11 | 74250 | systems/win32/miktex/tm/packages/texlogsieve__doc.tar.lzma
-2022/08/11 | 7408 | systems/texlive/tlnet/archive/customdice.source.r64089.tar.xz
-2022/08/11 | 7343 | systems/win32/miktex/tm/packages/postnotes.tar.lzma
-2022/08/11 | 728710 | systems/win32/miktex/tm/packages/bodeplot__doc.tar.lzma
-2022/08/11 | 717703 | systems/win32/miktex/tm/packages/proflycee__doc.tar.lzma
-2022/08/11 | 68258 | systems/win32/miktex/tm/packages/olsak-misc.tar.lzma
-2022/08/11 | 676 | macros/latex/contrib/create-theorem/README.md
-2022/08/11 | 66837 | macros/latex/contrib/runcode/troubleshoot.pdf
-2022/08/11 | 6679 | systems/win32/miktex/tm/packages/ocgx2__doc.tar.lzma
-2022/08/11 | 65091 | systems/win32/miktex/tm/packages/siunitx.tar.lzma
-2022/08/11 | 6489 | systems/win32/miktex/tm/packages/tikz-relay.tar.lzma
-2022/08/11 | 642560 | systems/win32/miktex/tm/packages/europecv__doc.tar.lzma
-2022/08/11 | 63738 | systems/win32/miktex/tm/packages/njuthesis__source.tar.lzma
-2022/08/11 | 622691 | systems/win32/miktex/tm/packages/colortbl__doc.tar.lzma
-2022/08/11 | 610698 | systems/win32/miktex/tm/packages/tikz-relay__doc.tar.lzma
-2022/08/11 | 6105 | systems/win32/miktex/tm/packages/unbtex.tar.lzma
-2022/08/11 | 6080 | systems/win32/miktex/tm/packages/bookcover.tar.lzma
-2022/08/11 | 590455 | systems/win32/miktex/tm/packages/l3kernel__source.tar.lzma
-2022/08/11 | 5725 | systems/win32/miktex/tm/packages/bodeplot.tar.lzma
-2022/08/11 | 56780 | macros/latex/contrib/runcode/runcode.pdf
-2022/08/11 | 5478 | systems/win32/miktex/tm/packages/unbtex__source.tar.lzma
-2022/08/11 | 53831 | systems/win32/miktex/tm/packages/yfonts-otf.tar.lzma
-2022/08/11 | 534525 | systems/win32/miktex/tm/packages/lt3rawobjects__doc.tar.lzma
-2022/08/11 | 5236 | systems/win32/miktex/tm/packages/lt3luabridge__source.tar.lzma
-2022/08/11 | 5065 | systems/win32/miktex/tm/packages/ptex2pdf.tar.lzma
-2022/08/11 | 5040 | systems/win32/miktex/tm/packages/sillypage__source.tar.lzma
-2022/08/11 | 492218 | systems/win32/miktex/tm/packages/gentombow__doc.tar.lzma
-2022/08/11 | 487082 | systems/win32/miktex/tm/packages/lt3luabridge__doc.tar.lzma
-2022/08/11 | 4685 | systems/win32/miktex/tm/packages/xsavebox__source.tar.lzma
-2022/08/11 | 4620 | systems/win32/miktex/tm/packages/yfonts-otf__source.tar.lzma
-2022/08/11 | 45480 | systems/win32/miktex/tm/packages/texlogsieve.tar.lzma
-2022/08/11 | 4398 | systems/win32/miktex/tm/packages/bhcexam.tar.lzma
-2022/08/11 | 4380 | systems/win32/miktex/tm/packages/xsavebox.tar.lzma
-2022/08/11 | 43809 | systems/win32/miktex/tm/packages/tuda-ci.tar.lzma
-2022/08/11 | 4168 | systems/texlive/tlnet/archive/bhcexam.r64093.tar.xz
-2022/08/11 | 3977562 | systems/win32/miktex/tm/packages/tudscr__doc.tar.lzma
-2022/08/11 | 396799 | systems/win32/miktex/tm/packages/europecv__source.tar.lzma
-2022/08/11 | 3945 | systems/win32/miktex/tm/packages/colortbl.tar.lzma
-2022/08/11 | 379622 | systems/win32/miktex/tm/packages/xsavebox__doc.tar.lzma
-2022/08/11 | 3788 | systems/win32/miktex/tm/packages/biblatex-software.tar.lzma
-2022/08/11 | 3668 | systems/win32/miktex/tm/packages/lt3rawobjects.tar.lzma
-2022/08/11 | 3666626 | systems/win32/miktex/tm/packages/media9__doc.tar.lzma
-2022/08/11 | 361526 | systems/win32/miktex/tm/packages/customdice__doc.tar.lzma
-2022/08/11 | 360976 | systems/texlive/tlnet/archive/customdice.doc.r64089.tar.xz
-2022/08/11 | 359746 | systems/win32/miktex/tm/packages/bhcexam__doc.tar.lzma
-2022/08/11 | 359312 | systems/texlive/tlnet/archive/bhcexam.doc.r64093.tar.xz
-2022/08/11 | 3584 | systems/win32/miktex/tm/packages/nimsticks__source.tar.lzma
-2022/08/11 | 3549 | systems/win32/miktex/tm/packages/zlmtt.tar.lzma
-2022/08/11 | 34279 | macros/latex/contrib/create-theorem/create-theorem-doc.tex
-2022/08/11 | 33280 | systems/win32/miktex/tm/packages/l3backend__source.tar.lzma
-2022/08/11 | 325945 | systems/win32/miktex/tm/packages/tudscr__source.tar.lzma
-2022/08/11 | 3254072 | systems/texlive/tlnet/archive/luatexja.doc.r64092.tar.xz
-2022/08/11 | 3206 | systems/win32/miktex/tm/packages/zlmtt__source.tar.lzma
-2022/08/11 | 3179 | macros/latex/contrib/fixdif/fixdif.ins
-2022/08/11 | 3145071 | systems/win32/miktex/tm/packages/animate__doc.tar.lzma
-2022/08/11 | 31275 | systems/win32/miktex/tm/packages/postnotes__source.tar.lzma
-2022/08/11 | 3116019 | systems/win32/miktex/tm/packages/luatexja__doc.tar.lzma
-2022/08/11 | 3078 | systems/win32/miktex/tm/packages/lt3luabridge.tar.lzma
-2022/08/11 | 30566 | systems/win32/miktex/tm/packages/animate__source.tar.lzma
-2022/08/11 | 305383 | systems/win32/miktex/tm/packages/biblatex-software__doc.tar.lzma
-2022/08/11 | 292032 | systems/win32/miktex/tm/packages/sillypage__doc.tar.lzma
-2022/08/11 | 2863 | systems/win32/miktex/tm/packages/simplebnf.tar.lzma
-2022/08/11 | 2821 | systems/win32/miktex/tm/packages/customdice.tar.lzma
-2022/08/11 | 28135 | systems/win32/miktex/tm/packages/tagpdf.tar.lzma
-2022/08/11 | 268190 | macros/latex/contrib/fixdif.zip
-2022/08/11 | 2632 | systems/texlive/tlnet/archive/simplebnf.r64091.tar.xz
-2022/08/11 | 2616 | systems/texlive/tlnet/archive/customdice.r64089.tar.xz
-2022/08/11 | 25812 | systems/win32/miktex/tm/packages/projlib__source.tar.lzma
-2022/08/11 | 25649 | systems/win32/miktex/tm/packages/hfutthesis.tar.lzma
-2022/08/11 | 25424 | systems/win32/miktex/tm/packages/projlib.tar.lzma
-2022/08/11 | 24749 | systems/win32/miktex/tm/packages/uni-titlepage__source.tar.lzma
-2022/08/11 | 24078 | systems/win32/miktex/tm/packages/animate.tar.lzma
-2022/08/11 | 23446 | macros/latex/contrib/fixdif/fixdif.dtx
-2022/08/11 | 233590 | systems/win32/miktex/tm/packages/zlmtt__doc.tar.lzma
-2022/08/11 | 2257 | systems/win32/miktex/tm/packages/simplebnf__source.tar.lzma
-2022/08/11 | 222030 | systems/win32/miktex/tm/packages/xecjk.tar.lzma
-2022/08/11 | 220662 | systems/win32/miktex/tm/packages/luatexja__source.tar.lzma
-2022/08/11 | 210366 | systems/win32/miktex/tm/packages/optex.tar.lzma
-2022/08/11 | 2084919 | systems/win32/miktex/tm/packages/profcollege__source.tar.lzma
-2022/08/11 | 2038852 | systems/win32/miktex/tm/packages/optex__doc.tar.lzma
-2022/08/11 | 199643 | support/TeX4ht/source/ChangeLog
-2022/08/11 | 1990 | systems/win32/miktex/tm/packages/nimsticks.tar.lzma
-2022/08/11 | 19403 | systems/win32/miktex/tm/packages/njuthesis.tar.lzma
-2022/08/11 | 191980 | systems/texlive/tlnet/archive/luatexja.r64092.tar.xz
-2022/08/11 | 191633 | systems/win32/miktex/tm/packages/luatexja.tar.lzma
-2022/08/11 | 19106 | macros/latex/contrib/create-theorem/LICENSE
-2022/08/11 | 19103 | systems/win32/miktex/tm/packages/colortbl__source.tar.lzma
-2022/08/11 | 1907971 | systems/win32/miktex/tm/packages/tagpdf__doc.tar.lzma
-2022/08/11 | 1900612 | systems/win32/miktex/tm/packages/media9.tar.lzma
-2022/08/11 | 18941 | macros/latex/contrib/runcode/troubleshoot.tex
-2022/08/11 | 1837729 | systems/win32/miktex/tm/packages/uni-titlepage__doc.tar.lzma
-2022/08/11 | 1785916 | systems/win32/miktex/tm/packages/bookcover__doc.tar.lzma
-2022/08/11 | 1782167 | systems/win32/miktex/tm/packages/media9__source.tar.lzma
-2022/08/11 | 17397 | systems/win32/miktex/tm/packages/ocgx2.tar.lzma
-2022/08/11 | 172729 | systems/win32/miktex/tm/packages/l3kernel.tar.lzma
-2022/08/11 | 17189 | systems/win32/miktex/tm/packages/bodeplot__source.tar.lzma
-2022/08/11 | 17120 | systems/win32/miktex/tm/packages/tikz-relay__source.tar.lzma
-2022/08/11 | 16822 | macros/latex/contrib/fixdif/fixdif-zh-cn.tex
-2022/08/11 | 163865 | systems/win32/miktex/tm/packages/tudscr.tar.lzma
-2022/08/11 | 163015 | macros/latex/contrib/fixdif/fixdif-zh-cn.pdf
-2022/08/11 | 1625928 | systems/win32/miktex/tm/packages/xecjk__doc.tar.lzma
-2022/08/11 | 15769 | macros/latex/contrib/runcode/runcode.sty
-2022/08/11 | 15636 | systems/win32/miktex/tm/packages/l3backend.tar.lzma
-2022/08/11 | 15529 | systems/win32/miktex/tm/packages/europecv.tar.lzma
-2022/08/11 | 15233 | systems/win32/miktex/tm/packages/bookcover__source.tar.lzma
-2022/08/11 | 151428 | systems/texlive/tlnet/archive/simplebnf.doc.r64091.tar.xz
-2022/08/11 | 150414 | systems/win32/miktex/tm/packages/simplebnf__doc.tar.lzma
-2022/08/11 | 146626 | systems/win32/miktex/tm/packages/yfonts-otf__doc.tar.lzma
-2022/08/11 | 1444792 | systems/win32/miktex/tm/packages/unbtex__doc.tar.lzma
-2022/08/11 | 1395 | systems/win32/miktex/tm/packages/olsak-misc__doc.tar.lzma
-2022/08/11 | 13662 | systems/win32/miktex/tm/packages/sillypage.tar.lzma
-2022/08/11 | 13273 | systems/win32/miktex/tm/packages/gentombow__source.tar.lzma
-2022/08/11 | 132560 | macros/latex/contrib/runcode.zip
-2022/08/11 | 12 | macros/latex/contrib/create-theorem/DEPENDS.txt
-2022/08/11 | 12832 | systems/win32/miktex/tm/packages/proflycee.tar.lzma
-2022/08/11 | 1246141 | systems/win32/miktex/tm/packages/siunitx__doc.tar.lzma
-2022/08/11 | 1212673 | systems/win32/miktex/tm/packages/profcollege.tar.lzma
-2022/08/11 | 11889 | systems/win32/miktex/tm/packages/biblatex-software__source.tar.lzma
-2022/08/11 | 1182741 | systems/win32/miktex/tm/packages/njuthesis__doc.tar.lzma
-2022/08/11 | 116799 | systems/win32/miktex/tm/packages/siunitx__source.tar.lzma
-2022/08/11 | 11673083 | systems/win32/miktex/tm/packages/l3kernel__doc.tar.lzma
-2022/08/11 | 1133492 | systems/win32/miktex/tm/packages/tuda-ci__doc.tar.lzma
-2022/08/11 | 11324 | macros/latex/contrib/runcode/runcode.tex
-2022/08/11 | 11119 | systems/win32/miktex/tm/packages/gentombow.tar.lzma
-2022/08/11 | 11077 | support/TeX4ht/source/tex4ht-html5.tex
-2022/08/11 | 108622 | macros/latex/contrib/create-theorem.zip
-2022/08/11 | 10761 | systems/win32/miktex/tm/packages/uni-titlepage.tar.lzma
-2022/08/11 | 106565 | systems/win32/miktex/tm/packages/nimsticks__doc.tar.lzma
-2022/08/11 | 10170 | systems/win32/miktex/tm/packages/lt3rawobjects__source.tar.lzma
-2022/08/11 | 100673 | macros/latex/contrib/create-theorem/create-theorem.sty
diff --git a/biblio/citation-style-language/CHANGELOG.md b/biblio/citation-style-language/CHANGELOG.md
index 1c6b2df688..e351714b3a 100644
--- a/biblio/citation-style-language/CHANGELOG.md
+++ b/biblio/citation-style-language/CHANGELOG.md
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [v0.2.0] - 2022-08-18
+
+### Added
+
+- The cite grouping, collapsing, and disambiguation features are now implemented.
+
+### Changed
+
+- The `citeproc` executable is renamed to `citeproc-lua` to avoid conflicts with other processor implementations.
+- Package configuration can also be given in the package loading options.
+- A warning is raised instead of and error in case of duplicate entry keys ([#14](https://github.com/zepinglee/citeproc-lua/issues/14)).
+
+### Fixed
+
+- Fix an infinite loop error when bib entry keys contain hyphens or underscores ([#18](https://github.com/zepinglee/citeproc-lua/issues/18)).
+- Fix incorrect item position in note style ([#20](https://github.com/zepinglee/citeproc-lua/issues/20)).
+- Fix compatibility with `\blockquote` of `csquotes` ([#21](https://github.com/zepinglee/citeproc-lua/issues/21)).
+- Fix non-lowercase field names ([#22](https://github.com/zepinglee/citeproc-lua/issues/22)).
+
## [v0.1.1] - 2022-03-21
### Added
@@ -27,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Initial CTAN release.
-[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.1.1...HEAD
+[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.2.0...HEAD
+[v0.2.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.1.1...0.2.0
[v0.1.1]: https://github.com/zepinglee/citeproc-lua/compare/v0.1.0...v0.1.1
[v0.1.0]: https://github.com/zepinglee/citeproc-lua/releases/tag/v0.1.0
diff --git a/biblio/citation-style-language/DEPENDS.txt b/biblio/citation-style-language/DEPENDS.txt
new file mode 100644
index 0000000000..3d0edb73de
--- /dev/null
+++ b/biblio/citation-style-language/DEPENDS.txt
@@ -0,0 +1,10 @@
+# The format of this file is described in https://www.tug.org/texlive/pkgcontrib.html#deps.
+
+hard luatex
+hard l3kernel
+hard l3packages
+hard filehook
+hard url
+hard luaxml
+hard lua-uca
+hard lualibs
diff --git a/biblio/citation-style-language/README.md b/biblio/citation-style-language/README.md
index 74c27590c6..6ad5a87602 100644
--- a/biblio/citation-style-language/README.md
+++ b/biblio/citation-style-language/README.md
@@ -48,7 +48,7 @@ lualatex example.tex
```bash
pdflatex example.tex
-citeproc example.aux
+citeproc-lua example.aux
pdflatex example.tex
```
diff --git a/biblio/citation-style-language/american-chemical-society.csl b/biblio/citation-style-language/american-chemical-society.csl
index bf75b2d8de..cde0e0c50f 100644
--- a/biblio/citation-style-language/american-chemical-society.csl
+++ b/biblio/citation-style-language/american-chemical-society.csl
@@ -21,7 +21,7 @@
<category citation-format="numeric"/>
<category field="chemistry"/>
<summary>The American Chemical Society style</summary>
- <updated>2021-05-22T12:00:00+00:00</updated>
+ <updated>2022-05-04T19:44:25-04: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">
@@ -250,14 +250,17 @@
</group>
</else-if>
<else-if type="webpage">
- <group delimiter=" ">
- <text variable="title"/>
- <text variable="URL"/>
- <date variable="accessed" prefix="(accessed " suffix=")" delimiter=" ">
- <date-part name="year"/>
- <date-part name="month" prefix="-" form="numeric-leading-zeros"/>
- <date-part name="day" prefix="-" form="numeric-leading-zeros"/>
- </date>
+ <group delimiter=". ">
+ <text variable="title" font-style="italic"/>
+ <text variable="container-title"/>
+ <group delimiter=" ">
+ <text variable="URL"/>
+ <date variable="accessed" prefix="(accessed " suffix=")">
+ <date-part name="year"/>
+ <date-part name="month" prefix="-" form="numeric-leading-zeros"/>
+ <date-part name="day" prefix="-" form="numeric-leading-zeros"/>
+ </date>
+ </group>
</group>
</else-if>
<else>
diff --git a/biblio/citation-style-language/american-medical-association.csl b/biblio/citation-style-language/american-medical-association.csl
index 44520822d0..b36bbb5488 100644
--- a/biblio/citation-style-language/american-medical-association.csl
+++ b/biblio/citation-style-language/american-medical-association.csl
@@ -27,7 +27,7 @@
<category citation-format="numeric"/>
<category field="medicine"/>
<summary>The American Medical Association style as used in JAMA. Version 11 as per November-2019.</summary>
- <updated>2021-10-28T13:38:04+00:00</updated>
+ <updated>2022-03-17T08:48:24+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">
@@ -86,7 +86,7 @@
</macro>
<macro name="title">
<choose>
- <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
+ <if type="bill book graphic legal_case legislation motion_picture report song thesis" match="any">
<text variable="title" font-style="italic" text-case="title"/>
</if>
<else>
@@ -247,6 +247,15 @@
<text variable="event-place"/>
</group>
</else-if>
+ <else-if type="thesis" match="any">
+ <group delimiter=". " prefix=" " suffix=".">
+ <text variable="genre"/>
+ <group delimiter="; ">
+ <text variable="publisher"/>
+ <date date-parts="year" form="text" variable="issued"/>
+ </group>
+ </group>
+ </else-if>
<else>
<text macro="editor" prefix=" " suffix="."/>
<group prefix=" " suffix=".">
diff --git a/biblio/citation-style-language/american-sociological-association.csl b/biblio/citation-style-language/american-sociological-association.csl
index 6657716cde..cf4ab0fc0d 100644
--- a/biblio/citation-style-language/american-sociological-association.csl
+++ b/biblio/citation-style-language/american-sociological-association.csl
@@ -16,7 +16,7 @@
<category citation-format="author-date"/>
<category field="sociology"/>
<summary>The ASA style following the 6th edition of the Style Guide</summary>
- <updated>2020-09-18T10:38:12+00:00</updated>
+ <updated>2022-05-08T17:48:56-04: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">
@@ -125,13 +125,25 @@
<macro name="year-date">
<choose>
<if variable="issued">
- <group delimiter=" ">
- <date variable="original-date" form="numeric" date-parts="year" prefix="[" suffix="]"/>
- <date variable="issued" form="numeric" date-parts="year"/>
+ <group>
+ <group delimiter=" ">
+ <date variable="original-date" form="numeric" date-parts="year" prefix="[" suffix="]"/>
+ <date variable="issued" form="numeric" date-parts="year"/>
+ </group>
+ <text variable="year-suffix"/>
</group>
</if>
+ <else-if variable="status">
+ <group>
+ <text variable="status" text-case="lowercase"/>
+ <text variable="year-suffix" prefix="-"/>
+ </group>
+ </else-if>
<else>
- <text term="no date" form="short"/>
+ <group>
+ <text term="no date" form="short"/>
+ <text variable="year-suffix" prefix="-"/>
+ </group>
</else>
</choose>
</macro>
@@ -140,6 +152,12 @@
<if variable="issued">
<date variable="issued" form="numeric" date-parts="year"/>
</if>
+ <else-if variable="status">
+ <group>
+ <text variable="status" text-case="lowercase"/>
+ <text variable="year-suffix" prefix="-"/>
+ </group>
+ </else-if>
<else>
<text term="no date" form="short"/>
</else>
diff --git a/biblio/citation-style-language/apa.csl b/biblio/citation-style-language/apa.csl
index 5ba01a9423..43a8e5932f 100644
--- a/biblio/citation-style-language/apa.csl
+++ b/biblio/citation-style-language/apa.csl
@@ -14,7 +14,7 @@
<category citation-format="author-date"/>
<category field="psychology"/>
<category field="generic-base"/>
- <updated>2022-01-31T09:43:56-05:00</updated>
+ <updated>2022-08-11T09:14:19-04: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">
@@ -320,8 +320,8 @@
<!-- General categories of item types:
Periodical: article-journal article-magazine article-newspaper post-weblog review review-book
Periodical or Booklike: paper-conference
- Booklike: article book broadcast chapter dataset entry entry-dictionary entry-encyclopedia figure
- graphic interview manuscript map motion_picture musical_score pamphlet patent
+ Booklike: article book broadcast chapter dataset entry entry-dictionary entry-encyclopedia figure
+ graphic interview manuscript map motion_picture musical_score pamphlet patent
personal_communication report song speech thesis post webpage
Legal: bill legal_case legislation treaty
-->
@@ -389,7 +389,7 @@
</if>
<else-if type="interview personal_communication" match="any">
<choose>
- <!-- These variables indicate that the letter is retrievable by the reader.
+ <!-- These variables indicate that the letter is retrievable by the reader.
If not, then use the APA in-text-only personal communication format -->
<if variable="archive container-title DOI publisher URL" match="none">
<group delimiter=", ">
@@ -470,7 +470,7 @@
</if>
</choose>
</else-if>
- <!-- Only year: article article-journal book chapter entry entry-dictionary entry-encyclopedia dataset figure graphic
+ <!-- Only year: article article-journal book chapter entry entry-dictionary entry-encyclopedia dataset figure graphic
manuscript map musical_score paper-conference[published] patent report review review-book thesis -->
</choose>
</if>
@@ -530,7 +530,7 @@
<if type="interview personal_communication" match="any">
<choose>
<if variable="archive container-title DOI publisher URL" match="none">
- <!-- These variables indicate that the communication is retrievable by the reader.
+ <!-- These variables indicate that the communication is retrievable by the reader.
If not, then use the in-text-only personal communication format -->
<date variable="issued" form="text"/>
</if>
@@ -1295,7 +1295,7 @@
<macro name="reviewed-title">
<choose>
<if variable="reviewed-title">
- <!-- Not possible to distinguish TV series episode from other reviewed
+ <!-- Not possible to distinguish TV series episode from other reviewed
works [Ex. 69] -->
<text variable="reviewed-title" font-style="italic"/>
</if>
@@ -1553,14 +1553,14 @@
</macro>
<macro name="event">
<choose>
- <if variable="event">
+ <if variable="event event-title" match="any">
<!-- To prevent Zotero from printing event-place due to its double-mapping of all 'place' to
both publisher-place and event-place. Remove this 'choose' when that is changed. -->
<choose>
<if variable="collection-editor editor editorial-director issue page volume" match="none">
<!-- Don't print event info if published in a proceedings -->
<group delimiter=", ">
- <text variable="event"/>
+ <text macro="event-title"/>
<text variable="event-place"/>
</group>
</if>
@@ -1568,6 +1568,20 @@
</if>
</choose>
</macro>
+ <macro name="event-title">
+ <choose>
+ <!-- TODO: We expect "event-title" to be used,
+ but processors and applications may not be updated yet.
+ This macro ensures that either "event" or "event-title" can be accpeted.
+ Remove if procesor logic and application adoption can handle this. -->
+ <if variable="event-title">
+ <text variable="event-title"/>
+ </if>
+ <else>
+ <text variable="event"/>
+ </else>
+ </choose>
+ </macro>
<!-- After 'source', APA also prints publication history (original publication, reprint info, retraction info) -->
<macro name="publication-history">
<choose>
@@ -1575,7 +1589,7 @@
<group prefix="(" suffix=")">
<choose>
<if variable="references">
- <!-- This provides the option for more elaborate description
+ <!-- This provides the option for more elaborate description
of publication history, such as full "reprinted" references
(examples 11, 43, 44) or retracted references -->
<text variable="references"/>
diff --git a/biblio/citation-style-language/chicago-author-date.csl b/biblio/citation-style-language/chicago-author-date.csl
index 8c133354b3..f8c640cd7f 100644
--- a/biblio/citation-style-language/chicago-author-date.csl
+++ b/biblio/citation-style-language/chicago-author-date.csl
@@ -45,6 +45,30 @@
<term name="translator" form="short">trans.</term>
</terms>
</locale>
+ <locale xml:lang="pt-PT">
+ <terms>
+ <term name="accessed">acedido a</term>
+ </terms>
+ </locale>
+ <locale xml:lang="pt">
+ <terms>
+ <term name="editor" form="verb">editado por</term>
+ <term name="editor" form="verb-short">ed.</term>
+ <term name="container-author" form="verb">por</term>
+ <term name="translator" form="verb-short">traduzido por</term>
+ <term name="translator" form="short">trad.</term>
+ <term name="editortranslator" form="verb">editado e traduzido por</term>
+ <term name="and">e</term>
+ <term name="no date" form="long">s.d</term>
+ <term name="no date" form="short">s.d.</term>
+ <term name="in">em</term>
+ <term name="at">em</term>
+ <term name="by">por</term>
+ <!-- PUNCTUATION -->
+ <term name="open-quote">"</term>
+ <term name="close-quote">"</term>
+ </terms>
+ </locale>
<macro name="secondary-contributors">
<choose>
<if type="chapter entry-dictionary entry-encyclopedia paper-conference" match="none">
diff --git a/biblio/citation-style-language/chicago-fullnote-bibliography.csl b/biblio/citation-style-language/chicago-fullnote-bibliography.csl
index fb2f1ae943..da4969f115 100644
--- a/biblio/citation-style-language/chicago-fullnote-bibliography.csl
+++ b/biblio/citation-style-language/chicago-fullnote-bibliography.csl
@@ -34,7 +34,7 @@
<category citation-format="note"/>
<category field="generic-base"/>
<summary>Chicago format with full notes and bibliography</summary>
- <updated>2022-01-16T14:46:01-05:00</updated>
+ <updated>2017-10-12T12: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">
diff --git a/biblio/citation-style-language/chicago-note-bibliography.csl b/biblio/citation-style-language/chicago-note-bibliography.csl
index 6ec4a29534..83da96cb4d 100644
--- a/biblio/citation-style-language/chicago-note-bibliography.csl
+++ b/biblio/citation-style-language/chicago-note-bibliography.csl
@@ -34,7 +34,7 @@
<category citation-format="note"/>
<category field="generic-base"/>
<summary>Chicago format with short notes and bibliography</summary>
- <updated>2022-01-16T14:46:01-05:00</updated>
+ <updated>2017-10-12T12: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">
diff --git a/biblio/citation-style-language/citation-style-language-doc.pdf b/biblio/citation-style-language/citation-style-language-doc.pdf
index b4ccbe55d3..af42980a81 100644
--- a/biblio/citation-style-language/citation-style-language-doc.pdf
+++ b/biblio/citation-style-language/citation-style-language-doc.pdf
Binary files differ
diff --git a/biblio/citation-style-language/citation-style-language-doc.tex b/biblio/citation-style-language/citation-style-language-doc.tex
index 538aaae00a..1dda26c5fa 100644
--- a/biblio/citation-style-language/citation-style-language-doc.tex
+++ b/biblio/citation-style-language/citation-style-language-doc.tex
@@ -49,7 +49,7 @@
}%
}
-\date{2022-03-21 v0.1.1}
+\date{2022-08-18 v0.2.0}
\maketitle
@@ -73,7 +73,7 @@ citations and bibliography according to the selected CSL style.
A LaTeX package (\file{citation-style-language.sty}) is provided to communicate with the processor.
Note that this project is in early development stage and some features of CSL
-are not implemented yet (especially collapsing and disambiguation).
+are not implemented yet.
Comments, suggestions, and bug reports are welcome.
@@ -131,14 +131,14 @@ The general procedure is similar to the traditional BibTeX workflow.
\end{syntax}
\end{function}
-The behavior of the \pkg{citation-style-language} package is controlled by several key-value
-options which can be set with the \cs{cslsetup} command.
-For example,
+Package options may be set when the package is loaded or at any later stage
+with the \cs{cslsetup} command.
+These two methods are equivalent.
\begin{LaTeXdemo}
- \cslsetup{
- style = apa,
- locale = zh-CN,
- }
+ \usepackage[style = apa]{citation-style-langugage}
+ % OR
+ \usepackage{citation-style-langugage}
+ \cslsetup{style = apa}
\end{LaTeXdemo}
\DescribeOption{style}
@@ -278,13 +278,11 @@ recommended.
If only one optional argument is provided, it is treated as \meta{postnote}.
The \meta{postnote} is used as a page locator if it consists of only digits.
-In other packages, several commands are provided for producing citations in
-different styles such as \cs{citet}, \cs{citep}, \cs{parencite}, and
-\cs{footnotecite}.
-In \pkg{citation-style-language} package, however, the format of citations is
-fixed as defined in CSL style and it is impossible to select another format
-without modifying the \file{.csl} style file.
-Note that narrative citation (like ``Doe (2018)'') will be supported in CSL 1.1.
+For author-date styles, there are also narrative in-text citations where the
+author names appear in running text and only dates are enclosed in parentheses
+(\cs{citet} in \pkg{natbib} pacakge or \cs{textcite} in \pkg{biblatex}).
+However such cite command in this pakcage is not available at the momment and
+it will be implemented in the next release.
\begin{function}{\cites}
\begin{syntax}
@@ -302,6 +300,17 @@ scanning process. The following example illustrates its usage.
\cites[prefix = {See }, page = 6]{key1}[section = 2.3]{key2}\relax [Text]
\end{LaTeXdemo}
+\begin{function}{\nocite}
+ \begin{syntax}
+ \cs{nocite}\marg{keys}
+ \end{syntax}
+\end{function}
+
+This command produces no output but makes the entries included in the
+bibliography, which is the same in standard \LaTeX.
+If the special key |*| is given (\cs{notecite\{*\}}), all the entries in the
+database are included.
+
\begin{function}{\printbibliography}
@@ -368,16 +377,11 @@ An error will be triggered if any of them is loaded together with \pkg{citation-
The \pkg{citation-style-language} package is in early development stage and there are some issues with it.
\begin{itemize}
- \item The \pkg{citeproc-lua} has not implemented all the features of CSL,
- especially disambiguation and collapsing.
+ \item The \pkg{citeproc-lua} has not implemented all the features of CSL.
For detailed information of the coverage on the CSL standard test
suite\footnote{\url{https://github.com/citation-style-language/test-suite}},
see \href{https://github.com/zepinglee/citeproc-lua/blob/main/test/citeproc-test.log}{citeproc-test.log}
in the GitHub repository.
- \item The processor is much slower than expected compared to other
- reference engines.
- This is because little care has been taken in the development so far.
- Optimization is needed in the future.
\item When used with \pkg{hyperref}, the citations are not correctly rendered
as hyperlinks.
\item The Unicode sorting method is provided by \pkg{lua-uca} package and
diff --git a/biblio/citation-style-language/citation-style-language.sty b/biblio/citation-style-language/citation-style-language.sty
index 546ac13eec..87165c4be2 100644
--- a/biblio/citation-style-language/citation-style-language.sty
+++ b/biblio/citation-style-language/citation-style-language.sty
@@ -9,9 +9,10 @@
\RequirePackage{expl3}
\RequirePackage{xparse}
-\ProvidesExplPackage {citation-style-language} {2022-01-22} {v0.1.0}
+\ProvidesExplPackage {citation-style-language} {2022-08-18} {v0.2.0}
{Citation Style Language for LaTeX}
+\RequirePackage { l3keys2e }
\RequirePackage { filehook }
\RequirePackage { url }
@@ -34,7 +35,7 @@
\__csl_load_check:n
\sys_if_engine_luatex:T
- { \lua_now:n { csl = require("csl") } }
+ { \lua_now:n { csl = require("citeproc-latex") } }
\NewDocumentCommand \cslsetup { m }
@@ -82,8 +83,11 @@
}
+% Appends the cite key into \l__csl_cite_keys_seq and cite-items into
+% \l__csl_cite_items_seq
+% #1, #2: prenote/postnote
+% #3: keys
\cs_new:Npn \__csl_process_cite_items:nnn #1#2#3
- % #1,#2: prenote/postnote, #3: keys
{
\tl_if_novalue:nTF {#2}
{
@@ -120,25 +124,27 @@
{
\prop_clear:N \l__csl_cite_item_prop
\prop_put:Nnn \l__csl_cite_item_prop { id } {#3}
+ % \bool_if:T \l__csl_suppress_author_bool
+ % { \prop_put:Nnn \l__csl_cite_item_prop { suppress-author } { true } }
+ % \bool_if:T \l__csl_author_only_bool
+ % { \prop_put:Nnn \l__csl_cite_item_prop { author-only } { true } }
\tl_if_empty:nF {#1}
{
\tl_set:Nn \l__csl_prefix_tl {#1}
\tl_put_right:NV \l__csl_prefix_tl \l__csl_prefix_separator_tl
- \prop_put:NnV \l__csl_cite_item_prop { prefix } { \l__csl_prefix_tl }
+ \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_prefix_tl
}
- \tl_if_in:nnTF {#2} { = }
+ \tl_if_empty:nF {#2}
{
- \keys_set:nn { csl / cite-item } {#2}
- }
- {
- \tl_if_empty:nF {#2}
+ \tl_if_in:nnTF {#2} { = }
+ { \keys_set:nn { csl / cite-item } {#2} }
{
\regex_match:nnTF { \d+ } {#2}
{ \__csl_set_locator:nn { page } {#2} }
{
\tl_set:Nn \l__csl_suffix_tl {#2}
\tl_put_left:NV \l__csl_suffix_tl \l__csl_suffix_separator_tl
- \prop_put:NnV \l__csl_cite_item_prop { suffix } { \l__csl_suffix_tl }
+ \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_suffix_tl
}
}
}
@@ -202,20 +208,26 @@
\tl_new:N \l__csl_citation_info_tl
\tl_new:N \l__csl_citation_tl
\prop_new:N \g__csl_citations_prop
+\prop_clear:N \l__csl_citation_prop
\cs_new:Npn \__csl_make_citation:NN #1#2
% #1: \l__csl_cite_keys_seq
% #2: \l__csl_cite_items_seq
{
+ \prop_clear:N \l__csl_citation_prop
\__csl_process_citation_id:NN \l__csl_citation_id_tl #1
+ \prop_put:NnV \l__csl_citation_prop { citationID } \l__csl_citation_id_tl
\tl_set:Nx \l__csl_cite_items_tl
{ \seq_use:Nn #2 { , } }
- \exp_args:NNV \__csl_process_note_index:Nn \l__csl_note_index_tl \l__csl_citation_id_tl
- \tl_set:Nx \l__csl_citation_info_tl
+ \prop_put:NnV \l__csl_citation_prop { citationItems } \l__csl_cite_items_tl
+ \__csl_get_note_index:N \l__csl_note_index_tl
+ \prop_put:Nnx \l__csl_citation_prop { properties } { noteIndex = { \l__csl_note_index_tl } }
+ \tl_clear:N \l__csl_citation_info_tl
+ \prop_map_inline:Nn \l__csl_citation_prop
{
- { \l__csl_citation_id_tl }
- { \l__csl_cite_items_tl }
- { \l__csl_note_index_tl }
+ \tl_if_empty:NF \l__csl_citation_info_tl
+ { \tl_put_right:Nn \l__csl_citation_info_tl { , } }
+ \tl_put_right:Nn \l__csl_citation_info_tl { ##1 = { ##2 } }
}
\exp_args:NV \__csl_write_aux_citation:n \l__csl_citation_info_tl
\prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl
@@ -224,8 +236,9 @@
{
\bool_if:NTF \l__csl_engine_initialized_bool
{
- \tl_set:Nx \l__csl_citation_tl
+ \tl_set:Nf \l__csl_citation_tl
{ \lua_now:e { csl.cite("\l__csl_citation_info_tl") } }
+ \exp_args:NV \__csl_print_citation:n \l__csl_citation_tl
}
{
\exp_args:Nx \__csl_print_undefined_citation:n
@@ -261,26 +274,18 @@
}
-\int_new:N \l__csl_note_index_int
-\int_gzero_new:N \g__csl_last_note_index_int
-\int_gzero_new:N \g__csl_citation_note_count_int
-
-\cs_new:Npn \__csl_process_note_index:Nn #1#2
- % #1 \l__csl_note_index_tl
- % #2: citationID
+% Save the note number to \l__csl_note_index_tl
+% TODO: multiple citations in a note
+\cs_new:Npn \__csl_get_note_index:N #1
+ % #1: \l__csl_note_index_tl
{
- \int_set_eq:Nc \l__csl_note_index_int { c@ \@mpfn }
- \prop_if_in:NnTF \g__csl_citations_prop {#2}
- { \int_incr:N \l__csl_note_index_int }
- { \int_gincr:N \g__csl_citation_note_count_int }
- \int_add:Nn \l__csl_note_index_int { \g__csl_citation_note_count_int }
- \tl_set:Nx #1 { \int_use:N \l__csl_note_index_int }
- \int_gset_eq:NN \g__csl_last_note_index_int \l__csl_note_index_int
- \int_compare:nT { \l__csl_note_index_int < \g__csl_last_note_index_int }
+ \bool_if:NTF \l__csl_note_style_bool
{
- \int_gzero:N \g__csl_last_note_index_int
- \int_gzero:N \g__csl_citation_note_count_int
+ \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn }
+ \int_incr:N \l_tmpa_int
+ \tl_set:Nx #1 { \int_use:N \l_tmpa_int }
}
+ { \tl_set:Nn #1 { 0 } }
}
@@ -294,6 +299,16 @@
}
+% \cs_new:Npn \__csl_print_citation:n #1
+% % #1: citation text
+% {
+% \bool_if:NTF \l__csl_note_style_bool
+% {
+% \footnote {#1}
+% }
+% {#1}
+% }
+
\cs_new:Npn \__csl_print_citation:n #1
% #1: "{<type>}{<citation text>}"
{ \__csl_print_citation_aux:nn #1 }
@@ -330,17 +345,36 @@
\cs_new:Npn \__csl_no_cite:n #1
{
- \__csl_if_preamble:TF
+ \seq_clear:N \l__csl_cite_keys_seq
+ \seq_clear:N \l__csl_cite_items_seq
+ \__csl_process_cite_items:nnn { } { } {#1}
+ \tl_set:Nx \l__csl_cite_items_tl
+ { \seq_use:Nn \l__csl_cite_items_seq { , } }
+ \tl_set:Nx \l__csl_citation_info_tl
{
- \AtBeginDocument
- { \__csl_write_aux_citation:n { { nocite } {#1} { } } }
+ citationID = { @nocite } ,
+ citationItems = { \l__csl_cite_items_tl } ,
+ properties = { noteIndex = { 0 } }
}
- { \__csl_write_aux_citation:n { { nocite } {#1} { } } }
+ \exp_args:NV \__csl_no_cite_write_aux:n \l__csl_citation_info_tl
\sys_if_engine_luatex:T
{ \lua_now:n { csl.nocite("#1") } }
}
+\cs_new:Npn \__csl_no_cite_write_aux:n #1
+ {
+ \__csl_if_preamble:TF
+ {
+ \AtBeginDocument
+ { \exp_args:Nx \__csl_write_aux_citation:n { #1 } }
+ }
+ {
+ \exp_args:Nx \__csl_write_aux_citation:n { #1 }
+ }
+ }
+
+
\prg_new_conditional:Nnn \__csl_if_preamble: { T , F , TF }
{
\if_meaning:w \@begindocumenthook \@undefined
@@ -352,6 +386,7 @@
% Used in aux files to register cite items.
+% #1: a citation object
\cs_set:Npn \citation #1
{
\sys_if_engine_luatex:T
@@ -362,9 +397,9 @@
\cs_new:Npn \cslcite #1#2
{
\bibcite {#1} {#2}
- \if@filesw
- \iow_now:Nn \@auxout { \bibcite {#1} {#2} }
- \fi
+ % \if@filesw
+ % \iow_now:Nn \@auxout { \bibcite {#1} {#2} }
+ % \fi
}
@@ -444,6 +479,8 @@
entry-spacing = { 1 } ,
}
+\ProcessKeysPackageOptions { csl }
+
\bool_new:N \l__csl_engine_initialized_bool
\prop_set_from_keyval:Nn \l__csl_babel_locale_mapping_prop
@@ -590,6 +627,7 @@
}
\str_if_eq:eeT { \lua_now:n { tex.print(csl.initialized) } } { true }
{ \bool_set_true:N \l__csl_engine_initialized_bool }
+ \__csl_get_style_class:
\@ifpackageloaded { hyperref }
{ \lua_now:n { csl.enable_linking() } }
{ }
@@ -614,6 +652,21 @@
\fi
}
+
+\str_new:N \l__csl_style_class_str
+% In-text (including numeric or author-date) or note style
+\bool_new:N \l__csl_note_style_bool
+
+\cs_new:Npn \__csl_get_style_class: {
+ \bool_if:NT \l__csl_engine_initialized_bool
+ {
+ \str_set:Nx \l__csl_style_class_str { \lua_now:n { csl.get_style_class() } }
+ \str_if_eq:VnT \l__csl_style_class_str { note }
+ { \bool_set_true:N \l__csl_note_style_bool }
+ }
+}
+
+
\clist_new:N \l__csl_options_clist
\cs_new:Npn \__csl_write_aux_csl_options:
@@ -972,6 +1025,19 @@
}
+% csquotes
+
+\AtEndOfPackageFile* { csquotes }
+ {
+ \BlockquoteDisable
+ {
+ \cs_set_eq:NN \__csl_make_citation:NN \use_none:nn
+ % \sys_if_engine_luatex:T
+ % { \lua_now:n { csl.preview_mode = true } }
+ }
+ }
+
+
% hyperref
% The hyperref package also patches \bibcite but it cannot provide hyperlinks
diff --git a/biblio/citation-style-language/citeproc-bib-data.json b/biblio/citation-style-language/citeproc-bib-data.json
deleted file mode 100644
index 69e26e16c3..0000000000
--- a/biblio/citation-style-language/citeproc-bib-data.json
+++ /dev/null
@@ -1,2349 +0,0 @@
-{
- "description": "Bib CSL mapping",
- "types": {
- "archival": {
- "csl": "collection",
- "source": "jurabib.bst"
- },
- "archive": {
- "csl": "collection",
- "notes": "New in CSL v1.0.2.",
- "source": "gbt7714-numerical.bst"
- },
- "article": {
- "csl": "article-journal",
- "notes": "May also be `article-magazine` or `article-newspaper` depending upon the field `entrysubtype`.",
- "source": "bibtex"
- },
- "artifactdataset": {
- "csl": "dataset",
- "source": "ACM-Reference-Format.bst"
- },
- "artifactsoftware": {
- "csl": "software",
- "source": "ACM-Reference-Format.bst"
- },
- "artwork": {
- "csl": "graphic",
- "source": "biblatex"
- },
- "atlas": {
- "csl": null,
- "source": "ametsoc2014.bst"
- },
- "audio": {
- "csl": "song",
- "notes": "CSL's `song` can be used for any audio recording (not only music).",
- "source": "biblatex"
- },
- "bachelor": {
- "csl": "thesis",
- "source": "dlfltxbbibtex.bst"
- },
- "bibnote": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex"
- },
- "book": {
- "csl": "book",
- "source": "bibtex"
- },
- "bookinbook": {
- "csl": "chapter",
- "source": "biblatex"
- },
- "booklet": {
- "csl": "pamphlet",
- "source": "bibtex"
- },
- "brochure": {
- "csl": "pamphlet",
- "source": "thesnumb.bst"
- },
- "cconference": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "collection": {
- "csl": "book",
- "source": "biblatex"
- },
- "comment": {
- "csl": null,
- "notes": "Special entry type for Scribe compatibility",
- "source": "bibtex"
- },
- "commentary": {
- "csl": "book",
- "notes": "Not supported.",
- "source": "biblatex"
- },
- "commented": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "conference": {
- "alias": "inproceedings",
- "csl": "paper-conference",
- "source": "bibtex"
- },
- "ctan": {
- "csl": "software",
- "source": "tugboat.bst"
- },
- "customa": {
- "csl": null,
- "source": "biblatex"
- },
- "customb": {
- "csl": null,
- "source": "biblatex"
- },
- "customc": {
- "csl": null,
- "source": "biblatex"
- },
- "customd": {
- "csl": null,
- "source": "biblatex"
- },
- "custome": {
- "csl": null,
- "source": "biblatex"
- },
- "customf": {
- "csl": null,
- "source": "biblatex"
- },
- "database": {
- "csl": "dataset",
- "source": "gbt7714-numerical.bst"
- },
- "dataset": {
- "csl": "dataset",
- "source": "biblatex"
- },
- "dictionary": {
- "csl": "book",
- "source": "vancouver.bst"
- },
- "docthesis": {
- "csl": "thesis",
- "source": "gost2003.bst"
- },
- "electronic": {
- "alias": "online",
- "csl": "webpage",
- "source": "biblatex"
- },
- "eulegislation": {
- "csl": "legislation",
- "source": "bath.bst"
- },
- "footnote": {
- "csl": null,
- "source": "apsrev4-2.bst"
- },
- "game": {
- "csl": "software",
- "source": "ACM-Reference-Format.bst"
- },
- "govpub": {
- "csl": "regulation",
- "source": "thesnumb.bst"
- },
- "habthesis": {
- "csl": "thesis",
- "source": "bestpapers-export.bst"
- },
- "heading": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "hidden": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "image": {
- "csl": "graphic",
- "source": "biblatex"
- },
- "inbook": {
- "csl": "chapter",
- "source": "bibtex"
- },
- "incollection": {
- "csl": "chapter",
- "source": "bibtex"
- },
- "inloosecollection": {
- "csl": "chapter",
- "source": "resphilosophica.bst"
- },
- "inpress": {
- "csl": "article",
- "notes": "Use for preprints, working papers, and similar works posted on a platform where some level of persistence or stewardship is expected (e.g. arXiv or other preprint repositories, working paper series).",
- "source": "bjnano.bst"
- },
- "inproceedings": {
- "csl": "paper-conference",
- "source": "bibtex"
- },
- "inreference": {
- "csl": "entry",
- "notes": "May also be `entry`, `entry-dictionary` or `entry-encyclopedia`.",
- "source": "biblatex"
- },
- "inserialcollection": {
- "csl": null,
- "source": "asmejour.bst"
- },
- "internet": {
- "csl": "webpage",
- "source": "IEEEtran.bst"
- },
- "journalpart": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "journals": {
- "csl": "periodical",
- "source": "bestpapers-export.bst"
- },
- "jurisdiction": {
- "csl": null,
- "notes": "\"Court decisions, court recordings, and similar things.\"",
- "source": "biblatex"
- },
- "jurthesis": {
- "csl": "thesis",
- "source": "jurabib.bst"
- },
- "legal": {
- "csl": "treaty",
- "notes": "\"Legal documents such as treaties.\"",
- "source": "biblatex"
- },
- "legislation": {
- "csl": "legislation",
- "notes": "\"Laws, bills, legislative proposals, and similar things.\" May also be `bill`",
- "source": "biblatex"
- },
- "letter": {
- "csl": "personal_communication",
- "source": "biblatex"
- },
- "lexicon": {
- "csl": "book",
- "source": "jurabib.bst"
- },
- "majorthesis": {
- "csl": "thesis",
- "source": "achicago.bst"
- },
- "manual": {
- "csl": "report",
- "nots": "CSL's `report` is also used for manuals and similar technical documentation (e.g. a software, instrument, or test manual).",
- "source": "bibtex"
- },
- "map": {
- "csl": "map",
- "source": "vancouver.bst"
- },
- "mastersthesis": {
- "alias": "thesis",
- "csl": "thesis",
- "source": "bibtex"
- },
- "masterthesis": {
- "csl": "thesis",
- "source": "asaetr.bst"
- },
- "minorthesis": {
- "csl": "thesis",
- "source": "achicago.bst"
- },
- "misc": {
- "csl": "document",
- "notes": "New in CSL v1.0.2.",
- "source": "bibtex"
- },
- "monograph": {
- "csl": "book",
- "source": "gbt7714-numerical.bst"
- },
- "monography": {
- "csl": "book",
- "source": "abntex2-alf.bst"
- },
- "movie": {
- "csl": "motion_picture",
- "source": "biblatex"
- },
- "music": {
- "csl": "song",
- "source": "biblatex"
- },
- "mvbook": {
- "csl": "book",
- "source": "biblatex"
- },
- "mvcollection": {
- "csl": "book",
- "source": "biblatex"
- },
- "mvproceedings": {
- "csl": "book",
- "source": "biblatex"
- },
- "mvreference": {
- "csl": "book",
- "source": "biblatex"
- },
- "news": {
- "csl": "article-newspaper",
- "source": "seuthesix.bst"
- },
- "newspaper": {
- "csl": "article-newspaper",
- "source": "gbt7714-numerical.bst"
- },
- "online": {
- "csl": "webpage",
- "source": "biblatex"
- },
- "other": {
- "csl": null,
- "source": "bjnano.bst"
- },
- "patent": {
- "csl": "patent",
- "source": "biblatex"
- },
- "performance": {
- "csl": "performance",
- "notes": "New in CSL v1.0.2.",
- "source": "biblatex"
- },
- "periodical": {
- "csl": "periodical",
- "notes": "New in CSL v1.0.2.",
- "source": "biblatex"
- },
- "phdthesis": {
- "alias": "thesis",
- "csl": "thesis",
- "source": "bibtex"
- },
- "preamble": {
- "csl": null,
- "notes": "Special entry type for inserting commands or text in the bbl",
- "source": "bibtex"
- },
- "preprint": {
- "csl": "article",
- "notes": "Use for preprints, working papers, and similar works posted on a platform where some level of persistence or stewardship is expected (e.g. arXiv or other preprint repositories, working paper series).",
- "source": "gbt7714-numerical.bst"
- },
- "presentation": {
- "csl": "speech",
- "notes": "A speech or other presentation (e.g. a paper, talk, poster, or symposium at a conference).",
- "source": "apsrev4-2.bst"
- },
- "proceedings": {
- "csl": "book",
- "source": "bibtex"
- },
- "program": {
- "csl": "software",
- "source": "ChemCommun.bst"
- },
- "reference": {
- "csl": "book",
- "source": "biblatex"
- },
- "report": {
- "csl": "report",
- "source": "biblatex"
- },
- "review": {
- "csl": "review",
- "notes": "\"A more specific variant of the `@article` type\"",
- "source": "biblatex"
- },
- "set": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex"
- },
- "setup": {
- "csl": null,
- "source": "bestpapers-export.bst"
- },
- "software": {
- "csl": "software",
- "notes": "New in CSL v1.0.2.",
- "source": "biblatex"
- },
- "standard": {
- "csl": "standard",
- "notes": "New in CSL v1.0.2.",
- "source": "biblatex"
- },
- "string": {
- "csl": null,
- "notes": "Special entry type for defining abbreviations",
- "source": "bibtex"
- },
- "suppbook": {
- "csl": "chapter",
- "notes": "lossy mapping; \"Supplemental material in a `@book`. This type is closely related to the @inbook entry type. While `@inbook` is primarily intended for a part of a book with its own title (e. g., a single essay in a collection of essays by the same author), this type is provided for elements such as prefaces, introductions, forewords, afterwords, etc. which often have a generic title only. Style guides may require such items to be formatted differently from other `@inbook` items.\"",
- "source": "biblatex"
- },
- "suppcollection": {
- "csl": "chapter",
- "notes": "lossy mapping; see `suppbook`",
- "source": "biblatex"
- },
- "suppperiodical": {
- "csl": "article",
- "notes": "see `article`",
- "source": "biblatex"
- },
- "techreport": {
- "alias": "report",
- "csl": "report",
- "source": "bibtex"
- },
- "techstandard": {
- "csl": "standard",
- "notes": "New in CSL v1.0.2.",
- "source": "udesoftec.bst"
- },
- "thesis": {
- "csl": "thesis",
- "source": "biblatex"
- },
- "uklegislation": {
- "csl": "legislation",
- "source": "bath.bst"
- },
- "unpublished": {
- "csl": "manuscript",
- "notes": "For unpublished works not made widely available or only hosted on personal websites, use manuscript",
- "source": "bibtex"
- },
- "video": {
- "csl": "motion_picture",
- "source": "biblatex"
- },
- "webpage": {
- "csl": "webpage",
- "source": "IEEEtran.bst"
- },
- "www": {
- "alias": "online",
- "csl": "webpage",
- "source": "biblatex"
- },
- "xdata": {
- "csl": null,
- "notes": "special item type: \"`@xdata` entries hold data which may be inherited by other entries using the xdata field. Entries of this type only serve as data containers; they may not be cited or added to the bibliography.\"",
- "source": "biblatex"
- }
- },
- "fields": {
- "abstract": {
- "csl": "abstract",
- "source": "biblatex",
- "type": "literal"
- },
- "account": {
- "csl": null,
- "source": "address-html.bst"
- },
- "acronym": {
- "csl": null,
- "source": "export.bst"
- },
- "add": {
- "csl": null,
- "source": "figbib.bst"
- },
- "add1": {
- "csl": null,
- "source": "figbib1.bst"
- },
- "addendum": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "address": {
- "alias": "location",
- "csl": "publisher-place",
- "source": "bibtex",
- "type": "literal"
- },
- "adsurl": {
- "csl": null,
- "source": "mnras.bst"
- },
- "advisor": {
- "csl": null,
- "source": "ACM-Reference-Format.bst"
- },
- "afterword": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "name"
- },
- "annotate": {
- "csl": "note",
- "source": "apacite.bst"
- },
- "annotation": {
- "csl": "note",
- "notes": "Descriptive text or notes about an item (e.g. in an annotated bibliography)",
- "source": "biblatex",
- "type": "literal"
- },
- "annotator": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "annote": {
- "alias": "annotation",
- "csl": "note",
- "source": "biblatex",
- "type": "literal"
- },
- "annotelanguage": {
- "csl": null,
- "source": "bababbr3-fl.bst"
- },
- "applicant": {
- "csl": null,
- "source": "seuthesix.bst"
- },
- "archive": {
- "csl": "archive",
- "source": "apsrev4-2.bst"
- },
- "archiveprefix": {
- "alias": "eprinttype",
- "csl": "archive",
- "source": "biblatex",
- "type": "literal"
- },
- "archname": {
- "csl": "archive",
- "source": "jurabib.bst"
- },
- "articleno": {
- "csl": null,
- "source": "ACM-Reference-Format.bst"
- },
- "arxiv": {
- "csl": null,
- "source": "aomalpha.bst"
- },
- "assignee": {
- "csl": null,
- "source": "vancouver.bst"
- },
- "author": {
- "csl": "author",
- "source": "bibtex",
- "type": "name"
- },
- "authorcountry": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "authorfa": {
- "csl": null,
- "source": "asa-fa.bst"
- },
- "authortype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "bibsource": {
- "csl": null,
- "source": "export.bst"
- },
- "biburl": {
- "csl": null,
- "source": "export.bst"
- },
- "binding": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "birthday": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "birthyear": {
- "csl": null,
- "source": "address-html.bst"
- },
- "bookaddress": {
- "csl": null,
- "source": "apsrev4-2.bst"
- },
- "bookauthor": {
- "csl": "container-author",
- "source": "biblatex",
- "type": "name"
- },
- "booklanguage": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "bookpages": {
- "csl": null,
- "source": "ACM-Reference-Format.bst"
- },
- "bookpagination": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "booksubtitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "booktitle": {
- "csl": "container-title",
- "source": "bibtex",
- "type": "literal"
- },
- "booktitleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "caption": {
- "csl": null,
- "source": "figbib.bst"
- },
- "caption1": {
- "csl": null,
- "source": "figbib1.bst"
- },
- "cartographer": {
- "csl": null,
- "source": "vancouver.bst"
- },
- "casenumber": {
- "csl": null,
- "source": "bath.bst"
- },
- "category": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "cellular": {
- "csl": null,
- "source": "address-html.bst"
- },
- "chair": {
- "csl": null,
- "source": "apacite.bst"
- },
- "chapter": {
- "csl": "chapter-number",
- "source": "bibtex",
- "type": "literal"
- },
- "citedate": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "city": {
- "csl": null,
- "source": "ACM-Reference-Format.bst"
- },
- "coden": {
- "csl": null,
- "source": "is-abbrv.bst"
- },
- "collaboration": {
- "csl": null,
- "source": "apsrev4-2.bst"
- },
- "collator": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "commentator": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "compiler": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "condition": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "conference-location": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "conference-number": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "conference-year": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "copy": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "country": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "credits": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "crossref": {
- "csl": null,
- "notes": "Inherits data from a parent entry.",
- "source": "biblatex",
- "type": "entrykey"
- },
- "ctrl-article-title": {
- "csl": null,
- "source": "achemso.bst"
- },
- "ctrl-chapter-title": {
- "csl": null,
- "source": "achemso.bst"
- },
- "ctrl-doi": {
- "csl": null,
- "source": "achemso.bst"
- },
- "ctrl-etal-firstonly": {
- "csl": null,
- "source": "achemso.bst"
- },
- "ctrl-etal-number": {
- "csl": null,
- "source": "achemso.bst"
- },
- "ctrl-link-doi": {
- "csl": null,
- "source": "angew.bst"
- },
- "ctrl-use-doi-all": {
- "csl": null,
- "source": "angew.bst"
- },
- "ctrl-use-title": {
- "csl": null,
- "source": "achemso.bst"
- },
- "dataset": {
- "csl": null,
- "source": "apalike-ejor.bst"
- },
- "date": {
- "csl": "issued",
- "source": "biblatex",
- "type": "date"
- },
- "day": {
- "csl": null,
- "source": "apacite.bst"
- },
- "dayfiled": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "definition": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "department": {
- "csl": null,
- "source": "ametsoc2014.bst"
- },
- "description": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "designator": {
- "csl": null,
- "source": "thesnumb.bst"
- },
- "dimensions": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "dissyear": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "doi": {
- "csl": "DOI",
- "source": "biblatex",
- "type": "verbatim"
- },
- "dticnumber": {
- "csl": null,
- "source": "thesnumb.bst"
- },
- "dummy": {
- "csl": null,
- "source": "expcites.bst"
- },
- "edition": {
- "csl": "edition",
- "source": "bibtex",
- "type": "literal"
- },
- "editor": {
- "csl": "editor",
- "source": "bibtex",
- "type": "name"
- },
- "editora": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "editoratype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "editorb": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "editorbtype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "editorc": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "editorctype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "editortype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "eid": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "email": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "endnumber": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "endvolume": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "endyear": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "englishtitle": {
- "csl": null,
- "source": "apacite.bst"
- },
- "entryset": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "entrykey"
- },
- "entrysubtype": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "epilog": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "eprint": {
- "csl": null,
- "notes": "Mapped to `PMID` if `eprinttype` is \"PubMed\".",
- "source": "biblatex",
- "type": "verbatim"
- },
- "eprintclass": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "eprints": {
- "csl": null,
- "source": "databib.bst"
- },
- "eprinttype": {
- "csl": "archive",
- "source": "biblatex",
- "type": "literal"
- },
- "erratumeid": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "erratumgermanpages": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "erratumnumpages": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "erratumpages": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "erratumvolume": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "erratumyear": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "eventdate": {
- "csl": "event-date",
- "source": "biblatex",
- "type": "date"
- },
- "eventtitle": {
- "csl": "event-title",
- "notes": "Supercedes `event` in CSL v1.0.2.",
- "source": "biblatex",
- "type": "literal"
- },
- "eventtitleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "eventyear": {
- "csl": null,
- "source": "bath.bst"
- },
- "execute": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "code"
- },
- "faddress": {
- "csl": null,
- "source": "achicago.bst"
- },
- "fakeset": {
- "csl": null,
- "source": "biblatex.bst"
- },
- "fax": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "file": {
- "csl": null,
- "source": "biblatex",
- "type": "verbatim"
- },
- "firstkey": {
- "csl": null,
- "source": "apacite.bst"
- },
- "fjournal": {
- "csl": null,
- "source": "ijmart.bst"
- },
- "flanguage": {
- "csl": null,
- "source": "achicago.bst"
- },
- "font": {
- "csl": null,
- "source": "nederlands.bst"
- },
- "foreword": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "founder": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "fpublisher": {
- "csl": null,
- "source": "achicago.bst"
- },
- "ftitle": {
- "csl": null,
- "source": "achicago.bst"
- },
- "furtherresp": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "fyear": {
- "csl": null,
- "source": "achicago.bst"
- },
- "gender": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "germanpages": {
- "csl": null,
- "source": "ChemCommun.bst"
- },
- "group": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "heading": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "hereafter": {
- "csl": null,
- "source": "opcit.bst"
- },
- "holder": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "howcited": {
- "csl": null,
- "source": "jox.bst"
- },
- "howpublished": {
- "csl": null,
- "notes": "Check if a URL is contained.",
- "source": "bibtex",
- "type": "literal"
- },
- "hyphenation": {
- "alias": "langid",
- "csl": "language",
- "source": "biblatex",
- "type": "literal"
- },
- "ids": {
- "csl": null,
- "source": "biblatex",
- "type": "entrykey"
- },
- "illustrated": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "illustrations": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "illustrator": {
- "csl": null,
- "source": "achicago.bst"
- },
- "indexsorttitle": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "indextitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "institution": {
- "csl": "publisher",
- "source": "bibtex",
- "type": "literal"
- },
- "introduction": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "intype": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "inventor": {
- "csl": null,
- "source": "vancouver.bst"
- },
- "ipc": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "isan": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "isbn": {
- "csl": "ISBN",
- "source": "biblatex",
- "type": "literal"
- },
- "ismn": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "iso-abbreviation": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "iso-author-punctuation": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "iso-date-place": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "isrn": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "issn": {
- "csl": "ISSN",
- "source": "biblatex",
- "type": "literal"
- },
- "issue": {
- "csl": "issue",
- "source": "biblatex",
- "type": "literal"
- },
- "issuesubtitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "issuetitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "issuetitleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "iswc": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "jfmnumber": {
- "csl": null,
- "source": "aomalpha.bst"
- },
- "journal": {
- "alias": "journaltitle",
- "csl": "container-title",
- "source": "bibtex",
- "type": "literal"
- },
- "journalsubtitle": {
- "csl": null,
- "notes": "It should be concatenated to the `container-title`.",
- "source": "biblatex",
- "type": "literal"
- },
- "journaltie": {
- "csl": null,
- "source": "tugboat.bst"
- },
- "journaltitle": {
- "csl": "container-title",
- "source": "biblatex",
- "type": "literal"
- },
- "journaltitleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "juraauthor": {
- "csl": null,
- "source": "jox.bst"
- },
- "juratitle": {
- "csl": null,
- "source": "jox.bst"
- },
- "key": {
- "alias": "sortkey",
- "csl": null,
- "notes": "Not supported.",
- "source": "bibtex",
- "type": "literal"
- },
- "keywords": {
- "csl": null,
- "source": "biblatex",
- "type": "keyword"
- },
- "label": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "lang": {
- "csl": null,
- "source": "hustthesis.bst"
- },
- "langid": {
- "csl": "language",
- "notes": "The language id of the bibliography entry. The identifier must be a language name known to the babel/polyglossia packages. It should be converted to ISO 639-1 language code in CSL.",
- "source": "biblatex",
- "type": "literal"
- },
- "langidopts": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "language": {
- "csl": null,
- "notes": "The `language` field in `biblatex` has no special internal meaning thus it is used only when langid is missing.",
- "source": "biblatex",
- "type": "key"
- },
- "lastaccessed": {
- "csl": "accessed",
- "source": "ACM-Reference-Format.bst"
- },
- "lastchecked": {
- "csl": "accessed",
- "source": "apacite.bst"
- },
- "lccn": {
- "csl": null,
- "source": "is-abbrv.bst"
- },
- "library": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "lista": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "listb": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "listc": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "listd": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "liste": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "listf": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "littype": {
- "csl": null,
- "source": "seuthesix.bst"
- },
- "location": {
- "csl": "publisher-place",
- "source": "biblatex",
- "type": "literal"
- },
- "madadurltest": {
- "csl": null,
- "source": "alpha-persian.bst"
- },
- "main": {
- "csl": null,
- "source": "figbib.bst"
- },
- "main1": {
- "csl": null,
- "source": "figbib1.bst"
- },
- "mainsubtitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "maintitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "maintitleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "majorcode": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "marginnote": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "mark": {
- "csl": null,
- "source": "gbt7714-numerical.bst"
- },
- "max.best.papers": {
- "csl": null,
- "source": "bestpapers-export.bst"
- },
- "mcitetail": {
- "csl": null,
- "source": "apsrmpM.bst"
- },
- "media": {
- "csl": "medium",
- "source": "gost2003.bst"
- },
- "medium": {
- "csl": "medium",
- "source": "gbt7714-numerical.bst"
- },
- "meeting": {
- "csl": null,
- "source": "amsra.bst"
- },
- "misctitle": {
- "csl": null,
- "source": "aasjournal.bst"
- },
- "miscyear": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "mobile": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "modifydate": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "month": {
- "csl": null,
- "notes": "Used only when `date` is empty.",
- "source": "bibtex",
- "type": "literal"
- },
- "monthfiled": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "mrnumber": {
- "csl": null,
- "source": "amsplain.bst"
- },
- "name": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "namea": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "nameaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "nameatype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "nameb": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "namebtype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "namec": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "namectype": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "nationality": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "nbirthday": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "newpage": {
- "csl": null,
- "source": "tugboat.bst"
- },
- "newspaper": {
- "csl": "container-title",
- "source": "seuthesix.bst"
- },
- "nickname": {
- "csl": null,
- "source": "address-html.bst"
- },
- "nihms": {
- "csl": null,
- "source": "apacite.bst"
- },
- "noed": {
- "csl": null,
- "source": "jox.bst"
- },
- "normal": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "normalauthor": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "normaleditor": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "note": {
- "csl": "note",
- "source": "bibtex",
- "type": "literal"
- },
- "nowarning": {
- "csl": null,
- "source": "tugboat.bst"
- },
- "number": {
- "csl": "number",
- "notes": "It is mapped to `issue` in `@ariticle` but to `number` in `@patent` or `@report`.",
- "source": "bibtex",
- "type": "literal"
- },
- "numpages": {
- "csl": null,
- "source": "ACM-Reference-Format.bst"
- },
- "oaddress": {
- "csl": null,
- "source": "achicago.bst"
- },
- "options": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "option"
- },
- "opublisher": {
- "csl": null,
- "source": "achicago.bst"
- },
- "org-short": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "organization": {
- "csl": "publisher",
- "notes": "It is mapped to `author` (in `institution` property) if possible.",
- "source": "bibtex",
- "type": "literal"
- },
- "origdate": {
- "csl": "original-date",
- "source": "biblatex",
- "type": "date"
- },
- "originaladdress": {
- "csl": "original-publisher-place",
- "source": "apacite.bst"
- },
- "originalbooktitle": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originaledition": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originaleditor": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originaljournal": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originalnumber": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originalpages": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originalpublisher": {
- "csl": "original-publisher",
- "source": "apacite.bst"
- },
- "originalvolume": {
- "csl": null,
- "source": "apacite.bst"
- },
- "originalyear": {
- "csl": "original-date",
- "source": "apacite.bst"
- },
- "origlanguage": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "origlocation": {
- "csl": "original-publisher-place",
- "source": "biblatex",
- "type": "literal"
- },
- "origpublisher": {
- "csl": "original-publisher",
- "source": "biblatex",
- "type": "literal"
- },
- "origtitle": {
- "csl": "original-title",
- "source": "biblatex",
- "type": "literal"
- },
- "oyear": {
- "csl": null,
- "source": "achicago.bst"
- },
- "pagename": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "pages": {
- "csl": "page",
- "source": "bibtex",
- "type": "range"
- },
- "pagetotal": {
- "csl": "number-of-pages",
- "source": "biblatex",
- "type": "literal"
- },
- "pagination": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "paper": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "part": {
- "csl": "part",
- "source": "biblatex",
- "type": "literal"
- },
- "patentid": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "pdf": {
- "alias": "file",
- "csl": null,
- "source": "biblatex",
- "type": "verbatim"
- },
- "phone": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "pid": {
- "csl": null,
- "source": "seuthesix.bst"
- },
- "pii": {
- "csl": null,
- "source": "amsra.bst"
- },
- "pmcid": {
- "csl": "PMCID",
- "source": "apacite.bst"
- },
- "prebibitem": {
- "csl": null,
- "source": "tugboat.bst"
- },
- "preface": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "preprint": {
- "csl": null,
- "source": "amsra.bst"
- },
- "presort": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "price": {
- "csl": null,
- "source": "is-abbrv.bst"
- },
- "primaryclass": {
- "alias": "eprintclass",
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "printing": {
- "csl": null,
- "source": "dk-abbrv.bst"
- },
- "prioritycountry": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "prioritydate": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "prioritynumber": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "pseudonym": {
- "csl": null,
- "source": "jox.bst"
- },
- "publication": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "publicationdate": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "publisher": {
- "csl": "publisher",
- "source": "bibtex",
- "type": "literal"
- },
- "pubmed": {
- "csl": "PMID",
- "source": "urlbst"
- },
- "pubstate": {
- "csl": null,
- "source": "biblatex",
- "type": "key"
- },
- "related": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "entrykey"
- },
- "relatedoptions": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "option"
- },
- "relatedstring": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "relatedtype": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "reprinted-from": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "reprinted-text": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "reprinttitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "requestdate": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "requestnumber": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "responsible": {
- "csl": null,
- "source": "rusnat.bst"
- },
- "review": {
- "csl": null,
- "source": "amsra.bst"
- },
- "revision": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "school": {
- "alias": "institution",
- "csl": "publisher",
- "source": "bibtex",
- "type": "literal"
- },
- "score": {
- "csl": null,
- "source": "bestpapers-export.bst"
- },
- "section": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "series": {
- "csl": "collection-title",
- "source": "bibtex",
- "type": "literal"
- },
- "seriesedition": {
- "csl": null,
- "source": "achicago.bst"
- },
- "short": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "shortarchive": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "shortauthor": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "shorteditor": {
- "csl": null,
- "source": "biblatex",
- "type": "name"
- },
- "shorthand": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "shorthandintro": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "shortjournal": {
- "csl": "container-title-short",
- "source": "biblatex",
- "type": "literal"
- },
- "shortseries": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "shortsubarchive": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "shorttitle": {
- "csl": "title-short",
- "source": "biblatex",
- "type": "literal"
- },
- "sig1": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "sig2": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "sig3": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "sig4": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "size": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "slaccitation": {
- "csl": null,
- "source": "apsrev4-2.bst"
- },
- "sort-short": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "sort-word": {
- "csl": null,
- "source": "glsplain.bst"
- },
- "sortas": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "sortkey": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "sortname": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "name"
- },
- "sortshorthand": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "sorttitle": {
- "csl": null,
- "notes": "Not supported.",
- "source": "biblatex",
- "type": "literal"
- },
- "sortyear": {
- "csl": null,
- "source": "biblatex",
- "type": "integer"
- },
- "source": {
- "csl": null,
- "source": "figbib.bst"
- },
- "source1": {
- "csl": null,
- "source": "figbib1.bst"
- },
- "specialitycode": {
- "csl": null,
- "source": "gost2003.bst"
- },
- "ssedition": {
- "csl": null,
- "source": "jox.bst"
- },
- "standard": {
- "csl": null,
- "source": "udesoftec.bst"
- },
- "startnumber": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "startvolume": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "startyear": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "state": {
- "csl": null,
- "source": "address-html.bst"
- },
- "status": {
- "csl": null,
- "source": "amsra.bst"
- },
- "stdcode": {
- "csl": null,
- "source": "seuthesix.bst"
- },
- "stitle": {
- "csl": null,
- "source": "jox.bst"
- },
- "street": {
- "csl": null,
- "source": "adrbirthday.bst"
- },
- "subarchive": {
- "csl": null,
- "source": "jurabib.bst"
- },
- "subtitle": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "symposium": {
- "csl": null,
- "source": "apacite.bst"
- },
- "text": {
- "csl": null,
- "source": "apacite.bst"
- },
- "timestamp": {
- "csl": null,
- "source": "export.bst"
- },
- "title": {
- "csl": "title",
- "source": "bibtex",
- "type": "literal"
- },
- "titleaddon": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "titlenote": {
- "csl": null,
- "source": "aomalpha.bst"
- },
- "totalpages": {
- "csl": null,
- "source": "aomalpha.bst"
- },
- "transissue": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "transjournal": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "translation": {
- "csl": null,
- "source": "apsrev4-2.bst"
- },
- "translator": {
- "csl": "translator",
- "source": "biblatex",
- "type": "name"
- },
- "transnumber": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "transpages": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "transsection": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "transvolume": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "transyear": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "type": {
- "csl": "genre",
- "source": "bibtex",
- "type": "key"
- },
- "typeoflit": {
- "csl": null,
- "source": "seuthesis.bst"
- },
- "umfnumber": {
- "csl": null,
- "source": "thesnumb.bst"
- },
- "updated": {
- "csl": null,
- "source": "vancouver.bst"
- },
- "url": {
- "csl": "URL",
- "source": "biblatex",
- "type": "uri"
- },
- "urlaccessdate": {
- "csl": "accessed",
- "source": "abntex2-alf.bst"
- },
- "urldate": {
- "csl": "accessed",
- "source": "biblatex",
- "type": "date"
- },
- "urlnewline": {
- "csl": null,
- "source": "tugboat.bst"
- },
- "urltype": {
- "csl": null,
- "source": "asmeconf.bst"
- },
- "urlyear": {
- "csl": null,
- "source": "bath.bst"
- },
- "urn": {
- "csl": null,
- "source": "export.bst"
- },
- "usera": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "userb": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "userc": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "userd": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "usere": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "userf": {
- "csl": null,
- "source": "biblatex",
- "type": "literal"
- },
- "value": {
- "csl": null,
- "source": "bookdb.bst"
- },
- "venue": {
- "csl": "event-place",
- "source": "biblatex",
- "type": "literal"
- },
- "verba": {
- "csl": null,
- "source": "biblatex",
- "type": "verbatim"
- },
- "verbb": {
- "csl": null,
- "source": "biblatex",
- "type": "verbatim"
- },
- "verbc": {
- "csl": null,
- "source": "biblatex",
- "type": "verbatim"
- },
- "version": {
- "csl": "version",
- "source": "biblatex",
- "type": "literal"
- },
- "versiontype": {
- "csl": null,
- "source": "asmeconf.bst"
- },
- "volformat": {
- "csl": null,
- "source": "jox.bst"
- },
- "volume": {
- "csl": "volume",
- "source": "bibtex",
- "type": "integer"
- },
- "volumes": {
- "csl": "number-of-volumes",
- "source": "biblatex",
- "type": "integer"
- },
- "volumetitle": {
- "csl": null,
- "source": "iopart-num.bst"
- },
- "word": {
- "csl": null,
- "source": "vancouver.bst"
- },
- "xdata": {
- "csl": null,
- "notes": "inherits fields from other items.",
- "source": "biblatex",
- "type": "entrykey"
- },
- "xid": {
- "csl": null,
- "source": "amsra.bst"
- },
- "xref": {
- "csl": null,
- "notes": "Establishes a parent-child relationship in biblatex, but without inheriting data => no need to parse this.",
- "source": "biblatex",
- "type": "entrykey"
- },
- "year": {
- "csl": null,
- "notes": "Used only when `date` is empty.",
- "source": "bibtex",
- "type": "date"
- },
- "year-presented": {
- "csl": null,
- "source": "abntex2-alf.bst"
- },
- "yearcomp": {
- "csl": null,
- "source": "achicago.bst"
- },
- "yearfiled": {
- "csl": null,
- "source": "IEEEtran.bst"
- },
- "zblnumber": {
- "csl": null,
- "source": "aomalpha.bst"
- },
- "zip": {
- "csl": null,
- "source": "adrbirthday.bst"
- }
- },
- "macros": {
- "jan": {
- "value": "1",
- "notes": "Use numeric form for easy conversion.",
- "source": "bibtex"
- },
- "feb": {
- "value": "2",
- "source": "bibtex"
- },
- "mar": {
- "value": "3",
- "source": "bibtex"
- },
- "apr": {
- "value": "4",
- "source": "bibtex"
- },
- "may": {
- "value": "5",
- "source": "bibtex"
- },
- "jun": {
- "value": "6",
- "source": "bibtex"
- },
- "jul": {
- "value": "7",
- "source": "bibtex"
- },
- "aug": {
- "value": "8",
- "source": "bibtex"
- },
- "sep": {
- "value": "9",
- "source": "bibtex"
- },
- "oct": {
- "value": "10",
- "source": "bibtex"
- },
- "nov": {
- "value": "11",
- "source": "bibtex"
- },
- "dec": {
- "value": "12",
- "source": "bibtex"
- },
- "acmcs": {
- "value": "ACM Computing Surveys",
- "source": "bibtex"
- },
- "acta": {
- "value": "Acta Informatica",
- "source": "bibtex"
- },
- "cacm": {
- "value": "Communications of the ACM",
- "source": "bibtex"
- },
- "ibmjrd": {
- "value": "IBM Journal of Research and Development",
- "source": "bibtex"
- },
- "ibmsj": {
- "value": "IBM Systems Journal",
- "source": "bibtex"
- },
- "ieeese": {
- "value": "IEEE Transactions on Software Engineering",
- "source": "bibtex"
- },
- "ieeetc": {
- "value": "IEEE Transactions on Computers",
- "source": "bibtex"
- },
- "ieeetcad": {
- "value": "IEEE Transactions on Computer-Aided Design of Integrated Circuits",
- "source": "bibtex"
- },
- "ipl": {
- "value": "Information Processing Letters",
- "source": "bibtex"
- },
- "jacm": {
- "value": "Journal of the ACM",
- "source": "bibtex"
- },
- "jcss": {
- "value": "Journal of Computer and System Sciences",
- "source": "bibtex"
- },
- "scp": {
- "value": "Science of Computer Programming",
- "source": "bibtex"
- },
- "sicomp": {
- "value": "SIAM Journal on Computing",
- "source": "bibtex"
- },
- "tocs": {
- "value": "ACM Transactions on Computer Systems",
- "source": "bibtex"
- },
- "tods": {
- "value": "ACM Transactions on Database Systems",
- "source": "bibtex"
- },
- "tog": {
- "value": "ACM Transactions on Graphics",
- "source": "bibtex"
- },
- "toms": {
- "value": "ACM Transactions on Mathematical Software",
- "source": "bibtex"
- },
- "toois": {
- "value": "ACM Transactions on Office Information Systems",
- "source": "bibtex"
- },
- "toplas": {
- "value": "ACM Transactions on Programming Languages and Systems",
- "source": "bibtex"
- },
- "tcs": {
- "value": "Theoretical Computer Science",
- "source": "bibtex"
- }
- }
-}
diff --git a/biblio/citation-style-language/citeproc-bib-data.lua b/biblio/citation-style-language/citeproc-bib-data.lua
new file mode 100644
index 0000000000..dafd3d05b4
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-bib-data.lua
@@ -0,0 +1,1759 @@
+-- This file is generated from citeproc-bib-data.json by update-bib-date.py
+
+return {
+ ["description"] = "Bib CSL mapping",
+ ["types"] = {
+ ["archival"] = {
+ ["csl"] = "collection",
+ },
+ ["archive"] = {
+ ["csl"] = "collection",
+ },
+ ["article"] = {
+ ["csl"] = "article-journal",
+ },
+ ["artifactdataset"] = {
+ ["csl"] = "dataset",
+ },
+ ["artifactsoftware"] = {
+ ["csl"] = "software",
+ },
+ ["artwork"] = {
+ ["csl"] = "graphic",
+ },
+ ["atlas"] = {
+ ["csl"] = nil,
+ },
+ ["audio"] = {
+ ["csl"] = "song",
+ },
+ ["bachelor"] = {
+ ["csl"] = "thesis",
+ },
+ ["bibnote"] = {
+ ["csl"] = nil,
+ },
+ ["book"] = {
+ ["csl"] = "book",
+ },
+ ["bookinbook"] = {
+ ["csl"] = "chapter",
+ },
+ ["booklet"] = {
+ ["csl"] = "pamphlet",
+ },
+ ["brochure"] = {
+ ["csl"] = "pamphlet",
+ },
+ ["cconference"] = {
+ ["csl"] = nil,
+ },
+ ["collection"] = {
+ ["csl"] = "book",
+ },
+ ["comment"] = {
+ ["csl"] = nil,
+ },
+ ["commentary"] = {
+ ["csl"] = "book",
+ },
+ ["commented"] = {
+ ["csl"] = nil,
+ },
+ ["conference"] = {
+ ["csl"] = "paper-conference",
+ },
+ ["ctan"] = {
+ ["csl"] = "software",
+ },
+ ["customa"] = {
+ ["csl"] = nil,
+ },
+ ["customb"] = {
+ ["csl"] = nil,
+ },
+ ["customc"] = {
+ ["csl"] = nil,
+ },
+ ["customd"] = {
+ ["csl"] = nil,
+ },
+ ["custome"] = {
+ ["csl"] = nil,
+ },
+ ["customf"] = {
+ ["csl"] = nil,
+ },
+ ["database"] = {
+ ["csl"] = "dataset",
+ },
+ ["dataset"] = {
+ ["csl"] = "dataset",
+ },
+ ["dictionary"] = {
+ ["csl"] = "book",
+ },
+ ["docthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["electronic"] = {
+ ["csl"] = "webpage",
+ },
+ ["eulegislation"] = {
+ ["csl"] = "legislation",
+ },
+ ["footnote"] = {
+ ["csl"] = nil,
+ },
+ ["game"] = {
+ ["csl"] = "software",
+ },
+ ["govpub"] = {
+ ["csl"] = "regulation",
+ },
+ ["habthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["heading"] = {
+ ["csl"] = nil,
+ },
+ ["hidden"] = {
+ ["csl"] = nil,
+ },
+ ["image"] = {
+ ["csl"] = "graphic",
+ },
+ ["inbook"] = {
+ ["csl"] = "chapter",
+ },
+ ["incollection"] = {
+ ["csl"] = "chapter",
+ },
+ ["inloosecollection"] = {
+ ["csl"] = "chapter",
+ },
+ ["inpress"] = {
+ ["csl"] = "article",
+ },
+ ["inproceedings"] = {
+ ["csl"] = "paper-conference",
+ },
+ ["inreference"] = {
+ ["csl"] = "entry",
+ },
+ ["inserialcollection"] = {
+ ["csl"] = nil,
+ },
+ ["internet"] = {
+ ["csl"] = "webpage",
+ },
+ ["journalpart"] = {
+ ["csl"] = nil,
+ },
+ ["journals"] = {
+ ["csl"] = "periodical",
+ },
+ ["jurisdiction"] = {
+ ["csl"] = nil,
+ },
+ ["jurthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["legal"] = {
+ ["csl"] = "treaty",
+ },
+ ["legislation"] = {
+ ["csl"] = "legislation",
+ },
+ ["letter"] = {
+ ["csl"] = "personal_communication",
+ },
+ ["lexicon"] = {
+ ["csl"] = "book",
+ },
+ ["majorthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["manual"] = {
+ ["csl"] = "report",
+ },
+ ["map"] = {
+ ["csl"] = "map",
+ },
+ ["mastersthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["masterthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["minorthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["misc"] = {
+ ["csl"] = "document",
+ },
+ ["monograph"] = {
+ ["csl"] = "book",
+ },
+ ["monography"] = {
+ ["csl"] = "book",
+ },
+ ["movie"] = {
+ ["csl"] = "motion_picture",
+ },
+ ["music"] = {
+ ["csl"] = "song",
+ },
+ ["mvbook"] = {
+ ["csl"] = "book",
+ },
+ ["mvcollection"] = {
+ ["csl"] = "book",
+ },
+ ["mvproceedings"] = {
+ ["csl"] = "book",
+ },
+ ["mvreference"] = {
+ ["csl"] = "book",
+ },
+ ["news"] = {
+ ["csl"] = "article-newspaper",
+ },
+ ["newspaper"] = {
+ ["csl"] = "article-newspaper",
+ },
+ ["online"] = {
+ ["csl"] = "webpage",
+ },
+ ["other"] = {
+ ["csl"] = nil,
+ },
+ ["patent"] = {
+ ["csl"] = "patent",
+ },
+ ["performance"] = {
+ ["csl"] = "performance",
+ },
+ ["periodical"] = {
+ ["csl"] = "periodical",
+ },
+ ["phdthesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["preamble"] = {
+ ["csl"] = nil,
+ },
+ ["preprint"] = {
+ ["csl"] = "article",
+ },
+ ["presentation"] = {
+ ["csl"] = "speech",
+ },
+ ["proceedings"] = {
+ ["csl"] = "book",
+ },
+ ["program"] = {
+ ["csl"] = "software",
+ },
+ ["reference"] = {
+ ["csl"] = "book",
+ },
+ ["report"] = {
+ ["csl"] = "report",
+ },
+ ["repository"] = {
+ ["csl"] = nil,
+ },
+ ["review"] = {
+ ["csl"] = "review",
+ },
+ ["set"] = {
+ ["csl"] = nil,
+ },
+ ["setup"] = {
+ ["csl"] = nil,
+ },
+ ["software"] = {
+ ["csl"] = "software",
+ },
+ ["standard"] = {
+ ["csl"] = "standard",
+ },
+ ["string"] = {
+ ["csl"] = nil,
+ },
+ ["suppbook"] = {
+ ["csl"] = "chapter",
+ },
+ ["suppcollection"] = {
+ ["csl"] = "chapter",
+ },
+ ["suppperiodical"] = {
+ ["csl"] = "article",
+ },
+ ["techreport"] = {
+ ["csl"] = "report",
+ },
+ ["techstandard"] = {
+ ["csl"] = "standard",
+ },
+ ["thesis"] = {
+ ["csl"] = "thesis",
+ },
+ ["uklegislation"] = {
+ ["csl"] = "legislation",
+ },
+ ["unpublished"] = {
+ ["csl"] = "manuscript",
+ },
+ ["video"] = {
+ ["csl"] = "motion_picture",
+ },
+ ["webpage"] = {
+ ["csl"] = "webpage",
+ },
+ ["website"] = {
+ ["csl"] = nil,
+ },
+ ["www"] = {
+ ["csl"] = "webpage",
+ },
+ ["xdata"] = {
+ ["csl"] = nil,
+ },
+ },
+ ["fields"] = {
+ ["abstract"] = {
+ ["csl"] = "abstract",
+ ["type"] = "literal",
+ },
+ ["account"] = {
+ ["csl"] = nil,
+ },
+ ["acronym"] = {
+ ["csl"] = nil,
+ },
+ ["add"] = {
+ ["csl"] = nil,
+ },
+ ["add1"] = {
+ ["csl"] = nil,
+ },
+ ["addendum"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["address"] = {
+ ["csl"] = "publisher-place",
+ ["type"] = "literal",
+ },
+ ["adsurl"] = {
+ ["csl"] = nil,
+ },
+ ["advisor"] = {
+ ["csl"] = nil,
+ },
+ ["afterword"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["annotate"] = {
+ ["csl"] = "note",
+ },
+ ["annotation"] = {
+ ["csl"] = "note",
+ ["type"] = "literal",
+ },
+ ["annotator"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["annote"] = {
+ ["csl"] = "note",
+ ["type"] = "literal",
+ },
+ ["annotelanguage"] = {
+ ["csl"] = nil,
+ },
+ ["applicant"] = {
+ ["csl"] = nil,
+ },
+ ["archive"] = {
+ ["csl"] = "archive",
+ },
+ ["archiveprefix"] = {
+ ["csl"] = "archive",
+ ["type"] = "literal",
+ },
+ ["archname"] = {
+ ["csl"] = "archive",
+ },
+ ["articleno"] = {
+ ["csl"] = nil,
+ },
+ ["arxiv"] = {
+ ["csl"] = nil,
+ },
+ ["assignee"] = {
+ ["csl"] = nil,
+ },
+ ["author"] = {
+ ["csl"] = "author",
+ ["type"] = "name",
+ },
+ ["authorcountry"] = {
+ ["csl"] = nil,
+ },
+ ["authorfa"] = {
+ ["csl"] = nil,
+ },
+ ["authortype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["bibsource"] = {
+ ["csl"] = nil,
+ },
+ ["biburl"] = {
+ ["csl"] = nil,
+ },
+ ["binding"] = {
+ ["csl"] = nil,
+ },
+ ["birthday"] = {
+ ["csl"] = nil,
+ },
+ ["birthyear"] = {
+ ["csl"] = nil,
+ },
+ ["bookaddress"] = {
+ ["csl"] = nil,
+ },
+ ["bookauthor"] = {
+ ["csl"] = "container-author",
+ ["type"] = "name",
+ },
+ ["booklanguage"] = {
+ ["csl"] = nil,
+ },
+ ["bookpages"] = {
+ ["csl"] = nil,
+ },
+ ["bookpagination"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["booksubtitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["booktitle"] = {
+ ["csl"] = "container-title",
+ ["type"] = "literal",
+ },
+ ["booktitleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["caption"] = {
+ ["csl"] = nil,
+ },
+ ["caption1"] = {
+ ["csl"] = nil,
+ },
+ ["cartographer"] = {
+ ["csl"] = nil,
+ },
+ ["casenumber"] = {
+ ["csl"] = nil,
+ },
+ ["category"] = {
+ ["csl"] = nil,
+ },
+ ["cellular"] = {
+ ["csl"] = nil,
+ },
+ ["chair"] = {
+ ["csl"] = nil,
+ },
+ ["chapter"] = {
+ ["csl"] = "chapter-number",
+ ["type"] = "literal",
+ },
+ ["citedate"] = {
+ ["csl"] = nil,
+ },
+ ["city"] = {
+ ["csl"] = nil,
+ },
+ ["code"] = {
+ ["csl"] = nil,
+ },
+ ["coden"] = {
+ ["csl"] = nil,
+ },
+ ["collaboration"] = {
+ ["csl"] = nil,
+ },
+ ["collator"] = {
+ ["csl"] = nil,
+ },
+ ["commentator"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["commit"] = {
+ ["csl"] = nil,
+ },
+ ["compiler"] = {
+ ["csl"] = nil,
+ },
+ ["condition"] = {
+ ["csl"] = nil,
+ },
+ ["conference-location"] = {
+ ["csl"] = nil,
+ },
+ ["conference-number"] = {
+ ["csl"] = nil,
+ },
+ ["conference-year"] = {
+ ["csl"] = nil,
+ },
+ ["copy"] = {
+ ["csl"] = nil,
+ },
+ ["country"] = {
+ ["csl"] = nil,
+ },
+ ["credits"] = {
+ ["csl"] = nil,
+ },
+ ["crossref"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["ctrl-article-title"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-chapter-title"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-doi"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-etal-firstonly"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-etal-number"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-link-doi"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-use-doi-all"] = {
+ ["csl"] = nil,
+ },
+ ["ctrl-use-title"] = {
+ ["csl"] = nil,
+ },
+ ["dataset"] = {
+ ["csl"] = nil,
+ },
+ ["date"] = {
+ ["csl"] = "issued",
+ ["type"] = "date",
+ },
+ ["day"] = {
+ ["csl"] = nil,
+ },
+ ["dayfiled"] = {
+ ["csl"] = nil,
+ },
+ ["definition"] = {
+ ["csl"] = nil,
+ },
+ ["department"] = {
+ ["csl"] = nil,
+ },
+ ["description"] = {
+ ["csl"] = nil,
+ },
+ ["designator"] = {
+ ["csl"] = nil,
+ },
+ ["dimensions"] = {
+ ["csl"] = nil,
+ },
+ ["dissyear"] = {
+ ["csl"] = nil,
+ },
+ ["doi"] = {
+ ["csl"] = "DOI",
+ ["type"] = "verbatim",
+ },
+ ["dticnumber"] = {
+ ["csl"] = nil,
+ },
+ ["dummy"] = {
+ ["csl"] = nil,
+ },
+ ["edition"] = {
+ ["csl"] = "edition",
+ ["type"] = "literal",
+ },
+ ["editor"] = {
+ ["csl"] = "editor",
+ ["type"] = "name",
+ },
+ ["editora"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["editoratype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["editorb"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["editorbtype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["editorc"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["editorctype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["editortype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["eid"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["email"] = {
+ ["csl"] = nil,
+ },
+ ["endnumber"] = {
+ ["csl"] = nil,
+ },
+ ["endvolume"] = {
+ ["csl"] = nil,
+ },
+ ["endyear"] = {
+ ["csl"] = nil,
+ },
+ ["englishtitle"] = {
+ ["csl"] = nil,
+ },
+ ["entryset"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["entrysubtype"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["epilog"] = {
+ ["csl"] = nil,
+ },
+ ["eprint"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["eprintclass"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["eprints"] = {
+ ["csl"] = nil,
+ },
+ ["eprinttype"] = {
+ ["csl"] = "archive",
+ ["type"] = "literal",
+ },
+ ["erratumeid"] = {
+ ["csl"] = nil,
+ },
+ ["erratumgermanpages"] = {
+ ["csl"] = nil,
+ },
+ ["erratumnumpages"] = {
+ ["csl"] = nil,
+ },
+ ["erratumpages"] = {
+ ["csl"] = nil,
+ },
+ ["erratumvolume"] = {
+ ["csl"] = nil,
+ },
+ ["erratumyear"] = {
+ ["csl"] = nil,
+ },
+ ["eventdate"] = {
+ ["csl"] = "event-date",
+ ["type"] = "date",
+ },
+ ["eventtitle"] = {
+ ["csl"] = "event-title",
+ ["type"] = "literal",
+ },
+ ["eventtitleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["eventyear"] = {
+ ["csl"] = nil,
+ },
+ ["execute"] = {
+ ["csl"] = nil,
+ ["type"] = "code",
+ },
+ ["faddress"] = {
+ ["csl"] = nil,
+ },
+ ["fakeset"] = {
+ ["csl"] = nil,
+ },
+ ["fax"] = {
+ ["csl"] = nil,
+ },
+ ["file"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["firstkey"] = {
+ ["csl"] = nil,
+ },
+ ["fjournal"] = {
+ ["csl"] = nil,
+ },
+ ["flanguage"] = {
+ ["csl"] = nil,
+ },
+ ["font"] = {
+ ["csl"] = nil,
+ },
+ ["foreword"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["founder"] = {
+ ["csl"] = nil,
+ },
+ ["fpublisher"] = {
+ ["csl"] = nil,
+ },
+ ["ftitle"] = {
+ ["csl"] = nil,
+ },
+ ["furtherresp"] = {
+ ["csl"] = nil,
+ },
+ ["fyear"] = {
+ ["csl"] = nil,
+ },
+ ["gender"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["germanpages"] = {
+ ["csl"] = nil,
+ },
+ ["group"] = {
+ ["csl"] = nil,
+ },
+ ["heading"] = {
+ ["csl"] = nil,
+ },
+ ["hereafter"] = {
+ ["csl"] = nil,
+ },
+ ["holder"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["howcited"] = {
+ ["csl"] = nil,
+ },
+ ["howpublished"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["hyphenation"] = {
+ ["csl"] = "language",
+ ["type"] = "literal",
+ },
+ ["ids"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["illustrated"] = {
+ ["csl"] = nil,
+ },
+ ["illustrations"] = {
+ ["csl"] = nil,
+ },
+ ["illustrator"] = {
+ ["csl"] = nil,
+ },
+ ["indexsorttitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["indextitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["institution"] = {
+ ["csl"] = "publisher",
+ ["type"] = "literal",
+ },
+ ["introduction"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["intype"] = {
+ ["csl"] = nil,
+ },
+ ["inventor"] = {
+ ["csl"] = nil,
+ },
+ ["ipc"] = {
+ ["csl"] = nil,
+ },
+ ["isan"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["isbn"] = {
+ ["csl"] = "ISBN",
+ ["type"] = "literal",
+ },
+ ["ismn"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["iso-abbreviation"] = {
+ ["csl"] = nil,
+ },
+ ["iso-author-punctuation"] = {
+ ["csl"] = nil,
+ },
+ ["iso-date-place"] = {
+ ["csl"] = nil,
+ },
+ ["isrn"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["issn"] = {
+ ["csl"] = "ISSN",
+ ["type"] = "literal",
+ },
+ ["issue"] = {
+ ["csl"] = "issue",
+ ["type"] = "literal",
+ },
+ ["issuesubtitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["issuetitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["issuetitleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["iswc"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["jfmnumber"] = {
+ ["csl"] = nil,
+ },
+ ["journal"] = {
+ ["csl"] = "container-title",
+ ["type"] = "literal",
+ },
+ ["journalsubtitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["journaltie"] = {
+ ["csl"] = nil,
+ },
+ ["journaltitle"] = {
+ ["csl"] = "container-title",
+ ["type"] = "literal",
+ },
+ ["journaltitleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["juraauthor"] = {
+ ["csl"] = nil,
+ },
+ ["juratitle"] = {
+ ["csl"] = nil,
+ },
+ ["key"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["keywords"] = {
+ ["csl"] = nil,
+ ["type"] = "keyword",
+ },
+ ["label"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["lang"] = {
+ ["csl"] = nil,
+ },
+ ["langid"] = {
+ ["csl"] = "language",
+ ["type"] = "literal",
+ },
+ ["langidopts"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["language"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["lastaccessed"] = {
+ ["csl"] = "accessed",
+ },
+ ["lastchecked"] = {
+ ["csl"] = "accessed",
+ },
+ ["lccn"] = {
+ ["csl"] = nil,
+ },
+ ["library"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["lista"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["listb"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["listc"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["listd"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["liste"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["listf"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["littype"] = {
+ ["csl"] = nil,
+ },
+ ["location"] = {
+ ["csl"] = "publisher-place",
+ ["type"] = "literal",
+ },
+ ["madadurltest"] = {
+ ["csl"] = nil,
+ },
+ ["main"] = {
+ ["csl"] = nil,
+ },
+ ["main1"] = {
+ ["csl"] = nil,
+ },
+ ["mainsubtitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["maintitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["maintitleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["majorcode"] = {
+ ["csl"] = nil,
+ },
+ ["marginnote"] = {
+ ["csl"] = nil,
+ },
+ ["mark"] = {
+ ["csl"] = nil,
+ },
+ ["max.best.papers"] = {
+ ["csl"] = nil,
+ },
+ ["mcitetail"] = {
+ ["csl"] = nil,
+ },
+ ["media"] = {
+ ["csl"] = "medium",
+ },
+ ["medium"] = {
+ ["csl"] = "medium",
+ },
+ ["meeting"] = {
+ ["csl"] = nil,
+ },
+ ["misctitle"] = {
+ ["csl"] = nil,
+ },
+ ["miscyear"] = {
+ ["csl"] = nil,
+ },
+ ["mobile"] = {
+ ["csl"] = nil,
+ },
+ ["modifydate"] = {
+ ["csl"] = nil,
+ },
+ ["month"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["monthfiled"] = {
+ ["csl"] = nil,
+ },
+ ["mrnumber"] = {
+ ["csl"] = nil,
+ },
+ ["name"] = {
+ ["csl"] = nil,
+ },
+ ["namea"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["nameaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["nameatype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["nameb"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["namebtype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["namec"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["namectype"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["nationality"] = {
+ ["csl"] = nil,
+ },
+ ["nbirthday"] = {
+ ["csl"] = nil,
+ },
+ ["newpage"] = {
+ ["csl"] = nil,
+ },
+ ["newspaper"] = {
+ ["csl"] = "container-title",
+ },
+ ["nickname"] = {
+ ["csl"] = nil,
+ },
+ ["nihms"] = {
+ ["csl"] = nil,
+ },
+ ["noed"] = {
+ ["csl"] = nil,
+ },
+ ["nolink"] = {
+ ["csl"] = nil,
+ },
+ ["normal"] = {
+ ["csl"] = nil,
+ },
+ ["normalauthor"] = {
+ ["csl"] = nil,
+ },
+ ["normaleditor"] = {
+ ["csl"] = nil,
+ },
+ ["note"] = {
+ ["csl"] = "note",
+ ["type"] = "literal",
+ },
+ ["nowarning"] = {
+ ["csl"] = nil,
+ },
+ ["number"] = {
+ ["csl"] = "number",
+ ["type"] = "literal",
+ },
+ ["numpages"] = {
+ ["csl"] = nil,
+ },
+ ["oaddress"] = {
+ ["csl"] = nil,
+ },
+ ["options"] = {
+ ["csl"] = nil,
+ ["type"] = "option",
+ },
+ ["opublisher"] = {
+ ["csl"] = nil,
+ },
+ ["org-short"] = {
+ ["csl"] = nil,
+ },
+ ["organization"] = {
+ ["csl"] = "publisher",
+ ["type"] = "literal",
+ },
+ ["origdate"] = {
+ ["csl"] = "original-date",
+ ["type"] = "date",
+ },
+ ["originaladdress"] = {
+ ["csl"] = "original-publisher-place",
+ },
+ ["originalbooktitle"] = {
+ ["csl"] = nil,
+ },
+ ["originaledition"] = {
+ ["csl"] = nil,
+ },
+ ["originaleditor"] = {
+ ["csl"] = nil,
+ },
+ ["originaljournal"] = {
+ ["csl"] = nil,
+ },
+ ["originalnumber"] = {
+ ["csl"] = nil,
+ },
+ ["originalpages"] = {
+ ["csl"] = nil,
+ },
+ ["originalpublisher"] = {
+ ["csl"] = "original-publisher",
+ },
+ ["originalvolume"] = {
+ ["csl"] = nil,
+ },
+ ["originalyear"] = {
+ ["csl"] = "original-date",
+ },
+ ["origlanguage"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["origlocation"] = {
+ ["csl"] = "original-publisher-place",
+ ["type"] = "literal",
+ },
+ ["origpublisher"] = {
+ ["csl"] = "original-publisher",
+ ["type"] = "literal",
+ },
+ ["origtitle"] = {
+ ["csl"] = "original-title",
+ ["type"] = "literal",
+ },
+ ["oyear"] = {
+ ["csl"] = nil,
+ },
+ ["pagename"] = {
+ ["csl"] = nil,
+ },
+ ["pages"] = {
+ ["csl"] = "page",
+ ["type"] = "range",
+ },
+ ["pagetotal"] = {
+ ["csl"] = "number-of-pages",
+ ["type"] = "literal",
+ },
+ ["pagination"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["paper"] = {
+ ["csl"] = nil,
+ },
+ ["part"] = {
+ ["csl"] = "part",
+ ["type"] = "literal",
+ },
+ ["patentid"] = {
+ ["csl"] = nil,
+ },
+ ["pdf"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["phone"] = {
+ ["csl"] = nil,
+ },
+ ["pid"] = {
+ ["csl"] = nil,
+ },
+ ["pii"] = {
+ ["csl"] = nil,
+ },
+ ["pmcid"] = {
+ ["csl"] = "PMCID",
+ },
+ ["prebibitem"] = {
+ ["csl"] = nil,
+ },
+ ["preface"] = {
+ ["csl"] = nil,
+ },
+ ["preprint"] = {
+ ["csl"] = nil,
+ },
+ ["presort"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["price"] = {
+ ["csl"] = nil,
+ },
+ ["primaryclass"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["printing"] = {
+ ["csl"] = nil,
+ },
+ ["prioritycountry"] = {
+ ["csl"] = nil,
+ },
+ ["prioritydate"] = {
+ ["csl"] = nil,
+ },
+ ["prioritynumber"] = {
+ ["csl"] = nil,
+ },
+ ["pseudonym"] = {
+ ["csl"] = nil,
+ },
+ ["publication"] = {
+ ["csl"] = nil,
+ },
+ ["publicationdate"] = {
+ ["csl"] = nil,
+ },
+ ["publisher"] = {
+ ["csl"] = "publisher",
+ ["type"] = "literal",
+ },
+ ["pubmed"] = {
+ ["csl"] = "PMID",
+ },
+ ["pubstate"] = {
+ ["csl"] = nil,
+ ["type"] = "key",
+ },
+ ["related"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["relatedoptions"] = {
+ ["csl"] = nil,
+ ["type"] = "option",
+ },
+ ["relatedstring"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["relatedtype"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["reprinted-from"] = {
+ ["csl"] = nil,
+ },
+ ["reprinted-text"] = {
+ ["csl"] = nil,
+ },
+ ["reprinttitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["requestdate"] = {
+ ["csl"] = nil,
+ },
+ ["requestnumber"] = {
+ ["csl"] = nil,
+ },
+ ["responsible"] = {
+ ["csl"] = nil,
+ },
+ ["review"] = {
+ ["csl"] = nil,
+ },
+ ["revision"] = {
+ ["csl"] = nil,
+ },
+ ["school"] = {
+ ["csl"] = "publisher",
+ ["type"] = "literal",
+ },
+ ["score"] = {
+ ["csl"] = nil,
+ },
+ ["section"] = {
+ ["csl"] = nil,
+ },
+ ["series"] = {
+ ["csl"] = "collection-title",
+ ["type"] = "literal",
+ },
+ ["seriesedition"] = {
+ ["csl"] = nil,
+ },
+ ["short"] = {
+ ["csl"] = nil,
+ },
+ ["shortarchive"] = {
+ ["csl"] = nil,
+ },
+ ["shortauthor"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["shorteditor"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["shorthand"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["shorthandintro"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["shortjournal"] = {
+ ["csl"] = "container-title-short",
+ ["type"] = "literal",
+ },
+ ["shortseries"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["shortsubarchive"] = {
+ ["csl"] = nil,
+ },
+ ["shorttitle"] = {
+ ["csl"] = "title-short",
+ ["type"] = "literal",
+ },
+ ["shorturl"] = {
+ ["csl"] = nil,
+ },
+ ["sig1"] = {
+ ["csl"] = nil,
+ },
+ ["sig2"] = {
+ ["csl"] = nil,
+ },
+ ["sig3"] = {
+ ["csl"] = nil,
+ },
+ ["sig4"] = {
+ ["csl"] = nil,
+ },
+ ["size"] = {
+ ["csl"] = nil,
+ },
+ ["slaccitation"] = {
+ ["csl"] = nil,
+ },
+ ["sort-short"] = {
+ ["csl"] = nil,
+ },
+ ["sort-word"] = {
+ ["csl"] = nil,
+ },
+ ["sortas"] = {
+ ["csl"] = nil,
+ },
+ ["sortkey"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["sortname"] = {
+ ["csl"] = nil,
+ ["type"] = "name",
+ },
+ ["sortshorthand"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["sorttitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["sortyear"] = {
+ ["csl"] = nil,
+ ["type"] = "integer",
+ },
+ ["source1"] = {
+ ["csl"] = nil,
+ },
+ ["specialitycode"] = {
+ ["csl"] = nil,
+ },
+ ["ssedition"] = {
+ ["csl"] = nil,
+ },
+ ["standard"] = {
+ ["csl"] = nil,
+ },
+ ["startnumber"] = {
+ ["csl"] = nil,
+ },
+ ["startvolume"] = {
+ ["csl"] = nil,
+ },
+ ["startyear"] = {
+ ["csl"] = nil,
+ },
+ ["state"] = {
+ ["csl"] = nil,
+ },
+ ["status"] = {
+ ["csl"] = nil,
+ },
+ ["stdcode"] = {
+ ["csl"] = nil,
+ },
+ ["stitle"] = {
+ ["csl"] = nil,
+ },
+ ["street"] = {
+ ["csl"] = nil,
+ },
+ ["subarchive"] = {
+ ["csl"] = nil,
+ },
+ ["subtitle"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["symposium"] = {
+ ["csl"] = nil,
+ },
+ ["text"] = {
+ ["csl"] = nil,
+ },
+ ["timestamp"] = {
+ ["csl"] = nil,
+ },
+ ["title"] = {
+ ["csl"] = "title",
+ ["type"] = "literal",
+ },
+ ["titleaddon"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["titlenote"] = {
+ ["csl"] = nil,
+ },
+ ["totalpages"] = {
+ ["csl"] = nil,
+ },
+ ["transissue"] = {
+ ["csl"] = nil,
+ },
+ ["transjournal"] = {
+ ["csl"] = nil,
+ },
+ ["translation"] = {
+ ["csl"] = nil,
+ },
+ ["translator"] = {
+ ["csl"] = "translator",
+ ["type"] = "name",
+ },
+ ["transnumber"] = {
+ ["csl"] = nil,
+ },
+ ["transpages"] = {
+ ["csl"] = nil,
+ },
+ ["transsection"] = {
+ ["csl"] = nil,
+ },
+ ["transvolume"] = {
+ ["csl"] = nil,
+ },
+ ["transyear"] = {
+ ["csl"] = nil,
+ },
+ ["type"] = {
+ ["csl"] = "genre",
+ ["type"] = "key",
+ },
+ ["typeoflit"] = {
+ ["csl"] = nil,
+ },
+ ["umfnumber"] = {
+ ["csl"] = nil,
+ },
+ ["updated"] = {
+ ["csl"] = nil,
+ },
+ ["url"] = {
+ ["csl"] = "URL",
+ ["type"] = "uri",
+ },
+ ["urlaccessdate"] = {
+ ["csl"] = "accessed",
+ },
+ ["urldate"] = {
+ ["csl"] = "accessed",
+ ["type"] = "date",
+ },
+ ["urlnewline"] = {
+ ["csl"] = nil,
+ },
+ ["urltype"] = {
+ ["csl"] = nil,
+ },
+ ["urlyear"] = {
+ ["csl"] = nil,
+ },
+ ["urn"] = {
+ ["csl"] = nil,
+ },
+ ["usera"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["userb"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["userc"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["userd"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["usere"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["userf"] = {
+ ["csl"] = nil,
+ ["type"] = "literal",
+ },
+ ["value"] = {
+ ["csl"] = nil,
+ },
+ ["venue"] = {
+ ["csl"] = "event-place",
+ ["type"] = "literal",
+ },
+ ["verba"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["verbb"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["verbc"] = {
+ ["csl"] = nil,
+ ["type"] = "verbatim",
+ },
+ ["version"] = {
+ ["csl"] = "version",
+ ["type"] = "literal",
+ },
+ ["versiontype"] = {
+ ["csl"] = nil,
+ },
+ ["volformat"] = {
+ ["csl"] = nil,
+ },
+ ["volume"] = {
+ ["csl"] = "volume",
+ ["type"] = "integer",
+ },
+ ["volumes"] = {
+ ["csl"] = "number-of-volumes",
+ ["type"] = "integer",
+ },
+ ["volumetitle"] = {
+ ["csl"] = nil,
+ },
+ ["word"] = {
+ ["csl"] = nil,
+ },
+ ["xdata"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["xid"] = {
+ ["csl"] = nil,
+ },
+ ["xref"] = {
+ ["csl"] = nil,
+ ["type"] = "entrykey",
+ },
+ ["year"] = {
+ ["csl"] = nil,
+ ["type"] = "date",
+ },
+ ["year-presented"] = {
+ ["csl"] = nil,
+ },
+ ["yearcomp"] = {
+ ["csl"] = nil,
+ },
+ ["yearfiled"] = {
+ ["csl"] = nil,
+ },
+ ["zblnumber"] = {
+ ["csl"] = nil,
+ },
+ ["zip"] = {
+ ["csl"] = nil,
+ },
+ },
+ ["macros"] = {
+ ["jan"] = {
+ ["value"] = "1",
+ },
+ ["feb"] = {
+ ["value"] = "2",
+ },
+ ["mar"] = {
+ ["value"] = "3",
+ },
+ ["apr"] = {
+ ["value"] = "4",
+ },
+ ["may"] = {
+ ["value"] = "5",
+ },
+ ["jun"] = {
+ ["value"] = "6",
+ },
+ ["jul"] = {
+ ["value"] = "7",
+ },
+ ["aug"] = {
+ ["value"] = "8",
+ },
+ ["sep"] = {
+ ["value"] = "9",
+ },
+ ["oct"] = {
+ ["value"] = "10",
+ },
+ ["nov"] = {
+ ["value"] = "11",
+ },
+ ["dec"] = {
+ ["value"] = "12",
+ },
+ ["acmcs"] = {
+ ["value"] = "ACM Computing Surveys",
+ },
+ ["acta"] = {
+ ["value"] = "Acta Informatica",
+ },
+ ["cacm"] = {
+ ["value"] = "Communications of the ACM",
+ },
+ ["ibmjrd"] = {
+ ["value"] = "IBM Journal of Research and Development",
+ },
+ ["ibmsj"] = {
+ ["value"] = "IBM Systems Journal",
+ },
+ ["ieeese"] = {
+ ["value"] = "IEEE Transactions on Software Engineering",
+ },
+ ["ieeetc"] = {
+ ["value"] = "IEEE Transactions on Computers",
+ },
+ ["ieeetcad"] = {
+ ["value"] = "IEEE Transactions on Computer-Aided Design of Integrated Circuits",
+ },
+ ["ipl"] = {
+ ["value"] = "Information Processing Letters",
+ },
+ ["jacm"] = {
+ ["value"] = "Journal of the ACM",
+ },
+ ["jcss"] = {
+ ["value"] = "Journal of Computer and System Sciences",
+ },
+ ["scp"] = {
+ ["value"] = "Science of Computer Programming",
+ },
+ ["sicomp"] = {
+ ["value"] = "SIAM Journal on Computing",
+ },
+ ["tocs"] = {
+ ["value"] = "ACM Transactions on Computer Systems",
+ },
+ ["tods"] = {
+ ["value"] = "ACM Transactions on Database Systems",
+ },
+ ["tog"] = {
+ ["value"] = "ACM Transactions on Graphics",
+ },
+ ["toms"] = {
+ ["value"] = "ACM Transactions on Mathematical Software",
+ },
+ ["toois"] = {
+ ["value"] = "ACM Transactions on Office Information Systems",
+ },
+ ["toplas"] = {
+ ["value"] = "ACM Transactions on Programming Languages and Systems",
+ },
+ ["tcs"] = {
+ ["value"] = "Theoretical Computer Science",
+ },
+ },
+} \ No newline at end of file
diff --git a/biblio/citation-style-language/citeproc-bib.lua b/biblio/citation-style-language/citeproc-bib.lua
index b99ba955dd..7e24b1a6a5 100644
--- a/biblio/citation-style-language/citeproc-bib.lua
+++ b/biblio/citation-style-language/citeproc-bib.lua
@@ -16,24 +16,12 @@
local bib = {}
-require("lualibs")
local unicode = require("unicode")
+bib.bib_data = require("citeproc-bib-data")
local util = require("citeproc-util")
-local path = "citeproc-bib-data.json"
-if kpse then
- path = kpse.find_file(path)
-end
-if path then
- local contents = util.read_file(path)
- if not contents then
- error(string.format('Failed to find "%s"', path))
- end
- bib.bib_data = utilities.json.tolua(contents)
-end
-
function bib.parse(contents)
local items = {}
for item_contents in string.gmatch(contents, "(@%w+%b{})") do
@@ -80,9 +68,9 @@ end
function bib.parse_fields(contents)
local fields = {}
local field_patterns = {
- "^(%w+)%s*=%s*(%b{}),?%s*(.-)$",
- '^(%w+)%s*=%s*"([^"]*)",?%s*(.-)$',
- "^(%w+)%s*=%s*(%w+),?%s*(.-)$",
+ "^([^,}%s]+)%s*=%s*(%b{}),?%s*(.-)$",
+ '^([^,}%s]+)%s*=%s*"([^"]*)",?%s*(.-)$',
+ "^([^,}%s]+)%s*=%s*(%w+),?%s*(.-)$",
}
while #contents > 0 do
@@ -91,6 +79,7 @@ function bib.parse_fields(contents)
for pattern_index, pattern in ipairs(field_patterns) do
field, value, rest = string.match(contents, pattern)
if value then
+ field = string.lower(field)
if pattern_index == 1 then
-- Strip braces "{}"
value = string.sub(value, 2, -2)
@@ -106,10 +95,14 @@ function bib.parse_fields(contents)
end
end
fields[field] = value
- contents = rest
break
end
end
+ if value then
+ contents = rest
+ else
+ break
+ end
end
return fields
end
diff --git a/biblio/citation-style-language/citeproc b/biblio/citation-style-language/citeproc-cli.lua
index 27663952bd..97a51d724c 100755..100644
--- a/biblio/citation-style-language/citeproc
+++ b/biblio/citation-style-language/citeproc-cli.lua
@@ -1,4 +1,3 @@
-#!/usr/bin/env texlua
--
-- Copyright (c) 2021-2022 Zeping Lee
@@ -6,12 +5,14 @@
-- Repository: https://github.com/zepinglee/citeproc-lua
--
-kpse.set_program_name("luatex")
+local cli = {}
+
require("lualibs")
local citeproc = require("citeproc")
local util = require("citeproc-util")
-local core = require("csl-core")
+local core = require("citeproc-latex-core")
+
local function getopt( arg, options )
local tab = {}
@@ -52,12 +53,12 @@ end
local function print_version()
- io.write(string.format("CiteProc-Lua %s\n", citeproc.__VERSION__))
+ io.write(string.format("citeproc-lua %s\n", citeproc.__VERSION__))
end
local function print_help()
- io.write("Usage: citeproc [options] auxname[.aux]\n")
+ io.write("Usage: citeproc-lua [options] auxname[.aux]\n")
io.write("Options:\n")
io.write(" -h, --help Print this message and exit.\n")
io.write(" -V, --version Print the version number and exit.\n")
@@ -143,7 +144,7 @@ local function process_aux_file(aux_file)
for _, citation in ipairs(citations) do
local citation_id = citation.citationID
- if citation_id ~= "nocite" then
+ if citation_id ~= "@nocite" then
local citation_str = citation_strings[citation_id]
output_string = output_string .. string.format("\\cslcite{%s}{{%s}{%s}}\n", citation_id, style_class, citation_str)
end
@@ -161,7 +162,7 @@ local function process_aux_file(aux_file)
end
-local function main()
+function cli.main()
local args = getopt(arg, "o")
-- for k, v in pairs(args) do
@@ -191,4 +192,5 @@ local function main()
end
-main()
+
+return cli
diff --git a/biblio/citation-style-language/citeproc-context.lua b/biblio/citation-style-language/citeproc-context.lua
new file mode 100644
index 0000000000..08be158bcf
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-context.lua
@@ -0,0 +1,335 @@
+--
+-- Copyright (c) 2021-2022 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+local context = {}
+
+local LocalizedQuotes = require("citeproc-output").LocalizedQuotes
+
+local util = require("citeproc-util")
+
+
+local Context = {
+ reference = nil,
+ format = nil,
+ cite_id = nil,
+ style = nil,
+ locale = nil,
+ name_citation = nil,
+ names_delimiter = nil,
+
+ position = nil,
+
+ disamb_pass = nil,
+
+ cite = nil,
+ bib_number = nil,
+
+ in_bibliography = false,
+ sort_key = nil,
+
+ year_suffix = nil,
+}
+
+function Context:new()
+ local o = {
+ in_bibliography = false
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function Context:get_variable(name, form)
+ local variable_type = util.variable_types[name]
+ if variable_type == "number" then
+ return self:get_number(name)
+ -- elseif variable_type == "date" then
+ -- return self:get_date(name)
+ elseif variable_type == "name" then
+ return self:get_name(name)
+ else
+ return self:get_ordinary(name, form)
+ end
+end
+
+function Context:get_number(name)
+ if name == "locator" then
+ return self.cite.locator
+ elseif name == "citation-number" then
+ -- return self.bib_number
+ return self.reference["citation-number"]
+ elseif name == "first-reference-note-number" then
+ return self.cite["first-reference-note-number"]
+ elseif name == "page-first" then
+ return self.page_first(self.reference.page)
+ else
+ return self.reference[name]
+ end
+end
+
+function Context:get_ordinary(name, form)
+ local res = nil
+ local variable_name = name
+ if form and form ~= "long" then
+ variable_name = variable_name .. "-" .. form
+ end
+
+ if variable_name == "locator" or variable_name == "label" then
+ res = self.cite[variable_name]
+ else
+ res = self.reference[variable_name]
+ end
+ if res then
+ return res
+ end
+
+ if variable_name == "container-title-short" then
+ res = self.reference["journalAbbreviation"]
+ if res then
+ return res
+ end
+ end
+
+ if form then
+ res = self.reference[name]
+ if res then
+ return res
+ end
+ end
+
+ -- if name == "title-short" or name == "container-title-short" then
+ -- variable_name = string.gsub(name, "%-short$", "")
+ -- res = self.reference[variable_name]
+ -- end
+
+ return res
+end
+
+-- TODO: optimize: process only once
+-- TODO: organize the name parsing code
+function Context:get_name(variable_name)
+ local names = self.reference[variable_name]
+ if names then
+ for _, name in ipairs(names) do
+ if name.family == "" then
+ name.family = nil
+ end
+ if name.given == "" then
+ name.given = nil
+ end
+ if name.given and not name.family then
+ name.family = name.given
+ name.given = nil
+ end
+ self:parse_name_suffix(name)
+ self:split_ndp_family(name)
+ -- self:split_given_ndp(name)
+ self:split_given_dp(name)
+ end
+ end
+ return names
+end
+
+function Context:parse_name_suffix(name)
+ if not name.suffix and name.family and string.match(name.family, ",") then
+ local words = util.split(name.family, ",%s*")
+ name.suffix = words[#words]
+ name.family = table.concat(util.slice(words, 1, -2), ", ")
+ end
+ if not name.suffix and name.given and string.match(name.given, ",") then
+ -- Split name suffix: magic_NameSuffixNoComma.txt
+ -- "John, III" => given: "John", suffix: "III"
+ local words = util.split(name.given, ",%s*")
+ name.suffix = words[#words]
+ name.given = table.concat(util.slice(words, 1, -2), ", ")
+ end
+end
+
+function Context:split_ndp_family(name)
+ if name["non-dropping-particle"] or not name.family then
+ return
+ end
+ if util.startswith(name.family, '"') and util.endswith(name.family, '"') then
+ -- Stop parsing family name if surrounded by quotation marks
+ -- bugreports_parseName.txt
+ name.family = string.gsub(name.family, '"', "")
+ return
+ end
+ local ndp_parts = {}
+ local family_parts = {}
+ local parts = util.split(name.family)
+ for i, part in ipairs(parts) do
+ local ndp, family
+ -- d'Aubignac
+ ndp, family = string.match(part, "^(%l')(.+)$")
+ if ndp and family then
+ table.insert(ndp_parts, ndp)
+ parts[i] = family
+ else
+ ndp, family = string.match(part, "^(%l’)(.+)$")
+ if ndp and family then
+ table.insert(ndp_parts, ndp)
+ parts[i] = family
+ else
+ -- al-Aswānī
+ ndp, family = string.match(part, "^(%l+%-)(.+)$")
+ if ndp and family then
+ table.insert(ndp_parts, ndp)
+ parts[i] = family
+ elseif i < #parts and util.is_lower(part) then
+ table.insert(ndp_parts, part)
+ end
+ end
+ end
+ if ndp or i == #parts then
+ for j = i, #parts do
+ table.insert(family_parts, parts[j])
+ end
+ break
+ end
+ if not util.is_lower(part) then
+ for j = i, #parts do
+ table.insert(family_parts, parts[j])
+ end
+ break
+ end
+ end
+ if #ndp_parts > 0 then
+ name["non-dropping-particle"] = table.concat(ndp_parts, " ")
+ name.family = table.concat(family_parts, " ")
+ end
+end
+
+function Context:split_given_dp(name)
+ if name["dropping-particle"] or not name.given then
+ return
+ end
+ local dp_parts = {}
+ local given_parts = {}
+ local parts = util.split(name.given)
+ for i = #parts, 1, -1 do
+ local part = parts[i]
+ if i == 1 or not util.is_lower(part) then
+ for j = 1, i do
+ table.insert(given_parts, parts[j])
+ end
+ break
+ end
+ -- name_ParsedDroppingParticleWithApostrophe.txt
+ -- given: "François Hédelin d'" =>
+ -- given: "François Hédelin", dropping-particle: "d'"
+ if string.match(part, "^%l+'?$") or string.match(part, "^%l+’$") then
+ table.insert(dp_parts, 1, part)
+ end
+ end
+ if #dp_parts > 0 then
+ name["dropping-particle"] = table.concat(dp_parts, " ")
+ name.given = table.concat(given_parts, " ")
+ end
+end
+
+-- function Context:split_given_ndp(name)
+-- if name["non-dropping-particle"] or not name.given then
+-- return
+-- end
+
+-- if not (string.match(name.given, "%l'$") or string.match(name.given, "%l’$")) then
+-- return
+-- end
+
+-- local words = util.split(name.given)
+-- if #words < 2 then
+-- return
+-- end
+-- local last_word = words[#words]
+-- if util.endswith(last_word, "'") or util.endswith(last_word, util.unicode["apostrophe"]) then
+-- name["non-dropping-particle"] = last_word
+-- name.given = table.concat(util.slice(words, 1, -2), " ")
+-- end
+-- util.debug(name)
+-- end
+
+function Context:get_localized_date(form)
+ return self.locale.dates[form]
+end
+
+function Context:get_macro(name)
+ local res = self.style.macros[name]
+ if not res then
+ util.error(string.format('Undefined macro "%s"', name))
+ end
+ return res
+end
+
+function Context:get_simple_term(name, form, plural)
+ assert(self.locale)
+ return self.locale:get_simple_term(name, form, plural)
+end
+
+function Context:get_localized_quotes()
+ return LocalizedQuotes:new(
+ self:get_simple_term("open-quote"),
+ self:get_simple_term("close-quote"),
+ self:get_simple_term("open-inner-quote"),
+ self:get_simple_term("close-inner-quote"),
+ self.locale.style_options.punctuation_in_quote
+ )
+end
+
+function Context.page_first(page)
+ local page_first = util.split(page, "%s*[&,-]%s*")[1]
+ return util.split(page_first, util.unicode["en dash"])[1]
+end
+
+-- https://docs.citationstyles.org/en/stable/specification.html#non-english-items
+function Context:is_english()
+ local language = self:get_variable("language")
+ if util.startswith(self.engine.lang, "en") then
+ if not language or util.startswith(language, "en") then
+ return true
+ else
+ return false
+ end
+ else
+ if language and util.startswith(language, "en") then
+ return true
+ else
+ return false
+ end
+ end
+end
+
+
+local IrState = {}
+
+function IrState:new(style, cite_id, cite, reference)
+ local o = {
+ macro_stack = {},
+ suppressed = {},
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function IrState:push_macro(macro_name)
+ for _, name in ipairs(macro_name) do
+ if name == macro_name then
+ util.error(string.format('Recursive macro "%s".', macro_name))
+ end
+ table.insert(self.macro_stack, macro_name)
+ end
+end
+
+function IrState:pop_macro(macro_name)
+ table.remove(self.macro_stack)
+end
+
+
+context.Context = Context
+context.IrState = IrState
+
+return context
diff --git a/biblio/citation-style-language/citeproc-element.lua b/biblio/citation-style-language/citeproc-element.lua
index 0e7abf87e3..197616cb08 100644
--- a/biblio/citation-style-language/citeproc-element.lua
+++ b/biblio/citation-style-language/citeproc-element.lua
@@ -6,410 +6,536 @@
local element = {}
-local unicode = require("unicode")
+local SeqIr = require("citeproc-ir-node").SeqIr
+
+local InlineElement = require("citeproc-output").InlineElement
+local Micro = require("citeproc-output").Micro
-local richtext = require("citeproc-richtext")
local util = require("citeproc-util")
local Element = {
- default_options = {},
+ element_name = nil,
+ children = nil,
+ element_type_map = {},
}
-function Element:new ()
- local o = {}
+function Element:new(element_name)
+ local o = {
+ element_name = element_name or self.element_name,
+ }
setmetatable(o, self)
self.__index = self
return o
end
-Element.option_type = {
- ["et-al-min"] = "integer",
- ["et-al-use-first"] = "integer",
- ["et-al-subsequent-min"] = "integer",
- ["et-al-subsequent-use-first"] = "integer",
- ["near-note-distance"] = "integer",
- ["line-spacing"] = "integer",
- ["entry-spacing"] = "integer",
- ["names-min"] = "integer",
- ["names-use-first"] = "integer",
- ["limit-day-ordinals-to-day-1"] = "boolean",
- ["punctuation-in-quote"] = "boolean",
- ["et-al-use-last"] = "boolean",
- ["initialize"] = "boolean",
- ["initialize-with-hyphen"] = "boolean",
- ["disambiguate-add-names"] = "boolean",
- ["disambiguate-add-givenname"] = "boolean",
- ["disambiguate-add-year-suffix"] = "boolean",
- ["hanging-indent"] = "boolean",
- ["names-use-last"] = "boolean",
- ["quotes"] = "boolean",
- ["strip-periods"] = "boolean",
-}
+function Element:derive(element_name, default_options)
+ local o = {
+ element_name = element_name or self.element_name,
+ children = nil,
+ }
-Element.inheritable_options = {
- -- Style
- ["initialize-with-hyphen"] = true,
- ["page-range-format"] = true,
- ["demote-non-dropping-particle"] = true,
- -- Citation
- ["disambiguate-add-givenname"] = true,
- ["givenname-disambiguation-rule"] = true,
- ["disambiguate-add-names"] = true,
- ["disambiguate-add-year-suffix"] = true,
- ["cite-group-delimiter"] = true,
- ["collapse"] = true,
- ["year-suffix-delimiter"] = true,
- ["after-collapse-delimiter"] = true,
- ["near-note-distance"] = true,
- -- Bibliography
- ["second-field-align"] = true, -- for use in layout
- ["subsequent-author-substitute"] = true,
- ["subsequent-author-substitute-rule"] = true,
- -- Date
- ["date-parts"] = true,
- -- Names
- ["and"] = true,
- ["delimiter-precedes-et-al"] = true,
- ["delimiter-precedes-last"] = true,
- ["et-al-min"] = true,
- ["et-al-use-first"] = true,
- ["et-al-use-last"] = true,
- ["et-al-subsequent-min"] = true,
- ["et-al-subsequent-use-first"] = true,
- ["names-min"] = true,
- ["names-use-first"] = true,
- ["names-use-last"] = true,
- ["initialize-with"] = true,
- ["name-as-sort-order"] = true,
- ["sort-separator"] = true,
- ["name-form"] = true,
- ["name-delimiter"] = true,
- ["names-delimiter"] = true,
-}
+ if default_options then
+ for key, value in pairs(default_options) do
+ o[key] = value
+ end
+ end
+
+ Element.element_type_map[element_name] = o
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
-function Element:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
- return self:render_children(item, context)
+function Element:from_node(node, parent)
+ local o = self:new()
+ o.element_name = self.element_name or node:get_element_name()
+ return o
end
-function Element:render_children (item, context)
- local output = {}
- for i, child in ipairs(self:get_children()) do
- if child:is_element() then
- if child.render == nil then
- local element_name = child:get_element_name()
- util.warning("Unkown type \"" .. element_name .. "\"")
- end
- local str = child:render(item, context)
- table.insert(output, str)
- end
+function Element:set_attribute(node, attribute)
+ local value = node:get_attribute(attribute)
+ if value then
+ local key = string.gsub(attribute, "%-" , "_")
+ self[key] = value
end
- return self:concat(output, context)
end
-function Element:set_base_class (node)
- if node:is_element() then
- local org_meta_table = getmetatable(node)
- setmetatable(node, {__index = function (_, key)
- if self[key] then
- return self[key]
- else
- return org_meta_table[key]
- end
- end})
+function Element:set_bool_attribute(node, attribute)
+ local value = node:get_attribute(attribute)
+ if value == "true" then
+ local key = string.gsub(attribute, "%-" , "_")
+ self[key] = true
+ elseif value == "false" then
+ local key = string.gsub(attribute, "%-" , "_")
+ self[key] = false
end
end
-function Element:debug_info (context, debug)
- -- debug = true
- if debug then
- local text = ""
- local level = 0
- if context and context.level then
- level = context.level + 1
- end
- text = text .. string.rep(" ", 2 * level)
- text = text .. self:get_element_name()
- local attrs = {}
- if self._attr then
- for attr, value in pairs(self._attr) do
- table.insert(attrs, attr .. "=\"" .. value .. "\"")
- end
- text = text .. "[" .. table.concat(attrs, " ") .. "]"
- end
- io.stderr:write(text .. "\n")
+function Element:set_number_attribute(node, attribute)
+ local value = node:get_attribute(attribute)
+ if value then
+ local key = string.gsub(attribute, "%-" , "_")
+ self[key] = tonumber(value)
end
end
-function Element:get_child (type)
- for _, child in ipairs(self:get_children()) do
- if child:get_element_name() == type then
- return child
+function Element:process_children_nodes(node)
+ if not self.children then
+ self.children = {}
+ end
+ for _, child in ipairs(node:get_children()) do
+ if child:is_element() then
+ local element_name = child:get_element_name()
+ local element_type = self.element_type_map[element_name] or Element
+ local child_element = element_type:from_node(child, self)
+ table.insert(self.children, child_element)
end
end
- return nil
-end
-function Element:get_style ()
- local style = self:root_node().style
- assert(style ~= nil)
- return style
end
-function Element:get_engine ()
- local engine = self:root_node().engine
- assert(engine ~= nil)
- return engine
+function Element:build_ir(engine, state, context)
+ return self:build_children_ir(engine, state, context)
end
-function Element:process_context (context)
- local state = {
- -- The `build` table is directly passed to new context.
- build = context.build or {},
- -- The `option` table is copied.
- options = {},
- -- Other items in `context` is copied.
- }
- for key, value in pairs(self.default_options) do
- state.options[key] = value
- end
- if context then
- local element_name = self:get_element_name()
- for key, value in pairs(context) do
- if key == "options" then
- for k, v in pairs(context.options) do
- if self.inheritable_options[k] then
- state.options[k] = v
- if element_name == "name" then
- if k == "name-form" then
- state.options["form"] = v
- end
- if k == "name-delimiter" then
- state.options["delimiter"] = v
- end
- elseif element_name == "names" then
- if k == "names-delimiter" then
- state.options["delimiter"] = v
- end
- end
- end
+function Element:build_children_ir(engine, state, context)
+ local child_irs = {}
+ local ir_sort_key
+ local group_var = "plain"
+ if self.children then
+ for _, child_element in ipairs(self.children) do
+ local child_ir = child_element:build_ir(engine, state, context)
+ if child_ir then
+ if child_ir.sort_key ~= nil then
+ ir_sort_key = child_ir.sort_key
end
- else
- state[key] = value
+ if child_ir.group_var == "important" then
+ group_var = "important"
+ end
+ table.insert(child_irs, child_ir)
end
end
- if state.level then
- state.level = state.level + 1
- else
- state.level = 0
- end
end
- if self._attr then
- for key, value in pairs(self._attr) do
- if self.option_type[key] == "integer" then
- value = tonumber(value)
- elseif self.option_type[key] == "boolean" then
- value = (value == "true")
- end
- state.options[key] = value
- end
+ local ir = SeqIr:new(child_irs, self)
+ ir.sort_key = ir_sort_key
+ ir.group_var = group_var
+ if #child_irs == 0 then
+ ir.group_var = "missing"
+ else
+ ir.group_var = group_var
end
- return state
+ return ir
end
-function Element:get_option (key, context)
- assert(context ~= nil)
- return context.options[key]
-end
-
-function Element:get_locale_option (key)
- local locales = self:get_style():get_locales()
- for i, locale in ipairs(locales) do
- local option = locale:get_option(key)
- if option ~= nil then
- return option
- end
+-- Used in cs:group and cs:macro
+function Element:build_group_ir(engine, state, context)
+ if not self.children then
+ return nil
end
- return nil
-end
+ local irs = {}
+ local name_count
+ local ir_sort_key
+ local group_var = "plain"
+
+ for _, child_element in ipairs(self.children) do
+ -- util.debug(child_element.element_name)
+ local child_ir = child_element:build_ir(engine, state, context)
+ -- util.debug(child_ir)
+ -- util.debug(child_ir.group_var)
+
+ if child_ir then
+ -- cs:group and its child elements are suppressed if
+ -- a) at least one rendering element in cs:group calls a variable (either
+ -- directly or via a macro), and
+ -- b) all variables that are called are empty. This accommodates
+ -- descriptive cs:text and `cs:label` elements.
+ local child_group_var = child_ir.group_var
+ if child_group_var == "important" then
+ group_var = "important"
+ elseif child_group_var == "missing" and child_ir._type ~= "YearSuffix" then
+ if group_var == "plain" then
+ group_var = "missing"
+ end
+ end
-function Element:get_variable (item, name, context)
- if context.suppressed_variables and context.suppressed_variables[name] then
- return nil
- else
- local res = item[name]
- if type(res) == "table" and res._type == "RichText" then
- -- TODO: should be deep copy
- res = res:shallow_copy()
- end
+ if child_ir.name_count then
+ if not name_count then
+ name_count = 0
+ end
+ name_count = name_count + child_ir.name_count
+ end
- if res and res ~= "" then
- if context.suppress_subsequent_variables then
- context.suppressed_variables[name] = true
+ if child_ir.sort_key ~= nil then
+ ir_sort_key = child_ir.sort_key
end
+
+ table.insert(irs, child_ir)
end
- return res
end
-end
-function Element:get_macro (name)
- local query = string.format("macro[name=\"%s\"]", name)
- local macro = self:root_node():query_selector(query)[1]
- if not macro then
- error(string.format("Failed to find %s.", query))
+ -- A non-empty nested cs:group is treated as a non-empty variable for the
+ -- puropses of determining suppression of the outer cs:group.
+ if #irs > 0 and group_var == "plain" then
+ group_var = "important"
end
- return macro
-end
-function Element:get_term (name, form, number, gender)
- return self:get_style():get_term(name, form, number, gender)
-end
+ local ir = SeqIr:new(irs, self)
+ ir.name_count = name_count
+ ir.sort_key = ir_sort_key
+ ir.group_var = group_var
--- Formatting
-function Element:escape (str, context)
- return str
- -- return self:get_engine().formatter.text_escape(str)
+ return ir
end
-function Element:format(text, context)
- if not text or text == "" then
- return nil
+function Element:render_text_inlines(str, context)
+ if str == "" then
+ return {}
end
- if text._type ~= "RichText" then
- text = richtext.new(text)
+
+ str = self:apply_strip_periods(str)
+ -- TODO: try links
+
+ local output_format = context.format
+ local localized_quotes = nil
+ if self.quotes then
+ localized_quotes = context:get_localized_quotes()
end
- local attributes = {
+
+ local inlines = InlineElement:parse(str, context)
+ local is_english = context:is_english()
+ output_format:apply_text_case(inlines, self.text_case, is_english)
+ inlines = {Micro:new(inlines)}
+ inlines = output_format:with_format(inlines, self.formatting)
+ inlines = output_format:affixed_quoted(inlines, self.affixes, localized_quotes)
+ return output_format:with_display(inlines, self.display)
+end
+
+function Element:set_formatting_attributes(node)
+ for _, attribute in ipairs({
"font-style",
"font-variant",
"font-weight",
"text-decoration",
"vertical-align",
- }
- for _, attribute in ipairs(attributes) do
- local value = context.options[attribute]
+ }) do
+ local value = node:get_attribute(attribute)
if value then
- if text.formats[attribute] then
- local new = richtext.new()
- new.contents = {text}
- text = new
+ if not self.formatting then
+ self.formatting = {}
end
- text:add_format(attribute, value)
+ self.formatting[attribute] = value
end
end
- return text
end
--- Affixes
-function Element:wrap (str, context)
- if not str or str == "" then
- return nil
- end
- local prefix = context.options["prefix"]
- local suffix = context.options["suffix"]
- local res = str
- if prefix and prefix ~= "" then
- local linkable = false
- local variable_name = context.options["variable"]
- if variable_name == "DOI" or variable_name == "PMID" or variable_name == "PMCID" then
- linkable = true
+function Element:set_affixes_attributes(node)
+ for _, attribute in ipairs({"prefix", "suffix"}) do
+ local value = node:get_attribute(attribute)
+ if value then
+ if not self.affixes then
+ self.affixes = {}
+ end
+ self.affixes[attribute] = value
end
- if variable_name == "URL" or (linkable and not string.match(prefix, "^https?://")) then
- res:add_format(variable_name, "true")
+ end
+end
+
+function Element:get_delimiter_attribute(node)
+ self:set_attribute(node, "delimiter")
+end
+
+function Element:set_display_attribute(node)
+ self:set_attribute(node, "display")
+end
+
+function Element:set_quotes_attribute(node)
+ self:set_bool_attribute(node, "quotes")
+end
+
+function Element:set_strip_periods_attribute(node)
+ self:set_bool_attribute(node, "strip-periods")
+end
+
+function Element:set_text_case_attribute(node)
+ self:set_attribute(node, "text-case")
+end
+
+-- function Element:apply_formatting(ir)
+-- local attributes = {
+-- "font_style",
+-- "font_variant",
+-- "font_weight",
+-- "text_decoration",
+-- "vertical_align",
+-- }
+-- for _, attribute in ipairs(attributes) do
+-- local value = self[attribute]
+-- if value then
+-- if not ir.formatting then
+-- ir.formatting = {}
+-- end
+-- ir.formatting[attribute] = value
+-- end
+-- end
+-- return ir
+-- end
+
+function Element:apply_affixes(ir)
+ if ir then
+ if self.prefix then
+ ir.prefix = self.prefix
end
- res = richtext.concat(prefix, res)
- if linkable and string.match(prefix, "^https?://") then
- res:add_format("URL", "true")
+ if self.suffix then
+ ir.suffix = self.suffix
end
end
- if suffix and suffix ~= "" then
- res = richtext.concat(res, suffix)
+ return ir
+end
+
+function Element:apply_delimiter(ir)
+ if ir and ir.children then
+ ir.delimiter = self.delimiter
end
- return res
+ return ir
end
--- Delimiters
-function Element:concat (strings, context)
- local delimiter = context.options["delimiter"]
- return richtext.concat_list(strings, delimiter)
+function Element:apply_display(ir)
+ ir.display = self.display
+ return ir
end
--- Display
-function Element:display(text, context)
- if not text then
- return text
- end
- local value = context.options["display"]
- if not value then
- return text
+function Element:apply_quotes(ir)
+ if ir and self.quotes then
+ ir.quotes = true
+ ir.children = {ir}
+ ir.open_quote = nil
+ ir.close_quote = nil
+ ir.open_inner_quote = nil
+ ir.close_inner_quote = nil
+ ir.punctuation_in_quote = false
end
- if type(text) == "string" then
- text = richtext.new(text)
+ return ir
+end
+
+function Element:apply_strip_periods(str)
+ local res = str
+ if str and self.strip_periods then
+ res = string.gsub(str, "%.", "")
end
- text:add_format("display", value)
- return text
+ return res
end
--- Quotes
-function Element:quote (str, context)
- if not str then
- return nil
+
+function Element:format_number(number, variable, form, context)
+ -- if not util.is_numeric(number) then
+ -- number = string.gsub(number, "\\%-", "-")
+ -- return number
+ -- end
+ number = util.strip(number)
+ if variable == "locator" then
+ variable = context:get_variable("label")
end
- if context.sorting then
- return str
+ form = form or "numeric"
+ local number_part_list = self:split_number_parts(number, context)
+ -- {
+ -- {"1", "", " & "}
+ -- {"5", "8", ", "}
+ -- }
+ -- util.debug(number_part_list)
+
+ for _, number_parts in ipairs(number_part_list) do
+ if form == "roman" then
+ self:format_roman_number_parts(number_parts)
+ elseif form == "ordinal" or form == "long-ordinal" then
+ local gender = context.locale:get_number_gender(variable)
+ self:format_ordinal_number_parts(number_parts, form, gender, context)
+ elseif number_parts[2] ~= "" and variable == "page" then
+ local page_range_format = context.style.page_range_format
+ self:format_page_range(number_parts, page_range_format)
+ else
+ self:format_numeric_number_parts(number_parts)
+ end
end
- if not str._type == "RichText" then
- str = richtext.new(str)
+
+ local range_delimiter = util.unicode["en dash"]
+ if variable == "page" then
+ local page_range_delimiter = context:get_simple_term("page-range-delimiter")
+ if page_range_delimiter then
+ range_delimiter = page_range_delimiter
+ end
end
- local quotes = context.options["quotes"] or false
- if quotes then
- str:add_format("quotes", "true")
+
+ local res = ""
+ for _, number_parts in ipairs(number_part_list) do
+ res = res .. number_parts[1]
+ if number_parts[2] ~= "" then
+ res = res .. range_delimiter
+ res = res .. number_parts[2]
+ end
+ res = res .. number_parts[3]
end
- return str
+ return res
+
end
--- Strip periods
-function Element:strip_periods (str, context)
- if not str then
- return nil
+function Element:split_number_parts(number, context)
+ -- number = string.gsub(number, util.unicode["en dash"], "-")
+ local and_symbol
+ and_symbol = context.locale:get_simple_term("and", "symbol")
+ if and_symbol then
+ and_symbol = " " .. and_symbol .. " "
end
- if str._type ~= "RichText" then
- str = richtext.new(str)
+ local number_part_list = {}
+ for _, tuple in ipairs(util.split_multiple(number, "%s*[,&]%s*", true)) do
+ local single_number, delim = table.unpack(tuple)
+ delim = util.strip(delim)
+ if delim == "," then
+ delim = ", "
+ elseif delim == "&" then
+ delim = and_symbol or " & "
+ end
+ local start = single_number
+ local stop = ""
+ local splits = util.split(start, "%s*%-%s*")
+ if #splits == 2 then
+ start, stop = table.unpack(splits)
+ if util.endswith(start, "\\") then
+ start = string.sub(start, 1, -2)
+ start = start .. "-" .. stop
+ stop = ""
+ end
+ -- if string.match(start, "^%a*%d+%a*$") and string.match(stop, "^%a*%d+%a*$") then
+ -- if s
+ table.insert(number_part_list, {start, stop, delim})
+ -- else
+ -- table.insert(number_part_list, {start .. "-" .. stop, "", delim})
+ -- end
+ else
+ table.insert(number_part_list, {start, stop, delim})
+ end
end
- local strip_periods = context.options["strip-periods"]
- if strip_periods then
- str:strip_periods()
+ return number_part_list
+end
+
+function Element:format_roman_number_parts(number_parts)
+ for i = 1, 2 do
+ local part = number_parts[i]
+ if string.match(part, "%d+") then
+ number_parts[i] = util.convert_roman(tonumber(part))
+ end
end
- return str
end
--- Text-case
-function Element:case (text, context)
- if not text or text == "" then
- return nil
+function Element:format_ordinal_number_parts(number_parts, form, gender, context)
+ for i = 1, 2 do
+ local part = number_parts[i]
+ if string.match(part, "%d+") then
+ local number = tonumber(part)
+ if form == "long-ordinal" and number >= 1 and number <= 10 then
+ number_parts[i] = context:get_simple_term(string.format("long-ordinal-%02d", number))
+ else
+ local suffix = context.locale:get_ordinal_term(number, gender)
+ if suffix then
+ number_parts[i] = number_parts[i] .. suffix
+ end
+ end
+ end
+ end
+end
+
+function Element:format_numeric_number_parts(number_parts)
+ -- if number_parts[2] ~= "" then
+ -- local first_prefix = string.match(number_parts[1], "^(.-)%d+")
+ -- local second_prefix = string.match(number_parts[2], "^(.-)%d+")
+ -- if first_prefix == second_prefix then
+ -- number_parts[1] = number_parts[1] .. "-" .. number_parts[2]
+ -- number_parts[2] = ""
+ -- end
+ -- end
+end
+
+-- https://docs.citationstyles.org/en/stable/specification.html#appendix-v-page-range-formats
+function Element:format_page_range(number_parts, page_range_format)
+ local start = number_parts[1]
+ local stop = number_parts[2]
+ local start_prefix, start_num = string.match(start, "^(.-)(%d+)$")
+ local stop_prefix, stop_num = string.match(stop, "^(.-)(%d+)$")
+ if start_prefix ~= stop_prefix then
+ -- Not valid range: "n11564-1568" -> "n11564-1568"
+ -- 110-N6
+ -- N110-P5
+ number_parts[1] = start .. "-" .. stop
+ number_parts[2] = ""
+ return
end
- if text._type ~= "RichText" then
- text = richtext.new(text)
+
+ if not page_range_format then
+ return
end
- local text_case = context.options["text-case"]
- if not text_case then
- return text
+ if page_range_format == "chicago-16" then
+ stop = self:_format_range_chicago_16(start_num, stop_num)
+ elseif page_range_format == "chicago-15" then
+ stop = self:_format_range_chicago_15(start_num, stop_num)
+ elseif page_range_format == "expanded" then
+ stop = stop_prefix .. self:_format_range_expanded(start_num, stop_num)
+ elseif page_range_format == "minimal" then
+ stop = self:_format_range_minimal(start_num, stop_num)
+ elseif page_range_format == "minimal-two" then
+ stop = self:_format_range_minimal(start_num, stop_num, 2)
end
- if text_case == "title" then
- -- title case conversion only affects English-language items
- local language = context.item["language"]
- if not language then
- language = self:get_style():get_attribute("default-locale") or "en-US"
- end
- if not util.startswith(language, "en") then
- return text
+ number_parts[2] = stop
+end
+
+function Element:_format_range_chicago_16(start, stop)
+ if #start < 3 or string.sub(start, -2) == "00" then
+ return self:_format_range_expanded(start, stop)
+ elseif string.sub(start, -2, -2) == "0" then
+ return self:_format_range_minimal(start, stop)
+ else
+ return self:_format_range_minimal(start, stop, 2)
+ end
+ return stop
+end
+
+function Element:_format_range_chicago_15(start, stop)
+ if #start < 3 or string.sub(start, -2) == "00" then
+ return self:_format_range_expanded(start, stop)
+ else
+ local changed_digits = self:_format_range_minimal(start, stop)
+ if string.sub(start, -2, -2) == "0" then
+ return changed_digits
+ elseif #start == 4 and #changed_digits == 3 then
+ return self:_format_range_expanded(start, stop)
+ else
+ return self:_format_range_minimal(start, stop, 2)
end
end
- text:add_format("text-case", text_case)
- return text
+ return stop
end
+function Element:_format_range_expanded(start, stop)
+ -- Expand "1234–56" -> "1234–1256"
+ if #start <= #stop then
+ return stop
+ end
+ return string.sub(start, 1, #start - #stop) .. stop
+end
+
+function Element:_format_range_minimal(start, stop, threshold)
+ threshold = threshold or 1
+ if #start < #stop then
+ return stop
+ end
+ local offset = #start - #stop
+ for i = 1, #stop - threshold do
+ local j = i + offset
+ if string.sub(stop, i, i) ~= string.sub(start, j, j) then
+ return string.sub(stop, i)
+ end
+ end
+ return string.sub(stop, -threshold)
+end
element.Element = Element
diff --git a/biblio/citation-style-language/citeproc-engine.lua b/biblio/citation-style-language/citeproc-engine.lua
index 33a5a08e08..2e9f4c4a61 100644
--- a/biblio/citation-style-language/citeproc-engine.lua
+++ b/biblio/citation-style-language/citeproc-engine.lua
@@ -8,17 +8,29 @@ local engine = {}
local dom = require("luaxml-domobject")
-local richtext = require("citeproc-richtext")
-local element = require("citeproc-element")
local nodes = require("citeproc-nodes")
-local formats = require("citeproc-formats")
+local Style = require("citeproc-node-style").Style
+local Locale = require("citeproc-node-locale").Locale
+local Context = require("citeproc-context").Context
+local IrState = require("citeproc-context").IrState
+local Rendered = require("citeproc-ir-node").Rendered
+local YearSuffix = require("citeproc-ir-node").YearSuffix
+-- local OutputFormat = require("citeproc-output").OutputFormat
+local LatexWriter = require("citeproc-output").LatexWriter
+local HtmlWriter = require("citeproc-output").HtmlWriter
+local SortStringFormat = require("citeproc-output").SortStringFormat
+local DisamStringFormat = require("citeproc-output").DisamStringFormat
+local InlineElement = require("citeproc-output").InlineElement
+local Micro = require("citeproc-output").Micro
+local Formatted = require("citeproc-output").Formatted
+local PlainText = require("citeproc-output").PlainText
local util = require("citeproc-util")
local CiteProc = {}
-function CiteProc.new (sys, style, lang, force_lang)
- if sys == nil then
+function CiteProc.new(sys, style, lang, force_lang)
+ if not sys then
error("\"citeprocSys\" required")
end
if sys.retrieveLocale == nil then
@@ -28,213 +40,1579 @@ function CiteProc.new (sys, style, lang, force_lang)
error("\"citeprocSys.retrieveItem\" required")
end
local o = {}
+
+ o.style = Style:parse(style)
+
+ o.sys = sys
+ o.locales = {}
+ o.system_locales = {}
+
+ o.lang = o.style.default_locale
+ if not o.lang or force_lang then
+ o.lang = lang or "en-US"
+ end
+
+ o.output_format = LatexWriter:new()
+
+ o.opt = {
+ -- Similar to citeproc-js's development_extensions.wrap_url_and_doi
+ url_link = false,
+ doi_link = false, -- also applied to PMID and PMCID
+ title_link = false,
+ }
+
o.registry = {
- citations = {}, -- A map
- citation_strings = {}, -- A list
- registry = {}, -- A map
- reflist = {}, -- A list
+ citations_by_id = {}, -- A map
+ citation_list = {}, -- A list
+ citations_by_item_id = {}, -- A map from item id to a map of citations
+ registry = {}, -- A map of bibliographic meta data
+ reflist = {}, -- list of cited ids
+ uncited_list = {},
previous_citation = nil,
requires_sorting = false,
+ longest_label = "",
+ maxoffset = 0,
}
- o.sys = sys
- o.system_locales = {}
+ o.cite_first_note_numbers = {}
+ o.cite_last_note_numbers = {}
+ o.note_citations_map = {}
- if type(style) == "string" then
- o.csl = dom.parse(style)
- else
- o.csl = style
- end
- o.csl:traverse_elements(CiteProc.set_base_class)
- o.csl:root_node().engine = o
- o.style = o.csl:get_path("style")[1]
- o.style.lang = lang
- o.csl:root_node().style = o.style
+ o.tainted_item_ids = {}
- o.style:set_lang(lang, force_lang)
+ o.disam_irs = {}
+ -- { <ir1>, <ir2>, ... }
- o.formatter = formats.latex
- o.linking_enabled = false
+ o.cite_irs_by_output = {}
+ -- {
+ -- ["Roe, J"] = {<ir1>},
+ -- ["Doe, J"] = {<ir2>, <ir3>},
+ -- ["Doe, John"] = {<ir2>},
+ -- ["Doe, Jack"] = {<ir2>},
+ -- }
+
+ o.person_names = {}
+ o.person_names_by_output = {}
setmetatable(o, { __index = CiteProc })
return o
end
-function CiteProc:updateItems (ids)
+function CiteProc:updateItems(ids)
self.registry.reflist = {}
self.registry.registry = {}
+ self.person_names = {}
+ self.person_names_by_output = {}
+ self.disam_irs = {}
+ self.cite_irs_by_output = {}
+
+ local cite_items = {}
+ local loaded_ids = {}
+
for _, id in ipairs(ids) do
- self:get_item(id)
+ table.insert(cite_items, {id = id})
+ loaded_ids[id] = true
+ end
+ for _, id in ipairs(self.registry.uncited_list) do
+ if not loaded_ids[id] then
+ table.insert(cite_items, {id = id})
+ loaded_ids[id] = true
+ end
end
+
+ -- TODO: optimize this
+ self:makeCitationCluster(cite_items)
+
+ self.registry.previous_citation = nil
+ self.cite_first_note_numbers = {}
+ self.cite_last_note_numbers = {}
+ self.note_citations_map = {}
end
-function CiteProc:updateUncitedItems(ids)
- for _, id in ipairs(ids) do
- if not self.registry.registry[id] then
- self:get_item(id)
+function CiteProc:updateUncitedItems(uncited_ids)
+ -- self.registry.reflist = {}
+ self.registry.registry = {}
+ self.registry.uncited_list = {}
+ self.person_names = {}
+ self.person_names_by_output = {}
+ self.disam_irs = {}
+ self.cite_irs_by_output = {}
+
+ local cite_items = {}
+ local loaded_ids = {}
+
+ for _, id in ipairs(self.registry.reflist) do
+ if not loaded_ids[id] then
+ table.insert(cite_items, {id = id})
+ loaded_ids[id] = true
end
end
- -- TODO: disambiguation
+ self.registry.reflist = {}
+
+ for _, id in ipairs(uncited_ids) do
+ if not loaded_ids[id] then
+ table.insert(cite_items, {id = id})
+ loaded_ids[id] = true
+ end
+ end
+
+ loaded_ids = {}
+ for _, id in ipairs(uncited_ids) do
+ if not loaded_ids[id] then
+ table.insert(self.registry.uncited_list, id)
+ loaded_ids[id] = true
+ end
+ end
+
+ -- TODO: optimize this
+ self:makeCitationCluster(cite_items)
+
+ self.registry.previous_citation = nil
+ self.cite_first_note_numbers = {}
+ self.cite_last_note_numbers = {}
+ self.note_citations_map = {}
end
function CiteProc:processCitationCluster(citation, citationsPre, citationsPost)
- -- citation = {
- -- citationID = "CITATION-3",
- -- citationItems = {
- -- { id = "ITEM-1" },
- -- { id = "ITEM-2" },
- -- },
- -- properties = {
- -- noteIndex = 3,
- -- },
- -- }
- -- citationsPre = {
- -- {"CITATION-1", 1},
- -- {"CITATION-2", 2},
- -- }
- -- citationsPost = {
- -- {"CITATION-4", 4},
- -- }
- -- returns = {
- -- {
- -- bibchange = true,
- -- citation_errors = {},
- -- },
- -- {
- -- { 2, "[1,2]", "CITATION-3" }
- -- }
- -- }
- self.registry.citations[citation.citationID] = citation
+ -- util.debug(citation)
+ -- util.debug(citationsPre)
+ -- Fix missing noteIndex: sort_CitationNumberPrimaryAscendingViaMacroCitation.txt
+ if not citation.properties then
+ citation.properties = {}
+ end
+ if not citation.properties.noteIndex then
+ citation.properties.noteIndex = 0
+ end
- local items = {}
+ -- Registor citation
+ self.registry.citations_by_id[citation.citationID] = citation
+
+ local citation_note_pairs = {}
+ util.extend(citation_note_pairs, citationsPre)
+ table.insert(citation_note_pairs, {citation.citationID, citation.properties.noteIndex})
+ util.extend(citation_note_pairs, citationsPost)
+ -- util.debug(citation_note_pairs)
+
+ local citations_by_id = {}
+ local citation_list = {}
+ for _, pair in ipairs(citation_note_pairs) do
+ local citation_id, note_number = table.unpack(pair)
+ local citation_ = self.registry.citations_by_id[citation_id]
+ if not citation_ then
+ util.error("Citation not in registry.")
+ end
+ citations_by_id[citation_.citationID] = citation_
+ table.insert(citation_list, citation_)
+ end
+ self.registry.citations_by_id = citations_by_id
+ self.registry.citation_list = citation_list
+
+ -- update self.registry.citations_by_item_id
+ local item_ids = {}
+ self.registry.citations_by_item_id = {}
+ for _, citation_ in ipairs(citation_list) do
+ for _, cite_item in ipairs(citation_.citationItems) do
+ if not self.registry.citations_by_item_id[cite_item.id] then
+ self.registry.citations_by_item_id[cite_item.id] = {}
+ table.insert(item_ids, cite_item.id)
+ end
+ self.registry.citations_by_item_id[cite_item.id][citation_.citationID] = true
+ end
+ end
+ self:updateItems(item_ids)
+
+ local params = {
+ bibchange = false,
+ citation_errors = {},
+ }
+ local output = {}
+ local tainted_citation_ids = self:get_tainted_citaion_ids(citation_note_pairs)
+ -- util.debug(tainted_citation_ids)
+
+ -- params.bibchange = #tainted_citation_ids > 0
+ for citation_id, _ in pairs(tainted_citation_ids) do
+ local citation_ = self.registry.citations_by_id[citation_id]
+
+ local citation_index = citation_.citation_index
+ local citation_str = self:build_citation_str(citation_)
+ table.insert(output, {citation_index, citation_str, citation_id})
+ end
+
+ -- util.debug(output)
+ return {params, output}
+end
+
+-- A variant of processCitationCluster() for easy use with LaTeX.
+-- It should be run after refreshing the registry (updateItems()) with all items
+function CiteProc:process_citation(citation)
+ -- util.debug(citation)
+ -- util.debug(citationsPre)
+ -- Fix missing noteIndex: sort_CitationNumberPrimaryAscendingViaMacroCitation.txt
+ if not citation.properties then
+ citation.properties = {}
+ end
+ if not citation.properties.noteIndex then
+ citation.properties.noteIndex = 0
+ end
+
+ -- Registor citation
+ self.registry.citations_by_id[citation.citationID] = citation
+
+ table.insert(self.registry.citation_list, citation)
+
+ local citation_note_pairs = {}
+ for _, citation_ in ipairs(self.registry.citation_list) do
+ table.insert(citation_note_pairs, {citation_.citationID, citation_.properties.noteIndex})
+ end
+
+ -- update self.registry.citations_by_item_id
for _, cite_item in ipairs(citation.citationItems) do
+ if not self.registry.citations_by_item_id[cite_item.id] then
+ self.registry.citations_by_item_id[cite_item.id] = {}
+ end
+ self.registry.citations_by_item_id[cite_item.id][citation.citationID] = true
+ end
+
+ -- self:updateItems(item_ids)
+ for i, cite_item in ipairs(citation.citationItems) do
cite_item.id = tostring(cite_item.id)
- local position_first = (self.registry.registry[cite_item.id] == nil)
- local item_data = self:get_item(cite_item.id)
+ self:get_item(cite_item.id)
+ end
- if item_data then
- -- Create a wrapper of the orignal item from registry so that
- -- it may hold different `locator` or `position` values for cites.
- local item = setmetatable({}, {__index = function (_, key)
- if cite_item[key] then
- return cite_item[key]
- else
- return item_data[key]
+ local tainted_citation_ids = self:get_tainted_citaion_ids(citation_note_pairs)
+ local citation_str = self:build_citation_str(citation)
+
+ return citation_str
+end
+
+
+function CiteProc:get_tainted_citaion_ids(citation_note_pairs)
+ local tainted_citation_ids = {}
+
+ self.cite_first_note_numbers = {}
+ self.cite_last_note_numbers = {}
+ self.note_citations_map = {}
+ -- {
+ -- 1 = {"citation-1", "citation-2"},
+ -- 2 = {"citation-2"},
+ -- }
+
+ local previous_citation
+ for citation_index, pair in ipairs(citation_note_pairs) do
+ local citation_id, note_number = table.unpack(pair)
+ -- util.debug(citation_id)
+ local citation = self.registry.citations_by_id[citation_id]
+ citation.properties.noteIndex = note_number
+ citation.citation_index = citation_index
+
+ local tainted = false
+
+ local previous_cite
+ for _, cite_item in ipairs(citation.citationItems) do
+ tainted = self:set_cite_item_position(cite_item, note_number, previous_cite, previous_citation)
+ self.cite_last_note_numbers[cite_item.id] = note_number
+ previous_cite = cite_item
+ end
+
+ if tainted then
+ tainted_citation_ids[citation.citationID] = true
+ end
+
+ if not self.note_citations_map[note_number] then
+ self.note_citations_map[note_number] = {}
+ end
+ table.insert(self.note_citations_map[note_number], citation.citationID)
+ previous_citation = citation
+ end
+
+ -- Update tainted citation ids because of citation-number's change
+ -- The self.tainted_item_ids were added in the sort_bibliography() procedure.
+ for item_id, _ in pairs(self.tainted_item_ids) do
+ if self.registry.citations_by_item_id[item_id] then
+ for citation_id, _ in pairs(self.registry.citations_by_item_id[item_id]) do
+ tainted_citation_ids[citation_id] = true
+ end
+ end
+ end
+
+ return tainted_citation_ids
+end
+
+function CiteProc:set_cite_item_position(cite_item, note_number, previous_cite, previous_citation)
+ local position = util.position_map["first"]
+
+ local first_reference_note_number = self.cite_first_note_numbers[cite_item.id]
+ if first_reference_note_number then
+ position = util.position_map["subsequent"]
+ else
+ self.cite_first_note_numbers[cite_item.id] = note_number
+ end
+
+ local preceding_cite_item = self:get_preceding_cite_item(cite_item, previous_cite, previous_citation, note_number)
+ if preceding_cite_item then
+ position = self:_get_cite_position(cite_item, preceding_cite_item)
+ end
+
+ local near_note = false
+ local last_note_number = self.cite_last_note_numbers[cite_item.id]
+ if last_note_number then
+ local note_distance = note_number - last_note_number
+ if note_distance <= self.style.citation.near_note_distance then
+ near_note = true
+ end
+ end
+
+ local tainted = false
+ if cite_item.position_level ~= position then
+ tainted = true
+ cite_item.position_level = position
+ end
+ if cite_item["first-reference-note-number"] ~= first_reference_note_number then
+ tainted = true
+ cite_item["first-reference-note-number"] = first_reference_note_number
+ end
+ if cite_item.near_note ~= near_note then
+ tainted = true
+ cite_item.near_note = near_note
+ end
+ return tainted
+end
+
+-- Find the preceding cite referencing the same item
+function CiteProc:get_preceding_cite_item(cite_item, previous_cite, previous_citation, note_number)
+ if previous_cite then
+ -- a. the current cite immediately follows on another cite, within the same
+ -- citation, that references the same item
+ if cite_item.id == previous_cite.id then
+ return previous_cite
+ end
+ elseif previous_citation then
+ -- (hidden) The previous citation is the only one in the previous note.
+ -- See also
+ -- https://github.com/citation-style-language/documentation/issues/121
+ -- position_IbidWithMultipleSoloCitesInBackref.txt
+ -- b. the current cite is the first cite in the citation, and the previous
+ -- citation consists of a single cite referencing the same item
+ local previous_note_number = previous_citation.properties.noteIndex
+ local num_previous_note_citations = #self.note_citations_map[previous_note_number]
+ if (previous_note_number == note_number - 1 and num_previous_note_citations == 1)
+ or previous_note_number == note_number then
+ if #previous_citation.citationItems == 1 then
+ previous_cite = previous_citation.citationItems[1]
+ if previous_cite.id == cite_item.id then
+ return previous_cite
end
- end})
+ end
+ end
+ end
+ return nil
+end
- if not item.position and position_first then
- item.position = util.position_map["first"]
+function CiteProc:_get_cite_position(item, preceding_cite)
+ if preceding_cite.locator then
+ if item.locator then
+ if item.locator == preceding_cite.locator and item.label == preceding_cite.label then
+ return util.position_map["ibid"]
+ else
+ return util.position_map["ibid-with-locator"]
end
+ else
+ return util.position_map["subsequent"]
+ end
+ else
+ if item.locator then
+ return util.position_map["ibid-with-locator"]
+ else
+ return util.position_map["ibid"]
+ end
+ end
+end
+
+function CiteProc:build_citation_str(citation)
+ -- util.debug(citation.citationID)
+ local items = {}
+ for i, cite_item in ipairs(citation.citationItems) do
+ cite_item.id = tostring(cite_item.id)
+ -- util.debug(cite_item.id)
+
+ -- Use "page" as locator label if missing
+ -- label_PluralWithAmpersand.txt
+ if cite_item.locator and not cite_item.label then
+ cite_item.label = "page"
+ end
+
+ table.insert(items, cite_item)
+ end
- local first_reference_note_number = nil
- for _, pre_citation in ipairs(citationsPre) do
- pre_citation = self.registry.citations[pre_citation[1]]
- for _, pre_cite_item in ipairs(pre_citation.citationItems) do
- if pre_cite_item.id == cite_item.id then
- first_reference_note_number = pre_citation.properties.noteIndex
+ if self.registry.requires_sorting then
+ self:sort_bibliography()
+ end
+
+ local citation_str = self:build_cluster(items)
+ return citation_str
+end
+
+function CiteProc:build_cluster(citation_items)
+ local output_format = self.output_format
+ local irs = {}
+ citation_items = self:sorted_citation_items(citation_items)
+ for _, cite_item in ipairs(citation_items) do
+ local ir = self:build_fully_disambiguated_ir(cite_item, output_format)
+ table.insert(irs, ir)
+ end
+
+ if self.style.citation.cite_grouping then
+ irs = self:group_cites(irs)
+ else
+ local citation_collapse = self.style.citation.collapse
+ if citation_collapse == "year" or citation_collapse == "year-suffix" or
+ citation_collapse == "year-suffix-ranged" then
+ irs = self:group_cites(irs)
+ end
+ end
+
+ if self.style.citation.collapse then
+ self:collapse_cites(irs)
+ end
+
+ -- Capitalize first
+ for i, ir in ipairs(irs) do
+ -- local layout_prefix
+ -- local layout_affixes = self.style.citation.layout.affixes
+ -- if layout_affixes then
+ -- layout_prefix = layout_affixes.prefix
+ -- end
+ local prefix = citation_items[i].prefix
+ if prefix then
+ if prefix and string.match(prefix, "[.!?]%s*$") and #util.split(util.strip(prefix)) > 1 then
+ ir:capitalize_first_term()
+ end
+ else
+ local delimiter = self.style.citation.layout.delimiter
+ if i == 1 or not delimiter or string.match(delimiter, "[.!?]%s*$") then
+ ir:capitalize_first_term()
+ end
+ end
+ end
+
+ -- util.debug(irs)
+
+ local citation_delimiter = self.style.citation.layout.delimiter
+ local citation_stream = {}
+
+ local context = Context:new()
+ context.engine = self
+ context.style = self.style
+ context.area = self.style.citation
+ context.in_bibliography = false
+ context.locale = self:get_locale(self.lang)
+ context.name_inheritance = self.style.citation.name_inheritance
+ context.format = output_format
+
+ local previous_ir
+ for i, ir in ipairs(irs) do
+ local cite_prefix = citation_items[i].prefix
+ local cite_suffix = citation_items[i].suffix
+ if not ir.collapse_suppressed then
+ local ir_inlines = ir:flatten(output_format)
+ if #ir_inlines > 0 then
+ -- Make sure ir_inlines has outputs contents.
+ -- collapse_AuthorCollapseNoDateSorted.txt
+ if previous_ir then
+ if previous_ir.own_delimiter then
+ table.insert(citation_stream, PlainText:new(previous_ir.own_delimiter))
+ elseif citation_delimiter and not (cite_prefix and util.startswith(cite_prefix, ",")) then
+ table.insert(citation_stream, PlainText:new(citation_delimiter))
end
- break
end
- if first_reference_note_number then
- break
+
+ if cite_prefix then
+ table.insert(citation_stream, Micro:new(InlineElement:parse(cite_prefix, context)))
+ end
+
+ -- util.debug(ir)
+ util.extend(citation_stream, ir_inlines)
+ previous_ir = ir
+
+ if cite_suffix then
+ table.insert(citation_stream, Micro:new(InlineElement:parse(cite_suffix, context)))
end
end
- item["first-reference-note-number"] = first_reference_note_number
+ end
+ end
+ -- util.debug(citation_stream)
- table.insert(items, item)
+ if context.area.layout.affixes then
+ local affixes = context.area.layout.affixes
+ if affixes.prefix then
+ table.insert(citation_stream, 1, PlainText:new(affixes.prefix))
+ end
+ if affixes.suffix then
+ table.insert(citation_stream, PlainText:new(affixes.suffix))
end
end
+ -- util.debug(citation_stream)
- if #citationsPre > 0 then
- local previous_citation_id = citationsPre[#citationsPre][1]
- local previous_citation = self.registry.citations[previous_citation_id]
- self.registry.previous_citation = previous_citation
+ if #citation_stream > 0 and context.area.layout.formatting then
+ citation_stream = {Formatted:new(citation_stream, context.area.layout.formatting)}
end
- if self.registry.requires_sorting then
- self:sort_bibliography()
+ if #citation_stream == 0 then
+ citation_stream = {PlainText:new("[CSL STYLE ERROR: reference with no printed form.]")}
end
- local params = {
- bibchange = false,
- citation_errors = {},
- }
+ -- util.debug(citation_stream)
+ local str = output_format:output(citation_stream, context)
+ str = util.strip(str)
- local citation_id_note_list = {}
- for _, citation_id_note in ipairs(citationsPre) do
- table.insert(citation_id_note_list, citation_id_note)
+ return str
+end
+
+function CiteProc:sorted_citation_items(items)
+ local citation_sort = self.style.citation.sort
+ if not citation_sort then
+ return items
end
- local note_index = 0
- if citation.properties and citation.properties.noteIndex then
- note_index = citation.properties.noteIndex
+
+ local state = IrState:new()
+ local context = Context:new()
+ context.engine = self
+ context.style = self.style
+ context.area = self.style.citation
+ context.in_bibliography = false
+ context.locale = self:get_locale(self.lang)
+ context.name_inheritance = self.style.citation.name_inheritance
+ context.format = SortStringFormat:new()
+ -- context.id = id
+ context.cite = nil
+ -- context.reference = self:get_item(id)
+
+ items = citation_sort:sort(items, state, context)
+ return items
+end
+
+function CiteProc:build_fully_disambiguated_ir(cite_item, output_format)
+ local cite_ir = self:build_ambiguous_ir(cite_item, output_format)
+ -- util.debug(cite_ir)
+ cite_ir = self:disambiguate_add_givenname(cite_ir)
+ cite_ir = self:disambiguate_add_names(cite_ir)
+ cite_ir = self:disambiguate_conditionals(cite_ir)
+ cite_ir = self:disambiguate_add_year_suffix(cite_ir)
+ return cite_ir
+end
+
+function CiteProc:build_ambiguous_ir(cite_item, output_format)
+ local state = IrState:new(self.style)
+ cite_item.id = tostring(cite_item.id)
+ local context = Context:new()
+ context.engine = self
+ context.style = self.style
+ context.area = self.style.citation
+ context.locale = self:get_locale(self.lang)
+ context.name_inheritance = self.style.citation.name_inheritance
+ context.format = output_format
+ context.id = cite_item.id
+ context.cite = cite_item
+ -- context.reference = self:get_item(cite_item.id)
+ context.reference = self.registry.registry[cite_item.id]
+
+ local ir
+ if context.reference then
+ ir = self.style.citation:build_ir(self, state, context)
+ else
+ -- The warning has been given in the retrieving procedure.
+ -- util.warning(string.format('Failed to find the entry "%s" in database.', cite_item.id))
+ ir = Rendered:new({Formatted:new({PlainText:new(cite_item.id)}, {["font-weight"] = "bold"})}, self)
end
- table.insert(citation_id_note_list, {citation.citationID, note_index})
- for _, citation_id_note in ipairs(citationsPost) do
- table.insert(citation_id_note_list, citation_id_note)
+
+ ir.cite_item = cite_item
+ ir.reference = context.reference
+ ir.ir_index = #self.disam_irs + 1
+ table.insert(self.disam_irs, ir)
+ ir.is_ambiguous = false
+ ir.disam_level = 0
+
+ -- Formattings like font-style are ignored for disambiguation.
+ local disam_format = DisamStringFormat:new()
+ local inlines = ir:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ ir.disam_str = disam_str
+
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
end
- local citation_id_cited = {}
- for _, citation_id_note in ipairs(citation_id_note_list) do
- citation_id_cited[citation_id_note[1]] = true
+ for ir_index, ir_ in pairs(self.cite_irs_by_output[disam_str]) do
+ if ir_.cite_item.id ~= cite_item.id then
+ ir.is_ambiguous = true
+ break
+ end
end
- for citation_id, _ in pairs(self.registry.citations) do
- if not citation_id_cited[citation_id] then
- self.registry.citations[citation_id] = nil
- self.registry.citation_strings[citation_id] = nil
+ self.cite_irs_by_output[disam_str][ir.ir_index] = ir
+
+ return ir
+end
+
+function CiteProc:disambiguate_add_givenname(cite_ir)
+ if self.style.citation.disambiguate_add_givenname then
+ -- util.debug("disambiguate_add_givenname: " .. cite_ir.cite_item.id)
+
+ local gn_disam_rule = self.style.citation.givenname_disambiguation_rule
+ if gn_disam_rule == "all-names" or gn_disam_rule == "all-names-with-initials" then
+ cite_ir = self:disambiguate_add_givenname_all_names(cite_ir)
+ elseif gn_disam_rule == "primary-name" or gn_disam_rule == "primary-name-with-initials" then
+ cite_ir = self:disambiguate_add_givenname_primary_name(cite_ir)
+ elseif gn_disam_rule == "by-cite" then
+ cite_ir = self:disambiguate_add_givenname_by_cite(cite_ir)
end
end
+ return cite_ir
+end
- local output = {}
+-- TODO: reorganize this code
+function CiteProc:disambiguate_add_givenname_all_names(cite_ir)
+ -- util.debug("disambiguate_add_givenname_all_names: " .. cite_ir.cite_item.id)
+ if not cite_ir.person_name_irs or #cite_ir.person_name_irs == 0 then
+ return cite_ir
+ end
+
+ -- util.debug(cite_ir.disam_str)
+
+ for _, person_name_ir in ipairs(cite_ir.person_name_irs) do
+ local name_output = person_name_ir.name_output
+ -- util.debug(name_output)
+
+ if not person_name_ir.person_name_index then
+ person_name_ir.person_name_index = #self.person_names + 1
+ table.insert(self.person_names, person_name_ir)
+ end
+
+ if not self.person_names_by_output[name_output] then
+ self.person_names_by_output[name_output] = {}
+ end
+ self.person_names_by_output[name_output][person_name_ir.person_name_index] = person_name_ir
+
+ local ambiguous_name_irs = {}
+ local ambiguous_same_output_irs = {}
+
+ for _, pn_ir in pairs(self.person_names_by_output[person_name_ir.name_output]) do
+ if pn_ir.full_name ~= person_name_ir.full_name then
+ table.insert(ambiguous_name_irs, pn_ir)
+ end
+ if pn_ir.name_output == person_name_ir.name_output then
+ table.insert(ambiguous_same_output_irs, pn_ir)
+ end
+ end
+
+ -- util.debug(person_name_ir.name_output)
+ -- util.debug(person_name_ir.full_name)
+ -- util.debug(#ambiguous_name_irs)
+ -- util.debug(person_name_ir.disam_variants_index)
+ -- util.debug(person_name_ir.disam_variants)
+
+ while person_name_ir.disam_variants_index < #person_name_ir.disam_variants do
+ if #ambiguous_name_irs == 0 then
+ break
+ end
+
+ for _, pn_ir in ipairs(ambiguous_same_output_irs) do
+ -- expand one name
+ if pn_ir.disam_variants_index < #pn_ir.disam_variants then
+ pn_ir.disam_variants_index = pn_ir.disam_variants_index + 1
+ pn_ir.name_output = pn_ir.disam_variants[pn_ir.disam_variants_index]
+ pn_ir.inlines = pn_ir.disam_inlines[pn_ir.name_output]
+
+ if not self.person_names_by_output[pn_ir.name_output] then
+ self.person_names_by_output[pn_ir.name_output] = {}
+ end
+ self.person_names_by_output[pn_ir.name_output][pn_ir.person_name_index] = pn_ir
+ end
+ end
+
+ -- util.debug(person_name_ir.name_output)
+
+ -- update ambiguous_name_irs and ambiguous_same_output_irs
+ ambiguous_name_irs = {}
+ ambiguous_same_output_irs = {}
+ for _, pn_ir in pairs(self.person_names_by_output[person_name_ir.name_output]) do
+ if pn_ir.full_name ~= person_name_ir.full_name then
+ -- util.debug(pn_ir.full_name .. ": " .. pn_ir.name_output)
+ table.insert(ambiguous_name_irs, pn_ir)
+ end
+ if pn_ir.name_output == person_name_ir.name_output then
+ table.insert(ambiguous_same_output_irs, pn_ir)
+ end
+ end
+
+ end
+ end
+
+ -- update cite_ir output
+ local disam_format = DisamStringFormat:new()
+ local inlines = cite_ir:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ cite_ir.disam_str = disam_str
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
+ end
+ self.cite_irs_by_output[disam_str][cite_ir.ir_index] = cite_ir
+
+ -- update ambiguous_cite_irs and ambiguous_same_output_irs
+ local ambiguous_cite_irs = {}
+ for ir_index, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ -- util.debug(ir_.cite_item.id)
+ if ir_.cite_item.id ~= cite_ir.cite_item.id then
+ table.insert(ambiguous_cite_irs, ir_)
+ end
+ end
+ if #ambiguous_cite_irs == 0 then
+ cite_ir.is_ambiguous = false
+ end
+
+ return cite_ir
+end
+
+function CiteProc:disambiguate_add_givenname_primary_name(cite_ir)
+ if not cite_ir.person_name_irs or #cite_ir.person_name_irs == 0 then
+ return cite_ir
+ end
+ local person_name_ir = cite_ir.person_name_irs[1]
+ local name_output = person_name_ir.name_output
+ -- util.debug(name_output)
+
+ if not person_name_ir.person_name_index then
+ person_name_ir.person_name_index = #self.person_names + 1
+ table.insert(self.person_names, person_name_ir)
+ end
+ if not self.person_names_by_output[name_output] then
+ self.person_names_by_output[name_output] = {}
+ end
+ self.person_names_by_output[name_output][person_name_ir.person_name_index] = person_name_ir
+
+ local ambiguous_name_irs = {}
+ local ambiguous_same_output_irs = {}
+
+ for _, pn_ir in pairs(self.person_names_by_output[person_name_ir.name_output]) do
+ if pn_ir.full_name ~= person_name_ir.full_name then
+ table.insert(ambiguous_name_irs, pn_ir)
+ end
+ if pn_ir.name_output == person_name_ir.name_output then
+ table.insert(ambiguous_same_output_irs, pn_ir)
+ end
+ end
+
+ for _, name_variant in ipairs(person_name_ir.disam_variants) do
+ if #ambiguous_name_irs == 0 then
+ break
+ end
+
+ for _, pn_ir in ipairs(ambiguous_same_output_irs) do
+ -- expand one name
+ if pn_ir.disam_variants_index < #pn_ir.disam_variants then
+ pn_ir.disam_variants_index = pn_ir.disam_variants_index + 1
+ pn_ir.name_output = pn_ir.disam_variants[pn_ir.disam_variants_index]
+ pn_ir.inlines = pn_ir.disam_inlines[pn_ir.name_output]
+
+ if not self.person_names_by_output[pn_ir.name_output] then
+ self.person_names_by_output[pn_ir.name_output] = {}
+ end
+ self.person_names_by_output[pn_ir.name_output][person_name_ir.person_name_index] = person_name_ir
+ end
+ end
+
+ -- update ambiguous_name_irs and ambiguous_same_output_irs
+ ambiguous_name_irs = {}
+ ambiguous_same_output_irs = {}
+ for _, pn_ir in pairs(self.person_names_by_output[person_name_ir.name_output]) do
+ if pn_ir.full_name ~= person_name_ir.full_name then
+ table.insert(ambiguous_name_irs, pn_ir)
+ end
+ if pn_ir.name_output == person_name_ir.name_output then
+ table.insert(ambiguous_same_output_irs, pn_ir)
+ end
+ end
+ end
+
+ return cite_ir
+end
+
+function CiteProc:disambiguate_add_givenname_by_cite(cite_ir)
+ if not cite_ir.is_ambiguous then
+ return cite_ir
+ end
+ if not cite_ir.person_name_irs or #cite_ir.person_name_irs == 0 then
+ return cite_ir
+ end
+
+ for _, ir_ in ipairs(self.disam_irs) do
+ -- util.debug(ir_.cite_item.id)
+ -- util.debug(ir_.disam_str)
+ end
+
+ local disam_format = DisamStringFormat:new()
+
+ local ambiguous_cite_irs = {}
+ local ambiguous_same_output_irs = {}
+
+ for ir_index, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ if ir_.cite_item.id ~= cite_ir.cite_item.id then
+ table.insert(ambiguous_cite_irs, ir_)
+ end
+ if ir_.disam_str == cite_ir.disam_str then
+ table.insert(ambiguous_same_output_irs, ir_)
+ end
+ end
+
+ for i, person_name_ir in ipairs(cite_ir.person_name_irs) do
+ -- util.debug(person_name_ir.name_output)
+ -- util.debug(person_name_ir.disam_variants)
+ if #ambiguous_cite_irs == 0 then
+ cite_ir.is_ambiguous = false
+ break
+ end
+
+ -- util.debug(person_name_ir.disam_variants)
+ while person_name_ir.disam_variants_index < #person_name_ir.disam_variants do
+ -- util.debug(person_name_ir.name_output)
+
+ local is_different_name = false
+ for _, ir_ in ipairs(ambiguous_cite_irs) do
+ if ir_.person_name_irs[i] then
+ if ir_.person_name_irs[i].full_name ~= person_name_ir.full_name then
+ -- util.debug(ir_.cite_item.id)
+ is_different_name = true
+ break
+ end
+ end
+ end
+ -- util.debug(is_different_name)
+ if not is_different_name then
+ break
+ end
+
+ for _, ir_ in ipairs(ambiguous_same_output_irs) do
+ -- util.debug(ir_.cite_item.id)
+ local person_name_ir_ = ir_.person_name_irs[i]
+ if person_name_ir_ then
+ if person_name_ir_.disam_variants_index < #person_name_ir_.disam_variants then
+ person_name_ir_.disam_variants_index = person_name_ir_.disam_variants_index + 1
+ local disam_variant = person_name_ir_.disam_variants[person_name_ir_.disam_variants_index]
+ person_name_ir_.name_output = disam_variant
+ -- util.debug(disam_variant)
+ person_name_ir_.inlines = person_name_ir_.disam_inlines[disam_variant]
+ -- Update cite ir output
+ local inlines = ir_:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ ir_.disam_str = disam_str
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
+ end
+ self.cite_irs_by_output[disam_str][ir_.ir_index] = ir_
+ end
+ end
+ end
+
+ -- update ambiguous_cite_irs and ambiguous_same_output_irs
+ ambiguous_cite_irs = {}
+ ambiguous_same_output_irs = {}
+ for ir_index, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ -- util.debug(ir_.cite_item.id)
+ if ir_.cite_item.id ~= cite_ir.cite_item.id then
+ table.insert(ambiguous_cite_irs, ir_)
+ end
+ if ir_.disam_str == cite_ir.disam_str then
+ table.insert(ambiguous_same_output_irs, ir_)
+ end
+ end
+
+ -- util.debug(#ambiguous_cite_irs)
+
+ if #ambiguous_cite_irs == 0 then
+ cite_ir.is_ambiguous = false
+ return cite_ir
+ end
+
+ end
+ end
+
+ return cite_ir
+end
+
+local function find_first_name_ir(ir)
+ if ir._type == "NameIr" then
+ return ir
+ end
+ if ir.children then
+ for _, child in ipairs(ir.children) do
+ local name_ir = find_first_name_ir(child)
+ if name_ir then
+ return name_ir
+ end
+ end
+ end
+ return nil
+end
+
+function CiteProc:disambiguate_add_names(cite_ir)
+ if not self.style.citation.disambiguate_add_names then
+ return cite_ir
+ end
+
+ if not cite_ir.name_ir then
+ cite_ir.name_ir = find_first_name_ir(cite_ir)
+ end
+ local name_ir = cite_ir.name_ir
+
+ if not cite_ir.is_ambiguous then
+ return cite_ir
+ end
+
+ if not name_ir or not name_ir.et_al_abbreviation then
+ return cite_ir
+ end
+
+ -- util.debug("disambiguate_add_names: " .. cite_ir.cite_item.id)
+
+ if name_ir then
+ -- util.debug(cite_ir.disam_str)
+ -- util.debug(cite_ir.name_ir.full_name_str)
+ -- util.debug(cite_ir.is_ambiguous)
+ end
+
+ local disam_format = DisamStringFormat:new()
+
+ while cite_ir.is_ambiguous do
+ if #cite_ir.name_ir.hidden_name_irs == 0 then
+ break
+ end
+
+ local ambiguous_cite_irs = {}
+ local ambiguous_same_output_irs = {}
+ for _, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ if ir_.cite_item.id ~= cite_ir.cite_item.id then
+ table.insert(ambiguous_cite_irs, ir_)
+ end
+ if ir_.disam_str == cite_ir.disam_str then
+ table.insert(ambiguous_same_output_irs, ir_)
+ end
+ end
+
+ -- util.debug(#ambiguous_same_output_irs)
+ if #ambiguous_cite_irs == 0 then
+ cite_ir.is_ambiguous = false
+ break
+ end
+
+ -- check if the cite can be (fully) disambiguated by adding names
+ local can_be_disambuguated = false
+ for _, ir_ in ipairs(ambiguous_cite_irs) do
+ if ir_.name_ir.full_name_str ~= cite_ir.name_ir.full_name_str then
+ can_be_disambuguated = true
+ break
+ end
+ end
+ -- util.debug(can_be_disambuguated)
+ if not can_be_disambuguated then
+ break
+ end
+
+ for _, ir_ in ipairs(ambiguous_same_output_irs) do
+ local added_person_name_ir = ir_.name_ir.name_inheritance:expand_one_name(ir_.name_ir)
+ if added_person_name_ir then
+ -- util.debug("Updated: " .. ir_.cite_item.id)
+ table.insert(ir_.person_name_irs, added_person_name_ir)
+
+ if not added_person_name_ir.person_name_index then
+ added_person_name_ir.person_name_index = #self.person_names + 1
+ table.insert(self.person_names, added_person_name_ir)
+ end
+ local name_output = added_person_name_ir.name_output
+ if not self.person_names_by_output[name_output] then
+ self.person_names_by_output[name_output] = {}
+ end
+ self.person_names_by_output[name_output][added_person_name_ir.person_name_index] = added_person_name_ir
+
+ -- Update ir output
+ local inlines = ir_:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ -- util.debug(disam_str)
+ ir_.disam_str = disam_str
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
+ end
+ self.cite_irs_by_output[disam_str][ir_.ir_index] = ir_
+ end
+ end
+
+ -- util.debug("disambiguate_add_givenname")
+
+ if self.style.citation.disambiguate_add_givenname then
+ local gn_disam_rule = self.style.citation.givenname_disambiguation_rule
+ if gn_disam_rule == "all-names" or gn_disam_rule == "all-names-with-initials" then
+ cite_ir = self:disambiguate_add_givenname_all_names(cite_ir)
+ elseif gn_disam_rule == "by-cite" then
+ cite_ir = self:disambiguate_add_givenname_by_cite(cite_ir)
+ end
+ end
+
+ cite_ir.is_ambiguous = self:check_ambiguity(cite_ir)
+
+ for _, ir_ in ipairs(self.disam_irs) do
+ -- util.debug(ir_.cite_item.id .. ": " .. ir_.disam_str)
+ end
+
+ end
+
+
+ return cite_ir
+end
+
+function CiteProc:collect_irs_with_disambiguate_branch(ir)
+ local irs_with_disambiguate_branch = {}
+ if ir.children then
+ for i, child_ir in ipairs(ir.children) do
+ if child_ir.disambiguate_branch_ir then
+ table.insert(irs_with_disambiguate_branch, child_ir)
+ elseif child_ir.children then
+ util.extend(irs_with_disambiguate_branch,
+ self:collect_irs_with_disambiguate_branch(child_ir))
+ end
+ end
+ end
+ return irs_with_disambiguate_branch
+end
+
+function CiteProc:disambiguate_conditionals(cite_ir)
+ -- util.debug(cite_ir)
+
+ cite_ir.irs_with_disambiguate_branch = self:collect_irs_with_disambiguate_branch(cite_ir)
+
+ local disam_format = DisamStringFormat:new()
+
+ while cite_ir.is_ambiguous do
+ if #cite_ir.irs_with_disambiguate_branch == 0 then
+ break
+ end
+
+ -- util.debug(cite_ir.cite_item.id)
+ -- util.debug(cite_ir.disam_str)
+
+ -- update ambiguous_same_output_irs
+ local ambiguous_same_output_irs = {}
+ for _, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ if ir_.disam_str == cite_ir.disam_str then
+ table.insert(ambiguous_same_output_irs, ir_)
+ end
+ end
+
+ for _, ir_ in ipairs(ambiguous_same_output_irs) do
+ if #ir_.irs_with_disambiguate_branch > 0 then
+ -- Disambiguation is incremental
+ -- disambiguate_IncrementalExtraText.txt
+ local condition_ir = ir_.irs_with_disambiguate_branch[1]
+ condition_ir.children[1] = condition_ir.disambiguate_branch_ir
+ condition_ir.group_var = condition_ir.disambiguate_branch_ir.group_var
+ table.remove(ir_.irs_with_disambiguate_branch, 1)
+ -- disambiguate_DisambiguateTrueReflectedInBibliography.txt
+ ir_.reference.disambiguate = true
+
+ -- Update ir output
+ local inlines = ir_:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ -- util.debug("update: " .. ir_.cite_item.id .. ": " .. disam_str)
+ ir_.disam_str = disam_str
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
+ end
+ self.cite_irs_by_output[disam_str][ir_.ir_index] = ir_
+ end
+ end
+
+ cite_ir.is_ambiguous = self:check_ambiguity(cite_ir)
+ -- util.debug(cite_ir.is_ambiguous)
+ for _, ir_ in ipairs(self.disam_irs) do
+ -- util.debug(ir_.cite_item.id .. ": " .. ir_.disam_str)
+ end
+
+ end
+ return cite_ir
+end
+
+function CiteProc:check_ambiguity(cite_ir)
+ for _, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ if ir_.cite_item.id ~= cite_ir.cite_item.id then
+ return true
+ end
+ end
+ return false
+end
+
+function CiteProc:get_same_output_irs(cite_ir)
+ local ambiguous_same_output_irs = {}
+ for _, ir_ in pairs(self.cite_irs_by_output[cite_ir.disam_str]) do
+ if ir_.disam_str == cite_ir.disam_str then
+ table.insert(ambiguous_same_output_irs, ir_)
+ end
+ end
+ return ambiguous_same_output_irs
+end
+
+function CiteProc:disambiguate_add_year_suffix(cite_ir)
+ if not cite_ir.is_ambiguous or not self.style.citation.disambiguate_add_year_suffix then
+ return cite_ir
+ end
+
+ local same_output_irs = self:get_same_output_irs(cite_ir)
+
+ table.sort(same_output_irs, function (a, b)
+ -- return a.ir_index < b.ir_index
+ return a.reference["citation-number"] < b.reference["citation-number"]
+ end)
+
+ local year_suffix_number = 0
+ -- util.debug(cite_ir)
+
+ local disam_format = DisamStringFormat:new()
+
+ for _, ir_ in ipairs(same_output_irs) do
+ ir_.reference.year_suffix_number = nil
+ end
+
+ for _, ir_ in ipairs(same_output_irs) do
+ -- print(ir_.cite_item.id)
+ -- print(ir_.reference)
+ if not ir_.reference.year_suffix_number then
+ year_suffix_number = year_suffix_number + 1
+ ir_.reference.year_suffix_number = year_suffix_number
+ ir_.reference["year-suffix"] = self:render_year_suffix(year_suffix_number)
+ end
- for i, citation_id_note in ipairs(citation_id_note_list) do
- local citation_id = citation_id_note[1]
- -- local note_index = citation_id_note[2]
- if citation_id == citation.citationID then
- local context = {
- build = {},
- engine = self,
- }
- local citation_str = self.style:render_citation(items, context)
-
- self.registry.citation_strings[citation_id] = citation_str
- table.insert(output, {i - 1, citation_str, citation_id})
+ if not ir_.year_suffix_irs then
+ ir_.year_suffix_irs = self:collect_year_suffix_irs(ir_)
+ if #ir_.year_suffix_irs == 0 then
+ -- By default, the year-suffix is appended the first year rendered through cs:date
+ local year_ir = self:find_first_year_ir(ir_)
+ -- util.debug(year_ir)
+ if year_ir then
+ local year_suffix_ir = YearSuffix:new({}, self.style.citation)
+ table.insert(year_ir.children, year_suffix_ir)
+ table.insert(ir_.year_suffix_irs, year_suffix_ir)
+ end
+ end
+ end
+
+ for _, year_suffix_ir in ipairs(ir_.year_suffix_irs) do
+ year_suffix_ir.inlines = {PlainText:new(ir_.reference["year-suffix"])}
+ year_suffix_ir.year_suffix_number = ir_.reference.year_suffix_number
+ year_suffix_ir.group_var = "important"
+ end
+
+ local inlines = ir_:flatten(disam_format)
+ local disam_str = disam_format:output(inlines, context)
+ -- util.debug("update: " .. ir_.cite_item.id .. ": " .. disam_str)
+ ir_.disam_str = disam_str
+ if not self.cite_irs_by_output[disam_str] then
+ self.cite_irs_by_output[disam_str] = {}
+ end
+ self.cite_irs_by_output[disam_str][ir_.ir_index] = ir_
+
+ end
+
+ cite_ir.is_ambiguous = false
+
+ return cite_ir
+end
+
+function CiteProc:collect_year_suffix_irs(ir)
+ local year_suffix_irs = {}
+ if ir.children then
+ for i, child_ir in ipairs(ir.children) do
+ if child_ir._type == "YearSuffix" then
+ table.insert(year_suffix_irs, child_ir)
+ elseif child_ir.children then
+ util.extend(year_suffix_irs,
+ self:collect_year_suffix_irs(child_ir))
+ end
+ end
+ end
+ return year_suffix_irs
+end
+
+function CiteProc:find_first_year_ir(ir)
+ if ir.is_year then
+ return ir
+ end
+ if ir.children then
+ for _, child_ir in ipairs(ir.children) do
+ local year_ir = self:find_first_year_ir(child_ir)
+ if year_ir then
+ return year_ir
+ end
+ end
+ end
+ return nil
+end
+
+function CiteProc:render_year_suffix(year_suffix_number)
+ if year_suffix_number <= 0 then
+ return nil
+ end
+ local year_suffix = ""
+ while year_suffix_number > 0 do
+ local i = (year_suffix_number - 1) % 26
+ year_suffix = string.char(i + 97) .. year_suffix
+ year_suffix_number = (year_suffix_number - 1) // 26
+ end
+ -- util.debug(year_suffix)
+ return year_suffix
+end
+
+local function find_first(ir, check)
+ if check(ir) then
+ return ir
+ end
+ if ir.children then
+ for _, child in ipairs(ir.children) do
+ local target_ir = find_first(child, check)
+ if target_ir then
+ return target_ir
+ end
+ end
+ end
+ return nil
+end
+
+function CiteProc:group_cites(irs)
+ local disam_format = DisamStringFormat:new()
+ for _, ir in ipairs(irs) do
+ local first_names_ir = ir.first_names_ir
+ if not first_names_ir then
+ first_names_ir = find_first(ir, function (ir_)
+ return ir_._element == "names"
+ end)
+ if first_names_ir then
+ local inlines = first_names_ir:flatten(disam_format)
+ first_names_ir.disam_str = disam_format:output(inlines, context)
+ end
+ ir.first_names_ir = first_names_ir
+ end
+ end
+
+ local irs_by_name = {}
+ local name_list = {}
+
+ for _, ir in ipairs(irs) do
+ local name_str = ""
+ if ir.first_names_ir then
+ name_str = ir.first_names_ir.disam_str
+ end
+ if not irs_by_name[name_str] then
+ irs_by_name[name_str] = {}
+ table.insert(name_list, name_str)
+ end
+ table.insert(irs_by_name[name_str], ir)
+ end
+
+ local grouped = {}
+ for _, name_str in ipairs(name_list) do
+ local irs_with_same_name = irs_by_name[name_str]
+ for i, ir in ipairs(irs_with_same_name) do
+ if i < #irs_with_same_name then
+ ir.own_delimiter = self.style.citation.cite_group_delimiter
+ end
+ table.insert(grouped, ir)
+ end
+ end
+ return grouped
+end
+
+function CiteProc:collapse_cites(irs)
+ if self.style.citation.collapse == "citation-number" then
+ self:collapse_cites_by_citation_number(irs)
+ elseif self.style.citation.collapse == "year" then
+ self:collapse_cites_by_year(irs)
+ elseif self.style.citation.collapse == "year-suffix" then
+ self:collapse_cites_by_year_suffix(irs)
+ elseif self.style.citation.collapse == "year-suffix-ranged" then
+ self:collapse_cites_by_year_suffix_ranged(irs)
+ end
+end
+
+function CiteProc:collapse_cites_by_citation_number(irs)
+ local cite_groups = {}
+ local current_group = {}
+ local previous_citation_number
+ for i, ir in ipairs(irs) do
+ local citation_number
+ local only_citation_number_ir = self:get_only_citation_number(ir)
+ if only_citation_number_ir then
+ -- Other irs like locators are not rendered.
+ -- collapse_CitationNumberRangesWithAffixesGrouped.txt
+ citation_number = only_citation_number_ir.citation_number
+ end
+ if i == 1 then
+ table.insert(current_group, ir)
+ elseif citation_number and previous_citation_number and
+ previous_citation_number + 1 == citation_number then
+ table.insert(current_group, ir)
else
- -- TODO: correct note_index
- -- TODO: update other citations after disambiguation
- local citation_str = self.registry.citation_strings[citation_id]
- if self.registry.citation_strings[citation_id] ~= citation_str then
- params.bibchange = true
- self.registry.citation_strings[citation_id] = citation_str
- table.insert(output, {i - 1, citation_str, citation_id})
+ table.insert(cite_groups, current_group)
+ current_group = {ir}
+ end
+ previous_citation_number = citation_number
+ end
+ table.insert(cite_groups, current_group)
+
+ for _, cite_group in ipairs(cite_groups) do
+ if #cite_group >= 3 then
+ cite_group[1].own_delimiter = util.unicode["en dash"]
+ for i = 2, #cite_group - 1 do
+ cite_group[i].collapse_suppressed = true
end
+ cite_group[#cite_group].own_delimiter = self.style.citation.after_collapse_delimiter
end
end
+end
- return {params, output}
+function CiteProc:get_only_citation_number(ir)
+ if ir.citation_number then
+ return ir
+ end
+ if not ir.children then
+ return nil
+ end
+ local only_citation_number_ir
+ for _, child in ipairs(ir.children) do
+ if child.group_var ~= "missing" then
+ local citation_number_ir = self:get_only_citation_number(child)
+ if citation_number_ir then
+ if only_citation_number_ir then
+ return nil
+ else
+ only_citation_number_ir = citation_number_ir
+ end
+ else
+ return false
+ end
+ end
+ end
+ return only_citation_number_ir
end
-function CiteProc:makeCitationCluster (citation_items)
+function CiteProc:collapse_cites_by_year(irs)
+ local cite_groups = {{}}
+ local previous_name_str
+ for i, ir in ipairs(irs) do
+ local name_str
+ if ir.first_names_ir then
+ name_str = ir.first_names_ir.disam_str
+ end
+ if i == 1 then
+ table.insert(cite_groups[#cite_groups], ir)
+ elseif name_str and name_str == previous_name_str then
+ -- ir.fist_names_ir was set in the cite grouping stage
+ -- TODO: and not previous cite suffix
+ table.insert(cite_groups[#cite_groups], ir)
+ else
+ table.insert(cite_groups, {ir})
+ end
+ previous_name_str = name_str
+ end
+
+ for _, cite_group in ipairs(cite_groups) do
+ if #cite_group > 1 then
+ for i, cite_ir in ipairs(cite_group) do
+ if i > 1 and cite_ir.first_names_ir then
+ cite_ir.first_names_ir.collapse_suppressed = true
+ end
+ if i == #cite_group then
+ cite_ir.own_delimiter = self.style.citation.after_collapse_delimiter
+ elseif i < #cite_group then
+ -- The delimiter depends on the citation > sort.
+ -- https://github.com/citation-style-language/test-suite/issues/39#issuecomment-687901688
+ if cite_ir.cite_item.locator then
+ -- Special hack for
+ cite_ir.own_delimiter = self.style.citation.after_collapse_delimiter
+ elseif self.style.citation.cite_grouping then
+ if self.style.citation.sort then
+ cite_ir.own_delimiter = self.style.citation.cite_group_delimiter
+ else
+ cite_ir.own_delimiter = self.style.citation.layout.delimiter
+ end
+ else
+ if self.style.citation.sort then
+ cite_ir.own_delimiter = self.style.citation.cite_group_delimiter
+ else
+ -- disambiguate_YearCollapseWithInstitution.txt
+ -- disambiguate_InitializeWithButNoDisambiguation.txt ?
+ cite_ir.own_delimiter = self.style.citation.layout.delimiter
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function find_rendered_year_suffix(ir)
+ if ir._type == "YearSuffix" then
+ return ir
+ end
+ if ir.children then
+ for _, child in ipairs(ir.children) do
+ if child.group_var ~= "missing" then
+ local year_suffix = find_rendered_year_suffix(child)
+ if year_suffix then
+ return year_suffix
+ end
+ end
+ end
+ end
+ return nil
+end
+
+function CiteProc:collapse_cites_by_year_suffix(irs)
+ self:collapse_cites_by_year(irs)
+ -- Group by disam_str
+ -- The year-suffix is ommitted in DisamStringFormat
+ local cite_groups = {{}}
+ local previous_ir
+ local previous_year_suffix
+ for i, ir in ipairs(irs) do
+ local year_suffix = find_rendered_year_suffix(ir)
+ ir.rendered_year_suffix_ir = year_suffix
+ if i == 1 then
+ table.insert(cite_groups[#cite_groups], ir)
+ elseif year_suffix and previous_ir.disam_str == ir.disam_str and previous_year_suffix then
+ -- TODO: and not previous cite suffix
+ table.insert(cite_groups[#cite_groups], ir)
+ else
+ table.insert(cite_groups, {ir})
+ end
+ previous_ir = ir
+ previous_year_suffix = year_suffix
+ end
+
+ for _, cite_group in ipairs(cite_groups) do
+ if #cite_group > 1 then
+ for i, cite_ir in ipairs(cite_group) do
+ if i > 1 then
+ -- cite_ir.children = {cite_ir.rendered_year_suffix_ir}
+ -- Set the collapse_suppressed flag rather than removing the child irs.
+ -- This leaves the disamb ir structure unchanged.
+ self:suppress_ir_except_child(cite_ir, cite_ir.rendered_year_suffix_ir)
+ end
+ if i < #cite_group then
+ if self.style.citation.cite_grouping then
+ -- In the current citeproc-js impplementation, explicitly set
+ -- cite-group-delimiter takes precedence over year-suffix-delimiter.
+ -- May be changed in the future.
+ -- https://github.com/citation-style-language/test-suite/issues/50
+ cite_ir.own_delimiter = self.style.citation.cite_group_delimiter
+ else
+ cite_ir.own_delimiter = self.style.citation.year_suffix_delimiter
+ end
+ elseif i == #cite_group then
+ cite_ir.own_delimiter = self.style.citation.after_collapse_delimiter
+ end
+ end
+ end
+ end
+end
+
+function CiteProc:suppress_ir_except_child(ir, target)
+ if ir == target then
+ ir.collapse_suppressed = false
+ return false
+ end
+ ir.collapse_suppressed = true
+ if ir.children then
+ for _, child in ipairs(ir.children) do
+ if child.group_var ~= "missing" and not child.collapse_suppressed then
+ if not self:suppress_ir_except_child(child, target) then
+ ir.collapse_suppressed = false
+ end
+ end
+ end
+ end
+ return ir.collapse_suppressed
+end
+
+function CiteProc:collapse_cites_by_year_suffix_ranged(irs)
+ self:collapse_cites_by_year_suffix(irs)
+ -- Group by disam_str
+ local cite_groups = {{}}
+ local previous_ir
+ local previous_year_suffix
+ for i, ir in ipairs(irs) do
+ local year_suffix_ir = find_rendered_year_suffix(ir)
+ ir.rendered_year_suffix_ir = year_suffix_ir
+ if i == 1 then
+ table.insert(cite_groups[#cite_groups], ir)
+ elseif year_suffix_ir and previous_ir.disam_str == ir.disam_str and previous_year_suffix and
+ year_suffix_ir.year_suffix_number == previous_year_suffix.year_suffix_number + 1 then
+ -- TODO: and not previous cite suffix
+ table.insert(cite_groups[#cite_groups], ir)
+ else
+ table.insert(cite_groups, {ir})
+ end
+ previous_ir = ir
+ previous_year_suffix = year_suffix_ir
+ end
+
+ for _, cite_group in ipairs(cite_groups) do
+ if #cite_group > 2 then
+ for i, cite_ir in ipairs(cite_group) do
+ if i == 1 then
+ cite_ir.own_delimiter = util.unicode["en dash"]
+ elseif i < #cite_group then
+ cite_ir.collapse_suppressed = true
+ end
+ end
+ end
+ end
+end
+
+function CiteProc:makeCitationCluster(citation_items)
local items = {}
- for _, cite_item in ipairs(citation_items) do
+ for i, cite_item in ipairs(citation_items) do
cite_item.id = tostring(cite_item.id)
- local position_first = (self.registry.registry[cite_item.id] == nil)
local item_data = self:get_item(cite_item.id)
-- Create a wrapper of the orignal item from registry so that
-- it may hold different `locator` or `position` values for cites.
- local item = setmetatable({}, {__index = function (_, key)
- if cite_item[key] then
- return cite_item[key]
- else
- return item_data[key]
+ local item = setmetatable(cite_item, {__index = item_data})
+
+ -- Use "page" as locator label if missing
+ -- label_PluralWithAmpersand.txt
+ if item.locator and not item.label then
+ item.label = "page"
+ end
+
+ item.position_level = util.position_map["first"]
+ if self.cite_first_note_numbers[cite_item.id] then
+ item.position_level = util.position_map["subsequent"]
+ else
+ self.cite_first_note_numbers[cite_item.id] = 0
+ end
+
+ local preceding_cite
+ if i == 1 then
+ local previous_citation = self.registry.previous_citation
+ if previous_citation then
+ if #previous_citation.citationItems == 1 and previous_citation.citationItems[1].id == item.id then
+ preceding_cite = previous_citation.citationItems[1]
+ end
end
- end})
+ elseif citation_items[i - 1].id == item.id then
+ preceding_cite = citation_items[i - 1]
+ end
- if not item.position and position_first then
- item.position = util.position_map["first"]
+ if preceding_cite then
+ item.position_level = self:_get_cite_position(item, preceding_cite)
end
+
table.insert(items, item)
end
@@ -242,134 +1620,252 @@ function CiteProc:makeCitationCluster (citation_items)
self:sort_bibliography()
end
- local context = {
- build = {},
- engine=self,
- }
- local res = self.style:render_citation(items, context)
+ local res = self:build_cluster(items)
+
+ -- local context = {
+ -- build = {},
+ -- engine=self,
+ -- }
+ -- local res = self.style:render_citation(items, context)
+
self.registry.previous_citation = {
citationID = "pseudo-citation",
citationItems = items,
properties = {
- noteIndex = 1,
+ noteIndex = 0,
}
}
return res
end
function CiteProc:makeBibliography()
- local items = {}
+ if not self.style.bibliography then
+ return {{}, {}}
+ end
+
+ local output_format = self.output_format
+
+ local res = {}
+
+ self.registry.longest_label = ""
+ self.registry.maxoffset = 0
+
+ for _, id in ipairs(self:get_sorted_refs()) do
+ local ref = self.registry.registry[id]
+
+ local state = IrState:new()
+ local context = Context:new()
+ context.engine = self
+ context.style = self.style
+ context.area = self.style.bibliography
+ context.in_bibliography = true
+ context.locale = self:get_locale(self.lang)
+ context.name_inheritance = self.style.bibliography.name_inheritance
+ context.format = output_format
+ context.id = id
+ context.cite = nil
+ context.reference = self:get_item(id)
+
+ local ir = self.style.bibliography:build_ir(self, state, context)
+ -- util.debug(ir)
+ ir.reference = context.reference
+
+ -- Add year-suffix
+ self:add_bibliography_year_suffix(ir)
+
+ -- The layout output may be empty: sort_OmittedBibRefNonNumericStyle.txt
+ if ir then
+ local flat = ir:flatten(output_format)
+ local str = output_format:output_bibliography_entry(flat, context)
+ table.insert(res, str)
+ end
+ end
+
+ local bib_start = self.output_format.markups["bibstart"]
+ local bib_end = self.output_format.markups["bibend"]
+ if type(bib_start) == "function" then
+ bib_start = bib_start(self)
+ end
+ if type(bib_end) == "function" then
+ bib_end = bib_end(self)
+ end
+
+ local params = {
+ hangingindent = self.style.bibliography.hanging_indent,
+ ["second-field-align"] = self.style.bibliography.second_field_align ~= nil,
+ linespacing = self.style.bibliography.line_spacing,
+ entryspacing = self.style.bibliography.entry_spacing,
+ maxoffset = self.registry.maxoffset,
+ bibstart = bib_start,
+ bibend = bib_end,
+ entry_ids = util.clone(self.registry.reflist),
+ }
+ return {params, res}
+end
+
+function CiteProc:get_sorted_refs()
if self.registry.requires_sorting then
self:sort_bibliography()
end
+ return self.registry.reflist
+end
- for _, id in ipairs(self.registry.reflist) do
- local item = self.registry.registry[id]
- table.insert(items, item)
+function CiteProc:add_bibliography_year_suffix(ir)
+ if not ir.reference.year_suffix_number then
+ return
end
- local context = {
- build = {},
- engine=self,
- }
- local res = self.style:render_biblography(items, context)
- return res
+ local year_suffix_number = ir.reference.year_suffix_number
+
+ if not ir.year_suffix_irs then
+ ir.year_suffix_irs = self:collect_year_suffix_irs(ir)
+ if #ir.year_suffix_irs == 0 then
+ local year_ir = self:find_first_year_ir(ir)
+ -- util.debug(year_ir)
+ if year_ir then
+ local year_suffix_ir = YearSuffix:new({}, self.style.citation)
+ table.insert(year_ir.children, year_suffix_ir)
+ table.insert(ir.year_suffix_irs, year_suffix_ir)
+ end
+ end
+ end
+
+ for _, year_suffix_ir in ipairs(ir.year_suffix_irs) do
+ year_suffix_ir.inlines = {PlainText:new(ir.reference["year-suffix"])}
+ year_suffix_ir.group_var = "important"
+ end
+
+
end
-function CiteProc:set_formatter(format)
- self.formatter = formats[format]
+function CiteProc:set_output_format(format)
+ if format == "latex" then
+ self.output_format = LatexWriter:new()
+ elseif format == "html" then
+ self.output_format = HtmlWriter:new()
+ end
end
function CiteProc:enable_linking()
- self.linking_enabled = true
+ self.opt.url_link = true
+ self.opt.doi_link = true
end
function CiteProc:disable_linking()
- self.linking_enabled = false
+ self.opt.url_link = false
+ self.opt.doi_link = false
end
-function CiteProc.set_base_class (node)
- if node:is_element() then
- local name = node:get_element_name()
- local element_class = nodes[name]
- if element_class then
- element_class:set_base_class(node)
- else
- element.Element:set_base_class(node)
+function CiteProc.create_element_tree(node)
+ local element_name = node:get_element_name()
+ local element_class = nodes[element_name]
+ local el = nil
+ if element_class then
+ el = element_class:from_node(node)
+ end
+ if el then
+ for i, child in ipairs(node:get_children()) do
+ if child:is_element() then
+ local child_element = CiteProc.create_element_tree(child)
+ if child_element then
+ if not el.children then
+ el.children = {}
+ end
+ table.insert(el.children, child_element)
+ end
+ end
end
end
+ return el
end
-function CiteProc:get_style_class()
- return self.style:get_attribute("class") or "in-text"
-end
-
-function CiteProc:get_item (id)
+function CiteProc:get_item(id)
local item = self.registry.registry[id]
if not item then
item = self:_retrieve_item(id)
if not item then
return nil
end
+ item = self:process_extra_note(item)
table.insert(self.registry.reflist, id)
item["citation-number"] = #self.registry.reflist
self.registry.registry[id] = item
self.registry.requires_sorting = true
end
- local res = {}
- setmetatable(res, {__index = item})
- return res
+ -- local res = {}
+ -- setmetatable(res, {__index = item})
+ -- return res
+ return item
end
-function CiteProc:_retrieve_item (id)
+function CiteProc:_retrieve_item(id)
-- Retrieve, copy, and normalize
local res = {}
local item = self.sys.retrieveItem(id)
if not item then
- util.warning(string.format('Failed to retrieve item "%s"', id))
+ util.warning(string.format('Failed to find entry "%s"', id))
return nil
end
item.id = tostring(item.id)
for key, value in pairs(item) do
- if key == "title" then
- value = self.normalize_string(value)
- end
res[key] = value
end
- if res["page"] and not res["page-first"] then
- local page_first = util.split(res["page"], "%s*[&,-]%s*")[1]
- page_first = util.split(page_first, util.unicode["en dash"])[1]
- res["page-first"] = page_first
- end
+ -- if res["page"] and not res["page-first"] then
+ -- local page_first = util.split(res["page"], "%s*[&,-]%s*")[1]
+ -- page_first = util.split(page_first, util.unicode["en dash"])[1]
+ -- res["page-first"] = page_first
+ -- end
return res
end
-function CiteProc.normalize_string (str)
- if not str or str == "" then
- return str
- end
- -- French punctuation spacing
- if type(str) == "string" then
- str = string.gsub(str, " ;", util.unicode["narrow no-break space"] .. ";")
- str = string.gsub(str, " %?", util.unicode["narrow no-break space"] .. "?")
- str = string.gsub(str, " !", util.unicode["narrow no-break space"] .. "!")
- str = string.gsub(str, " »", util.unicode["narrow no-break space"] .. "»")
- str = string.gsub(str, "« ", "«" .. util.unicode["narrow no-break space"])
+-- TODO: Nomalize all inputs
+function CiteProc:process_extra_note(item)
+ if item.note then
+ local note_fields = {}
+ for _, line in ipairs(util.split(item.note, "%s*\r?\n%s*")) do
+ -- util.debug(line)
+ local splits = util.split(line, ":%s+", 1)
+ -- util.debug(splits)
+ if #splits == 2 then
+ local field, value = table.unpack(splits)
+ -- util.debug(field)
+
+ local variable_type = util.variable_types[field]
+ if not item[field] or field == "type" or variable_type == "date" then
+ if variable_type == "number" then
+ item[field] = value
+ elseif variable_type == "date" then
+ item[field] = util.parse_iso_date(value)
+ elseif variable_type == "name" then
+ if not note_fields[field] then
+ note_fields[field] = {}
+ end
+ table.insert(note_fields[field], util.parse_extra_name(value))
+ else
+ item[field] = value
+ end
+ end
+ end
+ end
+ for field, value in pairs(note_fields) do
+ item[field] = value
+ end
end
- -- local text = str
- local text = richtext.new(str)
- return text
+ return item
end
function CiteProc:sort_bibliography()
-- Sort the items in registry according to the `sort` in `bibliography.`
-- This will update the `citation-number` of each item.
- local bibliography_sort = self.style:get_path("style bibliography sort")[1]
+ local bibliography_sort = nil
+ if self.style.bibliography and self.style.bibliography.sort then
+ bibliography_sort = self.style.bibliography.sort
+ end
if not bibliography_sort then
return
end
@@ -378,44 +1874,119 @@ function CiteProc:sort_bibliography()
table.insert(items, self.registry.registry[id])
end
- local context = {
- engine = self,
- style = self.style,
- mode = "bibliography",
- }
- context = self.style:process_context(context)
- context = self.style:get_path("style bibliography")[1]:process_context(context)
+ local state = IrState:new()
+ local context = Context:new()
+ context.engine = self
+ context.style = self.style
+ context.area = self.style.bibliography
+ context.in_bibliography = true
+ context.locale = self:get_locale(self.lang)
+ context.name_inheritance = self.style.bibliography.name_inheritance
+ context.format = SortStringFormat:new()
+ -- context.id = id
+ context.cite = nil
+ -- context.reference = self:get_item(id)
- bibliography_sort:sort(items, context)
+ bibliography_sort:sort(items, state, context)
self.registry.reflist = {}
+ self.tainted_item_ids = {}
for i, item in ipairs(items) do
+ if item["citation-number"] ~= i then
+ self.tainted_item_ids[item.id] = true
+ end
item["citation-number"] = i
- table.insert(self.registry.reflist, item.id)
+ self.registry.reflist[i] = item.id
end
self.registry.requires_sorting = false
end
-function CiteProc:get_system_locale (lang)
+function CiteProc:get_locale(lang)
+ if string.len(lang) == 2 then
+ lang = util.primary_dialects[lang] or lang
+ end
+ local locale = self.locales[lang]
+ if locale then
+ return locale
+ else
+ return self:get_merged_locales(lang)
+ end
+end
+
+function CiteProc:get_merged_locales(lang)
+ local fall_back_locales = {}
+
+ local language = string.sub(lang, 1, 2)
+ local primary_dialect = util.primary_dialects[language]
+
+ -- 1. In-style cs:locale elements
+ -- i. `xml:lang` set to chosen dialect, “de-AT”
+ table.insert(fall_back_locales, self.style.locales[lang])
+
+ -- ii. `xml:lang` set to matching language, “de” (German)
+ if language and language ~= lang then
+ table.insert(fall_back_locales, self.style.locales[language])
+ end
+
+ -- iii. `xml:lang` not set
+ table.insert(fall_back_locales, self.style.locales["@generic"])
+
+ -- 2. Locale files
+ -- iv. `xml:lang` set to chosen dialect, “de-AT”
+ if lang then
+ table.insert(fall_back_locales, self:get_system_locale(lang))
+ end
+
+ -- v. `xml:lang` set to matching primary dialect, “de-DE” (Standard German)
+ -- (only applicable when the chosen locale is a secondary dialect)
+ if primary_dialect and primary_dialect ~= lang then
+ table.insert(fall_back_locales, self:get_system_locale(primary_dialect))
+ end
+
+ -- vi. `xml:lang` set to “en-US” (American English)
+ if lang ~= "en-US" and primary_dialect ~= "en-US" then
+ table.insert(fall_back_locales, self:get_system_locale("en-US"))
+ end
+
+ -- Merge locales
+
+ local locale = Locale:new()
+ for i = #fall_back_locales, 1, -1 do
+ local fall_back_locale = fall_back_locales[i]
+ locale:merge(fall_back_locale)
+ end
+
+ self.locales[lang] = locale
+ return locale
+end
+
+function CiteProc:get_system_locale(lang)
local locale = self.system_locales[lang]
- if not locale then
- locale = self.sys.retrieveLocale(lang)
- if not locale then
- util.warning(string.format("Failed to retrieve locale \"%s\"", lang))
- return nil
- end
- if type(locale) == "string" then
- locale = dom.parse(locale)
- end
- locale:traverse_elements(self.set_base_class)
- locale = locale:get_path("locale")[1]
- locale:root_node().engine = self
- locale:root_node().style = self.style
- self.system_locales[lang] = locale
+ if locale then
+ return locale
+ end
+
+ local locale_str = self.sys.retrieveLocale(lang)
+ if not locale_str then
+ util.warning(string.format("Failed to retrieve locale \"%s\"", lang))
+ return nil
end
+ local locale_xml = dom.parse(locale_str)
+ local root_element = locale_xml:get_path("locale")[1]
+ locale = Locale:from_node(root_element)
+ self.system_locales[lang] = locale
return locale
end
+function CiteProc:get_style_class()
+ if self.style and self.style.class then
+ return self.style.class
+ else
+ return nil
+ end
+end
+
+
engine.CiteProc = CiteProc
return engine
diff --git a/biblio/citation-style-language/citeproc-formats.lua b/biblio/citation-style-language/citeproc-formats.lua
deleted file mode 100644
index fd9621936c..0000000000
--- a/biblio/citation-style-language/citeproc-formats.lua
+++ /dev/null
@@ -1,211 +0,0 @@
---
--- Copyright (c) 2021-2022 Zeping Lee
--- Released under the MIT license.
--- Repository: https://github.com/zepinglee/citeproc-lua
---
-
-local util = require("citeproc-util")
-
-
-local formats = {}
-
-formats.html = {
- ["text_escape"] = function (str)
- str = string.gsub(str, "%&", "&#38;")
- str = string.gsub(str, "<", "&#60;")
- str = string.gsub(str, ">", "&#62;")
- for char, sub in pairs(util.superscripts) do
- str = string.gsub(str, char, "<sup>" .. sub .. "</sup>")
- end
- return str
- end,
- ["bibstart"] = "<div class=\"csl-bib-body\">\n",
- ["bibend"] = "</div>",
- ["@font-style/italic"] = "<i>%s</i>",
- ["@font-style/oblique"] = "<em>%s</em>",
- ["@font-style/normal"] = '<span style="font-style:normal;">%s</span>',
- ["@font-variant/small-caps"] = '<span style="font-variant:small-caps;">%s</span>',
- ["@font-variant/normal"] = '<span style="font-variant:normal;">%s</span>',
- ["@font-weight/bold"] = "<b>%s</b>",
- ["@font-weight/normal"] = '<span style="font-weight:normal;">%s</span>',
- ["@font-weight/light"] = false,
- ["@text-decoration/none"] = '<span style="text-decoration:none;">%s</span>',
- ["@text-decoration/underline"] = '<span style="text-decoration:underline;">%s</span>',
- ["@vertical-align/sup"] = "<sup>%s</sup>",
- ["@vertical-align/sub"] = "<sub>%s</sub>",
- ["@vertical-align/baseline"] = '<span style="baseline">%s</span>',
- ["@quotes/true"] = function (str, context)
- local open_quote = context.style:get_term("open-quote"):render(context)
- local close_quote = context.style:get_term("close-quote"):render(context)
- return open_quote .. str .. close_quote
- end,
- ["@quotes/inner"] = function (str, context)
- local open_quote = context.style:get_term("open-inner-quote"):render(context)
- local close_quote = context.style:get_term("close-inner-quote"):render(context)
- return open_quote .. str .. close_quote
- end,
- ["@bibliography/entry"] = function (str, context)
- return '<div class="csl-entry">' .. str .. "</div>\n"
- end,
- ["@display/block"] = function (str, state)
- return '\n\n <div class="csl-block">' .. str .. "</div>\n"
- end,
- ["@display/left-margin"] = function (str, state)
- return '\n <div class="csl-left-margin">' .. str .. "</div>"
- end,
- ["@display/right-inline"] = function (str, state)
- str = util.rstrip(str)
- return '<div class="csl-right-inline">' .. str .. "</div>\n "
- end,
- ["@display/indent"] = function (str, state)
- return '<div class="csl-indent">' .. str .. "</div>\n "
- end,
- ["@URL/true"] = function (str, state)
- if state.engine.linking_enabled then
- return string.format('<a href="%s">%s</a>', str, str)
- else
- return str
- end
- end,
- ["@DOI/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://doi.org/" .. str;
- end
- return string.format('<a href="%s">%s</a>', href, str)
- else
- return str
- end
- end,
- ["@PMID/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://www.ncbi.nlm.nih.gov/pubmed/" .. str;
- end
- return string.format('<a href="%s">%s</a>', href, str)
- else
- return str
- end
- end,
- ["@PMCID/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://www.ncbi.nlm.nih.gov/pmc/articles/" .. str;
- end
- return string.format('<a href="%s">%s</a>', href, str)
- else
- return str
- end
- end,
-}
-
-formats.latex = {
- ["text_escape"] = function (str)
- str = str:gsub("\\", "\\textbackslash")
- str = str:gsub("#", "\\#")
- str = str:gsub("%$", "\\$")
- str = str:gsub("%%", "\\%%")
- str = str:gsub("&", "\\&")
- str = str:gsub("{", "\\{")
- str = str:gsub("}", "\\}")
- str = str:gsub("_", "\\_")
- str = str:gsub(util.unicode["no-break space"], "~")
- for char, sub in pairs(util.superscripts) do
- str = string.gsub(str, char, "\\textsuperscript{" .. sub .. "}")
- end
- return str
- end,
- ["bibstart"] = function (context)
- return string.format("\\begin{thebibliography}{%s}\n", context.build.longest_label)
- end,
- ["bibend"] = "\\end{thebibliography}",
- ["@font-style/normal"] = "{\\normalshape %s}",
- ["@font-style/italic"] = "\\emph{%s}",
- ["@font-style/oblique"] = "\\textsl{%s}",
- ["@font-variant/normal"] = "{\\normalshape %s}",
- ["@font-variant/small-caps"] = "\\textsc{%s}",
- ["@font-weight/normal"] = "\\fontseries{m}\\selectfont %s",
- ["@font-weight/bold"] = "\\textbf{%s}",
- ["@font-weight/light"] = "\\fontseries{l}\\selectfont %s",
- ["@text-decoration/none"] = false,
- ["@text-decoration/underline"] = "\\underline{%s}",
- ["@vertical-align/sup"] = "\\textsuperscript{%s}",
- ["@vertical-align/sub"] = "\\textsubscript{%s}",
- ["@vertical-align/baseline"] = false,
- ["@quotes/true"] = function (str, context)
- local open_quote = context.style:get_term("open-quote"):render(context)
- local close_quote = context.style:get_term("close-quote"):render(context)
- return open_quote .. str .. close_quote
- end,
- ["@quotes/inner"] = function (str, context)
- local open_quote = context.style:get_term("open-inner-quote"):render(context)
- local close_quote = context.style:get_term("close-inner-quote"):render(context)
- return open_quote .. str .. close_quote
- end,
- ["@bibliography/entry"] = function (str, context)
- if not string.match(str, "\\bibitem") then
- str = "\\bibitem{".. context.item.id .. "}\n" .. str
- end
- return str .. "\n"
- end,
- ["@display/block"] = function (str, state)
- return str
- end,
- ["@display/left-margin"] = function (str, state)
- if #str > #state.build.longest_label then
- state.build.longest_label = str
- end
- if string.match(str, "%]") then
- str = "{" .. str .. "}"
- end
- return string.format("\\bibitem[%s]{%s}\n", str, state.item.id)
- end,
- ["@display/right-inline"] = function (str, state)
- return str
- end,
- ["@display/indent"] = function (str, state)
- return str
- end,
- ["@URL/true"] = function (str, state)
- return "\\url{" .. str .. "}"
- end,
- ["@DOI/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://doi.org/" .. str;
- end
- return string.format("\\href{%s}{%s}", href, str)
- else
- return str
- end
- end,
- ["@PMID/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://www.ncbi.nlm.nih.gov/pubmed/" .. str;
- end
- return string.format("\\href{%s}{%s}", href, str)
- else
- return str
- end
- end,
- ["@PMCID/true"] = function (str, state)
- if state.engine.linking_enabled then
- local href = str
- if not string.match(href, "^https?://") then
- href = "https://www.ncbi.nlm.nih.gov/pmc/articles/" .. str;
- end
- return string.format("\\href{%s}{%s}", href, str)
- else
- return str
- end
- end,
-}
-
-
-return formats
diff --git a/biblio/citation-style-language/citeproc-ir-node.lua b/biblio/citation-style-language/citeproc-ir-node.lua
new file mode 100644
index 0000000000..01cca4abf6
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-ir-node.lua
@@ -0,0 +1,153 @@
+--
+-- Copyright (c) 2021-2022 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+local irnode = {}
+
+local util = require("citeproc-util")
+
+
+local IrNode = {
+ _element = nil,
+ _type = "IrNode",
+ _base_class = "IrNode",
+ text = nil,
+ formatting = nil,
+ affixes = nil,
+ children = nil,
+ delimiter = nil,
+}
+
+function IrNode:new(children, element)
+ local o = {
+ _element = element.element_name,
+ _type = self._type,
+ children = children,
+ group_var = "plain",
+ }
+
+ o.group_var = "missing"
+ for _, child_ir in ipairs(children) do
+ if child_ir.group_var == "important" then
+ o.group_var = "important"
+ break
+ elseif child_ir.group_var == "plain" then
+ o.group_var = "plain"
+ end
+ end
+
+ o.person_name_irs = {}
+ if children then
+ for _, child in ipairs(children) do
+ if child.person_name_irs then
+ util.extend(o.person_name_irs, child.person_name_irs)
+ end
+ end
+ end
+
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function IrNode:derive(type)
+ local o = {
+ _type = type,
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function IrNode:flatten(format)
+ return format:flatten_ir(self)
+end
+
+function IrNode:capitalize_first_term()
+ -- util.debug(self)
+ if self._type == "Rendered" and self.element and (self.element.term == "ibid" or self.element.term == "and") then
+ self.inlines[1]:capitalize_first_term()
+ elseif self._type == "SeqIr" and self.children[1] then
+ self.children[1]:capitalize_first_term()
+ end
+end
+
+
+
+local Rendered = IrNode:derive("Rendered")
+
+function Rendered:new(inlines, element)
+ local o = {
+ _element = element.element_name,
+ _type = self._type,
+ element = element, -- required for capitalizing first term
+ inlines = inlines,
+ group_var = "plain",
+ }
+
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+
+local YearSuffix = IrNode:derive("YearSuffix")
+
+function YearSuffix:new(inlines, element)
+ local o = {
+ _element = element.element_name,
+ _type = self._type,
+ element = element,
+ inlines = inlines,
+ group_var = "plain",
+ }
+
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+
+local NameIr = IrNode:derive("NameIr")
+
+
+local PersonNameIr = IrNode:derive("PersonNameIr")
+
+function PersonNameIr:new(inlines, element)
+ local o = {
+ _element = element.element_name,
+ _type = self._type,
+ inlines = inlines,
+ group_var = "plain",
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+
+local SeqIr = IrNode:derive("SeqIr")
+
+-- function SeqIr:new(children)
+-- o = IrNode.new(self, children)
+-- local o = {
+-- children = children,
+-- group_var = "plain",
+-- }
+-- setmetatable(o, self)
+-- self.__index = self
+-- return o
+-- end
+
+
+
+irnode.IrNode = IrNode
+irnode.Rendered = Rendered
+irnode.YearSuffix = YearSuffix
+irnode.NameIr = NameIr
+irnode.PersonNameIr = PersonNameIr
+irnode.SeqIr = SeqIr
+
+return irnode
diff --git a/biblio/citation-style-language/csl-core.lua b/biblio/citation-style-language/citeproc-latex-core.lua
index e4e2fed32e..0be2381797 100644
--- a/biblio/citation-style-language/csl-core.lua
+++ b/biblio/citation-style-language/citeproc-latex-core.lua
@@ -12,8 +12,7 @@ require("lualibs")
core.locale_file_format = "csl-locales-%s.xml"
-core.ids = {}
-core.loaded_ids = {}
+core.uncited_ids = {}
core.uncite_all_items = false
function core.error(message)
@@ -112,9 +111,10 @@ local function read_data_files(data_files)
for _, item in ipairs(csl_items) do
local id = item.id
if bib[id] then
- core.error(string.format('Duplicate entry key "%s" in "%s".', id, file_name))
+ core.warning(string.format('Duplicate entry key "%s" in "%s".', id, file_name))
+ else
+ bib[id] = item
end
- bib[id] = item
end
end
return bib
@@ -164,44 +164,51 @@ function core.init(style_name, data_files, lang)
return engine
end
-
-function core.make_citation(citation_info)
- -- `citation_info`: "{ITEM-1@2}{{id={ITEM-1},label={page},locator={6}}}{3}"
- local arguments = {}
- for argument in string.gmatch(citation_info, "(%b{})") do
- table.insert(arguments, string.sub(argument, 2, -2))
+local function parse_latex_seq(s)
+ local t = {}
+ for item in string.gmatch(s, "(%b{})") do
+ item = string.sub(item, 2, -2)
+ table.insert(t, item)
end
- if #arguments ~= 3 then
- error(string.format('Invalid citation "%s"', citation_info))
- return nil
- end
- local citation_id, cite_items_str, note_index = table.unpack(arguments)
+ return t
+end
- local cite_items = {}
- if citation_id == "nocite" then
- for _, cite_id in ipairs(util.split(cite_items_str, "%s*,%s*")) do
- table.insert(cite_items, {id = cite_id})
+local function parse_latex_prop(s)
+ local t = {}
+ for key, value in string.gmatch(s, "([%w%-]+)%s*=%s*(%b{})") do
+ value = string.sub(value, 2, -2)
+ if value == "true" then
+ value = true
+ elseif value == "false" then
+ value = false
end
+ t[key] = value
+ end
+ return t
+end
- else
- for item_str in string.gmatch(cite_items_str, "(%b{})") do
- item_str = string.sub(item_str, 2, -2)
- local cite_item = {}
- for key, value in string.gmatch(item_str, "([%w%-]+)=(%b{})") do
- value = string.sub(value, 2, -2)
- cite_item[key] = value
- end
- table.insert(cite_items, cite_item)
- end
+function core.make_citation(citation_info)
+ -- `citation_info`: "citationID={ITEM-1@2},citationItems={{id={ITEM-1},label={page},locator={6}}},properties={noteIndex={3}}"
+ local citation = parse_latex_prop(citation_info)
+ assert(citation.citationID)
+ assert(citation.citationItems)
+ assert(citation.properties)
+
+ citation.citationItems = parse_latex_seq(citation.citationItems)
+
+ for i, item in ipairs(citation.citationItems) do
+ citation.citationItems[i] = parse_latex_prop(item)
end
- local citation = {
- citationID = citation_id,
- citationItems = cite_items,
- properties = {
- noteIndex = tonumber(note_index),
- },
- }
+ citation.properties = parse_latex_prop(citation.properties)
+ local note_index = citation.properties.noteIndex
+ if not note_index or note_index == "" then
+ citation.properties.noteIndex = 0
+ elseif type(note_index) == "string" and string.match(note_index, "^%d+$") then
+ citation.properties.noteIndex = tonumber(note_index)
+ else
+ util.error(string.format('Invalid note index "%s".', note_index))
+ end
return citation
end
@@ -210,19 +217,13 @@ end
function core.process_citations(engine, citations)
local citations_pre = {}
- -- Save the time of bibliography sorting by update all ids at one time.
- core.update_item_ids(engine, citations)
+ core.update_uncited_items(engine, citations)
local citation_strings = {}
for _, citation in ipairs(citations) do
- if citation.citationID ~= "nocite" then
- local res = engine:processCitationCluster(citation, citations_pre, {})
-
- for _, citation_res in ipairs(res[2]) do
- local citation_str = citation_res[2]
- local citation_id = citation_res[3]
- citation_strings[citation_id] = citation_str
- end
+ if citation.citationID ~= "@nocite" then
+ local citation_str = engine:process_citation(citation)
+ citation_strings[citation.citationID] = citation_str
table.insert(citations_pre, {citation.citationID, citation.properties.noteIndex})
end
@@ -232,35 +233,30 @@ function core.process_citations(engine, citations)
end
-function core.update_item_ids(engine, citations)
+function core.update_uncited_items(engine, citations)
+ -- util.debug(core.uncite_all_items)
if core.uncite_all_items then
- for item_id, _ in pairs(core.bib) do
- if not core.loaded_ids[item_id] then
- table.insert(core.ids, item_id)
- core.loaded_ids[item_id] = true
- end
+ -- \nocite{*}
+ for id, _ in pairs(core.bib) do
+ table.insert(core.uncited_ids, id)
end
- end
- for _, citation in ipairs(citations) do
- for _, cite_item in ipairs(citation.citationItems) do
- local id = cite_item.id
- if id == "*" then
- for item_id, _ in pairs(core.bib) do
- if not core.loaded_ids[item_id] then
- table.insert(core.ids, item_id)
- core.loaded_ids[item_id] = true
+ else
+ for _, citation in ipairs(citations) do
+ if citation.citationID == "@nocite" then
+ for _, cite_item in ipairs(citation.citationItems) do
+ table.insert(core.uncited_ids, cite_item.id)
+ if cite_item.id == "*" then
+ for id, _ in pairs(core.bib) do
+ table.insert(core.uncited_ids, id)
+ end
+ else
+ table.insert(core.uncited_ids, cite_item.id)
end
end
- else
- if not core.loaded_ids[id] then
- table.insert(core.ids, id)
- core.loaded_ids[id] = true
- end
end
end
end
- engine:updateItems(core.ids)
- -- TODO: engine:updateUncitedItems(ids)
+ engine:updateUncitedItems(core.uncited_ids)
end
diff --git a/biblio/citation-style-language/citeproc-latex.lua b/biblio/citation-style-language/citeproc-latex.lua
new file mode 100644
index 0000000000..19348635b0
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-latex.lua
@@ -0,0 +1,150 @@
+--
+-- Copyright (c) 2021-2022 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+local csl = {}
+
+local citeproc = require("citeproc")
+local util = citeproc.util
+require("lualibs")
+local core = require("citeproc-latex-core")
+
+
+csl.initialized = "false"
+csl.id_list = {}
+csl.id_map = {} -- Boolean map for checking if id in list
+csl.uncited_id_list = {}
+csl.uncited_id_map = {}
+csl.citations_pre = {}
+
+csl.preview_mode = false -- Whether to use citeproc:preview_citation
+
+
+function csl.error(str)
+ luatexbase.module_error("csl", str)
+end
+function csl.warning(str)
+ luatexbase.module_warning("csl", str)
+end
+function csl.info(str)
+ luatexbase.module_info("csl", str)
+end
+
+
+function csl.init(style_name, bib_files, lang)
+ bib_files = util.split(util.strip(bib_files), "%s*,%s*")
+
+ csl.engine = core.init(style_name, bib_files, lang)
+
+ if csl.engine then
+ csl.initialized = "true"
+ else
+ return
+ end
+
+ -- csl.init is called via \AtBeginDocument and it's executed after
+ -- loading .aux file. The csl.id_list are already registered.
+ csl.engine:updateItems(csl.id_list)
+
+ if core.uncite_all_items then
+ for id, _ in pairs(core.bib) do
+ if not csl.uncited_id_map[id] then
+ table.insert(csl.uncited_id_list, id)
+ csl.uncited_id_map[id] = true
+ end
+ end
+ end
+ csl.engine:updateUncitedItems(csl.uncited_id_list)
+ csl.style_class = csl.engine:get_style_class()
+end
+
+
+function csl.get_style_class()
+ tex.sprint(csl.style_class)
+end
+
+
+function csl.register_citation_info(citation_info)
+ local citation = core.make_citation(citation_info)
+ for _, cite_item in ipairs(citation.citationItems) do
+ if not csl.id_map[cite_item.id] then
+ table.insert(csl.id_list, cite_item.id)
+ csl.id_map[cite_item.id] = true
+ end
+ end
+end
+
+
+function csl.enable_linking()
+ csl.engine:enable_linking()
+end
+
+
+function csl.cite(citation_info)
+ -- "citationID={ITEM-UNAVAILABLE@1},citationItems={{id={ITEM-UNAVAILABLE}}},properties={noteIndex={1}}"
+ -- util.debug(citation_info)
+ if not csl.engine then
+ csl.error("CSL engine is not initialized.")
+ end
+
+ local citation = core.make_citation(citation_info)
+
+ local citation_str
+ if csl.preview_mode then
+ -- TODO: preview mode in first pass of \blockquote of csquotes
+ -- citation_str = csl.engine:preview_citation(citation)
+ citation_str = ""
+ else
+ citation_str = csl.engine:process_citation(citation)
+ end
+
+ tex.sprint(string.format("{%s}{%s}", csl.style_class, citation_str))
+ -- tex.sprint(citation_str)
+
+ table.insert(csl.citations_pre, {citation.citationID, citation.properties.noteIndex})
+end
+
+
+function csl.nocite(ids_string)
+ local uncited_ids = util.split(ids_string, "%s*,%s*")
+ for _, uncited_id in ipairs(uncited_ids) do
+ if uncited_id == "*" then
+ if csl.engine then
+ for id, _ in pairs(core.bib) do
+ if not csl.uncited_id_map[id] then
+ table.insert(csl.uncited_id_list, id)
+ csl.uncited_id_map[id] = true
+ end
+ end
+ csl.engine:updateUncitedItems(csl.uncited_id_list)
+ else
+ core.uncite_all_items = true
+ end
+ else
+ if not csl.uncited_id_map[uncited_id] then
+ table.insert(csl.uncited_id_list, uncited_id)
+ csl.uncited_id_map[uncited_id] = true
+ if csl.engine then
+ csl.engine:updateUncitedItems(csl.uncited_id_list)
+ end
+ end
+ end
+ end
+end
+
+
+function csl.bibliography()
+ if not csl.engine then
+ csl.error("CSL engine is not initialized.")
+ return
+ end
+
+ local result = core.make_bibliography(csl.engine)
+
+ tex.print(util.split(result, "\n"))
+end
+
+
+return csl
diff --git a/biblio/citation-style-language/citeproc.1 b/biblio/citation-style-language/citeproc-lua.1
index bb891d9f41..c8fe3c3d68 100644
--- a/biblio/citation-style-language/citeproc.1
+++ b/biblio/citation-style-language/citeproc-lua.1
@@ -1,8 +1,8 @@
-.TH citeproc 1 "0.1.1"
+.TH citeproc-lua 1 "0.1.1"
.SH NAME
-citeproc \- make CSL citations and bibliography for LaTeX
+citeproc-lua \- make CSL citations and bibliography for LaTeX
.SH SYNOPSIS
-.B citeproc
+.B citeproc-lua
.RB [<options>]
.IR auxname [ \fB.aux\fP ]
.SH DESCRIPTION
diff --git a/biblio/citation-style-language/citeproc-lua.lua b/biblio/citation-style-language/citeproc-lua.lua
new file mode 100755
index 0000000000..c670866813
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-lua.lua
@@ -0,0 +1,12 @@
+#!/usr/bin/env texlua
+
+--
+-- Copyright (c) 2021-2022 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+kpse.set_program_name("luatex")
+
+local cli = require("citeproc-cli")
+cli.main()
diff --git a/biblio/citation-style-language/citeproc-node-choose.lua b/biblio/citation-style-language/citeproc-node-choose.lua
index e48731406c..3a4fc3f79e 100644
--- a/biblio/citation-style-language/citeproc-node-choose.lua
+++ b/biblio/citation-style-language/citeproc-node-choose.lua
@@ -6,123 +6,299 @@
local choose = {}
-local element = require("citeproc-element")
+local Element = require("citeproc-element").Element
+local SeqIr = require("citeproc-ir-node").SeqIr
local util = require("citeproc-util")
+-- [Choose](https://docs.citationstyles.org/en/stable/specification.html#choose)
+local Choose = Element:derive("choose")
-local Choose = element.Element:new()
+function Choose:from_node(node)
+ local o = Choose:new()
+ o.children = {}
+ o:process_children_nodes(node)
+ if #o.children == 0 then
+ return nil
+ end
+ return o
+end
+
+function Choose:build_ir(engine, state, context)
+ local branch
+ local branch_ir
+ for _, child in ipairs(self.children) do
+ if child:evaluate_conditions(engine, state, context) then
+ branch = child
+ branch_ir = child:build_ir(engine, state, context)
+ break
+ end
+ end
+
+ if not branch_ir then
+ branch_ir = SeqIr:new({}, self)
+ branch_ir.group_var = "missing"
+ end
+
+ local ir = SeqIr:new({branch_ir}, self)
+ ir.group_var = branch_ir.group_var
+ ir.name_count = branch_ir.name_count
+ ir.sort_key = branch_ir.sort_key
+
+ if not context.disambiguate then
+ context.disambiguate = true
-function Choose:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
- for i, child in ipairs(self:get_children()) do
- if child:is_element() then
- local result, status = child:render(item, context)
- if status then
- return result
+ for _, child in ipairs(self.children) do
+ if child:evaluate_conditions(engine, state, context) then
+ if child ~= branch then
+ ir.disambiguate_branch_ir = child:build_ir(engine, state, context)
+ end
+ break
end
end
+
+ context.disambiguate = false
end
- return nil
+
+ return ir
end
-local If = element.Element:new()
+local Condition = {
+ condition = nil,
+ value = nil,
+ match_type = "all",
+}
+
+function Condition:new(condition, value, match_type)
+ local o = {
+ condition = condition,
+ value = value,
+ match_type = match_type or "all"
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
-If.render = function (self, item, context)
- self:debug_info(context)
- context = self:process_context(context)
- local results = {}
- local variable_names = context.options["is-numeric"]
- if variable_names then
- for _, variable_name in ipairs(util.split(variable_names)) do
- local variable = self:get_variable(item, variable_name, context)
- table.insert(results, util.is_numeric(variable))
- end
+local If = Element:derive("if", {
+ conditions = nil,
+ match = "all"
+})
+
+function If:new()
+ local o = Element.new(self)
+ o.conditions = {}
+ o.match = "all"
+ return o
+end
+
+function If:from_node(node)
+ local o = If:new()
+ -- TODO: disambiguate
+ -- o:set_bool_attribute(node, "disambiguate")
+
+ o:add_conditions(node, "disambiguate")
+ o:add_conditions(node, "is-numeric")
+ o:add_conditions(node, "is-uncertain-date")
+ o:add_conditions(node, "locator")
+ o:add_conditions(node, "position")
+ o:add_conditions(node, "type")
+ o:add_conditions(node, "variable")
+
+ o.match = node:get_attribute("match")
+
+ o:process_children_nodes(node)
+
+ return o
+end
+
+function If:add_conditions(node, attribute)
+ local values = node:get_attribute(attribute)
+ if not values then
+ return
+ end
+ for _, value in ipairs(util.split(values)) do
+ local condition = Condition:new(attribute, value, self.match)
+ table.insert(self.conditions, condition)
end
+end
- variable_names = context.options["is-uncertain-date"]
- if variable_names then
- for _, variable_name in ipairs(util.split(variable_names)) do
- local variable = self:get_variable(item, variable_name, context)
- table.insert(results, util.is_uncertain_date(variable))
- end
+function If:build_children_ir(engine, state, context)
+ if not self.children then
+ return nil
end
+ local irs = {}
+ local name_count
+ local ir_sort_key
+ local group_var = "plain"
- local locator_types = context.options["locator"]
- if locator_types then
- for _, locator_type in ipairs(util.split(locator_types)) do
- local locator_label = item.label or "page"
- local res = locator_label == locator_type
- if locator_type == "sub-verbo" then
- res = locator_label == "sub-verbo" or locator_label == "sub verbo"
+ for _, child_element in ipairs(self.children) do
+ local child_ir = child_element:build_ir(engine, state, context)
+
+ if child_ir then
+ local child_group_var = child_ir.group_var
+ if child_group_var == "important" then
+ group_var = "important"
+ elseif child_group_var == "missing" and child_ir._type ~= "YearSuffix" then
+ if group_var == "plain" then
+ group_var = "missing"
+ end
end
- table.insert(results, res)
- end
- end
- local positions = context.options["position"]
- if positions then
- for _, position in ipairs(util.split(positions)) do
- local res = false
- if context.mode == "citation" then
- if position == "first" then
- res = (item.position == util.position_map["first"])
- elseif position == "near-note" then
- res = item["near-note"] ~= nil and item["near-note"] ~= false
- else
- res = (item.position >= util.position_map[position])
+ if child_ir.name_count then
+ if not name_count then
+ name_count = 0
end
+ name_count = name_count + child_ir.name_count
+ end
+
+ if child_ir.sort_key ~= nil then
+ ir_sort_key = child_ir.sort_key
end
- table.insert(results, res)
+
+ -- The condition can be simplified
+ table.insert(irs, child_ir)
end
end
- local type_names = context.options["type"]
- if type_names then
- for _, type_name in ipairs(util.split(type_names)) do
- table.insert(results, item["type"] == type_name)
+ if #irs == 0 then
+ group_var = "missing"
+ end
+
+ local ir = SeqIr:new(irs, self)
+ ir.name_count = name_count
+ ir.sort_key = ir_sort_key
+ ir.group_var = group_var
+ return ir
+end
+
+function If:build_ir(engine, state, context)
+ if not self:evaluate_conditions(engine, state, context) then
+ return nil
+ end
+
+ local ir = self:build_children_ir(engine, state, context)
+ if not ir then
+ return nil
+ end
+
+ ir.should_inherit_delim = true
+ return ir
+end
+
+function If:evaluate_conditions(engine, state, context)
+ local res = false
+ -- util.debug(self.conditions)
+ for _, condition in ipairs(self.conditions) do
+ if self:evaluate_condition(condition, state, context) then
+ if self.match == "any" then
+ return true
+ elseif self.match == "none" then
+ return false
+ end
+ else
+ if self.match == "all" then
+ return false
+ end
end
end
+ if self.match == "any" then
+ return false
+ else
+ return true
+ end
+end
+
+function If:evaluate_condition(condition, state, context)
+ -- util.debug(context.cite)
+ -- util.debug(condition)
+ if condition.condition == "disambiguate" then
+ return context.disambiguate or (context.in_bibliography and context.reference.disambiguate)
- variable_names = context.options["variable"]
- if variable_names then
- for _, variable_name in ipairs(util.split(variable_names)) do
- local variable = self:get_variable(item, variable_name, context)
- local res = (variable ~= nil and variable ~= "")
- table.insert(results, res)
+ elseif condition.condition == "is-numeric" then
+ local variable = context:get_variable(condition.value)
+ return util.is_numeric(variable)
+
+ elseif condition.condition == "is-uncertain-date" then
+ local variable = context:get_variable(condition.value)
+ -- TODO
+ return self:is_uncertain_date(variable)
+
+ elseif condition.condition == "locator" then
+ local locator_label = context:get_variable("label")
+ if locator_label == "sub verbo" then
+ locator_label = "sub-verbo"
+ end
+ return locator_label == condition.value
+
+ elseif condition.condition == "position" then
+ return self:check_position(condition.value, context)
+
+ elseif condition.condition == "type" then
+ local item_type = context:get_variable("type")
+ return item_type == condition.value
+
+ elseif condition.condition == "variable" then
+ local var = condition.value
+ if var == "locator" or var == "label" then
+ if context.in_bibliography then
+ return false
+ else
+ return context.cite[var] ~= nil
+ end
+ else
+ local res = context.reference[var] ~= nil
+ return res
end
end
+end
+
+function If:is_uncertain_date(variable)
+ if variable == nil then
+ return false
+ end
+ local circa = variable["circa"]
+ return circa and circa ~= ""
+end
- local match = context.options["match"] or "all"
- local status = false
- if match == "any" then
- status = util.any(results)
- elseif match == "none" then
- status = not util.any(results)
- else
- status = util.all(results)
+function If:check_position(position, context)
+ -- util.debug(context.cite)
+ if context.in_bibliography then
+ return false
end
- if status then
- return self:render_children(item, context), status
+
+ local position_level = context.cite.position or context.cite.position_level or 0
+ -- context.cite.position is for hacking in debugging
+ -- bugreports_DemoPageFullCiteCruftOnSubsequent.txt
+ if position == "first" then
+ return (position_level == util.position_map["first"])
+ elseif position == "near-note" then
+ return context.cite["near-note"] or context.cite.near_note
else
- return nil, false
+ return (position_level >= util.position_map[position])
end
end
-local ElseIf = If:new()
+local ElseIf = If:derive("else-if")
+
+local Else = Element:derive("else")
-local Else = element.Element:new()
+function Else:from_node(node)
+ local o = Else:new()
+ o:process_children_nodes(node)
+ return o
+end
-Else.render = function (self, item, context)
- self:debug_info(context)
- context = self:process_context(context)
- return self:render_children(item, context), true
+function Else:evaluate_conditions(engine, state, context)
+ return true
end
+Else.build_children_ir = If.build_children_ir
+Else.build_ir = If.build_ir
+
choose.Choose = Choose
choose.If = If
diff --git a/biblio/citation-style-language/citeproc-node-date.lua b/biblio/citation-style-language/citeproc-node-date.lua
index e10c1a9ac2..7ec1f439b8 100644
--- a/biblio/citation-style-language/citeproc-node-date.lua
+++ b/biblio/citation-style-language/citeproc-node-date.lua
@@ -6,376 +6,481 @@
local date_module = {}
-local element = require("citeproc-element")
+local Element = require("citeproc-element").Element
+local IrNode = require("citeproc-ir-node").IrNode
+local Rendered = require("citeproc-ir-node").Rendered
+local SeqIr = require("citeproc-ir-node").SeqIr
+local PlainText = require("citeproc-output").PlainText
local util = require("citeproc-util")
-local Date = element.Element:new()
+-- [Date](https://docs.citationstyles.org/en/stable/specification.html#date)
+local Date = Element:derive("date")
-function Date:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
+function Date:from_node(node)
+ local o = Date:new()
- if context.sorting then
- return self:render_sort_key(item, context)
+ o:set_attribute(node, "variable")
+ o:set_attribute(node, "form")
+ o:set_attribute(node, "date-parts")
+
+ if o.form and not o.date_parts then
+ o.date_parts = "year-month-day"
end
- local variable_name = context.options["variable"]
+ o:get_delimiter_attribute(node)
+ o:set_formatting_attributes(node)
+ o:set_affixes_attributes(node)
+ o:set_display_attribute(node)
+ o:set_text_case_attribute(node)
- local is_locale_date
- if variable_name then
- context.variable = variable_name
- is_locale_date = false
- else
- variable_name = context.variable
- is_locale_date = true
+ o.children = {}
+ o:process_children_nodes(node)
+
+ for _, date_part in ipairs(o.children) do
+ o[date_part.name] = date_part
end
- local date = self:get_variable(item, variable_name, context)
- if not date then
- return nil
+ return o
+end
+
+function Date:build_ir(engine, state, context)
+ local variable
+ if not state.suppressed[self.variable] then
+ variable = context:get_variable(self.variable)
+ end
+
+ if not variable then
+ local ir = Rendered:new({}, self)
+ ir.group_var = "missing"
+ return ir
end
- local res = nil
- local form = context.options["form"]
- if form and not is_locale_date then
- for _, date_part in ipairs(self:query_selector("date-part")) do
- local name = date_part:get_attribute("name")
- if not context.date_part_attributes then
- context.date_part_attributes = {}
+ local ir
+
+ if variable["date-parts"] and #variable["date-parts"] > 0 then
+
+ -- TODO: move input normlization in one place
+ for i = 1, 2 do
+ if variable["date-parts"][i] then
+ for j = 1, 3 do
+ local variabel_part = variable["date-parts"][i][j]
+ if variabel_part == 0 or variabel_part == "" then
+ variable["date-parts"][i][j] = nil
+ else
+ variable["date-parts"][i][j] = tonumber(variabel_part)
+ end
+ end
end
- if not context.date_part_attributes[name] then
- context.date_part_attributes[name] = {}
+ end
+ if variable["season"] and not variable["date-parts"][1][2] then
+ variable["date-parts"][1][2] = 20 + tonumber(variable["season"])
+ end
+
+ variable = variable["date-parts"]
+ if self.form then
+ ir = self:build_localized_date_ir(variable, engine, state, context)
+ else
+ ir = self:build_independent_date_ir(variable, engine, state, context)
+ end
+ ir.affixes = self.affixes
+
+ elseif variable["literal"] then
+ local inlines = self:render_text_inlines(variable["literal"], context)
+ ir = Rendered:new(inlines, self)
+ ir.group_var = "important"
+
+ elseif variable["raw"] then
+ local inlines = self:render_text_inlines(variable["raw"], context)
+ ir = Rendered:new(inlines, self)
+ ir.group_var = "important"
+
+ end
+
+ if not ir then
+ -- date_LiteralFailGracefullyIfNoValue.txt
+ ir = Rendered:new({}, self)
+ if context.sort_key then
+ ir.sort_key = false
+ end
+ ir.group_var = "missing"
+ return ir
+ end
+
+ if ir.group_var == "important" then
+ -- Suppress substituted name variable
+ if state.name_override and not context.sort_key then
+ state.suppressed[self.variable] = true
+ end
+ end
+
+ if context.sort_key then
+ ir.sort_key = self:render_sort_key(engine, state, context)
+ end
+
+ return ir
+end
+
+function Date:build_independent_date_ir(variable, engine, state, context)
+ -- else
+ -- local literal = variable["literal"]
+ -- if literal then
+ -- res = literal
+ -- else
+ -- local raw = variable["raw"]
+ -- if raw then
+ -- res = raw
+ -- end
+ -- end
+
+ return self:build_date_parts(self.children, variable, self.delimiter, engine, state, context)
+end
+
+function Date:build_localized_date_ir(variable, engine, state, context)
+ local date_part_mask = {}
+ for _, part in ipairs(util.split(self.date_parts or "year-month-day", "%-")) do
+ date_part_mask[part] = true
+ end
+ -- local date_parts = {}
+ -- for _, date_part in ipairs(self.children) do
+ -- date_parts[date_part.name] = date_part
+ -- end
+ local localized_date = context:get_localized_date(self.form)
+ local date_parts = {}
+ for _, date_part in ipairs(localized_date.children) do
+ if date_part_mask[date_part.name] then
+ date_part = date_part:copy()
+ local local_date_part = self[date_part.name]
+ if local_date_part then
+ local_date_part:override(date_part)
end
+ table.insert(date_parts, date_part)
+ end
+ end
+ return self:build_date_parts(date_parts, variable, localized_date.delimiter, engine, state, context)
+end
- for attr, value in pairs(date_part._attr) do
- if attr ~= name then
- context.date_part_attributes[name][attr] = value
- end
+function Date:build_date_parts(date_parts, variable, delimiter, engine, state, context)
+ if #variable >= 2 then
+ return self:build_date_range(date_parts, variable, delimiter, engine, state, context)
+ elseif #variable == 1 then
+ return self:build_single_date(date_parts, variable[1], delimiter, engine, state, context)
+ end
+end
+
+function Date:build_single_date(date_parts, single_date, delimiter, engine, state, context)
+ local irs = {}
+ for _, date_part in ipairs(date_parts) do
+ local part_ir = date_part:build_ir(single_date, engine, state, context)
+ table.insert(irs, part_ir)
+ end
+
+ local ir = SeqIr:new(irs, self)
+ ir.delimiter = self.delimiter
+
+ -- return Rendered:new(inlines, self)
+ return ir
+end
+
+local date_part_index = {
+ year = 1,
+ month = 2,
+ day = 3,
+}
+
+function Date:build_date_range(date_parts, variable, delimiter, engine, state, context)
+ local first, second = variable[1], variable[2]
+ local diff_level = 4
+ for _, date_part in ipairs(date_parts) do
+ local part_index = date_part_index[date_part.name]
+ if first[part_index] and first[part_index] ~= second[part_index] then
+ if part_index < diff_level then
+ diff_level = part_index
end
end
- res = self:get_locale_date(context, form):render(item, context)
- else
- if not date["date-parts"] or #date["date-parts"] == 0 then
- local literal = date["literal"]
- if literal then
- res = literal
+ end
+
+ local irs = {}
+
+ local range_part_queue = {}
+ local range_delimiter
+ for i, date_part in ipairs(date_parts) do
+ local part_index = date_part_index[date_part.name]
+ if part_index == diff_level then
+ range_delimiter = date_part.range_delimiter or util.unicode["en dash"]
+ end
+ if first[part_index] then
+ if part_index >= diff_level then
+ table.insert(range_part_queue, date_part)
else
- local raw = date["raw"]
- if raw then
- res = raw
+ if #range_part_queue > 0 then
+ table.insert(irs, self:build_date_range_parts(range_part_queue, variable,
+ delimiter, engine, state, context, range_delimiter))
+ range_part_queue = {}
end
- end
-
- else
- if #date["date-parts"] == 1 then
- res = self:_render_single_date(date, context)
- elseif #date["date-parts"] == 2 then
- res = self:_render_date_range(date, context)
+ table.insert(irs, date_part:build_ir(first, engine, state, context))
end
end
end
+ if #range_part_queue > 0 then
+ table.insert(irs, self:build_date_range_parts(range_part_queue, variable,
+ delimiter, engine, state, context, range_delimiter))
+ end
- table.insert(context.variable_attempt, res ~= nil)
+ local ir = SeqIr:new(irs, self)
+ ir.delimiter = delimiter
- res = self:format(res, context)
- res = self:wrap(res, context)
- return res
+ return ir
end
-function Date:get_locale_date(context, form)
- local date = nil
- local style = context.style
- local query = string.format("date[form=\"%s\"]", form)
- for _, locale in ipairs(style:get_locales()) do
- date = locale:query_selector(query)[1]
- if date then
- break
+function Date:build_date_range_parts(range_part_queue, variable, delimiter, engine, state, context, range_delimiter)
+ local irs = {}
+ local first, second = variable[1], variable[2]
+
+ local date_part_irs = {}
+ for i, diff_part in ipairs(range_part_queue) do
+ -- if delimiter and i > 1 then
+ -- table.insert(date_part_irs, PlainText:new(delimiter))
+ -- end
+ if i == #range_part_queue then
+ table.insert(date_part_irs, diff_part:build_ir(first, engine, state, context, "suffix"))
+ else
+ table.insert(date_part_irs, diff_part:build_ir(first, engine, state, context))
end
end
- if not date then
- error(string.format("Failed to find '%s'", query))
+ local range_part_ir = SeqIr:new(date_part_irs, self)
+ range_part_ir.delimiter = delimiter
+ table.insert(irs, range_part_ir)
+
+ table.insert(irs, Rendered:new({PlainText:new(range_delimiter)}, self))
+
+ date_part_irs = {}
+ for i, diff_part in ipairs(range_part_queue) do
+ if i == 1 then
+ table.insert(date_part_irs, diff_part:build_ir(second, engine, state, context, "prefix"))
+ else
+ table.insert(date_part_irs, diff_part:build_ir(second, engine, state, context))
+ end
end
- return date
+ range_part_ir = SeqIr:new(date_part_irs, self)
+ range_part_ir.delimiter = delimiter
+ table.insert(irs, range_part_ir)
+
+ local ir = SeqIr:new(irs, self)
+
+ return ir
end
-function Date:render_sort_key (item, context)
- local variable_name = context.options["variable"]
- local date = self:get_variable(item, variable_name, context)
- if not date or not date["date-parts"] then
- return nil
+function Date:render_sort_key(engine, state, context)
+ local date = context:get_variable(self.variable)
+ if not date then
+ return false
end
+ if not date["date-parts"] then
+ if self.literal then
+ return "1" .. self.literal
+ else
+ return false
+ end
+ end
+
local show_parts = {
year = false,
month = false,
day = false,
}
- if self:get_attribute("form") then
- local date_parts = self:get_attribute("date-parts") or "year-month-day"
- for _, dp_name in ipairs(util.split(date_parts, "%-")) do
+ if self.form then
+ for _, dp_name in ipairs(util.split(self.date_parts, "%-")) do
show_parts[dp_name] = true
end
else
- for _, child in ipairs(self:query_selector("date-part")) do
- show_parts[child:get_attribute("name")] = true
+ for _, date_part in ipairs(self.children) do
+ show_parts[date_part.name] = true
end
end
local res = ""
- for _, date_parts in ipairs(date["date-parts"]) do
+ for _, range_part in ipairs(date["date-parts"]) do
+ if res ~= "" then
+ res = res .. "/"
+ end
for i, dp_name in ipairs({"year", "month", "day"}) do
- local value = date_parts[i]
- if not value or not show_parts[dp_name] then
- value = 0
+ local value = 0
+ if show_parts[dp_name] and range_part[i] then
+ value = range_part[i]
end
if i == 1 then
res = res .. string.format("%05d", value + 10000)
else
- res = res .. string.format("%02d", value)
+ res = res .. "-" .. string.format("%02d", value)
end
end
end
return res
end
-function Date:_render_single_date (date, context)
- local show_parts = self:_get_show_parts(context)
- local output = {}
- for _, child in ipairs(self:query_selector("date-part")) do
- if show_parts[child:get_attribute("name")] then
- table.insert(output, child:render(date, context))
- end
+-- [Date-part](https://docs.citationstyles.org/en/stable/specification.html#date-part)
+local DatePart = Element:derive("date-part")
+
+function DatePart:from_node(node)
+ local o = DatePart:new()
+ o:set_attribute(node, "name")
+ o:set_attribute(node, "form")
+ if o.name == "month" then
+ o:set_strip_periods_attribute(node)
end
- return self:concat(output, context)
+ o:set_formatting_attributes(node)
+ o:set_text_case_attribute(node)
+ o:set_attribute(node, "range-delimiter")
+ o:set_affixes_attributes(node)
+ return o
end
-function Date:_render_date_range (date, context)
- local show_parts = self:_get_show_parts(context)
- local part_index = {}
-
- local largest_diff_part = nil
- for i, name in ipairs({"year", "month", "day"}) do
- part_index[name] = i
- local part_value1 = date["date-parts"][1][i]
- if show_parts[name] and part_value1 then
- if not largest_diff_part then
- largest_diff_part = name
- end
- end
+function DatePart:build_ir(single_date, engine, state, context, suppressed_affix)
+ local text
+ if self.name == "year" then
+ text = self:render_year(single_date[1], engine, state, context)
+ elseif self.name == "month" then
+ text = self:render_month(single_date[2], engine, state, context)
+ elseif self.name == "day" then
+ text = self:render_day(single_date[3], single_date[2], engine, state, context)
end
- local date_parts = {}
- for _, date_part in ipairs(self:query_selector("date-part")) do
- if show_parts[date_part:get_attribute("name")] then
- table.insert(date_parts, date_part)
- end
+ if not text then
+ local ir = Rendered:new({}, self)
+ ir.group_var = "missing"
+ return ir
end
- local diff_begin = 0
- local diff_end = #date_parts
- local range_delimiter = nil
-
- for i, date_part in ipairs(date_parts) do
- local name = date_part:get_attribute("name")
- if name == largest_diff_part then
- range_delimiter = date_part:get_attribute("range-delimiter")
- if not range_delimiter then
- range_delimiter = util.unicode["en dash"]
- end
- end
-
- local index = part_index[name]
- local part_value1 = date["date-parts"][1][index]
- local part_value2 = date["date-parts"][2][index]
- if part_value1 and part_value1 ~= part_value2 then
- if diff_begin == 0 then
- diff_begin = i
- end
- diff_end = i
- end
+ local inlines = {PlainText:new(text)}
+ local output_format = context.format
+ if not context.is_english then
+ print(debug.traceback())
end
+ local is_english = context:is_english()
+ output_format:apply_text_case(inlines, self.text_case, is_english)
+ inlines = output_format:with_format(inlines, self.formatting)
- local same_prefix = {}
- local range_begin = {}
- local range_end = {}
- local same_suffix = {}
+ local ir = Rendered:new(inlines, self)
+ ir.group_var = "important"
- local no_suffix_context = self:process_context(context)
- no_suffix_context.options["suffix"] = nil
-
- for i, date_part in ipairs(date_parts) do
- local res = nil
- if i == diff_end then
- res = date_part:render(date, no_suffix_context, true)
- else
- res = date_part:render(date, context)
- end
- if i < diff_begin then
- table.insert(same_prefix, res)
- elseif i <= diff_end then
- table.insert(range_begin, res)
- table.insert(range_end, date_part:render(date, context, false, true))
- else
- table.insert(same_suffix, res)
- end
+ if self.name == "year" then
+ ir = SeqIr:new({ir}, self)
+ ir.is_year = true
end
- local prefix_output = self:concat(same_prefix, context) or ""
- local range_begin_output = self:concat(range_begin, context) or ""
- local range_end_output = self:concat(range_end, context) or ""
- local suffix_output = self:concat(same_suffix, context)
- local range_output = range_begin_output .. range_delimiter .. range_end_output
-
- local res = self:concat({prefix_output, range_output, suffix_output}, context)
+ ir.affixes = util.clone(self.affixes)
+ if ir.affixes and suppressed_affix then
+ ir.affixes[suppressed_affix] = nil
+ end
- return res
+ return ir
end
-function Date:_get_show_parts (context)
- local show_parts = {}
- local date_parts = context.options["date-parts"] or "year-month-day"
- for _, date_part in ipairs(util.split(date_parts, "%-")) do
- show_parts[date_part] = true
+function DatePart:render_day(day, month, engine, state, context)
+ if not day or day == "" then
+ return nil
+ end
+ day = tonumber(day)
+ if day < 1 or day > 31 then
+ return nil
+ end
+ local form = self.form or "numeric"
+ if form == "ordinal" then
+ local limit_day_1 = context.locale.style_options.limit_day_ordinals_to_day_1
+ if limit_day_1 and day > 1 then
+ form = "numeric"
+ end
+ end
+ if form == "numeric-leading-zeros" then
+ return string.format("%02d", day)
+ elseif form == "ordinal" then
+ -- When the “day” date-part is rendered in the “ordinal” form, the ordinal
+ -- gender is matched against that of the month term.
+ local gender = context.locale:get_number_gender(string.format("month-%02d", month))
+ local suffix = context.locale:get_ordinal_term(day, gender)
+ return tostring(day) .. suffix
+ else -- numeric
+ return tostring(day)
end
- return show_parts
end
-
-local DatePart = element.Element:new()
-
-DatePart.render = function (self, date, context, last_range_begin, range_end)
- self:debug_info(context)
- context = self:process_context(context)
- local name = context.options["name"]
- local range_delimiter = context.options["range-delimiter"] or false
-
- -- The attributes set on cs:date-part elements of a cs:date with form
- -- attribute override those specified for the localized date formats
- if context.date_part_attributes then
- local context_attributes = context.date_part_attributes[name]
- if context_attributes then
- for attr, value in pairs(context_attributes) do
- context.options[attr] = value
+function DatePart:render_month(month, engine, state, context)
+ if not month or month == "" then
+ return nil
+ end
+ month = tonumber(month)
+ if not month or month < 1 or month > 24 then
+ return nil
+ end
+ local form = self.form or "long"
+ local res
+ if form == "long" or form == "short" then
+ if month >= 1 and month <= 12 then
+ res = context:get_simple_term(string.format("month-%02d", month), form)
+ else
+ local season = month % 4
+ if season == 0 then
+ season = 4
end
+ res = context:get_simple_term(string.format("season-%02d", season))
end
+ elseif form == "numeric-leading-zeros" then
+ res = string.format("%02d", month)
+ else
+ res = tostring(month)
end
+ return self:apply_strip_periods(res)
+end
- if last_range_begin then
- context.options["suffix"] = ""
+function DatePart:render_year(year, engine, state, context)
+ if not year or year == "" then
+ return nil
end
-
- local date_parts_index = 1
- if range_end then
- date_parts_index = 2
+ year = tonumber(year)
+ if year == 0 then
+ return nil
end
-
- local res = nil
- if name == "day" then
- local day = date["date-parts"][date_parts_index][3]
- if not day then
- return nil
- end
- day = tonumber(day)
- -- range open
- if day == 0 then
- return nil
- end
- local form = context.options["form"] or "numeric"
-
- if form == "ordinal" then
- local option = self:get_locale_option("limit-day-ordinals-to-day-1")
- if option and option ~= "false" and day > 1 then
- form = "numeric"
- end
- end
- if form == "numeric" then
- res = tostring(day)
- elseif form == "numeric-leading-zeros" then
- -- TODO: day == nil?
- if not day then
- return nil
- end
- res = string.format("%02d", day)
- elseif form == "ordinal" then
- res = util.to_ordinal(day)
+ local form = self.form or "long"
+ if form == "long" then
+ if year < 0 then
+ return tostring(-year) .. context:get_simple_term("bc")
+ elseif year < 1000 then
+ return tostring(year) .. context:get_simple_term("ad")
+ else
+ return tostring(year)
end
+ elseif form == "short" then
+ return string.sub(tostring(year), -2)
+ end
+end
- elseif name == "month" then
- local form = context.options["form"] or "long"
-
- local month = date["date-parts"][date_parts_index][2]
- if month then
- month = tonumber(month)
- -- range open
- if month == 0 then
- return nil
+function DatePart:copy()
+ local o = {}
+ for key, value in pairs(self) do
+ if type(value) == "table" then
+ o[key] = {}
+ for k, v in pairs(value) do
+ o[key][k] = v
end
+ else
+ o[key] = value
end
+ end
+ setmetatable(o, DatePart)
+ return o
+end
- if form == "long" or form == "short" then
- local term_name = nil
- if month then
- if month >= 1 and month <= 12 then
- term_name = string.format("month-%02d", month)
- elseif month >= 13 and month <= 24 then
- local season = month % 4
- if season == 0 then
- season = 4
- end
- term_name = string.format("season-%02d", season)
- else
- util.warning("Invalid month value")
- return nil
- end
- else
- local season = date["season"]
- if season then
- season = tonumber(season)
- term_name = string.format("season-%02d", season)
- else
- return nil
- end
- end
- res = self:get_term(term_name, form):render(context)
- elseif form == "numeric" then
- res = tostring(month)
- elseif form == "numeric-leading-zeros" then
- -- TODO: month == nil?
- if not month then
- return nil
- end
- res = string.format("%02d", month)
- end
- res = self:strip_periods(res, context)
-
- elseif name == "year" then
- local year = date["date-parts"][date_parts_index][1]
- if year then
- year = tonumber(year)
- -- range open
- if year == 0 then
- return nil
- end
- local form = context.options["form"] or "long"
- if form == "long" then
- year = tonumber(year)
- if year < 0 then
- res = tostring(-year) .. self:get_term("bc"):render(context)
- elseif year < 1000 then
- res = tostring(year) .. self:get_term("ad"):render(context)
- else
- res = tostring(year)
- end
- elseif form == "short" then
- res = string.sub(tostring(year), -2)
+function DatePart:override(localized_date_part)
+ for key, value in pairs(self) do
+ if type(value) == "table" and localized_date_part[key] then
+ for k, v in pairs(value) do
+ localized_date_part[key][k] = v
end
+ else
+ localized_date_part[key] = value
end
end
- res = self:case(res, context)
- res = self:format(res, context)
- res = self:wrap(res, context)
- res = self:display(res, context)
- return res
end
diff --git a/biblio/citation-style-language/citeproc-node-group.lua b/biblio/citation-style-language/citeproc-node-group.lua
index 51969212ba..81132a77dc 100644
--- a/biblio/citation-style-language/citeproc-node-group.lua
+++ b/biblio/citation-style-language/citeproc-node-group.lua
@@ -6,33 +6,36 @@
local group = {}
-local element = require("citeproc-element")
+local SeqIr = require("citeproc-ir-node").SeqIr
+local Element = require("citeproc-element").Element
local util = require("citeproc-util")
-local Group = element.Element:new()
+local Group = Element:derive("group")
-function Group:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
+function Group:from_node(node)
+ local o = Group:new()
+ o:get_delimiter_attribute(node)
+ o:set_affixes_attributes(node)
+ o:set_display_attribute(node)
+ o:set_formatting_attributes(node)
- local num_variable_attempt = #context.variable_attempt
+ o:process_children_nodes(node)
- local res = self:render_children(item, context)
+ return o
+end
- if #context.variable_attempt > num_variable_attempt then
- if not util.any(util.slice(context.variable_attempt, num_variable_attempt + 1)) then
- res = nil
- end
+function Group:build_ir(engine, state, context)
+ local ir = self:build_group_ir(engine, state, context)
+ if ir then
+ ir.delimiter = self.delimiter
+ ir.formatting = util.clone(self.formatting)
+ ir.affixes = util.clone(self.affixes)
+ ir.display = self.display
end
-
- res = self:format(res, context)
- res = self:wrap(res, context)
- res = self:display(res, context)
- return res
+ return ir
end
-
group.Group = Group
return group
diff --git a/biblio/citation-style-language/citeproc-node-label.lua b/biblio/citation-style-language/citeproc-node-label.lua
index 828f5e9122..27cafa2f18 100644
--- a/biblio/citation-style-language/citeproc-node-label.lua
+++ b/biblio/citation-style-language/citeproc-node-label.lua
@@ -6,104 +6,88 @@
local label = {}
-local element = require("citeproc-element")
+local Element = require("citeproc-element").Element
+local IrNode = require("citeproc-ir-node").IrNode
+local Rendered = require("citeproc-ir-node").Rendered
+local PlainText = require("citeproc-output").PlainText
local util = require("citeproc-util")
-local Label = element.Element:new()
+-- [Label](https://docs.citationstyles.org/en/stable/specification.html#label)
+local Label = Element:derive("label")
-function Label:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
+Label.form = "long"
+Label.plural = "contextual"
- local variable_name
- if context.names_element then
- -- The `variable` attribute of names may hold multiple roles.
- -- Each of them may call `Label:render()` to render the term.
- -- When used in `names` element, the role name is the first argument
- -- and the item is accessed via `context.item`.
- -- Bad design
- -- TODO: Redesign the arguments of render()
- variable_name = item
- else
- variable_name = context.options["variable"]
- end
-
- local form = context.options["form"]
- local plural = context.options["plural"] or "contextual"
+function Label:from_node(node)
+ local o = Label:new()
+ o:set_attribute(node, "variable")
+ o:set_attribute(node, "form")
+ o:set_attribute(node, "plural")
+ o:set_affixes_attributes(node)
+ o:set_formatting_attributes(node)
+ o:set_text_case_attribute(node)
+ o:set_strip_periods_attribute(node)
+ return o
+end
- if not context.names_element then
- local variable_type = util.variable_types[variable_name]
- -- variable must be or one of the number variables.
- if variable_type ~= "number" then
- return nil
- end
- -- The term is only rendered if the selected variable is non-empty
- local variable = item[variable_name]
- if not variable then
- return nil
- end
- if type(variable) == "string" then
- if not (string.match(variable, "^%d") or util.is_numeric(variable)) then
- return nil
- end
- end
- end
+function Label:build_ir(engine, state, context)
+ -- local variable = context:get_variable(self.variable, self.form)
- local term
- if variable_name == "locator" then
- local locator_type = item.label or "page"
- term = self:get_term(locator_type, form)
- else
- term = self:get_term(variable_name, form)
+ local is_plural = false
+ if self.plural == "always" then
+ is_plural = true
+ elseif self.plural == "never" then
+ is_plural = false
+ elseif self.plural == "contextual" then
+ is_plural = self:_is_variable_plural(self.variable, context)
end
- local res = nil
- if term then
- if plural == "contextual" and self:_is_plural(variable_name, context) or plural == "always" then
- res = term:render(context, true)
- else
- res = term:render(context, false)
+ local variable = self.variable
+ if variable == "locator" then
+ variable = context:get_variable("label") or "page"
+ if variable == "sub verbo" then
+ -- bugreports_MovePunctuationInsideQuotesForLocator.txt
+ variable = "sub-verbo"
end
-
- res = self:strip_periods(res, context)
- res = self:case(res, context)
- res = self:format(res, context)
- res = self:wrap(res, context)
end
- return res
+ local text = context:get_simple_term(variable, self.form, is_plural)
+ if not text or text == "" then
+ return nil
+ end
+
+ local inlines = self:render_text_inlines(text, context)
+ return Rendered:new(inlines, self)
end
-function Label:_is_plural (variable_name, context)
- local variable_type = util.variable_types[variable_name]
- -- Don't use self:get_variable here
- local variable = context.item[variable_name]
- local res = false
+function Label:_is_variable_plural(variable, context)
+ local value = context:get_variable(variable)
+ if not value then
+ return false
+ end
+ local variable_type = util.variable_types[variable]
if variable_type == "name" then
- -- Label inside `names`
- res = #variable > 1
-
+ return #variable > 1
elseif variable_type == "number" then
- if util.startswith(variable_name, "number-of-") then
- res = tonumber(variable) > 1
+ if util.startswith(variable, "number-of-") then
+ return tonumber(value) > 1
else
- variable = tostring(variable)
- variable = string.gsub(variable, "\\%-", "")
- if #util.split(variable, "%s*[,&-]%s*") > 1 then
- -- check if contains multiple numbers
- -- "i–ix": true
- -- res = string.match(tostring(variable), "%d+%D+%d+") ~= nil
- res = true
- elseif string.match(variable, "%Aand%A") or string.match(variable, "%Aet%A") then
- res = true
- else
- res = false
+ value = tostring(value)
+ -- label_CollapsedPageNumberPluralDetection.txt
+ -- 327\-30 => single
+ value = string.gsub(value, "\\%-", "")
+ if string.match(value, "[,&-]") then
+ return true
+ elseif string.match(value, util.unicode["en dash"]) then
+ return true
+ elseif string.match(value, "%Wand%W") then
+ return true
+ elseif string.match(value, "%Wet%W") then
+ return true
end
end
- else
- util.warning("Invalid attribute \"variable\".")
end
- return res
+ return false
end
diff --git a/biblio/citation-style-language/citeproc-node-layout.lua b/biblio/citation-style-language/citeproc-node-layout.lua
index 944ed883a3..168f923b08 100644
--- a/biblio/citation-style-language/citeproc-node-layout.lua
+++ b/biblio/citation-style-language/citeproc-node-layout.lua
@@ -6,229 +6,56 @@
local layout = {}
-local richtext = require("citeproc-richtext")
-local element = require("citeproc-element")
+local Element = require("citeproc-element").Element
+local SeqIr = require("citeproc-ir-node").SeqIr
local util = require("citeproc-util")
-local Layout = element.Element:new()
+local Layout = Element:derive("layout")
-function Layout:render (items, context)
- self:debug_info(context)
+function Layout:from_node(node)
+ local o = Layout:new()
+ o:set_affixes_attributes(node)
+ o:set_formatting_attributes(node)
+ o:get_delimiter_attribute(node)
- context.items = items
+ o:process_children_nodes(node)
- -- When used within cs:citation, the delimiter attribute may be used to specify a delimiter for cites within a citation.
- -- Thus the processing of context is put after render_children().
- if context.mode == "citation" then
- if context.options["collapse"] == "citation-number" then
- context.build.item_citation_numbers = {}
- context.build.item_citation_number_text = {}
- end
- elseif context.mode == "bibliography" then
- context.build.longest_label = ""
- context.build.preceding_first_rendered_names = nil
- context = self:process_context(context)
- end
-
- local output = {}
- local previous_cite = nil
- for _, item in ipairs(items) do
-
- context.item = item
- context.variable_attempt = {}
- context.suppressed_variables = {}
- context.suppress_subsequent_variables = false
- if context.mode == "bibliography" then
- context.build.first_rendered_names = {}
- end
-
- if not item.position then
- item.position = self:_get_position(item, previous_cite, context)
- end
-
- local first = nil
- local second = {}
- local element_index = 0
- for _, child in ipairs(self:get_children()) do
- if child:is_element() then
- element_index = element_index + 1
- local text = child:render(item, context)
- if element_index == 1 then
- first = text
- else
- table.insert(second, text)
- end
- end
- end
- second = self:concat(second, context)
-
- if context.mode == "bibliography" then
- if first and context.options["prefix"] then
- first = richtext.new(context.options["prefix"]) .. first
- end
- if second and context.options["suffix"] then
- second = second .. richtext.new(context.options["suffix"])
- end
- end
-
- local res = nil
- if context.options["second-field-align"] == "flush" then
- if first then
- first:add_format("display", "left-margin")
- res = first
- end
- if second then
- second:add_format("display", "right-inline")
- if res then
- res = richtext.concat(res, second)
- else
- res = second
- end
- end
- else
- res = self:concat({first, second}, context)
- end
-
- if context.mode == "citation" then
- if res and item["prefix"] then
- res = richtext.new(item["prefix"]) .. res
- end
- if res and item["suffix"] then
- res = res .. richtext.new(item["suffix"])
- end
- elseif context.mode == "bibliography" then
- if not res then
- res = richtext.new("[CSL STYLE ERROR: reference with no printed form.]")
- end
- res = self:wrap(res, context)
- -- util.debug(text)
- res = res:render(context.engine.formatter, context)
- res = context.engine.formatter["@bibliography/entry"](res, context)
- end
- table.insert(output, res)
- previous_cite = item
- end
-
- if context.mode == "citation" then
- if next(output) == nil then
- return "[CSL STYLE ERROR: reference with no printed form.]"
- end
-
- context = self:process_context(context)
- local res
- if context.options["collapse"] then
- res = self:_collapse_citations(output, context)
- else
- res = self:concat(output, context)
- end
- res = self:wrap(res, context)
- res = self:format(res, context)
- if res then
- -- util.debug(res)
- res = res:render(context.engine.formatter, context)
- end
- return res
-
- else
- local params = {
- maxoffset = #context.build.longest_label,
- }
-
- return {params, output}
- end
+ return o
end
-function Layout:_get_position (item, previous_cite, context)
- local engine = context.engine
- if not engine.registry.registry[item.id] then
- return util.position_map["first"]
+function Layout:build_ir(engine, state, context)
+ local ir = self:build_children_ir(engine, state, context)
+ if not ir then
+ return nil
end
-
- local position = util.position_map["subsequent"]
- -- Find the preceding cite referencing the same item
- local preceding_cite = nil
- if previous_cite then
- -- a. the current cite immediately follows on another cite
- if item.id == previous_cite.id then
- preceding_cite = previous_cite
- end
- elseif engine.registry.previous_citation then
- -- b. first cite in the citation and previous citation exists
- for _, cite in ipairs(engine.registry.previous_citation.citationItems) do
- if item.id == cite.id then
- preceding_cite = cite
- break
- end
- end
- end
-
- if preceding_cite then
- if preceding_cite.locator then
- -- Preceding cite does have a locator
- if item.locator then
- if item.locator == preceding_cite.locator then
- position = util.position_map["ibid"]
- else
- position = util.position_map["ibid-with-locator"]
+ if context.in_bibliography then
+ ir.delimiter = self.delimiter
+
+ -- Move affixes of `bibliography > layout` into the right-inline element
+ -- bugreports_SmallCapsEscape.txt
+ local has_right_inline = false
+ if self.affixes or self.formatting then
+ for i, child_ir in ipairs(ir.children) do
+ if child_ir.display == "right-inline" then
+ has_right_inline = true
+ local right_inline_with_affixes = SeqIr:new({child_ir}, self)
+ right_inline_with_affixes.affixes = util.clone(self.affixes)
+ right_inline_with_affixes.formatting = util.clone(self.formatting)
+ child_ir.display = nil
+ right_inline_with_affixes.display = "right-inline"
+ ir.children[i] = right_inline_with_affixes
+ break
end
- else
- -- the current cite lacks a locator
- position = util.position_map["subsequent"]
- end
- else
- -- Preceding cite does not have a locator
- if item.locator then
- position = util.position_map["ibid-with-locator"]
- else
- position = util.position_map["ibid"]
end
end
- end
- return position
-end
-
-function Layout:_collapse_citations(output, context)
- if context.options["collapse"] == "citation-number" then
- assert(#output == #context.items)
- local citation_numbers = {}
- for i, item in ipairs(context.items) do
- citation_numbers[i] = context.build.item_citation_numbers[item.id] or 0
+ if not has_right_inline then
+ ir.affixes = util.clone(self.affixes)
+ ir.formatting = util.clone(self.formatting)
end
-
- local collapsed_output = {}
- local citation_number_range_delimiter = util.unicode["en dash"]
- local index = 1
- while index <= #citation_numbers do
- local stop_index = index + 1
- if output[index] == context.build.item_citation_number_text[index] then
- while stop_index <= #citation_numbers do
- if output[stop_index] ~= context.build.item_citation_number_text[stop_index] then
- break
- end
- if citation_numbers[stop_index - 1] + 1 ~= citation_numbers[stop_index] then
- break
- end
- stop_index = stop_index + 1
- end
- end
-
- if stop_index >= index + 3 then
- local range_text = output[index] .. citation_number_range_delimiter .. output[stop_index - 1]
- table.insert(collapsed_output, range_text)
- else
- for i = index, stop_index - 1 do
- table.insert(collapsed_output, output[i])
- end
- end
-
- index = stop_index
- end
-
- return self:concat(collapsed_output, context)
end
- return self:concat(output, context)
+ return ir
end
diff --git a/biblio/citation-style-language/citeproc-node-locale.lua b/biblio/citation-style-language/citeproc-node-locale.lua
index 92a604992c..0e8cdd0787 100644
--- a/biblio/citation-style-language/citeproc-node-locale.lua
+++ b/biblio/citation-style-language/citeproc-node-locale.lua
@@ -6,127 +6,227 @@
local locale = {}
-local element = require("citeproc-element")
-
+local Element = require("citeproc-element").Element
+local util = require("citeproc-util")
+
+
+local Locale = Element:derive("locale")
+
+function Locale:new()
+ local o = {
+ xml_lang = nil,
+ terms = {},
+ ordinal_terms = nil,
+ dates = {},
+ style_options = {
+ -- limit_day_ordinals_to_day_1 = false,
+ -- punctuation_in_quote = false,
+ },
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
-local Locale = element.Element:new()
+function Locale:from_node(node)
+ local o = Locale:new()
+ o.xml_lang = node:get_attribute("xml:lang")
+ o:process_children_nodes(node)
+
+ for _, child in ipairs(o.children) do
+ local element_name = child.element_name
+ if element_name == "terms" then
+ o.terms = child.terms_map
+ o.ordinal_terms = child.ordinal_terms
+ elseif element_name == "date" then
+ o.dates[child.form] = child
+ end
+ end
-function Locale:get_option (key)
- local query = string.format("style-options[%s]", key)
- local option = self:query_selector(query)[1]
- if option then
- local value = option:get_attribute(key)
- if self.option_type[key] == "integer" then
- value = tonumber(value)
- elseif self.option_type[key] == "boolean" then
- value = (value == "true")
- end
- return value
- else
- return nil
+ for _, child in ipairs(node:get_children()) do
+ if child:is_element() and child:get_element_name() == "style-options" then
+ local style_options = child
+ o.style_options.limit_day_ordinals_to_day_1 = util.to_boolean(
+ style_options:get_attribute("limit-day-ordinals-to-day-1")
+ )
+ o.style_options.punctuation_in_quote = util.to_boolean(
+ style_options:get_attribute("punctuation-in-quote")
+ )
+ end
end
-end
-function Locale:get_term (name, form, number, gender)
+ return o
+end
- if form == "long" then
- form = nil
+function Locale:merge(other)
+ for key, value in pairs(other.terms) do
+ self.terms[key] = value
end
-
- local match_last
- local match_last_two
- local match_whole
- if number then
- assert(type(number) == "number")
- match_last = string.format("%s-%02d", name, number % 10)
- match_last_two = string.format("%s-%02d", name, number % 100)
- match_whole = string.format("%s-%02s", name, number)
+ -- https://docs.citationstyles.org/en/stable/specification.html#ordinal-suffixes
+ -- The “ordinal” term, and “ordinal-00” through “ordinal-99” terms, behave
+ -- differently from other terms when it comes to Locale Fallback.
+ -- Whereas other terms can be (re)defined individually, (re)defining any of
+ -- the ordinal terms through cs:locale replaces all previously defined
+ -- ordinal terms.
+ if other.ordinal_terms then
+ self.ordinal_terms = other.ordinal_terms
+ end
+ for key, value in pairs(other.dates) do
+ self.dates[key] = value
end
+ for key, value in pairs(other.style_options) do
+ if value ~= nil then
+ self.style_options[key] = value
+ end
+ end
+ return self
+end
- local res = nil
- for _, term in ipairs(self:query_selector("term")) do
- -- Use get_path?
- local match_name = name
-
- if number then
- local term_match = term:get_attribute("last-two-digits")
- if term_match == "whole-number" then
- match_name = match_whole
- elseif term_match == "last-two-digits" then
- match_name = match_last_two
- elseif number < 10 then
- -- "13" can match only "ordinal-13" not "ordinal-03"
- -- It is sliced to "3" in a later checking pass.
- match_name = match_last_two
+Locale.form_fallbacks = {
+ ["verb-short"] = {"verb-short", "verb", "long"},
+ ["verb"] = {"verb", "long"},
+ ["symbol"] = {"symbol", "short", "long"},
+ ["short"] = {"short", "long"},
+ ["long"] = {"long"},
+}
+
+-- Keep in sync with Terms:from_node
+function Locale:get_simple_term(name, form, plural)
+ form = form or "long"
+ for _, fallback_form in ipairs(self.form_fallbacks[form]) do
+ local key = name
+ if form ~= "long" then
+ if not key then print(debug.traceback()) end
+ key = key .. "/form-" .. fallback_form
+ end
+ local term = self.terms[key]
+ if term then
+ if plural then
+ return term.multiple or term.text
else
- match_name = match_last
+ return term.single or term.text
end
end
+ end
+ return nil
+end
- local term_name = term:get_attribute("name")
- local term_form = term:get_attribute("form")
- if term_form == "long" then
- term_form = nil
- end
- local term_gender = term:get_attribute("gender-form")
+function Locale:get_ordinal_term(number, gender)
+ -- TODO: match and gender
- if term_name == match_name and term_form == form and term_gender == gender then
- return term
- end
+ local keys = {}
+ if gender then
+ if number < 100 then
+ table.insert(keys, string.format("ordinal-%02d/gender-form-%s/match-whole-number", number, gender))
+ end
+ table.insert(keys, string.format("ordinal-%02d/gender-form-%s/match-last-two-digits", number % 100, gender))
+ table.insert(keys, string.format("ordinal-%02d/gender-form-%s/match-last-digit", number % 10, gender))
end
- -- Fallback
- if form == "verb-sort" then
- return self:get_term(name, "verb")
- elseif form == "symbol" then
- return self:get_term(name, "short")
- elseif form == "verb" then
- return self:get_term(name, "long")
- elseif form == "short" then
- return self:get_term(name, "long")
+ if number < 100 then
+ table.insert(keys, string.format("ordinal-%02d/match-whole-number", number))
end
-
- if number and number > 10 then
- return self:get_term(name, nil, number % 10, gender)
+ table.insert(keys, string.format("ordinal-%02d/match-last-two-digits", number % 100))
+ table.insert(keys, string.format("ordinal-%02d/match-last-digit", number % 10))
+ table.insert(keys, "ordinal")
+
+ for _, key in ipairs(keys) do
+ local term = self.ordinal_terms[key]
+ if term then
+ return term.text
+ end
end
+ return nil
+end
- if gender then
- return self:get_term(name, nil, number, nil)
+function Locale:get_number_gender(name)
+ local term = self.terms[name]
+ if term and term.gender then
+ return term.gender
+ else
+ return nil
end
+end
- if number then
- return self:get_term(name, nil, nil, nil)
- end
- return nil
+local Terms = Element:derive("terms")
+
+function Terms:new()
+ local o = Element.new(self)
+ o.element_name = "terms"
+ o.children = {}
+ o.terms_map = {}
+ o.ordinal_terms = nil
+ return o
end
-local Term = element.Element:new()
+function Terms:from_node(node)
+ local o = Terms:new()
+ o:process_children_nodes(node)
+ for _, term in ipairs(o.children) do
+ local form = term.form
+ local gender = term.gender
+ local gender_form = term.gender_form
+ local match
+ if util.startswith(term.name, "ordinal-0") then
+ match = term.match or "last-digit"
+ elseif util.startswith(term.name, "ordinal-") then
+ match = term.match or "last-two-digits"
+ end
-function Term:render (context, is_plural)
- self:debug_info(context)
- context = self:process_context(context)
+ local key = term.name
+ if form then
+ key = key .. '/form-' .. form
+ end
+ -- if gender then
+ -- key = key .. '/gender-' .. gender
+ -- end
+ if gender_form then
+ key = key .. '/gender-form-' .. gender_form
+ end
+ if match then
+ key = key .. '/match-' .. match
+ end
- local output = {
- single = self:get_text(),
- }
- for _, child in ipairs(self:get_children()) do
- if child:is_element() then
- output[child:get_element_name()] = self:escape(child:get_text())
+ if term.name == "ordinal" or util.startswith(term.name, "ordinal-") then
+ if not o.ordinal_terms then
+ o.ordinal_terms = {}
+ end
+ o.ordinal_terms[key] = term
+ else
+ o.terms_map[key] = term
end
end
- local res = output.single
- if is_plural then
- if output.multiple then
- res = output.multiple
+ return o
+end
+
+
+local Term = Element:derive("term")
+
+function Term:from_node(node)
+ local o = Term:new()
+
+ o.name = node:get_attribute("name")
+ o.form = node:get_attribute("form")
+ o.match = node:get_attribute("match")
+ o.gender = node:get_attribute("gender")
+ o.gender_form = node:get_attribute("gender-form")
+ o.text = node:get_text()
+ for _, child in ipairs(node:get_children()) do
+ if child:is_element() then
+ local element_name = child:get_element_name()
+ if element_name == "single" then
+ o.single = child:get_text()
+ o.text = o.single
+ elseif element_name == "multiple" then
+ o.multiple = child:get_text()
+ end
end
end
- if res == "" then
- return nil
- end
- return res
+
+ return o
end
diff --git a/biblio/citation-style-language/citeproc-node-names.lua b/biblio/citation-style-language/citeproc-node-names.lua
index 72096a58f9..2f02367eea 100644
--- a/biblio/citation-style-language/citeproc-node-names.lua
+++ b/biblio/citation-style-language/citeproc-node-names.lua
@@ -8,320 +8,839 @@ local names_module = {}
local unicode = require("unicode")
-local richtext = require("citeproc-richtext")
-local element = require("citeproc-element")
+local IrNode = require("citeproc-ir-node").IrNode
+local NameIr = require("citeproc-ir-node").NameIr
+local PersonNameIr = require("citeproc-ir-node").PersonNameIr
+local SeqIr = require("citeproc-ir-node").SeqIr
+local Rendered = require("citeproc-ir-node").Rendered
+local InlineElement = require("citeproc-output").InlineElement
+local PlainText = require("citeproc-output").PlainText
+local SortStringFormat = require("citeproc-output").SortStringFormat
+
+local Element = require("citeproc-element").Element
local util = require("citeproc-util")
-local Name = element.Element:new()
-
-Name.default_options = {
- ["delimiter"] = ", ",
- ["delimiter-precedes-et-al"] = "contextual",
- ["delimiter-precedes-last"] = "contextual",
- ["et-al-min"] = nil,
- ["et-al-use-first"] = nil,
- ["et-al-subsequent-min"] = nil,
- ["et-al-subsequent-use-first "] = nil,
- ["et-al-use-last"] = false,
- ["form"] = "long",
- ["initialize"] = true,
- ["initialize-with"] = false,
- ["name-as-sort-order"] = false,
- ["sort-separator"] = ", ",
- ["prefix"] = "",
- ["suffix"] = "",
-}
-
-function Name:render (names, context)
- self:debug_info(context)
- context = self:process_context(context)
-
- local and_ = context.options["and"]
- local delimiter = context.options["delimiter"]
- local delimiter_precedes_et_al = context.options["delimiter-precedes-et-al"]
- local delimiter_precedes_last = context.options["delimiter-precedes-last"]
- local et_al_min = context.options["et-al-min"]
- local et_al_use_first = context.options["et-al-use-first"]
- local et_al_subsequent_min = context.options["et-al-subsequent-min"]
- local et_al_subsequent_use_first = context.options["et-al-subsequent-use-first "]
- local et_al_use_last = context.options["et-al-use-last"]
-
- -- sorting
- if context.options["names-min"] then
- et_al_min = context.options["names-min"]
- end
- if context.options["names-use-first"] then
- et_al_use_first = context.options["names-use-first"]
- end
- if context.options["names-use-last"] ~= nil then
- et_al_use_last = context.options["names-use-last"]
- end
-
- local form = context.options["form"]
-
- local et_al_truncate = et_al_min and et_al_use_first and #names >= et_al_min
- local et_al_last = et_al_use_last and et_al_use_first <= et_al_min - 2
-
- if form == "count" then
- if et_al_truncate then
- return et_al_use_first
+local Names = Element:derive("names")
+local Name = Element:derive("name", {
+ delimiter = ", ",
+ delimiter_precedes_et_al = "contextual",
+ delimiter_precedes_last = "contextual",
+ et_al_use_last = false,
+ form = "long",
+ initialize = true,
+ sort_separator = ", ",
+})
+local NamePart = Element:derive("name-part")
+local EtAl = Element:derive("et-al")
+local Substitute = Element:derive("substitute")
+
+
+-- [Names](https://docs.citationstyles.org/en/stable/specification.html#names)
+function Names:new()
+ local o = Element.new(self)
+ o.name = nil
+ o.et_al = nil
+ o.substitute = nil
+ o.label = nil
+ return o
+end
+
+function Names:from_node(node)
+ local o = Names:new()
+ o:set_attribute(node, "variable")
+ o.name = nil
+ o.et_al = nil
+ o.substitute = nil
+ o.label = nil
+ o.children = {}
+ o:process_children_nodes(node)
+ for _, child in ipairs(o.children) do
+ local element_name = child.element_name
+ if element_name == "name" then
+ o.name = child
+ elseif element_name == "et-al" then
+ o.et_al = child
+ elseif element_name == "substitute" then
+ o.substitute = child
+ elseif element_name == "label" then
+ o.label = child
+ if o.name then
+ child.after_name = true
+ end
else
- return #names
+ util.warning(string.format('Unkown element "{}".', element_name))
end
end
+ o:get_delimiter_attribute(node)
+ o:set_affixes_attributes(node)
+ o:set_display_attribute(node)
+ o:set_formatting_attributes(node)
+ o:set_text_case_attribute(node)
+ return o
+end
- local output = nil
+function Names:build_ir(engine, state, context)
+ -- names_inheritance: names and name attributes inherited from cs:style
+ -- and cs:citaiton or cs:bibliography
+ -- name_override: names, name, et-al, label elements inherited in substitute element
+ local names_inheritance = Names:new()
+ names_inheritance.delimiter = context.name_inheritance.names_delimiter
- local res = nil
- local inverted = false
+ names_inheritance.variable = self.variable
- for i, name in ipairs(names) do
- if et_al_truncate and i > et_al_use_first then
- if et_al_last then
- if i == #names then
- output = richtext.concat(output, delimiter)
- output = output .. util.unicode["horizontal ellipsis"]
- output = output .. " "
- res = self:render_single_name(name, i, context)
- output = output .. res
- end
- else
- if not self:_check_delimiter(delimiter_precedes_et_al, i, inverted) then
- delimiter = " "
- end
- if output then
- output = richtext.concat_list({output, context.et_al:render(context)}, delimiter)
+ for _, attr in ipairs({"delimiter", "affixes", "formatting", "display"}) do
+ if self[attr] then
+ names_inheritance[attr] = util.clone(self[attr])
+ elseif state.name_override and state.name_override[attr] then
+ names_inheritance[attr] = util.clone(state.name_override[attr])
+ end
+ end
+
+ if self.name then
+ names_inheritance.name = util.clone(context.name_inheritance)
+ for key, value in pairs(self.name) do
+ names_inheritance.name[key] = util.clone(value)
+ end
+ else
+ if state.name_override then
+ names_inheritance.name = util.clone(state.name_override.name)
+ else
+ names_inheritance.name = util.clone(context.name_inheritance)
+ end
+ end
+
+ if self.et_al then
+ names_inheritance.et_al = util.clone(self.et_al)
+ elseif state.name_override then
+ names_inheritance.et_al = util.clone(state.name_override.et_al)
+ else
+ names_inheritance.et_al = EtAl:new()
+ end
+
+ if self.label then
+ names_inheritance.label = util.clone(self.label)
+ elseif state.name_override then
+ names_inheritance.label = util.clone(state.name_override.label)
+ end
+
+ if context.cite then
+ local position_level = context.cite.position or context.cite.position_level
+ if position_level and position_level >= util.position_map["subsequent"] then
+ if names_inheritance.name.et_al_subsequent_min then
+ names_inheritance.name.et_al_min = names_inheritance.name.et_al_subsequent_min
+ end
+ if names_inheritance.name.et_al_subsequent_use_first then
+ names_inheritance.name.et_al_use_first = names_inheritance.name.et_al_subsequent_use_first
+ end
+ end
+ end
+
+ local irs = {}
+ local num_names = 0
+ -- util.debug(self.name)
+
+ -- The names element may not hold a variable attribute.
+ -- substitute_SubstituteOnlyOnceString.txt
+ if names_inheritance.variable then
+ for _, variable in ipairs(util.split(names_inheritance.variable)) do
+ local name_ir = names_inheritance.name:build_ir(variable, names_inheritance.et_al, names_inheritance.label, engine, state, context)
+ if name_ir and names_inheritance.name.form == "count" then
+ num_names = num_names + name_ir.name_count
+ end
+ if name_ir and name_ir.group_var ~= "missing" then
+ table.insert(irs, name_ir)
+ end
+ end
+ end
+
+ if names_inheritance.name.form == "count" then
+ if num_names > 0 then
+ local ir = Rendered:new({PlainText:new(tostring(num_names))}, self)
+ ir.name_count = num_names
+ ir.group_var = "important"
+ ir = NameIr:new({ir}, self)
+ ir.name_count = num_names
+ ir.group_var = "important"
+ -- util.debug(ir)
+ return ir
+ end
+ else
+ if #irs > 0 then
+ local ir = SeqIr:new(irs, self)
+ ir.group_var = "important"
+ ir.delimiter = names_inheritance.delimiter
+ ir.formatting = util.clone(names_inheritance.formatting)
+ ir.affixes = util.clone(names_inheritance.affixes)
+ ir.display = names_inheritance.display
+ return ir
+ end
+ end
+
+ if self.substitute then
+ local new_state = util.clone(state)
+ new_state.name_override = names_inheritance
+ for _, substitution in ipairs(self.substitute.children) do
+ local ir = substitution:build_ir(engine, new_state, context)
+ if ir and ir.group_var ~= "missing" then
+ if not ir.person_name_irs or #ir.person_name_irs == 0 then
+ -- In case of a <text variable="title"/> in <substitute>
+ local name_count = ir.name_count
+ ir = NameIr:new({ir}, self)
+ ir.name_count = name_count -- sort_AguStyle.txt
+ ir.group_var = "important"
end
- break
+ return ir
end
- else
- if i > 1 then
- if i == #names and context.options["and"] then
- if self:_check_delimiter(delimiter_precedes_last, i, inverted) then
- output = richtext.concat(output, delimiter)
- else
- output = output .. " "
- end
- local and_term = ""
- if context.options["and"] == "text" then
- and_term = self:get_term("and"):render(context)
- elseif context.options["and"] == "symbol" then
- and_term = self:escape("&")
- end
- output = output .. and_term .. " "
+ end
+ end
+
+ local ir = Rendered:new({}, self)
+ ir.group_var = "missing"
+ return ir
+
+end
+
+
+function Names:substitute_single_field(result, context)
+ if not result then
+ return nil
+ end
+ if context.build.first_rendered_names and #context.build.first_rendered_names == 0 then
+ context.build.first_rendered_names[1] = result
+ end
+ result = self:substitute_names(result, context)
+ return result
+end
+
+function Names:substitute_names(result, context)
+ if not context.build.first_rendered_names then
+ return result
+ end
+ local name_strings = {}
+ local match_all
+
+ if #context.build.first_rendered_names > 0 then
+ match_all = true
+ else
+ match_all = false
+ end
+ for i, text in ipairs(context.build.first_rendered_names) do
+ local str = text:render(context.engine.formatter, context)
+ name_strings[i] = str
+ if context.build.preceding_first_rendered_names and str ~= context.build.preceding_first_rendered_names[i] then
+ match_all = false
+ end
+ end
+
+ if context.build.preceding_first_rendered_names then
+ local sub_str = context.options["subsequent-author-substitute"]
+ local sub_rule = context.options["subsequent-author-substitute-rule"]
+
+ if sub_rule == "complete-all" then
+ if match_all then
+ if sub_str == "" then
+ result = nil
else
- output = richtext.concat(output, delimiter)
+ result.contents = {sub_str}
end
end
- res, inverted = self:render_single_name(name, i, context)
- if res and res ~= "" then
- res = richtext.new(res)
- if context.build.first_rendered_names then
- table.insert(context.build.first_rendered_names, res)
+ elseif sub_rule == "complete-each" then
+ -- In-place substitution
+ if match_all then
+ for _, text in ipairs(context.build.first_rendered_names) do
+ text.contents = {sub_str}
end
+ result = self:concat(context.build.first_rendered_names, context)
+ end
- if output then
- output = richtext.concat(output, res)
+ elseif sub_rule == "partial-each" then
+ for i, text in ipairs(context.build.first_rendered_names) do
+ if name_strings[i] == context.build.preceding_first_rendered_names[i] then
+ text.contents = {sub_str}
else
- output = res
+ break
end
end
+ result = self:concat(context.build.first_rendered_names, context)
+
+ elseif sub_rule == "partial-first" then
+ if name_strings[1] == context.build.preceding_first_rendered_names[1] then
+ context.build.first_rendered_names[1].contents = {sub_str}
+ end
+ result = self:concat(context.build.first_rendered_names, context)
end
end
- local ret = self:format(output, context)
- ret = self:wrap(ret, context)
- return ret
+ if #context.build.first_rendered_names > 0 then
+ context.build.first_rendered_names = nil
+ end
+ context.build.preceding_first_rendered_names = name_strings
+ return result
end
-function Name:_check_delimiter (delimiter_attribute, index, inverted)
- -- `delimiter-precedes-et-al` and `delimiter-precedes-last`
- if delimiter_attribute == "always" then
- return true
- elseif delimiter_attribute == "never" then
- return false
- elseif delimiter_attribute == "contextual" then
- if index > 2 then
- return true
- else
- return false
- end
- elseif delimiter_attribute == "after-inverted-name" then
- if inverted then
- return true
- else
- return false
+-- [Name](https://docs.citationstyles.org/en/stable/specification.html#name)
+function Name:new()
+ local o = Element.new(self, "name")
+
+ o.family = NamePart:new("family")
+ o.given = NamePart:new("given")
+ return o
+end
+
+function Name:from_node(node)
+ local o = Name:new()
+ o:set_attribute(node, "and")
+ o:get_delimiter_attribute(node)
+ o:set_attribute(node, "delimiter-precedes-et-al")
+ o:set_attribute(node, "delimiter-precedes-last")
+ o:set_number_attribute(node, "et-al-min")
+ o:set_number_attribute(node, "et-al-use-first")
+ o:set_number_attribute(node, "et-al-subsequent-min")
+ o:set_number_attribute(node, "et-al-subsequent-use-first")
+ o:set_bool_attribute(node, "et-al-use-last")
+ o:set_attribute(node, "form")
+ o:set_bool_attribute(node, "initialize")
+ o:set_attribute(node, "initialize-with")
+ o:set_attribute(node, "name-as-sort-order")
+ o:set_attribute(node, "sort-separator")
+ o:set_affixes_attributes(node)
+ o:set_formatting_attributes(node)
+ o:process_children_nodes(node)
+ for _, child in ipairs(o.children) do
+ if child.name == "family" then
+ o.family = child
+ elseif child.name == "given" then
+ o.given = child
end
end
- return false
+ if not o.family then
+ o.family = NamePart:new()
+ o.family.name = "family"
+ end
+ if not o.given then
+ o.given = NamePart:new()
+ o.family.name = "given"
+ end
+ return o
end
-function Name:render_single_name (name, index, context)
- local form = context.options["form"]
- local initialize = context.options["initialize"]
- local initialize_with = context.options["initialize-with"]
- local name_as_sort_order = context.options["name-as-sort-order"]
- if context.sorting then
- name_as_sort_order = "all"
+
+function Name:build_ir(variable, et_al, label, engine, state, context)
+ -- Returns NameIR
+ local names
+ if not state.suppressed[variable] then
+ names = context:get_variable(variable)
+ end
+ if not names then
+ return nil
end
- local sort_separator = context.options["sort-separator"]
- local demote_non_dropping_particle = context.options["demote-non-dropping-particle"]
+ if context.sort_key then
+ self.delimiter = " "
+ self.name_as_sort_order = "all"
+ if context.sort_key.names_min then
+ self.et_al_min = context.sort_key.names_min
+ end
+ if context.sort_key.names_use_first then
+ self.et_al_use_first = context.sort_key.names_use_first
+ end
+ if context.sort_key.names_use_last then
+ self.et_al_use_last = context.sort_key.names_use_last
+ end
+ et_al = nil
+ label = nil
+ end
- -- TODO: make it a module
- local function _strip_quotes(str)
- if str then
- str = string.gsub(str, '"', "")
- str = string.gsub(str, "'", util.unicode["apostrophe"])
+ local et_al_abbreviation = self.et_al_min and self.et_al_use_first and #names >= self.et_al_min
+ local use_last = et_al_abbreviation and self.et_al_use_last and self.et_al_use_first <= self.et_al_min - 2
+
+ if self.form == "count" then
+ local count
+ if et_al_abbreviation then
+ count = self.et_al_use_first
+ else
+ count = #names
end
- return str
+ local ir = Rendered:new({PlainText:new(tostring(count))}, {})
+ ir.name_count = count
+ ir.group_var = "important"
+ return ir
end
- local family = _strip_quotes(name["family"]) or ""
- local given = _strip_quotes(name["given"]) or ""
- local dp = _strip_quotes(name["dropping-particle"]) or ""
- local ndp = _strip_quotes(name["non-dropping-particle"]) or ""
- local suffix = _strip_quotes(name["suffix"]) or ""
- local literal = _strip_quotes(name["literal"]) or ""
+ -- TODO: only build names as needed
+ local full_name_irs = {}
+ local full_name_str = ""
+ for i, name_var in ipairs(names) do
+ local person_name_ir = self:build_person_name_ir(name_var, i == 1, context)
+ table.insert(full_name_irs, person_name_ir)
- if family == "" then
- family = literal
- if family == "" then
- family = given
- given = ""
+ local name_variants = person_name_ir.disam_variants
+ if full_name_str ~= "" then
+ full_name_str = full_name_str .. " "
end
- if family ~= "" then
- return family
- else
- error("Name not avaliable")
+ full_name_str = full_name_str .. name_variants[#name_variants]
+ end
+
+ local person_name_irs -- TODO: rename to rendered_name_irs
+ local hidden_name_irs
+ if et_al_abbreviation then
+ person_name_irs = util.slice(full_name_irs, 1, self.et_al_use_first)
+ hidden_name_irs = util.slice(full_name_irs, self.et_al_use_first + 1, #full_name_irs)
+ if use_last then
+ table.insert(person_name_irs, full_name_irs[#full_name_irs])
+ table.remove(hidden_name_irs, #hidden_name_irs)
+ end
+ else
+ person_name_irs = util.slice(full_name_irs, 1, #full_name_irs)
+ hidden_name_irs = {}
+ end
+
+
+ local and_term_ir
+ if not context.sort_key then
+ -- sort_WithAndInOneEntry.txt
+ local and_term
+ if self["and"] == "text" then
+ and_term = context.locale:get_simple_term("and")
+ elseif self["and"] == "symbol" then
+ and_term = "&"
+ end
+ if and_term then
+ and_term_ir = Rendered:new({PlainText:new(and_term .. " ")}, {})
end
end
- if initialize_with then
- given = self:initialize(given, initialize_with, context)
+ local et_al_ir
+ if et_al and et_al_abbreviation and not use_last then
+ et_al_ir = et_al:build_ir(engine, state, context)
end
- local demote_ndp = false -- only active when form == "long"
- if demote_non_dropping_particle == "display-and-sort" or
- demote_non_dropping_particle == "sort-only" and context.sorting then
- demote_ndp = true
- else -- demote_non_dropping_particle == "never"
- demote_ndp = false
+ local irs = self:join_person_name_irs(person_name_irs, and_term_ir, et_al_ir, use_last)
+
+ local ir = NameIr:new(irs, self)
+
+ ir.name_inheritance = self
+ ir.name_variable = names
+ ir.and_term_ir = and_term_ir
+ ir.et_al_ir = et_al_ir
+ ir.et_al_abbreviation = et_al_abbreviation
+ ir.use_last = use_last
+
+ ir.full_name_irs = full_name_irs
+ ir.full_name_str = full_name_str
+ ir.person_name_irs = person_name_irs
+ ir.hidden_name_irs = hidden_name_irs
+
+ -- etal_UseZeroFirst.txt: et-al-use-first="0"
+ if #irs == 0 then
+ ir.group_var = "missing"
+ return ir
+ else
+ ir.group_var = "important"
end
- local family_name_part = nil
- local given_name_part = nil
- for _, child in ipairs(self:get_children()) do
- if child:is_element() and child:get_element_name() == "name-part" then
- local name_part = child:get_attribute("name")
- if name_part == "family" then
- family_name_part = child
- elseif name_part == "given" then
- given_name_part = child
+ ir.formatting = self.formatting
+ ir.affixes = self.affixes
+
+ irs = {ir}
+
+ if label then
+ local is_plural = (label.plural == "always" or (label.plural == "contextual" and #names > 1))
+ local label_term = context.locale:get_simple_term(variable, label.form, is_plural)
+ if label_term and label_term ~= "" then
+ local inlines = label:render_text_inlines(label_term, context)
+ local label_ir = Rendered:new(inlines, label)
+ if label.after_name then
+ table.insert(irs, label_ir)
+ else
+ table.insert(irs, 1, label_ir)
end
end
end
- local res = nil
- local inverted = false
- if form == "long" then
- local order
- local suffix_separator = sort_separator
- if not util.has_romanesque_char(name["family"]) then
- order = {family, given}
- inverted = true
- sort_separator = ""
- elseif name_as_sort_order == "all" or (name_as_sort_order == "first" and index == 1) then
-
- -- "Alan al-One"
- local hyphen_parts = util.split(family, "%-", 1)
- if #hyphen_parts > 1 then
- local particle
- particle, family = table.unpack(hyphen_parts)
- particle = particle .. "-"
- ndp = richtext.concat(ndp, particle)
+ ir = SeqIr:new(irs, self)
+
+ -- Suppress substituted name variable
+ if state.name_override and not context.sort_key then
+ state.suppressed[variable] = true
+ end
+
+ return ir
+end
+
+function Name:build_person_name_ir(name, is_first, context)
+ local is_latin = util.has_romanesque_char(name.family)
+ local is_inverted = (name.family and name.family ~= "" and is_latin and
+ (self.name_as_sort_order == "all" or (self.name_as_sort_order == "first" and is_first)))
+
+ local inlines = self:render_person_name(name, is_first, is_latin, is_inverted, context)
+ local person_name_ir = PersonNameIr:new(inlines, self)
+
+ person_name_ir.is_inverted = is_inverted
+
+ local output_format = SortStringFormat:new()
+ person_name_ir.name_output = output_format:output(inlines)
+ person_name_ir.disam_variants_index = 1
+
+ person_name_ir.disam_variants = {person_name_ir.name_output}
+ person_name_ir.disam_inlines = {inlines}
+
+ if context.area.disambiguate_add_givenname and not context.sort_key then
+ local disam_name = util.clone(self)
+ if disam_name.form == "short" then
+ disam_name.form = "long"
+ if disam_name.initialize and disam_name.initialize_with then
+ local name_inlines = disam_name:render_person_name(name, is_first, is_latin, is_inverted, context)
+ local disam_variant = output_format:output(name_inlines)
+ local last_variant = person_name_ir.disam_variants[#person_name_ir.disam_variants]
+ if disam_variant ~= last_variant then
+ table.insert(person_name_ir.disam_variants, disam_variant)
+ person_name_ir.disam_inlines[disam_variant] = name_inlines
+ end
end
+ end
- if family_name_part then
- family = family_name_part:format_name_part(family, context)
- ndp = family_name_part:format_name_part(ndp, context)
+ local givenname_disambiguation_rule = context.area.givenname_disambiguation_rule
+ local only_initials = (givenname_disambiguation_rule == "all-names-with-initials" or
+ givenname_disambiguation_rule == "primary-name-with-initials")
+ if disam_name.initialize and not only_initials then
+ disam_name.initialize = false
+ local name_inlines = disam_name:render_person_name(name, is_first, is_latin, is_inverted, context)
+ local disam_variant = output_format:output(name_inlines)
+ local last_variant = person_name_ir.disam_variants[#person_name_ir.disam_variants]
+ if disam_variant ~= last_variant then
+ table.insert(person_name_ir.disam_variants, disam_variant)
+ person_name_ir.disam_inlines[disam_variant] = name_inlines
end
- if given_name_part then
- given = given_name_part:format_name_part(given, context)
- dp = family_name_part:format_name_part(dp, context)
+ end
+
+ context.sort_key = true
+ local full_name_inlines = disam_name:render_person_name(name, is_first, is_latin, is_inverted, context)
+ -- full_name is used for comparison in disambiguation
+ person_name_ir.full_name = output_format:output(full_name_inlines)
+ context.sort_key = false
+ end
+
+ return person_name_ir
+end
+
+function Name:render_person_name(name, is_first, is_latin, is_inverted, context)
+ -- Return: inlines
+ -- TODO
+ local is_sort = context.sort_key
+ local demote_ndp = (context.style.demote_non_dropping_particle == "display-and-sort" or
+ (is_sort and context.style.demote_non_dropping_particle == "sort-only"))
+
+ local name_part_tokens = self:get_display_order(name, self.form, is_latin, is_sort, is_inverted, demote_ndp)
+ -- util.debug(name)
+ -- util.debug(name_part_tokens)
+
+ local inlines = {}
+ for i, token in ipairs(name_part_tokens) do
+ if token == "family" or token == "ndp-family" or token == "dp-ndp-family-suffix" then
+ local family_inlines = self:render_family(name, token, context)
+ util.extend(inlines, family_inlines)
+
+ elseif token == "given" or token == "given-dp" or token == "given-dp-ndp" then
+ local given_inlines = self:render_given(name, token, context)
+ util.extend(inlines, given_inlines)
+
+ elseif token == "dp" or token == "dp-ndp" then
+ local particle_inlines = self:render_particle(name, token, context)
+ util.extend(inlines, particle_inlines)
+
+ elseif token == "suffix" then
+ local text = name.suffix or ""
+ util.extend(inlines, InlineElement:parse(text, context))
+
+ elseif token == "literal" then
+ local literal_inlines = self.family:format_text_case(name.literal, context)
+ util.extend(inlines, literal_inlines)
+
+ elseif token == "space" then
+ table.insert(inlines, PlainText:new(" "))
+
+ elseif token == "wide-space" then
+ table.insert(inlines, PlainText:new(" "))
+
+ elseif token == "sort-separator" then
+ table.insert(inlines, PlainText:new(self.sort_separator))
+ end
+ end
+ -- util.debug(inlines)
+ return inlines
+end
+
+-- Name-part Order
+-- https://docs.citationstyles.org/en/stable/specification.html#name-part-order
+function Name:get_display_order(name, form, is_latin, is_sort, is_inverted, demote_ndp)
+ if is_sort then
+ if not name.family then
+ -- The literal is compared with the literal
+ if self.form == "long" then
+ return {"literal", "wide-space", "wide-space", "wide-space"}
+ else
+ return {"literal", "wide-space"}
end
+ end
+ if not is_latin then
+ if form == "long" and name.given then
+ return {"family", "given"}
+ else
+ return {"family"}
+ end
+ end
+
+ if self.form == "long" then
if demote_ndp then
- given = richtext.concat_list({given, dp, ndp}, " ")
+ return {"family", "wide-space", "dp-ndp", "wide-space", "given", "wide-space", "suffix"}
else
- family = richtext.concat_list({ndp, family}, " ")
- given = richtext.concat_list({given, dp}, " ")
+ return {"ndp-family", "wide-space", "dp", "wide-space", "given", "wide-space", "suffix"}
end
+ else
+ if demote_ndp then
+ return {"family", "wide-space", "dp-ndp"}
+ else
+ return {"ndp-family", "wide-space", "dp"}
+ end
+ end
+ end
+
+ if not name.family then
+ if name.literal then
+ return {"literal"}
+ else
+ util.error("Invalid name")
+ end
+ end
+
+ if not is_latin then
+ if form == "long" and name.given then
+ return {"family", "given"}
+ else
+ return {"family"}
+ end
+ end
- if family_name_part then
- family = family_name_part:wrap_name_part(family, context)
+ if form == "short" then
+ return {"ndp-family"}
+ end
+
+ local ndp = name["non-dropping-particle"]
+ local dp = name["dropping-particle"]
+
+ local name_part_tokens = {"family"}
+ if name.given then
+ if is_inverted then
+ if demote_ndp then
+ name_part_tokens = {"family", "sort-separator", "given-dp-ndp"}
+ else
+ name_part_tokens = {"ndp-family", "sort-separator", "given-dp"}
end
- if given_name_part then
- given = given_name_part:wrap_name_part(given, context)
+ else
+ name_part_tokens = {"given", "space", "dp-ndp-family-suffix"}
+ end
+ else
+ if is_inverted then
+ if demote_ndp then
+ if ndp or dp then
+ name_part_tokens = {"family", "sort-separator", "dp-ndp"}
+ else
+ name_part_tokens = {"family"}
+ end
+ else
+ name_part_tokens = {"ndp-family"}
end
+ else
+ name_part_tokens = {"dp-ndp-family-suffix"}
+ end
+ end
- order = {family, given, suffix}
- inverted = true
+ if name.suffix and is_inverted then
+ if is_inverted or name["comma-suffix"] then
+ table.insert(name_part_tokens, "sort-separator")
+ table.insert(name_part_tokens, "suffix")
+ elseif string.match(name.suffix, "^%p") then
+ table.insert(name_part_tokens, "sort-separator")
+ table.insert(name_part_tokens, "suffix")
else
- if family_name_part then
- family = family_name_part:format_name_part(family, context)
- ndp = family_name_part:format_name_part(ndp, context)
+ table.insert(name_part_tokens, "space")
+ table.insert(name_part_tokens, "suffix")
+ end
+ end
+
+ return name_part_tokens
+end
+
+function Name:render_family(name, token, context)
+ local inlines = {}
+ local name_part
+
+ if token == "dp-ndp-family-suffix" then
+ local dp_part = name["dropping-particle"]
+ if dp_part then
+ name_part = dp_part
+ local dp_inlines = self.given:format_text_case(dp_part, context)
+ util.extend(inlines, dp_inlines)
+ end
+ end
+
+ if token == "dp-ndp-family-suffix" or token == "ndp-family" then
+ local ndp_part = name["non-dropping-particle"]
+ if ndp_part then
+ if context.sort_key then
+ ndp_part = self:format_sort_particle(ndp_part)
end
- if given_name_part then
- given = given_name_part:format_name_part(given, context)
- dp = family_name_part:format_name_part(dp, context)
+ if #inlines > 0 then
+ table.insert(inlines, PlainText:new(" "))
end
+ name_part = ndp_part
+ local ndp_inlines = self.family:format_text_case(ndp_part, context)
+ util.extend(inlines, ndp_inlines)
+ end
+ end
- family = richtext.concat_list({dp, ndp, family}, " ")
- if name["comma-suffix"] then
- suffix_separator = ", "
+ local family = name.family
+ if context.sort_key then
+ -- Remove brackets for sorting: sort_NameVariable.txt
+ family = string.gsub(family, "[%[%]]", "")
+ end
+
+ local family_inlines = self.family:format_text_case(family, context)
+ if #inlines > 0 then
+ if not string.match(name_part, "^%l'$") and
+ not string.match(name_part, "^%l’$") and
+ not util.endswith(name_part, "-") then
+ table.insert(inlines, PlainText:new(" "))
+ end
+ end
+ util.extend(inlines, family_inlines)
+
+ if token == "dp-ndp-family-suffix" then
+ local suffix_part = name.suffix
+ if suffix_part then
+ if name["comma-suffix"] or util.startswith(suffix_part, "!") then
+ -- force use sort-separator exclamation prefix: magic_NameSuffixWithComma.txt
+ -- "! Jr." => "Jr."
+ table.insert(inlines, PlainText:new(self.sort_separator))
+ suffix_part = string.gsub(suffix_part, "^%p%s*", "")
else
- suffix_separator = " "
+ table.insert(inlines, PlainText:new(" "))
end
- family = richtext.concat_list({family, suffix}, suffix_separator)
+ table.insert(inlines, PlainText:new(suffix_part))
+ end
+ end
- if family_name_part then
- family = family_name_part:wrap_name_part(family, context)
- end
- if given_name_part then
- given = given_name_part:wrap_name_part(given, context)
- end
+ inlines = self.family:affixed(inlines)
+ return inlines
+end
+
+function Name:render_given(name, token, context)
+ local given = name.given
- order = {given, family}
- sort_separator = " "
+ if context.sort_key then
+ -- The empty given name is needed for evaluate the sort key.
+ if not given then
+ return {PlainText:new("")}
end
- res = richtext.concat_list(order, sort_separator)
+ -- Remove brackets for sorting: sort_NameVariable.txt
+ given = string.gsub(given, "[%[%]]", "")
+ end
- elseif form == "short" then
- if family_name_part then
- family = family_name_part:format_name_part(family, context)
- ndp = family_name_part:format_name_part(ndp, context)
+ if self.initialize_with then
+ given = self:initialize_name(given, self.initialize_with, context.style.initialize_with_hyphen)
+ end
+ local inlines = self.given:format_text_case(given, context)
+
+ if token == "given-dp" or token == "given-dp-ndp" then
+ local name_part = name["dropping-particle"]
+ if name_part then
+ table.insert(inlines, PlainText:new(" "))
+ local dp_inlines = self.given:format_text_case(name_part, context)
+ util.extend(inlines, dp_inlines)
end
- family = util.concat({ndp, family}, " ")
- if family_name_part then
- family = family_name_part:wrap_name_part(family, context)
+ end
+
+ if token == "given-dp-ndp" then
+ local name_part = name["non-dropping-particle"]
+ if name_part then
+ table.insert(inlines, PlainText:new(" "))
+ local ndp_inlines = self.family:format_text_case(name_part, context)
+ util.extend(inlines, ndp_inlines)
+ end
+ end
+
+ inlines = self.given:affixed(inlines)
+ return inlines
+end
+
+-- sort_LeadingApostropheOnNameParticle.txt
+-- "’t " => "t"
+function Name:format_sort_particle(particle)
+ particle = string.gsub(particle, "^'", "")
+ particle = string.gsub(particle, "^’", "")
+ return particle
+end
+
+function Name:render_particle(name, token, context)
+ local inlines = {}
+
+ local dp_part = name["dropping-particle"]
+ if dp_part then
+ dp_part = self:format_sort_particle(dp_part)
+ local dp_inlines = self.given:format_text_case(dp_part, context)
+ util.extend(inlines, dp_inlines)
+ end
+
+ if token == "dp-ndp" then
+ local ndp_part = name["non-dropping-particle"]
+ if ndp_part then
+ if #inlines > 0 then
+ table.insert(inlines, PlainText:new(" "))
end
- res = family
- else
- error(string.format('Invalid attribute form="%s" of "name".', form))
+ ndp_part = self:format_sort_particle(ndp_part)
+ local ndp_inlines = self.family:format_text_case(ndp_part, context)
+ util.extend(inlines, ndp_inlines)
+ end
+ end
+
+ return inlines
+end
+
+function Name:_check_delimiter(delimiter_attribute, num_first_names, inverted)
+ -- `delimiter-precedes-et-al` and `delimiter-precedes-last`
+ if delimiter_attribute == "always" then
+ return true
+ elseif delimiter_attribute == "never" then
+ return false
+ elseif delimiter_attribute == "contextual" then
+ if num_first_names > 1 then
+ return true
+ else
+ return false
+ end
+ elseif delimiter_attribute == "after-inverted-name" then
+ if inverted then
+ return true
+ else
+ return false
+ end
end
- return res, inverted
+ return false
end
-function Name:initialize (given, terminator, context)
+-- TODO: initialize name with markups
+-- name_InTextMarkupInitialize.txt
+-- name_InTextMarkupNormalizeInitials.txt
+function Name:initialize_name(given, with, initialize_with_hyphen)
if not given or given == "" then
return ""
end
- local initialize = context.options["initialize"]
- if context.options["initialize-with-hyphen"] == false then
+ if initialize_with_hyphen == false then
given = string.gsub(given, "-", " ")
end
@@ -367,9 +886,9 @@ function Name:initialize (given, terminator, context)
name_list[i-1] = name_list[i-1] .. " "
end
elseif is_abbreviation then
- name_list[i] = name .. terminator
+ name_list[i] = name .. with
else
- if initialize then
+ if self.initialize then
if util.is_upper(name) then
name = first_letter
else
@@ -389,7 +908,7 @@ function Name:initialize (given, terminator, context)
end
name = abbreviation
end
- name_list[i] = name .. terminator
+ name_list[i] = name .. with
else
name_list[i] = name .. " "
end
@@ -412,287 +931,176 @@ function Name:initialize (given, terminator, context)
end
-local NamePart = element.Element:new()
-
-function NamePart:format_name_part(name_part, context)
- context = self:process_context(context)
- local res = self:case(name_part, context)
- res = self:format(res, context)
- return res
-end
-
-function NamePart:wrap_name_part(name_part, context)
- context = self:process_context(context)
- local res = self:wrap(name_part, context)
- return res
-end
-
-
-local EtAl = element.Element:new()
-
-EtAl.default_options = {
- term = "et-al",
-}
-
-EtAl.render = function (self, context)
- self:debug_info(context)
- context = self:process_context(context)
- local res = self:get_term(context.options["term"]):render(context)
- res = self:format(res, context)
- return res
-end
-
-
-local Substitute = element.Element:new()
+function Name:join_person_name_irs(rendered_name_irs, and_term_ir, et_al_ir, use_last)
+ local first_items = rendered_name_irs
+ local last_item
+ if et_al_ir then
+ first_items = rendered_name_irs
+ last_item = et_al_ir
+ elseif #rendered_name_irs > 1 then
+ first_items = util.slice(rendered_name_irs, 1, #rendered_name_irs - 1)
+ last_item = rendered_name_irs[#rendered_name_irs]
+ end
-function Substitute:render (item, context)
- self:debug_info(context)
+ local irs = {}
- if context.suppressed_variables then
- -- true in layout, not in sort
- context.suppress_subsequent_variables = true
+ for i, person_name_ir in ipairs(first_items) do
+ if i > 1 then
+ table.insert(irs, Rendered:new({PlainText:new(self.delimiter)}, self))
+ end
+ table.insert(irs, person_name_ir)
end
- for i, child in ipairs(self:get_children()) do
- if child:is_element() then
- local result = child:render(item, context)
- if result and result ~= "" then
- return result
+ if last_item then
+ if use_last then
+ local delimiter = self.delimiter .. util.unicode["horizontal ellipsis"] .. " "
+ table.insert(irs, Rendered:new({PlainText:new(delimiter)}, self))
+ table.insert(irs, last_item)
+ elseif et_al_ir then
+ if #first_items > 0 then
+ local inverted = first_items[#first_items].is_inverted
+ local use_delimiter = self:_check_delimiter(self.delimiter_precedes_et_al, #first_items, inverted)
+ if use_delimiter then
+ table.insert(irs, Rendered:new({PlainText:new(self.delimiter)}, self))
+ elseif not et_al_ir.starts_with_cjk then
+ -- name_EtAlWithCombined.txt
+ table.insert(irs, Rendered:new({PlainText:new(" ")}, self))
+ end
+ table.insert(irs, last_item)
end
+ else
+ local inverted = first_items[#first_items].is_inverted
+ local use_delimiter = self:_check_delimiter(self.delimiter_precedes_last, #first_items, inverted)
+ if use_delimiter or not and_term_ir then
+ table.insert(irs, Rendered:new({PlainText:new(self.delimiter)}, self))
+ else
+ table.insert(irs, Rendered:new({PlainText:new(" ")}, self))
+ end
+ if and_term_ir and not et_al_ir then
+ table.insert(irs, and_term_ir)
+ end
+ table.insert(irs, last_item)
end
end
- return nil
-end
-
-local Names = element.Element:new()
-
-function Names:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
+ return irs
+end
- local names_delimiter = context.options["names-delimiter"]
- if names_delimiter then
- context.options["delimiter"] = names_delimiter
+-- For use in disambiguate-add-names
+function Name:expand_one_name(name_ir)
+ local rendered_name_irs = name_ir.person_name_irs
+ local hidden_name_irs = name_ir.hidden_name_irs
+ if #hidden_name_irs == 0 then
+ return nil
end
-
- -- Inherit attributes of parent `names` element
- local names_element = context.names_element
- if names_element then
- for key, value in pairs(names_element._attr) do
- context.options[key] = value
- end
- for key, value in pairs(self._attr) do
- context.options[key] = value
- end
+ local person_name_ir_to_add = hidden_name_irs[1]
+ if name_ir.use_last then
+ table.insert(rendered_name_irs, #rendered_name_irs, person_name_ir_to_add)
else
- context.names_element = self
- context.variable = context.options["variable"]
- end
-
- local name, et_al, label
- -- The position of cs:label relative to cs:name determines the order of
- -- the name and label in the rendered text.
- local label_position = nil
- for _, child in ipairs(self:get_children()) do
- if child:is_element() then
- local element_name = child:get_element_name()
- if element_name == "name" then
- name = child
- if label then
- label_position = "before"
- end
- elseif element_name == "et-al" then
- et_al = child
- elseif element_name == "label" then
- label = child
- if name then
- label_position = "after"
- end
- end
- end
+ table.insert(rendered_name_irs, person_name_ir_to_add)
end
- if label_position then
- context.label_position = label_position
- else
- label_position = context.label_position or "after"
+ table.remove(hidden_name_irs, 1)
+ if #hidden_name_irs == 0 then
+ if name_ir.et_al_abbreviation then
+ name_ir.et_al_abbreviation = false
+ end
+ if name_ir.use_last then
+ name_ir.use_last = false
+ end
end
- -- local name = self:get_child("name")
- if not name then
- name = context.name_element
+ local and_term_ir = name_ir.and_term_ir
+ local et_al_ir
+ if name_ir.et_al_abbreviation then
+ et_al_ir = name_ir.et_al_ir
end
- if not name then
- name = self:create_element("name", {}, self)
- Name:set_base_class(name)
- end
- context.name_element = name
+ local use_last = name_ir.use_last
- -- local et_al = self:get_child("et-al")
- if not et_al then
- et_al = context.et_al
- end
- if not et_al then
- et_al = self:create_element("et-al", {}, self)
- EtAl:set_base_class(et_al)
- end
- context.et_al = et_al
+ name_ir.children = self:join_person_name_irs(rendered_name_irs, and_term_ir, et_al_ir, use_last)
+ return person_name_ir_to_add
+end
- -- local label = self:get_child("label")
- if label then
- context.label = label
- else
- label = context.label
- end
-
- local sub_str = nil
- if context.mode == "bibliography" and not context.sorting then
- sub_str = context.options["subsequent-author-substitute"]
- -- if sub_str and #context.build.preceding_first_rendered_names == 0 then
- -- context.rendered_names = {}
- -- else
- -- sub_str = nil
- -- context.rendered_names = nil
- -- end
- end
-
- local variable_names = context.options["variable"] or context.variable
- local ret = nil
-
- if variable_names then
- local output = {}
- local num_names = 0
- for _, role in ipairs(util.split(variable_names)) do
- local names = self:get_variable(item, role, context)
-
- table.insert(context.variable_attempt, names ~= nil)
-
- if names then
- local res = name:render(names, context)
- if res then
- if type(res) == "number" then -- name[form="count"]
- num_names = num_names + res
- elseif label and not context.sorting then
- -- drop name label in sorting
- local label_result = label:render(role, context)
- if label_result then
- if label_position == "before" then
- res = richtext.concat(label_result, res)
- else
- res = richtext.concat(res, label_result)
- end
- end
- end
- end
- table.insert(output, res)
- end
- end
- if num_names > 0 then
- ret = tostring(num_names)
- else
- ret = self:concat(output, context)
- if ret and sub_str and context.build.first_rendered_names then
- ret = self:substitute_names(ret, context)
- end
- end
+-- [Name-part](https://docs.citationstyles.org/en/stable/specification.html#name-part-formatting)
+function NamePart:new(name)
+ local o = Element.new(self)
+ o.name = name
+ return o
+end
+
+function NamePart:from_node(node)
+ local o = NamePart:new()
+ o:set_attribute(node, "name")
+ o:set_formatting_attributes(node)
+ o:set_text_case_attribute(node)
+ o:set_affixes_attributes(node)
+ return o
+end
+
+function NamePart:format_text_case(text, context)
+ local output_format = context.format
+ local inlines = InlineElement:parse(text, context)
+ local is_english = context:is_english()
+ if not output_format then
+ print(debug.traceback())
end
+ output_format:apply_text_case(inlines, self.text_case, is_english)
- if ret then
- ret = self:format(ret, context)
- ret = self:wrap(ret, context)
- ret = self:display(ret, context)
- return ret
- else
- local substitute = self:get_child("substitute")
- if substitute then
- ret = substitute:render(item, context)
+ inlines = output_format:with_format(inlines, self.formatting)
+ return inlines
+end
+
+function NamePart:affixed(inlines)
+ if self.affixes then
+ if self.affixes.prefix then
+ table.insert(inlines, 1, PlainText:new(self.affixes.prefix))
end
- if ret and sub_str then
- ret = self:substitute_single_field(ret, context)
+ if self.affixes.suffix then
+ table.insert(inlines, PlainText:new(self.affixes.suffix))
end
- return ret
end
+ return inlines
end
-function Names:substitute_single_field(result, context)
- if not result then
- return nil
- end
- if context.build.first_rendered_names and #context.build.first_rendered_names == 0 then
- context.build.first_rendered_names[1] = result
- end
- result = self:substitute_names(result, context)
- return result
-end
-function Names:substitute_names(result, context)
- if not context.build.first_rendered_names then
- return result
- end
- local name_strings = {}
- local match_all
+-- [Et-al](https://docs.citationstyles.org/en/stable/specification.html#et-al)
+EtAl.term = "et-al"
- if #context.build.first_rendered_names > 0 then
- match_all = true
- else
- match_all = false
+function EtAl:from_node(node)
+ local o = EtAl:new()
+ o:set_attribute(node, "term")
+ o:set_formatting_attributes(node)
+ return o
+end
+
+function EtAl:build_ir(engine, state, context)
+ local term = context.locale:get_simple_term(self.term)
+ if not term then
+ return term
end
- for i, text in ipairs(context.build.first_rendered_names) do
- local str = text:render(context.engine.formatter, context)
- name_strings[i] = str
- if context.build.preceding_first_rendered_names and str ~= context.build.preceding_first_rendered_names[i] then
- match_all = false
- end
+ local inlines = InlineElement:parse(term, context)
+ if #inlines == 0 then
+ return nil
end
- if context.build.preceding_first_rendered_names then
- local sub_str = context.options["subsequent-author-substitute"]
- local sub_rule = context.options["subsequent-author-substitute-rule"]
+ inlines = context.format:with_format(inlines, self.formatting)
- if sub_rule == "complete-all" then
- if match_all then
- if sub_str == "" then
- result = nil
- else
- result.contents = {sub_str}
- end
- end
+ local ir = Rendered:new(inlines, self)
- elseif sub_rule == "complete-each" then
- -- In-place substitution
- if match_all then
- for _, text in ipairs(context.build.first_rendered_names) do
- text.contents = {sub_str}
- end
- result = self:concat(context.build.first_rendered_names, context)
- end
-
- elseif sub_rule == "partial-each" then
- for i, text in ipairs(context.build.first_rendered_names) do
- if name_strings[i] == context.build.preceding_first_rendered_names[i] then
- text.contents = {sub_str}
- else
- break
- end
- end
- result = self:concat(context.build.first_rendered_names, context)
-
- elseif sub_rule == "partial-first" then
- if name_strings[1] == context.build.preceding_first_rendered_names[1] then
- context.build.first_rendered_names[1].contents = {sub_str}
- end
- result = self:concat(context.build.first_rendered_names, context)
- end
+ if util.is_cjk_char(utf8.codepoint(term, 1)) then
+ ir.starts_with_cjk = true
end
- if #context.build.first_rendered_names > 0 then
- context.build.first_rendered_names = nil
- end
- context.build.preceding_first_rendered_names = name_strings
- return result
+ return ir
end
+function Substitute:from_node(node)
+ local o = Substitute:new()
+ o:process_children_nodes(node)
+ return o
+end
+
+
names_module.Names = Names
names_module.Name = Name
names_module.NamePart = NamePart
diff --git a/biblio/citation-style-language/citeproc-node-number.lua b/biblio/citation-style-language/citeproc-node-number.lua
index ba096157aa..4ef308e3d0 100644
--- a/biblio/citation-style-language/citeproc-node-number.lua
+++ b/biblio/citation-style-language/citeproc-node-number.lua
@@ -6,97 +6,63 @@
local number_module = {}
-local element = require("citeproc-element")
-local util = require("citeproc-util")
-
-
-local Number = element.Element:new()
-
-function Number:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
- local variable = context.options["variable"]
- local content = self:get_variable(item, variable, context)
+local Element = require("citeproc-element").Element
- table.insert(context.variable_attempt, content ~= nil)
+local Rendered = require("citeproc-ir-node").Rendered
- if not content then
- return nil
- end
-
- local numbers = {}
- local punct_list = {}
- local last_position = 1
- for number, punct, pos in string.gmatch(content, "(.-)%s*([-,&])%s*()") do
- table.insert(numbers, number)
- table.insert(punct_list, punct)
- last_position = pos
- end
- table.insert(numbers, string.sub(content, last_position))
+local util = require("citeproc-util")
- local res = ""
- for i, number in ipairs(numbers) do
- local punct = punct_list[i]
- number = self:_format_single_number(number, context)
- res = res .. number
- if punct == "-" then
- res = res .. punct
- elseif punct == "," then
- res = res .. punct .. " "
- elseif punct == "&" then
- res = res .. " " .. punct .. " "
- end
- end
+local Number = Element:derive("number")
- res = self:case(res, context)
- res = self:wrap(res, context)
- res = self:display(res, context)
+function Number:new(node)
+ local o = {
+ element_name = "number",
+ form = "numeric",
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
- return res
+function Number:from_node(node)
+ local o = Number:new()
+ o:set_attribute(node, "variable")
+ o:set_attribute(node, "form")
+ o:set_affixes_attributes(node)
+ o:set_display_attribute(node)
+ o:set_formatting_attributes(node)
+ o:set_text_case_attribute(node)
+ return o
end
-function Number:_format_single_number(number, context)
- local form = context.options["form"] or "numeric"
- if form == "numeric" or not string.match(number, "^%d+$") then
- return number
+function Number:build_ir(engine, state, context)
+ local number
+ if not state.suppressed[self.variable] then
+ number = context:get_variable(self.variable, self.form)
end
- number = tonumber(number)
- if form == "ordinal" or form == "long-ordinal" then
- return self:_format_oridinal(number, form, context)
- elseif form == "roman" then
- return util.convert_roman(number)
+ if not number then
+ local ir = Rendered:new({}, self)
+ ir.group_var = "missing"
+ return ir
end
-end
-
-function Number:_format_oridinal(number, form, context)
- assert(type(number) == "number")
- local variable = context.options["variable"]
- if form == "long-ordinal" then
- if number < 1 or number > 10 then
- form = "ordinal"
- end
+ if type(number) == "number" then
+ number = tostring(number)
+ number = self:format_number(number, self.variable, self.form, context)
+ elseif util.is_numeric(number) then
+ number = self:format_number(number, self.variable, self.form, context)
end
- local gender = nil
- local term = self:get_term(variable)
- if term then
- gender = term:get_attribute("gender")
- end
+ local inlines = self:render_text_inlines(number, context)
+ local ir = Rendered:new(inlines, self)
+ ir.group_var = "important"
- term = self:get_term(form, nil, number, gender)
- local res = term:render(context)
- if form == "ordinal" then
- if res then
- return tostring(number) .. res
- else
- res = tostring(number)
- end
- else
- return res
+ -- Suppress substituted name variable
+ if state.name_override and not context.sort_key then
+ state.suppressed[self.variable] = true
end
- return res
+ return ir
end
diff --git a/biblio/citation-style-language/citeproc-node-sort.lua b/biblio/citation-style-language/citeproc-node-sort.lua
index 1b82d21b55..876c3257da 100644
--- a/biblio/citation-style-language/citeproc-node-sort.lua
+++ b/biblio/citation-style-language/citeproc-node-sort.lua
@@ -8,57 +8,80 @@ local sort = {}
local unicode = require("unicode")
-local element = require("citeproc-element")
+local Element = require("citeproc-element").Element
+local Date = require("citeproc-node-date").Date
local names = require("citeproc-node-names")
-local date = require("citeproc-node-date")
+local InlineElement = require("citeproc-output").InlineElement
local util = require("citeproc-util")
-local Sort = element.Element:new()
+-- [Sorting](https://docs.citationstyles.org/en/stable/specification.html#sorting)
+local Sort = Element:derive("sort")
-function Sort:sort (items, context)
+function Sort:from_node(node)
+ local o = Sort:new()
+ o.children = {}
+
+ o:process_children_nodes(node)
+ o.sort_directions = {}
+ for i, key in ipairs(o.children) do
+ o.sort_directions[i] = (key.sort ~= "descending")
+ end
+ table.insert(o.sort_directions, true)
+
+ return o
+end
+
+function Sort:sort(items, state, context)
-- key_map = {
-- id1 = {key1, key2, ...},
-- id2 = {key1, key2, ...},
-- ...
-- }
- context.variable_attempt = {}
-
local key_map = {}
- local sort_directions = {}
+ local sort_directions = self.sort_directions
-- true: ascending
-- false: descending
- if not Sort.collator_obj then
- local lang = context.style.lang
+ if not Sort.collator then
+ local lang = context.engine.lang
local language = string.sub(lang, 1, 2)
-- It's 6 seconds slower to run the whole test-suite if these package
-- loading statements are put in the header.
- local ducet = require("lua-uca.lua-uca-ducet")
- local collator = require("lua-uca.lua-uca-collator")
- local languages = require("lua-uca.lua-uca-languages")
- local collator_obj = collator.new(ducet)
- if languages[language] then
- Sort.collator_obj = languages[language](collator_obj)
- else
- util.warning(string.format('Lcoale "%s" is not supported.', lang))
+ local uca_ducet = require("lua-uca.lua-uca-ducet")
+ local uca_collator = require("lua-uca.lua-uca-collator")
+ Sort.collator = uca_collator.new(uca_ducet)
+ if language ~= "en" then
+ local uca_languages = require("lua-uca.lua-uca-languages")
+ if uca_languages[language] then
+ Sort.collator = uca_languages[language](Sort.collator)
+ else
+ util.warning(string.format('Locale "%s" is not provided by lua-uca. The sorting order may be incorrect.', lang))
+ end
end
end
- for _, item in ipairs(items) do
- if not key_map[item.id] then
- key_map[item.id] = {}
-
- context.item = item
- for i, key in ipairs(self:query_selector("key")) do
- if sort_directions[i] == nil then
- local direction = (key:get_attribute("sort") ~= "descending")
- sort_directions[i] = direction
- end
- local value = key:render(item, context)
- table.insert(key_map[item.id], value)
+ -- TODO: optimize: use cached values for fixed keys
+ for i, item in ipairs(items) do
+ key_map[item.id] = {}
+
+ context.id = item.id
+ context.cite = item
+ context.reference = context.engine.registry.registry[item.id]
+
+ for j, key in ipairs(self.children) do
+ if context.reference then
+ context.sort_key = key
+ local key_str = key:eval(context.engine, state, context)
+ key_map[item.id][j] = key_str
+ else
+ -- The entry is missing
+ key_map[item.id][j] = false
end
end
+ -- To preserve the original order of items with same sort keys
+ -- sort_NameImplicitSortOrderAndForm.txt
+ table.insert(key_map[item.id], i)
end
-- util.debug(key_map)
@@ -66,6 +89,7 @@ function Sort:sort (items, context)
local function compare_entry(item1, item2)
return self.compare_entry(key_map, sort_directions, item1, item2)
end
+ -- util.debug(items)
table.sort(items, compare_entry)
return items
@@ -80,8 +104,8 @@ function Sort.compare(value1, value2)
end
function Sort.compare_strings(str1, str2)
- if Sort.collator_obj then
- return Sort.collator_obj:compare_strings(str1, str2)
+ if Sort.collator then
+ return Sort.collator:compare_strings(str1, str2)
else
return str1 < str2
end
@@ -109,77 +133,98 @@ function Sort.compare_entry(key_map, sort_directions, item1, item2)
end
end
-local Key = element.Element:new()
-
-function Key:render (item, context)
- context = self:process_context(context)
- context.options["name-as-sort-order"] = "all"
- context.sorting = true
- local variable = self:get_attribute("variable")
- local res = nil
- if variable then
- context.variable = variable
- local variable_type = util.variable_types[variable]
+local Key = Element:derive("key")
+
+function Key:new()
+ local o = Element.new(self)
+ Key.sort = "ascending"
+ return o
+end
+
+function Key:from_node(node)
+ local o = Key:new()
+ o:set_attribute(node, "sort")
+ o:set_attribute(node, "variable")
+ o:set_attribute(node, "macro")
+ o:set_number_attribute(node, "names-min")
+ o:set_number_attribute(node, "names-use-first")
+ o:set_bool_attribute(node, "names-use-last")
+ return o
+end
+
+function Key:eval(engine, state, context)
+ local res
+ if self.variable then
+ local variable_type = util.variable_types[self.variable]
if variable_type == "name" then
- res = self:_render_name(item, context)
+ res = self:eval_name(engine, state, context)
elseif variable_type == "date" then
- res = self:_render_date(item, context)
+ res = self:eval_date(context)
elseif variable_type == "number" then
- res = item[variable]
+ local value = context:get_variable(self.variable)
+ if type(value) == "string" and string.match(value, "%s+") then
+ value = tonumber(value)
+ end
+ res = value
else
- res = item[variable]
+ res = context:get_variable(self.variable)
+ if type(res) == "string" then
+ local inlines = InlineElement:parse(res, context)
+ res = context.format:output(inlines)
+ end
end
- else
- local macro = self:get_attribute("macro")
- if macro then
- res = self:get_macro(macro):render(item, context)
+ elseif self.macro then
+ local macro = context:get_macro(self.macro)
+ state:push_macro(self.macro)
+ local ir = macro:build_ir(engine, state, context)
+ state:pop_macro(self.macro)
+ if ir.name_count then
+ return ir.name_count
+ elseif ir.sort_key ~= nil then
+ return ir.sort_key
end
+ local output_format = context.format
+ local inlines = ir:flatten(output_format)
+ -- util.debug(inlines)
+ local str = output_format:output(inlines)
+ return str
end
if res == nil then
+ -- make table.insert(_, nil) work
res = false
- elseif type(res) == "table" and res._type == "RichText" then
- res = res:render(nil, context)
- end
- if type(res) == "string" then
- res = self._normalize_string(res)
end
return res
end
-function Key:_render_name (item, context)
- if not self.names then
- self.names = self:create_element("names", {}, self)
- names.Names:set_base_class(self.names)
- self.names:set_attribute("variable", context.options["variable"])
- self.names:set_attribute("form", "long")
+function Key:eval_name(engine, state, context)
+ if not self.name_inheritance then
+ self.name_inheritance = util.clone(context.name_inheritance)
end
- local res = self.names:render(item, context)
- return res
+ local name = context:get_variable(self.variable)
+ if not name then
+ return false
+ end
+ local ir = self.name_inheritance:build_ir(self.variable, nil, nil, engine, state, context)
+ if ir.name_count then
+ -- name count
+ return ir.name_count
+ end
+ local output_format = context.format
+ local inlines = ir:flatten(output_format)
+
+ local str = output_format:output(inlines)
+
+ return str
end
-function Key:_render_date (item, context)
+function Key:eval_date(context)
if not self.date then
- self.date = self:create_element("date", {}, self)
- date.Date:set_base_class(self.date)
- self.date:set_attribute("variable", context.options["variable"])
- self.date:set_attribute("form", "numeric")
+ self.date = Date:new()
+ self.date.variable = self.variable
+ self.date.form = "numeric"
+ self.date.date_parts = "year-month-day"
end
- local res = self.date:render(item, context)
- return res
-end
-function Key._normalize_string(str)
- str = unicode.utf8.lower(str)
- str = string.gsub(str, "[%[%]]", "")
- local words = {}
- for _, word in ipairs(util.split(str, " ")) do
- -- TODO: strip leading prepositions
- -- remove leading apostrophe on name particle
- word = string.gsub(word, "^" .. util.unicode["apostrophe"], "")
- table.insert(words, word)
- end
- str = table.concat(words, " ")
- str = string.gsub(str, util.unicode["apostrophe"], "'")
- return str
+ return self.date:render_sort_key(context.engine, nil, context)
end
diff --git a/biblio/citation-style-language/citeproc-node-style.lua b/biblio/citation-style-language/citeproc-node-style.lua
index 2fb10cc79c..5c387bd6c8 100644
--- a/biblio/citation-style-language/citeproc-node-style.lua
+++ b/biblio/citation-style-language/citeproc-node-style.lua
@@ -4,15 +4,126 @@
-- Repository: https://github.com/zepinglee/citeproc-lua
--
-local style = {}
+local style_module = {}
-local element = require("citeproc-element")
+local dom = require("luaxml-domobject")
+
+local Element = require("citeproc-element").Element
+local IrNode = require("citeproc-ir-node").IrNode
+local Rendered = require("citeproc-ir-node").Rendered
+local SeqIr = require("citeproc-ir-node").SeqIr
+local PlainText = require("citeproc-output").PlainText
+local DisamStringFormat = require("citeproc-output").DisamStringFormat
local util = require("citeproc-util")
-local Style = element.Element:new()
+local Style = Element:derive("style")
+
+function Style:new()
+ local o = {
+ children = {},
+ macros = {},
+ locales = {},
+ initialize_with_hyphen = true,
+ demote_non_dropping_particle = "display-and-sort",
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function Style:parse(xml_str)
+ local csl_xml = dom.parse(xml_str)
+ if not csl_xml then
+ error("Failed to parse CSL style.")
+ end
+ local style_node = csl_xml:get_path("style")[1]
+ if not csl_xml then
+ error('Element "style" not found.')
+ end
+ return Style:from_node(style_node)
+end
+
+local function make_name_inheritance(name, node)
+ name:set_attribute(node, "and")
+ name:set_attribute(node, "delimiter-precedes-et-al")
+ name:set_attribute(node, "delimiter-precedes-last")
+ name:set_number_attribute(node, "et-al-min")
+ name:set_number_attribute(node, "et-al-use-first")
+ name:set_number_attribute(node, "et-al-subsequent-min")
+ name:set_number_attribute(node, "et-al-subsequent-use-first")
+ name:set_bool_attribute(node, "et-al-use-last")
+ name:set_bool_attribute(node, "initialize")
+ name:set_attribute(node, "initialize-with")
+ name:set_attribute(node, "name-as-sort-order")
+ name:set_attribute(node, "sort-separator")
+ local delimiter = node:get_attribute("name-delimiter")
+ if delimiter then
+ name.delimiter = delimiter
+ end
+ local form = node:get_attribute("name-form")
+ if form then
+ name.form = form
+ end
+ local names_delimiter = node:get_attribute("names-delimiter")
+ if names_delimiter then
+ name.names_delimiter = names_delimiter
+ end
+end
+
+function Style:from_node(node)
+ local o = Style:new()
+
+ o:set_attribute(node, "class")
+ o:set_attribute(node, "default-locale")
+ o:set_attribute(node, "version")
+
+ -- Global Options
+ o.initialize_with_hyphen = true
+ o:set_bool_attribute(node, "initialize-with-hyphen")
+ o:set_attribute(node, "page-range-format")
+ o:set_attribute(node, "demote-non-dropping-particle")
+
+ -- Inheritable Name Options
+ -- https://docs.citationstyles.org/en/stable/specification.html#inheritable-name-options
+ o.name_inheritance = require("citeproc-node-names").Name:new()
+ make_name_inheritance(o.name_inheritance, node)
+
+ if o.page_range_format == "chicago" then
+ if o.version < "1.1" then
+ o.page_range_format = "chicago-15"
+ else
+ o.page_range_format = "chicago-16"
+ end
+ end
+
+ o.macros = {}
+ o.locales = {}
+
+ o.children = {}
+ o:process_children_nodes(node)
+
+ for _, child in ipairs(o.children) do
+ local element_name = child.element_name
+ if element_name == "info" then
+ o.info = child
+ elseif element_name == "citation" then
+ o.citation = child
+ elseif element_name == "bibliography" then
+ o.bibliography = child
+ elseif element_name == "macro" then
+ o.macros[child.name] = child
+ elseif element_name == "locale" then
+ local xml_lang = child.xml_lang or "@generic"
+ o.locales[xml_lang] = child
+ end
+ end
+
+ return o
+end
+
-Style.default_options = {
+Style._default_options = {
["initialize-with-hyphen"] = true,
["page-range-format"] = nil,
["demote-non-dropping-particle"] = "display-and-sort",
@@ -29,171 +140,385 @@ function Style:set_lang(lang, force_lang)
end
end
-function Style:render_citation (items, context)
- self:debug_info(context)
- context = self:process_context(context)
- context.style = self
- local citation = self:get_child("citation")
- return citation:render(items, context)
-end
-function Style:render_biblography (items, context)
- self:debug_info(context)
- context = self:process_context(context)
- context.style = self
- local bibliography = self:get_child("bibliography")
- return bibliography:render(items, context)
-end
+local Info = Element:derive("info")
+
+
+function Info:from_node(node)
+ local o = Info:new()
+
+ -- o.authors = nil
+ -- o.contributors = nil
+ o.categories = {}
+ o.id = nil
+ -- o.issn = nil
+ -- o.eissn = nil
+ -- o.issnl = nil
+ o.links = {
+ independent_parent = nil,
+ }
+ -- o.published = nil
+ -- o.rights = nil
+ -- o.summary = nil
+ o.title = nil
+ -- o.title_short = nil
+ o.updated = nil
+
+ for _, child in ipairs(node:get_children()) do
+ if child:is_element() then
+ local element_name = child:get_element_name()
+ if element_name == "category" then
+ local citation_format = child:get_attribute("citation-format")
+ if citation_format then
+ o.categories.citation_format = citation_format
+ end
+
+ elseif element_name == "id" then
+ o.id = child:get_text()
+
+ elseif element_name == "link" then
+ local href = child:get_attribute("href")
+ local rel = child:get_attribute("rel")
+ if href and rel == "independent-parent" then
+ o.links.independent_parent = href
+ end
+
+ elseif element_name == "title" then
+ o.title = child:get_text()
+
+ elseif element_name == "updated" then
+ o.updated = child:get_text()
+
+ end
+ end
+ end
-function Style:get_version ()
- return self:get_attribute("version")
+ return o
end
-function Style:get_locales()
- if not self.locale_dict then
- self.locale_dict = {}
- end
- local locales = self.locale_dict[self.lang]
- if not locales then
- locales = self:get_locale_list(self.lang)
- self.locale_dict[self.lang] = locales
- end
- return locales
-end
-function Style:get_locale_list (lang)
- assert(lang ~= nil)
- local language = string.sub(lang, 1, 2)
- local primary_dialect = util.primary_dialects[language]
- if not primary_dialect then
- -- util.warning(string.format("Failed to find primary dialect of \"%s\"", language))
- end
- local locale_list = {}
+local Citation = Element:derive("citation", {
+ givenname_disambiguation_rule = "by-cite",
+ -- https://github.com/citation-style-language/schema/issues/338
+ -- The cite_group_delimiter may be changed to inherit the delimiter in citaion > layout.
+ cite_group_delimiter = ", ",
+ near_note_distance = 5,
+})
- -- 1. In-style cs:locale elements
- -- i. `xml:lang` set to chosen dialect, “de-AT”
- if lang == language then
- lang = primary_dialect
- end
- table.insert(locale_list, self:get_in_style_locale(lang))
+function Citation:from_node(node, style)
- -- ii. `xml:lang` set to matching language, “de” (German)
- if language and language ~= lang then
- table.insert(locale_list, self:get_in_style_locale(language))
- end
+ local o = Citation:new()
+ o.children = {}
- -- iii. `xml:lang` not set
- table.insert(locale_list, self:get_in_style_locale(nil))
+ o:process_children_nodes(node)
- -- 2. Locale files
- -- iv. `xml:lang` set to chosen dialect, “de-AT”
- if lang then
- table.insert(locale_list, self:get_engine():get_system_locale(lang))
+ -- o.layouts = nil -- CSL-M extension
+
+ for _, child in ipairs(o.children) do
+ local element_name = child.element_name
+ if element_name == "layout" then
+ o.layout = child
+ elseif element_name == "sort" then
+ o.sort = child
+ end
end
- -- v. `xml:lang` set to matching primary dialect, “de-DE” (Standard German)
- -- (only applicable when the chosen locale is a secondary dialect)
- if primary_dialect and primary_dialect ~= lang then
- table.insert(locale_list, self:get_engine():get_system_locale(primary_dialect))
+ -- Disambiguation
+ o:set_bool_attribute(node, "disambiguate-add-givenname")
+ o:set_attribute(node, "givenname-disambiguation-rule")
+ o:set_bool_attribute(node, "disambiguate-add-names")
+ o:set_bool_attribute(node, "disambiguate-add-year-suffix")
+
+ -- Cite Grouping
+ o:set_attribute(node, "cite-group-delimiter")
+ -- In the current citeproc-js implementation and test suite,
+ -- cite grouping is activated by setting the cite-group-delimiter
+ -- attribute or the collapse attributes on cs:citation.
+ -- It may be changed to an independent procedure.
+ -- https://github.com/citation-style-language/schema/issues/338
+ if node:get_attribute("cite-group-delimiter") then
+ o.cite_grouping = true
+ else
+ o.cite_grouping = false
end
- -- vi. `xml:lang` set to “en-US” (American English)
- if lang ~= "en-US" and primary_dialect ~= "en-US" then
- table.insert(locale_list, self:get_engine():get_system_locale("en-US"))
+
+ -- Cite Collapsing
+ o:set_attribute(node, "collapse")
+ o:set_attribute(node, "year-suffix-delimiter")
+ if not o.year_suffix_delimiter then
+ o.year_suffix_delimiter = o.layout.delimiter
+ end
+ o:set_attribute(node, "after-collapse-delimiter")
+ if not o.after_collapse_delimiter then
+ o.after_collapse_delimiter = o.layout.delimiter
end
- return locale_list
-end
+ -- Note Distance
+ o:set_number_attribute(node, "near-note-distance")
-function Style:get_in_style_locale (lang)
- for _, locale in ipairs(self:query_selector("locale")) do
- if locale:get_attribute("xml:lang") == lang then
- return locale
+ local name_inheritance = require("citeproc-node-names").Name:new()
+ for key, value in pairs(style.name_inheritance) do
+ if value ~= nil then
+ name_inheritance[key] = value
end
end
- return nil
+ make_name_inheritance(name_inheritance, node)
+ o.name_inheritance = name_inheritance
+
+ -- update_mode = "plain" or "numeric" or "position" (or "both"?)
+
+ return o
end
-function Style:get_term (...)
- for _, locale in ipairs(self:get_locales()) do
- local res = locale:get_term(...)
- if res then
- return res
- end
+function Citation:build_ir(engine, state, context)
+ if not self.layout then
+ util.error("Missing citation layout.")
end
- return nil
+ return self.layout:build_ir(engine, state, context)
end
-local Citation = element.Element:new()
+local Bibliography = Element:derive("bibliography", {
+ hanging_indent = false,
+ line_spacing = 1,
+ entry_spacing = 1,
+ subsequent_author_substitute_rule = "complete-all"
+})
+
+function Bibliography:from_node(node, style)
+ local o = Bibliography:new()
+ o.children = {}
-function Citation:render (items, context)
- self:debug_info(context)
- context = self:process_context(context)
+ o:process_children_nodes(node)
- context.mode = "citation"
- context.citation = self
+ -- o.layouts = nil -- CSL-M extension
- local sort = self:get_child("sort")
- if sort then
- sort:sort(items, context)
+ for _, child in ipairs(o.children) do
+ local element_name = child.element_name
+ if element_name == "layout" then
+ o.layout = child
+ elseif element_name == "sort" then
+ o.sort = child
+ end
end
- local layout = self:get_child("layout")
- return layout:render(items, context)
+ -- Whitespace
+ o:set_bool_attribute(node, "hanging-indent")
+ o:set_attribute(node, "second-field-align")
+ o:set_number_attribute(node, "line-spacing")
+ o:set_number_attribute(node, "entry-spacing")
+
+ -- Reference Grouping
+ o:set_attribute(node, "subsequent-author-substitute")
+ o:set_attribute(node, "subsequent-author-substitute-rule")
+
+ local name_inheritance = require("citeproc-node-names").Name:new()
+ for key, value in pairs(style.name_inheritance) do
+ if value ~= nil then
+ name_inheritance[key] = value
+ end
+ end
+ make_name_inheritance(name_inheritance, node)
+ o.name_inheritance = name_inheritance
+
+ return o
end
+function Bibliography:build_ir(engine, state, context)
+ if not self.layout then
+ util.error("Missing bibliography layout.")
+ end
+ local ir = self.layout:build_ir(engine, state, context)
+ -- util.debug(ir)
+ if self.second_field_align == "flush" and #ir.children >= 2 then
+ ir.children[1].display = "left-margin"
+ local right_inline_ir = SeqIr:new(util.slice(ir.children, 2), self)
+ right_inline_ir.display = "right-inline"
+ if ir.affixes then
+ right_inline_ir.affixes = ir.affixes
+ right_inline_ir.formatting = ir.formatting
+ ir.affixes = nil
+ ir.formatting = nil
+ end
+ ir.children = {ir.children[1], right_inline_ir}
+ end
-local Bibliography = element.Element:new()
+ if self.subsequent_author_substitute then
+ self:substitute_subsequent_authors(engine, ir)
+ end
-Bibliography.default_options = {
- ["hanging-indent"] = false,
- ["second-field-align"] = nil,
- ["line-spacing"] = 1,
- ["entry-spacing"] = 1,
- ["subsequent-author-substitute"] = nil,
- ["subsequent-author-substitute-rule"] = "complete-all",
-}
+ if not ir then
+ ir = Rendered:new(PlainText:new("[CSL STYLE ERROR: reference with no printed form.]"), self)
+ end
+ return ir
+end
-function Bibliography:render (items, context)
- self:debug_info(context)
- context = self:process_context(context)
- -- util.debug(context)
+function Bibliography:substitute_subsequent_authors(engine, ir)
+ ir.first_name_ir = self:find_first_name_ir(ir) -- should be a SeqIr wiht _element = "names"
+ if not ir.first_name_ir then
+ engine.previous_bib_names_ir = nil
+ return
+ end
+ if self.subsequent_author_substitute_rule == "complete-all" then
+ self:substitute_subsequent_authors_complete_all(engine, ir)
+ elseif self.subsequent_author_substitute_rule == "complete-each" then
+ self:substitute_subsequent_authors_complete_each(engine, ir)
+ elseif self.subsequent_author_substitute_rule == "partial-each" then
+ self:substitute_subsequent_authors_partial_each(engine, ir)
+ elseif self.subsequent_author_substitute_rule == "partial-first" then
+ self:substitute_subsequent_authors_partial_first(engine, ir)
+ end
+ engine.previous_bib_names_ir = ir.first_name_ir
+end
- context.mode = "bibliography"
- context.bibliography = self
+function Bibliography:find_first_name_ir(ir)
+ if ir._type == "NameIr" then
+ return ir
+ elseif ir.children then
+ for _, child_ir in ipairs(ir.children) do
+ local first_name_ir = self:find_first_name_ir(child_ir)
+ if first_name_ir then
+ return first_name_ir
+ end
+ end
+ end
+ return nil
+end
- -- Already sorted in CiteProc:sort_bibliography()
+function Bibliography:substitute_subsequent_authors_complete_all(engine, ir)
+ local bib_names_str = ""
- local layout = self:get_child("layout")
- local res = layout:render(items, context)
+ if #ir.first_name_ir.person_name_irs > 0 then
+ for _, person_name_ir in ipairs(ir.first_name_ir.person_name_irs) do
+ if bib_names_str ~= "" then
+ bib_names_str = bib_names_str .. " "
+ end
+ local name_variants = person_name_ir.disam_variants
+ bib_names_str = bib_names_str .. name_variants[#name_variants]
+ end
+ else
+ -- In case of a <text variable="title"/> in <substitute>
+ local disam_format = DisamStringFormat:new()
+ local inlines = ir.first_name_ir:flatten(disam_format)
+ bib_names_str = disam_format:output(inlines)
+ end
+ ir.first_name_ir.bib_names_str = bib_names_str
+
+ if engine.previous_bib_names_ir and
+ engine.previous_bib_names_ir.bib_names_str == bib_names_str then
+ local text = self.subsequent_author_substitute
+ if text == "" then
+ ir.first_name_ir.children = {}
+ ir.first_name_ir.group_var = "missing"
+ else
+ -- the output of label is not substituted
+ -- util.debug(ir.first_name_ir)
+ ir.first_name_ir.children = {Rendered:new({PlainText:new(text)}, self)}
+ end
+ end
+end
- local params = res[1]
+function Bibliography:substitute_subsequent_authors_complete_each(engine, ir)
+ local bib_names_str = ""
- params.entryspacing = context.options["entry-spacing"]
- params.linespacing = context.options["line-spacing"]
- params.hangingindent = context.options["hanging-indent"]
- params["second-field-align"] = context.options["second-field-align"]
- for _, key in ipairs({"bibstart", "bibend"}) do
- local value = context.engine.formatter[key]
- if type(value) == "function" then
- value = value(context)
+ if #ir.first_name_ir.person_name_irs > 0 then
+ for _, person_name_ir in ipairs(ir.first_name_ir.person_name_irs) do
+ if bib_names_str ~= "" then
+ bib_names_str = bib_names_str .. " "
+ end
+ local name_variants = person_name_ir.disam_variants
+ bib_names_str = bib_names_str .. name_variants[#name_variants]
end
- params[key] = value
+ else
+ -- In case of a <text variable="title"/> in <substitute>
+ local disam_format = DisamStringFormat:new()
+ local inlines = ir.first_name_ir:flatten(disam_format)
+ bib_names_str = disam_format:output(inlines)
end
+ ir.first_name_ir.bib_names_str = bib_names_str
+
+ if engine.previous_bib_names_ir and
+ engine.previous_bib_names_ir.bib_names_str == bib_names_str then
+ local text = self.subsequent_author_substitute
+ if #ir.first_name_ir.person_name_irs > 0 then
+ for _, person_name_ir in ipairs(ir.first_name_ir.person_name_irs) do
+ person_name_ir.inlines = {PlainText:new(text)}
+ end
+ else
+ -- In case of a <text variable="title"/> in <substitute>
+ if text == "" then
+ ir.first_name_ir.children = {}
+ ir.first_name_ir.group_var = "missing"
+ else
+ ir.first_name_ir.children = {Rendered:new({PlainText:new(text)}, self)}
+ end
+ end
+ end
+end
- params.bibliography_errors = {}
- params.entry_ids = {}
- for _, item in ipairs(items) do
- table.insert(params.entry_ids, item.id)
+function Bibliography:substitute_subsequent_authors_partial_each(engine, ir)
+ local bib_names_str = ""
+
+ if #ir.first_name_ir.person_name_irs > 0 then
+ if engine.previous_bib_names_ir then
+ for i, person_name_ir in ipairs(ir.first_name_ir.person_name_irs) do
+ local prev_name_ir = engine.previous_bib_names_ir.person_names[i]
+ if prev_name_ir then
+ local prev_name_variants = prev_name_ir.disam_variants
+ local prev_full_name_str = prev_name_variants[#prev_name_variants]
+ local name_variants = person_name_ir.disam_variants
+ local full_name_str = name_variants[#name_variants]
+ if prev_full_name_str == full_name_str then
+ local text = self.subsequent_author_substitute
+ person_name_ir.inlines = {PlainText:new(text)}
+ else
+ break
+ end
+ end
+ end
+ end
+ else
+ -- In case of a <text variable="title"/> in <substitute>
+ local disam_format = DisamStringFormat:new()
+ local inlines = ir.first_name_ir:flatten(disam_format)
+ bib_names_str = disam_format:output(inlines)
+ ir.first_name_ir.bib_names_str = bib_names_str
+ if engine.previous_bib_names_ir and
+ engine.previous_bib_names_ir.bib_names_str == bib_names_str then
+ local text = self.subsequent_author_substitute
+ if text == "" then
+ ir.first_name_ir.children = {}
+ ir.first_name_ir.group_var = "missing"
+ else
+ ir.first_name_ir.children = {Rendered:new({PlainText:new(text)}, self)}
+ end
+ end
end
+end
+
+function Bibliography:substitute_subsequent_authors_partial_first(engine, ir)
+end
+
+local Macro = Element:derive("macro")
- return res
+function Macro:from_node(node)
+ local o = Macro:new()
+ o.children = {}
+ o:set_attribute(node, "name")
+ o:process_children_nodes(node)
+ return o
end
-style.Style = Style
-style.Citation = Citation
-style.Bibliography = Bibliography
+function Macro:build_ir(engine, state, context)
+ local ir = self:build_group_ir(engine, state, context)
+ return ir
+end
+
+
+style_module.Style = Style
+style_module.Citation = Citation
+style_module.Bibliography = Bibliography
-return style
+return style_module
diff --git a/biblio/citation-style-language/citeproc-node-text.lua b/biblio/citation-style-language/citeproc-node-text.lua
index e26a480438..fae3535013 100644
--- a/biblio/citation-style-language/citeproc-node-text.lua
+++ b/biblio/citation-style-language/citeproc-node-text.lua
@@ -4,224 +4,196 @@
-- Repository: https://github.com/zepinglee/citeproc-lua
--
-local text = {}
+local text_module = {}
-local element = require("citeproc-element")
-local richtext = require("citeproc-richtext")
+local Element = require("citeproc-element").Element
+local Rendered = require("citeproc-ir-node").Rendered
+local YearSuffix = require("citeproc-ir-node").YearSuffix
+local PlainText = require("citeproc-output").PlainText
+local Linked = require("citeproc-output").Linked
local util = require("citeproc-util")
-local Text = element.Element:new()
-
-function Text:render (item, context)
- self:debug_info(context)
- context = self:process_context(context)
+-- [Text](https://docs.citationstyles.org/en/stable/specification.html#text)
+local Text = Element:derive("text", {
+ -- Default attributes
+ variable = nil,
+ form = "long",
+ macro = nil,
+ term = nil,
+ plural = false,
+ value = nil,
+ -- Style behavior
+ formatting = nil,
+ affixes = nil,
+ delimiter = nil,
+ display = nil,
+ quotes = false,
+ strip_periods = false,
+ text_case = nil,
+})
+
+function Text:from_node(node)
+ local o = Text:new()
+ o:set_attribute(node, "variable")
+ o:set_attribute(node, "form")
+ o:set_attribute(node, "macro")
+ o:set_attribute(node, "term")
+ o:set_bool_attribute(node, "plural")
+ o:set_attribute(node, "value")
+
+ o:set_formatting_attributes(node)
+ o:set_affixes_attributes(node)
+ o:set_display_attribute(node)
+ o:set_quotes_attribute(node)
+ o:set_strip_periods_attribute(node)
+ o:set_text_case_attribute(node)
+ return o
+end
- local res = nil
+function Text:build_ir(engine, state, context)
+ local ir = nil
+ if self.variable then
+ ir = self:build_variable_ir(engine, state, context)
+ elseif self.macro then
+ ir = self:build_macro_ir(engine, state, context)
+ elseif self.term then
+ ir = self:build_term_ir(engine, state, context)
+ elseif self.value then
+ ir = self:build_value_ir(engine, state, context)
+ end
+ return ir
+end
- local variable = nil
- local variable_name = self:get_attribute("variable")
- if variable_name then
- local form = self:get_attribute("form")
- if form == "short" then
- variable = self:get_variable(item, variable_name .. "-" .. form, context)
- end
- if not variable then
- variable = self:get_variable(item, variable_name, context)
- end
- if variable then
- res = variable
- if type(res) == "number" then
- res = tostring(res)
- end
- if variable_name == "page" or variable_name == "locator" then
- res = util.lstrip(res)
- res = self:_format_page(res, context)
- end
- end
+function Text:build_variable_ir(engine, state, context)
+ local variable = self.variable
+ local text
- table.insert(context.variable_attempt, res ~= nil)
+ if variable == "year-suffix" then
+ return self:build_year_suffix_ir(engine, state, context)
end
- local macro_name = self:get_attribute("macro")
- if macro_name then
- local macro = self:get_macro(macro_name)
- res = macro:render(item, context)
+ if not state.suppressed[variable] then
+ text = context:get_variable(variable, self.form)
end
- local term_name = self:get_attribute("term")
- if term_name then
- local form = self:get_attribute("form")
-
- local term = self:get_term(term_name, form)
- if term then
- res = term:render(context)
- end
+ if not text then
+ local ir = Rendered:new({}, self)
+ ir.group_var = "missing"
+ return ir
end
-
- local value = self:get_attribute("value")
- if value then
- res = value
- res = self:escape(res)
+ if type(text) == "number" then
+ text = tostring(text)
end
-
- if type(res) == "string" and res ~= "" then
- res = richtext.new(res)
+ if util.variable_types[variable] == "number" then
+ text = self:format_number(text, variable, "numeric", context)
end
- if res and variable_name == "URL" then
- res:add_format("URL", "true")
+ local inlines
+ if (variable == "URL" and engine.opt.url_link) or
+ (variable == "DOI" and engine.opt.doi_link) or
+ (variable == "PMID" and engine.opt.doi_link) or
+ (variable == "PMID" and engine.opt.doi_link) then
+ inlines = self:render_linked(engine, state, context, variable, text)
+ else
+ inlines = self:render_text_inlines(text, context)
end
- res = self:strip_periods(res, context)
- res = self:case(res, context)
- res = self:format(res, context)
- res = self:quote(res, context)
- res = self:wrap(res, context)
- res = self:display(res, context)
+ local ir = Rendered:new(inlines, self)
+ ir.group_var = "important"
- if variable_name == "citation-number" then
- res = self:_process_citation_number(variable, res, context)
+ if variable == "citation-number" then
+ ir.citation_number = context.reference["citation-number"]
end
- return res
-end
-
-
-function Text:_process_citation_number(citation_number, res, context)
- if context.mode == "citation" and not context.sorting and context.options["collapse"] == "citation-number" then
- context.build.item_citation_numbers[context.item.id] = citation_number
- if type(res) == "string" then
- res = richtext.new(res)
- end
- table.insert(context.build.item_citation_number_text, res)
+ -- Suppress substituted name variable
+ if state.name_override and not context.sort_key then
+ state.suppressed[variable] = true
end
- return res
-end
-
-function Text:_format_page (page, context)
- local res = nil
-
- local page_range_delimiter = self:get_term("page-range-delimiter"):render(context) or util.unicode["en dash"]
- local page_range_format = context.options["page-range-format"]
- if page_range_format == "chicago" then
- if self:get_style():get_version() >= "1.1" then
- page_range_format = "chicago-16"
- else
- page_range_format = "chicago-15"
- end
- end
+ return ir
+end
- local last_position = 1
- local page_parts = {}
- local punct_list = {}
- for part, punct, pos in string.gmatch(page, "(.-)%s*([,&])%s*()") do
- table.insert(page_parts, part)
- table.insert(punct_list, punct)
- last_position = pos
- end
- table.insert(page_parts, string.sub(page, last_position))
-
- res = ""
- for i, part in ipairs(page_parts) do
- res = res .. self:_format_range(part, page_range_format, page_range_delimiter)
- local punct = punct_list[i]
- if punct then
- if punct == "&" then
- res = res .. " " .. punct .. " "
- else
- res = res .. punct .. " "
- end
+function Text:render_linked(engine, state, context, variable, text)
+ local href
+ if variable == "URL" then
+ href = text
+ elseif self.affixes and self.affixes.prefix then
+ if string.match(self.affixes.prefix, "https?://") then
+ text = self.affixes.prefix .. text
+ self.affixes.prefix = nil
+ href = text
end
- end
- res = self:escape(res)
- return res
+ elseif variable == "DOI" then
+ href = "https://doi.org/" .. text
+ elseif variable == "PMID" then
+ href = "https://www.ncbi.nlm.nih.gov/pubmed/" .. text
+ elseif variable == "PMCID" then
+ href = "https://www.ncbi.nlm.nih.gov/pmc/articles/" .. text
+ end
+ local inlines = {Linked:new(text, href)}
+ local output_format = context.format
+ local localized_quotes = nil
+ if self.quotes then
+ localized_quotes = context:get_localized_quotes()
+ end
+ inlines = output_format:with_format(inlines, self.formatting)
+ inlines = output_format:affixed_quoted(inlines, self.affixes, localized_quotes)
+ return output_format:with_display(inlines, self.display)
end
-function Text:_format_range (str, format, range_delimiter)
- local start, delimiter, stop = string.match(str, "(%w+)%s*(%-+)%s*(%S*)")
- if not stop or stop == "" then
- return string.gsub(str, "\\%-", "-")
- end
-
-
- local start_prefix, start_num = string.match(start, "(.-)(%d*)$")
- local stop_prefix, stop_num = string.match(stop, "(.-)(%d*)$")
-
- if start_prefix ~= stop_prefix then
- -- Not valid range: "n11564-1568" -> "n11564-1568"
- -- 110-N6
- -- N110-P5
- return start .. delimiter .. stop
- end
-
- if format == "chicago-16" then
- stop = self:_format_range_chicago_16(start_num, stop_num)
- elseif format == "chicago-15" then
- stop = self:_format_range_chicago_15(start_num, stop_num)
- elseif format == "expanded" then
- stop = stop_prefix .. self:_format_range_expanded(start_num, stop_num)
- elseif format == "minimal" then
- stop = self:_format_range_minimal(start_num, stop_num)
- elseif format == "minimal-two" then
- stop = self:_format_range_minimal(start_num, stop_num, 2)
+function Text:build_year_suffix_ir(engine, state, context)
+ local text = context:get_variable(self.variable, self.form)
+ local group_var
+ if text then
+ group_var = "important"
+ else
+ text = ""
+ group_var = "missing"
end
- return start .. range_delimiter .. stop
-end
-
-function Text:_format_range_chicago_16(start, stop)
- if #start < 3 or string.sub(start, -2) == "00" then
- return self:_format_range_expanded(start, stop)
- elseif string.sub(start, -2, -2) == "0" then
- return self:_format_range_minimal(start, stop)
- else
- return self:_format_range_minimal(start, stop, 2)
+ local ir = YearSuffix:new({PlainText:new(text)}, self)
+ ir.group_var = group_var
+ ir.affixes = util.clone(self.affixes)
+ ir.display = self.display
+ ir.formatting = util.clone(self.formatting)
+ if self.quotes then
+ ir.quotes = context:get_localized_quotes()
end
- return stop
+ return ir
end
-function Text:_format_range_chicago_15(start, stop)
- if #start < 3 or string.sub(start, -2) == "00" then
- return self:_format_range_expanded(start, stop)
- else
- local changed_digits = self:_format_range_minimal(start, stop)
- if string.sub(start, -2, -2) == "0" then
- return changed_digits
- elseif #start == 4 and #changed_digits == 3 then
- return self:_format_range_expanded(start, stop)
- else
- return self:_format_range_minimal(start, stop, 2)
+function Text:build_macro_ir(engine, state, context)
+ local macro = context:get_macro(self.macro)
+ state:push_macro(self.macro)
+ local ir = macro:build_ir(engine, state, context)
+ state:pop_macro(self.macro)
+ if ir then
+ ir.affixes = util.clone(self.affixes)
+ ir.display = self.display
+ ir.formatting = util.clone(self.formatting)
+ if self.quotes then
+ ir.quotes = context:get_localized_quotes()
end
end
- return stop
+ return ir
end
-function Text:_format_range_expanded(start, stop)
- -- Expand "1234–56" -> "1234–1256"
- if #start <= #stop then
- return stop
+function Text:build_term_ir(engine, state, context)
+ local str = context:get_simple_term(self.term, self.form, self.plural)
+ if not str then
+ return nil
end
- return string.sub(start, 1, #start - #stop) .. stop
+ local inlines = self:render_text_inlines(str, context)
+ return Rendered:new(inlines, self)
end
-function Text:_format_range_minimal(start, stop, threshold)
- threshold = threshold or 1
- if #start < #stop then
- return stop
- end
- local offset = #start - #stop
- for i = 1, #stop - threshold do
- local j = i + offset
- if string.sub(stop, i, i) ~= string.sub(start, j, j) then
- return string.sub(stop, i)
- end
- end
- return string.sub(stop, -threshold)
+function Text:build_value_ir(engine, state, context)
+ local inlines = self:render_text_inlines(self.value, context)
+ return Rendered:new(inlines, self)
end
-text.Text = Text
+text_module.Text = Text
-return text
+return text_module
diff --git a/biblio/citation-style-language/citeproc-output.lua b/biblio/citation-style-language/citeproc-output.lua
new file mode 100644
index 0000000000..6aca4533da
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-output.lua
@@ -0,0 +1,1534 @@
+--
+-- Copyright (c) 2021-2022 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+local output_module = {}
+
+local unicode = require("unicode")
+local dom = require("luaxml-domobject")
+
+local util = require("citeproc-util")
+
+
+local LocalizedQuotes = {
+ outer_open = util.unicode['left double quotation mark'],
+ outer_close = util.unicode['right double quotation mark'],
+ inner_open = util.unicode['left single quotation mark'],
+ inner_close = util.unicode['right single quotation mark'],
+ punctuation_in_quote = false,
+}
+
+function LocalizedQuotes:new(outer_open, outer_close, inner_open, inner_close, punctuation_in_quote)
+ local o = {
+ outer_open = outer_open or util.unicode['left double quotation mark'],
+ outer_close = outer_close or util.unicode['right double quotation mark'],
+ inner_open = inner_open or util.unicode['left single quotation mark'],
+ inner_close = inner_close or util.unicode['right single quotation mark'],
+ punctuation_in_quote = punctuation_in_quote,
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+
+local InlineElement = {
+ _type = "InlineElement",
+ _base_class = "InlineElement",
+}
+
+function InlineElement:derive(type)
+ local o = {
+ _type = type,
+ }
+ self[type] = o
+ setmetatable(o, self)
+ self.__index = self
+ o.__index = o
+ return o
+end
+
+function InlineElement:new(inlines)
+ local o = {
+ inlines = inlines,
+ _type = self._type,
+ }
+ setmetatable(o, self)
+ return o
+end
+
+
+local PlainText = InlineElement:derive("PlainText")
+
+function PlainText:new(value)
+ local o = InlineElement.new(self)
+ o.value = value
+ setmetatable(o, self)
+ return o
+end
+
+
+local Formatted = InlineElement:derive("Formatted")
+
+function Formatted:new(inlines, formatting)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ o.formatting = formatting
+ setmetatable(o, self)
+ return o
+end
+
+
+local Micro = InlineElement:derive("Micro")
+
+-- This is how we can flip-flop only user-supplied styling.
+-- Inside this is parsed micro html
+function Micro:new(inlines)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ setmetatable(o, self)
+ return o
+end
+
+
+local Quoted = InlineElement:derive("Quoted")
+
+function Quoted:new(inlines, localized_quotes)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ o.is_inner = false
+ if localized_quotes then
+ o.quotes = localized_quotes
+ else
+ o.quotes = LocalizedQuotes:new()
+ end
+
+ setmetatable(o, self)
+ return o
+end
+
+
+local NoCase = InlineElement:derive("NoCase")
+
+function NoCase:new(inlines)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ setmetatable(o, self)
+ return o
+end
+
+
+local NoDecor = InlineElement:derive("NoDecor")
+
+function NoDecor:new(inlines)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ setmetatable(o, self)
+ return o
+end
+
+
+local Linked = InlineElement:derive("Linked")
+
+function Linked:new(value, href)
+ local o = InlineElement.new(self)
+ o.value = value
+ o.href = href
+ setmetatable(o, self)
+ return o
+end
+
+
+local Div = InlineElement:derive("Div")
+
+function Div:new(inlines, display)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ o.div = display
+ setmetatable(o, self)
+ return o
+end
+
+
+function InlineElement:parse(str, context)
+ -- Return a list of inlines
+ if type(str) ~= "string" then
+ print(debug.traceback())
+ end
+ local html_str = "<div>" .. str .. "</div>"
+ local ok, html = pcall(dom.parse, html_str)
+ local inlines
+ if ok then
+ local div = html:get_path("div")[1]
+ local el = InlineElement:from_node(div)
+ inlines = el.inlines
+ else
+ local el = PlainText:new(str)
+ inlines = {el}
+ end
+
+ inlines = InlineElement:parse_quotes(inlines, context)
+ return inlines
+end
+
+function InlineElement:from_node(node)
+ local tag_name = node:get_element_name()
+ local inlines = {}
+
+ for _, child in ipairs(node:get_children()) do
+ local inline
+ if child:is_text() then
+ inline = PlainText:new(child:get_text())
+ elseif child:is_element() then
+ inline = InlineElement:from_node(child)
+ end
+ table.insert(inlines, inline)
+ end
+
+ if tag_name == "i" then
+ return Formatted:new(inlines, {["font-style"] = "italic"})
+ elseif tag_name == "b" then
+ return Formatted:new(inlines, {["font-weight"] = "bold"})
+ elseif tag_name == "sup" then
+ return Formatted:new(inlines, {["vertical-align"] = "sup"})
+ elseif tag_name == "sub" then
+ return Formatted:new(inlines, {["vertical-align"] = "sub"})
+ elseif tag_name == "sc" then
+ return Formatted:new(inlines, {["font-variant"] = "small-caps"})
+ elseif tag_name == "span" then
+ local style = node:get_attribute("style")
+ local class = node:get_attribute("class")
+ if style == "font-variant:small-caps;" or style == "font-variant: small-caps;" then
+ return Formatted:new(inlines, {["font-variant"] = "small-caps"})
+ elseif class == "nocase" then
+ return NoCase:new(inlines)
+ elseif class == "nodecor" then
+ return NoDecor:new(inlines)
+ end
+ end
+
+ return InlineElement:new(inlines)
+end
+
+function InlineElement:parse_quotes(inlines, context)
+ local quote_fragments = InlineElement:get_quote_fragments(inlines)
+ -- util.debug(quote_fragments)
+
+ local quote_stack = {}
+ local text_stack = {{}}
+
+ local localized_quotes = context:get_localized_quotes()
+
+ for _, fragment in ipairs(quote_fragments) do
+ local top_text_list = text_stack[#text_stack]
+
+ if type(fragment) == "table" then
+ if fragment.inlines then
+ fragment.inlines = self:parse_quotes(fragment.inlines, context)
+ end
+ table.insert(top_text_list, fragment)
+
+ elseif type(fragment) == "string" then
+ local quote = fragment
+ local top_quote = quote_stack[#quote_stack]
+
+ if quote == "'" then
+ if top_quote == "'" and #top_text_list > 0 then
+ table.remove(quote_stack)
+ local quoted = Quoted:new(top_text_list, localized_quotes)
+ table.remove(text_stack)
+ table.insert(text_stack[#text_stack], quoted)
+ else
+ table.insert(quote_stack, quote)
+ table.insert(text_stack, {})
+ end
+
+ elseif quote == '"' then
+ if top_quote == '"' then
+ table.remove(quote_stack)
+ local quoted = Quoted:new(top_text_list, localized_quotes)
+ table.remove(text_stack)
+ table.insert(text_stack[#text_stack], quoted)
+ else
+ table.insert(quote_stack, quote)
+ table.insert(text_stack, {})
+ end
+
+ elseif quote == util.unicode["left single quotation mark"] or
+ quote == util.unicode["left double quotation mark"] or
+ quote == util.unicode["left-pointing double angle quotation mark"] then
+ table.insert(quote_stack, quote)
+ table.insert(text_stack, {})
+
+ elseif (quote == util.unicode["right single quotation mark"] and
+ top_quote == util.unicode["left single quotation mark"]) or
+ (quote == util.unicode["right double quotation mark"] and
+ top_quote == util.unicode["left double quotation mark"]) or
+ (quote == util.unicode["right-pointing double angle quotation mark"] and
+ top_quote == util.unicode["left-pointing double angle quotation mark"]) then
+ table.remove(quote_stack)
+ local quoted = Quoted:new(top_text_list, localized_quotes)
+ table.remove(text_stack)
+ table.insert(text_stack[#text_stack], quoted)
+
+ else
+ local last_inline = top_text_list[#top_text_list]
+ if last_inline and last_inline._type == "PlainText" then
+ last_inline.value = last_inline.value .. fragment
+ else
+ table.insert(top_text_list, PlainText:new(fragment))
+ end
+ end
+
+ end
+ end
+
+ local elements = text_stack[1]
+ if #text_stack > 1 then
+ assert(#text_stack == #quote_stack + 1)
+ for i, quote in ipairs(quote_stack) do
+ if quote == "'" then
+ quote = util.unicode["apostrophe"]
+ end
+ local last_inline = elements[#elements]
+ if last_inline and last_inline._type == "PlainText" then
+ last_inline.value = last_inline.value .. quote
+ else
+ table.insert(elements, PlainText:new(quote))
+ end
+
+ for _, inline in ipairs(text_stack[i + 1]) do
+ if inline._type == "PlainText" then
+ local last_inline = elements[#elements]
+ if last_inline and last_inline._type == "PlainText" then
+ last_inline.value = last_inline.value .. inline.value
+ else
+ table.insert(elements, inline)
+ end
+ else
+ table.insert(elements, inline)
+ end
+ end
+ end
+ end
+
+ return elements
+end
+
+local function merge_fragments_at(fragments, i)
+ if type(fragments[i+1]) == "string" then
+ fragments[i] = fragments[i] .. fragments[i+1]
+ table.remove(fragments, i+1)
+ end
+ if type(fragments[i-1]) == "string" then
+ fragments[i-1] = fragments[i-1] .. fragments[i]
+ table.remove(fragments, i)
+ end
+end
+
+-- Return a list of strings and InlineElement
+function InlineElement:get_quote_fragments(inlines)
+ local fragments = {}
+ for _, inline in ipairs(inlines) do
+ if inline._type == "PlainText" then
+ local quote_tuples = {}
+ for _, quote in ipairs({
+ "'",
+ '"',
+ util.unicode["left single quotation mark"],
+ util.unicode["right single quotation mark"],
+ util.unicode["left double quotation mark"],
+ util.unicode["right double quotation mark"],
+ util.unicode["left-pointing double angle quotation mark"],
+ util.unicode["right-pointing double angle quotation mark"],
+ }) do
+ string.gsub(inline.value, "()(" .. quote .. ")()", function (idx, qt, next_idx)
+ table.insert(quote_tuples, {idx, qt, next_idx})
+ end)
+ end
+ table.sort(quote_tuples, function (a, b)
+ return a[1] < b[1]
+ end)
+ local start_idx = 1
+ for _, quote_tuple in ipairs(quote_tuples) do
+ local idx, qt, next_idx = table.unpack(quote_tuple)
+ local fragment = string.sub(inline.value, start_idx, idx-1)
+ if fragment ~= "" then
+ table.insert(fragments, fragment)
+ end
+ table.insert(fragments, qt)
+ start_idx = next_idx
+ end
+ -- Insert last fragment
+ local fragment = string.sub(inline.value, start_idx, #inline.value)
+ if fragment ~= "" then
+ table.insert(fragments, fragment)
+ end
+ else
+ table.insert(fragments, inline)
+ end
+
+ for i = #fragments, 1, -1 do
+ local fragment = fragments[i]
+ if fragment == "'" or fragment == '"' then
+ local left, right
+ if i > 1 then
+ left = fragments[i - 1]
+ if type(left) == "table" then
+ left = left:get_right_most_string()
+ end
+ end
+ if i < #fragments then
+ right = fragments[i + 1]
+ if type(right) == "table" then
+ right = right:get_left_most_string()
+ end
+ end
+ -- TODO: consider utf-8
+ if left and right then
+ if string.match(left, "%s$") and string.match(right, "^%s") then
+ -- Orphan quote: bugreports_SingleQuote.txt
+ if fragment == "'" then
+ fragments[i] = util.unicode['apostrophe']
+ end
+ merge_fragments_at(fragments, i)
+ end
+ if not string.match(left, "[%s%p]$") and not string.match(right, "^[%s%p]") then
+ if fragment == "'" then
+ fragments[i] = util.unicode['apostrophe']
+ end
+ merge_fragments_at(fragments, i)
+ end
+ end
+ end
+ end
+ end
+ return fragments
+end
+
+function InlineElement:get_left_most_string()
+ if self.value then
+ return self.value
+ elseif self.inlines then
+ return self.inlines[1]:get_left_most_string()
+ end
+end
+
+function InlineElement:get_right_most_string()
+ if self.value then
+ return self.value
+ elseif self.inlines then
+ return self.inlines[#self.inlines]:get_left_most_string()
+ end
+end
+
+function InlineElement:capitalize_first_term()
+ -- util.debug(self)
+ if self._type == "PlainText" then
+ self.value = util.capitalize(self.value)
+ elseif self.inlines[1] then
+ self.inlines[1]:capitalize_first_term()
+ end
+end
+
+
+local OutputFormat = {}
+
+function OutputFormat:new(format_name)
+ local o = {
+ name = format_name,
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function OutputFormat:flatten_ir(ir)
+ if self.group_var == "missing" or self.collapse_suppressed then
+ return {}
+ end
+ local inlines = {}
+ if ir._type == "SeqIr" or ir._type == "NameIr" then
+ inlines = self:flatten_seq_ir(ir)
+ else
+ inlines = self:with_format(ir.inlines, ir.formatting)
+ inlines = self:affixed_quoted(inlines, ir.affixes, ir.quotes);
+ inlines = self:with_display(inlines, ir.display);
+ end
+ return inlines
+end
+
+function OutputFormat:flatten_seq_ir(ir)
+ if not ir.children then
+ print(debug.traceback())
+ end
+ if #ir.children == 0 then
+ return {}
+ end
+ local inlines_list = {}
+ for _, child in ipairs(ir.children) do
+ if child.group_var ~= "missing" and not child.collapse_suppressed then
+ local child_inlines = self:flatten_ir(child)
+ if #child_inlines > 0 then
+ table.insert(inlines_list, child_inlines)
+ end
+ end
+ end
+
+ if #inlines_list == 0 then
+ return {}
+ end
+
+ local inlines = self:group(inlines_list, ir.delimiter, ir.formatting)
+ -- assert ir.quotes == localized quotes
+ inlines = self:affixed_quoted(inlines, ir.affixes, ir.quotes);
+ inlines = self:with_display(inlines, ir.display);
+ return inlines
+end
+
+function OutputFormat:group(inlines_list, delimiter, formatting)
+ -- Each node is list of InlineElements
+ if #inlines_list == 1 then
+ return self:format_list(inlines_list[1], formatting)
+ else
+ local inlines = OutputFormat:join_many(inlines_list, delimiter)
+ return self:format_list(inlines, formatting)
+ end
+end
+
+function OutputFormat:format_list(inlines, formatting)
+ if formatting then
+ return {Formatted:new(inlines, formatting)}
+ else
+ return inlines
+ end
+end
+
+function OutputFormat:join_many(lists, delimiter)
+ local res = {}
+ for i, list in ipairs(lists) do
+ if delimiter and i > 1 then
+ table.insert(res, PlainText:new(delimiter))
+ end
+ for _, el in ipairs(list) do
+ table.insert(res, el)
+ end
+ end
+ return res
+end
+
+function OutputFormat:with_format(inlines, formatting)
+ return self:format_list(inlines, formatting)
+end
+
+function OutputFormat:apply_text_case(inlines, text_case, is_english)
+ if not inlines or #inlines == 0 or not text_case then
+ return
+ end
+ -- Title case conversion only affects English-language items.
+ if text_case == "title" and not is_english then
+ return
+ end
+ local is_uppercase = false -- TODO
+ self:apply_text_case_inner(inlines, text_case, false, is_uppercase)
+end
+
+local function string_contains_word(str)
+ return string.match(str, "%w") ~= nil
+end
+
+local function inline_contains_word(inline)
+ if inline._type == "PlainText" then
+ return string_contains_word(inline.value)
+ elseif inline.inlines then
+ for _, el in ipairs(inline.inlines) do
+ if inline_contains_word(el) then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+function OutputFormat:apply_text_case_inner(inlines, text_case, seen_one, is_uppercase)
+ for i, inline in ipairs(inlines) do
+ if seen_one and text_case == "capitalize-first" then
+ break
+ end
+ local is_last = (i == #inlines)
+ if inline._type == "PlainText" then
+ inline.value = self:transform_case(inline.value, text_case, seen_one, is_last, is_uppercase);
+ seen_one = seen_one or string_contains_word(inline.value)
+ elseif inline._type == "NoCase" or
+ inline._type == "NoDecor" or
+ (inline._type == "Formatted" and inline.formatting["font-variant"] == "small-caps") or
+ (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sup") or
+ (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sub") then
+ seen_one = seen_one or inline_contains_word(inline)
+
+ elseif inline._type == "Formatted" or inline._type == "Quoted" then
+ seen_one = self:apply_text_case_inner(inline.inlines, text_case, seen_one, is_uppercase) or seen_one
+ end
+ end
+ return seen_one
+end
+
+local function transform_lowercase(str)
+ return string.gsub(str, utf8.charpattern, unicode.utf8.lower)
+end
+
+local function transform_uppercase(str)
+ -- TODO: locale specific uppercase: textcase_LocaleUnicode.txt
+ return string.gsub(str, utf8.charpattern, unicode.utf8.upper)
+end
+
+local function transform_first_word(str, transform)
+ -- TODO: [Unicode word boundaries](https://www.unicode.org/reports/tr29/#Word_Boundaries)
+ local segments = util.segment_words(str)
+ for _, segment in ipairs(segments) do
+ if segment[1] ~= "" then
+ segment[1] = transform(segment[1])
+ break
+ end
+ end
+ local res = ""
+ for _, segment in ipairs(segments) do
+ res = res .. segment[1] .. segment[2]
+ end
+ return res
+end
+
+local function transform_each_word(str, seen_one, is_last, transform)
+ -- util.debug(str)
+ local segments = util.segment_words(str)
+ -- util.debug(segments)
+ -- print(debug.traceback())
+
+ local first_idx
+ local last_idx
+ for i, segment in ipairs(segments) do
+ if segment[1] ~= "" then
+ if not first_idx then
+ first_idx = i
+ end
+ last_idx = i
+ end
+ end
+
+ local immediate_before = ""
+ local last_punct = ""
+ for i, segment in ipairs(segments) do
+ local is_first_word = not seen_one and i == first_idx
+ local is_last_word = is_last and i == last_idx
+ local follows_colon = (
+ last_punct == ":" or
+ last_punct == "!" or
+ last_punct == "?" or
+ last_punct == "?")
+ local no_stop_word = is_first_word or is_last_word or follows_colon or (segment[2] == "-" and immediate_before ~= "-")
+
+ if (immediate_before == "." or immediate_before == "-") and #segment[1] == 1 then
+ else
+ segment[1] = transform(segment[1], no_stop_word)
+ end
+
+ if segment[1] ~= "" then
+ immediate_before = segment[1]
+ last_punct = string.match(segment[1], "(%S)%s*$") or last_punct
+ end
+ if segment[2] ~= "" then
+ immediate_before = segment[2]
+ last_punct = string.match(segment[2], "(%S)%s*$") or last_punct
+ end
+ end
+ local res = ""
+ for _, segment in ipairs(segments) do
+ res = res .. segment[1] .. segment[2]
+ end
+ return res
+end
+
+local function transform_capitalize_word_if_lower(word)
+ if util.is_lower(word) then
+ return string.gsub(word, utf8.charpattern, unicode.utf8.upper, 1)
+ else
+ return word
+ end
+end
+
+local function title_case_word(word, no_stop_word)
+ -- Entirely non-English
+ -- e.g. "β" in "β-Carotine"
+ if string.match(word, "%a") and (not util.stop_words[word] or no_stop_word) and util.is_lower(word) then
+ return string.gsub(word, utf8.charpattern, unicode.utf8.upper, 1)
+ else
+ return word
+ end
+end
+
+function OutputFormat:transform_case(str, text_case, seen_one, is_last, is_uppercase)
+ local res = str
+ if text_case == "lowercase" then
+ res = transform_lowercase(str)
+ elseif text_case == "uppercase" then
+ res = transform_uppercase(str)
+ elseif text_case == "capitalize-first" then
+ res = transform_first_word(str, transform_capitalize_word_if_lower)
+ elseif text_case == "capitalize-all" then
+ res = transform_each_word(str, false, false, transform_capitalize_word_if_lower)
+ elseif text_case == "sentence" then
+ -- TODO: if uppercase convert all to lowercase
+ res = transform_first_word(str, transform_capitalize_word_if_lower)
+ elseif text_case == "title" then
+ -- TODO: if uppercase convert all to lowercase
+ res = transform_each_word(str, seen_one, is_last, title_case_word)
+ end
+ return res
+end
+
+function OutputFormat:affixed(inlines, affixes)
+ if affixes and affixes.prefix then
+ table.insert(inlines, 1, PlainText:new(affixes.prefix))
+ end
+ if affixes and affixes.suffix then
+ table.insert(inlines, PlainText:new(affixes.suffix))
+ end
+ return inlines
+end
+
+function OutputFormat:affixed_quoted(inlines, affixes, localized_quotes)
+ inlines = util.clone(inlines)
+ if localized_quotes then
+ inlines = self:quoted(inlines, localized_quotes)
+ end
+ if affixes and affixes.prefix then
+ table.insert(inlines, 1, PlainText:new(affixes.prefix))
+ end
+ if affixes and affixes.suffix then
+ table.insert(inlines, PlainText:new(affixes.suffix))
+ end
+ return inlines
+end
+
+function OutputFormat:quoted(inlines, localized_quotes)
+ return {Quoted:new(inlines, localized_quotes)}
+end
+
+function OutputFormat:with_display(nodes, display)
+ if display then
+ return {Div:new(nodes, display)}
+ else
+ return nodes
+ end
+end
+
+function OutputFormat:output(inlines, context)
+ self:flip_flop_inlines(inlines)
+
+ self:move_punctuation(inlines)
+
+ -- util.debug(inlines)
+
+ return self:write_inlines(inlines, context)
+end
+
+function OutputFormat:output_bibliography_entry(inlines, context)
+ self:flip_flop_inlines(inlines)
+ -- util.debug(inlines)
+ self:move_punctuation(inlines)
+ -- TODO:
+ -- if self.format == "html" then
+ -- elseif self.format == "latex" then
+ -- end
+ local res = self:write_inlines(inlines, context)
+ local markup = self.markups["@bibliography/entry"]
+ if type(markup) == "string" then
+ res = string.format(markup, res)
+ elseif type(markup) == "function" then
+ res = markup(res, context)
+ end
+ return res
+end
+
+function OutputFormat:flip_flop_inlines(inlines)
+ local flip_flop_state = {
+ ["font-style"] = "normal",
+ ["font-variant"] = "normal",
+ ["font-weight"] = "normal",
+ ["text-decoration"] = "none",
+ ["vertical-alignment"] = "baseline",
+ in_inner_quotes = false,
+ }
+ self:flip_flop(inlines, flip_flop_state)
+end
+
+function OutputFormat:flip_flop(inlines, state)
+ for i, inline in ipairs(inlines) do
+ if inline._type == "Micro" then
+ self:flip_flop_micro_inlines(inline.inlines, state)
+
+ elseif inline._type == "Formatted" then
+ local new_state = util.clone(state)
+ local formatting = inline.formatting
+
+ for _, attribute in ipairs({"font-style", "font-variant", "font-weight"}) do
+ local value = formatting[attribute]
+ if value then
+ if value == state[attribute] then
+ if value == "normal" then
+ formatting[attribute] = nil
+ -- Formatting outside Micro is not reset to "normal".
+ -- else
+ -- formatting[attribute] = "normal"
+ end
+ end
+ new_state[attribute] = value
+ end
+ end
+ self:flip_flop(inline.inlines, new_state)
+
+ elseif inline._type == "Quoted" then
+ inline.is_inner = state.in_inner_quotes
+ local new_state = util.clone(state)
+ new_state.in_inner_quotes = not new_state.in_inner_quotes
+ self:flip_flop(inline.inlines, new_state)
+
+ elseif inline._type == "NoDecor" then
+ local new_state = {
+ ["font-style"] = "normal",
+ ["font-variant"] = "normal",
+ ["font-weight"] = "normal",
+ ["text-decoration"] = "none",
+ }
+ self:flip_flop(inline.inlines, new_state)
+ for attr, value in pairs(new_state) do
+ if value and state[attr] ~= value then
+ if not inline.formatting then
+ inline._type = "Formatted"
+ inline.formatting = {}
+ end
+ inline.formatting[attr] = value
+ end
+ end
+
+ elseif inline.inlines then -- Div, ...
+ self:flip_flop(inline.inlines, state)
+ end
+ end
+end
+
+function OutputFormat:flip_flop_micro_inlines(inlines, state)
+ for i, inline in ipairs(inlines) do
+ if inline._type == "Micro" then
+ self:flip_flop_micro_inlines(inline.inlines, state)
+
+ elseif inline._type == "Formatted" then
+ local new_state = util.clone(state)
+ local formatting = inline.formatting
+
+ for _, attribute in ipairs({"font-style", "font-variant", "font-weight"}) do
+ local value = formatting[attribute]
+ if value then
+ if value == state[attribute] then
+ if value == "normal" then
+ formatting[attribute] = nil
+ else
+ -- Formatting inside Micro is reset to "normal".
+ formatting[attribute] = "normal"
+ value = "normal"
+ end
+ end
+ new_state[attribute] = value
+ end
+ end
+ self:flip_flop_micro_inlines(inline.inlines, new_state)
+
+ elseif inline._type == "Quoted" then
+ inline.is_inner = state.in_inner_quotes
+ local new_state = util.clone(state)
+ new_state.in_inner_quotes = not new_state.in_inner_quotes
+ self:flip_flop_micro_inlines(inline.inlines, new_state)
+
+ elseif inline._type == "NoDecor" then
+ local new_state = {
+ ["font-style"] = "normal",
+ ["font-variant"] = "normal",
+ ["font-weight"] = "normal",
+ ["text-decoration"] = "none",
+ }
+ self:flip_flop_micro_inlines(inline.inlines, new_state)
+ for attr, value in pairs(new_state) do
+ if value and state[attr] ~= value then
+ if not inline.formatting then
+ inline._type = "Formatted"
+ inline.formatting = {}
+ end
+ inline.formatting[attr] = value
+ end
+ end
+
+ elseif inline.inlines then -- Div, ...
+ self:flip_flop_micro_inlines(inline.inlines, state)
+ end
+ end
+end
+
+local function find_left(inline)
+ if not inline then
+ print(debug.traceback())
+ end
+ if inline._type == "PlainText" then
+ return inline
+ -- elseif inline._type == "Micro" then
+ -- return nil
+ elseif inline.inlines and inline._type~="Quoted" then
+ return find_left(inline.inlines[1])
+ else
+ return nil
+ end
+end
+
+local function find_right(inline)
+ if inline._type == "PlainText" then
+ return inline
+ -- elseif inline._type == "Micro" then
+ -- return nil
+ elseif inline.inlines and #inline.inlines > 0 and inline._type ~= "Quoted" then
+ return find_right(inline.inlines[#inline.inlines])
+ else
+ return nil
+ end
+end
+
+local function find_right_in_quoted(inline)
+ if inline._type == "PlainText" then
+ return inline
+ -- elseif inline._type == "Micro" then
+ -- return nil
+ elseif inline.inlines and #inline.inlines > 0 then
+ return find_right_in_quoted(inline.inlines[#inline.inlines])
+ else
+ return nil
+ end
+end
+
+-- "'Foo,' bar" => ,
+local function find_right_quoted(inline)
+ if inline._type == "Quoted" and #inline.inlines > 0 then
+ return find_right_in_quoted(inline.inlines[#inline.inlines]), inline.quotes.punctuation_in_quote
+ -- elseif inline._type == "Micro" then
+ -- return nil
+ elseif inline.inlines and #inline.inlines > 0 then
+ return find_right_quoted(inline.inlines[#inline.inlines])
+ else
+ return nil, false
+ end
+end
+
+local function smash_string_push(first, second)
+ local first_char = string.sub(first.value, -1)
+ local second_char = string.sub(second.value, 1, 1)
+ -- util.debug(first_char)
+ -- util.debug(second_char)
+
+ local punct_map = output_module.quote_punctuation_map
+ if second_char == " " and (first_char == " " or
+ util.endswith(first.value, util.unicode["no-break space"])) then
+ second.value = string.sub(second.value, 2)
+ elseif punct_map[first_char] then
+ if first_char == second_char then
+ second.value = string.sub(second.value, 2)
+ else
+ local combined = punct_map[first_char][second_char]
+ if combined and #combined == 1 then
+ second.value = string.sub(second.value, 2)
+ first.value = string.sub(first.value, 1, -2) .. combined
+ end
+ end
+ end
+end
+
+local function smash_just_punc(first, second)
+ first = find_right(first) -- PlainText
+ second = find_left(second) -- PlainText
+ if first and second then
+ local first_char = string.sub(first.value, -1)
+ local second_char = string.sub(second.value, 1, 1)
+ -- util.debug(first_char)
+ -- util.debug(second_char)
+
+ local punct_map = output_module.quote_punctuation_map
+ if second_char == " " and (first_char == " " or
+ util.endswith(first.value, util.unicode["no-break space"])) then
+ second.value = string.sub(second.value, 2)
+ return true
+ elseif punct_map[first_char] then
+ if first_char == second_char then
+ second.value = string.sub(second.value, 2)
+ return true
+ else
+ local combined = punct_map[first_char][second_char]
+ if combined and #combined == 1 then
+ second.value = string.sub(second.value, 2)
+ first.value = string.sub(first.value, 1, -2) .. combined
+ return true
+ end
+ end
+ end
+ else
+ return false
+ end
+end
+
+local function normalise_text_elements(inlines)
+ -- 1. Merge punctuations: "?." => "?"
+ -- 2. Merge spaces: " " => " "
+ local idx = 1
+ while idx < #inlines do
+ local first = inlines[idx]
+ local second = inlines[idx+1]
+
+ if first._type == "PlainText" and second._type == "PlainText" then
+ smash_string_push(first, second)
+ first.value = first.value .. second.value
+ table.remove(inlines, idx + 1)
+
+ elseif first._type == "Micro" and second._type == "PlainText" then
+ local success = smash_just_punc(first, second)
+ if success then
+ if second.value == "" then
+ table.remove(inlines, idx + 1)
+ end
+ else
+ idx = idx + 1
+ end
+
+ elseif first._type == "Formatted" and second._type == "PlainText" then
+ local success = smash_just_punc(first, second)
+ if success then
+ if second.value == "" then
+ table.remove(inlines, idx + 1)
+ end
+ else
+ idx = idx + 1
+ end
+
+ else
+ idx = idx + 1
+ end
+ end
+
+end
+
+local function move_in_quotes(first, second)
+ local first_char = string.sub(first.value, -1)
+ local second_char = string.sub(second.value, 1, 1)
+ local success = false
+ if output_module.move_in_puncts[second_char] then
+ if first_char == second_char then
+ second.value = string.sub(second.value, 2)
+ success = true
+ elseif output_module.quote_punctuation_map[first_char] then
+ local combined = output_module.quote_punctuation_map[first_char][second_char]
+ first.value = string.sub(first.value, 1, -2) .. combined
+ second.value = string.sub(second.value, 2)
+ success = true
+ else
+ first.value = first.value .. second_char
+ second.value = string.sub(second.value, 2)
+ success = true
+ end
+ end
+ return success
+end
+
+local function move_out_quotes(first, second)
+ local first_char = string.sub(first.value, -1)
+ local second_char = string.sub(second.value, 1, 1)
+ local success = false
+ if output_module.move_out_puncts[first_char] then
+ if first_char == second_char then
+ first.value = string.sub(first.value, 1, -2)
+ success = true
+ elseif output_module.quote_punctuation_map[second_char] then
+ local combined = output_module.quote_punctuation_map[first_char][second_char]
+ first.value = string.sub(first.value, 1, -2)
+ second.value = combined .. string.sub(second.value, 2)
+ success = true
+ else
+ first.value = string.sub(first.value, 1, -2)
+ second.value = first_char .. second.value
+ success = true
+ end
+ end
+ return success
+end
+
+local function move_around_quote(inlines)
+ local idx = 1
+
+ while idx < #inlines do
+ -- Move punctuation into quotes as needed
+ local first, punctuation_in_quote = find_right_quoted(inlines[idx])
+
+ local second = find_left(inlines[idx+1])
+ local success = false
+ if first and second then
+ if punctuation_in_quote then
+ success = move_in_quotes(first, second)
+ else
+ success = move_out_quotes(first, second)
+ end
+ if not success then
+ idx = idx + 1
+ end
+ else
+ idx = idx + 1
+ end
+ end
+end
+
+function OutputFormat:move_punctuation(inlines, piq)
+ -- Merge punctuations
+ normalise_text_elements(inlines)
+
+ move_around_quote(inlines)
+
+ for _, inline in ipairs(inlines) do
+ if inline._type == "Quoted" or inline._type == "Formatted" or
+ inline._type == "Div" then
+ self:move_punctuation(inline.inlines)
+ end
+ end
+end
+
+function OutputFormat:write_inlines(inlines, context)
+ local res = ""
+ for _, inline in ipairs(inlines) do
+ res = res .. self:write_inline(inline, context)
+ end
+ return res
+end
+
+function OutputFormat:write_inline(inline, context)
+ if inline.value then
+ return self:write_escaped(inline.value)
+ elseif inline.inlines then
+ return self:write_inlines(inline.inlines)
+ end
+ return ""
+end
+
+function OutputFormat:write_escaped(str, context)
+ return str
+end
+
+function OutputFormat:write_link(inline, context)
+ return self:write_escaped(inline.value)
+end
+
+
+
+local Markup = OutputFormat:new()
+
+function Markup:write_inline(inline, context)
+ -- Should be deprecated code
+ if type(inline) == "string" then
+ return self:write_escaped(inline, context)
+
+ elseif type(inline) == "table" then
+ -- util.debug(inline._type)
+ if inline._type == "PlainText" then
+ return self:write_escaped(inline.value, context)
+
+ elseif inline._type == "InlineElement" then
+ return self:write_children(inline, context)
+
+ elseif inline._type == "Formatted" then
+ return self:write_formatted(inline, context)
+
+ elseif inline._type == "Quoted" then
+ return self:write_quoted(inline, context)
+
+ elseif inline._type == "Div" then
+ return self:write_display(inline, context)
+
+ elseif inline._type == "Linked" then
+ return self:write_link(inline, context)
+
+ elseif inline._type == "NoCase" or inline._type == "NoDecor" then
+ return self:write_inlines(inline.inlines)
+
+ else
+ return self:write_inlines(inline.inlines)
+ end
+ end
+ return ""
+end
+
+function Markup:write_children(inline, context)
+ local res = ""
+ for _, child_inline in ipairs(inline.inlines) do
+ res = res .. self:write_inline(child_inline, context)
+ end
+ return res
+end
+
+function Markup:write_quoted(inline, context)
+ local res = self:write_children(inline, context)
+ local quotes = inline.quotes
+ if inline.is_inner then
+ return quotes.inner_open .. res .. quotes.inner_close
+ else
+ return quotes.outer_open .. res .. quotes.outer_close
+ end
+end
+
+
+local LatexWriter = Markup:new()
+
+LatexWriter.markups = {
+ ["bibstart"] = function (engine)
+ return string.format("\\begin{thebibliography}{%s}\n\n", engine.registry.longest_label)
+ end,
+ ["bibend"] = "\\end{thebibliography}",
+ ["@font-style/normal"] = "{\\normalshape %s}",
+ ["@font-style/italic"] = "\\textit{%s}",
+ ["@font-style/oblique"] = "\\textsl{%s}",
+ ["@font-variant/normal"] = "{\\normalshape %s}",
+ ["@font-variant/small-caps"] = "\\textsc{%s}",
+ ["@font-weight/normal"] = "{\\fontseries{m}\\selectfont %s}",
+ ["@font-weight/bold"] = "\\textbf{%s}",
+ ["@font-weight/light"] = "{\\fontseries{l}\\selectfont %s}",
+ ["@text-decoration/none"] = false,
+ ["@text-decoration/underline"] = "\\underline{%s}",
+ ["@vertical-align/sup"] = "\\textsuperscript{%s}",
+ ["@vertical-align/sub"] = "\\textsubscript{%s}",
+ ["@vertical-align/baseline"] = false,
+ ["@cite/entry"] = false,
+ ["@bibliography/entry"] = function (str, context)
+ if not string.match(str, "\\bibitem") then
+ str = "\\bibitem{".. context.id .. "}\n" .. str .. "\n"
+ end
+ return str
+ end,
+ ["@display/block"] = false,
+ ["@display/left-margin"] = '\n <div class="csl-left-margin">%s</div>',
+ ["@display/right-inline"] = '<div class="csl-right-inline">%s</div>\n ',
+ ["@display/indent"] = '<div class="csl-indent">%s</div>\n ',
+}
+
+function LatexWriter:write_escaped(str, context)
+ -- TeXbook, p. 38
+ str = str:gsub("\\", "\\textbackslash{}")
+ str = str:gsub("{", "\\{")
+ str = str:gsub("}", "\\}")
+ str = str:gsub("%$", "\\$")
+ str = str:gsub("&", "\\&")
+ str = str:gsub("#", "\\#")
+ str = str:gsub("%^", "\\^")
+ str = str:gsub("_", "\\_")
+ str = str:gsub("%%", "\\%%")
+ str = str:gsub("~", "\\~")
+ str = str:gsub(util.unicode["em space"], "\\quad ")
+ str = str:gsub(util.unicode["no-break space"], "~")
+ for char, sub in pairs(util.superscripts) do
+ str = string.gsub(str, char, "\\textsuperscript{" .. sub .. "}")
+ end
+ return str
+end
+
+function LatexWriter:write_formatted(inline, context)
+ local res = self:write_children(inline, context)
+ for _, key in ipairs({"font-style", "font-variant", "font-weight", "text-decoration", "vertical-align"}) do
+ local value = inline.formatting[key]
+ if value then
+ key = "@" .. key .. "/" .. value
+ local format_str = self.markups[key]
+ if format_str then
+ res = string.format(format_str, res)
+ end
+ end
+ end
+ return res
+end
+
+function LatexWriter:write_display(inline, context)
+ local plainter_text_writer = output_module.PlainTextWriter:new()
+ local str = plainter_text_writer:write_inline(inline)
+ local len = utf8.len(str)
+ if len > context.engine.registry.maxoffset then
+ context.engine.registry.maxoffset = len
+ context.engine.registry.longest_label = str
+ end
+
+ local res = self:write_children(inline, context)
+ if inline.display == "left-margin" then
+ if string.match(res, "%]") then
+ res = "{" .. res .. "}"
+ end
+ res = string.format("\\bibitem[%s]{%s}\n", res, context.id)
+
+ elseif inline.display == "right-inline" then
+ return res
+
+ elseif inline.display == "block" then
+ return ""
+ end
+ return res
+end
+
+function LatexWriter:write_link(inline, context)
+ if inline.href == inline.value then
+ return string.format("\\url{%s}", inline.value)
+ else
+ return string.format("\\href{%s}{%s}", inline.href, inline.value)
+ end
+end
+
+
+local HtmlWriter = Markup:new()
+
+HtmlWriter.markups = {
+ ["bibstart"] = "<div class=\"csl-bib-body\">\n",
+ ["bibend"] = "</div>",
+ ["@font-style/italic"] = "<i>%s</i>",
+ ["@font-style/oblique"] = "<em>%s</em>",
+ ["@font-style/normal"] = '<span style="font-style:normal;">%s</span>',
+ ["@font-variant/small-caps"] = '<span style="font-variant:small-caps;">%s</span>',
+ ["@font-variant/normal"] = '<span style="font-variant:normal;">%s</span>',
+ ["@font-weight/bold"] = "<b>%s</b>",
+ ["@font-weight/normal"] = '<span style="font-weight:normal;">%s</span>',
+ ["@font-weight/light"] = false,
+ ["@text-decoration/none"] = '<span style="text-decoration:none;">%s</span>',
+ ["@text-decoration/underline"] = '<span style="text-decoration:underline;">%s</span>',
+ ["@vertical-align/sup"] = "<sup>%s</sup>",
+ ["@vertical-align/sub"] = "<sub>%s</sub>",
+ ["@vertical-align/baseline"] = '<span style="baseline">%s</span>',
+ ["@cite/entry"] = nil,
+ ["@bibliography/entry"] = "<div class=\"csl-entry\">%s</div>\n",
+ ["@display/block"] = '\n\n <div class="csl-block">%s</div>\n',
+ ["@display/left-margin"] = '\n <div class="csl-left-margin">%s</div>',
+ ["@display/right-inline"] = '<div class="csl-right-inline">%s</div>\n ',
+ ["@display/indent"] = '<div class="csl-indent">%s</div>\n ',
+}
+
+function HtmlWriter:write_escaped(str, context)
+ str = string.gsub(str, "%&", "&#38;")
+ str = string.gsub(str, "<", "&#60;")
+ str = string.gsub(str, ">", "&#62;")
+ for char, sub in pairs(util.superscripts) do
+ str = string.gsub(str, char, "<sup>" .. sub .. "</sup>")
+ end
+ return str
+end
+
+function HtmlWriter:write_formatted(inline, context)
+ local res = self:write_children(inline, context)
+ for _, key in ipairs({"font-style", "font-variant", "font-weight", "text-decoration", "vertical-align"}) do
+ local value = inline.formatting[key]
+ if value then
+ key = "@" .. key .. "/" .. value
+ local format_str = self.markups[key]
+ if format_str then
+ res = string.format(format_str, res)
+ end
+ end
+ end
+ return res
+end
+
+function HtmlWriter:write_display(inline, context)
+ local plainter_text_writer = output_module.PlainTextWriter:new()
+ local str = plainter_text_writer:write_inline(inline)
+ local len = utf8.len(str)
+ if len > context.engine.registry.maxoffset then
+ context.engine.registry.maxoffset = len
+ context.engine.registry.longest_label = str
+ end
+
+ if #inline.inlines == 0 then
+ return ""
+ end
+ local res = self:write_children(inline, context)
+ local key = string.format("@display/%s", inline.div)
+ if inline.div == "right-inline" then
+ -- Strip trailing spaces
+ -- variables_ContainerTitleShort.txt
+ res = string.gsub(res, "%s+$", "")
+ end
+ local format_str = self.markups[key]
+ res = string.format(format_str, res)
+ return res
+end
+
+function HtmlWriter:write_link(inline, context)
+ return string.format('<a href="%s">%s</a>', inline.href, inline.value)
+end
+
+
+local PlainTextWriter = Markup:new()
+
+PlainTextWriter.markups = {}
+
+function PlainTextWriter:write_escaped(str, context)
+ return str
+end
+
+function PlainTextWriter:write_formatted(inline, context)
+ return self:write_children(inline, context)
+end
+
+function PlainTextWriter:write_display(inline, context)
+ return self:write_children(inline, context)
+end
+
+
+local SortStringFormat = OutputFormat:new()
+
+function SortStringFormat:output(inlines, context)
+ -- self:flip_flop_inlines(inlines)
+ -- self:move_punctuation(inlines)
+ return self:write_inlines(inlines, context)
+end
+
+function SortStringFormat:write_escaped(str, context)
+ str = string.gsub(str, ",", "")
+ return str
+end
+
+
+local DisamStringFormat = OutputFormat:new()
+
+function DisamStringFormat:output(inlines, context)
+ -- self:flip_flop_inlines(inlines)
+ -- self:move_punctuation(inlines)
+ return self:write_inlines(inlines, context)
+end
+
+function DisamStringFormat:flatten_ir(ir)
+ if self.group_var == "missing" then
+ return {}
+ end
+ local inlines
+ if ir._type == "SeqIr" or ir._type == "NameIr" then
+ inlines = self:flatten_seq_ir(ir)
+ elseif ir._type == "YearSuffix" then
+ -- Don't include year-suffix in disambiguation
+ inlines = {}
+ else
+ inlines = self:affixed_quoted(ir.inlines, ir.affixes, ir.quotes);
+ inlines = self:with_display(inlines, ir.display);
+ end
+ return inlines
+end
+
+function DisamStringFormat:flatten_seq_ir(ir)
+ if not ir.children then
+ print(debug.traceback())
+ end
+ if #ir.children == 0 then
+ return {}
+ end
+ local inlines_list = {}
+ for _, child in ipairs(ir.children) do
+ if child.group_var ~= "missing" then
+ -- and not child.collapse_suppressed
+ -- Suppressed irs are stil kept in the DisamStringFormat
+ table.insert(inlines_list, self:flatten_ir(child))
+ end
+ end
+
+ local inlines = self:group(inlines_list, ir.delimiter, ir.formatting)
+ -- assert ir.quotes == localized quotes
+ inlines = self:affixed_quoted(inlines, ir.affixes, ir.quotes);
+ inlines = self:with_display(inlines, ir.display);
+ return inlines
+end
+
+
+output_module.move_in_puncts = {
+ ["."] = true,
+ ["!"] = true,
+ ["?"] = true,
+ [","] = true,
+}
+
+output_module.move_out_puncts = {
+ [","] = true,
+ [";"] = true,
+ [":"] = true,
+}
+
+-- https://github.com/Juris-M/citeproc-js/blob/aa2683f48fe23be459f4ed3be3960e2bb56203f0/src/queue.js#L724
+-- Also merge duplicate punctuations.
+output_module.quote_punctuation_map = {
+ ["!"] = {
+ ["."] = "!",
+ ["?"] = "!?",
+ [":"] = "!",
+ [","] = "!,",
+ [";"] = "!;",
+ },
+ ["?"] = {
+ ["!"] = "?!",
+ ["."] = "?",
+ [":"] = "?",
+ [","] = "?,",
+ [";"] = "?;",
+ },
+ ["."] = {
+ ["!"] = ".!",
+ ["?"] = ".?",
+ [":"] = ".:",
+ [","] = ".,",
+ [";"] = ".;",
+ },
+ [":"] = {
+ ["!"] = "!",
+ ["?"] = "?",
+ ["."] = ":",
+ [","] = ":,",
+ [";"] = ":;",
+ },
+ [","] = {
+ ["!"] = ",!",
+ ["?"] = ",?",
+ [":"] = ",:",
+ ["."] = ",.",
+ [";"] = ",;",
+ },
+ [";"] = {
+ ["!"] = "!",
+ ["?"] = "?",
+ [":"] = ";",
+ [","] = ";,",
+ ["."] = ";",
+ }
+}
+
+
+output_module.LocalizedQuotes = LocalizedQuotes
+
+output_module.InlineElement = InlineElement
+output_module.PlainText = PlainText
+output_module.Formatted = Formatted
+output_module.Micro = Micro
+output_module.Quoted = Quoted
+output_module.Linked = Linked
+output_module.Div = Div
+output_module.NoCase = NoCase
+output_module.NoDecor = NoDecor
+
+output_module.OutputFormat = OutputFormat
+
+output_module.Markup = Markup
+output_module.LatexWriter = LatexWriter
+output_module.HtmlWriter = HtmlWriter
+output_module.PlainTextWriter = PlainTextWriter
+output_module.DisamStringFormat = DisamStringFormat
+output_module.SortStringFormat = SortStringFormat
+
+return output_module
diff --git a/biblio/citation-style-language/citeproc-richtext.lua b/biblio/citation-style-language/citeproc-richtext.lua
deleted file mode 100644
index f9afd3acc6..0000000000
--- a/biblio/citation-style-language/citeproc-richtext.lua
+++ /dev/null
@@ -1,779 +0,0 @@
---
--- Copyright (c) 2021-2022 Zeping Lee
--- Released under the MIT license.
--- Repository: https://github.com/zepinglee/citeproc-lua
---
-
-local richtext = {}
-
-local unicode = require("unicode")
-
-local util = require("citeproc-util")
-
-
-local RichText = {
- contents = nil,
- formats = nil,
- _type = "RichText",
-}
-
-function RichText:shallow_copy()
- local res = richtext.new()
- for _, text in ipairs(self.contents) do
- table.insert(res.contents, text)
- end
- for key, value in pairs(self.formats) do
- res.formats[key] = value
- end
- return res
-end
-
-function RichText:render(formatter, context, punctuation_in_quote)
- self:merge_punctuations()
-
- if punctuation_in_quote == nil and context then
- punctuation_in_quote = context.style:get_locale_option("punctuation-in-quote")
- end
- if punctuation_in_quote then
- self:move_punctuation_in_quote()
- end
-
- self:change_case()
-
- self:flip_flop()
-
- self:clean_formats()
-
- return self:_render(formatter, context)
-end
-
-function RichText:_render(formatter, context)
- local res = ""
- for _, text in ipairs(self.contents) do
- local str
- if type(text) == "string" then
- if formatter and formatter.text_escape then
- str = formatter.text_escape(text)
- else
- str = text
- end
- else -- RichText
- str = text:_render(formatter, context)
- end
- -- Remove leading spaces
- if string.sub(res, -1) == " " and string.sub(str, 1, 1) == " " then
- str = string.gsub(str, "^%s+", "")
- end
- res = res .. str
- end
- for _, attr in ipairs(richtext.format_sequence) do
- local value = self.formats[attr]
- if value then
- local key = string.format("@%s/%s", attr, value)
- if formatter then
- local format = formatter[key]
- if type(format) == "string" then
- res = string.format(format, res)
- elseif type(format) == "function" then
- res = format(res, context)
- end
- end
- end
- end
- return res
-end
-
-function RichText:merge_punctuations(contents, index)
- for i, text in ipairs(self.contents) do
- if text._type == "RichText" then
- contents, index = text:merge_punctuations(contents, index)
- elseif type(text) == "string" then
- if contents and index then
- local previous_string = contents[index]
- local last_char = string.sub(previous_string, -1)
- local right_punct_map = richtext.punctuation_map[last_char]
- if right_punct_map then
- local first_char = string.sub(text, 1, 1)
- local new_punctuations = nil
- if first_char == last_char then
- new_punctuations = last_char
- elseif contents == self.contents then
- new_punctuations = right_punct_map[first_char]
- end
- if new_punctuations then
- if #text == 1 then
- table.remove(self.contents, i)
- else
- self.contents[i] = string.sub(text, 2)
- end
- contents[index] = string.sub(previous_string, 1, -2) .. new_punctuations
- end
- end
- end
- contents = self.contents
- index = i
- end
- end
- return contents, index
-end
-
-function RichText:move_punctuation_in_quote()
- local i = 1
- while i <= #self.contents do
- local text = self.contents[i]
- if type(text) == "table" and text._type == "RichText" then
- text:move_punctuation_in_quote()
-
- if text.formats["quotes"] then
- local contents = self.contents
- local last_string = text
- while type(last_string) == "table" and last_string._type == "RichText" do
- contents = last_string.contents
- last_string = contents[#contents]
- end
-
- local done = false
- while not done do
- done = true
- last_string = contents[#contents]
- local last_char = string.sub(last_string, -1)
- if i < #self.contents then
- local next_text = self.contents[i + 1]
- if type(next_text) == "string" then
- local first_char = string.sub(next_text, 1, 1)
- if richtext.in_quote_punctuations[first_char] then
- done = false
- local right_punct_map = richtext.punctuation_map[last_char]
- if right_punct_map then
- first_char = right_punct_map[first_char]
- last_string = string.sub(last_string, 1, -2)
- end
- contents[#contents] = last_string .. first_char
- if #next_text == 1 then
- table.remove(self.contents, i + 1)
- else
- self.contents[i + 1] = string.sub(next_text, 2)
- end
- end
- end
- end
- end
- end
- end
- i = i + 1
- end
-end
-
-function RichText:change_case()
- for _, text in ipairs(self.contents) do
- if type(text) == "table" and text._type == "RichText" then
- text:change_case()
- end
- end
- local text_case = self.formats["text-case"]
- if text_case then
- if text_case == "lowercase" then
- self:lowercase()
- elseif text_case == "uppercase" then
- self:uppercase()
- elseif text_case == "capitalize-first" then
- self:capitalize_first()
- elseif text_case == "capitalize-all" then
- self:capitalize_all()
- elseif text_case == "sentence" then
- self:sentence()
- elseif text_case == "title" then
- self:title()
- end
- end
-end
-
-function RichText:_change_word_case(state, word_transform, first_tranform, is_phrase)
- if self.formats["text-case"] == "nocase" then
- return
- end
- if is_phrase and (self.formats["vertical-align"] == "sup" or
- self.formats["vertical-align"] == "sub" or
- self.formats["font-variant"] == "small-caps") then
- return
- end
- state = state or "after-sentence"
- word_transform = word_transform or function (x) return x end
- first_tranform = first_tranform or word_transform
- for i, text in ipairs(self.contents) do
- if type(text) == "string" then
-
- local res = ""
- local word_seps = {
- " ",
- "%-",
- "/",
- util.unicode["no-break space"],
- util.unicode["en dash"],
- util.unicode["em dash"],
- }
- for _, tuple in ipairs(util.split(text, word_seps, nil, true)) do
- local word, punctuation = table.unpack(tuple)
- if state == "after-sentence" then
- res = res .. first_tranform(word)
- if string.match(word, "%w") then
- state = "after-word"
- end
- else
- res = res .. word_transform(word, punctuation)
- end
- res = res .. punctuation
- if string.match(word, "[.!?:]%s*$") then
- state = "after-sentence"
- end
- end
-
- -- local word_index = 0
- -- local res = string.gsub(text, "%w+", function (word)
- -- word_index = word_index + 1
- -- if word_index == 1 then
- -- return first_tranform(word)
- -- else
- -- return word_transform(word)
- -- end
- -- end)
- -- if string.match(res, "[.!?:]%s*$") then
- -- state = "after-sentence"
- -- end
-
- self.contents[i] = res
- else
- state = text:_change_word_case(state, word_transform, first_tranform, true)
- end
- end
- return state
-end
-
-function RichText:lowercase()
- local word_transform = unicode.utf8.lower
- self:_change_word_case("after-sentence", word_transform)
-end
-
-function RichText:uppercase()
- local word_transform = unicode.utf8.upper
- self:_change_word_case("after-sentence", word_transform)
-end
-
-local function capitalize(str)
- local res = string.gsub(str, utf8.charpattern, unicode.utf8.upper, 1)
- return res
-end
-
-local function capitalize_if_lower(word)
- if util.is_lower(word) then
- return capitalize(word)
- else
- return word
- end
-end
-
-function RichText:capitalize_first(state)
- local first_tranform = capitalize_if_lower
- self:_change_word_case("after-sentence", nil, first_tranform)
-end
-
-function RichText:capitalize_all()
- local word_transform = capitalize_if_lower
- self:_change_word_case("after-sentence", word_transform)
-end
-
-function RichText:is_upper()
- for _, text in ipairs(self.contents) do
- if type(text) == "string" then
- if not util.is_upper(text) then
- return false
- end
- else
- local res = text:is_upper()
- if not res then
- return false
- end
- end
- end
- return true
-end
-
-function RichText:sentence()
- if self:is_upper() then
- local first_tranform = function(word)
- return capitalize(unicode.utf8.lower(word))
- end
- local word_transform = unicode.utf8.lower
- self:_change_word_case("after-sentence", word_transform, first_tranform)
- else
- local first_tranform = capitalize_if_lower
- self:_change_word_case("after-sentence", nil, first_tranform)
- end
-end
-
-function RichText:title()
- if self:is_upper() then
- local first_tranform = function(word)
- return capitalize(unicode.utf8.lower(word))
- end
- local word_transform = function(word, sep)
- local res = unicode.utf8.lower(word)
- if not util.stop_words[res] then
- res = capitalize(res)
- end
- return res
- end
- self:_change_word_case("after-sentence", word_transform, first_tranform)
- else
- local first_tranform = capitalize_if_lower
- local word_transform = function(word, sep)
- local lower = unicode.utf8.lower(word)
- -- Stop word before hyphen is treated as a normal word.
- if util.stop_words[lower] and sep ~= "-" then
- return lower
- elseif word == lower then
- return capitalize(word)
- else
- return word
- end
- end
- self:_change_word_case("after-sentence", word_transform, first_tranform)
- end
-end
-
-function richtext.concat(str1, str2)
- assert(str1 and str2)
-
- if type(str1) == "string" then
- str1 = richtext.new(str1)
- end
-
- local res
- if next(str1.formats) == nil or str2 == "" then
- -- shallow copy
- res = str1
- else
- res = richtext.new()
- res.contents = {str1}
- end
-
- if str2._type == "RichText" then
- if next(str2.formats) == nil then
- for _, text in ipairs(str2.contents) do
- table.insert(res.contents, text)
- end
- else
- table.insert(res.contents, str2)
- end
- elseif str2 ~= "" then
- table.insert(res.contents, str2)
- end
- return res
-end
-
-function richtext.concat_list(list, delimiter)
- -- Strings in the list may be nil thus ipairs() should be avoided.
- -- The delimiter may be nil.
- local res = nil
- for i = 1, #list do
- local text = list[i]
- if text and text ~= "" then
- if res then
- if delimiter and delimiter ~= "" then
- res = richtext.concat(res, delimiter)
- end
- res = richtext.concat(res, text)
- else
- if type(text) == "string" then
- text = richtext.new(text)
- end
- res = text
- end
- end
- end
- return res
-end
-
-function RichText:strip_periods()
- local last_string = self
- local contents = self.contents
- while last_string._type == "RichText" do
- contents = last_string.contents
- last_string = contents[#contents]
- end
- if string.sub(last_string, -1) == "." then
- contents[#contents] = string.sub(last_string, 1, -2)
- end
-end
-
-function RichText:add_format(attr, value)
- self.formats[attr] = value
-end
-
-function RichText:flip_flop(attr, value)
- if not attr then
- for attr, _ in pairs(richtext.flip_flop_formats) do
- self:flip_flop(attr)
- end
- return
- end
-
- local default_value = richtext.default_formats[attr]
-
- if value and value ~= default_value and self.formats[attr] == value then
- self.formats[attr] = richtext.flip_flop_values[attr][value]
- end
- if self.formats[attr] then
- value = self.formats[attr]
- end
-
- for _, text in ipairs(self.contents) do
- if type(text) == "table" and text._type == "RichText" then
- text:flip_flop(attr, value)
- end
- end
-end
-
-function RichText:clean_formats(format)
- -- Remove the formats that are default values
- if not format then
- for format, _ in pairs(richtext.default_formats) do
- self:clean_formats(format)
- end
- return
- end
- if self.formats[format] then
- if self.formats[format] == richtext.default_formats[format] then
- self.formats[format] = nil
- else
- return
- end
- end
- for _, text in ipairs(self.contents) do
- if type(text) == "table" and text._type == "RichText" then
- text:clean_formats(format)
- end
- end
-end
-
-local RichText_mt = {
- __index = RichText,
- __concat = richtext.concat,
-}
-
-local function table_update(t, new_t)
- for key, value in pairs(new_t) do
- t[key] = value
- end
- return t
-end
-
-function RichText._split_tags(str)
- -- Normalize markup
- str = string.gsub(str, '<span%s+style="font%-variant:%s*small%-caps;?">', '<span style="font-variant:small-caps;">')
- str = string.gsub(str, '<span%s+class="nocase">', '<span class="nocase">')
- str = string.gsub(str, '<span%s+class="nodecor">', '<span class="nodecor">')
-
- local strings = {}
-
- local start_index = 1
- local i = 1
-
- while i <= #str do
- local substr = string.sub(str, i)
- local starts_with_tag = false
- for tag, _ in pairs(richtext.tags) do
- if util.startswith(substr, tag) then
- if start_index <= i - 1 then
- table.insert(strings, string.sub(str, start_index, i-1))
- end
- table.insert(strings, tag)
- i = i + #tag
- start_index = i
- starts_with_tag = true
- break
- end
- end
- if not starts_with_tag then
- i = i + 1
- end
- end
- if start_index <= #str then
- table.insert(strings, string.sub(str, start_index))
- end
-
- for i = 1, #strings do
- str = strings[i]
- if str == "'" or str == util.unicode["apostrophe"] then
- local previous_str = strings[i - 1]
- local next_str = strings[i + 1]
- if previous_str and next_str then
- local previous_code_point = nil
- for _, code_point in utf8.codes(previous_str) do
- previous_code_point = code_point
- end
- local next_code_point = utf8.codepoint(next_str)
- if util.is_romanesque(previous_code_point) and util.is_romanesque(next_code_point) then
- -- An apostrophe
- strings[i-1] = strings[i-1] .. util.unicode["apostrophe"] .. strings[i+1]
- table.remove(strings, i+1)
- table.remove(strings, i)
- end
- end
- end
- end
-
- return strings
-end
-
-function richtext.new(text, formats)
- local res = {
- contents = {},
- formats = formats or {},
- }
-
- setmetatable(res, RichText_mt)
-
- if not text then
- return res
- end
-
- if type(text) == "string" then
-
- local strings = RichText._split_tags(text)
- local contents = {}
- for _, str in ipairs(strings) do
- table.insert(contents, str)
-
- local end_tag = nil
- if str == '"' then
- local last_text = contents[#contents - 1]
- if last_text and type(last_text) == "string" and string.match(last_text, "%s$") then
- end_tag = nil
- else
- end_tag = str
- end
- elseif richtext.end_tags[str] then
- end_tag = str
- end
-
- if end_tag then
- for i = #contents - 1, 1, -1 do
- local start_tag = contents[i]
- if type(start_tag) == "string" and richtext.tag_pairs[start_tag] == end_tag then
- local subtext = richtext.new()
- -- subtext.contents = util.slice(contents, i + 1, #contents - 1)
- if start_tag == "'" and end_tag == "'" and i == #contents - 1 then
- contents[i] = util.unicode["apostrophe"]
- contents[#contents] = util.unicode["apostrophe"]
- break
- end
-
- for j = i + 1, #contents - 1 do
- local substr = contents[j]
- if substr == "'" then
- substr = util.unicode["apostrophe"]
- end
- local last_text = subtext.contents[#subtext.contents]
- if type(substr) == "string" and type(last_text) == "string" then
- subtext.contents[#subtext.contents] = last_text .. substr
- else
- table.insert(subtext.contents, substr)
- end
- end
-
- if start_tag == '<span class="nodecor">' then
- for attr, value in pairs(richtext.default_formats) do
- subtext.formats[attr] = value
- end
- subtext.formats["text-case"] = "nocase"
- else
- for attr, value in pairs(richtext.tag_formats[start_tag]) do
- subtext.formats[attr] = value
- end
- end
-
- for j = #contents, i, -1 do
- table.remove(contents, j)
- end
- table.insert(contents, subtext)
- break
- end
- end
- end
- end
-
- for i = #contents, 1, -1 do
- if contents[i] == "'" then
- contents[i] = util.unicode["apostrophe"]
- end
- if type(contents[i]) == "string" and type(contents[i+1]) == "string" then
- contents[i] = contents[i] .. contents[i+1]
- table.remove(contents, i+1)
- end
- end
-
- if #contents == 1 and type(contents[1]) == "table" then
- res = contents[1]
- else
- res.contents = contents
- end
-
- return res
-
- elseif type(text) == "table" and text._type == "RichText" then
- return text
-
- elseif type(text) == "table" then
- return text
- end
- return nil
-end
-
-richtext.tag_formats = {
- ["<i>"] = {["font-style"] = "italic"},
- ["<b>"] = {["font-weight"] = "bold"},
- ["<sup>"] = {["vertical-align"] = "sup"},
- ["<sub>"] = {["vertical-align"] = "sub"},
- ["<sc>"] = {["font-variant"] = "small-caps"},
- ['<span style="font-variant:small-caps;">'] = {["font-variant"] = "small-caps"},
- ['<span class="nocase">'] = {["text-case"] = "nocase"},
- ['"'] = {["quotes"] = "true"},
- [util.unicode['left double quotation mark']] = {["quotes"] = "true"},
- ["'"] = {["quotes"] = "true"},
- [util.unicode['left single quotation mark']] = {["quotes"] = "true"},
-}
-
-richtext.default_formats = {
- ["URL"] = "false",
- ["DOI"] = "false",
- ["PMID"] = "false",
- ["PMCID"] = "false",
- ["font-style"] = "normal",
- ["font-variant"] = "normal",
- ["font-weight"] = "normal",
- ["text-decoration"] = "none",
- ["vertical-align"] = "baseline",
- ["quotes"] = "false",
-}
-
-richtext.format_sequence = {
- "URL",
- "DOI",
- "PMID",
- "PMCID",
- "font-style",
- "font-variant",
- "font-weight",
- "text-decoration",
- "vertical-align",
- "quotes",
- "display",
-}
-
-richtext.flip_flop_formats = {
- ["font-style"] = true,
- ["font-weight"] = true,
- ["font-variant"] = true,
- ["quotes"] = true,
-}
-
-richtext.flip_flop_values = {
- ["font-style"] = {
- italic = "normal",
- normal = "italic",
- },
- ["font-weight"] = {
- bold = "normal",
- normal = "bold",
- },
- ["font-variant"] = {
- ["small-caps"] = "normal",
- normal = "small-caps",
- },
- ["quotes"] = {
- ["true"] = "inner",
- inner = "true",
- },
-}
-
--- https://github.com/Juris-M/citeproc-js/blob/aa2683f48fe23be459f4ed3be3960e2bb56203f0/src/queue.js#L724
--- Also merge duplicate punctuations.
-richtext.punctuation_map = {
- ["!"] = {
- ["."] = "!",
- ["?"] = "!?",
- [":"] = "!",
- [","] = "!,",
- [";"] = "!;",
- },
- ["?"] = {
- ["!"] = "?!",
- ["."] = "?",
- [":"] = "?",
- [","] = "?,",
- [";"] = "?;",
- },
- ["."] = {
- ["!"] = ".!",
- ["?"] = ".?",
- [":"] = ".:",
- [","] = ".,",
- [";"] = ".;",
- },
- [":"] = {
- ["!"] = "!",
- ["?"] = "?",
- ["."] = ":",
- [","] = ":,",
- [";"] = ":;",
- },
- [","] = {
- ["!"] = ",!",
- ["?"] = ",?",
- [":"] = ",:",
- ["."] = ",.",
- [";"] = ",;",
- },
- [";"] = {
- ["!"] = "!",
- ["?"] = "?",
- [":"] = ";",
- [","] = ";,",
- ["."] = ";",
- }
-}
-
-richtext.in_quote_punctuations = {
- [","] = true,
- ["."] = true,
- ["?"] = true,
- ["!"] = true,
-}
-
-richtext.tag_pairs = {
- ["<i>"] = "</i>",
- ["<b>"] = "</b>",
- ["<sup>"] = "</sup>",
- ["<sub>"] = "</sub>",
- ["<sc>"] = "</sc>",
- ['<span style="font-variant:small-caps;">'] = "</span>",
- ['<span class="nocase">'] = "</span>",
- ['<span class="nodecor">'] = "</span>",
- ['"'] = '"',
- [util.unicode['left double quotation mark']] = util.unicode['right double quotation mark'],
- ["'"] = "'",
- [util.unicode['left single quotation mark']] = util.unicode['right single quotation mark'],
-}
-
-richtext.tags = {}
-
-richtext.end_tags = {}
-
-for start_tag, end_tag in pairs(richtext.tag_pairs) do
- richtext.tags[start_tag] = true
- richtext.tags[end_tag] = true
- richtext.end_tags[end_tag] = true
-end
-
-return richtext
diff --git a/biblio/citation-style-language/citeproc-util.lua b/biblio/citation-style-language/citeproc-util.lua
index c9adb6558f..38de3b5751 100644
--- a/biblio/citation-style-language/citeproc-util.lua
+++ b/biblio/citation-style-language/citeproc-util.lua
@@ -6,11 +6,55 @@
-- load `slnunicode` from LuaTeX
local unicode = require("unicode")
-local inspect = require("inspect")
+local inspect -- only load it when debugging
local util = {}
+function util.clone(obj)
+ if type(obj) == "table" then
+ local res = {}
+ for key, value in pairs(obj) do
+ res[key] = value
+ end
+ return setmetatable(res, getmetatable(obj))
+ else
+ return obj
+ end
+end
+
+function util.join(list, delimiter)
+ local res = {}
+ for i, item in ipairs(list) do
+ if i > 1 then
+ table.insert(res, delimiter)
+ end
+ table.insert(res, item)
+ end
+ return res
+end
+
+function util.to_boolean(str)
+ if not str then
+ return false
+ end
+ if str == "true" then
+ return true
+ elseif str == "false" then
+ return false
+ else
+ util.warning(string.format('Invalid boolean string "%s"', str))
+ return false
+ end
+end
+
+function util.to_list(str)
+ if not str then
+ return nil
+ end
+ return util.split(str)
+end
+
function util.to_ordinal (n)
assert(type(n) == "number")
local last_digit = n % 10
@@ -44,21 +88,60 @@ function util.warning(message)
end
end
-local function remove_all_metatables(item, path)
- if path[#path] ~= inspect.METATABLE then return item end
-end
+local remove_all_metatables = nil
-function util.debug(...)
- -- io.stderr:write(inspect(..., {process = remove_all_metatables}))
- io.stderr:write(inspect(...))
+function util.debug(obj)
+ if not inspect then
+ inspect = require("inspect")
+ remove_all_metatables = function (item, path)
+ if path[#path] ~= inspect.METATABLE then
+ return item
+ end
+ end
+ end
+ io.stderr:write("[")
+ io.stderr:write(debug.getinfo(2, "S").source:sub(2))
+ io.stderr:write(":")
+ io.stderr:write(debug.getinfo(2, "l").currentline)
+ io.stderr:write("] ")
+ io.stderr:write(inspect(obj, {process = remove_all_metatables}))
io.stderr:write("\n")
end
-- Similar to re.split() in Python
-function util.split(str, seps, maxsplit, include_sep)
+function util.split(str, sep, maxsplit)
if not str then
- error("Invalid string.")
+ util.error("Invalid string.")
+ end
+ sep = sep or "%s+"
+ if sep == "" then
+ util.error("Empty separator")
end
+ if string.find(str, sep) == nil then
+ return { str }
+ end
+
+ if maxsplit == nil or maxsplit < 0 then
+ maxsplit = -1 -- No limit
+ end
+ local result = {}
+ local pattern = "(.-)" .. sep .. "()"
+ local num_splits = 0
+ local lastPos = 1
+ for part, pos in string.gmatch(str, pattern) do
+ if num_splits == maxsplit then
+ break
+ end
+ num_splits = num_splits + 1
+ result[num_splits] = part
+ lastPos = pos
+ end
+ -- Handle the last field
+ result[num_splits + 1] = string.sub(str, lastPos)
+ return result
+end
+
+function util.split_multiple(str, seps, include_sep)
seps = seps or "%s+"
if seps == "" then
error("Empty separator")
@@ -97,6 +180,15 @@ function util.split(str, seps, maxsplit, include_sep)
return res
end
+-- TODO: [Unicode word boundaries](https://www.unicode.org/reports/tr29/#Word_Boundaries)
+-- Returns: {
+-- {word, boundary},
+-- {word, boundary},
+-- }
+function util.segment_words(str)
+ return util.split_multiple(str, util.word_boundaries, true)
+end
+
function util.slice (t, start, stop)
start = start or 1
stop = stop or #t
@@ -132,6 +224,31 @@ function util.concat (list, sep)
return res
end
+-- Python list.extend()
+function util.extend(first, second)
+ if not second then
+ print(debug.traceback())
+ end
+ local l = #first
+ for i, element in ipairs(second) do
+ first[l + i] = element
+ end
+ return first
+end
+
+-- Concat two lists in place
+function util.concat_list(first, second)
+ local res
+ for i, element in ipairs(first) do
+ res[i] = element
+ end
+ local i = #res
+ for j, element in ipairs(second) do
+ res[i + j] = element
+ end
+ return res
+end
+
function util.lstrip (str)
if not str then
return nil
@@ -153,22 +270,34 @@ function util.strip (str)
end
function util.startswith (str, prefix)
+ if not str then
+ return false
+ end
return string.sub(str, 1, #prefix) == prefix
end
function util.endswith (str, suffix)
+ if not str then
+ return false
+ end
return string.sub(str, -#suffix) == suffix
end
+function util.is_punct(str)
+ return string.match(str, "^%p$")
+end
+
function util.is_numeric (str)
if str == nil or str == "" then
return false
end
local res = true
for w in string.gmatch(str, "%w+") do
- if string.match(w, "^[a-zA-Z]*%d+[a-zA-Z]*$") == nil then
- res = false
- break
+ if not string.match(w, "^%a*%d+%a*$") and
+ not string.match(w, "^[MDCLXVI]+$") and
+ not string.match(w, "^[mdclxvi]+$") then
+ -- Roman number withou validation
+ return false
end
end
for w in string.gmatch(str, "%W+") do
@@ -180,19 +309,84 @@ function util.is_numeric (str)
return res
end
-function util.is_uncertain_date (variable)
- if variable == nil then
- return false
- end
- local value = variable["circa"]
- return value ~= nil and value ~= ""
-end
-
util.variable_types = {}
-- schema/schemas/styles/csl-variables.rnc
util.variables = {}
+-- -- Standard variables
+-- util.variables.standard = {
+-- "abstract",
+-- "annote",
+-- "archive",
+-- "archive_collection",
+-- "archive_location",
+-- "archive-place",
+-- "authority",
+-- "call-number",
+-- "citation-key",
+-- "citation-label",
+-- "collection-title",
+-- "container-title",
+-- "container-title-short",
+-- "dimensions",
+-- "division",
+-- "DOI",
+-- "event",
+-- "event-title",
+-- "event-place",
+-- "genre",
+-- "ISBN",
+-- "ISSN",
+-- "jurisdiction",
+-- "keyword",
+-- "language",
+-- "license",
+-- "medium",
+-- "note",
+-- "original-publisher",
+-- "original-publisher-place",
+-- "original-title",
+-- "part-title",
+-- "PMCID",
+-- "PMID",
+-- "publisher",
+-- "publisher-place",
+-- "references",
+-- "reviewed-genre",
+-- "reviewed-title",
+-- "scale",
+-- "source",
+-- "status",
+-- "title",
+-- "title-short",
+-- "URL",
+-- "volume-title",
+-- "year-suffix",
+-- }
+
+-- Number variables
+util.variables.number = {
+ "chapter-number",
+ "citation-number",
+ "collection-number",
+ "edition",
+ "first-reference-note-number",
+ "issue",
+ "locator",
+ "number",
+ "number-of-pages",
+ "number-of-volumes",
+ "page",
+ "page-first",
+ "part-number",
+ "printing-number",
+ "section",
+ "supplement-number",
+ "version",
+ "volume",
+}
+
-- Date variables
util.variables.date = {
"accessed",
@@ -234,28 +428,6 @@ util.variables.name = {
"translator",
}
--- Number variables
-util.variables.number = {
- "chapter-number",
- "citation-number",
- "collection-number",
- "edition",
- "first-reference-note-number",
- "issue",
- "locator",
- "number",
- "number-of-pages",
- "number-of-volumes",
- "page",
- "page-first",
- "part-number",
- "printing-number",
- "section",
- "supplement-number",
- "version",
- "volume",
-}
-
util.variable_types = {}
for type, variables in pairs(util.variables) do
@@ -327,10 +499,22 @@ util.unicode = {
["apostrophe"] = "\u{2019}",
["left double quotation mark"] = "\u{201C}",
["right double quotation mark"] = "\u{201D}",
+ ["left-pointing double angle quotation mark"] = "\u{00AB}",
+ ["right-pointing double angle quotation mark"] = "\u{00BB}",
["horizontal ellipsis"] = "\u{2026}",
["narrow no-break space"] = "\u{202F}",
}
+util.word_boundaries = {
+ ":",
+ " ",
+ "%-",
+ "/",
+ util.unicode["no-break space"],
+ util.unicode["en dash"],
+ util.unicode["em dash"],
+}
+
-- Text-case
@@ -342,9 +526,11 @@ function util.is_upper (str)
return unicode.utf8.upper(str) == str
end
-function util.capitalize (str)
- str = unicode.utf8.lower(str)
- local res = string.gsub(str, "%w", unicode.utf8.upper, 1)
+function util.capitalize(str)
+ -- if not str then
+ -- print(debug.traceback())
+ -- end
+ local res = string.gsub(str, utf8.charpattern, unicode.utf8.upper, 1)
return res
end
@@ -635,7 +821,7 @@ function util.convert_roman (number)
local output = {}
for _, tuple in ipairs(util.roman_numerals) do
local letter, value = table.unpack(tuple)
- table.insert(output, string.rep(letter, number // value))
+ table.insert(output, string.rep(letter, math.floor(number / value)))
number = number % value
end
return table.concat(output, "")
@@ -793,4 +979,35 @@ function util.read_file(path)
end
+function util.parse_iso_date(str)
+ local date
+ local date_parts = util.split(str, "/")
+ if #date_parts <= 2 then
+ date = {["date-parts"] = {}}
+ for _, date_part in ipairs(date_parts) do
+ table.insert(date["date-parts"], util.split(date_part, "%-"))
+ end
+ end
+ if not date then
+ date = {literal = str}
+ end
+ return date
+end
+
+
+function util.parse_extra_name(str)
+ local name
+ local name_parts = util.split(str, "%s*||%s*")
+ if #name_parts == 2 then
+ name = {
+ family = name_parts[1],
+ given = name_parts[2],
+ }
+ else
+ name = {literal = str}
+ end
+ return name
+end
+
+
return util
diff --git a/biblio/citation-style-language/citeproc.lua b/biblio/citation-style-language/citeproc.lua
index 828d951403..b266abbdc5 100644
--- a/biblio/citation-style-language/citeproc.lua
+++ b/biblio/citation-style-language/citeproc.lua
@@ -10,7 +10,7 @@ local engine = require("citeproc-engine")
local bib = require("citeproc-bib")
local util = require("citeproc-util")
-citeproc.__VERSION__ = "0.1.1"
+citeproc.__VERSION__ = "0.2.0"
citeproc.new = engine.CiteProc.new
citeproc.parse_bib = bib.parse
diff --git a/biblio/citation-style-language/csl-locales-en-GB.xml b/biblio/citation-style-language/csl-locales-en-GB.xml
index 11239a37d9..2e1d04ada2 100644
--- a/biblio/citation-style-language/csl-locales-en-GB.xml
+++ b/biblio/citation-style-language/csl-locales-en-GB.xml
@@ -11,7 +11,7 @@
<name>Rintze M. Zelle</name>
</translator>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
- <updated>2022-01-01T21:32:03-05:00</updated>
+ <updated>2022-03-12T05:55:43-05:00</updated>
</info>
<style-options punctuation-in-quote="false"/>
<date form="text">
@@ -309,39 +309,39 @@
</term>
<!-- SHORT LOCATOR FORMS -->
- <term name="appendix">
+ <term name="appendix" form="short">
<single>app.</single>
<multiple>apps.</multiple>
</term>
- <term name="article-locator">
+ <term name="article-locator" form="short">
<single>art.</single>
<multiple>arts.</multiple>
</term>
- <term name="elocation">
+ <term name="elocation" form="short">
<single>loc.</single>
<multiple>locs.</multiple>
</term>
- <term name="equation">
+ <term name="equation" form="short">
<single>eq.</single>
<multiple>eqs.</multiple>
</term>
- <term name="rule">
+ <term name="rule" form="short">
<single>r.</single>
<multiple>rr.</multiple>
</term>
- <term name="scene">
+ <term name="scene" form="short">
<single>sc.</single>
<multiple>scs.</multiple>
</term>
- <term name="table">
+ <term name="table" form="short">
<single>tbl.</single>
<multiple>tbls.</multiple>
</term>
- <term name="timestamp"> <!-- generally blank -->
+ <term name="timestamp" form="short"> <!-- generally blank -->
<single></single>
<multiple></multiple>
</term>
- <term name="title-locator">
+ <term name="title-locator" form="short">
<single>tit.</single>
<multiple>tits.</multiple>
</term>
diff --git a/biblio/citation-style-language/csl-locales-en-US.xml b/biblio/citation-style-language/csl-locales-en-US.xml
index 03ffc42f9f..7fa0207e6a 100644
--- a/biblio/citation-style-language/csl-locales-en-US.xml
+++ b/biblio/citation-style-language/csl-locales-en-US.xml
@@ -17,7 +17,7 @@
<name>Brenton M. Wiernik</name>
</translator>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
- <updated>2022-01-01T21:32:03-05:00</updated>
+ <updated>2022-03-12T05:55:43-05:00</updated>
</info>
<style-options punctuation-in-quote="true"/>
<date form="text">
@@ -315,39 +315,39 @@
</term>
<!-- SHORT LOCATOR FORMS -->
- <term name="appendix">
+ <term name="appendix" form="short">
<single>app.</single>
<multiple>apps.</multiple>
</term>
- <term name="article-locator">
+ <term name="article-locator" form="short">
<single>art.</single>
<multiple>arts.</multiple>
</term>
- <term name="elocation">
+ <term name="elocation" form="short">
<single>loc.</single>
<multiple>locs.</multiple>
</term>
- <term name="equation">
+ <term name="equation" form="short">
<single>eq.</single>
<multiple>eqs.</multiple>
</term>
- <term name="rule">
+ <term name="rule" form="short">
<single>r.</single>
<multiple>rr.</multiple>
</term>
- <term name="scene">
+ <term name="scene" form="short">
<single>sc.</single>
<multiple>scs.</multiple>
</term>
- <term name="table">
+ <term name="table" form="short">
<single>tbl.</single>
<multiple>tbls.</multiple>
</term>
- <term name="timestamp"> <!-- generally blank -->
+ <term name="timestamp" form="short"> <!-- generally blank -->
<single></single>
<multiple></multiple>
</term>
- <term name="title-locator">
+ <term name="title-locator" form="short">
<single>tit.</single>
<multiple>tits.</multiple>
</term>
diff --git a/biblio/citation-style-language/csl-locales-fr-FR.xml b/biblio/citation-style-language/csl-locales-fr-FR.xml
index e6a71687d4..c94055ef8a 100644
--- a/biblio/citation-style-language/csl-locales-fr-FR.xml
+++ b/biblio/citation-style-language/csl-locales-fr-FR.xml
@@ -4,8 +4,11 @@
<translator>
<name>Grégoire Colly</name>
</translator>
+ <translator>
+ <name>Collectif Zotero francophone</name>
+ </translator>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
- <updated>2022-01-01T21:32:03-05:00</updated>
+ <updated>2022-04-01T14:30:37+02:00</updated>
</info>
<style-options punctuation-in-quote="false" limit-day-ordinals-to-day-1="true"/>
<date form="text">
@@ -19,33 +22,33 @@
<date-part name="year"/>
</date>
<terms>
- <term name="advance-online-publication">advance online publication</term>
+ <term name="advance-online-publication">publication en ligne anticipée</term>
<term name="album">album</term>
- <term name="audio-recording">audio recording</term>
+ <term name="audio-recording">enregistrement audio</term>
<term name="film">film</term>
- <term name="henceforth">henceforth</term>
- <term name="loc-cit">loc. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
- <term name="no-place">no place</term>
- <term name="no-place" form="short">n.p.</term>
- <term name="no-publisher">no publisher</term> <!-- sine nomine -->
- <term name="no-publisher" form="short">n.p.</term>
- <term name="on">on</term>
- <term name="op-cit">op. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
- <term name="original-work-published">original work published</term>
+ <term name="henceforth">désormais</term>
+ <term name="loc-cit">loc.&#160;cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
+ <term name="no-place">sans lieu</term>
+ <term name="no-place" form="short">s.&#160;l.</term>
+ <term name="no-publisher">sans nom</term> <!-- sine nomine -->
+ <term name="no-publisher" form="short">s.&#160;n.</term>
+ <term name="on">sur</term>
+ <term name="op-cit">op.&#160;cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
+ <term name="original-work-published">édition originale</term>
<term name="personal-communication">communication personnelle</term>
<term name="podcast">podcast</term>
- <term name="podcast-episode">podcast episode</term>
- <term name="preprint">preprint</term>
- <term name="radio-broadcast">radio broadcast</term>
- <term name="radio-series">radio series</term>
- <term name="radio-series-episode">radio series episode</term>
- <term name="special-issue">special issue</term>
- <term name="special-section">special section</term>
- <term name="television-broadcast">television broadcast</term>
- <term name="television-series">television series</term>
- <term name="television-series-episode">television series episode</term>
- <term name="video">video</term>
- <term name="working-paper">working paper</term>
+ <term name="podcast-episode">épisode de podcast</term>
+ <term name="preprint">prépublication</term>
+ <term name="radio-broadcast">émission de radio</term>
+ <term name="radio-series">série radiophonique</term>
+ <term name="radio-series-episode">épisode de série radiophonique</term>
+ <term name="special-issue">numéro spécial</term>
+ <term name="special-section">section spéciale</term>
+ <term name="television-broadcast">émission de télévision</term>
+ <term name="television-series">série télévisée</term>
+ <term name="television-series-episode">épisode de série télévisée</term>
+ <term name="video">vidéo</term>
+ <term name="working-paper">document de travail</term>
<term name="accessed">consulté le</term>
<term name="and">et</term>
<term name="and others">et autres</term>
@@ -88,74 +91,74 @@
<term name="version">version</term>
<!-- LONG ITEM TYPE FORMS -->
- <term name="article">preprint</term>
- <term name="article-journal">journal article</term>
- <term name="article-magazine">magazine article</term>
- <term name="article-newspaper">newspaper article</term>
- <term name="bill">bill</term>
- <term name="book">book</term>
- <term name="broadcast">broadcast</term>
- <term name="chapter">book chapter</term>
- <term name="classic">classic</term>
+ <term name="article">article</term>
+ <term name="article-journal">article de revue</term>
+ <term name="article-magazine">article de magazine</term>
+ <term name="article-newspaper">article de presse</term>
+ <term name="bill">projet de loi</term>
+ <term name="book">livre</term>
+ <term name="broadcast">émission</term>
+ <term name="chapter">chapitre de livre</term>
+ <term name="classic">classique</term>
<term name="collection">collection</term>
- <term name="dataset">dataset</term>
+ <term name="dataset">jeu de données</term>
<term name="document">document</term>
- <term name="entry">entry</term>
- <term name="entry-dictionary">dictionary entry</term>
- <term name="entry-encyclopedia">encyclopedia entry</term>
- <term name="event">event</term>
+ <term name="entry">entrée</term>
+ <term name="entry-dictionary">entrée de dictionnaire</term>
+ <term name="entry-encyclopedia">entrée d'encyclopédie</term>
+ <term name="event">événement</term>
<!-- figure is in the list of locator terms -->
- <term name="graphic">graphic</term>
- <term name="hearing">hearing</term>
+ <term name="graphic">image</term>
+ <term name="hearing">audience</term>
<term name="interview">interview</term>
- <term name="legal_case">legal case</term>
- <term name="legislation">legislation</term>
- <term name="manuscript">manuscript</term>
- <term name="map">map</term>
- <term name="motion_picture">video recording</term>
- <term name="musical_score">musical score</term>
+ <term name="legal_case">affaire</term>
+ <term name="legislation">acte juridique</term>
+ <term name="manuscript">manuscrit</term>
+ <term name="map">carte</term>
+ <term name="motion_picture">enregistrement vidéo</term>
+ <term name="musical_score">partition</term>
<term name="pamphlet">pamphlet</term>
- <term name="paper-conference">conference paper</term>
- <term name="patent">patent</term>
- <term name="performance">performance</term>
- <term name="periodical">periodical</term>
+ <term name="paper-conference">article de colloque</term>
+ <term name="patent">brevet</term>
+ <term name="performance">interprétation</term>
+ <term name="periodical">périodique</term>
<term name="personal_communication">communication personnelle</term>
- <term name="post">post</term>
- <term name="post-weblog">blog post</term>
- <term name="regulation">regulation</term>
- <term name="report">report</term>
- <term name="review">review</term>
- <term name="review-book">book review</term>
- <term name="software">software</term>
- <term name="song">audio recording</term>
- <term name="speech">presentation</term>
- <term name="standard">standard</term>
- <term name="thesis">thesis</term>
- <term name="treaty">treaty</term>
- <term name="webpage">webpage</term>
+ <term name="post">billet</term>
+ <term name="post-weblog">billet de blog</term>
+ <term name="regulation">règlement</term>
+ <term name="report">rapport</term>
+ <term name="review">recension</term>
+ <term name="review-book">recension de livre</term>
+ <term name="software">logiciel</term>
+ <term name="song">chanson</term>
+ <term name="speech">présentation</term>
+ <term name="standard">norme</term>
+ <term name="thesis">thèse</term>
+ <term name="treaty">traité</term>
+ <term name="webpage">page web</term>
<!-- SHORT ITEM TYPE FORMS -->
- <term name="article-journal" form="short">journal art.</term>
- <term name="article-magazine" form="short">mag. art.</term>
- <term name="article-newspaper" form="short">newspaper art.</term>
- <term name="book" form="short">bk.</term>
- <term name="chapter" form="short">bk. chap.</term>
+ <term name="article-journal" form="short">art. de revue</term>
+ <term name="article-magazine" form="short">art. de mag.</term>
+ <term name="article-newspaper" form="short">art. de presse</term>
+ <term name="book" form="short">liv.</term>
+ <term name="chapter" form="short">chap. de liv.</term>
<term name="document" form="short">doc.</term>
<!-- figure is in the list of locator terms -->
<term name="graphic" form="short">graph.</term>
<term name="interview" form="short">interv.</term>
- <term name="manuscript" form="short">MS</term>
- <term name="motion_picture" form="short">video rec.</term>
- <term name="report" form="short">rep.</term>
- <term name="review" form="short">rev.</term>
- <term name="review-book" form="short">bk. rev.</term>
- <term name="song" form="short">audio rec.</term>
+ <term name="manuscript" form="short">ms</term>
+ <term name="motion_picture" form="short">enr. vidéo</term>
+ <term name="report" form="short">rap.</term>
+ <term name="review" form="short">recens.</term>
+ <term name="review-book" form="short">recens. de liv.</term>
+ <term name="song" form="short">enr. audio</term>
<!-- HISTORICAL ERA TERMS -->
<term name="ad">apr. J.-C.</term>
<term name="bc">av. J.-C.</term>
- <term name="bce">BCE</term>
- <term name="ce">CE</term>
+ <term name="bce">av. n. è.</term>
+ <term name="ce">n. è.</term>
<!-- PUNCTUATION -->
<term name="open-quote">«&#160;</term>
@@ -163,15 +166,15 @@
<term name="open-inner-quote">“</term>
<term name="close-inner-quote">”</term>
<term name="page-range-delimiter">&#8209;</term> <!-- non-breaking hyphen -->
- <term name="colon">:</term>
+ <term name="colon">&#160;:</term>
<term name="comma">,</term>
- <term name="semicolon">;</term>
+ <term name="semicolon">&#160;;</term>
<!-- ORDINALS -->
<term name="ordinal">ᵉ</term>
<term name="ordinal-01" gender-form="feminine" match="whole-number">ʳᵉ</term>
<term name="ordinal-01" gender-form="masculine" match="whole-number">ᵉʳ</term>
-
+
<!-- LONG ORDINALS -->
<term name="long-ordinal-01">premier</term>
<term name="long-ordinal-02">deuxième</term>
@@ -185,49 +188,49 @@
<term name="long-ordinal-10">dixième</term>
<!-- LONG LOCATOR FORMS -->
- <term name="act">
- <single>act</single>
- <multiple>acts</multiple>
+ <term name="act">
+ <single>acte</single>
+ <multiple>actes</multiple>
</term>
- <term name="appendix">
- <single>appendix</single>
- <multiple>appendices</multiple>
+ <term name="appendix">
+ <single>appendice</single>
+ <multiple>appendices</multiple>
</term>
- <term name="article-locator">
+ <term name="article-locator">
<single>article</single>
- <multiple>articles</multiple>
+ <multiple>articles</multiple>
</term>
- <term name="canon">
+ <term name="canon">
<single>canon</single>
- <multiple>canons</multiple>
+ <multiple>canons</multiple>
</term>
- <term name="elocation">
- <single>location</single>
- <multiple>locations</multiple>
+ <term name="elocation">
+ <single>emplacement</single>
+ <multiple>emplacements</multiple>
</term>
- <term name="equation">
- <single>equation</single>
- <multiple>equations</multiple>
+ <term name="equation">
+ <single>équation</single>
+ <multiple>équations</multiple>
</term>
- <term name="rule">
- <single>rule</single>
- <multiple>rules</multiple>
+ <term name="rule">
+ <single>règle</single>
+ <multiple>règles</multiple>
</term>
- <term name="scene">
- <single>scene</single>
- <multiple>scenes</multiple>
+ <term name="scene">
+ <single>scène</single>
+ <multiple>scènes</multiple>
</term>
- <term name="table">
- <single>table</single>
- <multiple>tables</multiple>
+ <term name="table">
+ <single>tableau</single>
+ <multiple>tableaux</multiple>
</term>
<term name="timestamp"> <!-- generally blank -->
<single></single>
- <multiple></multiple>
+ <multiple></multiple>
</term>
- <term name="title-locator">
- <single>title</single>
- <multiple>titles</multiple>
+ <term name="title-locator">
+ <single>titre</single>
+ <multiple>titres</multiple>
</term>
<term name="book">
<single>livre</single>
@@ -299,41 +302,41 @@
</term>
<!-- SHORT LOCATOR FORMS -->
- <term name="appendix">
- <single>app.</single>
- <multiple>apps.</multiple>
+ <term name="appendix">
+ <single>append.</single>
+ <multiple>append.</multiple>
</term>
- <term name="article-locator">
+ <term name="article-locator">
<single>art.</single>
- <multiple>arts.</multiple>
+ <multiple>art.</multiple>
</term>
- <term name="elocation">
- <single>loc.</single>
- <multiple>locs.</multiple>
+ <term name="elocation">
+ <single>emplact</single>
+ <multiple>emplact</multiple>
</term>
- <term name="equation">
+ <term name="equation">
<single>eq.</single>
- <multiple>eqs.</multiple>
+ <multiple>eq.</multiple>
</term>
- <term name="rule">
- <single>r.</single>
- <multiple>rr.</multiple>
+ <term name="rule">
+ <single>règle</single>
+ <multiple>règles</multiple>
</term>
- <term name="scene">
+ <term name="scene">
<single>sc.</single>
- <multiple>scs.</multiple>
+ <multiple>sc.</multiple>
</term>
- <term name="table">
- <single>tbl.</single>
- <multiple>tbls.</multiple>
+ <term name="table">
+ <single>tab.</single>
+ <multiple>tab.</multiple>
</term>
<term name="timestamp"> <!-- generally blank -->
<single></single>
- <multiple></multiple>
+ <multiple></multiple>
</term>
- <term name="title-locator">
+ <term name="title-locator">
<single>tit.</single>
- <multiple>tits.</multiple>
+ <multiple>tit.</multiple>
</term>
<term name="book" form="short">liv.</term>
<term name="chapter" form="short">chap.</term>
@@ -386,56 +389,56 @@
<!-- LONG ROLE FORMS -->
<term name="chair">
- <single>chair</single>
- <multiple>chairs</multiple>
+ <single>président</single>
+ <multiple>présidents</multiple>
</term>
<term name="compiler">
- <single>compiler</single>
- <multiple>compilers</multiple>
+ <single>compilateur</single>
+ <multiple>compilateurs</multiple>
</term>
<term name="contributor">
- <single>contributor</single>
- <multiple>contributors</multiple>
+ <single>contributeur</single>
+ <multiple>contributeurs</multiple>
</term>
<term name="curator">
- <single>curator</single>
- <multiple>curators</multiple>
+ <single>commissaire</single>
+ <multiple>commissaires</multiple>
</term>
<term name="executive-producer">
- <single>executive producer</single>
- <multiple>executive producers</multiple>
+ <single>producteur exécutif</single>
+ <multiple>producteurs exécutifs</multiple>
</term>
<term name="guest">
- <single>guest</single>
- <multiple>guests</multiple>
+ <single>invité</single>
+ <multiple>invités</multiple>
</term>
<term name="host">
- <single>host</single>
- <multiple>hosts</multiple>
+ <single>hôte</single>
+ <multiple>hôtes</multiple>
</term>
<term name="narrator">
- <single>narrator</single>
- <multiple>narrators</multiple>
+ <single>narrateur</single>
+ <multiple>narrateurs</multiple>
</term>
<term name="organizer">
- <single>organizer</single>
- <multiple>organizers</multiple>
+ <single>organisateur</single>
+ <multiple>organisateurs</multiple>
</term>
<term name="performer">
- <single>performer</single>
- <multiple>performers</multiple>
+ <single>interprète</single>
+ <multiple>interprètes</multiple>
</term>
<term name="producer">
- <single>producer</single>
- <multiple>producers</multiple>
+ <single>producteur</single>
+ <multiple>producteurs</multiple>
</term>
<term name="script-writer">
- <single>writer</single>
- <multiple>writers</multiple>
+ <single>scénariste</single>
+ <multiple>scénaristes</multiple>
</term>
<term name="series-creator">
- <single>series creator</single>
- <multiple>series creators</multiple>
+ <single>créateur de série</single>
+ <multiple>créateurs de série</multiple>
</term>
<term name="director">
<single>réalisateur</single>
@@ -464,44 +467,44 @@
<!-- SHORT ROLE FORMS -->
<term name="compiler" form="short">
- <single>comp.</single>
- <multiple>comps.</multiple>
+ <single>compil.</single>
+ <multiple>compil.</multiple>
</term>
<term name="contributor" form="short">
<single>contrib.</single>
- <multiple>contribs.</multiple>
+ <multiple>contrib.</multiple>
</term>
<term name="curator" form="short">
- <single>cur.</single>
- <multiple>curs.</multiple>
+ <single>commiss.</single>
+ <multiple>commiss.</multiple>
</term>
<term name="executive-producer" form="short">
- <single>exec. prod.</single>
- <multiple>exec. prods.</multiple>
+ <single>prod. exé.</single>
+ <multiple>prod. exé.</multiple>
</term>
<term name="narrator" form="short">
<single>narr.</single>
- <multiple>narrs.</multiple>
+ <multiple>narr.</multiple>
</term>
<term name="organizer" form="short">
<single>org.</single>
- <multiple>orgs.</multiple>
+ <multiple>org.</multiple>
</term>
<term name="performer" form="short">
- <single>perf.</single>
- <multiple>perfs.</multiple>
+ <single>interpr.</single>
+ <multiple>interpr.</multiple>
</term>
<term name="producer" form="short">
<single>prod.</single>
- <multiple>prods.</multiple>
+ <multiple>prod.</multiple>
</term>
<term name="script-writer" form="short">
- <single>writ.</single>
- <multiple>writs.</multiple>
+ <single>scénar.</single>
+ <multiple>scénar.</multiple>
</term>
<term name="series-creator" form="short">
- <single>cre.</single>
- <multiple>cres.</multiple>
+ <single>créat.</single>
+ <multiple>créat.</multiple>
</term>
<term name="director" form="short">
<single>réal.</single>
@@ -529,19 +532,19 @@
</term>
<!-- VERB ROLE FORMS -->
- <term name="chair" form="verb">chaired by</term>
- <term name="compiler" form="verb">compiled by</term>
- <term name="contributor" form="verb">with</term>
- <term name="curator" form="verb">curated by</term>
- <term name="executive-producer" form="verb">executive produced by</term>
- <term name="guest" form="verb">with guest</term>
- <term name="host" form="verb">hosted by</term>
- <term name="narrator" form="verb">narrated by</term>
- <term name="organizer" form="verb">organized by</term>
- <term name="performer" form="verb">performed by</term>
- <term name="producer" form="verb">produced by</term>
- <term name="script-writer" form="verb">written by</term>
- <term name="series-creator" form="verb">created by</term>
+ <term name="chair" form="verb">présidé par</term>
+ <term name="compiler" form="verb">compilé par</term>
+ <term name="contributor" form="verb">avec</term>
+ <term name="curator" form="verb">organisé par</term>
+ <term name="executive-producer" form="verb">production exécutive par</term>
+ <term name="guest" form="verb">avec pour invité</term>
+ <term name="host" form="verb">animé par</term>
+ <term name="narrator" form="verb">lu par</term>
+ <term name="organizer" form="verb">organisé par</term>
+ <term name="performer" form="verb">interprété par</term>
+ <term name="producer" form="verb">produit par</term>
+ <term name="script-writer" form="verb">scénario de</term>
+ <term name="series-creator" form="verb">créé par</term>
<term name="container-author" form="verb">par</term>
<term name="director" form="verb">réalisé par</term>
<term name="editor" form="verb">édité par</term>
@@ -554,18 +557,18 @@
<term name="editortranslator" form="verb">édité et traduit par</term>
<!-- SHORT VERB ROLE FORMS -->
- <term name="compiler" form="verb-short">comp. by</term>
- <term name="contributor" form="verb-short">w.</term>
- <term name="curator" form="verb-short">cur. by</term>
- <term name="executive-producer" form="verb-short">exec. prod. by</term>
- <term name="guest" form="verb-short">w. guest</term>
- <term name="host" form="verb-short">hosted by</term>
- <term name="narrator" form="verb-short">narr. by</term>
- <term name="organizer" form="verb-short">org. by</term>
- <term name="performer" form="verb-short">perf. by</term>
- <term name="producer" form="verb-short">prod. by</term>
- <term name="script-writer" form="verb-short">writ. by</term>
- <term name="series-creator" form="verb-short">cre. by</term>
+ <term name="compiler" form="verb-short">compil. par</term>
+ <term name="contributor" form="verb-short">ac</term>
+ <term name="curator" form="verb-short">org. par</term>
+ <term name="executive-producer" form="verb-short">prod. exé. par</term>
+ <term name="guest" form="verb-short">ac pr inv.</term>
+ <term name="host" form="verb-short">anim. par</term>
+ <term name="narrator" form="verb-short">lu par</term>
+ <term name="organizer" form="verb-short">org. par</term>
+ <term name="performer" form="verb-short">interpr. par</term>
+ <term name="producer" form="verb-short">prod. par</term>
+ <term name="script-writer" form="verb-short">scénar. de</term>
+ <term name="series-creator" form="verb-short">créé par</term>
<term name="director" form="verb-short">réal. par</term>
<term name="editor" form="verb-short">éd. par</term>
<term name="editorial-director" form="verb-short">ss la dir. de</term>
diff --git a/biblio/citation-style-language/csl.lua b/biblio/citation-style-language/csl.lua
deleted file mode 100644
index 90f5bea588..0000000000
--- a/biblio/citation-style-language/csl.lua
+++ /dev/null
@@ -1,143 +0,0 @@
---
--- Copyright (c) 2021-2022 Zeping Lee
--- Released under the MIT license.
--- Repository: https://github.com/zepinglee/citeproc-lua
---
-
-local csl = {}
-
-local citeproc = require("citeproc")
-local util = citeproc.util
-require("lualibs")
-local core = require("csl-core")
-
-
-csl.initialized = "false"
-csl.citations = {}
-csl.citations_pre = {}
-
-
-function csl.error(str)
- luatexbase.module_error("csl", str)
-end
-function csl.warning(str)
- luatexbase.module_warning("csl", str)
-end
-function csl.info(str)
- luatexbase.module_info("csl", str)
-end
-
-
-function csl.init(style_name, bib_files, lang)
- bib_files = util.split(util.strip(bib_files), "%s*,%s*")
-
- csl.engine = core.init(style_name, bib_files, lang)
-
- if csl.engine then
- csl.initialized = "true"
- else
- return
- end
-
- -- csl.init is called via \AtBeginDocument and it's executed after
- -- loading .aux file. The csl.ids are already registered.
- csl.citation_strings = core.process_citations(csl.engine, csl.citations)
- csl.style_class = csl.engine:get_style_class()
-
- for _, citation in ipairs(csl.citations) do
- local citation_id = citation.citationID
- local citation_str = csl.citation_strings[citation_id]
- local bibcite_command = string.format("\\bibcite{%s}{{%s}{%s}}", citation.citationID, csl.style_class, citation_str)
- tex.sprint(bibcite_command)
- end
-
-end
-
-
-function csl.register_citation_info(citation_info)
- local citation = core.make_citation(citation_info)
- table.insert(csl.citations, citation)
-end
-
-
-function csl.enable_linking()
- csl.engine:enable_linking()
-end
-
-
-function csl.cite(citation_info)
- if not csl.engine then
- csl.error("CSL engine is not initialized.")
- end
-
- local citation = core.make_citation(citation_info)
-
- local res = csl.engine:processCitationCluster(citation, csl.citations_pre, {})
-
- local citation_str
- for _, citation_res in ipairs(res[2]) do
- local citation_id = citation_res[3]
- -- csl.citation_strings[citation_id] = citation_res[2]
- if citation_id == citation.citationID then
- citation_str = citation_res[2]
- end
- end
- tex.sprint(citation_str)
-
- table.insert(csl.citations_pre, {citation.citationID, citation.properties.noteIndex})
-end
-
-
-function csl.nocite(ids_string)
- local cite_ids = util.split(ids_string, "%s*,%s*")
- if csl.engine then
- local ids = {}
- for _, cite_id in ipairs(cite_ids) do
- if cite_id == "*" then
- for item_id, _ in pairs(core.bib) do
- table.insert(ids, item_id)
- end
- else
- table.insert(ids, cite_id)
- end
- end
- csl.engine:updateUncitedItems(ids)
- else
- -- `\nocite` in preamble, where csl.engine is not initialized yet
- for _, cite_id in ipairs(cite_ids) do
- if cite_id == "*" then
- core.uncite_all_items = true
- else
- if not core.loaded_ids[cite_id] then
- table.insert(core.ids, cite_id)
- core.loaded_ids[cite_id] = true
- end
- end
- end
- end
-end
-
-
-function csl.bibliography()
- if not csl.engine then
- csl.error("CSL engine is not initialized.")
- return
- end
-
- -- if csl.include_all_items then
- -- for id, _ in pairs(csl.bib) do
- -- if not csl.loaded_ids[id] then
- -- table.insert(csl.ids, id)
- -- csl.loaded_ids[id] = true
- -- end
- -- end
- -- end
- -- csl.engine:updateItems(csl.ids)
-
- local result = core.make_bibliography(csl.engine)
-
- tex.print(util.split(result, "\n"))
-end
-
-
-return csl
diff --git a/biblio/citation-style-language/harvard-cite-them-right.csl b/biblio/citation-style-language/harvard-cite-them-right.csl
index 2800678205..360f0833c6 100644
--- a/biblio/citation-style-language/harvard-cite-them-right.csl
+++ b/biblio/citation-style-language/harvard-cite-them-right.csl
@@ -1,10 +1,10 @@
<?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="sort-only" default-locale="en-GB">
<info>
- <title>Cite Them Right 11th edition - Harvard</title>
+ <title>Cite Them Right 12th edition - Harvard</title>
<id>http://www.zotero.org/styles/harvard-cite-them-right</id>
<link href="http://www.zotero.org/styles/harvard-cite-them-right" rel="self"/>
- <link href="http://www.zotero.org/styles/harvard-cite-them-right-10th-edition" rel="template"/>
+ <link href="http://www.zotero.org/styles/harvard-cite-them-right-11th-edition" rel="template"/>
<link href="http://www.citethemrightonline.com/" rel="documentation"/>
<author>
<name>Patrick O'Brien</name>
@@ -12,7 +12,7 @@
<category citation-format="author-date"/>
<category field="generic-base"/>
<summary>Harvard according to Cite Them Right, 11th edition.</summary>
- <updated>2021-09-01T07:43:59+00:00</updated>
+ <updated>2022-06-28T22:44:10-04: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-GB">
@@ -34,7 +34,7 @@
<choose>
<if variable="container-author" match="none">
<names variable="editor translator" delimiter=", ">
- <name and="text" initialize-with="." name-as-sort-order="all"/>
+ <name and="text" initialize-with="."/>
<label form="short" prefix=" (" suffix=")"/>
</names>
</if>
@@ -98,7 +98,10 @@
<macro name="access">
<choose>
<if variable="DOI">
- <text variable="DOI" prefix="doi:"/>
+ <group delimiter=": ">
+ <text term="available at" text-case="capitalize-first"/>
+ <text variable="DOI" prefix="https://doi.org/"/>
+ </group>
</if>
<else-if variable="URL">
<text term="available at" suffix=": " text-case="capitalize-first"/>
diff --git a/biblio/citation-style-language/ieee.csl b/biblio/citation-style-language/ieee.csl
index a4c76e3d56..bff5b9197e 100644
--- a/biblio/citation-style-language/ieee.csl
+++ b/biblio/citation-style-language/ieee.csl
@@ -45,7 +45,7 @@
<category field="engineering"/>
<category field="generic-base"/>
<summary>IEEE style as per the 2021 guidelines, V 01.29.2021.</summary>
- <updated>2022-02-05T21:19:36-05:00</updated>
+ <updated>2021-05-07T00:52:46+10: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">
diff --git a/biblio/citation-style-language/modern-language-association.csl b/biblio/citation-style-language/modern-language-association.csl
index 11db55d19a..fcb9845c4c 100644
--- a/biblio/citation-style-language/modern-language-association.csl
+++ b/biblio/citation-style-language/modern-language-association.csl
@@ -12,7 +12,7 @@
<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>2022-01-23T06:46:03-05:00</updated>
+ <updated>2022-04-24T09:59:40-04: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">
@@ -205,7 +205,7 @@
<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">
+ <else-if type="article-journal" match="any">
<date variable="issued" form="text" date-parts="year-month"/>
</else-if>
<else-if type="speech" match="none">
diff --git a/biblio/citation-style-language/nature.csl b/biblio/citation-style-language/nature.csl
index 2646cfe922..08d9db6ae9 100644
--- a/biblio/citation-style-language/nature.csl
+++ b/biblio/citation-style-language/nature.csl
@@ -15,7 +15,7 @@
<category field="generic-base"/>
<issn>0028-0836</issn>
<eissn>1476-4687</eissn>
- <updated>2019-10-08T13:18:12+00:00</updated>
+ <updated>2022-07-02T09:18:26-04: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>
<macro name="title">
@@ -37,7 +37,7 @@
</macro>
<macro name="access">
<choose>
- <if variable="volume"/>
+ <if variable="volume" type="article" match="any"/>
<else-if variable="DOI">
<text variable="DOI" prefix="doi:"/>
</else-if>
@@ -55,6 +55,28 @@
</group>
</group>
</if>
+ <else-if type="article">
+ <group delimiter=" ">
+ <choose>
+ <if variable="genre" match="any">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ <else>
+ <text term="article" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ <text term="at"/>
+ <choose>
+ <if variable="DOI" match="any">
+ <text variable="DOI" prefix="https://doi.org/"/>
+ </if>
+ <else>
+ <text variable="URL"/>
+ </else>
+ </choose>
+ <date date-parts="year" form="text" variable="issued" prefix="(" suffix=")"/>
+ </group>
+ </else-if>
<else-if type="report webpage post post-weblog" match="any">
<group delimiter=" ">
<text variable="URL"/>
diff --git a/biblio/citation-style-language/vancouver.csl b/biblio/citation-style-language/vancouver.csl
index edbb69b411..71c9203228 100644
--- a/biblio/citation-style-language/vancouver.csl
+++ b/biblio/citation-style-language/vancouver.csl
@@ -1,5 +1,5 @@
<?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="sort-only" page-range-format="minimal">
+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only" initialize-with-hyphen="false" page-range-format="minimal">
<info>
<title>Vancouver</title>
<id>http://www.zotero.org/styles/vancouver</id>
diff --git a/graphics/pgf/contrib/fancyqr/README.md b/graphics/pgf/contrib/fancyqr/README.md
new file mode 100644
index 0000000000..ebb2173348
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/README.md
@@ -0,0 +1,36 @@
+# fancyqr
+
+[![made-with-latex](https://img.shields.io/badge/Made%20with-LaTeX-1f425f.svg)](https://www.latex-project.org/) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/GPL-3.0) [![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com) [![compile qr](https://github.com/EagleoutIce/fancyqr/actions/workflows/compile.yaml/badge.svg)](https://github.com/EagleoutIce/fancyqr/actions/workflows/compile.yaml)
+
+[<img src="https://github.com/EagleoutIce/fancyqr/blob/gh-pages/preview-1.png?raw=true" width="600"/>](qr-example.tex)
+
+Simple package to create fancy qr-codes with the help of the [`qrcode`](https://www.ctan.org/pkg/qrcode)-package.
+You may use `\fancyqr` just like the normal `\qrcode` (`\fancyqr[<qr-options>]{<url>}`). See the [documentation](https://media.githubusercontent.com/media/EagleoutIce/fancyqr/blob/gh-pages/build/fancyqr-doc.pdf).
+
+*fancyqr* is actively developed by *Florian Sihler* (contact me at: <florian.sihler@uni-ulm.de>) under the [GPLv3 License](LICENSE). I am very happy about every contribution (see [CONTRIBUTING.md](CONTRIBUTING.md)).
+
+If you do want to hide a center square (e.g, because you want to embed an image) you can use `\FancyQrDoNotPrintSquare{<x>}{<y>}` to hide a rectangle with radius x and y set from the center. If you choose this option, the default `\FancyQrRoundCut` that rounds cut corners can be changed with `\FancyQrHardCut`.
+At the moment, there are six other styles `flat`, `frame`, `blob`, `glitch`, `swift`, and `dots`, that you can load (locally) by using `\FancyQrLoad{<name>}`. The default style is named `default` and can be 'reset' by `\FancyQrLoad{default}` or `\FancyLoadDefault`.
+
+There are the following extra qr-options (you can set all of them with `\fancyqrset{<keys>}`):
+| Option | Type | Default | Explanation |
+| ----------------- | ------- | :------: | ---------------------------------------------------------- |
+| `image` | LaTeX | | Automatically center an image.[^1] |
+| `image padding` | number | | Additionally hide blocks (x & y) around the image. |
+| `image x padding` | number | `0` | Additionally hide blocks (x) around the image. |
+| `image y padding` | number | `0` | Additionally hide blocks (y) around the image. |
+| `gradient` | boolean | true | Toggle the color gradient |
+| `color` | color | | Disables the `gradient` and sets the qr color accordingly. |
+| `l color` | color | `purple` | Set the top left gradient color. |
+| `left color` | color | | Alias for `l color`. |
+| `r color` | color | `teal` | Set the bottom right gradient color. |
+| `right color` | color | | Alias for `r color`. |
+| `gradient angle` | angle | `135` | Change the gradient angle. |
+
+The defaults are set like this:
+
+```LateX
+\fancyqrset{image padding=0,gradient=true,gradient angle=135,r color=teal,l color=purple}
+```
+
+[^1]: The package will automatically calculate the required `\FancyQrDoNotPrintSquare` (you have to make sure the, the qr code still has enough information to be readable). Therefore, the image will not scale with the qr code.
diff --git a/graphics/pgf/contrib/fancyqr/fancyqr-doc.pdf b/graphics/pgf/contrib/fancyqr/fancyqr-doc.pdf
new file mode 100644
index 0000000000..c2a0ae9661
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/fancyqr-doc.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/fancyqr/fancyqr-doc.tex b/graphics/pgf/contrib/fancyqr/fancyqr-doc.tex
new file mode 100644
index 0000000000..40712060b9
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/fancyqr-doc.tex
@@ -0,0 +1,87 @@
+% Florian Sihler, 2022
+% Licensed under GNU General Public License version 3
+% https://opensource.org/licenses/gpl-3.0.html
+\documentclass[parskip=half,english,numbers=noenddot,footnotes=nomultiple,oneside]{scrartcl}
+
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\usepackage{babel}
+
+\usepackage{microtype}
+\usepackage[hidelinks]{hyperref}
+
+\usepackage{lmodern}
+\usepackage{array,booktabs}
+\usepackage{footnote}
+\usepackage{fontawesome}
+
+\usepackage{fancyqr}
+\usepackage{xcolor}
+\usepackage[tex]{listings}
+
+\lstdefinelanguage{ltx}{
+ language={[LaTeX]TeX},
+ moretexcs=[1]{fancyqr,qrcode,FancyQrDoNotPrintSquare,FancyQrRoundCut,FancyQrHardCut,FancyQrLoad,FancyLoadDefault,fancyqrset,faGithub}
+}
+\lstset{basicstyle=\ttfamily,breaklines,texcsstyle=*\color{purple}\bfseries,language=ltx}
+\lstMakeShortInline|
+\def\ltx#1{\lstinline/#1/}
+\interfootnotelinepenalty=10000
+
+
+\title{The \texttt{fancyqr} package}
+\author{%
+ \texorpdfstring{Florian Sihler\medskip\\*
+ \fancyqr{https://github.com/EagleoutIce/fancyqr}
+ }{Florian Sihler}}
+\date{Version v1.0 \textendash\ 2022/08/18}
+
+
+\begin{document}
+ \maketitle
+
+
+ \texttt{fancyqr} is a simple package to create fancy qr codes with the help of the \textit{\href{https://www.ctan.org/pkg/qrcode}{qrcode}}-package.
+ You can use the |\fancyqr|-macro just like the normal |\qrcode|.\footnote{\ltx{\\fancyqr[<qr-options>]\{<url>\}}}
+
+ If you do want to hide a center square (e.g, because you want to embed an image) you can use |\FancyQrDoNotPrintSquare{<x>}{<y>}| to hide a rectangle with radius x and y set from the center. If you choose this option, the default |\FancyQrRoundCut| that rounds cut corners can be changed with |\FancyQrHardCut|.
+ At the moment, there are six other styles for the qr-code |flat|, |frame|, |blob|, |glitch|, |swift|, and |dots|, that you can load (locally) by using |\FancyQrLoad{<name>}|. The default style is named |default| and can be 'reset' by |\FancyQrLoad{default}| or |\FancyLoadDefault|.
+
+ All of the extra qr-options (you can set all of them with |\fancyqrset{<keys>}|) are showcased in \autoref{tbl:extra-keys}.
+ The defaults are set like this:
+\begin{lstlisting}
+\fancyqrset{image padding=0,gradient=true,
+ gradient angle=135,r color=teal,l color=purple}
+\end{lstlisting}
+ Consider the following example (uses \href{https://www.ctan.org/pkg/fontawesome}{fontawesome} for the symbol, but you can use include images,~\ldots):
+\begin{lstlisting}
+\fancyqr[image=\huge\faGithub,image padding=1,color=black!90!gray]{https://github.com/EagleoutIce/fancyqr}
+\end{lstlisting}
+
+ \parbox[c]{.3\linewidth}{Which produces:}\hfill\parbox[c]{.4\linewidth}{\raggedleft\fancyqr[image=\Huge\faGithub,image padding=1,color=black!90!gray]{https://github.com/EagleoutIce/fancyqr}}\par
+
+ \begin{savenotes}
+ \begin{table}
+ \centering\begin{tabular}{>{\ttfamily}ll>{\ttfamily}cp{.5\linewidth}}
+ \toprule
+ \multicolumn{1}{l}{Option} & Type & \multicolumn{1}{c}{Default} & Explanation \\
+ \midrule
+ image & \LaTeX & & Automatically center an image.\footnote{The package will automatically calculate the required \ltx{\\FancyQrDoNotPrintSquare} (you have to make sure that the qr code still has enough information to be readable). Therefore, the image will not scale with the qr code.} \\
+ image padding & number & & Additionally hide blocks (x \& y) around the image. \\
+ image x padding & number & 0 & Additionally hide blocks (x) around the image. \\
+ image y padding & number & 0 & Additionally hide blocks (y) around the image. \\
+ gradient & boolean & true & Toggle the color gradient \\
+ color & color & & Disables the |gradient| and sets the color accordingly. \\
+ l color & color & purple & Set the top left gradient color. \\
+ left color & color & & Alias for |l color|. \\
+ r color & color & teal & Set the bottom right gradient color. \\
+ right color & color & & Alias for |r color|. \\
+ gradient angle & angle & 135 & Change the gradient angle. \\
+ \bottomrule
+ \end{tabular}
+ \caption{Overview of special qr-options.}
+ \label{tbl:extra-keys}
+ \end{table}
+ \end{savenotes}
+
+\end{document} \ No newline at end of file
diff --git a/graphics/pgf/contrib/fancyqr/fancyqr.sty b/graphics/pgf/contrib/fancyqr/fancyqr.sty
new file mode 100644
index 0000000000..e727b5e039
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/fancyqr.sty
@@ -0,0 +1,235 @@
+% Florian Sihler, 2022
+% Licensed under GNU General Public License version 3
+% https://opensource.org/licenses/gpl-3.0.html
+\def\filename{fancyqr}
+\ProvidesPackage{\filename}[2022/08/18 version v1.0 Fancy QR-Codes]
+\RequirePackage{tikz, qrcode}
+
+% element
+% x: {\the\j}; y: {\the\i} | \@max@x \@max@y
+\def\FancyQrColor#1{\if@fancyqr@gradient
+\pgfmathsetmacro\angle{Mod(\fancyqr@gradient@angle+225,360)}% rotate to align 0 to the right
+\pgfmathsetmacro\gradient{%
+ % we do rotate the x and y points before color drawing by
+ % Mod(\fancyqr@gradient@angle,360) with the shifted origin
+ % Old: #3/2 #4/2
+ ((\the\j-\@max@x/2)*cos(\angle) - (\the\i-\@max@y/2)*sin(\angle) + \@max@x/2)/\@max@x * 50% rel x [0,1]
+ + ((\the\j-\@max@x/2)*sin(\angle) + (\the\i-\@max@y/2)*cos(\angle) + \@max@y/2)/\@max@y * 50% rel y [0,1]
+ }\@declaredcolor{qr@fancy@gradient@br!\gradient!qr@fancy@gradient@tl}\else\@declaredcolor{qr@fancy@gradient@tl}\fi{#1}}
+
+% O 1 O
+% 2 X 3
+% O 4 O
+% uses \@up\@left\@right\@down
+\def\GetPattern{%
+\ifcsname qcc\@up\@left\@right\@down\endcsname
+ \csname qcc\@up\@left\@right\@down\endcsname
+\else\rule\qr@modulesize\z@\fi}
+
+\tikzset{qrrc/.style={rounded corners=.5\qr@modulesize},qrrd/.style={fill}}
+
+% is larger to be compensated by overlaps
+\def\qrm{\dimexpr\qr@modulesize+.15\p@\relax}
+\long\def\qr@newpattern#1#2#3#4#5{%
+\expandafter\def\csname qcc#1#2#3#4\endcsname{%
+ \parbox[b][\qr@modulesize]\qr@modulesize{\kern-.075\p@\smash{\clap{\tikz[x=\qrm,y=\qrm,inner sep=\z@,outer sep=\z@]{\path[qrrd]#5;}}}}%
+}}
+
+\def\FancyLoadDefault{%
+% .
+\qr@newpattern0000{[qrrc](0,0)rectangle(\qrm,\qrm)}%
+% | | - -
+\qr@newpattern1000{(0,\qrm)[qrrc]--(0,0)--(\qrm,0)[sharp corners]--(\qrm,\qrm)--cycle}%
+\qr@newpattern0001{(0,0)[qrrc]--(0,\qrm)--(\qrm,\qrm)[sharp corners]--(\qrm,0)--cycle}%
+\qr@newpattern0100{(0,0)[qrrc]--(\qrm,0)--(\qrm,\qrm)[sharp corners]--(0,\qrm)--cycle}%
+\qr@newpattern0010{(\qrm,0)[qrrc]--(0,0)--(0,\qrm)[sharp corners]--(\qrm,\qrm)--cycle}%
+% corners
+\qr@newpattern1100{(\qrm,\qrm)[qrrc]--(\qrm,0)[sharp corners]--(0,0)--(0,\qrm)--cycle}% top left
+\qr@newpattern1010{(0,\qrm)[qrrc]--(0,0)[sharp corners]--(\qrm,0)--(\qrm,\qrm)--cycle}% top right
+\qr@newpattern0101{(0,\qrm)[qrrc]--(\qrm,\qrm)[sharp corners]--(\qrm,0)--(0,0)--cycle}% bottom left
+\qr@newpattern0011{(0,0)[qrrc]--(0,\qrm)[sharp corners]--(\qrm,\qrm)--(\qrm,0)--cycle}% bottom right
+% straights | --
+\qr@newpattern1001{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern0110{(0,0)rectangle(\qrm,\qrm)}%
+% enclosed
+\qr@newpattern1111{(0,0)rectangle(\qrm,\qrm)}%
+% t's
+\qr@newpattern0111{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1011{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1101{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1110{(0,0)rectangle(\qrm,\qrm)}%
+}
+\FancyLoadDefault % allows to reset the style after other loads
+\def\@fancy@qr@default@name{default}
+
+\def\FancyQrLoad#1{\let\@tmp\newpattern\let\newpattern\qr@newpattern\@bsphack\def\@@tmp{#1}\ifx\@@tmp\@fancy@qr@default@name\FancyLoadDefault\else
+\expandafter\edef\csname pingu@lib@#1@atcode\endcsname{\the\catcode`\@}%
+\catcode`\@=11\relax
+\input{fancyqr-style-#1.code}
+\catcode`\@=\csname pingu@lib@#1@atcode\endcsname
+\fi\@esphack\let\newpattern\@tmp\let\@tmp\relax}
+
+
+% modify the getter so everything that is not defined is white:
+\def\fancy@qr@matrixentry#1#2#3{%
+ \ifcsname #1@#2@#3\endcsname
+ % #1 = matrix name
+ % #2 = row number
+ % #3 = column number
+ \csname #1@#2@#3\endcsname
+ \else\qr@white@format\fi
+}%
+
+\def\FancyQrDoNotPrintSquare#1#2{\def\fancy@qr@donotprint@center@x{#1}\def\fancy@qr@donotprint@center@y{#2}}
+\FancyQrDoNotPrintSquare00
+
+\newif\iffancy@qr@do@print@
+\def\qr@fancy@updateif#1#2{\fancy@qr@do@print@true
+\ifnum#1>\@do@y@min\relax \ifnum#1<\@do@y@max\relax \ifnum#2>\@do@x@min\relax \ifnum#2<\@do@x@max\relax \fancy@qr@do@print@false \fi\fi\fi\fi}
+
+\newif\iffancy@qr@roundcut@
+\fancy@qr@roundcut@true
+\let\FancyQrHardCut\fancy@qr@roundcut@false
+\let\FancyQrRoundCut\fancy@qr@roundcut@true
+
+% clear plus if not to be printed
+\def\qr@fancy@clear@surround#1#2#3{%
+ \qr@fancy@updateif{\the\numexpr#2-1}{#3}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@\the\numexpr#2-1 @#3\endcsname\@undefined \fi
+ \qr@fancy@updateif{\the\numexpr#2+1}{#3}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@\the\numexpr#2+1 @#3\endcsname\@undefined \fi
+ \qr@fancy@updateif{#2}{\the\numexpr#3-1}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@#2@\the\numexpr#3-1\endcsname\@undefined \fi
+ \qr@fancy@updateif{#2}{\the\numexpr#3+1}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@#2@\the\numexpr#3+1\endcsname\@undefined \fi
+}
+
+\newif\if@fancyqr@image@
+
+\def\fancy@qr@printmatrix#1{%
+ \def\qr@white{0}\def\qr@black{1}%
+ \let\qr@black@fixed\qr@black
+ \let\qr@white@fixed\qr@white
+ \let\qr@black@format\qr@black
+ \let\qr@white@format\qr@white
+ %Set module size
+ \qr@modulesize=\qr@desiredheight
+ \divide\qr@modulesize by \qr@size\relax
+ \qr@minipagewidth=\qr@modulesize
+ \if@fancyqr@image@% image is in \fancyqr@imgbox
+ \pgfmathsetmacro\@x{int(ceil((.5\wd\fancyqr@imgbox)/\qr@modulesize)+\fancyqr@img@padding@x)}%
+ \pgfmathsetmacro\@y{int(ceil((.5\ht\fancyqr@imgbox+.5\dp\fancyqr@imgbox)/\qr@modulesize)+\fancyqr@img@padding@y)}%
+ \FancyQrDoNotPrintSquare\@x\@y
+ \fi
+ \multiply\qr@minipagewidth by \qr@size\relax
+ \ifqr@tight \else \advance\qr@minipagewidth by 8\qr@modulesize \fi
+ \minipage\qr@minipagewidth
+ \baselineskip=\qr@modulesize
+ \ifqr@tight\else\rule\z@{4\qr@modulesize}\par\fi% %Blank space at top.
+ \edef\@max@x{\qr@numberofrowsinmatrix{#1}}%
+ \edef\@max@y{\qr@numberofcolsinmatrix{#1}}%
+ \edef\@do@x@min{\the\numexpr\@max@x/2-\fancy@qr@donotprint@center@x-1}%
+ \edef\@do@x@max{\the\numexpr\@max@x/2+\fancy@qr@donotprint@center@x+1}%
+ \edef\@do@y@min{\the\numexpr\@max@y/2-\fancy@qr@donotprint@center@y-1}%
+ \edef\@do@y@max{\the\numexpr\@max@y/2+\fancy@qr@donotprint@center@y+1}%
+ \qr@for \i=1 to \@max@y by 1{%
+ \ifqr@tight\else\rule{4\qr@modulesize}\z@\fi% %Blank space at left.
+ \qr@for \j=1 to \@max@x by 1{%
+ \qr@fancy@updateif\i\j
+ \iffancy@qr@do@print@
+ \edef\@mid{\qr@matrixentry{#1}{\the\i}{\the\j}}%
+ \ifnum\@mid=\qr@white
+ \rule\qr@modulesize\z@
+ \else% if not white, get its pattern
+ \iffancy@qr@roundcut@\qr@fancy@clear@surround{#1}{\the\i}{\the\j}\fi
+ \edef\@up{\qr@matrixentry{#1}{\the\numexpr\the\i-1}{\the\j}}%
+ \edef\@left{\qr@matrixentry{#1}{\the\i}{\the\numexpr\the\j-1}}%
+ \edef\@right{\qr@matrixentry{#1}{\the\i}{\the\numexpr\the\j+1}}%
+ \edef\@down{\qr@matrixentry{#1}{\the\numexpr\the\i+1}{\the\j}}%
+ \FancyQrColor{\GetPattern}%
+ \fi\else \rule\qr@modulesize\z@\fi
+ }\par}%
+ \ifqr@tight\else\rule\z@{4\qr@modulesize}\par\fi
+ \endminipage
+ \if@fancyqr@image@\nobreak
+ \llap{\parbox\qr@minipagewidth{\centering\usebox\fancyqr@imgbox}}\fi
+}%
+
+\def\fancy@qr@setup#1{%
+ \qr@creatematrix{#1}%
+ \expandafter\gdef\csname #1@numrows\endcsname{\qr@size}%
+ \expandafter\gdef\csname #1@numcols\endcsname{\qr@size}%
+ % we do not need to create blank because we store all
+ \qr@placefinderpatterns{#1}%
+ \qr@placetimingpatterns{#1}%
+ \qr@placealignmentpatterns{#1}%
+}
+
+\newcount\c@fancy@a \newcount\c@fancy@b
+% the normal data is... well...
+\def\fancy@qr@writedata#1#2{%
+ % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc.
+ % #2 = a string consisting of 0's and 1's to write into the matrix.
+ \expandafter\c@fancy@a\the\numexpr\qr@numberofrowsinmatrix{#1}\relax
+ \expandafter\c@fancy@b\the\numexpr\qr@numberofcolsinmatrix{#1}\relax
+ \edef\qr@datatowrite{#2\relax}%
+ \c@qr@i0\relax
+ \@whilenum\c@qr@i<\c@fancy@a\do{%
+ \c@qr@j0 \advance\c@qr@i\@ne
+ \@whilenum\c@qr@j<\c@fancy@b\do{%
+ \advance\c@qr@j\@ne
+ \expandafter\fancy@qr@writebit\qr@datatowrite:{#1}%
+ }%
+ }%
+}
+
+\def\fancy@qr@writebit#1#2:#3{%
+ % #3 = matrix name
+ % (qr@i,qr@j) = position to write in (LaTeX counters)
+ % #1 = bit to be written
+ % #2 = remaining bits plus '\relax' as an end-of-file marker
+ \edef\qr@datatowrite{#2}%
+ \ifnum#1=1
+ \qr@storetomatrix{#3}{\number\c@qr@i}{\number\c@qr@j}{\qr@black}%
+ \else
+ \qr@storetomatrix{#3}{\number\c@qr@i}{\number\c@qr@j}{\qr@white}%
+ \fi
+}%
+
+
+\def\fancy@qr@printsavedbinarymatrix#1{%
+ \def\qr@binarystring{#1\relax\relax}%
+ \fancy@qr@setup{@tmp}%
+ \fancy@qr@writedata{@tmp}{\qr@binarystring}%
+ \fancy@qr@printmatrix{@tmp}%
+}%
+
+\newsavebox\fancyqr@imgbox
+\define@key{fancyqr}{image x padding}{\def\fancyqr@img@padding@x{#1}}
+\define@key{fancyqr}{image y padding}{\def\fancyqr@img@padding@y{#1}}
+\define@key{fancyqr}{image padding}{\def\fancyqr@img@padding@x{#1}\def\fancyqr@img@padding@y{#1}}
+\define@key{fancyqr}{image}{\@fancyqr@image@true\savebox\fancyqr@imgbox{#1}}
+\define@key{fancyqr}{color}{\@fancyqr@gradientfalse\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{left color}{\colorlet{qr@fancy@gradient@br}{#1}}
+\define@key{fancyqr}{l color}{\colorlet{qr@fancy@gradient@br}{#1}}
+\define@key{fancyqr}{right color}{\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{r color}{\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{gradient angle}{\def\fancyqr@gradient@angle{#1}}
+\define@boolkey{fancyqr}[@fancyqr@]{gradient}[true]{}% if@fancyqr@gradient
+
+\def\fancyqrset#1{\setkeys{qr,fancyqr}{#1}}
+\fancyqrset{image padding=0,gradient=true,gradient angle=135,r color=teal,l color=purple}
+
+\def\@fancyqr@init{\let\qr@printsavedbinarymatrix\fancy@qr@printsavedbinarymatrix\let\qr@matrixentry\fancy@qr@matrixentry\let\qr@printmatrix\fancy@qr@printmatrix}
+\def\fancyqr{\@ifstar\s@fancyqr\ns@fancyqr}
+% we rebuild some parts of qrcode to allow this macro to extend the keys while keeping the wrapper
+\def\s@fancyqr{\qr@starinvokedtrue\@@fancyqr}
+\def\ns@fancyqr{\qr@starinvokedfalse\@@fancyqr}
+\newcommand\@@fancyqr[1][]{\begingroup\@fancyqr@init
+\ifqr@starinvoked\qr@hyperlinkfalse\fi
+\setkeys{qr,fancyqr}{#1}\bgroup
+\qr@verbatimcatcodes\qr@setescapedspecials\qrcode@in}
+\endinput
+
+% TODO: NEGATIVE PATTERNS IF MIDDLE IS 0
+% => make rounded negative corners \ No newline at end of file
diff --git a/graphics/pgf/contrib/fancyqr/qr-example.tex b/graphics/pgf/contrib/fancyqr/qr-example.tex
new file mode 100644
index 0000000000..d58e7f835d
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/qr-example.tex
@@ -0,0 +1,25 @@
+% Florian Sihler, 2022
+% Licensed under GNU General Public License version 3
+% https://opensource.org/licenses/gpl-3.0.html
+\documentclass{article}
+
+\usepackage{fontawesome}
+
+\usepackage{fancyqr}
+
+\usepackage[active,tightpage]{preview} % for presentation
+\setlength\PreviewBorder{15pt}
+
+\fancyqrset{height=3.25cm,level=H,padding}
+
+\begin{document}
+\preview
+% \FancyQrDoNotPrintSquare{8}{9}
+% \FancyQrHardCut
+\mbox{\FancyQrLoad{blobs}
+\fancyqr[image=\scalebox{2.9}{\faGithub\kern1pt},image padding=1,color=black!90!gray]{https://github.com/EagleoutIce/fancyqr}
+\FancyQrLoad{default}
+\fancyqr{https://github.com/EagleoutIce/fancyqr}
+\FancyQrLoad{dots}\fancyqr[image={\tikz\node[align=center,draw]{\huge Ha\\Huhu};},r color=gray,gradient angle=45]{https://github.com/EagleoutIce/fancyqr}}%
+\endpreview
+\end{document} \ No newline at end of file
diff --git a/macros/texinfo/latest/texinfo.tex b/macros/texinfo/latest/texinfo.tex
index 8fc17de28c..c7ebff708f 100644
--- a/macros/texinfo/latest/texinfo.tex
+++ b/macros/texinfo/latest/texinfo.tex
@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2022-04-09.08}
+\def\texinfoversion{2022-08-18.14}
%
% Copyright 1985, 1986, 1988, 1990-2022 Free Software Foundation, Inc.
%
@@ -2558,7 +2558,7 @@ end
\def\it{\fam=\itfam \setfontstyle{it}}
\def\sl{\fam=\slfam \setfontstyle{sl}}
\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
-\def\tt{\fam=\ttfam \setfontstyle{tt}}\def\ttstylename{tt}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
% Texinfo sort of supports the sans serif font style, which plain TeX does not.
% So we set up a \sf.
@@ -2691,6 +2691,14 @@ end
%
\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+% Check if internal flag is clear, i.e. has not been @set.
+\def\ifflagclear#1#2#3{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ #2\else#3\fi
+}
+
+
+
{
\catcode`\'=\active
\catcode`\`=\active
@@ -2707,14 +2715,14 @@ end
%
\def\codequoteright{%
\ifmonospace
- \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
- \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ \ifflagclear{txicodequoteundirected}{%
+ \ifflagclear{codequoteundirected}{%
'%
- \else \char'15 \fi
- \else \char'15 \fi
- \else
- '%
- \fi
+ }{\char'15 }%
+ }{\char'15 }%
+ \else
+ '%
+ \fi
}
%
% and a similar option for the left quote char vs. a grave accent.
@@ -2723,16 +2731,16 @@ end
%
\def\codequoteleft{%
\ifmonospace
- \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
- \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ \ifflagclear{txicodequotebacktick}{%
+ \ifflagclear{codequotebacktick}{%
% [Knuth] pp. 380,381,391
% \relax disables Spanish ligatures ?` and !` of \tt font.
\relax`%
- \else \char'22 \fi
- \else \char'22 \fi
- \else
- \relax`%
- \fi
+ }{\char'22 }%
+ }{\char'22 }%
+ \else
+ \relax`%
+ \fi
}
% Commands to set the quote options.
@@ -2779,15 +2787,16 @@ end
\def\dosmartslant#1#2{%
\ifusingtt
{{\ttsl #2}\let\next=\relax}%
- {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ {\def\next{{#1#2}\smartitaliccorrection}}%
\next
}
\def\smartslanted{\dosmartslant\sl}
\def\smartitalic{\dosmartslant\it}
-% Output an italic correction unless \next (presumed to be the following
-% character) is such as not to need one.
-\def\smartitaliccorrection{%
+% Output an italic correction unless the following character is such as
+% not to need one.
+\def\smartitaliccorrection{\futurelet\next\smartitaliccorrectionx}
+\def\smartitaliccorrectionx{%
\ifx\next,%
\else\ifx\next-%
\else\ifx\next.%
@@ -2798,18 +2807,18 @@ end
\aftersmartic
}
-% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
-\def\ttslanted#1{{\ttsl #1}}
-
-% @cite is like \smartslanted except unconditionally use \sl. We never want
-% ttsl for book titles, do we?
-\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+% @cite unconditionally uses \sl with \smartitaliccorrection.
+\def\cite#1{{\sl #1}\smartitaliccorrection}
+% @var unconditionally uses \sl. This gives consistency for
+% parameter names whether they are in @def, @table @code or a
+% regular paragraph.
+% The \null is to reset \spacefactor.
\def\aftersmartic{}
\def\var#1{%
\let\saveaftersmartic = \aftersmartic
\def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
- \smartslanted{#1}%
+ {\sl #1}\smartitaliccorrection
}
\let\i=\smartitalic
@@ -2817,8 +2826,14 @@ end
\let\dfn=\smartslanted
\let\emph=\smartitalic
-% Explicit font changes: @r, @sc, undocumented @ii.
-\def\r#1{{\rm #1}} % roman font
+% @r for roman font, used for code comment
+\def\r#1{{%
+ \usenormaldash % get --, --- ligatures even if in @code
+ \defcharsdefault % in case on def line
+ \rm #1}}
+{\catcode`-=\active \gdef\usenormaldash{\let-\normaldash}}
+
+% @sc, undocumented @ii.
\def\sc#1{{\smallcaps#1}} % smallcaps font
\def\ii#1{{\it #1}} % italic font
@@ -2856,7 +2871,7 @@ end
% @t, explicit typewriter.
\def\t#1{%
- {\tt \plainfrenchspacing #1}%
+ {\tt \defcharsdefault \plainfrenchspacing #1}%
\null
}
@@ -4432,7 +4447,7 @@ $$%
\message{conditionals,}
-% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotlatex, @ifnotplaintext,
% @ifnotxml always succeed. They currently do nothing; we don't
% attempt to check whether the conditionals are properly nested. But we
% have to remember that they are conditionals, so that @end doesn't
@@ -4446,6 +4461,7 @@ $$%
\makecond{ifnotdocbook}
\makecond{ifnothtml}
\makecond{ifnotinfo}
+\makecond{ifnotlatex}
\makecond{ifnotplaintext}
\makecond{ifnotxml}
@@ -4458,10 +4474,12 @@ $$%
\def\ifdocbook{\doignore{ifdocbook}}
\def\ifhtml{\doignore{ifhtml}}
\def\ifinfo{\doignore{ifinfo}}
+\def\iflatex{\doignore{iflatex}}
\def\ifnottex{\doignore{ifnottex}}
\def\ifplaintext{\doignore{ifplaintext}}
\def\ifxml{\doignore{ifxml}}
\def\ignore{\doignore{ignore}}
+\def\latex{\doignore{latex}}
\def\menu{\doignore{menu}}
\def\xml{\doignore{xml}}
@@ -4985,25 +5003,24 @@ $$%
\catcode`\-=13
\catcode`\`=13
\gdef\indexnonalnumdisappear{%
- \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else
+ \ifflagclear{txiindexlquoteignore}{}{%
% @set txiindexlquoteignore makes us ignore left quotes in the sort term.
% (Introduced for FSFS 2nd ed.)
\let`=\empty
- \fi
+ }%
%
- \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else
+ \ifflagclear{txiindexbackslashignore}{}{%
\backslashdisappear
- \fi
- %
- \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else
+ }%
+ \ifflagclear{txiindexhyphenignore}{}{%
\def-{}%
- \fi
- \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else
+ }%
+ \ifflagclear{txiindexlessthanignore}{}{%
\def<{}%
- \fi
- \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else
+ }%
+ \ifflagclear{txiindexatsignignore}{}{%
\def\@{}%
- \fi
+ }%
}
\gdef\indexnonalnumreappear{%
@@ -5295,9 +5312,7 @@ $$%
%
\atdummies
%
- \expandafter\ifx\csname SETtxiindexescapeisbackslash\endcsname\relax\else
- \escapeisbackslash
- \fi
+ \ifflagclear{txiindexescapeisbackslash}{}{\escapeisbackslash}%
%
% For texindex which always views { and } as separators.
\def\{{\lbracechar{}}%
@@ -5481,9 +5496,9 @@ $$%
% old index files using \ as the escape character. Reading this would
% at best lead to typesetting garbage, at worst a TeX syntax error.
\def\printindexzz#1#2\finish{%
- \expandafter\ifx\csname SETtxiindexescapeisbackslash\endcsname\relax
+ \ifflagclear{txiindexescapeisbackslash}{%
\uccode`\~=`\\ \uppercase{\if\noexpand~}\noexpand#1
- \expandafter\ifx\csname SETtxiskipindexfileswithbackslash\endcsname\relax
+ \ifflagclear{txiskipindexfileswithbackslash}{%
\errmessage{%
ERROR: A sorted index file in an obsolete format was skipped.
To fix this problem, please upgrade your version of 'texi2dvi'
@@ -5499,15 +5514,15 @@ this, Texinfo will try to use index files in the old format.
If you continue to have problems, deleting the index files and starting again
might help (with 'rm \jobname.?? \jobname.??s')%
}%
- \else
+ }{%
(Skipped sorted index file in obsolete format)
- \fi
+ }%
\else
\begindoublecolumns
\input \jobname.\indexname s
\enddoublecolumns
\fi
- \else
+ }{%
\begindoublecolumns
\catcode`\\=0\relax
%
@@ -5517,7 +5532,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\catcode`\@=0\relax
\input \jobname.\indexname s
\enddoublecolumns
- \fi
+ }%
}
% These macros are used by the sorted index file itself.
@@ -7277,22 +7292,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
}
\let\Eraggedright\par
-\envdef\raggedleft{%
- \parindent=0pt \leftskip0pt plus2em
- \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
- \hbadness=10000 % Last line will usually be underfull, so turn off
- % badness reporting.
-}
-\let\Eraggedleft\par
-
-\envdef\raggedcenter{%
- \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
- \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
- \hbadness=10000 % Last line will usually be underfull, so turn off
- % badness reporting.
-}
-\let\Eraggedcenter\par
-
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins. We keep \parskip nonzero in general, since
@@ -7515,9 +7514,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% file; b) letting users define the frontmatter in as flexible order as
% possible is desirable.
%
-\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
-\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
-%
+\def\copying{\checkenv{}\begingroup\macrobodyctxt\docopying}
+{\catcode`\ =\other
+\gdef\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+}
+
\def\insertcopying{%
\begingroup
\parindent = 0pt % paragraph indentation looks wrong on title page
@@ -7599,21 +7600,15 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\Edefun{\endgraf\medbreak}
-% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
-% the only thing remaining is to define \deffnheader.
+% \makedefun{deffoo}{ (definition of \deffooheader) }
%
+% Define \deffoo, \deffoox \Edeffoo and \deffooheader.
\def\makedefun#1{%
\expandafter\let\csname E#1\endcsname = \Edefun
\edef\temp{\noexpand\domakedefun
\makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
\temp
}
-
-% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) }
-%
-% Define \deffn and \deffnx, without parameters.
-% \deffnheader has to be defined explicitly.
-%
\def\domakedefun#1#2#3{%
\envdef#1{%
\startdefun
@@ -7646,74 +7641,51 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi\fi
}
-% \dosubind {index}{topic}{subtopic}
-%
-% If SUBTOPIC is present, precede it with a space, and call \doind.
-% (At some time during the 20th century, this made a two-level entry in an
-% index such as the operation index. Nobody seemed to notice the change in
-% behaviour though.)
-\def\dosubind#1#2#3{%
- \def\thirdarg{#3}%
- \ifx\thirdarg\empty
- \doind{#1}{#2}%
- \else
- \doind{#1}{#2\space#3}%
- \fi
-}
-
% Untyped functions:
% @deffn category name args
-\makedefun{deffn}{\deffngeneral{}}
-
-% @deffn category class name args
-\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
-
-% \defopon {category on}class name args
-\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+\makedefun{deffn}#1 #2 #3\endheader{%
+ \doind{fn}{\code{#2}}%
+ \defname{#1}{}{#2}\magicamp\defunargs{#3\unskip}%
+}
-% \deffngeneral {subind}category name args
-%
-\def\deffngeneral#1#2 #3 #4\endheader{%
- \dosubind{fn}{\code{#3}}{#1}%
- \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+% @defop category class name args
+\makedefun{defop}#1 {\defopheaderx{#1\ \putwordon}}
+\def\defopheaderx#1#2 #3 #4\endheader{%
+ \doind{fn}{\code{#3}\space\putwordon\ \code{#2}}%
+ \defname{#1\ \code{#2}}{}{#3}\magicamp\defunargs{#4\unskip}%
}
% Typed functions:
% @deftypefn category type name args
-\makedefun{deftypefn}{\deftypefngeneral{}}
+\makedefun{deftypefn}#1 #2 #3 #4\endheader{%
+ \doind{fn}{\code{#3}}%
+ \doingtypefntrue
+ \defname{#1}{#2}{#3}\defunargs{#4\unskip}%
+}
% @deftypeop category class type name args
-\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
-
-% \deftypeopon {category on}class type name args
-\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
-
-% \deftypefngeneral {subind}category type name args
-%
-\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
- \dosubind{fn}{\code{#4}}{#1}%
+\makedefun{deftypeop}#1 {\deftypeopheaderx{#1\ \putwordon}}
+\def\deftypeopheaderx#1#2 #3 #4 #5\endheader{%
+ \doind{fn}{\code{#4}\space\putwordon\ \code{#1\ \code{#2}}}%
\doingtypefntrue
- \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+ \defname{#1\ \code{#2}}{#3}{#4}\defunargs{#5\unskip}%
}
% Typed variables:
% @deftypevr category type var args
-\makedefun{deftypevr}{\deftypecvgeneral{}}
+\makedefun{deftypevr}#1 #2 #3 #4\endheader{%
+ \doind{vr}{\code{#3}}%
+ \defname{#1}{#2}{#3}\defunargs{#4\unskip}%
+}
% @deftypecv category class type var args
-\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
-
-% \deftypecvof {category of}class type var args
-\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
-
-% \deftypecvgeneral {subind}category type var args
-%
-\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
- \dosubind{vr}{\code{#4}}{#1}%
- \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+\makedefun{deftypecv}#1 {\deftypecvheaderx{#1\ \putwordof}}
+\def\deftypecvheaderx#1#2 #3 #4 #5\endheader{%
+ \doind{vr}{\code{#4}\space\putwordof\ \code{#2}}%
+ \defname{#1\ \code{#2}}{#3}{#4}\defunargs{#5\unskip}%
}
% Untyped variables:
@@ -7722,10 +7694,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
% @defcv category class var args
-\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
-
-% \defcvof {category of}class var args
-\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+\makedefun{defcv}#1 {\defcvheaderx{#1\ \putwordof}}
+\def\defcvheaderx#1#2 {\deftypecvheaderx{#1}#2 {} }
% Types:
@@ -7743,10 +7713,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\makedefun{defvar}{\defvrheader{\putwordDefvar} }
\makedefun{defopt}{\defvrheader{\putwordDefopt} }
\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
-\makedefun{defmethod}{\defopon\putwordMethodon}
-\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
-\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
-\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+\makedefun{defmethod}{\defopheaderx\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopheaderx\putwordMethodon}
+\makedefun{defivar}{\defcvheaderx\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvheaderx\putwordInstanceVariableof}
% \defname, which formats the name of the @def (not the args).
% #1 is the category, such as "Function".
@@ -7765,9 +7735,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\rettypeownlinefalse
\ifdoingtypefn % doing a typed function specifically?
% then check user option for putting return type on its own line:
- \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
- \rettypeownlinetrue
- \fi
+ \ifflagclear{txideftypefnnl}{}{\rettypeownlinetrue}%
\fi
%
% How we'll format the category name. Putting it in brackets helps
@@ -7832,30 +7800,18 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi % no return type
#3% output function name
}%
- {\rm\enskip}% hskip 0.5 em of \rmfont
+ \ifflagclear{txidefnamenospace}{%
+ {\rm\enskip}% hskip 0.5 em of \rmfont
+ }{}%
%
\boldbrax
% arguments will be output next, if any.
}
-% Print arguments in slanted roman (not ttsl), inconsistently with using
-% tt for the name. This is because literal text is sometimes needed in
-% the argument list (groff manual), and ttsl and tt are not very
-% distinguishable. Prevent hyphenation at `-' chars.
-%
+% Print arguments. Use slanted for @def*, typewriter for @deftype*.
\def\defunargs#1{%
- % use sl by default (not ttsl),
- % tt for the names.
- \df \sl \hyphenchar\font=0
- %
- % On the other hand, if an argument has two dashes (for instance), we
- % want a way to get ttsl. We used to recommend @var for that, so
- % leave the code in, but it's strange for @var to lead to typewriter.
- % Nowadays we recommend @code, since the difference between a ttsl hyphen
- % and a tt hyphen is pretty tiny. @code also disables ?` !`.
- \def\var##1{{\setregularquotes\ttslanted{##1}}}%
+ \df \ifdoingtypefn \tt \else \sl \fi
#1%
- \sl\hyphenchar\font=45
}
% We want ()&[] to print specially on the defun line.
@@ -7874,9 +7830,12 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% so TeX would otherwise complain about undefined control sequence.
{
\activeparens
- \global\let(=\lparen \global\let)=\rparen
- \global\let[=\lbrack \global\let]=\rbrack
- \global\let& = \&
+ \gdef\defcharsdefault{%
+ \let(=\lparen \let)=\rparen
+ \let[=\lbrack \let]=\rbrack
+ \let& = \&%
+ }
+ \globaldefs=1 \defcharsdefault
\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
\gdef\magicamp{\let&=\amprm}
@@ -8060,24 +8019,17 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\catcode`\_=\other
\catcode`\|=\other
\catcode`\~=\other
- \passthroughcharstrue
-}
-
-\def\scanargctxt{% used for copying and captions, not macros.
- \scanctxt
\catcode`\@=\other
- \catcode`\\=\other
\catcode`\^^M=\other
+ \catcode`\\=\active
+ \passthroughcharstrue
}
-\def\macrobodyctxt{% used for @macro definitions
+\def\macrobodyctxt{% used for @macro definitions and @copying
\scanctxt
\catcode`\ =\other
- \catcode`\@=\other
\catcode`\{=\other
\catcode`\}=\other
- \catcode`\^^M=\other
- \usembodybackslash
}
% Used when scanning braced macro arguments. Note, however, that catcode
@@ -8086,14 +8038,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\macroargctxt{%
\scanctxt
\catcode`\ =\active
- \catcode`\@=\other
- \catcode`\^^M=\other
- \catcode`\\=\active
}
\def\macrolineargctxt{% used for whole-line arguments without braces
\scanctxt
- \catcode`\@=\other
\catcode`\{=\other
\catcode`\}=\other
}
@@ -8137,7 +8085,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
\addtomacrolist{\the\macname}%
\fi
- \begingroup \macrobodyctxt
+ \begingroup \macrobodyctxt \usembodybackslash
\ifrecursive \expandafter\parsermacbody
\else \expandafter\parsemacbody
\fi}
@@ -8941,7 +8889,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname
%
- \expandafter\ifx\csname SETtxiomitxrefpg\endcsname\relax
+ \ifflagclear{txiomitxrefpg}{%
% But we always want a comma and a space:
,\space
%
@@ -8956,7 +8904,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\tokenafterxref ,% @NL
\else\ifx\tie\tokenafterxref ,% @tie
\fi\fi\fi\fi\fi\fi
- \fi
+ }{}%
\fi\fi
\fi
\endlink
@@ -9604,7 +9552,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
%
\def\caption{\docaption\thiscaption}
\def\shortcaption{\docaption\thisshortcaption}
-\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\docaption{\checkenv\float \bgroup\scanctxt\defcaption}
\def\defcaption#1#2{\egroup \def#1{#2}}
% The parameter is the control sequence identifying the counter we are
@@ -10324,9 +10272,9 @@ directory should work if nowhere else does.}
% Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp
% to the corresponding UTF-8 sequence.
\gdef\parseXMLCharref{%
- \ifnum\countUTFz < "A0\relax
+ \ifnum\countUTFz < "20\relax
\errhelp = \EMsimple
- \errmessage{Cannot define Unicode char value < 00A0}%
+ \errmessage{Cannot define Unicode char value < 0020}%
\else\ifnum\countUTFz < "800\relax
\parseUTFviiiA,%
\parseUTFviiiB C\UTFviiiTwoOctetsName.,%
@@ -10396,6 +10344,103 @@ directory should work if nowhere else does.}
% least make most of the characters not bomb out.
%
\def\unicodechardefs{%
+ \DeclareUnicodeCharacter{0020}{ } % space
+ \DeclareUnicodeCharacter{0021}{\char"21}
+ \DeclareUnicodeCharacter{0022}{\char"22}
+ \DeclareUnicodeCharacter{0023}{\char"23}
+ \DeclareUnicodeCharacter{0024}{\char"24}
+ \DeclareUnicodeCharacter{0025}{\char"25}
+ \DeclareUnicodeCharacter{0026}{\char"26}
+ \DeclareUnicodeCharacter{0027}{\char"27}
+ \DeclareUnicodeCharacter{0028}{\char"28}
+ \DeclareUnicodeCharacter{0029}{\char"29}
+ \DeclareUnicodeCharacter{002A}{\char"2A}
+ \DeclareUnicodeCharacter{002B}{\char"2B}
+ \DeclareUnicodeCharacter{002C}{\char"2C}
+ \DeclareUnicodeCharacter{002D}{\char"2D}
+ \DeclareUnicodeCharacter{002E}{\char"2E}
+ \DeclareUnicodeCharacter{002F}{\char"2F}
+ \DeclareUnicodeCharacter{0030}{0}%
+ \DeclareUnicodeCharacter{0031}{1}%
+ \DeclareUnicodeCharacter{0032}{2}%
+ \DeclareUnicodeCharacter{0033}{3}%
+ \DeclareUnicodeCharacter{0034}{4}%
+ \DeclareUnicodeCharacter{0035}{5}%
+ \DeclareUnicodeCharacter{0036}{6}%
+ \DeclareUnicodeCharacter{0037}{7}%
+ \DeclareUnicodeCharacter{0038}{8}%
+ \DeclareUnicodeCharacter{0039}{9}%
+ \DeclareUnicodeCharacter{003A}{\char"3A}
+ \DeclareUnicodeCharacter{003B}{\char"3B}
+ \DeclareUnicodeCharacter{003C}{\char"3C}
+ \DeclareUnicodeCharacter{003D}{\char"3D}
+ \DeclareUnicodeCharacter{003E}{\char"3E}
+ \DeclareUnicodeCharacter{003F}{\char"3F}
+ \DeclareUnicodeCharacter{0040}{\char"40}
+ \DeclareUnicodeCharacter{0041}{A}%
+ \DeclareUnicodeCharacter{0042}{B}%
+ \DeclareUnicodeCharacter{0043}{C}%
+ \DeclareUnicodeCharacter{0044}{D}%
+ \DeclareUnicodeCharacter{0045}{E}%
+ \DeclareUnicodeCharacter{0046}{F}%
+ \DeclareUnicodeCharacter{0047}{G}%
+ \DeclareUnicodeCharacter{0048}{H}%
+ \DeclareUnicodeCharacter{0049}{I}%
+ \DeclareUnicodeCharacter{004A}{J}%
+ \DeclareUnicodeCharacter{004B}{K}%
+ \DeclareUnicodeCharacter{004C}{L}%
+ \DeclareUnicodeCharacter{004D}{M}%
+ \DeclareUnicodeCharacter{004E}{N}%
+ \DeclareUnicodeCharacter{004F}{O}%
+ \DeclareUnicodeCharacter{0050}{P}%
+ \DeclareUnicodeCharacter{0051}{Q}%
+ \DeclareUnicodeCharacter{0052}{R}%
+ \DeclareUnicodeCharacter{0053}{S}%
+ \DeclareUnicodeCharacter{0054}{T}%
+ \DeclareUnicodeCharacter{0055}{U}%
+ \DeclareUnicodeCharacter{0056}{V}%
+ \DeclareUnicodeCharacter{0057}{W}%
+ \DeclareUnicodeCharacter{0058}{X}%
+ \DeclareUnicodeCharacter{0059}{Y}%
+ \DeclareUnicodeCharacter{005A}{Z}%
+ \DeclareUnicodeCharacter{005B}{\char"5B}
+ \DeclareUnicodeCharacter{005C}{\char"5C}
+ \DeclareUnicodeCharacter{005D}{\char"5D}
+ \DeclareUnicodeCharacter{005E}{\char"5E}
+ \DeclareUnicodeCharacter{005F}{\char"5F}
+ \DeclareUnicodeCharacter{0060}{\char"60}
+ \DeclareUnicodeCharacter{0061}{a}%
+ \DeclareUnicodeCharacter{0062}{b}%
+ \DeclareUnicodeCharacter{0063}{c}%
+ \DeclareUnicodeCharacter{0064}{d}%
+ \DeclareUnicodeCharacter{0065}{e}%
+ \DeclareUnicodeCharacter{0066}{f}%
+ \DeclareUnicodeCharacter{0067}{g}%
+ \DeclareUnicodeCharacter{0068}{h}%
+ \DeclareUnicodeCharacter{0069}{i}%
+ \DeclareUnicodeCharacter{006A}{j}%
+ \DeclareUnicodeCharacter{006B}{k}%
+ \DeclareUnicodeCharacter{006C}{l}%
+ \DeclareUnicodeCharacter{006D}{m}%
+ \DeclareUnicodeCharacter{006E}{n}%
+ \DeclareUnicodeCharacter{006F}{o}%
+ \DeclareUnicodeCharacter{0070}{p}%
+ \DeclareUnicodeCharacter{0071}{q}%
+ \DeclareUnicodeCharacter{0072}{r}%
+ \DeclareUnicodeCharacter{0073}{s}%
+ \DeclareUnicodeCharacter{0074}{t}%
+ \DeclareUnicodeCharacter{0075}{u}%
+ \DeclareUnicodeCharacter{0076}{v}%
+ \DeclareUnicodeCharacter{0077}{w}%
+ \DeclareUnicodeCharacter{0078}{x}%
+ \DeclareUnicodeCharacter{0079}{y}%
+ \DeclareUnicodeCharacter{007A}{z}%
+ \DeclareUnicodeCharacter{007B}{\char"7B}
+ \DeclareUnicodeCharacter{007C}{\char"7C}
+ \DeclareUnicodeCharacter{007D}{\char"7D}
+ \DeclareUnicodeCharacter{007E}{\char"7E}
+ % \DeclareUnicodeCharacter{007F}{} % DEL
+ %
\DeclareUnicodeCharacter{00A0}{\tie}%
\DeclareUnicodeCharacter{00A1}{\exclamdown}%
\DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent
@@ -11276,7 +11321,7 @@ directory should work if nowhere else does.}
\textleading = 12.5pt
%
\internalpagesizes{160mm}{120mm}%
- {\voffset}{\hoffset}%
+ {\voffset}{-11.4mm}%
{\bindingoffset}{8pt}%
{210mm}{148mm}%
%
@@ -11358,6 +11403,7 @@ directory should work if nowhere else does.}
\message{and turning on texinfo input format.}
\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+\catcode`\^^K = 10 % treat vertical tab as whitespace
% DEL is a comment character, in case @c does not suffice.
\catcode`\^^? = 14
diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
index 79e3fb8221..b7f4fe2ec8 100644
--- a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
@@ -48,6 +48,8 @@ $mirrors = {
'http://ftp.ktug.org/tex-archive/' => 1,
'https://cran.asia/tex/' => 1,
'https://ftp.kaist.ac.kr/pub/tex-archive/' => 1,
+ 'https://lab.uklee.pe.kr/tex-archive/' => 1,
+ 'https://mirror.kakao.com/CTAN/' => 1,
'https://mirror.navercorp.com/CTAN/' => 1,
},
'Philippines' => {
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
index 95ee38115f..dd620a8491 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
@@ -26,11 +26,11 @@ depend container_split_src_files/1
depend frozen/0
depend minrelease/2016
depend release/2022
-depend revision/64138
+depend revision/64143
name 00texlive.image
category TLCore
-revision 64119
+revision 64143
shortdesc TeX Live files only in the source repository
longdesc The files here are not copied by the installer and containers
longdesc are not built for them; they exist only in the source
@@ -1733,6 +1733,7 @@ runfiles size=12913
tlpkg/tlpsrc/fancylabel.tlpsrc
tlpkg/tlpsrc/fancynum.tlpsrc
tlpkg/tlpsrc/fancypar.tlpsrc
+ tlpkg/tlpsrc/fancyqr.tlpsrc
tlpkg/tlpsrc/fancyref.tlpsrc
tlpkg/tlpsrc/fancyslides.tlpsrc
tlpkg/tlpsrc/fancytabs.tlpsrc
@@ -4611,7 +4612,7 @@ depend setting_available_architectures:aarch64-linux amd64-freebsd amd64-netbsd
name 00texlive.installer
category TLCore
-revision 64133
+revision 64140
shortdesc TeX Live standalone installer package
longdesc This package defines the files to go into the installer
longdesc archives (install-tl-unx.tar.gz, install-tl.zip) built by the
@@ -57965,7 +57966,7 @@ catalogue-version 1.5.3
name citation-style-language
category Package
-revision 63023
+revision 64143
shortdesc Bibliography formatting with Citation Style Language
longdesc The Citation Style Language (CSL) is an XML-based language that
longdesc defines the formats of citations and bibliography. There are
@@ -57979,27 +57980,37 @@ longdesc both citations and bibliography according to the selected CSL
longdesc style. A LaTeX package (citation-style-language.sty) is
longdesc provided to communicate with the processor.
depend citation-style-language.ARCH
-containersize 108620
-containerchecksum 9195782dfdbc9a53eb93087faf87e93adc0aaab12aea4fed33f382fe31a0ec581e67e3104f7a2d997a19b7b02b58ccb29270d448f3ed160c38abaceee3e2c9c9
-doccontainersize 234896
-doccontainerchecksum da36eb08775cd79fa2d75beb69609bb162bffd469a168a2b532440ef16a7839caf57c332bf35b04cbe7d57e5c71fb3a336d08c0b2023f7ca61f786e7886d89c9
-docfiles size=65
+depend filehook
+depend l3kernel
+depend l3packages
+depend lua-uca
+depend lualibs
+depend luatex
+depend luaxml
+depend url
+containersize 123848
+containerchecksum 03a04ba7cf862ebf609a1f4b6ab689f157cafa9ecbdc48c60ca9b9968c7770b185fbb9d1f420b60c61b49138bb57a62d5a5513e9161df79fe60cfe4d83e2142f
+doccontainersize 236380
+doccontainerchecksum 8df0347098ac6ba3cdad0c43e8b1222e8e511d21e25a55566792d109c7b1b1a40fe3d0c1ccac4151b3f21684cd07459cd809841c7f2f192178009ba449ed921a
+docfiles size=66
texmf-dist/doc/latex/citation-style-language/CHANGELOG.md
+ texmf-dist/doc/latex/citation-style-language/DEPENDS.txt
texmf-dist/doc/latex/citation-style-language/README.md details="Readme"
texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf details="Package documentation"
texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex
- texmf-dist/doc/man/man1/citeproc.1
- texmf-dist/doc/man/man1/citeproc.man1.pdf
-srccontainersize 1132
-srccontainerchecksum 2855310fedad682b34f011d222d5f9e014aac741cfb361cba4b53e8036477d665d9bb59ab36e5ecdecc6e25774baee1c51929768be1727cac6fd25577192b513
-srcfiles size=1
- texmf-dist/source/latex/citation-style-language/README.md
-runfiles size=475
- texmf-dist/scripts/citation-style-language/citeproc
+ texmf-dist/doc/man/man1/citeproc-lua.1
+ texmf-dist/doc/man/man1/citeproc-lua.man1.pdf
+runfiles size=502
+ texmf-dist/scripts/citation-style-language/citeproc-bib-data.lua
texmf-dist/scripts/citation-style-language/citeproc-bib.lua
+ texmf-dist/scripts/citation-style-language/citeproc-cli.lua
+ texmf-dist/scripts/citation-style-language/citeproc-context.lua
texmf-dist/scripts/citation-style-language/citeproc-element.lua
texmf-dist/scripts/citation-style-language/citeproc-engine.lua
- texmf-dist/scripts/citation-style-language/citeproc-formats.lua
+ texmf-dist/scripts/citation-style-language/citeproc-ir-node.lua
+ texmf-dist/scripts/citation-style-language/citeproc-latex-core.lua
+ texmf-dist/scripts/citation-style-language/citeproc-latex.lua
+ texmf-dist/scripts/citation-style-language/citeproc-lua.lua
texmf-dist/scripts/citation-style-language/citeproc-node-choose.lua
texmf-dist/scripts/citation-style-language/citeproc-node-date.lua
texmf-dist/scripts/citation-style-language/citeproc-node-group.lua
@@ -58012,13 +58023,10 @@ runfiles size=475
texmf-dist/scripts/citation-style-language/citeproc-node-style.lua
texmf-dist/scripts/citation-style-language/citeproc-node-text.lua
texmf-dist/scripts/citation-style-language/citeproc-nodes.lua
- texmf-dist/scripts/citation-style-language/citeproc-richtext.lua
+ texmf-dist/scripts/citation-style-language/citeproc-output.lua
texmf-dist/scripts/citation-style-language/citeproc-util.lua
texmf-dist/scripts/citation-style-language/citeproc.lua
- texmf-dist/scripts/citation-style-language/csl-core.lua
- texmf-dist/scripts/citation-style-language/csl.lua
texmf-dist/tex/latex/citation-style-language/citation-style-language.sty
- texmf-dist/tex/latex/citation-style-language/citeproc-bib-data.json
texmf-dist/tex/latex/citation-style-language/locales/csl-locales-af-ZA.xml
texmf-dist/tex/latex/citation-style-language/locales/csl-locales-ar.xml
texmf-dist/tex/latex/citation-style-language/locales/csl-locales-bg-BG.xml
@@ -58093,151 +58101,167 @@ catalogue-contact-repository https://github.com/zepinglee/citeproc-lua
catalogue-ctan /biblio/citation-style-language
catalogue-license mit cc-by-sa-3
catalogue-topics biblio use-lua
-catalogue-version 0.1.1
+catalogue-version 0.2.0
name citation-style-language.aarch64-linux
category Package
-revision 61687
+revision 64143
shortdesc aarch64-linux files of citation-style-language
-containersize 356
-containerchecksum cd0d5ba7fbcdc48db6a116a55a583cb4d68c0c92c75041b6b5b53b798972160eb589d30e1542d2080871ec936a91fe4c32af15931bb0dbcc00319d4cad875c1f
-binfiles arch=aarch64-linux size=1
+containersize 384
+containerchecksum f82a7ef1c649ecf7b44f2feb503d6661eaea3a03a677c685d1a0b938b5ea8511b3fefae62470b619ec1e342d51fc2391be322c7e98716def2741d2a108617a68
+binfiles arch=aarch64-linux size=2
bin/aarch64-linux/citeproc
+ bin/aarch64-linux/citeproc-lua
name citation-style-language.amd64-freebsd
category Package
-revision 61687
+revision 64143
shortdesc amd64-freebsd files of citation-style-language
-containersize 360
-containerchecksum 89d110f0118ef6a7b9ce4001e1bc604fdfb1cbe156cfbb7254d96639296c461352131b556b2b11363473789abdd93036f9aca54c20c74f1b3615f0049037bbc3
-binfiles arch=amd64-freebsd size=1
+containersize 388
+containerchecksum c14279a791de16ae9ef3146d0ab7565a30d0537870f474b095652eab130fdfe30c6f7008cb6e7f9685a9bb28d209d7e3ee7e7dc3bc35516c23bcacaefe2da9c6
+binfiles arch=amd64-freebsd size=2
bin/amd64-freebsd/citeproc
+ bin/amd64-freebsd/citeproc-lua
name citation-style-language.amd64-netbsd
category Package
-revision 61687
+revision 64143
shortdesc amd64-netbsd files of citation-style-language
-containersize 360
-containerchecksum 646e20fead81e3197c9b7bff5b391e2ababd471bf10c3d3abde37f070ff276a5f92722e386d75ddc2cf9170a024e82475f8a9daa7ef9026fa41a403776362251
-binfiles arch=amd64-netbsd size=1
+containersize 388
+containerchecksum fb441c93cf15de009873f341bfa7f6284f44b8111e9fa15dbabe4b310c28b0fde7629c21a4a7a797a55cdcee27b605ff1e6cdc29fc44bc611cf90e6f97a0cda8
+binfiles arch=amd64-netbsd size=2
bin/amd64-netbsd/citeproc
+ bin/amd64-netbsd/citeproc-lua
name citation-style-language.armhf-linux
category Package
-revision 61687
+revision 64143
shortdesc armhf-linux files of citation-style-language
-containersize 356
-containerchecksum 60c487247a8a97a8adc98fa81a0c8ce425e01269a243f3b0f6211102eea330cd6a94bef5aa3fd0b3b76589fb94bb4e650313fba75200e0f27939381335c10293
-binfiles arch=armhf-linux size=1
+containersize 388
+containerchecksum 21825b1f5c53a91a3695fd6b62fdb9c99dceacb1b80289145eaa4f54615e9db92acd1d50583c683fab98d1664489e1c128228e75e33c857dc7075d47ded82264
+binfiles arch=armhf-linux size=2
bin/armhf-linux/citeproc
+ bin/armhf-linux/citeproc-lua
name citation-style-language.i386-cygwin
category Package
-revision 61687
+revision 64143
shortdesc i386-cygwin files of citation-style-language
-containersize 356
-containerchecksum e3c4ca4d0b4fc3d078acedccd1b792fe8f6c70b4b0aa75d13ca7510bf4b0a6397ad33b9f3198ba2c468e15169e0921dcee60eab3d207a25f4205e33979e971c8
-binfiles arch=i386-cygwin size=1
+containersize 388
+containerchecksum be1598d06bfc2fdbeb7a449cc6c0f9cb278df2d215c8cda739905d7d0ef964485160b40b28ef4aee8aa91bf81c45ee0e8748c2fedc614394f11f89515ff080b3
+binfiles arch=i386-cygwin size=2
bin/i386-cygwin/citeproc
+ bin/i386-cygwin/citeproc-lua
name citation-style-language.i386-freebsd
category Package
-revision 61687
+revision 64143
shortdesc i386-freebsd files of citation-style-language
-containersize 360
-containerchecksum c63cd4a26cd0895bd6fdcb83ae4d60b9583b22250c37e091a574ee2963aa87f168993d2d547d0054c7367586ad00f77f772697ac234924f2d31eceb48ebf1410
-binfiles arch=i386-freebsd size=1
+containersize 388
+containerchecksum 0c76bd732f6f833037d8d837cfb5930255012c9fa677bd24f5712dcf1c4d9961e0baf6eaff57ede0874b395418f903b0d2272bb3ae823e22d1f6512ffbc1ed4d
+binfiles arch=i386-freebsd size=2
bin/i386-freebsd/citeproc
+ bin/i386-freebsd/citeproc-lua
name citation-style-language.i386-linux
category Package
-revision 61687
+revision 64143
shortdesc i386-linux files of citation-style-language
-containersize 356
-containerchecksum 8025d70df1bc6b2614aa2d2606c533802ce58595a943a06b40c15b39dff5eecb5b03f8b09d902f029ea9e738b643c590e11db876fd3ef2f34cdff2c6dc46b23b
-binfiles arch=i386-linux size=1
+containersize 388
+containerchecksum 544d47662c16eb5f618dfab2c9b734886a4803077ad290c6902d8f2988de65810d4d50877dda0566dd6e14fddca715135b16929ea9eb307c5d5631e99bcd52fb
+binfiles arch=i386-linux size=2
bin/i386-linux/citeproc
+ bin/i386-linux/citeproc-lua
name citation-style-language.i386-netbsd
category Package
-revision 61687
+revision 64143
shortdesc i386-netbsd files of citation-style-language
-containersize 356
-containerchecksum e309afb37117e0085e4a5398f3e06681786b76026fc104cd671c383d923ea91c9cd4a2b99e6cb5cf7a56228af24c3d5ff9750ca32ff32aec619b1d6d713d0c33
-binfiles arch=i386-netbsd size=1
+containersize 388
+containerchecksum 6ba20c9af55e6ad69e4804ee948aba1cc3bbe296e3754ce78e0b568f601c3cd5fce25b74c7a557827336e03989be68484465508b527a77d94715a2e525294ea9
+binfiles arch=i386-netbsd size=2
bin/i386-netbsd/citeproc
+ bin/i386-netbsd/citeproc-lua
name citation-style-language.i386-solaris
category Package
-revision 61687
+revision 64143
shortdesc i386-solaris files of citation-style-language
-containersize 356
-containerchecksum 871517bc3e718869a4bccf9ce9a6b917bca1d01caad2910b604c70f132caa6bd1eaa345e0afb5c06d2d143303d1dc747f64380142449713d59abf24ed1efcc1a
-binfiles arch=i386-solaris size=1
+containersize 388
+containerchecksum f33c074e65fbf2a89c1b4c439a37bfec08284dbd85194011c13805398b7240c20d6d736df6a8370c20238daaecb07c9cc2c5a85ff179ab5d4234a8c514b63909
+binfiles arch=i386-solaris size=2
bin/i386-solaris/citeproc
+ bin/i386-solaris/citeproc-lua
name citation-style-language.universal-darwin
category Package
-revision 61687
+revision 64143
shortdesc universal-darwin files of citation-style-language
-containersize 360
-containerchecksum 45eae030cc33df8bb31cb9d060c9b487d1cb9fdc45c3749ba98df46378cf72b2079abd262f237541eb7275f0a9c0576384684a9de3b90cc7420b3834b34af1cd
-binfiles arch=universal-darwin size=1
+containersize 388
+containerchecksum b5c93e5d4e08402253adb6d09349062db8042d2957290d6b7c4d8c015bba8b448e69d116e732405d4dce99f76c1d060463199b8469d130cf5ac89cd7edd77b92
+binfiles arch=universal-darwin size=2
bin/universal-darwin/citeproc
+ bin/universal-darwin/citeproc-lua
name citation-style-language.win32
category Package
-revision 61687
+revision 64143
shortdesc win32 files of citation-style-language
-containersize 700
-containerchecksum 09c0cb26b34d5610f21e7d3623eec3028f31f895bc901736def15e566e69d146cc8ce37242c413039dc11c752b24fb0434a85536451b9865b56b657304157b11
-binfiles arch=win32 size=1
+containersize 724
+containerchecksum 72f00ac5e5bba688d46afa19b3c4428d2bc1fddaaf4101222ff14dd0e9ad804c1d035d4ac78b1612ce4185ee1aedfbefcda6fcf373d42bc1c1eecf4aa14f2bf1
+binfiles arch=win32 size=2
+ bin/win32/citeproc-lua.exe
bin/win32/citeproc.exe
name citation-style-language.x86_64-cygwin
category Package
-revision 61687
+revision 64143
shortdesc x86_64-cygwin files of citation-style-language
-containersize 360
-containerchecksum ac453db6259cd643d3887bb224a2516be9ea4d091b92262a278e6ef3c58ca3be627b19277d6acf80a8d19694c8cb3cef085c95ed0c5c397c4b81376f0909e645
-binfiles arch=x86_64-cygwin size=1
+containersize 388
+containerchecksum 292305621b71086c797769aed0d8b01ac9917fe0e209e8b132343eaa01181c87a1a07673680131f0a34946e58d20464e70a56b7f4533e743470fb9eff96df5c1
+binfiles arch=x86_64-cygwin size=2
bin/x86_64-cygwin/citeproc
+ bin/x86_64-cygwin/citeproc-lua
name citation-style-language.x86_64-darwinlegacy
category Package
-revision 61687
+revision 64143
shortdesc x86_64-darwinlegacy files of citation-style-language
-containersize 368
-containerchecksum 77f6c7f558e3c8777392a0c9556627bb13d2fac36fa0e5575cff76e4e87b467997a0fc78fc9a3d0de37149391ca3ef080a6eb350b0ce797d5ac0d9a1c38afd45
-binfiles arch=x86_64-darwinlegacy size=1
+containersize 396
+containerchecksum 3eed74223cac8e80f2f7e812facfc58880a83a3ae2e5c7d71cbc7861e86f72aa106edc3be11aa4bb8b28d024ede160f813ef852d2da7ca15c9fdd546ae351bd1
+binfiles arch=x86_64-darwinlegacy size=2
bin/x86_64-darwinlegacy/citeproc
+ bin/x86_64-darwinlegacy/citeproc-lua
name citation-style-language.x86_64-linux
category Package
-revision 61687
+revision 64143
shortdesc x86_64-linux files of citation-style-language
-containersize 360
-containerchecksum fb08bd011571ed8730849cfafca1ecea8647430fbb991bc68076d168fa2712ab445733be21b81c9bf1ab868f2280fdb4f64174f14d848f1227627efeb5aa1058
-binfiles arch=x86_64-linux size=1
+containersize 388
+containerchecksum b64e7a48faca7b798a8ec2c7acf1a484288ef22af1fc61d7be29c4a252818dbb0e633b5c4ac6c4d100c0d1d531d48f95182c731bf800bc1efe333acb9a61227d
+binfiles arch=x86_64-linux size=2
bin/x86_64-linux/citeproc
+ bin/x86_64-linux/citeproc-lua
name citation-style-language.x86_64-linuxmusl
category Package
-revision 61687
+revision 64143
shortdesc x86_64-linuxmusl files of citation-style-language
-containersize 364
-containerchecksum bd8b6ddd3e84abcc3e4f8d6fbc657be5a0817d1cd92495ac76cc1c38848573fc0f0574512c8fd51a1ea32fcaea78304d55a60f058f74cfac1e558315ca71d37e
-binfiles arch=x86_64-linuxmusl size=1
+containersize 392
+containerchecksum 56d51af38eac9e50ec94900a73eb215ed742016105c195da5c89f56515d2e686fe10aeb734c2c99c07f947ea61f476da92888889dd82b14fdfe558da0e28a676
+binfiles arch=x86_64-linuxmusl size=2
bin/x86_64-linuxmusl/citeproc
+ bin/x86_64-linuxmusl/citeproc-lua
name citation-style-language.x86_64-solaris
category Package
-revision 61687
+revision 64143
shortdesc x86_64-solaris files of citation-style-language
-containersize 356
-containerchecksum a15ebb727819155d9aedd472cdda08b4fb39a09e6036a7914bbf2002b717038e94f09b6c5297e779ff5ed26e5d59b5ff64544ad294a6d41fb8a0b3ce897eb46d
-binfiles arch=x86_64-solaris size=1
+containersize 384
+containerchecksum eab0764eb7d86b58bb2302e5b9ad250e964f7bb089131e52b3fffbfaa1ecc4a6eca1b9d50ef2dc3c8f6959c3472755b916f7a43bf8045dd2c478cf195d42cfc0
+binfiles arch=x86_64-solaris size=2
bin/x86_64-solaris/citeproc
+ bin/x86_64-solaris/citeproc-lua
name cite
category Package
@@ -69036,7 +69060,7 @@ containerchecksum c73220abd1545907a1d8de37cb534d2c6bd2534f1b55f03c069f39f535c326
name collection-latexextra
category Collection
-revision 64106
+revision 64141
shortdesc LaTeX additional packages
relocated 1
longdesc A very large collection of add-on packages for LaTeX.
@@ -69513,6 +69537,7 @@ depend fancyhandout
depend fancylabel
depend fancynum
depend fancypar
+depend fancyqr
depend fancyslides
depend fancytabs
depend fancytooltips
@@ -70490,8 +70515,8 @@ depend zref-clever
depend zref-vario
depend zwgetfdate
depend zwpagelayout
-containersize 6712
-containerchecksum 25cf86ccdffd5de6c8e6a3806d16dc9cb7b3e8b32bbb837e65c6ef39e21cf0b64e6cf9e4538d37a31138ade26a3059d70ab099817dd434ebe0371c23836f3974
+containersize 6720
+containerchecksum 7d56a6b33f849453b6c62a09e42f87139087ea051e3ecab25fb9287566a2fa6a5bd91907d44f9efe433d5dc2bf8469061f2b75b821b05ce91084d8ebe9bfc953
name collection-latexrecommended
category Collection
@@ -115558,6 +115583,22 @@ catalogue-license lppl1.3
catalogue-topics decoration
catalogue-version 1.3
+name fancyqr
+category Package
+revision 64141
+relocated 1
+containersize 3384
+containerchecksum 61664c94bf5c432f3e6b9498471bba1c16503decbc274bafc9cae755b6073d84b41c747e5e739b0a4d9dff1630578df262003446cf3960b920862bf480e77eb9
+doccontainersize 248004
+doccontainerchecksum e97d2eeb84fdea0111b11914a5c670386c925d1534bcfda429e0fd1a17c1ffd80da4f147a6e7f214cf8d14e28407379ea43c6339f23ac559428a0915ab9c4b82
+docfiles size=65
+ RELOC/doc/latex/fancyqr/README.md
+ RELOC/doc/latex/fancyqr/fancyqr-doc.pdf
+ RELOC/doc/latex/fancyqr/fancyqr-doc.tex
+ RELOC/doc/latex/fancyqr/qr-example.tex
+runfiles size=3
+ RELOC/tex/latex/fancyqr/fancyqr.sty
+
name fancyref
category Package
revision 15878
@@ -192456,7 +192497,7 @@ catalogue-version 0.5
name luavlna
category Package
-revision 58087
+revision 64142
shortdesc Prevent line breaks after single letter words, units, or academic titles
relocated 1
longdesc In some languages, like Czech or Polish, there should be no
@@ -192472,10 +192513,10 @@ longdesc units. The package supports both plain LuaTeX and LuaLaTeX.
longdesc BTW: "vlna" is the Czech word for "wave" or "curl" and also
longdesc denotes the tilde which, in TeX, is used for "unbreakable
longdesc spaces".
-containersize 7628
-containerchecksum ccef03e521ab96c6ba786bc6d2651c1178935902c6889fbb98156f04105498292b500c824474551bafe23ab76967c212730cdd781d8cb7f86cf8c8aa1aa64d56
-doccontainersize 95132
-doccontainerchecksum 7f484b73c1ed198a325a7835d647b4be21db1fdbf4065988d2f45f0a07bd6ca1697509186be4b911080bc8e5e753262a2a62f1f89cbf8e95aedf3cc1e21844b9
+containersize 7636
+containerchecksum 58c16981ec1515c74a2ffd7632f16d0fb28b9fe32e6e954b49be602c721110e3537a66059b149a4d5c9b652ee717ee1c736ea03d2e4df3803c1b6c4465c50bf1
+doccontainersize 95244
+doccontainerchecksum a8d808e891ee8eb4958061912d0cd7b8c89da3d352ae984b08c92f56ae1222209132e8612172392787bc27e2e62a8a487e48fe1c728c545d8afef5fb7f23747e
docfiles size=27
RELOC/doc/luatex/luavlna/README.md details="Readme"
RELOC/doc/luatex/luavlna/luavlna-doc.pdf details="Package documentation"
@@ -192497,7 +192538,7 @@ catalogue-contact-repository https://github.com/michal-h21/luavlna
catalogue-ctan /macros/luatex/generic/luavlna
catalogue-license lppl1.3
catalogue-topics typesetting czech slovak polish luatex
-catalogue-version 0.1i
+catalogue-version 0.1j
name luaxml
category Package
@@ -306242,7 +306283,7 @@ docfiles size=376
name texlive-scripts
category TLCore
-revision 64133
+revision 64140
shortdesc TeX Live infrastructure programs
longdesc Includes install-tl, tl-portable, rungs, etc.; not needed for
longdesc tlmgr to run but still ours. Not included in tlcritical.
@@ -306250,10 +306291,10 @@ depend texlive-scripts.ARCH
depend texlive.infra
execute addMap mathpple.map
postaction shortcut type=menu name="TeX Live command-line" cmd=TEXDIR/tlpkg/installer/tl-cmd.bat
-containersize 113500
-containerchecksum c484dd10b45309e9098db9b431040c37325a9eb6e6a3db3cadd5c7663892577271bf4bf83194f3a1f161516066aa64a839141b8bc5181ea9d7236c932c66bac6
+containersize 113524
+containerchecksum a3e5cad4f847f276edd5875aa70fe3259f7136e53ab93e216ee28f3720a75535354466aa34d4a0075b919abc3be096f3cf27a1f2ef5b0dd2f44273467b56ae6c
doccontainersize 419376
-doccontainerchecksum 3d16d680c65fe1a044fb2b2f1e92e420c99ddeae17fd1e73420e65aba38fbcd74181278f9ef70fa1981bf9332d702804cd292393c5b4e1e6329e6fd0a37c1a77
+doccontainerchecksum f760e10cf2187cf1025a0703a83df4f131b41749f18bc94aeecdaa4932fc8a2ae17c09f474944fe269413f56907cb75eee6e86617344effa4ffd576d1b68b887
docfiles size=517
doc.html
texmf-dist/doc/man/man1/fmtutil-sys.1
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
index 1261a4504c..36e4c711a0 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
@@ -1 +1 @@
-ad6dadb8fd3bdd05429fb2ad25392ce9 texlive.tlpdb
+d77be122c44dca09cbf13708b65bc36d texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
index 82c10db0f7..9653420561 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
@@ -1 +1 @@
-6f6a86ee411cc63fac661c9b90eb12024a7e0ac4dd5ed8b284ee0c84b86fab78020441b440c9a243d72745225095af5b7442bbfcb57ee0d108795714d81884f3 texlive.tlpdb
+2040651c186185803ffd2c4d70a6256aaa73416ed5a4d92e15d2155730f6ceb1c970f7fcb18488b43602de5a9a56a984e4bb59d9895b30b8e09773148c9a9591 texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
index b904641690..db18b8177b 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
@@ -1,10 +1,10 @@
-----BEGIN PGP SIGNATURE-----
-iQEcBAEBCgAGBQJi/X9sAAoJEEzhh34ZQ4xwjtUH/20lgYHnnhrH1OJUw+x/JbJf
-8X22Qjvm/3+j4blBX4IuGfBqmRMRF1pZTAkMXyz3S/0Fe/nXv+grl+2rL3Vw2vny
-BB4qCwremQmt7s8cNJbHMAYHb3C4aa/javJB3NlhajAqw3hDXhqpZWE8A8XYvIvF
-2cFmsSPI1LgnmRCIgjcQ43VyQonIE09nx/8j4h+hwv19mYPpv9vaGEkLvQ3Bmj/U
-9Kx5As8v1oMhL/rePhu2P8LQmEtdr70hmrVWK3m7qbS+izJL1w6ckam61t8cCyWt
-d4DWSds7VBThvAzvzJEY1rB9+V+dpuqJIloRvtHIYKXQCm1l6BkMKoT35dDPOus=
-=5Cht
+iQEcBAEBCgAGBQJi/tC7AAoJEEzhh34ZQ4xwpssIAJdvIXfjzwW+R5zdHkn/QSMY
+gGoq//FSQQnrduS7+2TdLVk63NtpLIpfzp4aRgjb5YXYLct4yuJwOsEDBpD7sJpU
+Vv16q7E5XhZ2GaX/290P5Ku4IL3dwVvbfxi8166vBD5jcTM0QneBHI9pUbW/PZB5
+ZLe2JrzHh4O58O3c9bxRVeaSCFrZ9wwm3jTZK+mp+wbMk141N6uTXbvphn7+3C8+
+WMKPT2/ul/3cRJPDXdy9g4t25tNJ+eFplvJVudoGhuYv+LzZwhMyVQoe10lekAVN
+o7A1v9de2cP22BOgaSNy5aDbGo/5CiMitrY3oVYyUyGRCPB9LCDbbhXA+oqKOCs=
+=Qwhd
-----END PGP SIGNATURE-----
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
index 8373e7c31f..209ba558bf 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
Binary files differ
diff --git a/systems/win32/miktex/tm/packages/next/pr.ini b/systems/win32/miktex/tm/packages/next/pr.ini
index 78097f5b25..1d42f0f922 100644
--- a/systems/win32/miktex/tm/packages/next/pr.ini
+++ b/systems/win32/miktex/tm/packages/next/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1660767344
+date=1660853743
lastupd=miktex-arctrl-bin-x64-2.9 miktex-asymptote-bin-x64-2.9 miktex-autosp-bin-x64-2.9 miktex-axohelp-bin-x64-2.9 miktex-bibarts-bin-x64-2.9 miktex-bibtex-bin-x64-2.9 miktex-bibtex8bit-bin-x64-2.9 miktex-bzip2-bin-x64-2.9 miktex-cairo-bin-x64-2.9 miktex-chktex-bin-x64-2.9 miktex-cjkutils-bin-x64-2.9 miktex-console-bin-x64-2.9 miktex-curl-bin-x64-2.9 miktex-cweb-bin-x64-2.9 miktex-devnag-bin-x64-2.9 miktex-doc miktex-dvicopy-bin-x64-2.9 miktex-dvipdfmx-bin-x64-2.9 miktex-dvipng-bin-x64-2.9 miktex-dvips-bin-x64-2.9
-lstdigest=96dfacf3fc5d4799de13949cbce96e2c
+lstdigest=9bc8600c929a31899b341547adc423d8
numpkg=5869
relstate=next
-version=8264
+version=8265
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: V03wfEOs33tFJcQMPw0lUfXdzQweiOvxw0cJrAX2edn3KGGCYb3vrzc+d8Xo1+EVbid8Af1sOP+fW2IflLM2m616JCqM/yXVHj7Zxo+3INa4qGSatNMtkoVnzrG5d1ytVW5dsynkvVlKnLqEVhqFaeiGdsdPkDI9Icy+qc7A3IRvgrFSCFSCMwBuqMHDVfWGoNaRH93XpK8TC0Z3WEPnHuPS/QFpb6Lcv0GzV0BgmY1/Q3Fmzt7edQQL1SQMUUEAMdrNArKoIYarbz8isSz1iXQbivpbb2e/Cn7d8r70mBbnSp+yBmhqOG6pjF58oZD40NO1O4J571+FdI6limzGxA==
+;;;; signature/miktex: mJEJizlXb3/deFyJknfB0EmCUzvfzJaB7NJOrDqckjPT9+0/C8byibZ4een6O4xWPTiYTsYkZE4UC7zB0va3Sq05k/PzyMFuizWYpk2TeWV9ED8nQOwnSXIf3FVgT4gVlZqtqKhD/y96b1Y/IGFzaSwMGMNGHa6yk0CejZlpMom8bQSFQdRX7cQ5uRQ7jIwA2c04ulx5/EVVhu/wKYM6StYKq0dpSAy7AdxIDW9o15K4QaeOq3TZF2kyCYUHxpODKG4meN6FpTvVam1ySBC6BNTpAu+tFLrznf9S7fgnC2RGsNQpB+HFYvuBmzmhHkpb9GpmP0tCwVQFzmc3561L2g==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/systems/win32/miktex/tm/packages/pr.ini b/systems/win32/miktex/tm/packages/pr.ini
index 75c79593dd..d00c3f88d5 100644
--- a/systems/win32/miktex/tm/packages/pr.ini
+++ b/systems/win32/miktex/tm/packages/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1660767066
+date=1660853464
lastupd=asymptote create-theorem create-theorem__doc create-theorem__source easybook easybook__doc easybook__source exam-zh exam-zh__doc exam-zh__source ffcode ffcode__doc ffcode__source fixdif fixdif__doc fixdif__source hereapplies hereapplies__doc hereapplies__source media4svg
-lstdigest=244f161274be109beb6719bb42976e33
+lstdigest=a977a4f1bfc637ec3e13271156d54dae
numpkg=5869
relstate=stable
-version=8264
+version=8265
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: RJ3OyCf2wTVTc5Me2Z/fO6JwKYIP/uG2r0cjUSpYWNw5Ffaw8UdsTSy37Ebnbu/fJOhs3xKLZ1o7pStPgZs+PJMp3eNLKgQg6Vi5pL1lK0T1avwvEibAYekxuU54C1oKmbbTO3lzB0n1qlly8KBDh28bj/3TzWrh15PuhSIe5oo5jlhy1eVElWLBi9pgketod0gm1gTcMpu2U8RvzXi1PgcUwzIOfJ1KXIvd+M/4KJ1tTK5BUEb0cYtcPwQqTQUCLLwW87vT9vuoKVsZa3zObx4bcUfTLkp6iyVZxbASvPLia+hliLqq9xmNZWMtcoYp6fZfLj3nEoKPVynhv/qNvQ==
+;;;; signature/miktex: R1+svlioVBG79y7M2+F0DNfVKwYDhB9sPkPocOlBrpCEZuPDgHjF1gyEen0tv+fN0SC+7BJGe1ZxR+65y4+7eSWtJu7Qk/lQt8Z03JgzL3YHkWhzjbJmXjUxa8VgjY4EcT50fZAXe2XdFaPmynz8Xflvsf6DELDFiunyEclvC3YzmdHQmOuWRFVDdlZ99dOwDtpBFZ0UQJ11ucRKVc2zW8fT5kYRSs6UeEIanKJokw0u2CMg0cElLQjR3/GVao4TIzgzeBiuGeheO2zg9C6I7p18atH/37aS2Kh8ei8Qt7tSjWfqxYtkxKYF/xCVxeiqRUwcomp5AqbqDrP0fLSrzw==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/timestamp b/timestamp
index 437fb69092..6c3eba81cb 100644
--- a/timestamp
+++ b/timestamp
@@ -2,4 +2,4 @@
# The source CTAN of this site's material:
dante.ctan.org
# The year-month-day-hour-minute of this site's material:
-2022-08-18-02-02
+2022-08-19-02-02