summaryrefslogtreecommitdiff
path: root/biblio
diff options
context:
space:
mode:
Diffstat (limited to 'biblio')
-rw-r--r--biblio/bibtex/bibtex-x/Makefile.in126
-rw-r--r--biblio/bibtex/bibtex-x/aclocal.m4421
-rwxr-xr-xbiblio/bibtex/bibtex-x/configure.texk340
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/README.md8
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.pdfbin91245 -> 91432 bytes
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.tex2
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.pdfbin62291 -> 62994 bytes
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.tex35
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-bibtex.sty14
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-unsrt.bst6
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran-year.bst6
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iran.bst6
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iranlatin-unsrt.bst6
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iranlatin-year.bst6
-rw-r--r--biblio/bibtex/contrib/iran-bibtex/iranlatin.bst6
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Changes86
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/LICENSE379
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/MANIFEST44
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.PL71
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.TDS35
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/README9
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/dist.ini28
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm367
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm429
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm443
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/notes26
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/00-load.t11
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/01-parse.t36
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t39
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t102
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/04-entry.t42
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/05-author.t68
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t46
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t42
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t24
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/09-complex.t42
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t61
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t28
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/12-von_token.t12
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/13_output.t39
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/14-extratext.t65
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t72
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib7
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib27
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib11
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib10
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib22
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib21
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt6
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt24
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib55
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt40
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug66325.t71
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug67419.t29
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t143
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t18
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod.t12
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t21
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t15
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Changes27
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/LICENSE375
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MANIFEST17
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.json40
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.yml22
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile917
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL51
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS53
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/README13
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/dist.ini16
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/head.ltx28
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdfbin0 -> 208301 bytes
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm788
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm728
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.173
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdfbin0 -> 21652 bytes
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl156
-rwxr-xr-xbiblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt169
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/convert.t136
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t21
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t15
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t16
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/weaver.ini24
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/Makefile31
-rw-r--r--biblio/bibtex/utils/bibtexperllibs/README53
-rw-r--r--biblio/citation-style-language/CHANGELOG.md70
-rw-r--r--biblio/citation-style-language/american-medical-association.csl6
-rw-r--r--biblio/citation-style-language/apa.csl975
-rw-r--r--biblio/citation-style-language/chicago-author-date.csl28
-rw-r--r--biblio/citation-style-language/citation-style-language-bib.sty149
-rw-r--r--biblio/citation-style-language/citation-style-language-cite.sty370
-rw-r--r--biblio/citation-style-language/citation-style-language-compatible.sty61
-rw-r--r--biblio/citation-style-language/citation-style-language-doc.pdfbin229210 -> 240563 bytes
-rw-r--r--biblio/citation-style-language/citation-style-language-doc.tex311
-rw-r--r--biblio/citation-style-language/citation-style-language-init.sty191
-rw-r--r--biblio/citation-style-language/citation-style-language.sty58
-rw-r--r--biblio/citation-style-language/citeproc-bibtex-data.lua7
-rw-r--r--biblio/citation-style-language/citeproc-bibtex-parser.lua8
-rw-r--r--biblio/citation-style-language/citeproc-bibtex2csl.lua3
-rw-r--r--biblio/citation-style-language/citeproc-cli.lua180
-rw-r--r--biblio/citation-style-language/citeproc-context.lua12
-rw-r--r--biblio/citation-style-language/citeproc-element.lua30
-rw-r--r--biblio/citation-style-language/citeproc-engine.lua961
-rw-r--r--biblio/citation-style-language/citeproc-ir-node.lua2
-rw-r--r--biblio/citation-style-language/citeproc-journal-data.lua63
-rw-r--r--biblio/citation-style-language/citeproc-latex-core.lua525
-rw-r--r--biblio/citation-style-language/citeproc-latex-parser.lua44
-rw-r--r--biblio/citation-style-language/citeproc-latex.lua183
-rw-r--r--biblio/citation-style-language/citeproc-lua.12
-rw-r--r--biblio/citation-style-language/citeproc-manager.lua1049
-rw-r--r--biblio/citation-style-language/citeproc-node-bibliography.lua2
-rw-r--r--biblio/citation-style-language/citeproc-node-choose.lua12
-rw-r--r--biblio/citation-style-language/citeproc-node-citation.lua73
-rw-r--r--biblio/citation-style-language/citeproc-node-names.lua2
-rw-r--r--biblio/citation-style-language/citeproc-node-number.lua3
-rw-r--r--biblio/citation-style-language/citeproc-node-sort.lua2
-rw-r--r--biblio/citation-style-language/citeproc-node-style.lua71
-rw-r--r--biblio/citation-style-language/citeproc-node-text.lua9
-rw-r--r--biblio/citation-style-language/citeproc-output.lua720
-rw-r--r--biblio/citation-style-language/citeproc-util.lua123
-rw-r--r--biblio/citation-style-language/citeproc.lua2
-rw-r--r--biblio/citation-style-language/csl-locales-de-AT.xml4
-rw-r--r--biblio/citation-style-language/csl-locales-de-CH.xml4
-rw-r--r--biblio/citation-style-language/csl-locales-de-DE.xml4
-rw-r--r--biblio/citation-style-language/csl-locales-en-US.xml3
-rw-r--r--biblio/citation-style-language/csl-locales-zh-TW.xml5
-rw-r--r--biblio/citation-style-language/ieee.csl50
-rw-r--r--biblio/citation-style-language/modern-humanities-research-association.csl19
-rw-r--r--biblio/ctan-bibdata/ctan.bib1889
128 files changed, 12988 insertions, 3226 deletions
diff --git a/biblio/bibtex/bibtex-x/Makefile.in b/biblio/bibtex/bibtex-x/Makefile.in
index 2066f50e0f..df63795f54 100644
--- a/biblio/bibtex/bibtex-x/Makefile.in
+++ b/biblio/bibtex/bibtex-x/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# Makefile.in generated by automake 1.17 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -71,6 +71,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+am__rm_f = rm -f $(am__rm_f_notfound)
+am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -235,10 +237,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
+ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
}
man1dir = $(mandir)/man1
NROFF = nroff
@@ -372,6 +373,7 @@ am__sh_e_setup = case $$- in *e*) set +e;; esac
# Default flags passed to test drivers.
am__common_driver_flags = \
--color-tests "$$am__color_tests" \
+ $$am__collect_skipped_logs \
--enable-hard-errors "$$am__enable_hard_errors" \
--expect-failure "$$am__expect_failure"
# To be inserted before the command running the test. Creates the
@@ -396,6 +398,11 @@ if test -f "./$$f"; then dir=./; \
elif test -f "$$f"; then dir=; \
else dir="$(srcdir)/"; fi; \
tst=$$dir$$f; log='$@'; \
+if test -n '$(IGNORE_SKIPPED_LOGS)'; then \
+ am__collect_skipped_logs='--collect-skipped-logs no'; \
+else \
+ am__collect_skipped_logs=''; \
+fi; \
if test -n '$(DISABLE_HARD_ERRORS)'; then \
am__enable_hard_errors=no; \
else \
@@ -460,20 +467,22 @@ distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
- find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -rf "$(distdir)" \
+ find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \
+ ; rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
+GZIP_ENV = -9
DIST_TARGETS = dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
-distcleancheck_listfiles = find . -type f -print
+distcleancheck_listfiles = \
+ find . \( -type f -a \! \
+ \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -569,8 +578,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
+am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
+am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -773,12 +784,12 @@ config.h: stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
- @rm -f stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status config.h
+ $(AM_V_at)rm -f stamp-h1
+ $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
- rm -f stamp-h1
- touch $@
+ $(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ $(AM_V_at)rm -f stamp-h1
+ $(AM_V_at)touch $@
distclean-hdr:
-rm -f config.h stamp-h1
@@ -821,16 +832,11 @@ uninstall-binPROGRAMS:
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
+ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files
clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
- echo " rm -f" $$list; \
- rm -f $$list || exit $$?; \
- test -n "$(EXEEXT)" || exit 0; \
- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f" $$list; \
- rm -f $$list
+ $(am__rm_f) $(bin_PROGRAMS)
+ test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=)
bibtex8$(EXEEXT): $(bibtex8_OBJECTS) $(bibtex8_DEPENDENCIES) $(EXTRA_bibtex8_DEPENDENCIES)
@rm -f bibtex8$(EXEEXT)
@@ -862,7 +868,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
- @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+ @: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -1302,7 +1308,6 @@ distclean-tags:
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
am--force-recheck:
@:
-
$(TEST_SUITE_LOG): $(TEST_LOGS)
@$(am__set_TESTS_bases); \
am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
@@ -1378,10 +1383,37 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
result_count $$1 "XPASS:" $$xpass "$$red"; \
result_count $$1 "ERROR:" $$error "$$mgn"; \
}; \
+ output_system_information () \
+ { \
+ echo; \
+ { uname -a | $(AWK) '{ \
+ printf "System information (uname -a):"; \
+ for (i = 1; i < NF; ++i) \
+ { \
+ if (i != 2) \
+ printf " %s", $$i; \
+ } \
+ printf "\n"; \
+}'; } 2>&1; \
+ if test -r /etc/os-release; then \
+ echo "Distribution information (/etc/os-release):"; \
+ sed 8q /etc/os-release; \
+ elif test -r /etc/issue; then \
+ echo "Distribution information (/etc/issue):"; \
+ cat /etc/issue; \
+ fi; \
+ }; \
+ please_report () \
+ { \
+echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \
+echo "together with the test-suite.log file (gzipped) and your system"; \
+echo "information. Thanks."; \
+ }; \
{ \
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
$(am__rst_title); \
create_testsuite_report --no-color; \
+ output_system_information; \
echo; \
echo ".. contents:: :depth: 2"; \
echo; \
@@ -1401,26 +1433,25 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
if $$success; then :; else \
- echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\
if test -n "$(PACKAGE_BUGREPORT)"; then \
- echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \
fi; \
echo "$$col$$br$$std"; \
fi; \
$$success || exit 1
check-TESTS:
- @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
- @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @$(am__rm_f) $(RECHECK_LOGS)
+ @$(am__rm_f) $(RECHECK_LOGS:.log=.trs)
+ @$(am__rm_f) $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
log_list=`for i in $$bases; do echo $$i.log; done`; \
- trs_list=`for i in $$bases; do echo $$i.trs; done`; \
- log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ log_list=`echo $$log_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
recheck: all
- @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @$(am__rm_f) $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
| $(am__list_recheck_tests)` || exit 1; \
@@ -1449,7 +1480,7 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
$(am__remove_distdir)
- test -d "$(distdir)" || mkdir "$(distdir)"
+ $(AM_V_at)$(MKDIR_P) "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -1535,7 +1566,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
+ eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@@ -1545,7 +1576,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
+ eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
@@ -1644,16 +1675,16 @@ install-strip:
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
- -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
- -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
- -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ -$(am__rm_f) $(TEST_LOGS)
+ -$(am__rm_f) $(TEST_LOGS:.log=.trs)
+ -$(am__rm_f) $(TEST_SUITE_LOG)
clean-generic:
distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
- -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+ -$(am__rm_f) $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
+ -$(am__rm_f) $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -1664,7 +1695,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -f ./$(DEPDIR)/bibtex8-bibtex-1.Po
+ -rm -f ./$(DEPDIR)/bibtex8-bibtex-1.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-2.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-3.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-4.Po
@@ -1725,7 +1756,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -f ./$(DEPDIR)/bibtex8-bibtex-1.Po
+ -rm -f ./$(DEPDIR)/bibtex8-bibtex-1.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-2.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-3.Po
-rm -f ./$(DEPDIR)/bibtex8-bibtex-4.Po
@@ -1799,3 +1830,10 @@ tests/bibtexu.log tests/bibtexu-basic.log tests/bibtexu-range.log \
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
+
+# Tell GNU make to disable its built-in pattern rules.
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
diff --git a/biblio/bibtex/bibtex-x/aclocal.m4 b/biblio/bibtex/bibtex-x/aclocal.m4
index f523361ff4..aceb5fd825 100644
--- a/biblio/bibtex/bibtex-x/aclocal.m4
+++ b/biblio/bibtex/bibtex-x/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
+# generated automatically by aclocal 1.17 -*- Autoconf -*-
-# Copyright (C) 1996-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# Copyright (C) 2002-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.16'
+[am__api_version='1.17'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.16.5], [],
+m4_if([$1], [1.17], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.5])dnl
+[AM_AUTOMAKE_VERSION([1.17])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-# Copyright (C) 2011-2021 Free Software Foundation, Inc.
+# Copyright (C) 2011-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -70,16 +70,18 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
AC_DEFUN([AM_PROG_AR],
[AC_BEFORE([$0], [LT_INIT])dnl
AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_BEFORE([$0], [AC_PROG_AR])dnl
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([ar-lib])dnl
AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
: ${AR=ar}
+: ${ARFLAGS=cr}
AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
[AC_LANG_PUSH([C])
am_cv_ar_interface=ar
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
- [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ [am_ar_try='$AR $ARFLAGS libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
AC_TRY_EVAL([am_ar_try])
if test "$ac_status" -eq 0; then
am_cv_ar_interface=ar
@@ -118,7 +120,7 @@ AC_SUBST([AR])dnl
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -170,7 +172,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2021 Free Software Foundation, Inc.
+# Copyright (C) 1997-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -201,7 +203,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2021 Free Software Foundation, Inc.
+# Copyright (C) 1999-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -333,7 +335,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # When given -MP, icc 7.0 and 7.1 complain thus:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
@@ -392,7 +394,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2021 Free Software Foundation, Inc.
+# Copyright (C) 1999-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -460,7 +462,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -594,7 +596,7 @@ if test -z "$CSCOPE"; then
fi
AC_SUBST([CSCOPE])
-AC_REQUIRE([AM_SILENT_RULES])dnl
+AC_REQUIRE([_AM_SILENT_RULES])dnl
dnl The testsuite driver may need to know about EXEEXT, so add the
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
@@ -602,47 +604,9 @@ AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
+AC_REQUIRE([_AM_PROG_RM_F])
+AC_REQUIRE([_AM_PROG_XARGS_N])
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <https://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
- fi
-fi
dnl The trailing newline in this macro's definition is deliberate, for
dnl backward compatibility and to allow trailing 'dnl'-style comments
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
@@ -675,7 +639,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -696,7 +660,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2021 Free Software Foundation, Inc.
+# Copyright (C) 2003-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -718,7 +682,7 @@ AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -753,7 +717,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -796,7 +760,7 @@ AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2021 Free Software Foundation, Inc.
+# Copyright (C) 1997-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -830,7 +794,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -859,7 +823,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2021 Free Software Foundation, Inc.
+# Copyright (C) 1999-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -906,7 +870,23 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2022-2024 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_RM_F
+# ---------------
+# Check whether 'rm -f' without any arguments works.
+# https://bugs.gnu.org/10828
+AC_DEFUN([_AM_PROG_RM_F],
+[am__rm_f_notfound=
+AS_IF([(rm -f && rm -fr && rm -rf) 2>/dev/null], [], [am__rm_f_notfound='""'])
+AC_SUBST(am__rm_f_notfound)
+])
+
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -925,16 +905,169 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# _AM_SLEEP_FRACTIONAL_SECONDS
+# ----------------------------
+AC_DEFUN([_AM_SLEEP_FRACTIONAL_SECONDS], [dnl
+AC_CACHE_CHECK([whether sleep supports fractional seconds],
+ am_cv_sleep_fractional_seconds, [dnl
+AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=yes],
+ [am_cv_sleep_fractional_seconds=no])
+])])
+
+# _AM_FILESYSTEM_TIMESTAMP_RESOLUTION
+# -----------------------------------
+# Determine the filesystem's resolution for file modification
+# timestamps. The coarsest we know of is FAT, with a resolution
+# of only two seconds, even with the most recent "exFAT" extensions.
+# The finest (e.g. ext4 with large inodes, XFS, ZFS) is one
+# nanosecond, matching clock_gettime. However, it is probably not
+# possible to delay execution of a shell script for less than one
+# millisecond, due to process creation overhead and scheduling
+# granularity, so we don't check for anything finer than that. (See below.)
+AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl
+AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS])
+AC_CACHE_CHECK([filesystem timestamp resolution],
+ am_cv_filesystem_timestamp_resolution, [dnl
+# Default to the worst case.
+am_cv_filesystem_timestamp_resolution=2
+
+# Only try to go finer than 1 sec if sleep can do it.
+# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work,
+# - 1 sec is not much of a win compared to 2 sec, and
+# - it takes 2 seconds to perform the test whether 1 sec works.
+#
+# Instead, just use the default 2s on platforms that have 1s resolution,
+# accept the extra 1s delay when using $sleep in the Automake tests, in
+# exchange for not incurring the 2s delay for running the test for all
+# packages.
+#
+am_try_resolutions=
+if test "$am_cv_sleep_fractional_seconds" = yes; then
+ # Even a millisecond often causes a bunch of false positives,
+ # so just try a hundredth of a second. The time saved between .001 and
+ # .01 is not terribly consequential.
+ am_try_resolutions="0.01 0.1 $am_try_resolutions"
+fi
+
+# In order to catch current-generation FAT out, we must *modify* files
+# that already exist; the *creation* timestamp is finer. Use names
+# that make ls -t sort them differently when they have equal
+# timestamps than when they have distinct timestamps, keeping
+# in mind that ls -t prints the *newest* file first.
+rm -f conftest.ts?
+: > conftest.ts1
+: > conftest.ts2
+: > conftest.ts3
+
+# Make sure ls -t actually works. Do 'set' in a subshell so we don't
+# clobber the current shell's arguments. (Outer-level square brackets
+# are removed by m4; they're present so that m4 does not expand
+# <dollar><star>; be careful, easy to get confused.)
+if (
+ set X `[ls -t conftest.ts[12]]` &&
+ {
+ test "$[]*" != "X conftest.ts1 conftest.ts2" ||
+ test "$[]*" != "X conftest.ts2 conftest.ts1";
+ }
+); then :; else
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ _AS_ECHO_UNQUOTED(
+ ["Bad output from ls -t: \"`[ls -t conftest.ts[12]]`\""],
+ [AS_MESSAGE_LOG_FD])
+ AC_MSG_FAILURE([ls -t produces unexpected output.
+Make sure there is not a broken ls alias in your environment.])
+fi
+
+for am_try_res in $am_try_resolutions; do
+ # Any one fine-grained sleep might happen to cross the boundary
+ # between two values of a coarser actual resolution, but if we do
+ # two fine-grained sleeps in a row, at least one of them will fall
+ # entirely within a coarse interval.
+ echo alpha > conftest.ts1
+ sleep $am_try_res
+ echo beta > conftest.ts2
+ sleep $am_try_res
+ echo gamma > conftest.ts3
+
+ # We assume that 'ls -t' will make use of high-resolution
+ # timestamps if the operating system supports them at all.
+ if (set X `ls -t conftest.ts?` &&
+ test "$[]2" = conftest.ts3 &&
+ test "$[]3" = conftest.ts2 &&
+ test "$[]4" = conftest.ts1); then
+ #
+ # Ok, ls -t worked. If we're at a resolution of 1 second, we're done,
+ # because we don't need to test make.
+ make_ok=true
+ if test $am_try_res != 1; then
+ # But if we've succeeded so far with a subsecond resolution, we
+ # have one more thing to check: make. It can happen that
+ # everything else supports the subsecond mtimes, but make doesn't;
+ # notably on macOS, which ships make 3.81 from 2006 (the last one
+ # released under GPLv2). https://bugs.gnu.org/68808
+ #
+ # We test $MAKE if it is defined in the environment, else "make".
+ # It might get overridden later, but our hope is that in practice
+ # it does not matter: it is the system "make" which is (by far)
+ # the most likely to be broken, whereas if the user overrides it,
+ # probably they did so with a better, or at least not worse, make.
+ # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html
+ #
+ # Create a Makefile (real tab character here):
+ rm -f conftest.mk
+ echo 'conftest.ts1: conftest.ts2' >conftest.mk
+ echo ' touch conftest.ts2' >>conftest.mk
+ #
+ # Now, running
+ # touch conftest.ts1; touch conftest.ts2; make
+ # should touch ts1 because ts2 is newer. This could happen by luck,
+ # but most often, it will fail if make's support is insufficient. So
+ # test for several consecutive successes.
+ #
+ # (We reuse conftest.ts[12] because we still want to modify existing
+ # files, not create new ones, per above.)
+ n=0
+ make=${MAKE-make}
+ until test $n -eq 3; do
+ echo one > conftest.ts1
+ sleep $am_try_res
+ echo two > conftest.ts2 # ts2 should now be newer than ts1
+ if $make -f conftest.mk | grep 'up to date' >/dev/null; then
+ make_ok=false
+ break # out of $n loop
+ fi
+ n=`expr $n + 1`
+ done
+ fi
+ #
+ if $make_ok; then
+ # Everything we know to check worked out, so call this resolution good.
+ am_cv_filesystem_timestamp_resolution=$am_try_res
+ break # out of $am_try_res loop
+ fi
+ # Otherwise, we'll go on to check the next resolution.
+ fi
+done
+rm -f conftest.ts?
+# (end _am_filesystem_timestamp_resolution)
+])])
+
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
+[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION])
+# This check should not be cached, as it may vary across builds of
+# different projects.
+AC_MSG_CHECKING([whether build environment is sane])
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -953,49 +1086,40 @@ esac
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
-if (
- am_has_slept=no
- for am_try in 1 2; do
- echo "timestamp, slept: $am_has_slept" > conftest.file
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
- alias in your environment])
- fi
- if test "$[2]" = conftest.file || test $am_try -eq 2; then
- break
- fi
- # Just in case.
- sleep 1
- am_has_slept=yes
- done
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
+am_build_env_is_sane=no
+am_has_slept=no
+rm -f conftest.file
+for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ test "$[]2" = conftest.file
+ ); then
+ am_build_env_is_sane=yes
+ break
+ fi
+ # Just in case.
+ sleep "$am_cv_filesystem_timestamp_resolution"
+ am_has_slept=yes
+done
+
+AC_MSG_RESULT([$am_build_env_is_sane])
+if test "$am_build_env_is_sane" = no; then
+ AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-AC_MSG_RESULT([yes])
+
# If we didn't sleep, we still need to ensure time stamps of config.status and
# generated files are strictly newer.
am_sleep_pid=
-if grep 'slept: no' conftest.file >/dev/null 2>&1; then
- ( sleep 1 ) &
+AS_IF([test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1],, [dnl
+ ( sleep "$am_cv_filesystem_timestamp_resolution" ) &
am_sleep_pid=$!
-fi
+])
AC_CONFIG_COMMANDS_PRE(
[AC_MSG_CHECKING([that generated files are newer than configure])
if test -n "$am_sleep_pid"; then
@@ -1006,18 +1130,18 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2009-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# AM_SILENT_RULES([DEFAULT])
-# --------------------------
-# Enable less verbose build rules; with the default set to DEFAULT
-# ("yes" being less verbose, "no" or empty being verbose).
-AC_DEFUN([AM_SILENT_RULES],
-[AC_ARG_ENABLE([silent-rules], [dnl
+# _AM_SILENT_RULES
+# ----------------
+# Enable less verbose build rules support.
+AC_DEFUN([_AM_SILENT_RULES],
+[AM_DEFAULT_VERBOSITY=1
+AC_ARG_ENABLE([silent-rules], [dnl
AS_HELP_STRING(
[--enable-silent-rules],
[less verbose build output (undo: "make V=1")])
@@ -1025,11 +1149,6 @@ AS_HELP_STRING(
[--disable-silent-rules],
[verbose build output (undo: "make V=0")])dnl
])
-case $enable_silent_rules in @%:@ (((
- yes) AM_DEFAULT_VERBOSITY=0;;
- no) AM_DEFAULT_VERBOSITY=1;;
- *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
-esac
dnl
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
dnl do not support nested variable expansions.
@@ -1048,14 +1167,6 @@ am__doit:
else
am_cv_make_support_nested_variables=no
fi])
-if test $am_cv_make_support_nested_variables = yes; then
- dnl Using '$V' instead of '$(V)' breaks IRIX make.
- AM_V='$(V)'
- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
-else
- AM_V=$AM_DEFAULT_VERBOSITY
- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
-fi
AC_SUBST([AM_V])dnl
AM_SUBST_NOTMAKE([AM_V])dnl
AC_SUBST([AM_DEFAULT_V])dnl
@@ -1064,9 +1175,33 @@ AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
AM_BACKSLASH='\'
AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+dnl Delay evaluation of AM_DEFAULT_VERBOSITY to the end to allow multiple calls
+dnl to AM_SILENT_RULES to change the default value.
+AC_CONFIG_COMMANDS_PRE([dnl
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+esac
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+])dnl
])
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Set the default verbosity level to DEFAULT ("yes" being less verbose, "no" or
+# empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_REQUIRE([_AM_SILENT_RULES])
+AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1])])
+
+# Copyright (C) 2001-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1094,7 +1229,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# Copyright (C) 2006-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1113,7 +1248,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2021 Free Software Foundation, Inc.
+# Copyright (C) 2004-2024 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1159,15 +1294,19 @@ m4_if([$1], [v7],
am_uid=`id -u || echo unknown`
am_gid=`id -g || echo unknown`
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
- if test $am_uid -le $am_max_uid; then
- AC_MSG_RESULT([yes])
+ if test x$am_uid = xunknown; then
+ AC_MSG_WARN([ancient id detected; assuming current UID is ok, but dist-ustar might not work])
+ elif test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
else
- AC_MSG_RESULT([no])
- _am_tools=none
+ AC_MSG_RESULT([no])
+ _am_tools=none
fi
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
- if test $am_gid -le $am_max_gid; then
- AC_MSG_RESULT([yes])
+ if test x$gm_gid = xunknown; then
+ AC_MSG_WARN([ancient id detected; assuming current GID is ok, but dist-ustar might not work])
+ elif test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
_am_tools=none
@@ -1244,6 +1383,26 @@ AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
+# Copyright (C) 2022-2024 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_XARGS_N
+# ----------------
+# Check whether 'xargs -n' works. It should work everywhere, so the fallback
+# is not optimized at all as we never expect to use it.
+AC_DEFUN([_AM_PROG_XARGS_N],
+[AC_CACHE_CHECK([xargs -n works], am_cv_xargs_n_works, [dnl
+AS_IF([test "`echo 1 2 3 | xargs -n2 echo`" = "1 2
+3"], [am_cv_xargs_n_works=yes], [am_cv_xargs_n_works=no])])
+AS_IF([test "$am_cv_xargs_n_works" = yes], [am__xargs_n='xargs -n'], [dnl
+ am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "$@" "$am__xargs_n_arg"; done; }'
+])dnl
+AC_SUBST(am__xargs_n)
+])
+
m4_include([../../m4/kpse-common.m4])
m4_include([../../m4/kpse-cxx-hack.m4])
m4_include([../../m4/kpse-icu-flags.m4])
diff --git a/biblio/bibtex/bibtex-x/configure.texk b/biblio/bibtex/bibtex-x/configure.texk
index 00b9d70529..c491679900 100755
--- a/biblio/bibtex/bibtex-x/configure.texk
+++ b/biblio/bibtex/bibtex-x/configure.texk
@@ -733,6 +733,8 @@ CC
MAINT
MAINTAINER_MODE_FALSE
MAINTAINER_MODE_TRUE
+am__xargs_n
+am__rm_f_notfound
AM_BACKSLASH
AM_DEFAULT_VERBOSITY
AM_DEFAULT_V
@@ -3287,7 +3289,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-am__api_version='1.16'
+am__api_version='1.17'
@@ -3390,6 +3392,165 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5
+printf %s "checking whether sleep supports fractional seconds... " >&6; }
+if test ${am_cv_sleep_fractional_seconds+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if sleep 0.001 2>/dev/null
+then :
+ am_cv_sleep_fractional_seconds=yes
+else case e in #(
+ e) am_cv_sleep_fractional_seconds=no ;;
+esac
+fi
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_sleep_fractional_seconds" >&5
+printf "%s\n" "$am_cv_sleep_fractional_seconds" >&6; }
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking filesystem timestamp resolution" >&5
+printf %s "checking filesystem timestamp resolution... " >&6; }
+if test ${am_cv_filesystem_timestamp_resolution+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) # Default to the worst case.
+am_cv_filesystem_timestamp_resolution=2
+
+# Only try to go finer than 1 sec if sleep can do it.
+# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work,
+# - 1 sec is not much of a win compared to 2 sec, and
+# - it takes 2 seconds to perform the test whether 1 sec works.
+#
+# Instead, just use the default 2s on platforms that have 1s resolution,
+# accept the extra 1s delay when using $sleep in the Automake tests, in
+# exchange for not incurring the 2s delay for running the test for all
+# packages.
+#
+am_try_resolutions=
+if test "$am_cv_sleep_fractional_seconds" = yes; then
+ # Even a millisecond often causes a bunch of false positives,
+ # so just try a hundredth of a second. The time saved between .001 and
+ # .01 is not terribly consequential.
+ am_try_resolutions="0.01 0.1 $am_try_resolutions"
+fi
+
+# In order to catch current-generation FAT out, we must *modify* files
+# that already exist; the *creation* timestamp is finer. Use names
+# that make ls -t sort them differently when they have equal
+# timestamps than when they have distinct timestamps, keeping
+# in mind that ls -t prints the *newest* file first.
+rm -f conftest.ts?
+: > conftest.ts1
+: > conftest.ts2
+: > conftest.ts3
+
+# Make sure ls -t actually works. Do 'set' in a subshell so we don't
+# clobber the current shell's arguments. (Outer-level square brackets
+# are removed by m4; they're present so that m4 does not expand
+# <dollar><star>; be careful, easy to get confused.)
+if (
+ set X `ls -t conftest.ts[12]` &&
+ {
+ test "$*" != "X conftest.ts1 conftest.ts2" ||
+ test "$*" != "X conftest.ts2 conftest.ts1";
+ }
+); then :; else
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ printf "%s\n" ""Bad output from ls -t: \"`ls -t conftest.ts[12]`\""" >&5
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "ls -t produces unexpected output.
+Make sure there is not a broken ls alias in your environment.
+See 'config.log' for more details" "$LINENO" 5; }
+fi
+
+for am_try_res in $am_try_resolutions; do
+ # Any one fine-grained sleep might happen to cross the boundary
+ # between two values of a coarser actual resolution, but if we do
+ # two fine-grained sleeps in a row, at least one of them will fall
+ # entirely within a coarse interval.
+ echo alpha > conftest.ts1
+ sleep $am_try_res
+ echo beta > conftest.ts2
+ sleep $am_try_res
+ echo gamma > conftest.ts3
+
+ # We assume that 'ls -t' will make use of high-resolution
+ # timestamps if the operating system supports them at all.
+ if (set X `ls -t conftest.ts?` &&
+ test "$2" = conftest.ts3 &&
+ test "$3" = conftest.ts2 &&
+ test "$4" = conftest.ts1); then
+ #
+ # Ok, ls -t worked. If we're at a resolution of 1 second, we're done,
+ # because we don't need to test make.
+ make_ok=true
+ if test $am_try_res != 1; then
+ # But if we've succeeded so far with a subsecond resolution, we
+ # have one more thing to check: make. It can happen that
+ # everything else supports the subsecond mtimes, but make doesn't;
+ # notably on macOS, which ships make 3.81 from 2006 (the last one
+ # released under GPLv2). https://bugs.gnu.org/68808
+ #
+ # We test $MAKE if it is defined in the environment, else "make".
+ # It might get overridden later, but our hope is that in practice
+ # it does not matter: it is the system "make" which is (by far)
+ # the most likely to be broken, whereas if the user overrides it,
+ # probably they did so with a better, or at least not worse, make.
+ # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html
+ #
+ # Create a Makefile (real tab character here):
+ rm -f conftest.mk
+ echo 'conftest.ts1: conftest.ts2' >conftest.mk
+ echo ' touch conftest.ts2' >>conftest.mk
+ #
+ # Now, running
+ # touch conftest.ts1; touch conftest.ts2; make
+ # should touch ts1 because ts2 is newer. This could happen by luck,
+ # but most often, it will fail if make's support is insufficient. So
+ # test for several consecutive successes.
+ #
+ # (We reuse conftest.ts[12] because we still want to modify existing
+ # files, not create new ones, per above.)
+ n=0
+ make=${MAKE-make}
+ until test $n -eq 3; do
+ echo one > conftest.ts1
+ sleep $am_try_res
+ echo two > conftest.ts2 # ts2 should now be newer than ts1
+ if $make -f conftest.mk | grep 'up to date' >/dev/null; then
+ make_ok=false
+ break # out of $n loop
+ fi
+ n=`expr $n + 1`
+ done
+ fi
+ #
+ if $make_ok; then
+ # Everything we know to check worked out, so call this resolution good.
+ am_cv_filesystem_timestamp_resolution=$am_try_res
+ break # out of $am_try_res loop
+ fi
+ # Otherwise, we'll go on to check the next resolution.
+ fi
+done
+rm -f conftest.ts?
+# (end _am_filesystem_timestamp_resolution)
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_filesystem_timestamp_resolution" >&5
+printf "%s\n" "$am_cv_filesystem_timestamp_resolution" >&6; }
+
+# This check should not be cached, as it may vary across builds of
+# different projects.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
printf %s "checking whether build environment is sane... " >&6; }
# Reject unsafe characters in $srcdir or the absolute working directory
@@ -3410,49 +3571,45 @@ esac
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
-if (
- am_has_slept=no
- for am_try in 1 2; do
- echo "timestamp, slept: $am_has_slept" > conftest.file
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
- alias in your environment" "$LINENO" 5
- fi
- if test "$2" = conftest.file || test $am_try -eq 2; then
- break
- fi
- # Just in case.
- sleep 1
- am_has_slept=yes
- done
- test "$2" = conftest.file
- )
-then
- # Ok.
- :
-else
- as_fn_error $? "newly created file is older than distributed files!
+am_build_env_is_sane=no
+am_has_slept=no
+rm -f conftest.file
+for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ test "$2" = conftest.file
+ ); then
+ am_build_env_is_sane=yes
+ break
+ fi
+ # Just in case.
+ sleep "$am_cv_filesystem_timestamp_resolution"
+ am_has_slept=yes
+done
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_build_env_is_sane" >&5
+printf "%s\n" "$am_build_env_is_sane" >&6; }
+if test "$am_build_env_is_sane" = no; then
+ as_fn_error $? "newly created file is older than distributed files!
Check your system clock" "$LINENO" 5
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
+
# If we didn't sleep, we still need to ensure time stamps of config.status and
# generated files are strictly newer.
am_sleep_pid=
-if grep 'slept: no' conftest.file >/dev/null 2>&1; then
- ( sleep 1 ) &
+if test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1
+then :
+
+else case e in #(
+ e) ( sleep "$am_cv_filesystem_timestamp_resolution" ) &
am_sleep_pid=$!
+ ;;
+esac
fi
rm -f conftest.file
@@ -3742,17 +3899,13 @@ else
fi
rmdir .tst 2>/dev/null
+AM_DEFAULT_VERBOSITY=1
# Check whether --enable-silent-rules was given.
if test ${enable_silent_rules+y}
then :
enableval=$enable_silent_rules;
fi
-case $enable_silent_rules in # (((
- yes) AM_DEFAULT_VERBOSITY=0;;
- no) AM_DEFAULT_VERBOSITY=1;;
- *) AM_DEFAULT_VERBOSITY=1;;
-esac
am_make=${MAKE-make}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
printf %s "checking whether $am_make supports nested variables... " >&6; }
@@ -3775,15 +3928,45 @@ esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
printf "%s\n" "$am_cv_make_support_nested_variables" >&6; }
-if test $am_cv_make_support_nested_variables = yes; then
- AM_V='$(V)'
- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
-else
- AM_V=$AM_DEFAULT_VERBOSITY
- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
-fi
AM_BACKSLASH='\'
+am__rm_f_notfound=
+if (rm -f && rm -fr && rm -rf) 2>/dev/null
+then :
+
+else case e in #(
+ e) am__rm_f_notfound='""' ;;
+esac
+fi
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking xargs -n works" >&5
+printf %s "checking xargs -n works... " >&6; }
+if test ${am_cv_xargs_n_works+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if test "`echo 1 2 3 | xargs -n2 echo`" = "1 2
+3"
+then :
+ am_cv_xargs_n_works=yes
+else case e in #(
+ e) am_cv_xargs_n_works=no ;;
+esac
+fi ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_xargs_n_works" >&5
+printf "%s\n" "$am_cv_xargs_n_works" >&6; }
+if test "$am_cv_xargs_n_works" = yes
+then :
+ am__xargs_n='xargs -n'
+else case e in #(
+ e) am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "" "$am__xargs_n_arg"; done; }'
+ ;;
+esac
+fi
+
@@ -5030,7 +5213,7 @@ else case e in #(
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # When given -MP, icc 7.0 and 7.1 complain thus:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
@@ -9276,47 +9459,9 @@ fi
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-Please tell bug-automake@gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <https://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
- fi
-fi
# am_maintainer_mode
@@ -9560,6 +9705,7 @@ esac
fi
: ${AR=ar}
+: ${ARFLAGS=cr}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
printf %s "checking the archiver ($AR) interface... " >&6; }
@@ -9580,7 +9726,7 @@ int some_variable = 0;
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
- am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+ am_ar_try='$AR $ARFLAGS libconftest.a conftest.$ac_objext >&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
(eval $am_ar_try) 2>&5
ac_status=$?
@@ -15679,7 +15825,7 @@ else case e in #(
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # When given -MP, icc 7.0 and 7.1 complain thus:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
@@ -21499,6 +21645,18 @@ printf %s "checking that generated files are newer than configure... " >&6; }
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5
printf "%s\n" "done" >&6; }
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+esac
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+
if test -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
diff --git a/biblio/bibtex/contrib/iran-bibtex/README.md b/biblio/bibtex/contrib/iran-bibtex/README.md
index 1da64ac767..355cdcfa9a 100644
--- a/biblio/bibtex/contrib/iran-bibtex/README.md
+++ b/biblio/bibtex/contrib/iran-bibtex/README.md
@@ -111,6 +111,14 @@ If you want to report any bugs or issues, please use [the issue tracker](https:/
## Change log
+### Version 0.4.3 (2024/08/4)
+
+ 1. Fixing a minor issue that surfaced in the previous update.
+
+### Version 0.4.2 (2024/08/2)
+
+ 1. Made some improvements.
+
### Version 0.4.1 (2024/05/6)
1. Made some improvements.
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.pdf b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.pdf
index c7aaac23d1..eab5543e69 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.pdf
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.pdf
Binary files differ
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.tex b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.tex
index 76ef420989..477390c391 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.tex
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-pattern.tex
@@ -18,7 +18,7 @@
\begin{document}
\title{خلاصه‌ای از الگوی چیدمان مشخصه‌ها در فهرست‌نویسی منبعها به شیوه‌ی استناددهی ایران}
\author{فرشاد رسولی\thanks{رایانامه: \url{farshad.rasuli@gmail.com}}}
-\date{نسخه‌ی ۰٫۴٫۱ --- ۱۷ اردیبهشت ۱۴۰۳}
+\date{نسخه‌ی ۰٫۴٫۳ --- ۱۴ اَمُرداد ۱۴۰۳}
\maketitle
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.pdf b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.pdf
index 382d98a821..7a4b5b22f9 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.pdf
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.pdf
Binary files differ
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.tex b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.tex
index c9e7da533d..a22e1f4691 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.tex
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex-userguide-fa.tex
@@ -1,7 +1,7 @@
\documentclass[a4paper,11pt]{article}
-\usepackage{color}
-\usepackage[usenames,dvpinames,table]{xcolor}
+\usepackage[usenames]{color}
+\usepackage{xcolor}
\usepackage{xecolor}
\usepackage{graphics}
\usepackage{graphicx}
@@ -46,7 +46,7 @@
\title{راهنمای کاربر بسته‌ی \lr{\bf\sffamily iran-bibtex}}
\author{فرشاد رسولی\thanks{رایانامه: \url{farshad.rasuli@gmail.com}}}
-\date{نسخه‌ی ۰٫۴٫۱ --- ۱۷ اردیبهشت ۱۴۰۳}
+\date{نسخه‌ی ۰٫۴٫۳ --- ۱۴ اَمُرداد ۱۴۰۳}
\maketitle
@@ -60,16 +60,13 @@
شیوه‌نامه‌ی ایران یک شیوه‌نامه‌ی فهرست‌نویسی منبعهای اطلاعاتی به زبان فارسی، و انگلیسی است که در سال ۱۳۹۵ توسط ایرانداک\زیرنویس{پژوهشگاه علوم و فناوری اطلاعات ایران} تهیه و منتشر شده است. این بسته با هدف پیاده‌سازی این شیوه‌نامه در سامانه‌ی لاتک برای استفاده در نوشتارهای فارسی، و انگلیسی آماده شده است.
-این بسته به گونه‌ای طراحی شده است که در نوشتارهای فارسی که با \XePersian{} آماده میشوند و نوشتارهای غیرفارسی که با موتورهای پردازش مختلف آماده میشوند نیز کاربرد دارد.
+این بسته به گونه‌ای طراحی شده است که در نوشتارهای فارسی که با \XePersian{} آماده شده و با موتور \XeTeX{} پردازش میشوند و نوشتارهای غیرفارسی که با دیگر موتورهای پردازش آماده میشوند کاربرد دارد.
برای استنادهای درون متنی، پیش‌نهاد شیوه‌نامه‌ی ایران استفاده از سبک پدیدآورنده-سال است؛ ولی از آن‌جایی که سبکهای استناددهی مختلفی در سامانه‌ی لاتک وجود دارد، با حفظ اصلهای این شیوه‌نامه در فهرست‌نویسی منبعهای اطلاعاتی، دیگر سبکهای استناددهی درون متنی مانند سبکهای شماره‌گذاری نیز افزوده شده است.
-\section{چگونگی فراخوانی، و استفاده از بسته}
-
-
-\subsection{فراخوانی بسته}
+\section{فراخوانی بسته}
برای فراخوانی بسته‌ی ایران-بیب‌تک کافی است این بسته را با این فرمان فراخوانی کنید:\\
\hspace*{\fill}\lr{\tt \textbackslash usepackage[<bibstyle>,<options>]\{iran-bibtex\}}
@@ -86,19 +83,22 @@
برای تولید خروجی نوشتارهای فارسی کافی است پرونده‌ی موردنظر را به این ترتیب پردازش کنید:
-\begin{itemize}[nosep]
-\begin{latin}
+\begin{itemize}[noitemsep, topsep=0pt]
+\begin{latinitems}
\item \texttt{xelatex file.tex}
\item \texttt{bibtex8 -W -c iran-bibtex-cp1256fa file}
\item \texttt{xelatex file.tex}
\item \texttt{xelatex file.tex}
-\end{latin}
+\end{latinitems}
\end{itemize}
-فرمان \م‌ل{\tt bibtex8 -W -c iran-bibtex-cp1256fa file} مرجعهای غیرفارسی را پس از مرجعهای فارسی فهرست میکند. اگر میخواهید که مرجعهای غیرفارسی در آغاز فهرست شوند فرمان \م‌ل{\tt bibtex8 file} را جایگزین کنید.
+فرمان \م‌ل{\tt bibtex8 -W -c iran-bibtex-cp1256fa file} مرجعهای غیرفارسی را پس از مرجعهای فارسی فهرست میکند. اگر میخواهید که مرجعهای غیرفارسی پیش از مرجعهای فارسی فهرست شوند فرمان \م‌ل{\tt bibtex8 file} را جایگزین کنید.
+
+
+\section{استفاده از بسته}
\subsection{سبکهای استناددهی آماده شده در این بسته}
@@ -169,14 +169,15 @@
+\newpage
\paragraph*{فرمان \lr{\tt \textbackslash citet} (استناد متنی)}~\\[0.5\baselineskip]
\begin{tabular}{ccc}
کیانی و همکاران (۱۳۹۵) &$\Rightarrow$& \lr{\tt \textbackslash citet\{key\}}\\
کیانی و همکاران (۱۳۹۵، فصل~۲) &$\Rightarrow$& \lr{\tt \textbackslash citet\rl{[فصل~۲]}\{key\}}\\
-ببینید کیانی و همکاران (۱۳۹۵، ص.~۱۰) &$\Rightarrow$& \lr{\tt \textbackslash citet\rl{[ص.~۱۰][ببینید]}\{key\}}\\
+کیانی و همکاران (ببینید ۱۳۹۵، ص.~۱۰) &$\Rightarrow$& \lr{\tt \textbackslash citet\rl{[ص.~۱۰][ببینید]}\{key\}}\\
کیانی، صفایی، رفیعی، و امانی (۱۳۹۵) &$\Rightarrow$& \lr{\tt \textbackslash citet*\{key\}}\\
کیانی، صفایی، رفیعی، و امانی (۱۳۹۵، فصل~۲) &$\Rightarrow$& \lr{\tt \textbackslash citet*\rl{[فصل~۲]}\{key\}}\\
-ببینید کیانی، صفایی، رفیعی، و امانی (۱۳۹۵، ص.~۱۰) &$\Rightarrow$& \lr{\tt \textbackslash citet*\rl{[ص.~۱۰][ببینید]}\{key\}}\\
+کیانی، صفایی، رفیعی، و امانی (ببینید ۱۳۹۵، ص.~۱۰) &$\Rightarrow$& \lr{\tt \textbackslash citet*\rl{[ص.~۱۰][ببینید]}\{key\}}\\
\end{tabular}
@@ -203,7 +204,7 @@
\subsection{مشخصه‌ی \lr{\tt language}}
-در این بسته، از مشخصه‌ی \م‌ل{\tt language} برای تعیین حروف‌چینی آن مرجع در فهرست مرجعها، و منبعها استفاده میشود. برای آن‌که مرجعی که به زبان فارسی است از راست به چپ حروف‌چینی شود، باید مشخصه‌ی \م‌ل{\tt language} آن مرجع برابر با \م‌ل{\tt persian} وارد گردد\زیرنویس{این مشخصه به بزرگی یا کوچکی حرفها حساس نیست}؛ در غیر این صورت، آن مرجع به عنوان مرجعی غیرفارسی فهرست میشود.
+در این بسته، از مشخصه‌ی \م‌ل{\tt language} برای تعیین حروف‌چینی آن مرجع در فهرست مرجعها، و منبعها استفاده میشود. برای آن‌که مرجعی که به زبان فارسی است از راست به چپ حروف‌چینی شود، باید مشخصه‌ی \م‌ل{\tt language} آن مرجع برابر با \م‌ل{\tt persian} وارد گردد\زیرنویس{این مشخصه به بزرگی یا کوچکی حرفها حساس نیست}؛ در غیر این صورت، آن مرجع به عنوان مرجعی غیرفارسی فهرست شده و حروف‌چینی میگردد.
\subsection{مشخصه‌ی \lr{\tt authorfa}}
@@ -212,9 +213,9 @@
\section{مثالهای استفاده از این بسته}
-شمار زیادی از مثالهای آورده شده در شیوه‌نامه‌ی ایران، که با استفاده از این بسته پیاده‌سازی شدند در مخزن گیت‌هاب این بسته به نشانی
+شمار زیادی از مثالهای ارائه شده در شیوه‌نامه‌ی ایران با استفاده از این بسته پیاده‌سازی شده‌اند. این مثالها در مخزن گیت‌هاب این بسته به نشانی
\href{https://github.com/farshadrasuli/iran-bibtex}{github.com/farshadrasuli/iran-bibtex}
-در پوشه‌ی \م‌ل{examples} آماده شده است که میتواند راهنمای بسیار خوبی برای یادگیری استفاده از این بسته در استفاده از شیوه‌نامه‌ی ایران باشد.
+در پوشه‌ی \م‌ل{examples} در دسترس هستند. این مثالها میتوانند راهنمای بسیار خوبی برای یادگیری این بسته در استفاده از شیوه‌نامه‌ی ایران باشند.
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex.sty b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex.sty
index 1cc11bf54d..9ee5b3525d 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-bibtex.sty
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-bibtex.sty
@@ -1,5 +1,5 @@
%%
-%% This is file “iran-bibtex.sty”, v0.4.1 (2024-05-06)
+%% This is file “iran-bibtex.sty”, v0.4.3 (2024-08-04)
%%
%% __________________________________________________
%% Copyright (c) 2023-2024 Farshad Rasuli
@@ -26,10 +26,10 @@
% === Package structure: Identification
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{iran-bibtex}
- [2024-05-06 v0.4.1 Iran Manual of Style (1st edn, 2016)]
+ [2024-08-04 v0.4.3 Iran Manual of Style (1st edn, 2016)]
-\def\iranbibtex@version{0.4.1}
-\def\iranbibtexdate{2024-05-06} % May 6th, 2024
+\def\iranbibtex@version{0.4.3}
+\def\iranbibtexdate{2024-08-04} % August 4th, 2024
\def\iranbibtexfirstrelease{2023-12-12} % December 12th, 2023
\edef\@iranbibtex@info{%
***************************************************************%
@@ -168,9 +168,9 @@
%% provide command for bibliography environment
\newcommand{\enquote}[1]{``#1''}
\newcommand{\faquote}[1]{«#1»}
-\providecommand{\url}[1]{{\tt #1}}
-\providecommand{\doi}[1]{\url{#1}}
-\providecommand{\eprint}[2][]{\url{#2}}
+\providecommand{\url}[1]{\@ifpackageloaded{hyperref}{\href{#1}{#1}}{\tt #1}}
+\providecommand{\doi}[1]{\@ifpackageloaded{hyperref}{\href{https://doi.org/#1}{#1}}{\url{#1}}}
+\providecommand{\eprint}[2][]{\@ifpackageloaded{hyperref}{\href{#2}{#2}}{\url{#2}}}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-unsrt.bst b/biblio/bibtex/contrib/iran-bibtex/iran-unsrt.bst
index cd7955b90a..b0092b30f4 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-unsrt.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-unsrt.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iran-unsrt.bst”, v0.1.1 (2024-05-06)
+%% This file is “iran-unsrt.bst”, v0.1.2 (2024/08/2)
%% generated with the DOCSTRIP utility, then modified to support
%% bilingual (English/Latin, and Persian/Farsi) in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016).
@@ -1932,7 +1932,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -2262,7 +2262,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran-year.bst b/biblio/bibtex/contrib/iran-bibtex/iran-year.bst
index cb7feac8ab..f02038c535 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran-year.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iran-year.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iran-year.bst”, v0.1.1 (2024-05-06)
+%% This file is “iran-year.bst”, v0.1.2 (2024/08/2)
%% generated with the DOCSTRIP utility, then modified to support
%% bilingual (English/Latin, and Persian/Farsi) in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016).
@@ -1973,7 +1973,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -2303,7 +2303,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iran.bst b/biblio/bibtex/contrib/iran-bibtex/iran.bst
index 7a76ceb1c9..2d384c5250 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iran.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iran.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iran.bst”, v0.4.1 (2024-05-06)
+%% This file is “iran.bst”, v0.4.2 (2024/08/2)
%% generated with the DOCSTRIP utility, then modified to support
%% bilingual (English/Latin, and Persian/Farsi) in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016).
@@ -1973,7 +1973,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -2303,7 +2303,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iranlatin-unsrt.bst b/biblio/bibtex/contrib/iran-bibtex/iranlatin-unsrt.bst
index e34c05b977..64915a09b0 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iranlatin-unsrt.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iranlatin-unsrt.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iranlatin-unsrt.bst”, v0.1.1 (2024-05-06)
+%% This file is “iranlatin-unsrt.bst”, v0.1.2 (2024/08/2)
%% created by modifying “iranlatin.bst” file in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016) to support
%% English/Latin only.
@@ -1528,7 +1528,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -1852,7 +1852,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iranlatin-year.bst b/biblio/bibtex/contrib/iran-bibtex/iranlatin-year.bst
index 045f3f3484..5792d53b4d 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iranlatin-year.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iranlatin-year.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iranlatin-year.bst”, v0.1.1 (2024-05-06)
+%% This file is “iranlatin-year.bst”, v0.1.2 (2024/08/2)
%% created by modifying “iranlatin.bst” file in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016) to support
%% English/Latin only.
@@ -1569,7 +1569,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -1893,7 +1893,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/contrib/iran-bibtex/iranlatin.bst b/biblio/bibtex/contrib/iran-bibtex/iranlatin.bst
index a5095e258c..b574953427 100644
--- a/biblio/bibtex/contrib/iran-bibtex/iranlatin.bst
+++ b/biblio/bibtex/contrib/iran-bibtex/iranlatin.bst
@@ -1,6 +1,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% This file is “iranlatin.bst”, v0.1.1 (2024-05-06)
+%% This file is “iranlatin.bst”, v0.1.2 (2024/08/2)
%% created by modifying “iran.bst” file in accordance with the
%% “Iran Manual of Style Citation Guide” (1st edn., 2016) to support
%% English/Latin only.
@@ -1569,7 +1569,7 @@ FUNCTION {field.doi}
doi empty$
{ "" }
{
- bbl.doi "u" change.case$ ":\doi{" * doi * "}" *
+ bbl.doi "u" change.case$ ":~\doi{" * doi * "}" *
}
if$
}
@@ -1893,7 +1893,7 @@ FUNCTION {field.url}
url duplicate$ empty$
{ pop$ "" }
{
- bbl.url "u" change.case$ ": \url{" * swap$ * "}" *
+ bbl.url "u" change.case$ ":~\url{" * swap$ * "}" *
}
if$
}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Changes b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Changes
new file mode 100644
index 0000000000..da5c2afb8e
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Changes
@@ -0,0 +1,86 @@
+Revision history for BibTeX::Parser
+
+1.04 2023-08-20 New release
+
+1.03 2022-11-06
+ Avoid extra spaces with von part. (Author.pm)
+ Add ' to re_namechar. (Parser.pm)
+
+1.02 2018-04-29 03:19:56 +0000
+ Corrected the bug when Jr is not accompanied by von.
+
+1.01 2017-11-19 03:12:34 +0000
+ New options for to_string:
+ - print_pre - whether to print text preceding the entry
+ - type_capitalization ('Uppercase', 'Lowercase',
+ 'Titlecase')
+ - field_capitalization ('Uppercase', 'Lowercase',
+ 'Titlecase')
+
+1.00 2017-03-18 21:53:15+00:00
+ Typo corrected: editors -> editor
+
+0.70 2016-11-23 02:28:35+00:00
+ Compatibility with perl 5.25 (Alexandr Ciornii)
+
+0.69 2016-03-24 15:13:50-04:00
+ Added option canonize_names to Entry::to_string
+
+0.68 2016-03-10 13:45:31-05:00
+ Now we preserve the order of entries
+
+0.67 2015-12-28 22:36:42+00:00
+ Corrected test t/13_output.t
+
+0.66 2015-12-23 19:52:55-05:00
+ Corrected bug 67419.
+ Added $entry->to_string function
+ No Do not remove braces from the authors' names
+
+0.65 2013-09-03 21:04:43
+ Add links in documentation.
+
+0.64 2012-03-10 22:23:50
+ Remove a warning about undefined value.
+
+0.63 2011-03-15 23:08:18
+ Parse files with errors (no keys, spaces in wrong positions). Bug #66325
+
+0.62 2010-10-15 08:52:53
+ Declare Test::More minimum version with done_testing
+
+0.61 2010-07-19 16:37:49
+ Add methods $entry->cleaned_author / cleaned_editor
+
+0.6 2010-07-19 14:43:15
+ Add method $entry->cleaned_field( 'name' )
+ Add prerequisite LaTeX::ToUnicode >= 0.02
+
+0.5 2010-07-06 13:17:45 Europe/Berlin
+ Do not attempt to clean up returned values
+ Author names with braces are split correctly
+
+0.4 2010-02-09
+ Parsing of quoted author names (e.g. "{Foo and Bar, Inc.}")
+
+0.3.2 2009-07-26
+ Removed dependency on Text::Balanced
+
+0.3.1 2009-07-19
+ No changes, removed huge test file from dist
+
+0.3 2009-07-18
+ Better parsing of author names,
+ new Method B::P::Entry->raw_bibtex
+ Removed Module::Install from package
+
+0.21 2009-01-23
+ Fixed errors in synopsis.
+
+0.2 2008-12-30
+ First public release.
+
+0.1 2008-03-14
+ First version, internal
+
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/LICENSE b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/LICENSE
new file mode 100644
index 0000000000..1a50e57d4d
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/LICENSE
@@ -0,0 +1,379 @@
+This software is copyright (c) 2013-2022 by Gerhard Gossen and Boris Veytsman and Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+Terms of the Perl programming language system itself
+
+a) the GNU General Public License as published by the Free
+ Software Foundation; either version 1, or (at your option) any
+ later version, or
+b) the "Artistic License"
+
+--- The GNU General Public License, Version 1, February 1989 ---
+
+This software is copyright (c) 2013-2016 by Gerhard Gossen and Boris Veytsman
+
+This is free software, licensed under:
+
+ The GNU General Public License, Version 1, February 1989
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must tell them their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License. The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+ 7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+ 8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+--- The Artistic License 1.0 ---
+
+This software is Copyright (c) 2013 by Gerhard Gossen.
+
+This is free software, licensed under:
+
+ The Artistic License 1.0
+
+The Artistic License
+
+Preamble
+
+The intent of this document is to state the conditions under which a Package
+may be copied, such that the Copyright Holder maintains some semblance of
+artistic control over the development of the package, while giving the users of
+the package the right to use and distribute the Package in a more-or-less
+customary fashion, plus the right to make reasonable modifications.
+
+Definitions:
+
+ - "Package" refers to the collection of files distributed by the Copyright
+ Holder, and derivatives of that collection of files created through
+ textual modification.
+ - "Standard Version" refers to such a Package if it has not been modified,
+ or has been modified in accordance with the wishes of the Copyright
+ Holder.
+ - "Copyright Holder" is whoever is named in the copyright or copyrights for
+ the package.
+ - "You" is you, if you're thinking about copying or distributing this Package.
+ - "Reasonable copying fee" is whatever you can justify on the basis of media
+ cost, duplication charges, time of people involved, and so on. (You will
+ not be required to justify it to the Copyright Holder, but only to the
+ computing community at large as a market that must bear the fee.)
+ - "Freely Available" means that no fee is charged for the item itself, though
+ there may be fees involved in handling the item. It also means that
+ recipients of the item may redistribute it under the same conditions they
+ received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications derived
+from the Public Domain or from the Copyright Holder. A Package modified in such
+a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided that
+you insert a prominent notice in each changed file stating how and when you
+changed that file, and provided that you do at least ONE of the following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or an
+ equivalent medium, or placing the modifications on a major archive site
+ such as ftp.uu.net, or by allowing the Copyright Holder to include your
+ modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict with
+ standard executables, which must also be provided, and provide a separate
+ manual page for each non-standard executable that clearly documents how it
+ differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or executable
+form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where to
+ get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of the Package
+ with your modifications.
+
+ c) accompany any non-standard executables with their corresponding Standard
+ Version executables, giving the non-standard executables non-standard
+ names, and clearly documenting the differences in manual pages (or
+ equivalent), together with instructions on where to get the Standard
+ Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package. You
+may not charge a fee for this Package itself. However, you may distribute this
+Package in aggregate with other (possibly commercial) programs as part of a
+larger (possibly commercial) software distribution provided that you do not
+advertise this Package as a product of your own.
+
+6. The scripts and library files supplied as input to or produced as output
+from the programs of this Package do not automatically fall under the copyright
+of this Package, but belong to whomever generated them, and may be sold
+commercially, and may be aggregated with this Package.
+
+7. C or perl subroutines supplied by you and linked into this Package shall not
+be considered part of this Package.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/MANIFEST b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/MANIFEST
new file mode 100644
index 0000000000..032eea6a15
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/MANIFEST
@@ -0,0 +1,44 @@
+LICENSE
+Changes
+MANIFEST
+t/pod.t
+t/cleaned_field.t
+t/release-pod-coverage.t
+t/bug67419.t
+t/09-complex.t
+t/bug66325.t
+t/07-parse_englishbib.t
+t/13_output.t
+t/01-parse.t
+t/14-extratext.t
+t/05-author.t
+t/08-parse_large.t
+t/release-pod-syntax.t
+t/12-von_token.t
+t/00-load.t
+t/11-split_braced.t
+t/02-parse_string.t
+t/04-entry.t
+t/03-parse_entry.t
+t/bibs/mathscinet.txt
+t/bibs/10-funnyname.bib
+t/bibs/english.bib
+t/bibs/braces.bib
+t/bibs/endnote.txt
+t/bibs/14-extratext.bib
+t/bibs/01.bib
+t/bibs/engineering_village.txt
+t/bibs/09-complex.bib
+t/bibs/06.bib
+t/pod-coverage.t
+t/10-funnyname.t
+t/15-capitalization.t
+t/06-parse_complex.t
+README
+notes
+lib/BibTeX/Parser/Author.pm
+lib/BibTeX/Parser/Entry.pm
+lib/BibTeX/Parser.pm
+Makefile.PL
+Makefile.TDS
+dist.ini
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.PL b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.PL
new file mode 100644
index 0000000000..77f3e53aed
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.PL
@@ -0,0 +1,71 @@
+
+use strict;
+use warnings;
+
+
+
+use ExtUtils::MakeMaker 6.30;
+
+
+
+my %WriteMakefileArgs = (
+ "ABSTRACT" => "A pure perl BibTeX parser",
+ "AUTHOR" => 'Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org',
+ "BUILD_REQUIRES" => {},
+ "CONFIGURE_REQUIRES" => {
+ "ExtUtils::MakeMaker" => "6.31"
+ },
+ "DISTNAME" => "BibTeX-Parser",
+ "EXE_FILES" => [],
+ "LICENSE" => "perl",
+ "NAME" => "BibTeX::Parser",
+ "PREREQ_PM" => {
+ "File::Spec" => 0,
+ "IO::File" => 0,
+ "IO::String" => 0,
+ "LaTeX::ToUnicode" => "0.55",
+ "Test::More" => "0.88"
+ },
+ "TEST_REQUIRES" => {
+ "Test::More" => "0.88"
+ },
+ 'VERSION_FROM' => 'lib/BibTeX/Parser.pm',
+ "test" => {
+ "TESTS" => "t/*.t"
+ }
+);
+
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
+ my $tr = delete $WriteMakefileArgs{TEST_REQUIRES};
+ my $br = $WriteMakefileArgs{BUILD_REQUIRES};
+ for my $mod ( keys %$tr ) {
+ if ( exists $br->{$mod} ) {
+ $br->{$mod} = $tr->{$mod} if $tr->{$mod} > $br->{$mod};
+ }
+ else {
+ $br->{$mod} = $tr->{$mod};
+ }
+ }
+}
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) {
+ my $br = delete $WriteMakefileArgs{BUILD_REQUIRES};
+ my $pp = $WriteMakefileArgs{PREREQ_PM};
+ for my $mod ( keys %$br ) {
+ if ( exists $pp->{$mod} ) {
+ $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod};
+ }
+ else {
+ $pp->{$mod} = $br->{$mod};
+ }
+ }
+}
+
+delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
+ unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
+
+WriteMakefile(%WriteMakefileArgs);
+
+
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.TDS b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.TDS
new file mode 100644
index 0000000000..dbe1a35c00
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/Makefile.TDS
@@ -0,0 +1,35 @@
+# This is Makefile for TDS-compliant TeX distributions
+# Written by Boris Veytsman, boris@varphi.com
+#
+# This file is in public domain
+#
+PREFIX = /usr/local
+
+LIBDIR = $(PREFIX)/scripts/bibtexperllibs
+
+DOCDIR = $(PREFIX)/doc/bibtex/bibtexperllibs
+
+all:
+
+docs:
+
+install:
+ mkdir -p $(LIBDIR)
+ cp -r lib/* $(LIBDIR)
+ mkdir -p $(DOCDIR)
+ cp -r man/man3/* $(DOCDIR)
+
+check test: Makefile
+# need bash pipefail so exit status is from the make, not the tr.
+# the -f Makefile is because of possible GNUmakefile -> Makefile.TDS symlink.
+ bash -c "set -o pipefail; \
+ env PERL5LIB=../LaTeX-ToUnicode/lib \
+ make -f Makefile test | tr '\r' '\n'"
+
+Makefile MYMETA.json MYMeta.yml: Makefile.PL force
+ perl Makefile.PL || rm -f $@
+
+clean distclean:
+ $(RM) -r Makefile MYMETA.* blib pm_to_blib *.tar.gz
+
+force:
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/README b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/README
new file mode 100644
index 0000000000..cb6f19b576
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/README
@@ -0,0 +1,9 @@
+This is the BibTeX::Parser Perl package:
+
+ A pure Perl BibTeX parser
+
+Copyright 2013--2023 Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/dist.ini b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/dist.ini
new file mode 100644
index 0000000000..bc60ca9352
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/dist.ini
@@ -0,0 +1,28 @@
+name = BibTeX-Parser
+version = 1.04
+author = Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org>
+license = Perl_5
+copyright_holder = Gerhard Gossen and Boris Veytsman and Karl Berry
+
+[@Classic]
+
+[NextRelease]
+format = %-7v %{yyyy-MM-dd HH:mm:ss}d
+
+[PodWeaver]
+
+[Prereqs]
+Test::More = 0
+IO::String = 0
+IO::File = 0
+File::Spec = 0
+LaTeX::ToUnicode = 0.11
+
+[Prereqs / TestRequires]
+Test::More = 0.88 ; for done_testing
+
+[PruneFiles]
+filenames = t/bibs/java.bib
+
+[Repository]
+[@Git]
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm
new file mode 100644
index 0000000000..fd7c67c862
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm
@@ -0,0 +1,367 @@
+package BibTeX::Parser;
+{
+ $BibTeX::Parser::VERSION = '1.05';
+}
+# ABSTRACT: A pure perl BibTeX parser
+use warnings;
+use strict;
+
+use BibTeX::Parser::Entry;
+
+
+my $re_namechar = qr/[a-zA-Z0-9\!\$\&\*\+\-\.\/\:\;\<\>\?\[\]\^\_\`\|\']/o;
+my $re_name = qr/$re_namechar+/o;
+
+
+sub new {
+ my ( $class, $fh ) = @_;
+
+ return bless {
+ fh => $fh,
+ strings => {
+ jan => "January",
+ feb => "February",
+ mar => "March",
+ apr => "April",
+ may => "May",
+ jun => "June",
+ jul => "July",
+ aug => "August",
+ sep => "September",
+ oct => "October",
+ nov => "November",
+ dec => "December",
+
+ },
+ line => -1,
+ buffer => "",
+ }, $class;
+}
+
+sub _slurp_close_bracket;
+
+sub _parse_next {
+ my $self = shift;
+
+ while (1) { # loop until regular entry is finished
+ return 0 if $self->{fh}->eof;
+ local $_ = $self->{buffer};
+
+ until (/@/m) {
+ my $line = $self->{fh}->getline;
+ return 0 unless defined $line;
+ $line =~ s/^%.*$//;
+ $_ .= $line;
+ }
+
+ my $current_entry = new BibTeX::Parser::Entry;
+ if (/@($re_name)/cgo) {
+ my $type = uc $1;
+ $current_entry->type( $type );
+ my $start_pos = pos($_) - length($type) - 1;
+
+ # read rest of entry (matches braces)
+ my $bracelevel = 0;
+ $bracelevel += tr/\{/\{/; #count braces
+ $bracelevel -= tr/\}/\}/;
+ while ( $bracelevel != 0 ) {
+ my $position = pos($_);
+ my $line = $self->{fh}->getline;
+ last unless defined $line;
+ $bracelevel =
+ $bracelevel + ( $line =~ tr/\{/\{/ ) - ( $line =~ tr/\}/\}/ );
+ $_ .= $line;
+ pos($_) = $position;
+ }
+
+ # Remember text before the entry
+ my $pre = substr($_, 0, $start_pos-1);
+ if ($start_pos == 0) {
+ $pre = '';
+ }
+ $current_entry->pre($pre);
+
+
+ # Remember raw bibtex code
+ my $raw = substr($_, $start_pos);
+ $raw =~ s/^\s+//;
+ $raw =~ s/\s+$//;
+ $current_entry->raw_bibtex($raw);
+
+ my $pos = pos $_;
+ tr/\n/ /;
+ pos($_) = $pos;
+
+ if ( $type eq "STRING" ) {
+ if (/\G\{\s*($re_name)\s*=\s*/cgo) {
+ my $key = $1;
+ my $value = _parse_string( $self->{strings} );
+ if ( defined $self->{strings}->{$key} ) {
+ warn("Redefining string $key!");
+ }
+ $self->{strings}->{$key} = $value;
+ /\G[\s\n]*\}/cg;
+ } else {
+ $current_entry->error("Malformed string!");
+ return $current_entry;
+ }
+ } elsif ( $type eq "COMMENT" or $type eq "PREAMBLE" ) {
+ /\G\{./cgo;
+ _slurp_close_bracket;
+ } else { # normal entry
+ $current_entry->parse_ok(1);
+
+ # parse key
+ if (/\G\s*\{(?:\s*($re_name)\s*,[\s\n]*|\s+\r?\s*)/cgo) {
+ $current_entry->key($1);
+
+ # fields
+ while (/\G[\s\n]*($re_name)[\s\n]*=[\s\n]*/cgo) {
+ $current_entry->field(
+ $1 => _parse_string( $self->{strings} ) );
+ my $idx = index( $_, ',', pos($_) );
+ pos($_) = $idx + 1 if $idx > 0;
+ }
+
+ return $current_entry;
+
+ } else {
+
+ $current_entry->error("Malformed entry (key contains illegal characters) at " . substr($_, pos($_) || 0, 20) . ", ignoring");
+ _slurp_close_bracket;
+ return $current_entry;
+ }
+ }
+
+ $self->{buffer} = substr $_, pos($_);
+
+ } else {
+ $current_entry->error("Did not find type at " . substr($_, pos($_) || 0, 20));
+ return $current_entry;
+ }
+
+ }
+}
+
+
+sub next {
+ my $self = shift;
+
+ return $self->_parse_next;
+}
+
+# slurp everything till the next closing brace. Handles
+# nested brackets
+sub _slurp_close_bracket {
+ my $bracelevel = 0;
+ BRACE: {
+ /\G[^\}]*\{/cg && do { $bracelevel++; redo BRACE };
+ /\G[^\{]*\}/cg
+ && do {
+ if ( $bracelevel > 0 ) {
+ $bracelevel--;
+ redo BRACE;
+ } else {
+ return;
+ }
+ }
+ }
+}
+
+# parse bibtex string in $_ and return. A BibTeX string is either enclosed
+# in double quotes '"' or matching braces '{}'. The braced form may contain
+# nested braces.
+sub _parse_string {
+ my $strings_ref = shift;
+
+ my $value = "";
+
+ PART: {
+ if (/\G(\d+)/cg) {
+ $value .= $1;
+ } elsif (/\G($re_name)/cgo) {
+ warn("Using undefined string $1") unless defined $strings_ref->{$1};
+ $value .= $strings_ref->{$1} || "";
+ } elsif (/\G"(([^"\\]*(\\.)*[^\\"]*)*)"/cgs)
+ { # quoted string with embeded escapes
+ $value .= $1;
+ } else {
+ my $part = _extract_bracketed( $_ );
+ $value .= substr $part, 1, length($part) - 2; # strip quotes
+ }
+
+ if (/\G\s*#\s*/cg) { # string concatenation by #
+ redo PART;
+ }
+ }
+ $value =~ s/[\s\n]+/ /g;
+ return $value;
+}
+
+sub _extract_bracketed
+{
+ for($_[0]) # alias to $_
+ {
+ /\G\s+/cg;
+ my $start = pos($_);
+ my $depth = 0;
+ while(1)
+ {
+ /\G\\./cg && next;
+ /\G\{/cg && (++$depth, next);
+ /\G\}/cg && (--$depth > 0 ? next : last);
+ /\G([^\\\{\}]+)/cg && next;
+ last; # end of string
+ }
+ return substr($_, $start, pos($_)-$start);
+ }
+}
+
+# Split the $string using $pattern as a delimiter with
+# each part having balanced braces (so "{$pattern}"
+# does NOT split).
+# Return empty list if unmatched braces
+
+sub _split_braced_string {
+ my $string = shift;
+ my $pattern = shift;
+ my @tokens;
+ return () if $string eq '';
+ my $buffer;
+ while (!defined pos $string || pos $string < length $string) {
+ if ( $string =~ /\G(.*?)(\{|$pattern)/cgi ) {
+ my $match = $1;
+ if ( $2 =~ /$pattern/i ) {
+ $buffer .= $match;
+ push @tokens, $buffer;
+ $buffer = "";
+ } elsif ( $2 =~ /\{/ ) {
+ $buffer .= $match . "{";
+ my $numbraces=1;
+ while ($numbraces !=0 && pos $string < length $string) {
+ my $symbol = substr($string, pos $string, 1);
+ $buffer .= $symbol;
+ if ($symbol eq '{') {
+ $numbraces ++;
+ } elsif ($symbol eq '}') {
+ $numbraces --;
+ }
+ pos($string) ++;
+ }
+ if ($numbraces != 0) {
+ return ();
+ }
+ } else {
+ $buffer .= $match;
+ }
+ } else {
+ $buffer .= substr $string, (pos $string || 0);
+ last;
+ }
+ }
+ push @tokens, $buffer if $buffer;
+ return @tokens;
+}
+
+
+1; # End of BibTeX::Parser
+
+
+__END__
+=pod
+
+=head1 NAME
+
+BibTeX::Parser - A pure perl BibTeX parser
+
+
+=head1 SYNOPSIS
+
+Parses BibTeX files.
+
+ use BibTeX::Parser;
+ use IO::File;
+
+ my $fh = IO::File->new("filename");
+
+ # Create parser object ...
+ my $parser = BibTeX::Parser->new($fh);
+
+ # ... and iterate over entries
+ while (my $entry = $parser->next ) {
+ if ($entry->parse_ok) {
+ my $type = $entry->type;
+ my $title = $entry->field("title");
+
+ my @authors = $entry->author;
+ # or:
+ my @editors = $entry->editor;
+
+ foreach my $author (@authors) {
+ print $author->first . " "
+ . $author->von . " "
+ . $author->last . ", "
+ . $author->jr;
+ }
+ } else {
+ warn "Error parsing file: " . $entry->error;
+ }
+ }
+
+
+
+=head1 FUNCTIONS
+
+=head2 new
+
+Creates new parser object.
+
+Parameters:
+
+ * fh: A filehandle
+
+=head2 next
+
+Returns the next parsed entry or undef.
+
+
+=head1 NOTES
+
+The fields C<author> and C<editor> are canonicalized, see
+L<BibTeX::Parser::Author>.
+
+
+=head1 SEE ALSO
+
+=over 4
+
+=item
+
+L<BibTeX::Parser::Entry>
+
+=item
+
+L<BibTeX::Parser::Author>
+
+=back
+
+=head1 VERSION
+
+version 1.04
+
+
+=head1 AUTHOR
+
+Gerhard Gossen <gerhard.gossen@googlemail.com> and
+Boris Veytsman <boris@varphi.com> and
+Karl Berry <karl@freefriends.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2013-2024 by Gerhard Gossen and Boris Veytsman and Karl Berry.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm
new file mode 100644
index 0000000000..a35e2073a6
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm
@@ -0,0 +1,429 @@
+package BibTeX::Parser::Author;
+{
+ $BibTeX::Parser::Author::VERSION = '1.04';
+}
+
+use warnings;
+use strict;
+
+use BibTeX::Parser;
+
+
+use overload
+ '""' => \&to_string;
+
+
+
+sub new {
+ my $class = shift;
+
+ if (@_) {
+ my $self = [ $class->split(@_) ];
+ return bless $self, $class;
+ } else {
+ return bless [], $class;
+ }
+}
+
+sub _get_or_set_field {
+ my ($self, $field, $value) = @_;
+ if (defined $value) {
+ $self->[$field] = $value;
+ } else {
+ return $self->[$field];
+ }
+}
+
+
+sub first {
+ shift->_get_or_set_field(0, @_);
+}
+
+
+sub von {
+ shift->_get_or_set_field(1, @_);
+}
+
+
+sub last {
+ shift->_get_or_set_field(2, @_);
+}
+
+
+sub jr {
+ shift->_get_or_set_field(3, @_);
+}
+
+
+# Take a string and create an array [first, von, last, jr]
+sub split {
+ my ($self_or_class, $name) = @_;
+
+ # remove whitespace at start and end of string
+ $name =~ s/^\s*(.*)\s*$/$1/s;
+
+
+
+ if (!length($name)) {
+ return (undef, undef, undef, undef);
+ }
+
+ my @comma_separated =
+ BibTeX::Parser::_split_braced_string($name,
+ '\s*,\s*');
+ if (scalar(@comma_separated) == 0) {
+ # Error?
+ return (undef, undef, undef, undef);
+ }
+
+ my $first=undef;
+ my $von=undef;
+ my $last=undef;
+ my $jr=undef;
+
+ if (scalar(@comma_separated) == 1) {
+ # First von Last form
+ my @tokens =
+ BibTeX::Parser::_split_braced_string($name, '\s+');
+ if (!scalar (@tokens)) {
+ return (undef, undef, undef, undef);
+ }
+ my ($start_von, $start_last) = _getStartVonLast (@tokens);
+ if ($start_von >0) {
+ $first = join(' ', splice(@tokens,0,$start_von));
+ }
+ if (($start_last-$start_von) >0) {
+ $von = join(' ', splice(@tokens,0,$start_last-$start_von));
+ }
+ $last = join(' ',@tokens);
+ return ($first, $von, $last, $jr);
+ }
+ # Now we work with von Last, [Jr,] First form
+ if (scalar @comma_separated == 2) { # no jr
+ my @tokens=
+ BibTeX::Parser::_split_braced_string($comma_separated[1], '\s+');
+ $first = join(' ', @tokens);
+ } else { # jr is present
+ my @tokens=
+ BibTeX::Parser::_split_braced_string($comma_separated[1], '\s+');
+ $jr = join(' ', @tokens);
+ @tokens=
+ BibTeX::Parser::_split_braced_string($comma_separated[2], '\s+');
+ $first = join(' ', @tokens);
+ }
+ my @tokens =
+ BibTeX::Parser::_split_braced_string($comma_separated[0], '\s+');
+ my $start_last = _getStartLast(@tokens);
+ if ($start_last > 0) {
+ $von=join(' ', splice(@tokens,0,$start_last));
+ }
+ $last = join(' ',@tokens);
+ return ($first, $von, $last, $jr);
+
+}
+
+# Return the index of the first von element and the first lastname
+# element. If no von element, von=last
+
+sub _getStartVonLast {
+ my $length=scalar(@_);
+ if ($length==1) {
+ return (0,0);
+ }
+ my $start_von=-1;
+ my $start_last=$length-1;
+ for (my $i=0; $i<$length; $i++) {
+ if (_is_von_token($_[$i])) {
+ $start_von=$i;
+ last;
+ }
+ }
+ if ($start_von== -1) { # no von part
+ return($length-1, $length-1);
+ }
+ if ($start_von== $length-1) { # all parts but last are upper case?
+ return($length-1, $length-1);
+ }
+ for (my $i=$start_von+1; $i<$length; $i++) {
+ if (!_is_von_token($_[$i])) {
+ $start_last=$i;
+ last;
+ }
+ }
+ return($start_von, $start_last);
+}
+
+
+# Return the index of the first lastname
+# element provided no first name elements are present
+
+sub _getStartLast {
+ my $length=scalar(@_);
+ if ($length==1) {
+ return 0;
+ }
+ my $start_last=$length-1;
+ for (my $i=0; $i<$length; $i++) {
+ if (!_is_von_token($_[$i])) {
+ $start_last=$i;
+ last;
+ }
+ }
+ return $start_last;
+}
+
+
+sub _split_name_parts {
+ my $name = shift;
+
+ if ( $name !~ /\{/ ) {
+ return split /\s+/, $name;
+ } else {
+ my @parts;
+ my $cur_token = '';
+ while ( scalar( $name =~ /\G ( [^\s\{]* ) ( \s+ | \{ | \s* $ ) /xgc ) ) {
+ $cur_token .= $1;
+ if ( $2 =~ /\{/ ) {
+ if ( scalar( $name =~ /\G([^\}]*)\}/gc ) ) {
+ $cur_token .= "{$1}";
+ } else {
+ die "Unmatched brace in name '$name'";
+ }
+ } else {
+ if ( $cur_token =~ /^{(.*)}$/ ) {
+ $cur_token = $1;
+ }
+ push @parts, $cur_token;
+ $cur_token = '';
+ }
+ }
+ return @parts;
+ }
+
+}
+
+
+sub _get_single_author_from_tokens {
+ my (@tokens) = @_;
+ if (@tokens == 0) {
+ return (undef, undef, undef, undef);
+ } elsif (@tokens == 1) { # name without comma
+ if ( $tokens[0] =~ /(^|\s)[[:lower:]]/) { # name has von part or has only lowercase names
+ my @name_parts = _split_name_parts $tokens[0];
+
+ my $first;
+ while (@name_parts && ucfirst($name_parts[0]) eq $name_parts[0] ) {
+ $first .= $first ? ' ' . shift @name_parts : shift @name_parts;
+ }
+
+ my $von;
+ # von part are lowercase words
+ while ( @name_parts && lc($name_parts[0]) eq $name_parts[0] ) {
+ $von .= $von ? ' ' . shift @name_parts : shift @name_parts;
+ }
+
+ if (@name_parts) {
+ return ($first, $von, join(" ", @name_parts), undef);
+ } else {
+ return (undef, undef, $tokens[0], undef);
+ }
+ } else {
+ if ( $tokens[0] !~ /\{/ && $tokens[0] =~ /^((.*)\s+)?\b(\S+)$/) {
+ return ($2, undef, $3, undef);
+ } else {
+ my @name_parts = _split_name_parts $tokens[0];
+ return ($name_parts[0], undef, $name_parts[1], undef);
+ }
+ }
+
+ } elsif (@tokens == 2) {
+ my @von_last_parts = _split_name_parts $tokens[0];
+ my $von;
+ # von part are lowercase words
+ while ( @von_last_parts && lc($von_last_parts[0]) eq $von_last_parts[0] ) {
+ $von .= $von ? ' ' . shift @von_last_parts : shift @von_last_parts;
+ }
+ return ($tokens[1], $von, join(" ", @von_last_parts), undef);
+ } else {
+ my @von_last_parts = _split_name_parts $tokens[0];
+ my $von;
+ # von part are lowercase words
+ while ( @von_last_parts && lc($von_last_parts[0]) eq $von_last_parts[0] ) {
+ $von .= $von ? ' ' . shift @von_last_parts : shift @von_last_parts;
+ }
+ return ($tokens[2], $von, join(" ", @von_last_parts), $tokens[1]);
+ }
+
+}
+
+
+
+# The goal is to return a name in form
+# von Last, Jr, First
+# where any of the parts except Last may be empty.
+#
+sub to_string {
+ my $self = shift;
+
+ my $last = $self->last; # assume always present
+ my $first = $self->first ? (", " . $self->first) : ''; # ", first"
+ my $von = $self->von ? ($self->von . " ") : ''; # "von "
+ my $jr = $self->jr ? (", " . $self->jr ) : ''; # ", jr"
+ #
+ my $ret = "${von}${last}${jr}${first}";
+ #warn "returning name: $ret\n";
+ return $ret;
+
+# original code, which introduced a spurious space with a von part.
+# https://github.com/borisveytsman/crossrefware/issues/11
+#
+# if ($self->jr) {
+# return () . " " . $self->last . ", " . $self->jr . ", " . $self->first;
+# } else {
+# return ($self->von ? $self->von . " " : '') . $self->last . ($self->first ? ", " . $self->first : '');
+# }
+#
+}
+
+
+# Return 1 if the first letter on brace level 0 is lowercase
+sub _is_von_token {
+ my $string = shift;
+ while ($string =~
+ s/^(\\[[:alpha:]]+\{|\{|\\[[:^alpha:]]?|[[:^alpha:]])//) {
+ if ($1 eq '{' ) {
+ my $numbraces=1;
+ while ($numbraces !=0 && length($string)) {
+ my $symbol = substr($string, 0, 1);
+ if ($symbol eq '{') {
+ $numbraces ++;
+ } elsif ($symbol eq '}') {
+ $numbraces --;
+ }
+ $string = substr($string,1);
+ }
+ }
+ }
+
+ if (length $string ) {
+ my $symbol = substr($string, 0, 1);
+ if (lc($symbol) eq $symbol) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return 1;
+ }
+
+}
+
+1; # End of BibTeX::Entry
+
+__END__
+=pod
+
+=head1 NAME
+
+BibTeX::Author - Contains a single author for a BibTeX document.
+
+=head1 SYNOPSIS
+
+This class ist a wrapper for a single BibTeX author. It is usually created
+by a BibTeX::Parser.
+
+ use BibTeX::Parser::Author;
+
+ my $entry = BibTeX::Parser::Author->new($full_name);
+
+ my $firstname = $author->first;
+ my $von = $author->von;
+ my $last = $author->last;
+ my $jr = $author->jr;
+
+ # or ...
+
+ my ($first, $von, $last, $jr) = BibTeX::Author->split($fullname);
+
+
+
+=head1 FUNCTIONS
+
+=head2 new
+
+Create new author object. Expects full name as parameter.
+
+=head2 first
+
+Set or get first name(s).
+
+=head2 von
+
+Set or get 'von' part of name.
+
+=head2 last
+
+Set or get last name(s).
+
+=head2 jr
+
+Set or get 'jr' part of name.
+
+=head2 split
+
+Split name into (firstname, von part, last name, jr part). Returns array
+with four strings, some of them possibly empty.
+
+=head2 to_string
+
+Return string representation of the name.
+
+=head1 NOTES
+
+BibTeX allows three representations of a person's name:
+
+=over 4
+
+=item 1.
+
+First von Last
+
+=item 2.
+
+von Last, First
+
+=item 3.
+
+von Last, Jr, First
+
+=back
+
+The module always converts the first form to the second of third one
+to allow simple string comparisons.
+
+The algorithm to determine the von part is the following: von part
+consists of tokens where the first letter at brace level 0 is in lower case.
+Anything in a "special characters" is on brace level 0. Thus the following
+tokens are considered von parts: C<von>, C<\NOOP{von}Von>, and
+the following token is not: C<{von}>
+
+=head1 VERSION
+
+version 1.04
+
+
+=head1 AUTHOR
+
+Gerhard Gossen <gerhard.gossen@googlemail.com> and
+Boris Veytsman <boris@varphi.com> and
+Karl Berry <karl@freefriends.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2013--2023 by Gerhard Gossen and Boris Veytsman and Karl Berry.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm
new file mode 100644
index 0000000000..3ee6b2e404
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm
@@ -0,0 +1,443 @@
+package BibTeX::Parser::Entry;
+{
+ $BibTeX::Parser::Entry::VERSION = '1.04';
+}
+
+use warnings;
+use strict;
+
+use BibTeX::Parser;
+use BibTeX::Parser::Author;
+
+
+
+sub new {
+ my ($class, $type, $key, $parse_ok, $fieldsref) = @_;
+
+ my %fields = defined $fieldsref ? %$fieldsref : ();
+ my $i=0;
+ foreach my $field (keys %fields) {
+ if ($field !~ /^_/) {
+ $fields{_fieldnums}->{$field}=$i;
+ $i++;
+ }
+ }
+ if (defined $type) {
+ $fields{_type} = uc($type);
+ }
+ $fields{_key} = $key;
+ $fields{_parse_ok} = $parse_ok;
+ $fields{_raw} = '';
+ return bless \%fields, $class;
+}
+
+
+
+sub parse_ok {
+ my $self = shift;
+ if (@_) {
+ $self->{_parse_ok} = shift;
+ }
+ $self->{_parse_ok};
+}
+
+
+sub error {
+ my $self = shift;
+ if (@_) {
+ $self->{_error} = shift;
+ $self->parse_ok(0);
+ }
+ return $self->parse_ok ? undef : $self->{_error};
+}
+
+
+sub type {
+ if (scalar @_ == 1) {
+ # get
+ my $self = shift;
+ return $self->{_type};
+ } else {
+ # set
+ my ($self, $newval) = @_;
+ $self->{_type} = uc($newval);
+ }
+}
+
+
+sub key {
+ if (scalar @_ == 1) {
+ # get
+ my $self = shift;
+ return $self->{_key};
+ } else {
+ # set
+ my ($self, $newval) = @_;
+ $self->{_key} = $newval;
+ }
+
+}
+
+
+sub field {
+ if (scalar @_ == 2) {
+ # get
+ my ($self, $field) = @_;
+ return $self->{ lc( $field ) };
+ } else {
+ my ($self, $key, $value) = @_;
+ my $field = lc ($key);
+ $self->{$field} = $value; #_sanitize_field($value);
+ if (!exists($self->{_fieldnums}->{$field})) {
+ my $num = scalar keys %{$self->{_fieldnums}};
+ $self->{_fieldnums}->{$field} = $num;
+ }
+ }
+
+}
+
+use LaTeX::ToUnicode qw( convert );
+
+
+sub cleaned_field {
+ my ( $self, $field, @options ) = @_;
+ if ( $field =~ /author|editor/i ) {
+ return $self->field( $field );
+ } else {
+ return convert( $self->field( lc $field ), @options );
+ }
+}
+
+
+sub cleaned_author {
+ my $self = shift;
+ $self->_handle_cleaned_author_editor( [ $self->author ], @_ );
+}
+
+
+sub cleaned_editor {
+ my $self = shift;
+ $self->_handle_cleaned_author_editor( [ $self->editor ], @_ );
+}
+
+sub _handle_cleaned_author_editor {
+ my ( $self, $authors, @options ) = @_;
+ map {
+ my $author = $_;
+ my $new_author = BibTeX::Parser::Author->new;
+ map {
+ $new_author->$_( convert( $author->$_, @options ) )
+ } grep { defined $author->$_ } qw( first von last jr );
+ $new_author;
+ } @$authors;
+}
+
+no LaTeX::ToUnicode;
+
+sub _handle_author_editor {
+ my $type = shift;
+ my $self = shift;
+ if (@_) {
+ if (@_ == 1) { #single string
+ # my @names = split /\s+and\s+/i, $_[0];
+ $_[0] =~ s/^\s*//;
+ $_[0] =~ s/\s*$//;
+ my @names = BibTeX::Parser::_split_braced_string($_[0],
+ '\s+and\s+');
+ if (!scalar @names) {
+ $self->error('Bad names in author/editor field');
+ return;
+ }
+ $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names];
+ $self->field($type, join " and ", @{$self->{"_$type"}});
+ } else {
+ $self->{"_$type"} = [];
+ foreach my $param (@_) {
+ if (ref $param eq "BibTeX::Author") {
+ push @{$self->{"_$type"}}, $param;
+ } else {
+ push @{$self->{"_$type"}}, new BibTeX::Parser::Author $param;
+ }
+
+ $self->field($type, join " and ", @{$self->{"_$type"}});
+ }
+ }
+ } else {
+ unless ( defined $self->{"_$type"}) {
+ my @names = BibTeX::Parser::_split_braced_string($self->{$type} || "", '\s+and\s+' );
+ $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names];
+ }
+ return @{$self->{"_$type"}};
+ }
+}
+
+
+
+sub author {
+ _handle_author_editor('author', @_);
+}
+
+
+sub editor {
+ _handle_author_editor('editor', @_);
+}
+
+
+sub fieldlist {
+ my $self = shift;
+
+ return grep {!/^_/} keys %$self;
+}
+
+
+sub has {
+ my ($self, $field) = @_;
+
+ return defined $self->{$field};
+}
+
+sub _sanitize_field {
+ my $value = shift;
+ for ($value) {
+ tr/\{\}//d;
+ s/\\(?!=[ \\])//g;
+ s/\\\\/\\/g;
+ }
+ return $value;
+}
+
+
+
+sub raw_bibtex {
+ my $self = shift;
+ if (@_) {
+ $self->{_raw} = shift;
+ }
+ return $self->{_raw};
+}
+
+sub pre {
+ my $self = shift;
+ if (@_) {
+ $self->{_pre} = shift;
+ }
+ return $self->{_pre};
+}
+
+
+sub to_string {
+ my $self = shift;
+ my %options=@_;
+ if (!exists($options{canonize_names})) {
+ $options{canonize_names}=1;
+ }
+ my @fields = grep {!/^_/} keys %$self;
+ @fields = sort {
+ $self->{_fieldnums}->{$a} <=>
+ $self->{_fieldnums}->{$b}} @fields;
+ my $result = '';
+ if ($options{print_pre}) {
+ $result .= $self->pre()."\n";
+ }
+ my $type = $self->type;
+ if (exists($options{type_capitalization})) {
+ if ($options{type_capitalization} eq 'Lowercase') {
+ $type = lc $type;
+ }
+ if ($options{type_capitalization} eq 'Titlecase') {
+ $type = ucfirst lc $type;
+ }
+ }
+ print STDERR $self->key, "\n";
+ $result .= '@'.$type."{".$self->key.",\n";
+ foreach my $field (@fields) {
+ my $value = $self->field($field);
+ if ($field eq 'author' && $options{canonize_names}) {
+ my @names = ($self->author);
+ $value = join(' and ', @names);
+ }
+ if ($field eq 'editor' && $options{canonize_names}) {
+ my @names = ($self->editor);
+ $value = join(' and ', @names);
+ }
+ if (exists($options{field_capitalization})) {
+ if ($options{field_capitalization} eq 'Uppercase') {
+ $field = uc $field;
+ }
+ if ($options{field_capitalization} eq 'Titlecase') {
+ $field = ucfirst $field;
+ }
+ }
+ $result .= " $field = {"."$value"."},\n";
+ }
+ $result .= "}";
+ return $result;
+}
+
+1; # End of BibTeX::Entry
+
+__END__
+=pod
+
+=head1 NAME
+
+BibTeX::Parser::Entry - Contains a single entry of a BibTeX document.
+
+=head1 SYNOPSIS
+
+This class is a wrapper for a single BibTeX entry. It is usually created
+by BibTeX::Parser.
+
+ use BibTeX::Parser::Entry;
+
+ my $entry = BibTeX::Parser::Entry->new($type, $key, $parse_ok, \%fields);
+
+ if ($entry->parse_ok) {
+ my $type = $entry->type;
+ my $key = $enty->key;
+ print $entry->field("title");
+ my @authors = $entry->author;
+ my @editors = $entry->editor;
+
+ ...
+
+ print $entry->to_string;
+ }
+
+
+=head1 FUNCTIONS
+
+=head2 new
+
+Create new entry.
+
+=head2 parse_ok
+
+If the entry was correctly parsed, this method returns a true value, false otherwise.
+
+=head2 error
+
+Return the error message, if the entry could not be parsed or undef otherwise.
+
+=head2 type
+
+Get or set the type of the entry, eg. 'ARTICLE' or 'BOOK'. Return value is
+always uppercase.
+
+=head2 key
+
+Get or set the reference key of the entry.
+
+=head2 field($name [, $value])
+
+Get or set the contents of a field. The first parameter is the name of the
+field, the second (optional) value is the new value.
+
+=head2 cleaned_field($name)
+
+Retrieve the contents of a field in a format that is cleaned of TeX markup.
+
+=head2 cleaned_author
+
+Get an array of L<BibTeX::Parser::Author> objects for the authors of this
+entry. Each name has been cleaned of accents and braces.
+
+=head2 cleaned_editor
+
+Get an array of L<BibTeX::Parser::Author> objects for the editors of this
+entry. Each name has been cleaned of accents and braces.
+
+=head2 author([@authors])
+
+Get or set the authors. Returns an array of L<BibTeX::Author|BibTeX::Author>
+objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects
+or strings.
+
+Note: You can also change the authors with $entry->field('author', $authors_string)
+
+=head2 editor([@editors])
+
+Get or set the editors. Returns an array of L<BibTeX::Author|BibTeX::Author>
+objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects
+or strings.
+
+Note: You can also change the authors with $entry->field('editor', $editors_string)
+
+=head2 fieldlist ()
+
+Returns a list of all the fields used in this entry.
+
+=head2 has($fieldname)
+
+Returns a true value if this entry has a value for $fieldname.
+
+=head2 pre ()
+
+Return the text in BibTeX file before the entry
+
+=head2 raw_bibtex ()
+
+Return raw BibTeX entry (if available).
+
+=head2 to_string ([options])
+
+Returns a text of the BibTeX entry in BibTeX format. Options are
+a hash.
+
+The return string is the entry reformated with lines indented by 4
+spaces and the @entrytype uppercased. Example:
+
+ @BOOK{Knuth:TAOCP1,
+ author = {Knuth, Donald E.},
+ publisher = {Addison-Wesley},
+ title = {The Art of Computer Programming},
+ year = {1968},
+ url = {https://www-cs-faculty.stanford.edu/~knuth/taocp.html},
+ }
+
+=over 4
+
+=item C<canonize_names>
+
+If true (the default), authors' and editors'
+names are translated into canonical bibtex form. The command
+C<$entry-E<gt>to_string(canonize_names=E<gt>0)> overrides this behavior.
+
+=item C<field_capitalization>
+
+Capitalization of the field names.
+Can take values 'Uppercase', 'Lowercase' (the default) or 'Titlecase'
+
+=item C<print_pre>
+
+False by default. If true, the text in the Bib file before the
+entry is printed. Note that at present we assume the text
+before the entry NEVER has the @ symbol inside
+
+=item C<type_capitalization>
+
+Capitalization of the type names.
+Can take values 'Uppercase' (the default), 'Lowercase' or 'Titlecase'
+
+
+=back
+
+=head1 VERSION
+
+version 1.05
+
+=head1 AUTHOR
+
+Gerhard Gossen <gerhard.gossen@googlemail.com> and
+Boris Veytsman <boris@varphi.com> and
+Karl Berry <karl@freefriends.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2013-2024 by Gerhard Gossen and Boris Veytsman and Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/notes b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/notes
new file mode 100644
index 0000000000..5e41df4090
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/notes
@@ -0,0 +1,26 @@
+from Biblio::Catalog::BibTeX :
+
+sub tex2html {
+ my $latex = shift;
+ return "" unless defined($latex);
+
+ for ($latex) {
+ s/\\textit\{([^{]+)\}/<i>$1<\/i>/g;
+ s/\\textbf\{([^{]+)\}/<b>$1<\/b>/g;
+ s/\\texttt\{([^{]+)\}/<tt>$1<\/tt>/g;
+ s/\\emph{([^{]+)}/<i>$1<\/i>/g;
+ s/\\item\b/<li>/g;
+ s/\\_/_/g;
+ s/\\mbox{([^}]+)}/$1/g;
+ s/{\\it\s([^}]+)}/<i>$1<\/i>/g;
+ s/\\LaTeX/LaTeX/g;
+ s/\\begin{itemize}/<ul>/g;
+ s/\\begin{quote}/<blockquote><i>/g;
+ s/\\end{quote}/<\/i><\/blockquote>/g;
+ s/\\end{itemize}/<\/ul>/g;
+ s/[}{]//g;
+ }
+
+ return $latex;
+}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/00-load.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/00-load.t
new file mode 100644
index 0000000000..9862dc7986
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/00-load.t
@@ -0,0 +1,11 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 3;
+
+BEGIN {
+ use_ok( 'BibTeX::Parser' );
+ use_ok( 'BibTeX::Parser::Author' );
+ use_ok( 'BibTeX::Parser::Entry' );
+}
+
+diag( "Testing BibTeX::Parser $BibTeX::Parser::VERSION, Perl $], $^X" );
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/01-parse.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/01-parse.t
new file mode 100644
index 0000000000..70e298d4be
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/01-parse.t
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 11;
+
+use BibTeX::Parser;
+use IO::File;
+
+use constant ENTRIES => 1;
+
+my $fh = new IO::File "t/bibs/01.bib", "r" ;
+
+if (defined $fh) {
+ my $parser = new BibTeX::Parser $fh;
+
+ isa_ok($parser, "BibTeX::Parser");
+
+ my $count = 0;
+
+ while (my $entry = $parser->next) {
+ $count++;
+ isa_ok($entry, "BibTeX::Parser::Entry");
+ is($entry->key, "key01", "key");
+ is($entry->type, "ARTICLE", "type");
+ ok($entry->parse_ok, "parse_ok");
+ is($entry->field("year"), 1950, "field");
+ is($entry->field("month"), "January~1", "field");
+
+ my @authors = $entry->author;
+ is(scalar @authors, 2, "#authors");
+ isa_ok($authors[0], "BibTeX::Parser::Author");
+ is("$authors[0]", "Duck, Donald", "correct author");
+ }
+
+ is($count, ENTRIES, "number of entries");
+}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t
new file mode 100644
index 0000000000..90b87eba14
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 7;
+
+use BibTeX::Parser;
+
+my %strings = ();
+
+$_ = 1234;
+parse_ok("parse digit string");
+
+$_ = '"simple double quoted string"';
+parse_is("simple double quoted string", "- double quoted string");
+
+$_ = '"double quotes { with embeded } brackets"';
+parse_is("double quotes { with embeded } brackets", "- with embeded brackets");
+
+$_ = '"string 1 " # "string 2"';
+parse_is("string 1 string 2", "- concatenation");
+
+$strings{test} = "string";
+$strings{other} = "text";
+
+$_ = "test";
+parse_is("string", "- string variable");
+
+$_ = "test # other";
+parse_is("stringtext", "- concatenation of string variables");
+
+$_ = '"M{\"{u}}nchen"';
+parse_is('M{\"{u}}nchen', "- escaped quote");
+
+sub parse_ok {
+ is(BibTeX::Parser::_parse_string(\%strings), $_, shift);
+}
+
+sub parse_is {
+ is(BibTeX::Parser::_parse_string(\%strings), shift, shift);
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t
new file mode 100644
index 0000000000..6b4e4632bc
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 3;
+
+use IO::String;
+use BibTeX::Parser;
+
+{
+ my $string = q|@article{lin1973,
+ author = "Shen Lin and Brian W. Kernighan",
+ title = "An Effective Heuristic Algorithm for the Travelling-Salesman Problem",
+ journal = "Operations Research",
+ volume = 21,
+ year = 1973,
+ pages = "498--516"
+ }|;
+ my $fh = IO::String->new($string);
+
+ my $parser = BibTeX::Parser->new( $fh );
+
+#my @result = BibTeX::Parser->_parse($fh);
+
+ my $entry = $parser->next;
+
+ is_deeply($entry, {_type => 'ARTICLE', _key => 'lin1973', author => "Shen Lin and Brian W. Kernighan",
+ title => "An Effective Heuristic Algorithm for the Travelling-Salesman Problem",
+ journal => "Operations Research",
+ volume => 21,
+ year => 1973,
+ pages => "498--516", _parse_ok => 1,
+ _fieldnums => {'author' => 0, 'title' => 1,
+ 'journal' => 2, 'volume' => 3,
+ 'year' => 4, 'pages' => 5},
+ _pre => '',
+ _raw => $string}, "parse \@ARTICLE");
+
+}
+{
+ my $string1 = q|@article{lin1973,
+ author = "Shen Lin and Brian W. Kernighan",
+ title = "An Effective Heuristic Algorithm for the Travelling-Salesman Problem",
+ journal = "Operations Research",
+ volume = 21,
+ year = 1973,
+ pages = "498--516"
+ }|;
+ my $string = "some
+text
+$string1";
+ my $fh = IO::String->new($string);
+
+ my $parser = BibTeX::Parser->new( $fh );
+
+#my @result = BibTeX::Parser->_parse($fh);
+
+ my $entry = $parser->next;
+
+ is_deeply($entry, {_type => 'ARTICLE', _key => 'lin1973', author => "Shen Lin and Brian W. Kernighan",
+ title => "An Effective Heuristic Algorithm for the Travelling-Salesman Problem",
+ journal => "Operations Research",
+ volume => 21,
+ year => 1973,
+ pages => "498--516", _parse_ok => 1,
+ _fieldnums => {'author' => 0, 'title' => 1,
+ 'journal' => 2, 'volume' => 3,
+ 'year' => 4, 'pages' => 5},
+ _pre => "some\ntext",
+ _raw => $string1}, "parse \@ARTICLE");
+
+}
+{
+ my $string = q|@InProceedings{Herper:2001:MVS,
+ author = {Henry Herper},
+ title = {{M}odellierung von {S}ystemen: ein
+ {A}pplikationsgebiet im {I}nformatikunterricht},
+ booktitle = {Informatikunterricht und Medienbildung, INFOS 2001
+ (9. Fachtagung Informatik und Schule, Paderborn
+ 17.-20- September 2001) -- Tagungsband},
+ editor = {Reinhard Keil-Slavik and Johannes Magenheim},
+ year = {2001},
+}|;
+ my $fh = IO::String->new($string);
+
+ my $parser = BibTeX::Parser->new( $fh );
+
+ my $entry = $parser->next;
+
+ is_deeply($entry, {
+ _type => 'INPROCEEDINGS',
+ _key => 'Herper:2001:MVS',
+ _fieldnums => {'author' => 0, 'title' => 1,
+ 'booktitle' => 2, 'editor' => 3,
+ 'year' => 4},
+ author => "Henry Herper",
+ title => "{M}odellierung von {S}ystemen: ein {A}pplikationsgebiet im {I}nformatikunterricht",
+ booktitle => "Informatikunterricht und Medienbildung, INFOS 2001 (9. Fachtagung Informatik und Schule, Paderborn 17.-20- September 2001) -- Tagungsband",
+ editor => "Reinhard Keil-Slavik and Johannes Magenheim",
+ year => 2001,
+ _parse_ok => 1,
+ _pre => '',
+ _raw => $string}, "parse \@ARTICLE");
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/04-entry.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/04-entry.t
new file mode 100644
index 0000000000..3ca9797011
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/04-entry.t
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 13;
+
+use BibTeX::Parser::Entry;
+
+
+my $entry = new BibTeX::Parser::Entry("type", "key", 1, {title => "title"});
+
+isa_ok($entry, "BibTeX::Parser::Entry");
+
+is($entry->type, "TYPE", "Entry::type get");
+
+$entry->type("newtype");
+
+is($entry->type, "NEWTYPE", "Entry::type set");
+
+is($entry->key, "key", "Entry::key get");
+
+$entry->key("newkey");
+
+is($entry->key, "newkey", "Entry::key set");
+
+is($entry->field("title"), "title", "Entry::field with new");
+
+$entry->field("title" => "newtitle");
+
+is($entry->field("title"), "newtitle", "Entry::field overwrite");
+
+$entry->field("year" => 2008);
+
+is($entry->field("year"), 2008, "Entry::field set");
+
+is($entry->field("pages"), undef, "Entry::field undef on unknown value");
+
+is($entry->fieldlist, 2, "size of fieldlist");
+
+ok($entry->has("title"), "Entry::has true on known value");
+
+ok($entry->has("year"), "Entry::has true on known value");
+
+ok( ! $entry->has("pages"), "Entry::has false on unknown value");
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/05-author.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/05-author.t
new file mode 100644
index 0000000000..45bc5413df
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/05-author.t
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+use Test::More;
+
+use BibTeX::Parser::Author;
+
+# Names from Mittelbach, Goossens: The LaTeX Companion, Second Edition.
+my %names = (
+ "Donald E. Knuth" => ["Donald E.", undef, "Knuth", undef],
+ "John Chris Smith" => ["John Chris", undef, "Smith", undef],
+ "Smith, John Chris" => ["John Chris", undef, "Smith", undef],
+ "Thomas von Neumann" => ["Thomas", "von", "Neumann", undef],
+ "von Neumann, Thomas" => ["Thomas", "von", "Neumann", undef],
+ "Lopez Fernandez, Miguel" => ["Miguel", undef, "Lopez Fernandez", undef],
+ "Pierre de la Porte" => ["Pierre", "de la", "Porte", undef],
+ "Smith, Jr., Robert" => ["Robert", undef, "Smith", "Jr."],
+ "von Smith, Jr., Robert" => ["Robert", "von", "Smith", "Jr."],
+ "Johannes Martinus Albertus van de Groene Heide" => ["Johannes Martinus Albertus", "van de", "Groene Heide", undef],
+ "Maria-Victoria Delgrande" => ["Maria-Victoria", undef, "Delgrande", undef],
+ "Anonymous" => [undef, undef, "Anonymous", undef],
+ "von Neumann" => [undef, "von", "Neumann", undef],
+ "N. Tetteh-Lartey" => ["N.", undef, "Tetteh-Lartey", undef],
+ "von Tetteh-Lartey, N." => ["N.", "von", "Tetteh-Lartey", undef],
+ "von Tetteh-Lartey, Jr., N." => ["N.", "von", "Tetteh-Lartey", "Jr."],
+ "" => [undef, undef, undef, undef],
+ " " => [undef, undef, undef, undef],
+ "\n" => [undef, undef, undef, undef],
+ "al." => [undef, undef, "al.", undef],
+ "et.~al." => [undef, undef, "et.~al.", undef],
+ "O'Malley, A." => ["A.", undef, "O'Malley", undef],
+ "A. O'Malley" => ["A.", undef, "O'Malley", undef],
+ "Arthur O'Malley" => ["Arthur", undef, "O'Malley", undef],
+ "O'Malley, Arthur" => ["Arthur", undef, "O'Malley", undef],
+ 'L.M. M\"uller' => ["L.M.", undef, 'M\"uller', undef],
+ 'M\"uller, L.M.' => ["L.M.", undef, 'M\"uller', undef],
+ 'L.M. M"uller' => ["L.M.", undef, 'M"uller', undef],
+ 'M"uller, L.M.' => ["L.M.", undef, 'M"uller', undef],
+ 'van Beethoven, Ludwig' => ["Ludwig", "van", "Beethoven", undef ],
+ '{Barnes and Noble, Inc.}' => [undef, undef, '{Barnes and Noble, Inc.}', undef],
+ "Ludwigg {van Beethoven}" => ["Ludwigg", undef, "{van Beethoven}", undef],
+ '{van Beethoven}, Ludwig' => ["Ludwig", undef, "{van Beethoven}", undef ],
+);
+
+plan tests => (keys(%names) * 6 + 5);
+
+my $author = new BibTeX::Parser::Author;
+
+isa_ok($author, "BibTeX::Parser::Author", "Correct type");
+
+is($author->first, undef, "Initial state 'first'");
+is($author->von, undef, "Initial state 'von'");
+is($author->last, undef, "Initial state 'last'");
+is($author->jr, undef, "Initial state 'jr'");
+
+
+foreach my $name (keys %names) {
+
+ is_deeply([BibTeX::Parser::Author->split($name)], $names{$name}, $name =~ /\w/ ? $name : "whitespace name: '$name'" );
+
+ $author = new BibTeX::Parser::Author $name;
+
+ isa_ok($author, "BibTeX::Parser::Author");
+
+ is($author->first, $names{$name}->[0] );
+ is($author->von, $names{$name}->[1]);
+ is($author->last, $names{$name}->[2]);
+ is($author->jr, $names{$name}->[3]);
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t
new file mode 100644
index 0000000000..95a5848a71
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+
+use Test::More tests => 19;
+
+use strict;
+use IO::File;
+use BibTeX::Parser;
+
+my $fh = IO::File->new("t/bibs/06.bib");
+
+my $parser = new BibTeX::Parser $fh;
+
+
+my $entry = $parser->next;
+
+isa_ok($entry, 'BibTeX::Parser::Entry', "Correct type");
+ok($entry->parse_ok, "Entry parsed correctly");
+is($entry->type, "ARTICLE", "BibTeX type is correct");
+is($entry->field("title"), "Paper title", "Title attribute");
+is($entry->field("year"), 2008);
+is($entry->field("month"), "August", "Month expansion");
+is($entry->key, 'key1', "key");
+
+my @authors = $entry->author;
+is(scalar @authors, 2, "number of authors correct");
+my $author = shift @authors;
+is_deeply(
+ [$author->first, $author->von, $author->last, $author->jr],
+ ['Gerhard', undef, 'Gossen', undef], "author correct");
+
+$author = shift @authors;
+is_deeply(
+ [$author->first, $author->von, $author->last, $author->jr],
+ ['Ludwig', 'van', 'Beethoven', undef], "author correct");
+
+$entry = $parser->next;
+isa_ok($entry, 'BibTeX::Parser::Entry', "Correct type");
+ok($entry->parse_ok, "Entry parsed correctly");
+is($entry->type, "BOOK", "BibTeX type is correct");
+is($entry->field("title"), "Book title", "Title attribute");
+is($entry->field("year"), 2008);
+is($entry->field("month"), "August", "Month expansion");
+is($entry->key, 'key2', "key");
+@authors = $entry->author;
+is(scalar @authors, 1, "number of authors");
+is(scalar $entry->editor, 0, "number of editors");
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t
new file mode 100644
index 0000000000..3348a55248
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use Test::More tests => 8;
+
+use strict;
+use IO::File;
+use BibTeX::Parser;
+
+
+my $fh = IO::File->new("t/bibs/english.bib");
+
+my $parser = new BibTeX::Parser $fh;
+
+my $count = 0;
+
+my $entry = $parser->next;
+
+is($entry->parse_ok, 0, "Ignore spurious @ before parenthesis");
+
+$entry = $parser->next;
+
+is($entry->parse_ok, 0, "Ignore spurious @ in email address");
+
+$entry = $parser->next;
+
+is(scalar $entry->author, 1, "# authors");
+#@BOOK{Carey,
+# AUTHOR="G. V. Carey",
+is($entry->field("title"), "Mind the Stop: A Brief Guide to Punctuation", "title");
+is($entry->field("publisher"), "Penguin", "publisher");
+is($entry->field("year"), 1958, "year");
+$count++;
+
+while ($entry = $parser->next) {
+ $count++;
+ if ($count == 8) {
+ is( scalar $entry->author, 4, 'Last entry has 4 authors');
+ }
+}
+
+
+is($count, 8, "number of entries");
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t
new file mode 100644
index 0000000000..5375d9a062
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+
+use Test::More skip_all => "Performance test", tests => 1;
+
+use IO::File;
+use BibTeX::Parser;
+
+my $starttime = time;
+
+my $fh = IO::File->new('t/bibs/java.bib'); #cl-nlp8x.bib');
+
+my $parser = new BibTeX::Parser $fh;
+my $entries = 0;
+
+#my @result = BibTeX::Parser->_parse($fh);
+
+while(my $entry = $parser->next) {
+ $entries++;
+}
+
+my $parsetime = time - $starttime;
+
+warn "Parsed $entries entries in $parsetime seconds";
+ok(1, "Parsed $entries entries in $parsetime seconds");
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/09-complex.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/09-complex.t
new file mode 100644
index 0000000000..56ce75cceb
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/09-complex.t
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 1;
+
+use IO::File;
+use BibTeX::Parser;
+
+
+my $fh = IO::File->new('t/bibs/09-complex.bib');
+
+my $parser = new BibTeX::Parser $fh;
+
+#my @result = BibTeX::Parser->_parse($fh);
+
+my $entry = $parser->next;
+
+is_deeply($entry, {_type => 'ARTICLE', _key => 'Ahrenberg88',
+ author => "L. Ahrenberg and A. Jonsson",
+ title => "An interactive system for tagging dialogues",
+ journal => 'Literary \& Linguistic Computing',
+ volume => 3,
+ number => "2",
+ pages => "66--70",
+ year => "1988",
+ keywords => "conver",
+ _fieldnums => {'author' => 0, 'title' => 1,
+ 'journal' => 2, 'volume' => 3,
+ 'number' => 4, 'pages'=> 5,
+ 'year' => 6, 'keywords' => 7},
+ _parse_ok => 1,
+ _raw => '@Article{Ahrenberg88,
+ author = "L. Ahrenberg and A. Jonsson",
+ title = "An interactive system for tagging dialogues",
+ journal = "Literary \& Linguistic Computing",
+ volume = "3",
+ number = "2",
+ pages = "66--70",
+ year = "1988",
+ keywords = "conver",
+}',
+ _pre => ''
+ }, "parse \@ARTICLE");
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t
new file mode 100644
index 0000000000..8ab48396e9
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 11;
+
+use IO::File;
+use BibTeX::Parser;
+
+my $fh = IO::File->new('t/bibs/10-funnyname.bib');
+
+my $parser = BibTeX::Parser->new($fh);
+
+#my @result = BibTeX::Parser->_parse($fh);
+
+my $entry = $parser->next;
+
+is_deeply(
+ $entry,
+ {
+ _type => 'ARTICLE',
+ _key => 'testkey',
+ author => 'A. Bar and L.M. M\"uller',
+ title => 'foo',
+ journal => 'journal',
+ volume => 1,
+ number => 1,
+ pages => 1,
+ year => 2008,
+ _parse_ok => 1,
+ _fieldnums => {'year' => 0, 'title' => 1,
+ 'author' => 2, 'journal' => 3,
+ 'volume' => 4, 'number'=> 5,
+ 'pages' => 6},
+ _raw => '@article{testkey,
+ year = {2008},
+ title = "foo",
+ author = {A. Bar and L.M. M\"uller},
+ journal = {journal},
+ volume = {1},
+ number = {1},
+ pages = {1},
+}',
+ _pre => ''
+ },
+ "parse \@ARTICLE"
+);
+
+my @authors = $entry->author;
+
+pass("->author didn't loop forever");
+ok(@authors == 2, "Two authors");
+
+is($authors[0]->first, 'A.', "A1 first name");
+is($authors[0]->last, 'Bar', "A1 last name");
+ok(!$authors[0]->von, "A1 no 'von'");
+ok(!$authors[0]->jr, "A1 no 'jr'");
+
+is($authors[1]->first, 'L.M.', "A2 first name");
+is($authors[1]->last, 'M\"uller', "A2 last name");
+ok(!$authors[1]->von, "A2 no 'von'");
+ok(!$authors[1]->jr, "A2 no 'jr'");
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t
new file mode 100644
index 0000000000..85a29be86f
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t
@@ -0,0 +1,28 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 12;
+
+use BibTeX::Parser;
+use IO::File;
+
+my @tokens = BibTeX::Parser::_split_braced_string("a and b", '\s+and\s+');
+is(scalar @tokens,2);
+is($tokens[0],'a');
+is($tokens[1],'b');
+
+@tokens = BibTeX::Parser::_split_braced_string("a {and} b", '\s+and\s+');
+is(scalar @tokens,1);
+is($tokens[0],'a {and} b');
+
+@tokens = BibTeX::Parser::_split_braced_string("a {and b", '\s+and\s+');
+is(scalar @tokens,0);
+
+@tokens = BibTeX::Parser::_split_braced_string("} a {", '\s+');
+is(scalar @tokens,0);
+
+@tokens = BibTeX::Parser::_split_braced_string("{a b} c {d}e u", '\s+');
+is(scalar @tokens,4);
+is($tokens[0],'{a b}');
+is($tokens[1],'c');
+is($tokens[2],'{d}e');
+is($tokens[3],'u');
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/12-von_token.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/12-von_token.t
new file mode 100644
index 0000000000..6daceafa96
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/12-von_token.t
@@ -0,0 +1,12 @@
+#!/usr/bin/perl -w
+
+use Test::More tests => 5;
+
+use BibTeX::Parser::Author;
+use IO::File;
+
+is(BibTeX::Parser::Author::_is_von_token('von'),1);
+is(BibTeX::Parser::Author::_is_von_token('Von'),0);
+is(BibTeX::Parser::Author::_is_von_token('\noop{von}Von'),1);
+is(BibTeX::Parser::Author::_is_von_token('\noop{Von}von'),0);
+is(BibTeX::Parser::Author::_is_von_token('\noop{AE}{\AE}schylus'),0);
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/13_output.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/13_output.t
new file mode 100644
index 0000000000..02fb1cd26f
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/13_output.t
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+
+use Test::More;
+
+use BibTeX::Parser;
+use IO::File;
+
+
+my $fh = new IO::File "t/bibs/01.bib", "r" ;
+
+my $parser = new BibTeX::Parser $fh;
+
+
+
+
+while (my $entry = $parser->next) {
+ if($entry->key eq 'key01') {
+ my $result1='@ARTICLE{key01,
+ year = {1950},
+ author = {Duck, Donald and Else, Someone},
+ editor = {Itor, E. D. and Other, A. N.},
+ title = {Title text},
+ month = {January~1},
+}';
+ my $result2='@ARTICLE{key01,
+ year = {1950},
+ author = {Donald Duck and Someone Else},
+ editor = {E. D. Itor and A. N. Other},
+ title = {Title text},
+ month = {January~1},
+}';
+ is($entry->to_string,$result1);
+ is($entry->to_string(canonize_names=>0),$result2);
+ }
+
+}
+
+done_testing();
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/14-extratext.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/14-extratext.t
new file mode 100644
index 0000000000..0a663b043a
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/14-extratext.t
@@ -0,0 +1,65 @@
+#!/usr/bin/perl -w
+
+
+use Test::More tests => 6;
+
+use BibTeX::Parser;
+use IO::File;
+
+
+my $fh = new IO::File "t/bibs/14-extratext.bib", "r" ;
+
+my $parser = new BibTeX::Parser $fh;
+
+
+
+
+while (my $entry = $parser->next) {
+
+ if($entry->key eq 'Partridge') {
+ my $result1= '@BOOK{Partridge,
+ author = {Partridge, Eric},
+ title = {Use and Abuse: a Guide to Good {E}nglish},
+ publisher = {Hamish Hamilton},
+ edition = {4},
+ year = {1970},
+}';
+ my $result2 = "First published in 1947\n$result1";
+ is($entry->to_string,$result1);
+ is($entry->to_string(print_pre=>1),$result2);
+ }
+
+ if ($entry->key eq 'Cooper') {
+ my $result1 = '@BOOK{Cooper,
+ author = {Cooper, Bruce M.},
+ title = {Writing Technical Reports},
+ publisher = {Penguin},
+ year = {1964},
+}';
+ my $result2 = "\n\n$result1";
+ is($entry->to_string,$result1);
+ is($entry->to_string(print_pre=>1),$result2);
+ }
+
+
+ if ($entry->key eq 'Fowler-ModernEnglish') {
+
+ my $result1 = '@BOOK{Fowler-ModernEnglish,
+ author = {Fowler, H. W.},
+ title = {[A Dictionary of] Modern {E}nglish Usage},
+ publisher = {Oxford University Press},
+ edition = {2},
+ year = {1965},
+}';
+ my $result2 = '
+
+
+First published in 1926
+'. $result1;
+ is($entry->to_string,$result1);
+ is($entry->to_string(print_pre=>1),$result2);
+ }
+}
+
+done_testing();
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t
new file mode 100644
index 0000000000..4254f5c12f
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t
@@ -0,0 +1,72 @@
+#!/usr/bin/perl -w
+
+use Test::More tests=>7;
+
+use BibTeX::Parser;
+use IO::File;
+
+
+my $fh = new IO::File "t/bibs/01.bib", "r" ;
+
+my $parser = new BibTeX::Parser $fh;
+
+
+
+
+while (my $entry = $parser->next) {
+ if($entry->key eq 'key01') {
+ my $result1='@ARTICLE{key01,
+ year = {1950},
+ author = {Duck, Donald and Else, Someone},
+ editor = {Itor, E. D. and Other, A. N.},
+ title = {Title text},
+ month = {January~1},
+}';
+ my $result2='@ARTICLE{key01,
+ YEAR = {1950},
+ AUTHOR = {Duck, Donald and Else, Someone},
+ EDITOR = {Itor, E. D. and Other, A. N.},
+ TITLE = {Title text},
+ MONTH = {January~1},
+}';
+ my $result3='@ARTICLE{key01,
+ Year = {1950},
+ Author = {Duck, Donald and Else, Someone},
+ Editor = {Itor, E. D. and Other, A. N.},
+ Title = {Title text},
+ Month = {January~1},
+}';
+ my $result4='@article{key01,
+ year = {1950},
+ author = {Duck, Donald and Else, Someone},
+ editor = {Itor, E. D. and Other, A. N.},
+ title = {Title text},
+ month = {January~1},
+}';
+ my $result5='@Article{key01,
+ year = {1950},
+ author = {Duck, Donald and Else, Someone},
+ editor = {Itor, E. D. and Other, A. N.},
+ title = {Title text},
+ month = {January~1},
+}';
+ is($entry->to_string,$result1);
+ is($entry->to_string(field_capitalization=>'Lowercase'),
+ $result1);
+ is($entry->to_string(field_capitalization=>'Uppercase'),
+ $result2);
+ is($entry->to_string(field_capitalization=>'Titlecase'),
+ $result3);
+
+ is($entry->to_string(type_capitalization=>'Lowercase'),
+ $result4);
+ is($entry->to_string(type_capitalization=>'Uppercase'),
+ $result1);
+ is($entry->to_string(type_capitalization=>'Titlecase'),
+ $result5);
+ }
+
+}
+
+done_testing();
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib
new file mode 100644
index 0000000000..7f6233d177
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib
@@ -0,0 +1,7 @@
+@ARTICLE{key01,
+ year = 1950,
+ author = {Donald Duck and Someone Else},
+ editor = {E. D. Itor and A. N. Other},
+ title = {Title text},
+ month = jan # "~1"
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib
new file mode 100644
index 0000000000..242ae662cc
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib
@@ -0,0 +1,27 @@
+this is text, which is ignored by bibtex.
+
+@PREAMBLE{
+ This is only used for BibTeX files used in LaTeX documents
+}
+
+@Comment{
+ Comments are ignored too.
+}
+
+@ARTICLE{key1,
+ author = {Gerhard Gossen and Ludwig van Beethoven},
+ title = "Paper title",
+ year = 2008,
+ month = aug,
+}
+
+@STRING{ gerhard = "Gerhard" }
+
+@STRING{ gossen = "Gossen" }
+
+@BOOK{ key2,
+ author = gerhard # " " # gossen,
+ title = "Book title",
+ year = "2008",
+ month = aug,
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib
new file mode 100644
index 0000000000..cacf322723
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib
@@ -0,0 +1,11 @@
+@Article{Ahrenberg88,
+ author = "L. Ahrenberg and A. Jonsson",
+ title = "An interactive system for tagging dialogues",
+ journal = "Literary \& Linguistic Computing",
+ volume = "3",
+ number = "2",
+ pages = "66--70",
+ year = "1988",
+ keywords = "conver",
+}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib
new file mode 100644
index 0000000000..050fbc0534
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib
@@ -0,0 +1,10 @@
+@article{testkey,
+ year = {2008},
+ title = "foo",
+ author = {A. Bar and L.M. M\"uller},
+ journal = {journal},
+ volume = {1},
+ number = {1},
+ pages = {1},
+}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib
new file mode 100644
index 0000000000..56f96aa01b
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib
@@ -0,0 +1,22 @@
+First published in 1947
+@BOOK{Partridge,
+ AUTHOR="Eric Partridge",
+ TITLE="Use and Abuse: a Guide to Good {E}nglish",
+ PUBLISHER="Hamish Hamilton",
+ EDITION="4", YEAR="1970"}
+
+
+@BOOK{Cooper,
+ AUTHOR="Bruce M. Cooper",
+ TITLE="Writing Technical Reports",
+ PUBLISHER="Penguin", YEAR="1964"}
+
+
+
+First published in 1926
+@BOOK{Fowler-ModernEnglish,
+ AUTHOR="H. W. Fowler",
+ TITLE="[A Dictionary of] Modern {E}nglish Usage",
+ PUBLISHER="Oxford University Press",
+ EDITION="2", YEAR="1965"}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib
new file mode 100644
index 0000000000..3791fb5760
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib
@@ -0,0 +1,21 @@
+@Article{scholkopf98kpca,
+ author = {Bernhard {Sch\"olkopf} and Alex Smola and K.R. Muller},
+ title = {Nonlinear component analysis as a kernel eigenvalue
+problem},
+ journal = {Neural Computation},
+ year = {1998},
+ volume = {10},
+ pages = {1299--1319}
+}
+
+@article{brownetal93,
+ author = {Peter F. Brown and Stephen A. {Della Pietra} and
+ Vincent J. {Della Pietra} and Robert~L. Mercer},
+ title = {The Mathematics of Statistical Machine Translation:
+ Parameter Estimation},
+ journal = {Computational Linguistics},
+ year = 1993,
+ volume = 19,
+ number = 2,
+ pages = {263-311}
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt
new file mode 100644
index 0000000000..e75f1d2050
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt
@@ -0,0 +1,6 @@
+@article{
+ volume = {59},
+ number = {6},
+ year = {1999}
+}
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt
new file mode 100644
index 0000000000..256f5a853d
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt
@@ -0,0 +1,24 @@
+@inproceedings{1997493856789 ,
+language = {English},
+year = {1997},
+}
+
+
+@inproceedings{1998043944915 ,
+language = {English},
+year = {1997},
+}
+
+
+@article{2003137419501 ,
+language = {English},
+year = {2002},
+}
+
+
+@inproceedings{2002367072517 ,
+language = {English},
+year = {2002},
+}
+
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib
new file mode 100644
index 0000000000..f0f097409f
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib
@@ -0,0 +1,55 @@
+$Id: @(#) english.bib 1.0 23-OCT-1989 17:10:00 Aston archive$
+
+Please notify Adrian F Clark <alien@uk.ac.essex.ese> of any additions
+or corrections to this list.
+
+@BOOK{Carey,
+ AUTHOR="G. V. Carey",
+ TITLE="Mind the Stop: A Brief Guide to Punctuation",
+ PUBLISHER="Penguin", YEAR="1958"}
+
+@BOOK{Cooper,
+ AUTHOR="Bruce M. Cooper",
+ TITLE="Writing Technical Reports",
+ PUBLISHER="Penguin", YEAR="1964"}
+
+@BOOK{Fowler-ModernEnglish,
+ AUTHOR="H. W. Fowler",
+ TITLE="[A Dictionary of] Modern {E}nglish Usage",
+ PUBLISHER="Oxford University Press",
+ EDITION="2", YEAR="1965"}
+ (but first published in 1926)
+
+@BOOK{Fowler-KingsEnglish,
+ AUTHOR="H. W. Fowler and F. G. Fowler",
+ TITLE="The {K}ing's {E}nglish",
+ PUBLISHER="Oxford University Press",
+ EDITION="3", YEAR="1931"}
+ (but first published in 1906)
+
+@BOOK{Gowers,
+ AUTHOR="Sir Ernest Gowers",
+ TITLE="The Complete Plain Words",
+ PUBLISHER="Penguin", YEAR="1954"}
+ (but first published by HMSO)
+
+@BOOK{Hart,
+ AUTHOR="Horace Hart",
+ TITLE="[Hart's] Rules for Compositors and Readers
+ [at the Oxford University Press]",
+ PUBLISHER="Oxford University Press",
+ EDITION="39", YEAR="1983"}
+ (but first published in 1893)
+
+@BOOK{Partridge,
+ AUTHOR="Eric Partridge",
+ TITLE="Use and Abuse: a Guide to Good {E}nglish",
+ PUBLISHER="Hamish Hamilton",
+ EDITION="4", YEAR="1970"}
+ (but first published in 1947)
+
+@BOOK{Quirk-CompGram,
+ AUTHOR="Randolph Quirk and Sydney Greenbaum and Geoffrey Leach and
+ Jan Svartnik",
+ TITLE="A Comprehensive Grammar of the {E}nglish Language",
+ PUBLISHER="Longman", YEAR="1985"}
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt
new file mode 100644
index 0000000000..eea5a05a70
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt
@@ -0,0 +1,40 @@
+MathSciNet </mathscinet/index.html>
+
+ *
+ Clipboard </mathscinet/clipboard.html>
+ * Home </mathscinet/index.html>
+ * Preferences </mathscinet/preferences.html>
+ * Help </mathscinet/help/headline_review_help_full.html>
+ * Support Mail </mathscinet/support_mail.html>
+ * Terms of Use </mathscinet/help/mathscinet_terms_of_use.html>
+ * University of Southampton
+
+@article {MR2254280,
+ VOLUME = {23},
+ YEAR = {2006},
+}
+
+
+@article {MR2254274,
+ VOLUME = {23},
+ YEAR = {2006},
+}
+
+
+@article {MR2248052,
+ VOLUME = {23},
+ YEAR = {2006},
+}
+
+
+*Matches:* 3
+Mirror Sites
+
+
+© Copyright 2011, American Mathematical Society
+<http://www.ams.org/ams/copyright.html>
+Privacy Statement <http://www.ams.org/ams/privacy.html>
+American Mathematical Society <http://www.ams.org>
+American Mathematical Society
+201 Charles Street
+Providence, RI 02904-2294
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug66325.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug66325.t
new file mode 100644
index 0000000000..ac83b43aa9
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug66325.t
@@ -0,0 +1,71 @@
+#!/usr/bin/perl -w
+
+use Test::More;
+
+use BibTeX::Parser;
+use IO::File;
+
+{
+ my $fh = new IO::File "t/bibs/endnote.txt", "r" ;
+
+ if (defined $fh) {
+ my $parser = new BibTeX::Parser $fh;
+
+ while (my $entry = $parser->next) {
+ isa_ok($entry, "BibTeX::Parser::Entry");
+ ok($entry->parse_ok, "parse_ok");
+ is($entry->key, undef, "key");
+ is($entry->type, "ARTICLE", "type");
+ is($entry->field("year"), 1999, "field");
+ is($entry->field("volume"), 59, "first field");
+ }
+ }
+}
+
+{
+ my $fh = new IO::File "t/bibs/mathscinet.txt", "r" ;
+ my @keys = qw(MR2254280 MR2254274 MR2248052);
+
+ if (defined $fh) {
+ my $parser = new BibTeX::Parser $fh;
+ my $count = 0;
+
+ while (my $entry = $parser->next) {
+ isa_ok($entry, "BibTeX::Parser::Entry");
+ ok($entry->parse_ok, "parse_ok");
+ is($entry->key, $keys[$count], "key");
+ is($entry->type, "ARTICLE", "type");
+ is($entry->field("volume"), 23, "first field");
+ is($entry->field("year"), 2006, "field");
+ $count++;
+ }
+
+ is($count, 3, "number of entries");
+ }
+}
+
+{
+ my $fh = new IO::File "t/bibs/engineering_village.txt", "r" ;
+
+ my @types = qw( inproceedings inproceedings article inproceedings );
+ my @keys = qw( 1997493856789 1998043944915 2003137419501 2002367072517 );
+ my @years = qw( 1997 1997 2002 2002 );
+
+ if (defined $fh) {
+ my $parser = new BibTeX::Parser $fh;
+ my $count = 0;
+
+ while (my $entry = $parser->next) {
+ isa_ok($entry, "BibTeX::Parser::Entry");
+ ok($entry->parse_ok, "parse_ok");
+ is($entry->key, $keys[$count], "key");
+ is($entry->type, uc $types[$count], "type");
+ is($entry->field("language"), "English", "first field");
+ is($entry->field("year"), $years[$count], "field");
+ $count++;
+ }
+
+ is($count, 4, "number of entries");
+ }
+}
+done_testing;
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug67419.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug67419.t
new file mode 100644
index 0000000000..0f944f373a
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/bug67419.t
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+use Test::More;
+
+use BibTeX::Parser;
+use IO::File;
+
+my $fh = new IO::File "t/bibs/braces.bib", "r" ;
+my $parser = new BibTeX::Parser $fh;
+while (my $entry=$parser->next) {
+ is($entry->parse_ok,1);
+ if ($entry->key eq 'scholkopf98kpca') {
+ @authors=$entry->author;
+ is(scalar @authors,3);
+ is("$authors[0]", '{Sch\"olkopf}, Bernhard');
+ is("$authors[1]", 'Smola, Alex');
+ is("$authors[2]", 'Muller, K.R.');
+ }
+ if ($entry->key eq 'brownetal93') {
+ @authors=$entry->author;
+ is(scalar @authors,4);
+ is("$authors[0]", 'Brown, Peter F.');
+ is("$authors[1]", '{Della Pietra}, Stephen A.');
+ is("$authors[2]", '{Della Pietra}, Vincent J.');
+ is("$authors[3]", 'Mercer, Robert~L.');
+ }
+}
+
+done_testing();
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t
new file mode 100644
index 0000000000..980fb1d60d
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use utf8;
+
+use Test::More;
+use BibTeX::Parser::Entry;
+
+sub new_entry {
+ BibTeX::Parser::Entry->new( 'ARTICLE', 'Foo2010', 1, { @_ } );
+}
+{
+ my @german_tests = (
+ [ '"a' => 'ä' ],
+ ['"`' => '„' ],
+ ["\"'" => '“' ],
+ );
+
+ foreach my $test ( @german_tests ) {
+ my $entry = new_entry( foo => $test->[0] );
+ is( $entry->cleaned_field( 'foo', german => 1 ), $test->[1], "Convert $test->[0], german => 1" );
+ }
+}
+
+{
+ binmode( DATA, ':utf8' );
+ while (<DATA>) {
+ chomp;
+ my ( $tex, $result ) = split /\t/;
+ is( new_entry( foo => $tex )->cleaned_field( 'foo' ), $result, "Convert $tex" );
+ }
+ close DATA;
+}
+
+{
+ my $entry_with_authors = new_entry( author => 'F{\"o}o Bar and B"ar, F.' );
+ my @authors = $entry_with_authors->author;
+ is( scalar @authors, 2, "Number of authors is correct");
+ is( $authors[0]->first, 'F{\"o}o', "non-cleaned version of first" );
+ is( $authors[0]->last, 'Bar', "non-cleaned version of last" );
+
+ is( $authors[1]->first, 'F.', "non-cleaned version of first" );
+ is( $authors[1]->last, 'B"ar', "non-cleaned version of last" );
+
+ my @clean_authors = $entry_with_authors->cleaned_author;
+ is( $clean_authors[0]->first, 'Föo', "cleaned version of first" );
+ is( $clean_authors[0]->last, 'Bar', "cleaned version of last" );
+
+ is( $clean_authors[1]->first, 'F.', "cleaned version of first" );
+ is( $clean_authors[1]->last, 'B"ar', "cleaned version of last" );
+}
+done_testing;
+
+__DATA__
+\# #
+\& &
+{\`a} à
+{\^a} â
+{\~a} ã
+{\'a} á
+{\'{a}} á
+{\"a} ä
+{\`A} À
+{\'A} Á
+{\"A} Ä
+{\aa} å
+{\AA} Å
+{\ae} æ
+{\bf 12} 12
+{\'c} ć
+{\cal P} P
+{\c{c}} ç
+{\c{C}} Ç
+{\c{e}} ȩ
+{\c{s}} ş
+{\c{S}} Ş
+{\c{t}} ţ
+{\-d} d
+{\`e} è
+{\^e} ê
+{\'e} é
+{\"e} ë
+{\'E} É
+{\em bits} bits
+{\H{o}} ő
+{\`i} ì
+{\^i} î
+{\i} ı
+{\`i} ì
+{\'i} í
+{\"i} ï
+{\`\i} ì
+{\'\i} í
+{\"\i} ï
+{\`{\i}} ì
+{\'{\i}} í
+{\"{\i}} ï
+{\it Note} Note
+{\k{e}} ę
+{\l} ł
+{\-l} l
+{\log} log
+{\~n} ñ
+{\'n} ń
+{\^o} ô
+{\o} ø
+{\'o} ó
+{\"o} ö
+{\"{o}} ö
+{\'O} Ó
+{\"O} Ö
+{\"{O}} Ö
+{\rm always} always
+{\-s} s
+{\'s} ś
+{\sc JoiN} JoiN
+{\sl bit\/ \bf 7} bit 7
+{\sl L'Informatique Nouvelle} L’Informatique Nouvelle
+{\small and} and
+{\ss} ß
+{\TeX} TeX
+{\TM} ™
+{\tt awk} awk
+{\^u} û
+{\'u} ú
+{\"u} ü
+{\"{u}} ü
+{\'U} Ú
+{\"U} Ü
+{\u{a}} ă
+{\u{g}} ğ
+{\v{c}} č
+{\v{C}} Č
+{\v{e}} ě
+{\v{n}} ň
+{\v{r}} ř
+{\v{s}} š
+{\v{S}} Š
+{\v{z}} ž
+{\v{Z}} Ž
+{\'y} ý
+{\.{z}} ż
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t
new file mode 100644
index 0000000000..fc40a57c2a
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod::Coverage
+my $min_tpc = 1.08;
+eval "use Test::Pod::Coverage $min_tpc";
+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
+ if $@;
+
+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
+# but older versions don't recognize some common documentation styles
+my $min_pc = 0.18;
+eval "use Pod::Coverage $min_pc";
+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
+ if $@;
+
+all_pod_coverage_ok();
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod.t
new file mode 100644
index 0000000000..e22a39b524
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/pod.t
@@ -0,0 +1,12 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod
+my $min_tp = 1.22;
+eval "use Test::Pod $min_tp";
+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
+
+all_pod_files_ok();
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t
new file mode 100644
index 0000000000..3a818499f0
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t
@@ -0,0 +1,21 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use Test::More;
+
+eval "use Test::Pod::Coverage 1.08";
+plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage"
+ if $@;
+
+eval "use Pod::Coverage::TrustPod";
+plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage"
+ if $@;
+
+all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' });
diff --git a/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t
new file mode 100644
index 0000000000..d46a955694
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t
@@ -0,0 +1,15 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+use Test::More;
+
+eval "use Test::Pod 1.41";
+plan skip_all => "Test::Pod 1.41 required for testing POD" if $@;
+
+all_pod_files_ok();
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Changes b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Changes
new file mode 100644
index 0000000000..3db5c19724
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Changes
@@ -0,0 +1,27 @@
+Changes for LaTeX::ToUnicode
+
+0.54 2023-11-17 Better handling of \{ \}. New release
+
+0.53 2023-08-20 Tests fixed, new release
+
+0.52 2022-11-07 Support many more control sequences, \kern removal,
+ \<newline>, etc. Add ltxunitxt script to access functionality
+ from command line.
+
+0.11 2020-12-12 Updates and cleaing
+
+0.05 2016-11-23 02:28:35+00:00
+ Compatibility with perl 5.25 (Alexandr Ciornii)
+
+0.04 2015-12-25 19:16:41+00:00
+ Macrons are handled properly
+
+0.03 2010-10-18 18:04:14
+ Specify minimal perl version (5.8.0) for UTF-8 support
+
+0.02 2010/07/09
+ Handle accents with \i
+ Add script used to generate accents table
+
+0.01 2010/07/09
+ First release.
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/LICENSE b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/LICENSE
new file mode 100644
index 0000000000..c3402b3869
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/LICENSE
@@ -0,0 +1,375 @@
+Copyright 2010-2023 Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+Terms of the Perl programming language system itself
+
+a) the GNU General Public License as published by the Free
+ Software Foundation; either version 1, or (at your option) any
+ later version, or
+b) the "Artistic License"
+
+--- The GNU General Public License, Version 1, February 1989 ---
+
+This is free software, licensed under:
+
+ The GNU General Public License, Version 1, February 1989
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must tell them their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License. The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+ 7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+ 8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+--- The Artistic License 1.0 ---
+
+This software is Copyright (c) 2010 by Gerhard Gossen.
+
+This is free software, licensed under:
+
+ The Artistic License 1.0
+
+The Artistic License
+
+Preamble
+
+The intent of this document is to state the conditions under which a Package
+may be copied, such that the Copyright Holder maintains some semblance of
+artistic control over the development of the package, while giving the users of
+the package the right to use and distribute the Package in a more-or-less
+customary fashion, plus the right to make reasonable modifications.
+
+Definitions:
+
+ - "Package" refers to the collection of files distributed by the Copyright
+ Holder, and derivatives of that collection of files created through
+ textual modification.
+ - "Standard Version" refers to such a Package if it has not been modified,
+ or has been modified in accordance with the wishes of the Copyright
+ Holder.
+ - "Copyright Holder" is whoever is named in the copyright or copyrights for
+ the package.
+ - "You" is you, if you're thinking about copying or distributing this Package.
+ - "Reasonable copying fee" is whatever you can justify on the basis of media
+ cost, duplication charges, time of people involved, and so on. (You will
+ not be required to justify it to the Copyright Holder, but only to the
+ computing community at large as a market that must bear the fee.)
+ - "Freely Available" means that no fee is charged for the item itself, though
+ there may be fees involved in handling the item. It also means that
+ recipients of the item may redistribute it under the same conditions they
+ received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications derived
+from the Public Domain or from the Copyright Holder. A Package modified in such
+a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided that
+you insert a prominent notice in each changed file stating how and when you
+changed that file, and provided that you do at least ONE of the following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or an
+ equivalent medium, or placing the modifications on a major archive site
+ such as ftp.uu.net, or by allowing the Copyright Holder to include your
+ modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict with
+ standard executables, which must also be provided, and provide a separate
+ manual page for each non-standard executable that clearly documents how it
+ differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or executable
+form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where to
+ get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of the Package
+ with your modifications.
+
+ c) accompany any non-standard executables with their corresponding Standard
+ Version executables, giving the non-standard executables non-standard
+ names, and clearly documenting the differences in manual pages (or
+ equivalent), together with instructions on where to get the Standard
+ Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package. You
+may not charge a fee for this Package itself. However, you may distribute this
+Package in aggregate with other (possibly commercial) programs as part of a
+larger (possibly commercial) software distribution provided that you do not
+advertise this Package as a product of your own.
+
+6. The scripts and library files supplied as input to or produced as output
+from the programs of this Package do not automatically fall under the copyright
+of this Package, but belong to whomever generated them, and may be sold
+commercially, and may be aggregated with this Package.
+
+7. C or perl subroutines supplied by you and linked into this Package shall not
+be considered part of this Package.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MANIFEST b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MANIFEST
new file mode 100644
index 0000000000..2aa0688c10
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MANIFEST
@@ -0,0 +1,17 @@
+LICENSE
+Changes
+MANIFEST
+t/release-pod-coverage.t
+t/release-pod-syntax.t
+t/convert.t
+t/release-synopsis.t
+README
+script/ltx2unitxt
+script/convert.pl
+lib/LaTeX/ToUnicode/Tables.pm
+lib/LaTeX/ToUnicode.pm
+Makefile.PL
+head.ltx
+Makefile.TDS
+weaver.ini
+dist.ini
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.json b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.json
new file mode 100644
index 0000000000..a5c58de3f3
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.json
@@ -0,0 +1,40 @@
+{
+ "abstract" : "Convert LaTeX commands to Unicode",
+ "author" : [
+ "Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>"
+ ],
+ "dynamic_config" : 0,
+ "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010",
+ "license" : [
+ "perl_5"
+ ],
+ "meta-spec" : {
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "version" : 2
+ },
+ "name" : "LaTeX-ToUnicode",
+ "no_index" : {
+ "directory" : [
+ "t",
+ "inc"
+ ]
+ },
+ "prereqs" : {
+ "build" : {
+ "requires" : {
+ "Pod::LaTeX" : "0.61"
+ }
+ },
+ "configure" : {
+ "requires" : {
+ "ExtUtils::MakeMaker" : "6.31"
+ }
+ },
+ "runtime" : {
+ "requires" : {}
+ }
+ },
+ "release_status" : "stable",
+ "version" : "0.55",
+ "x_serialization_backend" : "JSON::PP version 4.16"
+}
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.yml b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.yml
new file mode 100644
index 0000000000..fd62be1272
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/MYMETA.yml
@@ -0,0 +1,22 @@
+---
+abstract: 'Convert LaTeX commands to Unicode'
+author:
+ - 'Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>'
+build_requires:
+ Pod::LaTeX: '0.61'
+configure_requires:
+ ExtUtils::MakeMaker: '6.31'
+dynamic_config: 0
+generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'
+license: perl
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: '1.4'
+name: LaTeX-ToUnicode
+no_index:
+ directory:
+ - t
+ - inc
+requires: {}
+version: '0.55'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile
new file mode 100644
index 0000000000..3ad447fe26
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile
@@ -0,0 +1,917 @@
+# This Makefile is for the LaTeX::ToUnicode extension to perl.
+#
+# It was generated automatically by MakeMaker version
+# 7.70 (Revision: 77000) from the contents of
+# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
+#
+# ANY CHANGES MADE HERE WILL BE LOST!
+#
+# MakeMaker ARGV: ()
+#
+
+# MakeMaker Parameters:
+
+# ABSTRACT => q[Convert LaTeX commands to Unicode]
+# AUTHOR => [q[Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>]]
+# BUILD_REQUIRES => { Pod::LaTeX=>q[0.61] }
+# CONFIGURE_REQUIRES => { ExtUtils::MakeMaker=>q[6.31] }
+# DISTNAME => q[LaTeX-ToUnicode]
+# EXE_FILES => [q[script/ltx2unitxt]]
+# LICENSE => q[perl]
+# NAME => q[LaTeX::ToUnicode]
+# PREREQ_PM => { Pod::LaTeX=>q[0.61] }
+# TEST_REQUIRES => { }
+# VERSION_FROM => q[lib/LaTeX/ToUnicode.pm]
+# test => { TESTS=>q[t/*.t] }
+
+# --- MakeMaker post_initialize section:
+
+
+# --- MakeMaker const_config section:
+
+# These definitions are from config.sh (via /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level/Config.pm).
+# They may have been overridden via Makefile.PL or on the command line.
+AR = ar
+CC = cc
+CCCDLFLAGS =
+CCDLFLAGS =
+CPPRUN = cc -E
+DLEXT = bundle
+DLSRC = dl_dlopen.xs
+EXE_EXT =
+FULL_AR = /usr/bin/ar
+LD = cc
+LDDLFLAGS = -mmacosx-version-min=14.2 -bundle -undefined dynamic_lookup -fstack-protector-strong
+LDFLAGS = -mmacosx-version-min=14.2 -fstack-protector-strong
+LIBC =
+LIB_EXT = .a
+OBJ_EXT = .o
+OSNAME = darwin
+OSVERS = 23.2.0
+RANLIB = ranlib
+SITELIBEXP = /opt/homebrew/opt/perl/lib/perl5/site_perl/5.38
+SITEARCHEXP = /opt/homebrew/opt/perl/lib/perl5/site_perl/5.38/darwin-thread-multi-2level
+SO = dylib
+VENDORARCHEXP =
+VENDORLIBEXP =
+
+
+# --- MakeMaker constants section:
+AR_STATIC_ARGS = cr
+DIRFILESEP = /
+DFSEP = $(DIRFILESEP)
+NAME = LaTeX::ToUnicode
+NAME_SYM = LaTeX_ToUnicode
+VERSION = 0.55
+VERSION_MACRO = VERSION
+VERSION_SYM = 0_55
+DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
+XS_VERSION = 0.55
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
+INST_ARCHLIB = blib/arch
+INST_SCRIPT = blib/script
+INST_BIN = blib/bin
+INST_LIB = blib/lib
+INST_MAN1DIR = blib/man1
+INST_MAN3DIR = blib/man3
+MAN1EXT = 1
+MAN3EXT = 3
+MAN1SECTION = 1
+MAN3SECTION = 3
+INSTALLDIRS = site
+DESTDIR =
+PREFIX = $(SITEPREFIX)
+PERLPREFIX = /opt/homebrew/Cellar/perl/5.38.2_1
+SITEPREFIX = /opt/homebrew/opt/perl
+VENDORPREFIX =
+INSTALLPRIVLIB = /opt/homebrew/Cellar/perl/5.38.2_1/lib/perl5/5.38
+DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
+INSTALLSITELIB = /opt/homebrew/Cellar/perl/5.38.2_1/lib/perl5/site_perl/5.38
+DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
+INSTALLVENDORLIB =
+DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
+INSTALLARCHLIB = /opt/homebrew/Cellar/perl/5.38.2_1/lib/perl5/5.38/darwin-thread-multi-2level
+DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
+INSTALLSITEARCH = /opt/homebrew/Cellar/perl/5.38.2_1/lib/perl5/site_perl/5.38/darwin-thread-multi-2level
+DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
+INSTALLVENDORARCH =
+DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
+INSTALLBIN = /opt/homebrew/Cellar/perl/5.38.2_1/bin
+DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
+INSTALLSITEBIN = /opt/homebrew/Cellar/perl/5.38.2_1/bin
+DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
+INSTALLVENDORBIN =
+DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
+INSTALLSCRIPT = /opt/homebrew/Cellar/perl/5.38.2_1/bin
+DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
+INSTALLSITESCRIPT = /opt/homebrew/Cellar/perl/5.38.2_1/bin
+DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
+INSTALLVENDORSCRIPT =
+DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
+INSTALLMAN1DIR = /opt/homebrew/Cellar/perl/5.38.2_1/share/man/man1
+DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
+INSTALLSITEMAN1DIR = /opt/homebrew/Cellar/perl/5.38.2_1/share/man/man1
+DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
+INSTALLVENDORMAN1DIR =
+DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
+INSTALLMAN3DIR = /opt/homebrew/Cellar/perl/5.38.2_1/share/man/man3
+DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
+INSTALLSITEMAN3DIR = /opt/homebrew/Cellar/perl/5.38.2_1/share/man/man3
+DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
+INSTALLVENDORMAN3DIR =
+DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
+PERL_LIB = /opt/homebrew/opt/perl/lib/perl5/5.38
+PERL_ARCHLIB = /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level
+PERL_ARCHLIBDEP = /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level
+LIBPERL_A = libperl.a
+FIRST_MAKEFILE = Makefile
+MAKEFILE_OLD = Makefile.old
+MAKE_APERL_FILE = Makefile.aperl
+PERLMAINCC = $(CC)
+PERL_INC = /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level/CORE
+PERL_INCDEP = /opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level/CORE
+PERL = "/opt/homebrew/Cellar/perl/5.38.2_1/bin/perl"
+FULLPERL = "/opt/homebrew/Cellar/perl/5.38.2_1/bin/perl"
+ABSPERL = $(PERL)
+PERLRUN = $(PERL)
+FULLPERLRUN = $(FULLPERL)
+ABSPERLRUN = $(ABSPERL)
+PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+PERL_CORE = 0
+PERM_DIR = 755
+PERM_RW = 644
+PERM_RWX = 755
+
+MAKEMAKER = /opt/homebrew/opt/perl/lib/perl5/5.38/ExtUtils/MakeMaker.pm
+MM_VERSION = 7.70
+MM_REVISION = 77000
+
+# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
+# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
+# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
+# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
+MAKE = make
+FULLEXT = LaTeX/ToUnicode
+BASEEXT = ToUnicode
+PARENT_NAME = LaTeX
+DLBASE = $(BASEEXT)
+VERSION_FROM = lib/LaTeX/ToUnicode.pm
+OBJECT =
+LDFROM = $(OBJECT)
+LINKTYPE = dynamic
+BOOTDEP =
+
+# Handy lists of source code files:
+XS_FILES =
+C_FILES =
+O_FILES =
+H_FILES =
+MAN1PODS =
+MAN3PODS = lib/LaTeX/ToUnicode.pm \
+ lib/LaTeX/ToUnicode/Tables.pm
+
+# Where is the Config information that we are using/depend on
+CONFIGDEP = $(PERL_ARCHLIBDEP)$(DFSEP)Config.pm $(PERL_INCDEP)$(DFSEP)config.h
+
+# Where to build things
+INST_LIBDIR = $(INST_LIB)/LaTeX
+INST_ARCHLIBDIR = $(INST_ARCHLIB)/LaTeX
+
+INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
+INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
+
+INST_STATIC =
+INST_DYNAMIC =
+INST_BOOT =
+
+# Extra linker info
+EXPORT_LIST =
+PERL_ARCHIVE =
+PERL_ARCHIVEDEP =
+PERL_ARCHIVE_AFTER =
+
+
+TO_INST_PM = lib/LaTeX/ToUnicode.pm \
+ lib/LaTeX/ToUnicode/Tables.pm
+
+
+# --- MakeMaker platform_constants section:
+MM_Unix_VERSION = 7.70
+PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
+
+
+# --- MakeMaker tool_autosplit section:
+# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
+AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$$$ARGV[0], $$$$ARGV[1], 0, 1, 1)' --
+
+
+
+# --- MakeMaker tool_xsubpp section:
+
+
+# --- MakeMaker tools_other section:
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(TRUE)
+NOECHO = @
+RM_F = rm -f
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' --
+EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' --
+FALSE = false
+TRUE = true
+ECHO = echo
+ECHO_N = echo -n
+UNINST = 0
+VERBINST = 0
+MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' --
+DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' --
+UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' --
+WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' --
+MACROSTART =
+MACROEND =
+USEMAKEFILE = -f
+FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' --
+CP_NONEMPTY = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'cp_nonempty' --
+
+
+# --- MakeMaker makemakerdflt section:
+makemakerdflt : all
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dist section:
+TAR = COPY_EXTENDED_ATTRIBUTES_DISABLE=1 COPYFILE_DISABLE=1 tar
+TARFLAGS = cvf
+ZIP = zip
+ZIPFLAGS = -r
+COMPRESS = gzip --best
+SUFFIX = .gz
+SHAR = shar
+PREOP = $(NOECHO) $(NOOP)
+POSTOP = $(NOECHO) $(NOOP)
+TO_UNIX = $(NOECHO) $(NOOP)
+CI = ci -u
+RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
+DIST_CP = best
+DIST_DEFAULT = tardist
+DISTNAME = LaTeX-ToUnicode
+DISTVNAME = LaTeX-ToUnicode-0.55
+
+
+# --- MakeMaker macro section:
+
+
+# --- MakeMaker depend section:
+
+
+# --- MakeMaker cflags section:
+
+
+# --- MakeMaker const_loadlibs section:
+
+
+# --- MakeMaker const_cccmd section:
+
+
+# --- MakeMaker post_constants section:
+
+
+# --- MakeMaker pasthru section:
+
+PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
+ LINKTYPE="$(LINKTYPE)"\
+ PREFIX="$(PREFIX)"\
+ PASTHRU_DEFINE='$(DEFINE) $(PASTHRU_DEFINE)'\
+ PASTHRU_INC='$(INC) $(PASTHRU_INC)'
+
+
+# --- MakeMaker special_targets section:
+.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
+
+.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir pure_all subdirs clean_subdirs makemakerdflt manifypods realclean_subdirs subdirs_dynamic subdirs_pure_nolink subdirs_static subdirs-test_dynamic subdirs-test_static test_dynamic test_static
+
+
+
+# --- MakeMaker c_o section:
+
+
+# --- MakeMaker xs_c section:
+
+
+# --- MakeMaker xs_o section:
+
+
+# --- MakeMaker top_targets section:
+all :: pure_all manifypods
+ $(NOECHO) $(NOOP)
+
+pure_all :: config pm_to_blib subdirs linkext
+ $(NOECHO) $(NOOP)
+
+subdirs :: $(MYEXTLIB)
+ $(NOECHO) $(NOOP)
+
+config :: $(FIRST_MAKEFILE) blibdirs
+ $(NOECHO) $(NOOP)
+
+help :
+ perldoc ExtUtils::MakeMaker
+
+
+# --- MakeMaker blibdirs section:
+blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
+ $(NOECHO) $(NOOP)
+
+# Backwards compat with 6.18 through 6.25
+blibdirs.ts : blibdirs
+ $(NOECHO) $(NOOP)
+
+$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_LIBDIR)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR)
+ $(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
+
+$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_ARCHLIB)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB)
+ $(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
+
+$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_AUTODIR)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR)
+ $(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
+
+$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR)
+ $(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
+
+$(INST_BIN)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_BIN)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN)
+ $(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
+
+$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_SCRIPT)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT)
+ $(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
+
+$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_MAN1DIR)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR)
+ $(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
+
+$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
+ $(NOECHO) $(MKPATH) $(INST_MAN3DIR)
+ $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR)
+ $(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
+
+
+
+# --- MakeMaker linkext section:
+
+linkext :: dynamic
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dlsyms section:
+
+
+# --- MakeMaker dynamic_bs section:
+
+BOOTSTRAP =
+
+
+# --- MakeMaker dynamic section:
+
+dynamic :: $(FIRST_MAKEFILE) config $(INST_BOOT) $(INST_DYNAMIC)
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dynamic_lib section:
+
+
+# --- MakeMaker static section:
+
+## $(INST_PM) has been moved to the all: target.
+## It remains here for awhile to allow for old usage: "make static"
+static :: $(FIRST_MAKEFILE) $(INST_STATIC)
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker static_lib section:
+
+
+# --- MakeMaker manifypods section:
+
+POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
+POD2MAN = $(POD2MAN_EXE)
+
+
+manifypods : pure_all config \
+ lib/LaTeX/ToUnicode.pm \
+ lib/LaTeX/ToUnicode/Tables.pm
+ $(NOECHO) $(POD2MAN) --section=$(MAN3SECTION) --perm_rw=$(PERM_RW) -u \
+ lib/LaTeX/ToUnicode.pm $(INST_MAN3DIR)/LaTeX::ToUnicode.$(MAN3EXT) \
+ lib/LaTeX/ToUnicode/Tables.pm $(INST_MAN3DIR)/LaTeX::ToUnicode::Tables.$(MAN3EXT)
+
+
+
+
+# --- MakeMaker processPL section:
+
+
+# --- MakeMaker installbin section:
+
+EXE_FILES = script/ltx2unitxt
+
+pure_all :: $(INST_SCRIPT)/ltx2unitxt
+ $(NOECHO) $(NOOP)
+
+realclean ::
+ $(RM_F) \
+ $(INST_SCRIPT)/ltx2unitxt
+
+$(INST_SCRIPT)/ltx2unitxt : script/ltx2unitxt $(FIRST_MAKEFILE) $(INST_SCRIPT)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists
+ $(NOECHO) $(RM_F) $(INST_SCRIPT)/ltx2unitxt
+ $(CP) script/ltx2unitxt $(INST_SCRIPT)/ltx2unitxt
+ $(FIXIN) $(INST_SCRIPT)/ltx2unitxt
+ -$(NOECHO) $(CHMOD) $(PERM_RWX) $(INST_SCRIPT)/ltx2unitxt
+
+
+
+# --- MakeMaker subdirs section:
+
+# none
+
+# --- MakeMaker clean_subdirs section:
+clean_subdirs :
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker clean section:
+
+# Delete temporary files but do not touch installed files. We don't delete
+# the Makefile here so a later make realclean still has a makefile to use.
+
+clean :: clean_subdirs
+ - $(RM_F) \
+ $(BASEEXT).bso $(BASEEXT).def \
+ $(BASEEXT).exp $(BASEEXT).x \
+ $(BOOTSTRAP) $(INST_ARCHAUTODIR)/extralibs.all \
+ $(INST_ARCHAUTODIR)/extralibs.ld $(MAKE_APERL_FILE) \
+ *$(LIB_EXT) *$(OBJ_EXT) \
+ *perl.core MYMETA.json \
+ MYMETA.yml blibdirs.ts \
+ core core.*perl.*.? \
+ core.[0-9] core.[0-9][0-9] \
+ core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] \
+ core.[0-9][0-9][0-9][0-9][0-9] lib$(BASEEXT).def \
+ mon.out perl \
+ perl$(EXE_EXT) perl.exe \
+ perlmain.c pm_to_blib \
+ pm_to_blib.ts so_locations \
+ tmon.out
+ - $(RM_RF) \
+ blib
+ $(NOECHO) $(RM_F) $(MAKEFILE_OLD)
+ - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
+
+
+# --- MakeMaker realclean_subdirs section:
+# so clean is forced to complete before realclean_subdirs runs
+realclean_subdirs : clean
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker realclean section:
+# Delete temporary files (via clean) and also delete dist files
+realclean purge :: realclean_subdirs
+ - $(RM_F) \
+ $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
+ - $(RM_RF) \
+ $(DISTVNAME)
+
+
+# --- MakeMaker metafile section:
+metafile : create_distdir
+ $(NOECHO) $(ECHO) Generating META.yml
+ $(NOECHO) $(ECHO) '---' > META_new.yml
+ $(NOECHO) $(ECHO) 'abstract: '\''Convert LaTeX commands to Unicode'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'author:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' - '\''Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' Pod::LaTeX: '\''0.61'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: '\''6.31'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'dynamic_config: 1' >> META_new.yml
+ $(NOECHO) $(ECHO) 'generated_by: '\''ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'license: perl' >> META_new.yml
+ $(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml
+ $(NOECHO) $(ECHO) ' version: '\''1.4'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'name: LaTeX-ToUnicode' >> META_new.yml
+ $(NOECHO) $(ECHO) 'no_index:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' directory:' >> META_new.yml
+ $(NOECHO) $(ECHO) ' - t' >> META_new.yml
+ $(NOECHO) $(ECHO) ' - inc' >> META_new.yml
+ $(NOECHO) $(ECHO) 'requires: {}' >> META_new.yml
+ $(NOECHO) $(ECHO) 'version: '\''0.55'\''' >> META_new.yml
+ $(NOECHO) $(ECHO) 'x_serialization_backend: '\''CPAN::Meta::YAML version 0.018'\''' >> META_new.yml
+ -$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
+ $(NOECHO) $(ECHO) Generating META.json
+ $(NOECHO) $(ECHO) '{' > META_new.json
+ $(NOECHO) $(ECHO) ' "abstract" : "Convert LaTeX commands to Unicode",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "author" : [' >> META_new.json
+ $(NOECHO) $(ECHO) ' "Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>"' >> META_new.json
+ $(NOECHO) $(ECHO) ' ],' >> META_new.json
+ $(NOECHO) $(ECHO) ' "dynamic_config" : 1,' >> META_new.json
+ $(NOECHO) $(ECHO) ' "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "license" : [' >> META_new.json
+ $(NOECHO) $(ECHO) ' "perl_5"' >> META_new.json
+ $(NOECHO) $(ECHO) ' ],' >> META_new.json
+ $(NOECHO) $(ECHO) ' "meta-spec" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "version" : 2' >> META_new.json
+ $(NOECHO) $(ECHO) ' },' >> META_new.json
+ $(NOECHO) $(ECHO) ' "name" : "LaTeX-ToUnicode",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "no_index" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "directory" : [' >> META_new.json
+ $(NOECHO) $(ECHO) ' "t",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "inc"' >> META_new.json
+ $(NOECHO) $(ECHO) ' ]' >> META_new.json
+ $(NOECHO) $(ECHO) ' },' >> META_new.json
+ $(NOECHO) $(ECHO) ' "prereqs" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "build" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "Pod::LaTeX" : "0.61"' >> META_new.json
+ $(NOECHO) $(ECHO) ' }' >> META_new.json
+ $(NOECHO) $(ECHO) ' },' >> META_new.json
+ $(NOECHO) $(ECHO) ' "configure" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "ExtUtils::MakeMaker" : "6.31"' >> META_new.json
+ $(NOECHO) $(ECHO) ' }' >> META_new.json
+ $(NOECHO) $(ECHO) ' },' >> META_new.json
+ $(NOECHO) $(ECHO) ' "runtime" : {' >> META_new.json
+ $(NOECHO) $(ECHO) ' "requires" : {}' >> META_new.json
+ $(NOECHO) $(ECHO) ' }' >> META_new.json
+ $(NOECHO) $(ECHO) ' },' >> META_new.json
+ $(NOECHO) $(ECHO) ' "release_status" : "stable",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "version" : "0.55",' >> META_new.json
+ $(NOECHO) $(ECHO) ' "x_serialization_backend" : "JSON::PP version 4.16"' >> META_new.json
+ $(NOECHO) $(ECHO) '}' >> META_new.json
+ -$(NOECHO) $(MV) META_new.json $(DISTVNAME)/META.json
+
+
+# --- MakeMaker signature section:
+signature :
+ cpansign -s
+
+
+# --- MakeMaker dist_basics section:
+distclean :: realclean distcheck
+ $(NOECHO) $(NOOP)
+
+distcheck :
+ $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
+
+skipcheck :
+ $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
+
+manifest :
+ $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
+
+veryclean : realclean
+ $(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old
+
+
+
+# --- MakeMaker dist_core section:
+
+dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
+ $(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
+ -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' --
+
+tardist : $(DISTVNAME).tar$(SUFFIX)
+ $(NOECHO) $(NOOP)
+
+uutardist : $(DISTVNAME).tar$(SUFFIX)
+ uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
+ $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)_uu'
+
+$(DISTVNAME).tar$(SUFFIX) : distdir
+ $(PREOP)
+ $(TO_UNIX)
+ $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
+ $(RM_RF) $(DISTVNAME)
+ $(COMPRESS) $(DISTVNAME).tar
+ $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)'
+ $(POSTOP)
+
+zipdist : $(DISTVNAME).zip
+ $(NOECHO) $(NOOP)
+
+$(DISTVNAME).zip : distdir
+ $(PREOP)
+ $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
+ $(RM_RF) $(DISTVNAME)
+ $(NOECHO) $(ECHO) 'Created $(DISTVNAME).zip'
+ $(POSTOP)
+
+shdist : distdir
+ $(PREOP)
+ $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
+ $(RM_RF) $(DISTVNAME)
+ $(NOECHO) $(ECHO) 'Created $(DISTVNAME).shar'
+ $(POSTOP)
+
+
+# --- MakeMaker distdir section:
+create_distdir :
+ $(RM_RF) $(DISTVNAME)
+ $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
+ -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
+
+distdir : create_distdir distmeta
+ $(NOECHO) $(NOOP)
+
+
+
+# --- MakeMaker dist_test section:
+disttest : distdir
+ cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
+ cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
+ cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
+
+
+
+# --- MakeMaker dist_ci section:
+ci :
+ $(ABSPERLRUN) -MExtUtils::Manifest=maniread -e '@all = sort keys %{ maniread() };' \
+ -e 'print(qq{Executing $(CI) @all\n});' \
+ -e 'system(qq{$(CI) @all}) == 0 or die $$!;' \
+ -e 'print(qq{Executing $(RCS_LABEL) ...\n});' \
+ -e 'system(qq{$(RCS_LABEL) @all}) == 0 or die $$!;' --
+
+
+# --- MakeMaker distmeta section:
+distmeta : create_distdir metafile
+ $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -e q{META.yml};' \
+ -e 'eval { maniadd({q{META.yml} => q{Module YAML meta-data (added by MakeMaker)}}) }' \
+ -e ' or die "Could not add META.yml to MANIFEST: $${'\''@'\''}"' --
+ $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -f q{META.json};' \
+ -e 'eval { maniadd({q{META.json} => q{Module JSON meta-data (added by MakeMaker)}}) }' \
+ -e ' or die "Could not add META.json to MANIFEST: $${'\''@'\''}"' --
+
+
+
+# --- MakeMaker distsignature section:
+distsignature : distmeta
+ $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) }' \
+ -e ' or die "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}"' --
+ $(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
+ cd $(DISTVNAME) && cpansign -s
+
+
+
+# --- MakeMaker install section:
+
+install :: pure_install doc_install
+ $(NOECHO) $(NOOP)
+
+install_perl :: pure_perl_install doc_perl_install
+ $(NOECHO) $(NOOP)
+
+install_site :: pure_site_install doc_site_install
+ $(NOECHO) $(NOOP)
+
+install_vendor :: pure_vendor_install doc_vendor_install
+ $(NOECHO) $(NOOP)
+
+pure_install :: pure_$(INSTALLDIRS)_install
+ $(NOECHO) $(NOOP)
+
+doc_install :: doc_$(INSTALLDIRS)_install
+ $(NOECHO) $(NOOP)
+
+pure__install : pure_site_install
+ $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+doc__install : doc_site_install
+ $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+pure_perl_install :: all
+ $(NOECHO) $(MOD_INSTALL) \
+ read "$(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist" \
+ write "$(DESTINSTALLARCHLIB)/auto/$(FULLEXT)/.packlist" \
+ "$(INST_LIB)" "$(DESTINSTALLPRIVLIB)" \
+ "$(INST_ARCHLIB)" "$(DESTINSTALLARCHLIB)" \
+ "$(INST_BIN)" "$(DESTINSTALLBIN)" \
+ "$(INST_SCRIPT)" "$(DESTINSTALLSCRIPT)" \
+ "$(INST_MAN1DIR)" "$(DESTINSTALLMAN1DIR)" \
+ "$(INST_MAN3DIR)" "$(DESTINSTALLMAN3DIR)"
+ $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+ "$(SITEARCHEXP)/auto/$(FULLEXT)"
+
+
+pure_site_install :: all
+ $(NOECHO) $(MOD_INSTALL) \
+ read "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" \
+ write "$(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist" \
+ "$(INST_LIB)" "$(DESTINSTALLSITELIB)" \
+ "$(INST_ARCHLIB)" "$(DESTINSTALLSITEARCH)" \
+ "$(INST_BIN)" "$(DESTINSTALLSITEBIN)" \
+ "$(INST_SCRIPT)" "$(DESTINSTALLSITESCRIPT)" \
+ "$(INST_MAN1DIR)" "$(DESTINSTALLSITEMAN1DIR)" \
+ "$(INST_MAN3DIR)" "$(DESTINSTALLSITEMAN3DIR)"
+ $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+ "$(PERL_ARCHLIB)/auto/$(FULLEXT)"
+
+pure_vendor_install :: all
+ $(NOECHO) $(MOD_INSTALL) \
+ read "$(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist" \
+ write "$(DESTINSTALLVENDORARCH)/auto/$(FULLEXT)/.packlist" \
+ "$(INST_LIB)" "$(DESTINSTALLVENDORLIB)" \
+ "$(INST_ARCHLIB)" "$(DESTINSTALLVENDORARCH)" \
+ "$(INST_BIN)" "$(DESTINSTALLVENDORBIN)" \
+ "$(INST_SCRIPT)" "$(DESTINSTALLVENDORSCRIPT)" \
+ "$(INST_MAN1DIR)" "$(DESTINSTALLVENDORMAN1DIR)" \
+ "$(INST_MAN3DIR)" "$(DESTINSTALLVENDORMAN3DIR)"
+
+
+doc_perl_install :: all
+ $(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLARCHLIB)/perllocal.pod"
+ -$(NOECHO) $(MKPATH) "$(DESTINSTALLARCHLIB)"
+ -$(NOECHO) $(DOC_INSTALL) \
+ "Module" "$(NAME)" \
+ "installed into" "$(INSTALLPRIVLIB)" \
+ LINKTYPE "$(LINKTYPE)" \
+ VERSION "$(VERSION)" \
+ EXE_FILES "$(EXE_FILES)" \
+ >> "$(DESTINSTALLARCHLIB)/perllocal.pod"
+
+doc_site_install :: all
+ $(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLARCHLIB)/perllocal.pod"
+ -$(NOECHO) $(MKPATH) "$(DESTINSTALLARCHLIB)"
+ -$(NOECHO) $(DOC_INSTALL) \
+ "Module" "$(NAME)" \
+ "installed into" "$(INSTALLSITELIB)" \
+ LINKTYPE "$(LINKTYPE)" \
+ VERSION "$(VERSION)" \
+ EXE_FILES "$(EXE_FILES)" \
+ >> "$(DESTINSTALLARCHLIB)/perllocal.pod"
+
+doc_vendor_install :: all
+ $(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLARCHLIB)/perllocal.pod"
+ -$(NOECHO) $(MKPATH) "$(DESTINSTALLARCHLIB)"
+ -$(NOECHO) $(DOC_INSTALL) \
+ "Module" "$(NAME)" \
+ "installed into" "$(INSTALLVENDORLIB)" \
+ LINKTYPE "$(LINKTYPE)" \
+ VERSION "$(VERSION)" \
+ EXE_FILES "$(EXE_FILES)" \
+ >> "$(DESTINSTALLARCHLIB)/perllocal.pod"
+
+
+uninstall :: uninstall_from_$(INSTALLDIRS)dirs
+ $(NOECHO) $(NOOP)
+
+uninstall_from_perldirs ::
+ $(NOECHO) $(UNINSTALL) "$(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist"
+
+uninstall_from_sitedirs ::
+ $(NOECHO) $(UNINSTALL) "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist"
+
+uninstall_from_vendordirs ::
+ $(NOECHO) $(UNINSTALL) "$(VENDORARCHEXP)/auto/$(FULLEXT)/.packlist"
+
+
+# --- MakeMaker force section:
+# Phony target to force checking subdirectories.
+FORCE :
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker perldepend section:
+
+
+# --- MakeMaker makefile section:
+# We take a very conservative approach here, but it's worth it.
+# We move Makefile to Makefile.old here to avoid gnu make looping.
+$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
+ $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
+ $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
+ -$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
+ -$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
+ - $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
+ $(PERLRUN) Makefile.PL
+ $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
+ $(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <=="
+ $(FALSE)
+
+
+
+# --- MakeMaker staticmake section:
+
+# --- MakeMaker makeaperl section ---
+MAP_TARGET = perl
+FULLPERL = "/opt/homebrew/Cellar/perl/5.38.2_1/bin/perl"
+MAP_PERLINC = "-Iblib/arch" "-Iblib/lib" "-I/opt/homebrew/opt/perl/lib/perl5/5.38/darwin-thread-multi-2level" "-I/opt/homebrew/opt/perl/lib/perl5/5.38"
+
+$(MAP_TARGET) :: $(MAKE_APERL_FILE)
+ $(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
+
+$(MAKE_APERL_FILE) : static $(FIRST_MAKEFILE) pm_to_blib
+ $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
+ $(NOECHO) $(PERLRUNINST) \
+ Makefile.PL DIR="" \
+ MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
+ MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
+
+
+# --- MakeMaker test section:
+TEST_VERBOSE=0
+TEST_TYPE=test_$(LINKTYPE)
+TEST_FILE = test.pl
+TEST_FILES = t/*.t
+TESTDB_SW = -d
+
+testdb :: testdb_$(LINKTYPE)
+ $(NOECHO) $(NOOP)
+
+test :: $(TEST_TYPE)
+ $(NOECHO) $(NOOP)
+
+# Occasionally we may face this degenerate target:
+test_ : test_dynamic
+ $(NOECHO) $(NOOP)
+
+subdirs-test_dynamic :: dynamic pure_all
+
+test_dynamic :: subdirs-test_dynamic
+ PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)
+
+testdb_dynamic :: dynamic pure_all
+ PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
+
+subdirs-test_static :: static pure_all
+
+test_static :: subdirs-test_static
+ PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)
+
+testdb_static :: static pure_all
+ PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
+
+
+
+# --- MakeMaker ppd section:
+# Creates a PPD (Perl Package Description) for a binary distribution.
+ppd :
+ $(NOECHO) $(ECHO) '<SOFTPKG NAME="LaTeX-ToUnicode" VERSION="0.55">' > LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' <ABSTRACT>Convert LaTeX commands to Unicode</ABSTRACT>' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' <AUTHOR>Gerhard Gossen &lt;gerhard.gossen@googlemail.com&gt; and Boris Veytsman &lt;boris@varphi.com&gt; and Karl Berry &lt;karl@freefriends.com&gt;</AUTHOR>' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="darwin-thread-multi-2level-5.38" />' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> LaTeX-ToUnicode.ppd
+ $(NOECHO) $(ECHO) '</SOFTPKG>' >> LaTeX-ToUnicode.ppd
+
+
+# --- MakeMaker pm_to_blib section:
+
+pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM)
+ $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \
+ 'lib/LaTeX/ToUnicode.pm' 'blib/lib/LaTeX/ToUnicode.pm' \
+ 'lib/LaTeX/ToUnicode/Tables.pm' 'blib/lib/LaTeX/ToUnicode/Tables.pm'
+ $(NOECHO) $(TOUCH) pm_to_blib
+
+
+# --- MakeMaker selfdocument section:
+
+# here so even if top_targets is overridden, these will still be defined
+# gmake will silently still work if any are .PHONY-ed but nmake won't
+
+static ::
+ $(NOECHO) $(NOOP)
+
+dynamic ::
+ $(NOECHO) $(NOOP)
+
+config ::
+ $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker postamble section:
+
+
+# End.
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL
new file mode 100644
index 0000000000..ff2b0f7bf2
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL
@@ -0,0 +1,51 @@
+
+use strict;
+use warnings;
+
+BEGIN { require 5.8.0; }
+
+use ExtUtils::MakeMaker 6.31;
+
+
+
+my %WriteMakefileArgs = (
+ 'ABSTRACT' => 'Convert LaTeX commands to Unicode',
+ 'AUTHOR' => 'Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>',
+ 'BUILD_REQUIRES' => {
+ 'Pod::LaTeX' => '0.61'
+ },
+ 'CONFIGURE_REQUIRES' => {
+ 'ExtUtils::MakeMaker' => '6.31'
+ },
+ 'DISTNAME' => 'LaTeX-ToUnicode',
+ 'EXE_FILES' => ['script/ltx2unitxt'],
+ 'LICENSE' => 'perl',
+ 'NAME' => 'LaTeX::ToUnicode',
+ 'PREREQ_PM' => {},
+ 'VERSION_FROM' => 'lib/LaTeX/ToUnicode.pm',
+ 'test' => {
+ 'TESTS' => 't/*.t'
+ }
+);
+
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) {
+ my $br = delete $WriteMakefileArgs{BUILD_REQUIRES};
+ my $pp = $WriteMakefileArgs{PREREQ_PM};
+ for my $mod ( keys %$br ) {
+ if ( exists $pp->{$mod} ) {
+ $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod};
+ }
+ else {
+ $pp->{$mod} = $br->{$mod};
+ }
+ }
+}
+
+delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
+ unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
+
+WriteMakefile(%WriteMakefileArgs);
+
+
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS
new file mode 100644
index 0000000000..6d6869c917
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS
@@ -0,0 +1,53 @@
+#
+# This is Makefile for TDS-compliant TeX distributions
+# Written by Boris Veytsman, boris@varphi.com
+#
+# This file is in public domain
+#
+PREFIX = /usr/local
+
+LIBDIR = $(PREFIX)/scripts/bibtexperllibs
+
+DOCDIR = $(PREFIX)/doc/bibtex/bibtexperllibs
+
+DOCS = latex-tounicode.pdf ltx2unitxt.pdf ltx2unitxt.1
+
+all:
+
+docs: $(DOCS)
+
+latex-tounicode.pdf: latex-tounicode.tex ltx2unitxt.pdf
+ texfot pdflatex $< || { rm -f $@; exit 1; }
+
+ToUnicode = lib/LaTeX/ToUnicode
+
+latex-tounicode.tex: $(ToUnicode).pm $(ToUnicode)/Tables.pm
+ pod2latex -modify -full -prefile head.ltx -out $@ $^
+
+latex-tounicode.tex: head.ltx
+# unfortunately pod2latex doesn't recognize =encoding, so there
+# are two warnings of "Command encoding not recognised ...". Oh well.
+
+ltx2unitxt.1: script/ltx2unitxt
+# don't run --version since the --help message includes --version output.
+ help2man --no-info --version-string=" " \
+--name="convert LaTeX source fragment to plain (Unicode) text or simple html" \
+ $< >$@ \
+ || { rm -f $@; exit 1; }
+ltx2unitxt.pdf: ltx2unitxt.1
+ sed 's/^Releases:/\nReleases:/' $< | groff -man -t -rS11 - | ps2pdf - $@
+
+force:
+
+install: all docs
+ mkdir -p $(LIBDIR)
+ cp -r lib/* $(LIBDIR)
+ mkdir -p $(DOCDIR)
+ cp -r man/man3/* $(DOCDIR)
+ cp -r latex-tounicode.pdf ltx2unitxt.pdf ltx2unitxt.1 $(DOCDIR)
+
+clean:
+ $(RM) -r *.log *.aux *.out *.toc latex-tounicode.tex *.tar.gz
+
+distclean: clean
+ $(RM) -r $(DOCS) \ No newline at end of file
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/README b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/README
new file mode 100644
index 0000000000..1f241e3979
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/README
@@ -0,0 +1,13 @@
+This is the LaTeX::ToUnicode Perl package:
+
+ Convert LaTeX source fragments to Unicode plain text or simple html
+
+Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs
+Releases: https://ctan.org/pkg/bibtexperllibs
+
+Copyright 2010-2022 Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl5 programming language system itself.
+
+
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/dist.ini b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/dist.ini
new file mode 100644
index 0000000000..5c038d1985
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/dist.ini
@@ -0,0 +1,16 @@
+name = LaTeX-ToUnicode
+author = Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org>
+license = Perl_5
+copyright_holder = Gerhard Gossen and Boris Veytsman
+copyright_year = 2010-2023
+version = 0.53
+
+[@Classic]
+[Prereqs]
+perl = 5.8.0
+[NextRelease]
+format = %-7v %{yyyy-MM-dd HH:mm:ss}d
+[PodWeaver]
+[Repository]
+[@Git]
+[SynopsisTests]
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/head.ltx b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/head.ltx
new file mode 100644
index 0000000000..3f946fcba0
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/head.ltx
@@ -0,0 +1,28 @@
+% documentation for LaTeX::ToUnicode.
+% head.ltx file public domain.
+%
+\documentclass[11pt]{article}
+\usepackage{fullpage,pdfpages}
+\usepackage[hidelinks]{hyperref}
+\let\printindex=\empty % index is not useful
+\sloppy \hbadness=3000 % not aiming for good typesetting
+
+% Silence useless font warning about braces in cmsy instead of cmtt:
+\makeatletter\def\@font@warning#1{}\makeatother
+
+% https://tex.stackexchange.com/questions/68272
+\newcommand\invisiblesection[1]{%
+ \refstepcounter{section}%
+ \addcontentsline{toc}{section}{\protect\numberline{\thesection}#1}%
+ \sectionmark{#1}%
+}
+
+\begin{document}
+\title{\texttt{LaTeX::ToUnicode} documentation}
+\author{Boris Veytsman\thanks{borisv@lk.net}}
+\maketitle
+\tableofcontents
+
+\invisiblesection{ltx2unitxt---convert \LaTeX\ source fragments}
+
+\includepdf[pages=-]{ltx2unitxt}
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf
new file mode 100644
index 0000000000..723cfc0251
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf
Binary files differ
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm
new file mode 100644
index 0000000000..80650febe8
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm
@@ -0,0 +1,788 @@
+use strict;
+use warnings;
+package LaTeX::ToUnicode;
+BEGIN {
+ $LaTeX::ToUnicode::VERSION = '0.55';
+}
+#ABSTRACT: Convert LaTeX commands to Unicode (simplistically)
+
+require Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw( convert debuglevel $endcw );
+
+use utf8;
+use Encode;
+use LaTeX::ToUnicode::Tables;
+
+# Terminating a control word (not symbol) the way TeX does: at the
+# boundary between a letter (lookbehind) and a nonletter (lookahead),
+# and then ignore any following whitespace.
+our $endcw = qr/(?<=[a-zA-Z])(?=[^a-zA-Z]|$)\s*/;
+
+# all we need for is debugging being on and off. And it's pretty random
+# what gets output.
+my $debug = 0;
+
+sub debuglevel { $debug = shift; }
+sub _debug {
+ return unless $debug;
+ # The backtrace info is split between caller(0) and caller(1), sigh.
+ # We don't need the package name, it's included in $subr in practice.
+ my (undef,$filename,$line,undef) = caller(0);
+ my (undef,undef,undef,$subr) = caller(1);
+ warn @_, " at $filename:$line ($subr)\n";
+}
+
+# The main conversion function.
+#
+sub convert {
+ my ($string, %options) = @_;
+ #warn debug_hash_as_string("starting with: $string", %options);
+
+ # First, remove leading and trailing horizontal whitespace
+ # on each line of the possibly-multiline string we're given.
+ $string =~ s/^[ \t]*//m;
+ $string =~ s/[ \t]*$//m;
+
+ # For HTML output, must convert special characters that were in the
+ # TeX text (&<>) to their entities to avoid misparsing. We want to
+ # do this first, because conversion of the markup commands might
+ # output HTML tags like <tt>, and we don't want to convert those <>.
+ # Although &lt;tt&gt; works, better to keep the output HTML as
+ # human-readable as we can.
+ #
+ if ($options{html}) {
+ $string =~ s/([^\\]|^)&/$1&amp;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+ }
+
+ my $user_hook = $options{hook};
+ if ($user_hook) {
+ $string = &$user_hook($string, \%options);
+ _debug("after user hook: $string");
+ }
+
+ # Convert general commands that take arguments, since (1) they might
+ # insert TeX commands that need to be converted, and (2) because
+ # their arguments could well contain constructs that will map to a
+ # Perl string \x{nnnn} for Unicode character nnnn; those Perl braces
+ # for the \x will confuse further parsing of the TeX.
+ #
+ $string = _convert_commands_with_arg($string);
+ _debug("after commands with arg: $string");
+
+ # Convert markups (\texttt, etc.); they have the same brace-parsing issue.
+ $string = _convert_markups($string, \%options);
+ _debug("after markups: $string");
+
+ # And urls, a special case of commands with arguments.
+ $string = _convert_urls($string, \%options);
+ _debug("after urls: $string");
+
+ $string = _convert_control_words($string);
+ _debug("after control words: $string");
+
+ $string = _convert_control_symbols($string);
+ _debug("after control symbols: $string");
+
+ $string = _convert_accents($string);
+ $string = _convert_german($string) if $options{german};
+ $string = _convert_symbols($string);
+ $string = _convert_ligatures($string);
+
+ # Let's handle ties here, after all the other conversions, since
+ # they don't fit well with any of the tables.
+ #
+ # /~, or ~ at the beginning of a line, is probably part of a url or
+ # path, not a tie. Otherwise, consider it a space, since we can't
+ # distinguish true no-break spots (Donald~E. Knuth) from ties that
+ # are only relevant to a particular line width.
+ #
+ $string =~ s,([^/])~,$1 ,g;
+
+ # Remove kerns. Clearly needs generalizing/sharpening to recognize
+ # dimens better, and plenty of other commands could use it.
+ # Here, we only handle literal dimensions ("+1.3pt"), not dimens
+ # referring to control sequences, with or without factors
+ # ("1.1\baselineskip").
+ #_debug("before kern: $string");
+ my $dimen_re = qr/[-+]?[0-9., ]+[a-z][a-z]\s*/;
+ $string =~ s!\\kern${endcw}${dimen_re}!!g;
+
+ # What the heck, let's do \hfuzz and \vfuzz too. They come up pretty
+ # often and practically the same thing (plus ignore optional =)..
+ $string =~ s!\\[hv]fuzz${endcw}=?\s*${dimen_re}!!g;
+
+ # And here is \penalty. natbib outputs \penalty0 sometimes.
+ # Similar with $dimen_re, we only handle literal and decimal
+ # integers here, not things like "0 or `A.
+ my $number_re = qr/[-+]?[0-9]+\s*/;
+ $string =~ s!\\penalty${endcw}\s*${number_re}!!g;
+
+ # After all the conversions, $string contains \x{....} constructs
+ # (Perl Unicode characters) where translations have happened. Change
+ # those to the desired output format. Thus we assume that the
+ # Unicode \x{....}'s are not themselves involved in further
+ # translations, which is, so far, true.
+ #
+ if (! $options{entities}) {
+ # Convert our \x strings from Tables.pm to the binary characters.
+
+ # As an extra-special case, we want to preserve the translation of
+ # \{ and \} as 007[bd] entities even if the --entities option is
+ # not give; otherwise they'd get eliminated like all other braces.
+ # Use a temporary cs \xx to keep them marked, and don't use braces
+ # to delimit the argument since they'll get deleted.
+ $string =~ s/\\x\{(007[bd])\}/\\xx($1)/g;
+
+ # Convert all other characters to characters.
+ # Assume exactly four hex digits, since we wrote Tables.pm that way.
+ $string =~ s/\\x\{(....)\}/ pack('U*', hex($1))/eg;
+
+ } elsif ($options{entities}) {
+ # Convert the XML special characters that appeared in the input,
+ # e.g., from a TeX \&. Unless we're generating HTML output, in
+ # which case they have already been converted.
+ if (! $options{html}) {
+ $string =~ s/&/&amp;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+ }
+
+ # Our values in Tables.pm are simple ASCII strings \x{....},
+ # so we can replace them with hex entities with no trouble.
+ # Fortunately TeX does not have a standard \x control sequence.
+ $string =~ s/\\x\{(....)\}/&#x$1;/g;
+
+ # The rest of the job is about binary Unicode characters in the
+ # input. We want to transform them into entities also. As always
+ # in Perl, there's more than one way to do it, and several are
+ # described here, just for the fun of it.
+ my $ret = "";
+ #
+ # decode_utf8 is described in https://perldoc.perl.org/Encode.
+ # Without the decode_utf8, all of these methods output each byte
+ # separately; apparently $string is a byte string at this point,
+ # not a Unicode string. I don't know why that is.
+ $ret = decode_utf8($string);
+ #
+ # Transform everything that's not printable ASCII or newline into
+ # entities.
+ $ret =~ s/([^ -~\n])/ sprintf("&#x%04x;", ord($1)) /eg;
+ #
+ # This method leaves control characters as literal; doesn't matter
+ # for XML output, since control characters aren't allowed, but
+ # let's use the regexp method anyway.
+ #$ret = encode("ascii", decode_utf8($string), Encode::FB_XMLCREF);
+ #
+ # The nice_string function from perluniintro also works.
+ #
+ # This fails, just outputs numbers (that is, ord values):
+ # foreach my $c (unpack("U*", $ret)) {
+ #
+ # Without the decode_utf8, outputs each byte separately.
+ # With the decode_utf8, works, but the above seems cleaner.
+ #foreach my $c (split(//, $ret)) {
+ # if (ord($c) <= 31 || ord($c) >= 128) {
+ # $ret .= sprintf("&#x%04x;", ord($c));
+ # } else {
+ # $ret .= $c;
+ # }
+ #}
+ #
+ $string = $ret; # assigned from above.
+ }
+
+ if ($string =~ /\\x\{/) {
+ warn "LaTeX::ToUnicode::convert: untranslated \\x remains: $string\n";
+ warn "LaTeX::ToUnicode::convert: please report as bug.\n";
+ }
+
+ # Drop all remaining braces.
+ $string =~ s/[{}]//g;
+
+ if (! $options{entities}) {
+ # With all the other braces gone, now we can convert the preserved
+ # brace entities from \{ and \} to actual braces.
+ $string =~ s/\\xx\((007[bd])\)/ pack('U*', hex($1))/eg;
+ }
+
+ # Backslashes might remain. Don't remove them, as it makes for a
+ # useful way to find unhandled commands.
+
+ # leave newlines alone, but trim spaces and tabs.
+ $string =~ s/^[ \t]+//s; # remove leading whitespace
+ $string =~ s/[ \t]+$//s; # remove trailing whitespace
+ $string =~ s/[ \t]+/ /gs; # collapse all remaining whitespace to one space
+
+ $string;
+}
+
+# Convert commands that take a single braced argument. The table
+# defines text we're supposed to insert before and after the argument.
+# We let future processing handle conversion of both the inserted text
+# and the argument.
+#
+sub _convert_commands_with_arg {
+ my $string = shift;
+
+ foreach my $cmd ( keys %LaTeX::ToUnicode::Tables::ARGUMENT_COMMANDS ) {
+ my $repl = $LaTeX::ToUnicode::Tables::ARGUMENT_COMMANDS{$cmd};
+ my $lft = $repl->[0]; # ref to two-element list
+ my $rht = $repl->[1];
+ # \cmd{foo} -> LFT foo RHT
+ $string =~ s/\\$cmd${endcw}\{(.*?)\}/$lft$1$rht/g;
+ #warn "replaced arg $cmd, yielding $string\n";
+ }
+
+ $string;
+}
+
+# Convert url commands in STRING. This is a special case of commands
+# with arguments: \url{u} and \href{u}{desc text}. The HTML output
+# (generated if $OPTIONS{html} is set) is just too special to be handled
+# in a table; further, \href is the only two-argument command we are
+# currently handling.
+#
+sub _convert_urls {
+ my ($string,$options) = @_;
+
+ if ($options->{html}) {
+ # HTML output.
+ # \url{URL} -> <a href="URL">URL</a>
+ $string =~ s,\\url$endcw\{([^}]*)\}
+ ,<a href="$1">$1</a>,gx;
+ #
+ # \href{URL}{TEXT} -> <a href="URL">TEXT</a>
+ $string =~ s,\\href$endcw\{([^}]*)\}\s*\{([^}]*)\}
+ ,<a href="$1">$2</a>,gx;
+
+ } else {
+ # plain text output.
+ # \url{URL} -> URL
+ $string =~ s/\\url$endcw\{([^}]*)\}/$1/g;
+ #
+ # \href{URL}{TEXT} -> TEXT (URL)
+ # but, as a special case, if URL ends with TEXT, just output URL,
+ # as in:
+ # \href{https://doi.org/10/fjzzc8}{10/fjzzc8}
+ # ->
+ # https://doi.org/10/fjzzc8
+ #
+ # Yet more specialness: the TEXT might have extra braces, as in
+ # \href{https://doi.org/10/fjzzc8}{{10/fjzzc8}}
+ # left over from previous markup commands (\path) which got
+ # removed. We want to accept and ignore such extra braces,
+ # hence the \{+ ... \}+ in recognizing TEXT.
+ #
+#warn "txt url: starting with $string\n";
+ if ($string =~ m/\\href$endcw\{([^}]*)\}\s*\{+([^}]*)\}+/) {
+ my $url = $1;
+ my $text = $2;
+#warn " url: $url\n";
+#warn " text: $text\n";
+ my $repl = ($url =~ m!$text$!) ? $url : "$text ($url)";
+#warn " repl: $repl\n";
+ $string =~ s/\\href$endcw\{([^}]*)\}\s*\{+([^}]*)\}+/$repl/;
+#warn " str: $string\n";
+ }
+ }
+
+ $string;
+}
+
+# Convert control words (not symbols), that is, a backslash and an
+# alphabetic sequence of characters terminated by a non-alphabetic
+# character. Following whitespace is ignored.
+#
+sub _convert_control_words {
+ my $string = shift;
+
+ foreach my $command ( keys %LaTeX::ToUnicode::Tables::CONTROL_WORDS ) {
+ my $repl = $LaTeX::ToUnicode::Tables::CONTROL_WORDS{$command};
+ # replace {\CMD}, whitespace ignored after \CMD.
+ $string =~ s/\{\\$command$endcw\}/$repl/g;
+
+ # replace \CMD, preceded by not-consumed non-backslash.
+ $string =~ s/(?<=[^\\])\\$command$endcw/$repl/g;
+
+ # replace \CMD at beginning of whole string, which otherwise
+ # wouldn't be matched. Two separate regexps to avoid
+ # variable-length lookbehind.
+ $string =~ s/^\\$command$endcw/$repl/g;
+ }
+
+ $string;
+}
+
+# Convert control symbols, other than accents. Much simpler than
+# control words, since are self-delimiting, don't take arguments, and
+# don't consume any following text.
+#
+sub _convert_control_symbols {
+ my $string = shift;
+
+ foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::CONTROL_SYMBOLS ) {
+ my $repl = $LaTeX::ToUnicode::Tables::CONTROL_SYMBOLS{$symbol};
+
+ # because these are not alphabetic, we can quotemeta them,
+ # and we need to because "\" is one of the symbols.
+ my $rx = quotemeta($symbol);
+
+ # the preceding character must not be a backslash, else "\\ "
+ # could have the "\ " seen first as a control space, leaving
+ # a spurious \ behind. Don't consume the preceding.
+ # Or it could be at the beginning of a line.
+ #
+ $string =~ s/(^|(?<=[^\\]))\\$rx/$repl/g;
+ #warn "after sym $symbol (\\$rx -> $repl), have: $string\n";
+ }
+
+ $string;
+}
+
+# Convert accents.
+#
+sub _convert_accents {
+ my $string = shift;
+
+ # first the non-alphabetic accent commands, like \".
+ my %tbl = %LaTeX::ToUnicode::Tables::ACCENT_SYMBOLS;
+ $string =~ s/(\{\\(.)\s*\{(\\?\w{1,2})\}\})/$tbl{$2}{$3} || $1/eg; #{\"{a}}
+ $string =~ s/(\{\\(.)\s*(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # {\"a}
+ $string =~ s/(\\(.)\s*(\\?\w{1,1}))/ $tbl{$2}{$3} || $1/eg; # \"a
+ $string =~ s/(\\(.)\s*\{(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # \"{a}
+
+ # second the alphabetic commands, like \c. They have to be handled
+ # differently because \cc is not \c{c}! The only difference in the
+ # regular expressions is using $endcw instead of just \s*.
+ #
+ %tbl = %LaTeX::ToUnicode::Tables::ACCENT_LETTERS;
+ $string =~ s/(\{\\(.)$endcw\{(\\?\w{1,2})\}\})/$tbl{$2}{$3} || $1/eg; #{\"{a}}
+ $string =~ s/(\{\\(.)$endcw(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # {\"a}
+ $string =~ s/(\\(.)$endcw(\\?\w{1,1}))/ $tbl{$2}{$3} || $1/eg; # \"a
+ $string =~ s/(\\(.)$endcw\{(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # \"{a}
+
+
+ # The argument is just one \w character for the \"a case, not two,
+ # because otherwise we might consume a following character that is
+ # not part of the accent, e.g., a backslash (\"a\'e).
+ #
+ # Others can be two because of the \t tie-after accent. Even {\t oo} is ok.
+ #
+ # Allow whitespace after the \CMD in all cases, e.g., "\c c". Even
+ # for the control symbols, it turns out spaces are ignored there
+ # (as in \" o), unlike the usual syntax.
+ #
+ # Some non-word constituents would work, but in practice we hope
+ # everyone just uses letters.
+
+ $string;
+}
+
+# For the [n]german package.
+sub _convert_german {
+ my $string = shift;
+
+ foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::GERMAN ) {
+ $string =~ s/\Q$symbol\E/$LaTeX::ToUnicode::Tables::GERMAN{$symbol}/g;
+ }
+ $string;
+}
+
+# Control words that produce printed symbols (and letters in languages
+# other than English), that is.
+#
+sub _convert_symbols {
+ my $string = shift;
+
+ foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::SYMBOLS ) {
+ my $repl = $LaTeX::ToUnicode::Tables::SYMBOLS{$symbol};
+ # preceded by a (non-consumed) non-backslash,
+ # usual termination for a control word.
+ # These commands don't take arguments.
+ $string =~ s/(?<=[^\\])\\$symbol$endcw/$repl/g;
+
+ # or the beginning of the whole string:
+ $string =~ s/^\\$symbol$endcw/$repl/g;
+ }
+ $string;
+}
+
+# Special character sequences, not \commands. They aren't all
+# technically ligatures, but no matter.
+#
+sub _convert_ligatures {
+ my $string = shift;
+
+ # have to convert these in order specified.
+ my @ligs = @LaTeX::ToUnicode::Tables::LIGATURES;
+ for (my $i = 0; $i < @ligs; $i+=2) {
+ my $in = $ligs[$i];
+ my $out = $ligs[$i+1];
+ $string =~ s/\Q$in\E/$out/g;
+ }
+ $string;
+}
+
+#
+# Convert LaTeX markup commands in STRING like \textbf{...} and
+# {\bfshape ...} and {\bf ...}.
+#
+# If we're aiming for plain text output, they are just cleared away (the
+# braces are not removed).
+#
+# If we're generating HTML output ("html" key is set in $OPTIONS hash
+# ref), we use the value in the hash, so that \textbf{foo} becomes
+# <b>foo</b>. Nested markup doesn't work.
+#
+sub _convert_markups {
+ my ($string, $options) = @_;
+
+ # HTML is different.
+ return _convert_markups_html($string) if $options->{html};
+
+ # Not HTML, so here we'll "convert" to plain text by removing the
+ # markup commands.
+
+ # we can do all the markup commands at once.
+ my $markups = join('|', keys %LaTeX::ToUnicode::Tables::MARKUPS);
+
+ # Remove \textMARKUP{...}, leaving just the {...}
+ $string =~ s/\\text($markups)$endcw//g;
+
+ # Similarly remove \MARKUPshape, plus remove \upshape.
+ $string =~ s/\\($markups|up)shape$endcw//g;
+
+ # Remove braces and \command in: {... \MARKUP ...}
+ $string =~ s/(\{[^{}]+)\\(?:$markups)$endcw([^{}]+\})/$1$2/g;
+
+ # Remove braces and \command in: {\MARKUP ...}
+ $string =~ s/\{\\(?:$markups)$endcw([^{}]*)\}/$1/g;
+
+ # Remove: {\MARKUP
+ # Although this will leave unmatched } chars behind, there's no
+ # alternative without full parsing, since the bib entry will often
+ # look like: {\em {The TeX{}book}}. Also might, in principle, be
+ # at the end of a line.
+ $string =~ s/\{\\(?:$markups)$endcw//g;
+
+ # Ultimately we remove all braces in ltx2crossrefxml SanitizeText fns,
+ # so the unmatched braces don't matter ... that code should be moved.
+
+ $string;
+}
+
+# Convert \markup in STRING to html. We can't always figure out where to
+# put the end tag, but we always put it somewhere. We don't even attempt
+# to handle nested markup.
+#
+sub _convert_markups_html {
+ my ($string) = @_;
+
+ my %MARKUPS = %LaTeX::ToUnicode::Tables::MARKUPS;
+ # have to consider each markup \command separately.
+ for my $markup (keys %MARKUPS) {
+ my $hcmd = $MARKUPS{$markup}; # some TeX commands don't translate
+ my $tag = $hcmd ? "<$hcmd>" : "";
+ my $end_tag = $hcmd ? "</$hcmd>" : "";
+
+ # The easy one: \textMARKUP{...}
+ $string =~ s/\\text$markup$endcw\{(.*?)\}/$tag$1$end_tag/g;
+
+ # {x\MARKUP(shape) y} -> x<mk>y</mk> (leave out braces)
+ $string =~ s/\{([^{}]+)\\$markup(shape)?$endcw([^{}]+)\}
+ /$1$tag$3$end_tag/gx;
+
+ # {\MARKUP(shape) y} -> <mk>y</mk>. Same as previous but without
+ # the x part. Could do it in one regex but this seems clearer.
+ $string =~ s/\{\\$markup(shape)?$endcw([^{}]+)\}
+ /$tag$2$end_tag/gx;
+
+ # for {\MARKUP(shape) ... with no matching brace, we don't know
+ # where to put the end tag, so seems best to do nothing.
+ }
+
+ $string;
+}
+
+
+##############################################################
+# debug_hash_as_string($LABEL, HASH)
+#
+# Return LABEL followed by HASH elements, followed by a newline, as a
+# single string. If HASH is a reference, it is followed (but no recursive
+# derefencing).
+###############################################################
+sub debug_hash_as_string {
+ my ($label) = shift;
+ my (%hash) = (ref $_[0] && $_[0] =~ /.*HASH.*/) ? %{$_[0]} : @_;
+
+ my $str = "$label: {";
+ my @items = ();
+ for my $key (sort keys %hash) {
+ my $val = $hash{$key};
+ $val = ".undef" if ! defined $val;
+ $key =~ s/\n/\\n/g;
+ $val =~ s/\n/\\n/g;
+ push (@items, "$key:$val");
+ }
+ $str .= join (",", @items);
+ $str .= "}";
+
+ return "$str\n";
+}
+
+1;
+
+__END__
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+LaTeX::ToUnicode - Convert LaTeX commands to Unicode
+
+=head1 VERSION
+
+version 0.54
+
+=head1 SYNOPSIS
+
+ use LaTeX::ToUnicode qw( convert debuglevel $endcw );
+
+ # simple examples:
+ convert( '{\"a}' ) eq 'ä'; # true
+ convert( '{\"a}', entities=>1 ) eq '&#00EF;'; # true
+ convert( '"a', german=>1 ) eq 'ä'; # true, `german' package syntax
+ convert( '"a', ) eq '"a'; # false, not enabled by default
+
+ # more generally:
+ my $latexstr;
+ my $unistr = convert($latexstr); # get literal (binary) Unicode characters
+
+ my $entstr = convert($latexstr, entities=>1); # get &#xUUUU;
+
+ my $htmstr = convert($latexstr, entities=>1, html=>1); # also html markup
+
+ my $unistr = convert($latexstr, hook=>\&my_hook); # user-defined hook
+
+ # if nonzero, dumps various info; perhaps other levels in the future.
+ LaTeX::ToUnicode::debuglevel($verbose);
+
+ # regexp for terminating TeX control words, e.g., in hooks.
+ my $endcw = $LaTeX::ToUnicode::endcw;
+ $string =~ s/\\newline$endcw/ /g; # translate \newline to space
+
+=head1 DESCRIPTION
+
+This module provides a method to convert LaTeX markups for accents etc.
+into their Unicode equivalents. It translates some commands for special
+characters or accents into their Unicode (or HTML) equivalents and
+removes formatting commands. It is not at all bulletproof or complete.
+
+This module is intended to convert fragments of LaTeX source, such as
+bibliography entries and abstracts, into plain text (or, optionally,
+simplistic HTML). It is not a document conversion system. Math, tables,
+figures, sectioning, etc., are not handled in any way, and mostly left
+in their TeX form in the output. The translations assume standard LaTeX
+meanings for characters and control sequences; macros in the input are
+not considered.
+
+The aim for all the output is utter simplicity and minimalism, not
+faithful translation. For example, although Unicode has a code point for
+a thin space, the LaTeX C<\thinspace> (etc.) command is translated to
+the empty string; such spacing refinements desirable in the TeX output
+are, in our experience, generally not desired in the HTML output from
+this tool.
+
+As another example, TeX C<%> comments are not removed, even on lines by
+themselves, because they may be inside verbatim blocks, and we don't
+attempt to keep any such context. In practice, TeX comments are rare in
+the text fragments intended to be handled, so removing them in advance
+has not been a great burden.
+
+As another example, LaTeX ties, C<~> characters, are replaced with
+normal spaces (exception: unless they follow a C</> character or at the
+beginning of a line, when they're assumed to be part of a url or a
+pathname), rather than a no-break space character, because in our
+experience most ties intended for the TeX output would just cause
+trouble in plain text or HTML.
+
+Regarding normal whitespace: all leading and trailing horizontal
+whitespace (that is, SPC and TAB) is removed. All internal horizontal
+whitespace sequences are collapsed to a single space.
+
+After the conversions, all brace characters (C<{}>) are simply removed
+from the returned string. This turns out to be a significant convenience
+in practice, since many LaTeX commands which take arguments don't need
+to do anything for our purposes except output the argument.
+
+On the other hand, backslashes are not removed. This is so the caller
+can check for C<\\> and thus discover untranslated commands. Of course
+there are many other constructs that might not be translated, or
+translated wrongly. There is no escaping the need to carefully look at
+the output.
+
+Suggestions and bug reports are welcome for practical needs; we know
+full well that there are hundreds of commands not handled that could be.
+Virtually all the behavior mentioned here would be easily made
+customizable, if there is a need to do so.
+
+=head1 FUNCTIONS
+
+=head2 convert( $latex_string, %options )
+
+Convert the text in C<$latex_string> into a plain(er) Unicode string.
+Escape sequences for accented and special characters (e.g., C<\i>,
+C<\"a>, ...) are converted. A few basic formatting commands (e.g.,
+C<{\it ...}>) are removed. See the L<LaTeX::ToUnicode::Tables> submodule
+for the full conversion tables.
+
+These keys are recognized in C<%options>:
+
+=over
+
+=item C<entities>
+
+Output C<&#xUUUU;> entities (valid in XML); in this case, also convert
+the E<lt>, E<gt>, C<&> metacharacters to entities. Recognized non-ASCII
+Unicode characters in the original input are also converted to entities,
+not only the translations from TeX commands.
+
+The default is to output literal (binary) Unicode characters, and
+not change any metacharacters.
+
+=item C<german>
+
+If this option is set, the commands introduced by the package `german'
+(e.g. C<"a> eq C<ä>, note the missing backslash) are also
+handled.
+
+=item C<html>
+
+If this option is set, the output is simplistic html rather than plain
+text. This affects only a few things: S<1) the> output of urls from
+C<\url> and C<\href>; S<2) the> output of markup commands like
+C<\textbf> (but nested markup commands don't work); S<3) two> other
+random commands, C<\enquote> and C<\path>, because they are needed.
+
+=item C<hook>
+
+The value must be a function that takes two arguments and returns a
+string. The first argument is the incoming string (may be multiple
+lines), and the second argument is a hash reference of options, exactly
+what was passed to this C<convert> function. Thus the hook can detect
+whether html is needed.
+
+The hook is called (almost) right away, before any of the other
+conversions have taken place. That way the hook can make use of the
+predefined conversions instead of repeating them. The only changes made
+to the input string before the hook is called are trivial: leading and
+trailing whitespace (space and tab) on each line are removed, and, for
+HTML output, incoming ampersand, less-than, and greater-than characters
+are replaced with their entities.
+
+Any substitutions that result in Unicode code points must use
+C<\\x{nnnn}> on the right hand side: that's two backslashes and a
+four-digit hex number.
+
+As an example, here is a skeleton of the hook function for TUGboat:
+
+ sub LaTeX_ToUnicode_convert_hook {
+ my ($string,$options) = @_;
+
+ my $endcw = $LaTeX::ToUnicode::endcw;
+ die "no endcw regexp in LaTeX::ToUnicode??" if ! $endcw;
+
+ ...
+ $string =~ s/\\newline$endcw/ /g;
+
+ # TUB's \acro{} takes an argument, but we do nothing with it.
+ # The braces will be removed by convert().
+ $string =~ s/\\acro$endcw//g;
+ ...
+ $string =~ s/\\CTAN$endcw/CTAN/g;
+ $string =~ s/\\Dash$endcw/\\x{2014}/g; # em dash; replacement is string
+ ...
+
+ # ignore \begin{abstract} and \end{abstract} commands.
+ $string =~ s,\\(begin|end)$endcw\{abstract\}\s*,,g;
+
+ # Output for our url abbreviations, and other commands, depends on
+ # whether we're generating plain text or HTML.
+ if ($options->{html}) {
+ # HTML.
+ # \tbsurl{URLBASE} -> <a href="https://URLBASE">URLBASE</a>
+ $string =~ s,\\tbsurl$endcw\{([^}]*)\}
+ ,<a href="https://$1">$1</a>,gx;
+ ...
+ # varepsilon, and no line break at hyphen.
+ $string =~ s,\\eTeX$endcw,\\x{03B5}<nobr>-</nobr>TeX,g;
+
+ } else {
+ # for plain text, we can just prepend the protocol://.
+ $string =~ s,\\tbsurl$endcw,https://,g;
+ ...
+ $string =~ s,\\eTeX$endcw,\\x{03B5}-TeX,g;
+ }
+ ...
+ return $string;
+ }
+
+As shown here for C<\eTeX> (an abbreviation macro defined in the
+TUGboat style files), if markup is desired in the output, the
+substitutions must be different for HTML and plain text. Otherwise, the
+desired HTML markup is transliterated as if it were plain text. Or else
+the translations must be extended so that TeX markup can be used on the
+rhs to be replaced with the desired HTML (C<&lt;nobr&gt;> in this case).
+
+For the full definition (and plenty of additional information),
+see the file C<ltx2crossrefxml-tugboat.cfg> in the TUGboat source
+repository at
+<https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref>.
+
+The hook function is specified in the C<convert()> call like this:
+
+ LaTeX::ToUnicode::convert(..., { hook => \&LaTeX_ToUnicode_convert_hook })
+
+=back
+
+=head2 debuglevel( $level )
+
+Output debugging information if C<$level> is nonzero.
+
+=head2 $endcw
+
+A predefined regexp for terminating TeX control words (not control
+symbols!). Can be used in, for example, hook functions:
+
+ my $endcw = $LaTeX::ToUnicode::endcw;
+ $string =~ s/\\newline$endcw/ /g; # translate \newline to space
+
+It's defined as follows:
+
+ our $endcw = qr/(?<=[a-zA-Z])(?=[^a-zA-Z]|$)\s*/;
+
+That is, look behind for an alphabetic character, then look ahead for a
+non-alphabetic character (or end of line), then consume whitespace.
+Fingers crossed.
+
+=head1 AUTHOR
+
+Gerhard Gossen <gerhard.gossen@googlemail.com>,
+Boris Veytsman <boris@varphi.com>,
+Karl Berry <karl@freefriends.org>
+
+L<https://github.com/borisveytsman/bibtexperllibs>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2010-2024 Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl5 programming language system itself.
+
+=cut
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm
new file mode 100644
index 0000000000..90bbbc90f6
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm
@@ -0,0 +1,728 @@
+package LaTeX::ToUnicode::Tables;
+BEGIN {
+ $LaTeX::ToUnicode::Tables::VERSION = '0.55';
+}
+use strict;
+use warnings;
+#ABSTRACT: Character tables for LaTeX::ToUnicode
+
+use utf8; # just for the german support
+
+# Technically not all of these are ligatures, but close enough.
+# Order is important, so has to be a list, not a hash.
+#
+our @LIGATURES = (
+ "---" => '\x{2014}', # em dash
+ "--" => '\x{2013}', # en dash
+ "!`" => '\x{00A1}', # inverted exclam
+ "?`" => '\x{00A1}', # inverted question
+ "``" => '\x{201c}', # left double
+ "''" => '\x{201d}', # right double
+ "`" => '\x{2018}', # left single
+ "'" => '\x{2019}', # right single
+);
+# test text: em---dash, en--dash, exc!`am, quest?`ion, ``ld, rd'', `ls, rs'.
+#
+# Some additional ligatures supported in T1 encoding, but we won't (from
+# tex-text.map):
+# U+002C U+002C <> U+201E ; ,, -> DOUBLE LOW-9 QUOTATION MARK
+# U+003C U+003C <> U+00AB ; << -> LEFT POINTING GUILLEMET
+# U+003E U+003E <> U+00BB ; >> -> RIGHT POINTING GUILLEMET
+
+# for {\MARKUP(shape) ...} and \textMARKUP{...}; although not all
+# command names are defined in LaTeX for all markups, we translate them
+# anyway. Also, LaTeX has more font axes not included here: md, ulc, sw,
+# ssc, etc. See ltfntcmd.dtx and ltfssaxes.dtx if we ever want to try
+# for completeness.
+#
+our %MARKUPS = (
+ 'bf' => 'b',
+ 'cal' => '',
+ 'em' => 'em',
+ 'french' => '', # polyglossia
+ 'it' => 'i',
+ 'rm' => '',
+ 'sc' => '', # qqq should uppercasify
+ 'sf' => '',
+ 'sl' => 'i',
+ 'small' => '',
+ 'subscript' => 'sub',
+ 'superscript' => 'sup',
+ 'tt' => 'tt',
+);
+
+# More commands taking arguments that we want to handle.
+#
+our %ARGUMENT_COMMANDS = (
+ 'emph' => ['\textem{', '}'], # \textem doesn't exist, but we handle it
+ 'enquote' => ["`", "'"],
+ 'natexlab' => ["", ""], # natbib
+ 'path' => ['\texttt{', '}'], # ugh, might not be a braced argument
+);
+
+# Non-alphabetic \COMMANDs, other than accents and special cases.
+#
+our %CONTROL_SYMBOLS = (
+ ' ' => ' ', # control space
+ "\t" => ' ', # control space
+ "\n" => '\x{0020}', # control space; use entity to avoid being trimmed
+ '!' => '', # negative thin space
+ # " umlaut
+ '#' => '#', # sharp sign
+ '$' => '$', # dollar sign
+ '%' => '%', # percent sign
+ '&' => '\x{0026}', # ampersand, entity to avoid html conflict
+ # ' acute accent
+ '(' => '', # start inline math
+ ')' => '', # end inline math
+ '*' => '', # discretionary multiplication
+ '+' => '', # tabbing: tab stop to right
+ ',' => '', # thin space
+ '-' => '', # discretionary hyphenation
+ # . overdot accent
+ '/' => '', # italic correction
+ # 0..9 undefined
+ ':' => '', # medium space
+ ';' => ' ', # thick space
+ '<' => '', # tabbing: text to left of margin
+ # = macron accent
+ '>' => '', # tabbing: next tab stop
+ # ? undefined
+ '@' => '#', # end of sentence
+ # A..Z control words, not symbols
+ '[' => '', # start display math
+ '\\' => ' ', # line break
+ ']' => '', # end display math
+ # ^ circumflex accent
+ '_' => '_', # underscore
+ # ` grave accent
+ # a..z control words, not symbols
+ '{' => '\x{007b}', # lbrace
+ '|' => '\x{2225}', # parallel
+ '}' => '\x{007d}', # rbrace
+ # ~ tilde accent
+);
+
+# Alphabetic \COMMANDs that map to nothing. This is simply
+# interpolated into %CONTROL_WORDS (next), not used directly, so we
+# redundantly specify the '' on every line.
+#
+our %CONTROL_WORDS_EMPTY = (
+ 'begingroup' => '',
+ 'bgroup' => '',
+ 'checkcomma' => '',
+ #'cite' => '', # keep \cite undefined since it needs manual work
+ 'clearpage' => '',
+ 'doi' => '',
+ 'egroup' => '',
+ 'endgroup' => '',
+ 'ensuremath' => '',
+ 'hbox' => '',
+ 'ignorespaces' => '',
+ 'mbox' => '',
+ 'medspace' => '',
+ 'negmedspace' => '',
+ 'negthickspace' => '',
+ 'negthinspace' => '',
+ 'newblock' => '',
+ 'newpage' => '',
+ 'noindent' => '',
+ 'nolinkurl' => '',
+ 'oldstylenums' => '',
+ 'pagebreak' => '',
+ 'protect' => '',
+ 'raggedright' => '',
+ 'relax' => '',
+ 'thinspace' => '',
+ 'unskip' => '',
+ 'urlprefix' => '',
+);
+
+# Alphabetic commands, that expand to nothing (above) and to
+# something (below).
+#
+our %CONTROL_WORDS = (
+ %CONTROL_WORDS_EMPTY,
+ 'BibLaTeX' => 'BibLaTeX',
+ 'BibTeX' => 'BibTeX',
+ 'LaTeX' => 'LaTeX',
+ 'LuaLaTeX' => 'LuaLaTeX',
+ 'LuaTeX' => 'LuaTeX',
+ 'MF' => 'Metafont',
+ 'MP' => 'MetaPost',
+ 'Omega' => '\x{03A9}',
+ 'TeX' => 'TeX',
+ 'XeLaTeX' => 'XeLaTeX',
+ 'XeTeX' => 'XeTeX',
+ 'bullet' => '\x{2022}',
+ 'dag' => '\x{2020}',
+ 'ddag' => '\x{2021}',
+ 'dots' => '\x{2026}',
+ 'epsilon' => '\x{03F5}',
+ 'hookrightarrow' => '\x{2194}',
+ 'ldots' => '\x{2026}',
+ 'log' => 'log',
+ 'omega' => '\x{03C9}',
+ 'par' => "\n\n",
+ 'qquad' => ' ', # 2em space
+ 'quad' => ' ', # em space
+ 'textbackslash' => '\x{005C}', # entities so \ in output indicates
+ # untranslated TeX source
+ 'textbraceleft' => '\x{007B}', # entities so our bare-brace removal
+ 'textbraceright' => '\x{007D}', # skips them
+ 'textgreater' => '\x{003E}',
+ 'textless' => '\x{003C}',
+ 'textquotedbl' => '"',
+ 'thickspace' => ' ',
+ 'varepsilon' => '\x{03B5}',
+);
+
+# Control words (not symbols) that generate various non-English
+# letters and symbols. Lots more could be added.
+#
+our %SYMBOLS = ( # Table 3.2 in Lamport, plus more
+ 'AA' => '\x{00C5}', # A with ring
+ 'aa' => '\x{00E5}',
+ 'AE' => '\x{00C6}', # AE
+ 'ae' => '\x{00E6}',
+ 'DH' => '\x{00D0}', # ETH
+ 'dh' => '\x{00F0}',
+ 'DJ' => '\x{0110}', # D with stroke
+ 'dj' => '\x{0111}',
+ 'i' => '\x{0131}', # small dotless i
+ 'L' => '\x{0141}', # L with stroke
+ 'l' => '\x{0142}',
+ 'NG' => '\x{014A}', # ENG
+ 'ng' => '\x{014B}',
+ 'OE' => '\x{0152}', # OE
+ 'oe' => '\x{0153}',
+ 'O' => '\x{00D8}', # O with stroke
+ 'o' => '\x{00F8}',
+ 'SS' => 'SS', # lately also U+1E9E, but SS seems good enough
+ 'ss' => '\x{00DF}',
+ 'TH' => '\x{00DE}', # THORN
+ 'textordfeminine' => '\x{00AA}',
+ 'textordmasculine' => '\x{00BA}',
+ 'textregistered' => '\x{00AE}',
+ 'th' => '\x{00FE}',
+ 'TM' => '\x{2122}', # trade mark sign
+);
+
+# Accent commands that are not alphabetic.
+#
+our %ACCENT_SYMBOLS = (
+ "\"" => { # with diaresis
+ A => '\x{00C4}',
+ E => '\x{00CB}',
+ H => '\x{1E26}',
+ I => '\x{00CF}',
+ O => '\x{00D6}',
+ U => '\x{00DC}',
+ W => '\x{1E84}',
+ X => '\x{1E8c}',
+ Y => '\x{0178}',
+ "\\I" => '\x{00CF}',
+ "\\i" => '\x{00EF}',
+ a => '\x{00E4}',
+ e => '\x{00EB}',
+ h => '\x{1E27}',
+ i => '\x{00EF}',
+ o => '\x{00F6}',
+ t => '\x{1E97}',
+ u => '\x{00FC}',
+ w => '\x{1E85}',
+ x => '\x{1E8d}',
+ y => '\x{00FF}',
+ },
+ "'" => { # with acute
+ A => '\x{00C1}',
+ AE => '\x{01FC}',
+ C => '\x{0106}',
+ E => '\x{00C9}',
+ G => '\x{01F4}',
+ I => '\x{00CD}',
+ K => '\x{1E30}',
+ L => '\x{0139}',
+ M => '\x{1E3E}',
+ N => '\x{0143}',
+ O => '\x{00D3}',
+ P => '\x{1E54}',
+ R => '\x{0154}',
+ S => '\x{015A}',
+ U => '\x{00DA}',
+ W => '\x{1E82}',
+ Y => '\x{00DD}',
+ Z => '\x{0179}',
+ "\\I" => '\x{00CD}',
+ "\\i" => '\x{00ED}',
+ a => '\x{00E1}',
+ ae => '\x{01FD}',
+ c => '\x{0107}',
+ e => '\x{00E9}',
+ g => '\x{01F5}',
+ i => '\x{00ED}',
+ k => '\x{1E31}',
+ l => '\x{013A}',
+ m => '\x{1E3f}',
+ n => '\x{0144}',
+ o => '\x{00F3}',
+ p => '\x{1E55}',
+ r => '\x{0155}',
+ s => '\x{015B}',
+ u => '\x{00FA}',
+ w => '\x{1E83}',
+ y => '\x{00FD}',
+ z => '\x{017A}',
+ },
+ "^" => { # with circumflex
+ A => '\x{00C2}',
+ C => '\x{0108}',
+ E => '\x{00CA}',
+ G => '\x{011C}',
+ H => '\x{0124}',
+ I => '\x{00CE}',
+ J => '\x{0134}',
+ O => '\x{00D4}',
+ R => 'R\x{0302}',
+ S => '\x{015C}',
+ U => '\x{00DB}',
+ W => '\x{0174}',
+ Y => '\x{0176}',
+ Z => '\x{1E90}',
+ "\\I" => '\x{00CE}',
+ "\\J" => '\x{0134}',
+ "\\i" => '\x{00EE}',
+ "\\j" => '\x{0135}',
+ a => '\x{00E2}',
+ c => '\x{0109}',
+ e => '\x{00EA}',
+ g => '\x{011D}',
+ h => '\x{0125}',
+ i => '\x{00EE}',
+ j => '\x{0135}',
+ o => '\x{00F4}',
+ s => '\x{015D}',
+ u => '\x{00FB}',
+ w => '\x{0175}',
+ y => '\x{0177}',
+ z => '\x{1E91}',
+ },
+ "`" => { # with grave
+ A => '\x{00C0}',
+ E => '\x{00C8}',
+ I => '\x{00CC}',
+ N => '\x{01F8}',
+ O => '\x{00D2}',
+ U => '\x{00D9}',
+ W => '\x{1E80}',
+ Y => '\x{1Ef2}',
+ "\\I" => '\x{00CC}',
+ "\\i" => '\x{00EC}',
+ a => '\x{00E0}',
+ e => '\x{00E8}',
+ i => '\x{00EC}',
+ n => '\x{01F9}',
+ o => '\x{00F2}',
+ u => '\x{00F9}',
+ w => '\x{1E81}',
+ y => '\x{1EF3}',
+ },
+ "." => { # with dot above
+ A => '\x{0226}',
+ B => '\x{1E02}',
+ C => '\x{010A}',
+ D => '\x{1E0A}',
+ E => '\x{0116}',
+ F => '\x{1E1E}',
+ G => '\x{0120}',
+ H => '\x{1E22}',
+ I => '\x{0130}',
+ M => '\x{1E40}',
+ N => '\x{1E44}',
+ O => '\x{022E}',
+ P => '\x{1E56}',
+ R => '\x{1E58}',
+ S => '\x{1E60}',
+ T => '\x{1E6a}',
+ W => '\x{1E86}',
+ X => '\x{1E8A}',
+ Y => '\x{1E8E}',
+ Z => '\x{017B}',
+ "\\I" => '\x{0130}',
+ a => '\x{0227}',
+ b => '\x{1E03}',
+ c => '\x{010B}',
+ d => '\x{1E0B}',
+ e => '\x{0117}',
+ f => '\x{1e1f}',
+ g => '\x{0121}',
+ h => '\x{1E23}',
+ m => '\x{1E41}',
+ n => '\x{1E45}',
+ o => '\x{022F}',
+ p => '\x{1E57}',
+ r => '\x{1E59}',
+ s => '\x{1E61}',
+ t => '\x{1E6b}',
+ w => '\x{1E87}',
+ x => '\x{1E8b}',
+ y => '\x{1E8f}',
+ z => '\x{017C}',
+ },
+ '=' => { # with macron
+ A => '\x{0100}',
+ AE => '\x{01E2}',
+ E => '\x{0112}',
+ G => '\x{1E20}',
+ I => '\x{012A}',
+ O => '\x{014C}',
+ U => '\x{016A}',
+ Y => '\x{0232}',
+ "\\I" => '\x{012A}',
+ "\\i" => '\x{012B}',
+ a => '\x{0101}',
+ ae => '\x{01E3}',
+ e => '\x{0113}',
+ g => '\x{1E21}',
+ i => '\x{012B}',
+ o => '\x{014D}',
+ u => '\x{016B}',
+ y => '\x{0233}',
+ },
+ "~" => { # with tilde
+ A => '\x{00C3}',
+ E => '\x{1EBC}',
+ I => '\x{0128}',
+ N => '\x{00D1}',
+ O => '\x{00D5}',
+ U => '\x{0168}',
+ V => '\x{1E7C}',
+ Y => '\x{1EF8}',
+ "\\I" => '\x{0128}',
+ "\\i" => '\x{0129}',
+ a => '\x{00E3}',
+ e => '\x{1EBD}',
+ i => '\x{0129}',
+ n => '\x{00F1}',
+ o => '\x{00F5}',
+ u => '\x{0169}',
+ v => '\x{1E7D}',
+ y => '\x{1EF9}',
+ },
+);
+
+# Accent commands that are alphabetic.
+#
+our %ACCENT_LETTERS = (
+ "H" => { # with double acute
+ O => '\x{0150}',
+ U => '\x{0170}',
+ o => '\x{0151}',
+ u => '\x{0171}',
+ },
+ "c" => { # with cedilla
+ C => '\x{00C7}',
+ D => '\x{1E10}',
+ E => '\x{0228}',
+ G => '\x{0122}',
+ H => '\x{1E28}',
+ K => '\x{0136}',
+ L => '\x{013B}',
+ N => '\x{0145}',
+ R => '\x{0156}',
+ S => '\x{015E}',
+ T => '\x{0162}',
+ c => '\x{00E7}',
+ d => '\x{1E11}',
+ e => '\x{0229}',
+ g => '\x{0123}',
+ h => '\x{1E29}',
+ k => '\x{0137}',
+ l => '\x{013C}',
+ n => '\x{0146}',
+ r => '\x{0157}',
+ s => '\x{015F}',
+ t => '\x{0163}',
+ },
+ "d" => { # with dot below
+ A => '\x{1EA0}',
+ B => '\x{1E04}',
+ D => '\x{1E0C}',
+ E => '\x{1EB8}',
+ H => '\x{1E24}',
+ I => '\x{1ECA}',
+ K => '\x{1E32}',
+ L => '\x{1E36}',
+ M => '\x{1E42}',
+ N => '\x{1E46}',
+ O => '\x{1ECC}',
+ R => '\x{1E5A}',
+ S => '\x{1E62}',
+ T => '\x{1E6C}',
+ U => '\x{1EE4}',
+ V => '\x{1E7E}',
+ W => '\x{1E88}',
+ Y => '\x{1Ef4}',
+ Z => '\x{1E92}',
+ "\\I" => '\x{1ECA}',
+ "\\i" => '\x{1ECB}',
+ a => '\x{1EA1}',
+ b => '\x{1E05}',
+ d => '\x{1E0D}',
+ e => '\x{1EB9}',
+ h => '\x{1E25}',
+ i => '\x{1ECB}',
+ k => '\x{1E33}',
+ l => '\x{1E37}',
+ m => '\x{1E43}',
+ n => '\x{1E47}',
+ o => '\x{1ECD}',
+ r => '\x{1E5b}',
+ s => '\x{1E63}',
+ t => '\x{1E6D}',
+ u => '\x{1EE5}',
+ v => '\x{1E7F}',
+ w => '\x{1E89}',
+ y => '\x{1EF5}',
+ z => '\x{1E93}',
+ },
+ "h" => { # with hook above
+ A => '\x{1EA2}',
+ E => '\x{1EBA}',
+ I => '\x{1EC8}',
+ O => '\x{1ECe}',
+ U => '\x{1EE6}',
+ Y => '\x{1EF6}',
+ "\\I" => '\x{1EC8}',
+ "\\i" => '\x{1EC9}',
+ a => '\x{1EA3}',
+ e => '\x{1EBB}',
+ i => '\x{1EC9}',
+ o => '\x{1ECF}',
+ u => '\x{1EE7}',
+ y => '\x{1EF7}',
+ },
+ "k" => { # with ogonek
+ A => '\x{0104}',
+ E => '\x{0118}',
+ I => '\x{012E}',
+ O => '\x{01EA}',
+ U => '\x{0172}',
+ "\\I" => '\x{012E}',
+ "\\i" => '\x{012F}',
+ a => '\x{0105}',
+ e => '\x{0119}',
+ i => '\x{012F}',
+ o => '\x{01EB}',
+ u => '\x{0173}',
+ },
+ "r" => { # with ring above
+ A => '\x{00C5}',
+ U => '\x{016E}',
+ a => '\x{00E5}',
+ u => '\x{016F}',
+ w => '\x{1E98}',
+ y => '\x{1E99}',
+ },
+ "u" => { # with breve
+ A => '\x{0102}',
+ E => '\x{0114}',
+ G => '\x{011E}',
+ I => '\x{012C}',
+ O => '\x{014E}',
+ U => '\x{016C}',
+ "\\I" => '\x{012C}',
+ "\\i" => '\x{012D}',
+ a => '\x{0103}',
+ e => '\x{0115}',
+ g => '\x{011F}',
+ i => '\x{012D}',
+ o => '\x{014F}',
+ u => '\x{016D}',
+ },
+ "v" => { # with caron
+ A => '\x{01CD}',
+ C => '\x{010C}',
+ D => '\x{010E}',
+ DZ => '\x{01C4}',
+ E => '\x{011A}',
+ G => '\x{01E6}',
+ H => '\x{021E}',
+ I => '\x{01CF}',
+ K => '\x{01E8}',
+ L => '\x{013D}',
+ N => '\x{0147}',
+ O => '\x{01D1}',
+ R => '\x{0158}',
+ S => '\x{0160}',
+ T => '\x{0164}',
+ U => '\x{01D3}',
+ Z => '\x{017D}',
+ "\\I" => '\x{01CF}',
+ "\\i" => '\x{01D0}',
+ "\\j" => '\x{01F0}',
+ a => '\x{01CE}',
+ c => '\x{010D}',
+ d => '\x{010F}',
+ dz => '\x{01C6}',
+ e => '\x{011B}',
+ g => '\x{01E7}',
+ h => '\x{021F}',
+ i => '\x{01D0}',
+ j => '\x{01F0}',
+ k => '\x{01E9}',
+ l => '\x{013E}',
+ n => '\x{0148}',
+ o => '\x{01D2}',
+ r => '\x{0159}',
+ s => '\x{0161}',
+ t => '\x{0165}',
+ u => '\x{01D4}',
+ z => '\x{017E}',
+ },
+);
+
+#
+our %GERMAN = ( # for package `german'/`ngerman'
+ '"a' => 'ä',
+ '"A' => 'Ä',
+ '"e' => 'ë',
+ '"E' => 'Ë',
+ '"i' => 'ï',
+ '"I' => 'Ï',
+ '"o' => 'ö',
+ '"O' => 'Ö',
+ '"u' => 'ü',
+ '"U' => 'Ü',
+ '"s' => 'ß',
+ '"S' => 'SS',
+ '"z' => 'ß',
+ '"Z' => 'SZ',
+ '"ck' => 'ck', # old spelling: ck -> k-k
+ '"ff' => 'ff', # old spelling: ff -> ff-f
+ '"`' => '„',
+ "\"'" => '“',
+ '"<' => '«',
+ '">' => '»',
+ '"-' => '\x{00AD}', # soft hyphen
+ '""' => '\x{200B}', # zero width space
+ '"~' => '\x{2011}', # non-breaking hyphen
+ '"=' => '-',
+ '\glq' => '‚', # left german single quote
+ '\grq' => '‘', # right german single quote
+ '\flqq' => '«',
+ '\frqq' => '»',
+ '\dq' => '"',
+);
+
+1;
+
+__END__
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+LaTeX::ToUnicode::Tables - Character tables for LaTeX::ToUnicode
+
+=head1 VERSION
+
+version 0.54
+
+=head1 CONSTANTS
+
+=head2 @LIGATURES
+
+Standard TeX character sequences (not \commands) which need to be
+replaced: C<---> with U+2014 (em dash), etc. Includes: em dash, en
+dash, inverted exclamation, inverted question, left double quote, right
+double quote, left single quote, right single quote. They are replaced
+in that order.
+
+=head2 %MARKUPS
+
+Hash where keys are the names of formatting commands like C<\tt>,
+without the backslash, namely: C<bf cal em it rm sc sf sl small tt>. Values
+are the obvious HTML equivalent where one exists, given as the tag name
+without the angle brackets: C<b em i tt>. Otherwise the value is the empty
+string.
+
+=head2 %ARGUMENT_COMMANDS
+
+Hash where keys are the names of TeX commands taking arguments that we
+handle, without the backslash, such as C<enquote>. Each value is a
+reference to a list of two strings, the first being the text to insert
+before the argument, the second being the text to insert after. For
+example, for C<enquote> the value is C<["`", "'"]>. The inserted text is
+subject to further replacements.
+
+Only three such commands are currently handled: C<\emph>, C<\enquote>,
+and C<\path>.
+
+=head2 %CONTROL_SYMBOLS
+
+A hash where the keys are non-alphabetic C<\command>s (without the
+backslash), other than accents and special cases. These don't take
+arguments. Although some of these have Unicode equivalents, such as the
+C<\,> thin space, it seems better to keep the output as simple as
+possible; small spacing tweaks in TeX aren't usually desirable in plain
+text or HTML.
+
+The values are single-quoted strings C<'\x{...}'>, not double-quoted
+literal characters <"\x{...}">, to ease future parsing of the
+TeX/text/HTML.
+
+This hash is necessary because TeX's parsing rules for control symbols
+are different from control words: no space or other token is needed to
+terminate control symbols.
+
+=head2 %CONTROL_WORDS
+
+Keys are names of argument-less commands, such as C<\LaTeX> (without the
+backslash). Values are the replacements, often the empty string.
+
+=head2 %SYMBOLS
+
+Keys are the commands for extended characters, such as C<\AA> (without
+the backslash.)
+
+=head2 %ACCENT_SYMBOLS
+
+Two-level hash of accented characters like C<\'{a}>. The keys of this
+hash are the accent symbols (without the backslash), such as C<`> and
+C<'>. The corresponding values are hash references where the keys are
+the base letters and the values are single-quoted C<'\x{....}'> strings.
+
+=head2 %ACCENT_LETTERS
+
+Same as %ACCENT_SYMBOLS, except the keys are accents that are
+alphabetic, such as C<\c> (without the backslash as always).
+
+As with control sequences, it's necessary to distinguish symbols and
+alphabetic commands because of the different parsing rules.
+
+=head2 %GERMAN
+
+Character sequences (not necessarily commands) as defined by the package
+`german'/`ngerman', e.g. C<"a> (a with umlaut), C<"s> (german sharp s)
+or C<"`"> (german left quote). Note the missing backslash.
+
+The keys of this hash are the literal character sequences.
+
+=head1 AUTHOR
+
+Gerhard Gossen <gerhard.gossen@googlemail.com>,
+Boris Veytsman <boris@varphi.com>,
+Karl Berry <karl@freefriends.org>
+
+L<https://github.com/borisveytsman/bibtexperllibs>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2010-2024 Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl5 programming language system itself.
+
+=cut
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1 b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1
new file mode 100644
index 0000000000..e3f1065bba
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1
@@ -0,0 +1,73 @@
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
+.TH LTX2UNITXT "1" "September 2024" "ltx2unitxt " "User Commands"
+.SH NAME
+ltx2unitxt \- convert LaTeX source fragment to plain (Unicode) text or simple html
+.SH SYNOPSIS
+.B ltx2unitxt
+[\fI\,-c CONFIG\/\fR] [\fI\,-o OUTPUT\/\fR] [\fI\,--html\/\fR] [...] [\fI\,INFILE\/\fR]...
+.SH DESCRIPTION
+Convert the LaTeX source in INFILE (or standard input) to plain text
+using Unicode code points for accents and other special characters; or,
+optionally, output HTML with simple translations for font changes and url
+commands.
+.PP
+Common accent sequences, special characters, and simple markup commands
+are translated, but there is no attempt at completeness. Math, tables,
+figures, sectioning, etc., are not handled in any way, and mostly left
+in their TeX form in the output. The translations assume standard LaTeX
+meanings for characters and control sequences; macros in the input are
+not considered.
+.PP
+The input can be a fragment of text, not a full document, as the purpose
+of this script was to handle bibliography entries and abstracts (for the
+ltx2crossrefxml script that is part of the crossrefware package).
+Patches to extend this script are welcome. It uses the LaTeX::ToUnicode
+Perl library for the conversion; see its documentation for details.
+.PP
+Conversion is currently done line by line, so TeX constructs that cross
+multiple lines are not handled properly. If it turns out to be useful,
+conversion could be done by paragraph instead.
+.PP
+The config file is read as a Perl source file. It can define a function
+`LaTeX_ToUnicode_convert_hook()' which will be called early; the value
+it returns (which must be a string) will then be subject to the standard
+conversion.
+.PP
+For an example of using this script and associated code, see the TUGboat
+processing at
+https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref.
+.SH OPTIONS
+.TP
+\fB\-c\fR, \fB\-\-config\fR=\fI\,FILE\/\fR
+read (Perl) config FILE for a hook, as explained above
+.TP
+\fB\-e\fR, \fB\-\-entities\fR
+output entities &#xNNNN; instead of literal characters
+.TP
+\fB\-g\fR, \fB\-\-german\fR
+handle some features of the german package
+.TP
+\fB\-h\fR, \fB\-\-html\fR
+output simplistic HTML instead of plain text
+.TP
+\fB\-o\fR, \fB\-\-output\fR=\fI\,FILE\/\fR
+output to FILE instead of stdout
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+be verbose
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+output version information and exit
+.TP
+\-?, \fB\-\-help\fR
+display this help and exit
+.PP
+Options can be abbreviated unambiguously, and start with either \- or \fB\-\-\fR.
+.PP
+Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs
+Releases: https://ctan.org/pkg/bibtexperllibs
+.PP
+ltx2unitxt (bibtexperllibs) 0.51
+Copyright 2023 Karl Berry.
+This is free software: you can redistribute it and/or
+modify it under the same terms as Perl itself.
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf
new file mode 100644
index 0000000000..e533b0abc7
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf
Binary files differ
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl
new file mode 100644
index 0000000000..70cc0bda84
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl
@@ -0,0 +1,156 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use utf8;
+
+use feature 'say';
+use FindBin;
+
+my $UNICODE_DATA_URL = "http://www.unicode.org/Public/UNIDATA/UnicodeData.txt";
+
+
+my $stream;
+if ( -f "$FindBin::Bin/UnicodeData.txt" ) {
+ open $stream, "<", "$FindBin::Bin/UnicodeData.txt" or die;
+} else {
+ open $stream, "-|", "curl $UNICODE_DATA_URL" or die;
+}
+my %data;
+
+my %chars = (
+ 'ACUTE' => "'",
+ 'ACUTE AND DOT ABOVE' => '',
+ 'BAR' => '',
+ 'BELT' => '',
+ 'BREVE' => 'u',
+ 'BREVE AND ACUTE' => '',
+ 'BREVE AND DOT BELOW' => '',
+ 'BREVE AND GRAVE' => '',
+ 'BREVE AND HOOK ABOVE' => '',
+ 'BREVE AND TILDE' => '',
+ 'BREVE BELOW' => '',
+ 'CARON' => 'v',
+ 'CARON AND DOT ABOVE' => '',
+ 'CEDILLA' => 'c',
+ 'CEDILLA AND ACUTE' => '',
+ 'CEDILLA AND BREVE' => '',
+ 'CIRCUMFLEX' => '^',
+ 'CIRCUMFLEX AND ACUTE' => '',
+ 'CIRCUMFLEX AND DOT BELOW' => '',
+ 'CIRCUMFLEX AND GRAVE' => '',
+ 'CIRCUMFLEX AND HOOK ABOVE' => '',
+ 'CIRCUMFLEX AND TILDE' => '',
+ 'CIRCUMFLEX BELOW' => '',
+ 'COMMA' => '',
+ 'COMMA BELOW' => '',
+ 'CROSSED-TAIL' => '',
+ 'CURL' => '',
+ 'DESCENDER' => '',
+ 'DIAERESIS' => '"',
+ 'DIAERESIS AND ACUTE' => '',
+ 'DIAERESIS AND CARON' => '',
+ 'DIAERESIS AND GRAVE' => '',
+ 'DIAERESIS AND MACRON' => '',
+ 'DIAERESIS BELOW' => '',
+ 'DIAGONAL STROKE' => '',
+ 'DOT ABOVE' => '.',
+ 'DOT ABOVE AND MACRON' => '',
+ 'DOT BELOW' => 'd',
+ 'DOT BELOW AND DOT ABOVE' => '',
+ 'DOT BELOW AND MACRON' => '',
+ 'DOUBLE ACUTE' => 'H',
+ 'DOUBLE BAR' => '',
+ 'DOUBLE GRAVE' => '',
+ 'FISHHOOK' => '',
+ 'FISHHOOK AND MIDDLE TILDE' => '',
+ 'FLOURISH' => '',
+ 'GRAVE' => '`',
+ 'HIGH STROKE' => '',
+ 'HOOK' => '',
+ 'HOOK ABOVE' => 'h',
+ 'HOOK AND TAIL' => '',
+ 'HOOK TAIL' => '',
+ 'HORIZONTAL BAR' => '',
+ 'HORN' => '',
+ 'HORN AND ACUTE' => '',
+ 'HORN AND DOT BELOW' => '',
+ 'HORN AND GRAVE' => '',
+ 'HORN AND HOOK ABOVE' => '',
+ 'HORN AND TILDE' => '',
+ 'INVERTED BREVE' => '',
+ 'LEFT HOOK' => '',
+ 'LINE BELOW' => '',
+ 'LONG LEG' => '',
+ 'LONG RIGHT LEG' => '',
+ 'LONG STROKE OVERLAY' => '',
+ 'LOOP' => '',
+ 'LOW RING INSIDE' => '',
+ 'MACRON' => '=',
+ 'MACRON AND ACUTE' => '',
+ 'MACRON AND DIAERESIS' => '',
+ 'MACRON AND GRAVE' => '',
+ 'MIDDLE DOT' => '',
+ 'MIDDLE TILDE' => '',
+ 'NOTCH' => '',
+ 'OGONEK' => 'k',
+ 'OGONEK AND MACRON' => '',
+ 'PALATAL HOOK' => '',
+ 'RETROFLEX HOOK' => '',
+ 'RIGHT HALF RING' => '',
+ 'RIGHT HOOK' => '',
+ 'RING ABOVE' => 'r',
+ 'RING ABOVE AND ACUTE' => '',
+ 'RING BELOW' => '',
+ 'SMALL LETTER J' => '',
+ 'SMALL LETTER Z' => '',
+ 'SMALL LETTER Z WITH CARON' => '',
+ 'SQUIRREL TAIL' => '',
+ 'STRIKETHROUGH' => '',
+ 'STROKE' => '',
+ 'STROKE AND ACUTE' => '',
+ 'STROKE AND DIAGONAL STROKE' => '',
+ 'STROKE THROUGH DESCENDER' => '',
+ 'SWASH TAIL' => '',
+ 'TAIL' => '',
+ 'TILDE' => '~',
+ 'TILDE AND ACUTE' => '',
+ 'TILDE AND DIAERESIS' => '',
+ 'TILDE AND MACRON' => '',
+ 'TILDE BELOW' => '',
+ 'TOPBAR' => '',
+);
+
+my %missing;
+
+while(<$stream>) {
+ chomp;
+ my @F = split /;/;
+ my $hex = $F[0];
+ if ( $F[1] =~ /LATIN (SMALL|CAPITAL) LETTER ((?:\w+ )*\w{1,2}) WITH (.+)$/ ) {
+ my $case = $1;
+ my $letter = $2;
+ my $accent = $3;
+
+ if ( $case eq 'SMALL' ) {
+ $letter = lc $letter;
+ }
+ if ( $chars{$accent} && $letter !~ / / ) {
+ my $char = chr( eval "0x$hex" );
+ $data{ $chars{$accent} }->{ $letter } = $char;
+ if ( lc( $letter ) eq 'i' ) {
+ my $additional_letter = "\\$letter";
+ $data{ $chars{$accent} }->{ $additional_letter } = $char;
+ }
+ } else {
+ push @{ $missing{$accent} }, $letter;
+ }
+ }
+}
+
+use Data::Dumper::Concise;
+
+binmode(STDOUT, ":utf8");
+
+say Dumper( \%data );
+#say Dumper( \%missing );
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt
new file mode 100755
index 0000000000..661ea40417
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt
@@ -0,0 +1,169 @@
+#!/usr/bin/env perl
+# Use the LaTeX::ToUnicode module (also in the bibtexperllibs
+# repository/package, like this script) to convert LaTeX to Unicode.
+#
+# We work on fragments of text, not whole documents, the goal being to
+# replace LaTeX commands and syntax with obvious plain text equivalents,
+# or remove them.
+
+use strict;
+use warnings;
+
+use Cwd;
+use File::Basename;
+use File::Spec;
+
+BEGIN {
+ # find files relative to our installed location within TeX Live
+ chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root
+ if (length($TLMaster)) {
+ unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
+ }
+ # find development bibtexperllibs in sibling checkout to this script,
+ # even if $0 is a symlink. Irrelevant when using from an installation.
+ my $real0 = Cwd::abs_path($0);
+ my $scriptdir = File::Basename::dirname($real0);
+ my $dev_btxperllibs = Cwd::abs_path("$scriptdir/../..");
+
+ # we need the lib/ subdirectories inside ...
+ unshift (@INC, glob ("$dev_btxperllibs/*/lib")) if -d $dev_btxperllibs;
+
+}
+
+use LaTeX::ToUnicode;
+
+our %opts;
+local *OUT; # output filehandle
+
+exit(main());
+
+sub main {
+ init();
+
+ # by paragraph?
+ while (<>) {
+ print OUT (convert($_));
+ }
+
+ return 0;
+}
+
+sub convert {
+ my ($in) = @_;
+
+ my @args = (); # what we'll pass to the convert() fn.
+ #
+ if (defined(&{"LaTeX_ToUnicode_convert_hook"})) {
+ push (@args, "hook" => \&LaTeX_ToUnicode_convert_hook); }
+ if ($opts{e}) { push (@args, "entities" => 1); }
+ if ($opts{g}) { push (@args, "german" => 1); }
+ if ($opts{h}) { push (@args, "html" => 1); }
+
+ LaTeX::ToUnicode::debuglevel($opts{v});
+ my $out = LaTeX::ToUnicode::convert($in, @args);
+
+ #warn "out=$out";
+ return $out;
+}
+
+
+# Command line options, etc.
+#
+sub init {
+ my $USAGE = <<END;
+Usage: $0 [-c CONFIG] [-o OUTPUT] [--html] [...] [INFILE]...
+
+Convert the LaTeX source in INFILE (or standard input) to plain text
+using Unicode code points for accents and other special characters; or,
+optionally, output HTML with simple translations for font changes and url
+commands.
+
+Common accent sequences, special characters, and simple markup commands
+are translated, but there is no attempt at completeness. Math, tables,
+figures, sectioning, etc., are not handled in any way, and mostly left
+in their TeX form in the output. The translations assume standard LaTeX
+meanings for characters and control sequences; macros in the input are
+not considered.
+
+The input can be a fragment of text, not a full document, as the purpose
+of this script was to handle bibliography entries and abstracts (for the
+ltx2crossrefxml script that is part of the crossrefware package).
+Patches to extend this script are welcome. It uses the LaTeX::ToUnicode
+Perl library for the conversion; see its documentation for details.
+
+Conversion is currently done line by line, so TeX constructs that cross
+multiple lines are not handled properly. If it turns out to be useful,
+conversion could be done by paragraph instead.
+
+The config file is read as a Perl source file. It can define a function
+`LaTeX_ToUnicode_convert_hook()' which will be called early; the value
+it returns (which must be a string) will then be subject to the standard
+conversion.
+
+For an example of using this script and associated code, see the TUGboat
+processing at
+https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref.
+
+Options:
+ -c, --config=FILE read (Perl) config FILE for a hook, as explained above
+ -e, --entities output entities &#xNNNN; instead of literal characters
+ -g, --german handle some features of the german package
+ -h, --html output simplistic HTML instead of plain text
+ -o, --output=FILE output to FILE instead of stdout
+ -v, --verbose be verbose
+ -V, --version output version information and exit
+ -?, --help display this help and exit
+
+Options can be abbreviated unambiguously, and start with either - or --.
+
+Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs
+Releases: https://ctan.org/pkg/bibtexperllibs
+END
+
+ my $VERSION = <<END;
+ltx2unitxt (bibtexperllibs) 0.51
+Copyright 2023 Karl Berry.
+This is free software: you can redistribute it and/or
+modify it under the same terms as Perl itself.
+END
+
+ use Getopt::Long qw(:config no_ignore_case); # otherwise v|V is the same
+
+ GetOptions(
+ "config|c=s" => \($opts{c}),
+ "entities|e" => \($opts{e}),
+ "german|g" => \($opts{g}),
+ "html|h" => \($opts{h}),
+ "output|o=s" => \($opts{o}),
+ "verbose|v" => \($opts{v}),
+ "version|V" => \($opts{V}),
+ "help|?" => \($opts{help}))
+ || die "Try $0 --help for more information.\n";
+
+ if ($opts{help}) { print "$USAGE\n$VERSION"; exit 0; }
+ if ($opts{V}) { print $VERSION; exit 0; }
+
+ binmode(STDOUT, ":utf8");
+ *OUT = *STDOUT;
+
+ if (defined($opts{o})) {
+ open(OUT, ">$opts{o}") || die "open(>$opts{o}) failed: $!\n";
+ binmode(OUT, ":utf8")
+ }
+
+ if ($opts{c}) {
+ if (-r $opts{c}) {
+ # if config arg is absolute, fine; if not, prepend "./" as slightly
+ # less troublesome than putting "." in the @INC path.
+ my $rel = (File::Spec->file_name_is_absolute($opts{c}) ? "" : "./");
+ my $cnffile = "$rel$opts{c}";
+ verbose("requiring config file: $cnffile");
+ require $cnffile;
+ } else {
+ die "open config file ($opts{c}) for reading failed: $!\n";
+ }
+ }
+}
+
+
+sub verbose { print @_ if $::opts{v}; }
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/convert.t b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/convert.t
new file mode 100644
index 0000000000..9bd7a4f3d4
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/convert.t
@@ -0,0 +1,136 @@
+use strict;
+use warnings;
+
+use Test::More;
+use utf8;
+
+BEGIN{ use_ok( 'LaTeX::ToUnicode', qw( convert ) ); }
+
+binmode( STDOUT, ':utf8' );
+my @tests = (
+ [ '\LaTeX' => 'LaTeX' ],
+ [ '\$ \% \& \_ \{ \} \#' => '$ % & _ { } #' ],
+ [ '{\"{a}}' => 'ä' ],
+ [ '{\"a}' => 'ä' ],
+ [ '{\`{a}}' => 'à' ],
+ [ '{\`a}' => 'à' ],
+ [ '\ae' => 'æ' ],
+ [ '\L' => 'Ł' ],
+ [ "{\\'e}" => 'é'],
+ ['\={a}' => 'ā'],
+ ['{\=a}' => 'ā'],
+);
+
+foreach my $test ( @tests ) {
+ is( convert( $test->[0] ), $test->[1], "Convert $test->[0]" );
+}
+
+my @german_tests = (
+ [ '"a' => 'ä' ],
+ ['"`' => '„' ],
+ ["\"'" => '“' ],
+);
+
+foreach my $test ( @german_tests ) {
+ is( convert( $test->[0], german => 1 ), $test->[1], "Convert $test->[0], german => 1" );
+}
+
+binmode( DATA, ':utf8' );
+while (<DATA>) {
+ chomp;
+ my ( $tex, $result ) = split /\t/;
+ is( convert( $tex ), $result, "Convert $tex" );
+}
+close DATA;
+
+done_testing;
+
+__DATA__
+\& &
+{\`a} à
+{\^a} â
+{\~a} ã
+{\'a} á
+{\'{a}} á
+{\"a} ä
+{\`A} À
+{\'A} Á
+{\"A} Ä
+{\aa} å
+{\AA} Å
+{\ae} æ
+{\bf 12} 12
+{\'c} ć
+{\cal P} P
+{\c{c}} ç
+{\c{C}} Ç
+{\c{e}} ȩ
+{\c{s}} ş
+{\c{S}} Ş
+{\c{t}} ţ
+{\-d} d
+{\`e} è
+{\^e} ê
+{\'e} é
+{\"e} ë
+{\'E} É
+{\em bits} bits
+{\H{o}} ő
+{\`i} ì
+{\^i} î
+{\i} ı
+{\`i} ì
+{\'i} í
+{\"i} ï
+{\`\i} ì
+{\'\i} í
+{\"\i} ï
+{\`{\i}} ì
+{\'{\i}} í
+{\"{\i}} ï
+{\it Note} Note
+{\k{e}} ę
+{\l} ł
+{\-l} l
+{\log} log
+{\~n} ñ
+{\'n} ń
+{\^o} ô
+{\o} ø
+{\'o} ó
+{\"o} ö
+{\"{o}} ö
+{\'O} Ó
+{\"O} Ö
+{\"{O}} Ö
+{\rm always} always
+{\-s} s
+{\'s} ś
+{\sc JoiN} JoiN
+{\sl bit\/ \bf 7} bit 7
+{\sl L'Informatique Nouvelle} L’Informatique Nouvelle
+{\small and} and
+{\ss} ß
+{\TeX} TeX
+{\TM} ™
+{\tt awk} awk
+{\^u} û
+{\'u} ú
+{\"u} ü
+{\"{u}} ü
+{\'U} Ú
+{\"U} Ü
+{\u{a}} ă
+{\u{g}} ğ
+{\v{c}} č
+{\v{C}} Č
+{\v{e}} ě
+{\v{n}} ň
+{\v{r}} ř
+{\v{s}} š
+{\v{S}} Š
+{\v{z}} ž
+{\v{Z}} Ž
+{\'y} ý
+{\.{z}} ż
+Herv{\`e} Br{\"o}nnimann Hervè Brönnimann
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t
new file mode 100644
index 0000000000..3a818499f0
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t
@@ -0,0 +1,21 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use Test::More;
+
+eval "use Test::Pod::Coverage 1.08";
+plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage"
+ if $@;
+
+eval "use Pod::Coverage::TrustPod";
+plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage"
+ if $@;
+
+all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' });
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t
new file mode 100644
index 0000000000..d46a955694
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t
@@ -0,0 +1,15 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+use Test::More;
+
+eval "use Test::Pod 1.41";
+plan skip_all => "Test::Pod 1.41 required for testing POD" if $@;
+
+all_pod_files_ok();
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t
new file mode 100644
index 0000000000..7a83682539
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t
@@ -0,0 +1,16 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use Test::More;
+
+eval "use Test::Synopsis";
+plan skip_all => "Test::Synopsis required for testing synopses"
+ if $@;
+all_synopsis_ok('lib');
diff --git a/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/weaver.ini b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/weaver.ini
new file mode 100644
index 0000000000..1cc341ff23
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/LaTeX-ToUnicode/weaver.ini
@@ -0,0 +1,24 @@
+[-Encoding]
+[@CorePrep]
+
+[Name]
+[Version]
+
+[Region / prelude]
+
+[Generic / SYNOPSIS]
+[Generic / DESCRIPTION]
+[Generic / OVERVIEW]
+
+[Collect / ATTRIBUTES]
+command = attr
+
+[Collect / METHODS]
+command = method
+
+[Leftovers]
+
+[Region / postlude]
+
+[Authors]
+[Legal]
diff --git a/biblio/bibtex/utils/bibtexperllibs/Makefile b/biblio/bibtex/utils/bibtexperllibs/Makefile
new file mode 100644
index 0000000000..8baa7008f6
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/Makefile
@@ -0,0 +1,31 @@
+#
+# This is Makefile for TDS-compliant TeX distributions
+# Written by Boris Veytsman, boris@varphi.com
+#
+# This file is in public domain
+#
+
+PACKAGE = bibtexperllibs
+
+DIRS = BibTeX-Parser LaTeX-ToUnicode
+
+all:
+
+clean:
+ for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS clean); done
+
+
+lastrel = /home/ftp/tex-archive/support/bibtexperllibs
+diff:
+ diff -u0r $(lastrel) .
+
+distclean: clean
+ for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS distclean); done
+
+install:
+ for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS install); done
+
+archive:
+ for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS docs); done
+ for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS clean); done
+ COPYFILE_DISABLE=1 tar -czvf ../$(PACKAGE).tgz -C .. --exclude '*~' --exclude '*.tgz' --exclude CVS --exclude .git --exclude .gitignore --exclude blib --exclude "*.tar.gz" --exclude pm_to_blib $(PACKAGE)
diff --git a/biblio/bibtex/utils/bibtexperllibs/README b/biblio/bibtex/utils/bibtexperllibs/README
new file mode 100644
index 0000000000..1cf1e987e8
--- /dev/null
+++ b/biblio/bibtex/utils/bibtexperllibs/README
@@ -0,0 +1,53 @@
+ BibTeX Perl Libs
+ Version 1.91
+ Gerhard Gossen, Boris Veytsman, Karl Berry
+
+This package provides BibTeX-related Perl libraries by Gerhard Gossen,
+maintained and repackaged by Boris Veytsman for TeX Live and other
+TDS-compliant distributions. The libraries are written in pure Perl,
+so shoud work out of the box on any architecture.
+
+To use them in your scripts, add to the @INC variable the directory
+scripts/bibtexperllibs inside your TeX distribution. A script ltx2unitxt
+packages the conversion libraries for use from the command line.
+
+Bug reports, source code: https://github.com/borisveytsman/bibtexperllibs
+Releases: https://ctan.org/pkg/bibtexperllibs
+
+For an example of using the LaTeX::ToUnicode module, see the
+crossrefware package (which has also been the motivation for continued
+development here).
+
+Changes:
+
+ version 1.91 2024-08-27 Handle (ignore) simple \penalty commands and
+ \natexlab for natbib, and \textfrench for polyglossia.
+ doc updates.
+
+ version 1.9 2023-11-18 Braces are rendered correctly by LaTeX-ToUnicode.
+
+ version 1.8 2023-08-20 Tests updates, timestamp updates.
+
+ version 1.7 2021-01-20 LaTeX::ToUnicode 0.51 for still more
+ ltx2crossrefxml support, including simple html output.
+ (No changes to BibTeX::Parser.)
+
+ version 1.6 2020-12-10 LaTeX::ToUnicode 0.11 for more ltx2crossrefxml
+ support. (No changes to BibTeX::Parser.)
+
+ version 1.5 Upgraded BibTeX::Parser to 1.02 (bugfixes)
+
+ version 1.4 Upgraded BibTeX::Parser to 1.01
+
+ version 1.3 Upgraded BibTeX::Parser to 1.00
+
+ version 1.2 Upgraded BibTeX::Parser to v0.70 and LaTeX::ToUnicode to 0.05
+
+ version 1.1 Upgraded BibTeX::Parser to v0.69
+
+ version 1.0 Upgraded BibTeX::Parser to v0.68 and LaTeX::ToUnicode to 0.04
+
+ version 0.2 New upstream version for BibTeX::Parser (0.66)
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
diff --git a/biblio/citation-style-language/CHANGELOG.md b/biblio/citation-style-language/CHANGELOG.md
index 76bcc5c067..7a21395f0f 100644
--- a/biblio/citation-style-language/CHANGELOG.md
+++ b/biblio/citation-style-language/CHANGELOG.md
@@ -7,6 +7,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [0.6.4] - 2024-09-15
+
+### Fixed
+
+- Refactor `processCitationCluster()` to fix unexpected nil ([#77](https://github.com/zepinglee/citeproc-lua/issues/77)).
+
+## [0.6.3] - 2024-08-28
+
+### Added
+
+- Add support for citation affixes.
+
+### Fixed
+
+- Fix `\ref` with underscore in citation affixes ([#74](https://github.com/zepinglee/citeproc-lua/issues/74)).
+
+## [0.6.2] - 2024-08-21
+
+### Added
+
+- Add support for `perpage` package.
+
+### Fixed
+
+- Fix note position in multiple chapters ([#72](https://github.com/zepinglee/citeproc-lua/issues/72)).
+- Fix incorrect locale map of UKenglish.
+
+## [0.6.1] - 2024-08-15
+
+### Fixed
+
+- Fix parsing quotation marks ([#71](https://github.com/zepinglee/citeproc-lua/issues/71)).
+
+## [0.6.0] - 2024-07-31
+
+### Added
+
+- Add support for multiple bibliographies (`refsection` environment).
+- Add global `ref-section` option.
+
+### Fixed
+
+- Fix an error of empty locator in citation ([#70](https://github.com/zepinglee/citeproc-lua/discussions/70)).
+
+## [0.5.1] - 2024-07-10
+
+### Fixed
+
+- Fix a bug in font style flip-flopping with raw code ([#67](https://github.com/zepinglee/citeproc-lua/issues/67)).
+
+## [0.5.0] - 2024-06-09
+
+### Added
+
+- Add `\fullcite` command ([#64](https://github.com/zepinglee/citeproc-lua/issues/64)).
+- Add support for annotated bibliography ([#64](https://github.com/zepinglee/citeproc-lua/issues/64)).
+
+## Changed
+
+- Check if the `\cite` command is in a footnote.
+
## [0.4.9] - 2024-04-21
## Added
@@ -186,7 +247,14 @@ 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.4.9...HEAD
+[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.4...HEAD
+[0.6.4]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.3...v0.6.4
+[0.6.3]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.2...v0.6.3
+[0.6.2]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.1...v0.6.2
+[0.6.1]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.0...v0.6.1
+[0.6.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.5.1...v0.6.0
+[0.5.1]: https://github.com/zepinglee/citeproc-lua/compare/v0.5.0...v0.5.1
+[0.5.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.4.9...v0.5.0
[0.4.9]: https://github.com/zepinglee/citeproc-lua/compare/v0.4.8...v0.4.9
[0.4.8]: https://github.com/zepinglee/citeproc-lua/compare/v0.4.7...v0.4.8
[0.4.7]: https://github.com/zepinglee/citeproc-lua/compare/v0.4.6...v0.4.7
diff --git a/biblio/citation-style-language/american-medical-association.csl b/biblio/citation-style-language/american-medical-association.csl
index 86dd573abc..2b84d6e57a 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>2022-09-28T07:33:04-04:00</updated>
+ <updated>2024-08-04T17:48:30-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">
@@ -66,7 +66,7 @@
<group delimiter=". ">
<choose>
<if type="webpage post post-weblog" match="any">
- <date variable="issued" prefix="Published " form="text"/>
+ <date variable="issued" form="text"/>
</if>
</choose>
<group>
@@ -173,7 +173,7 @@
<if variable="URL">
<group delimiter=". " suffix=".">
<text variable="URL"/>
- <group prefix="Published ">
+ <group>
<date variable="issued">
<date-part name="month" suffix=" "/>
<date-part name="day" suffix=", "/>
diff --git a/biblio/citation-style-language/apa.csl b/biblio/citation-style-language/apa.csl
index ad86a91b7f..97fc1afd6c 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>2024-02-12T22:12:55-05:00</updated>
+ <updated>2024-08-27T14:44:31-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">
@@ -23,6 +23,10 @@
<single>ed. &amp; trans.</single>
<multiple>eds. &amp; trans.</multiple>
</term>
+ <term name="editor-translator" form="short">
+ <single>ed. &amp; trans.</single>
+ <multiple>eds. &amp; trans.</multiple>
+ </term>
<term name="translator" form="short">trans.</term>
<term name="interviewer" form="short">
<single>interviewer</single>
@@ -32,6 +36,7 @@
<single>ed.</single>
<multiple>eds.</multiple>
</term>
+ <term name="performer" form="verb">recorded by</term>
<term name="circa" form="short">ca.</term>
<term name="bc"> B.C.E.</term>
<term name="ad"> C.E.</term>
@@ -41,7 +46,12 @@
</term>
<term name="software">computer software</term>
<term name="at" form="long">before the</term>
+ <term name="collection">archival collection</term>
+ <term name="post">online post</term>
+ <term name="at" form="long">before the</term>
<term name="hearing" form="verb">testimony of</term>
+ <term name="review-of" form="long">review of the</term>
+ <term name="review-of" form="short">review of</term>
</terms>
</locale>
<locale xml:lang="da">
@@ -82,101 +92,172 @@
<term name="et-al">et al.</term>
</terms>
</locale>
- <!-- TODO: New types: classic collection document event hearing performance periodical regulation -software- standard -->
- <!-- TODO: New creator roles: chair compiler contributor curator executive-producer guest host narrator organizer performer producer script-writer series-creator -->
- <!-- TODO: New variables:
- available-date submitted
- part-number printing-number supplement-number
- part-title volume-title
- archive_collection
- division jurisdiction
- event-title
- language
- license
- reviewed-genre
+ <!-- For Indigeneous Knowledge, assume the item is stored as `document` or `speech`
+ and that Nation/Community, treaty, where the Elder lives,
+ and topic are all stored in `title`
+ cf. https://libguides.norquest.ca/c.php?g=314831&p=5188823.
+ If the item is stored as `interview`, assume that Nation/Community, treat, and topic
+ are stored in `title`, 'Oral teaching' or similar is stored in `archive`, and where
+ the Elder lives is stored in `archive-place`.
-->
- <!-- TODO: New terms:
- advance-online-publication
- album on audio-recording
- original-work-published
- personal-communication
- preprint
- review-of
- item types
+ <!-- Reviews are detected if an item has type `review` or `review-book` or if it has any of the variables
+ `reviewed-title`, `reviewed-author`, or `reviewed-genre`. For the latter case, reviews are commonly
+ stored as types `article-journal`, `article-magazine`, `article-newspaper`, `post-weblog`, or `webpage`
-->
- <!-- TODO: Check Indigeneous Knowledge format -->
<!-- General categories of item types:
- Periodical: article-journal article-magazine article-newspaper post-weblog review review-book
+ Periodical: article-journal article-magazine article-newspaper periodical post-weblog review review-book
Periodical or Booklike: paper-conference
Booklike: article book broadcast chapter classic collection dataset document
entry entry-dictionary entry-encyclopedia event figure
- graphic interview manuscript map motion_picture musical_score pamphlet patent
- performance periodical personal_communication post report
+ graphic interview manuscript map motion_picture musical_score
+ pamphlet patent performance personal_communication post report
software song speech standard thesis webpage
Legal: bill hearing legal_case legislation regulation treaty
-->
+ <!-- Equivalencies:
+ classic == book
+ document == report, but give full date
+ standard == report
+ performance == speech
+ event == speech
+ collection == book, but give full date
+ -->
+ <!-- Role equivalencies:
+ compiler == editor
+ organizer, curator == chair
+ script-writer == director
+ producer == director (but don't print both)
+ guest, host == director
+ series-creator, executive-producer == editor
+ -->
<!-- APA references contain four parts: author, date, title, source -->
<macro name="author-bib">
- <!-- TODO: New creator roles (media, contributor) -->
- <!-- TODO: Add new item types -->
- <names variable="composer" delimiter=", ">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <substitute>
- <names variable="author"/>
- <names variable="illustrator"/>
- <names variable="director">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="long" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <choose>
- <if variable="container-title">
- <choose>
- <if type="book entry entry-dictionary entry-encyclopedia" match="any">
- <choose>
- <if variable="title">
- <group delimiter=" ">
- <text macro="title"/>
- <text macro="parenthetical"/>
- </group>
- </if>
- <else>
- <text macro="title-and-descriptions"/>
- </else>
- </choose>
- </if>
- </choose>
- </if>
- </choose>
- <!-- TODO: Test for editortranslator and put that first as that becomes available -->
- <names variable="editor" delimiter=", ">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <names variable="editorial-director">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <names variable="collection-editor">
- <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=" (" suffix=")" text-case="title"/>
- </names>
- <choose>
- <if variable="title">
- <group delimiter=" ">
- <text macro="title"/>
- <text macro="parenthetical"/>
- </group>
- </if>
- <else>
- <text macro="title-and-descriptions"/>
- </else>
- </choose>
- </substitute>
- </names>
+ <group delimiter=" ">
+ <names variable="composer" delimiter=", ">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <substitute>
+ <names variable="author"/>
+ <!-- Note: `narrator` only cited in secondary-contributors -->
+ <names variable="illustrator"/>
+ <!-- TODO: Replace `delimiter` with `collapse` to combine names variables when that becomes available. -->
+ <choose>
+ <if type="broadcast">
+ <names variable="script-writer director" delimiter=", &amp; ">
+ <!-- Note: Actors/performers and producers [not executive] not cited in APA style. -->
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ </if>
+ </choose>
+ <names variable="director">
+ <!-- For non-broadcast items, APA only cites directors and not writers. -->
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <!-- TODO: Replace `delimiter` with `collapse` to combine names variables when that becomes available. -->
+ <names variable="guest host" delimiter=", &amp; ">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="producer">
+ <!-- Note: Producers not cited if there is a writer/director, but use if they are the principle creator. -->
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <choose>
+ <if variable="container-title">
+ <choose>
+ <if type="book classic collection entry entry-dictionary entry-encyclopedia" match="any">
+ <!-- Items with book-like container-title substitute with their title and parenthetical,
+ but leave bracketed after container-title. This mimics the `container-booklike` formatting. -->
+ <choose>
+ <if variable="title">
+ <group delimiter=" ">
+ <text macro="title"/>
+ <text macro="parenthetical"/>
+ </group>
+ </if>
+ <else>
+ <text macro="title-and-descriptions"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ <names variable="executive-producer">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="series-creator">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="editor-translator">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <!-- Note: Translator is not cited as a primary creator (only as Ed. & Trans.). -->
+ <names variable="editor">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="editorial-director">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="compiler">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <choose>
+ <if type="event performance speech" match="any">
+ <names variable="chair">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="organizer">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ </if>
+ </choose>
+ <names variable="curator">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="long" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <names variable="collection-editor">
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=" (" suffix=")" text-case="title"/>
+ </names>
+ <choose>
+ <if variable="title">
+ <!-- If an item has a title, substitute missing author with title and parenthetical, but leave bracketed
+ after the date (in the 'title' position). -->
+ <group delimiter=" ">
+ <text macro="title"/>
+ <text macro="parenthetical"/>
+ </group>
+ </if>
+ <else>
+ <!-- If an item has no title, substitute with bracketed followed by parenthetical. -->
+ <text macro="title-and-descriptions"/>
+ </else>
+ </choose>
+ </substitute>
+ </names>
+ <choose>
+ <!-- Print "with" contributor for books, but not for other types that commonly have them (eg, thesis, software) -->
+ <if type="book classic collection" match="any">
+ <names variable="contributor" prefix="(" suffix=")">
+ <label form="verb" suffix=" "/>
+ <name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
+ </names>
+ </if>
+ </choose>
+ </group>
</macro>
<macro name="author-intext">
- <!-- TODO: New creator roles -->
- <!-- TODO: Add new item types -->
<choose>
<if type="bill hearing legal_case legislation regulation treaty" match="any">
<text macro="title-intext"/>
@@ -212,18 +293,37 @@
<substitute>
<names variable="author"/>
<names variable="illustrator"/>
+ <!-- TODO: Replace `delimiter` with `collapse` to combine names variables when that becomes available. -->
+ <choose>
+ <if type="broadcast">
+ <names variable="script-writer director" delimiter=", &amp; "/>
+ </if>
+ </choose>
<names variable="director"/>
+ <!-- TODO: Replace `delimiter` with `collapse` to combine names variables when that becomes available. -->
+ <names variable="guest host" delimiter=", &amp; "/>
+ <names variable="producer"/>
<choose>
<if variable="container-title">
<choose>
- <if type="book entry entry-dictionary entry-encyclopedia" match="any">
+ <if type="book classic collection entry entry-dictionary entry-encyclopedia" match="any">
<text macro="title-intext"/>
</if>
</choose>
</if>
</choose>
+ <names variable="executive-producer"/>
+ <names variable="series-creator"/>
<names variable="editor"/>
<names variable="editorial-director"/>
+ <names variable="compiler"/>
+ <choose>
+ <if type="event performance speech" match="any">
+ <names variable="chair"/>
+ <names variable="organizer"/>
+ </if>
+ </choose>
+ <names variable="curator"/>
<text macro="title-intext"/>
</substitute>
</names>
@@ -241,7 +341,6 @@
</choose>
</macro>
<macro name="date-bib">
- <!-- TODO: Add new item types -->
<group delimiter=" " prefix="(" suffix=")">
<choose>
<if is-uncertain-date="issued">
@@ -257,7 +356,7 @@
<text variable="year-suffix"/>
</group>
<choose>
- <if type="article-magazine article-newspaper broadcast interview motion_picture pamphlet personal_communication post post-weblog song speech webpage" match="any">
+ <if type="article-magazine article-newspaper broadcast collection document event interview motion_picture pamphlet performance personal_communication post post-weblog song speech webpage" match="any">
<!-- Many video and audio examples in manual give full dates. Err on the side of too much information. -->
<date variable="issued">
<date-part name="month"/>
@@ -267,7 +366,7 @@
<else-if type="paper-conference">
<!-- Capture 'speech' stored as 'paper-conference' -->
<choose>
- <if variable="collection-editor editor editorial-director issue page volume" match="none">
+ <if variable="collection-editor compiler editor editorial-director issue page volume" match="none">
<date variable="issued">
<date-part name="month"/>
<date-part name="day" prefix=" "/>
@@ -275,14 +374,14 @@
</if>
</choose>
</else-if>
- <!-- 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 -->
+ <!-- Only year: article article-journal book chapter classic entry entry-dictionary entry-encyclopedia dataset figure graphic
+ manuscript map musical_score paper-conference[published] patent periodical report review review-book software standard thesis -->
</choose>
</group>
</if>
<else-if variable="status">
<group>
- <!-- TODO: Should I print status as-is, or should I print the in-press term? -->
+ <!-- We print the status variable directly rather than using in-press, etc. terms. -->
<text variable="status" text-case="lowercase"/>
<text variable="year-suffix" prefix="-"/>
</group>
@@ -296,6 +395,7 @@
</group>
</macro>
<macro name="date-sort">
+ <!-- This is necessary to ensure that citeproc sorts all item types chonologically in the same list. -->
<choose>
<if type="article article-journal book chapter entry entry-dictionary entry-encyclopedia dataset figure graphic manuscript map musical_score patent report review review-book thesis" match="any">
<date variable="issued" date-parts="year" form="numeric"/>
@@ -303,7 +403,7 @@
<else-if type="paper-conference">
<!-- Capture 'speech' stored as 'paper-conference' -->
<choose>
- <if variable="collection-editor editor editorial-director issue page volume" match="any">
+ <if variable="collection-editor compiler editor editorial-director issue page volume" match="any">
<date variable="issued" date-parts="year" form="numeric"/>
</if>
<else>
@@ -339,7 +439,6 @@
</choose>
</macro>
<macro name="date-intext">
- <!-- TODO: Add new item types -->
<choose>
<if variable="issued">
<group delimiter="/">
@@ -387,7 +486,7 @@
</group>
</if>
<else-if variable="status">
- <!-- TODO: Should I print status as-is, or should I print the in-press term? -->
+ <!-- We print the status variable directly rather than using in-press, etc. terms. -->
<text variable="status" text-case="lowercase"/>
<text variable="year-suffix" prefix="-"/>
</else-if>
@@ -398,7 +497,7 @@
</choose>
</macro>
<!-- APA has two description elements following the title:
- title (parenthetical) [bracketed] -->
+ title (parenthetical) [bracketed] -->
<macro name="title-and-descriptions">
<choose>
<if variable="title">
@@ -429,64 +528,121 @@
</choose>
</macro>
<macro name="title">
- <!-- TODO: Add new item types -->
<choose>
<if type="post webpage" match="any">
<!-- Webpages are always italicized -->
- <text variable="title" font-style="italic"/>
+ <text macro="title-plus-part-title" font-style="italic"/>
</if>
- <else-if variable="container-title" match="any">
- <!-- Other types are italicized based on presence of container-title.
+ <!-- Other types are italicized based on presence of container-title.
Assume that review and review-book are published in periodicals/blogs,
not just on a web page (ex. 69) -->
- <text variable="title"/>
+ <else-if type="article-journal article-magazine article-newspaper periodical post-weblog review review-book" match="any">
+ <text macro="periodical-title"/>
</else-if>
- <else>
+ <else-if type="paper-conference">
+ <!-- Treat paper-conference as book-like if it has an editor, otherwise as periodical-like -->
<choose>
- <if type="article-journal article-magazine article-newspaper post-weblog review review-book" match="any">
- <text variable="title" font-style="italic"/>
+ <if variable="collection-editor compiler editor editorial-director" match="any">
+ <text macro="booklike-title"/>
</if>
- <else-if type="paper-conference">
- <choose>
- <if variable="collection-editor editor editorial-director" match="any">
- <group delimiter=": " font-style="italic">
- <text variable="title"/>
- <!-- TODO: Replace with volume-title -->
- <choose>
- <if is-numeric="volume" match="none">
- <group delimiter=" ">
- <label variable="volume" form="short" text-case="capitalize-first"/>
- <text variable="volume"/>
- </group>
- </if>
- </choose>
- </group>
- </if>
- <else>
- <text variable="title" font-style="italic"/>
- </else>
- </choose>
- </else-if>
<else>
- <group delimiter=": " font-style="italic">
+ <text macro="periodical-title"/>
+ </else>
+ </choose>
+ </else-if>
+ <else>
+ <text macro="booklike-title"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="periodical-title">
+ <!-- For periodicals, assume that part-number and part-title refer to the article and append to title -->
+ <choose>
+ <if variable="container-title" match="any">
+ <text macro="title-plus-part-title"/>
+ </if>
+ <else>
+ <!-- for periodical items without container titles, don't append volume-title to title -->
+ <text macro="title-plus-part-title" font-style="italic"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="booklike-title">
+ <!-- For book-like items, assume part-number and part-title refer to the book/volume. -->
+ <choose>
+ <if variable="container-title" match="any">
+ <text variable="title"/>
+ </if>
+ <else>
+ <!-- For book-like items without container titles and with volume-title, append volume-title to title (ex. 30) -->
+ <text macro="title-plus-volume-title" font-style="italic"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="title-plus-part-title">
+ <choose>
+ <if variable="reviewed-author reviewed-genre reviewed-title" type="review review-book" match="any">
+ <!-- If a review has no `reviewed-title`, assume that `title` contains the title of the reviewed work
+ and omit it here; it is printed in the `reviewed-item` macro. -->
+ <choose>
+ <if variable="reviewed-title" match="none"/>
+ <else>
+ <group delimiter=": ">
<text variable="title"/>
- <!-- TODO: Replace with volume-title -->
- <choose>
- <if is-numeric="volume" match="none">
- <group delimiter=" ">
- <label variable="volume" form="short" text-case="capitalize-first"/>
- <text variable="volume"/>
- </group>
- </if>
- </choose>
+ <text macro="part-title"/>
</group>
</else>
</choose>
+ </if>
+ <else>
+ <group delimiter=": ">
+ <text variable="title"/>
+ <text macro="part-title"/>
+ </group>
</else>
</choose>
</macro>
+ <macro name="part-title">
+ <group delimiter=". ">
+ <group delimiter=" ">
+ <label variable="part-number" form="short" text-case="capitalize-first"/>
+ <text variable="part-number"/>
+ </group>
+ <text variable="part-title" text-case="capitalize-first"/>
+ </group>
+ </macro>
+ <macro name="title-plus-volume-title">
+ <group delimiter=": ">
+ <text variable="title"/>
+ <text macro="volume-title"/>
+ </group>
+ </macro>
+ <macro name="volume-title">
+ <group delimiter=": ">
+ <choose>
+ <if variable="volume-title">
+ <group delimiter=" ">
+ <group delimiter=". ">
+ <group delimiter=" ">
+ <label variable="volume" form="short" text-case="capitalize-first"/>
+ <text variable="volume"/>
+ </group>
+ <text variable="volume-title"/>
+ </group>
+ </group>
+ </if>
+ <else-if is-numeric="volume" match="none">
+ <group delimiter=" ">
+ <label variable="volume" form="short" text-case="capitalize-first"/>
+ <text variable="volume"/>
+ </group>
+ </else-if>
+ </choose>
+ <!-- For book-like items, assume part-number and part-title refer to the book/volume. -->
+ <text macro="part-title"/>
+ </group>
+ </macro>
<macro name="title-intext">
- <!-- TODO: Add new item types -->
<choose>
<if type="bill report">
<!-- Bills, resolutions, and congressional reports are not italicized and substitute bill number if no title. -->
@@ -544,7 +700,6 @@
</choose>
</macro>
<macro name="parenthetical">
- <!-- TODO: Add new item types -->
<!-- (Secondary contributors; Database location; Genre no. 123; Report Series 123, Version, Edition, Volume, Page) -->
<group prefix="(" suffix=")">
<choose>
@@ -604,7 +759,7 @@
<text macro="secondary-contributors"/>
<choose>
<if type="broadcast graphic map motion_picture song" match="any">
- <!-- For audiovisual media, number information comes after title, not container-title -->
+ <!-- For audiovisual media, number information comes after title, not container-title (ex. 94) -->
<text macro="number"/>
</if>
</choose>
@@ -622,7 +777,6 @@
</group>
</macro>
<macro name="parenthetical-container">
- <!-- TODO: Add new item types -->
<choose>
<if variable="container-title" match="any">
<group prefix="(" suffix=")">
@@ -630,7 +784,7 @@
<text macro="database-location"/>
<choose>
<if type="broadcast graphic map motion_picture song" match="none">
- <!-- For audiovisual media, number information comes after title, not container-title -->
+ <!-- For audiovisual media, number information comes after title, not container-title (ex. 94) -->
<text macro="number"/>
</if>
</choose>
@@ -641,65 +795,12 @@
</choose>
</macro>
<macro name="bracketed">
- <!-- TODO: Add new item types -->
<!-- [Descriptive information] -->
<!-- If there is a number, genre is already printed in macro="number" -->
<group prefix="[" suffix="]">
<choose>
- <if variable="reviewed-author reviewed-title" type="review review-book" match="any">
- <!-- Reviewed item -->
- <group delimiter="; ">
- <group delimiter=", ">
- <group delimiter=" ">
- <!-- Assume that genre is entered as 'Review of the book' or similar -->
- <choose>
- <if variable="number" match="none">
- <choose>
- <if variable="genre">
- <text variable="genre" text-case="capitalize-first"/>
- </if>
- <else-if variable="medium">
- <text variable="medium" text-case="capitalize-first"/>
- </else-if>
- <else>
- <!-- TODO: Replace with term="review" -->
- <!-- TODO: Handle review vs review-of depending on presence of reviewed-title -->
- <!-- TODO: Add reviewed-genre -->
- <text value="Review of"/>
- </else>
- </choose>
- </if>
- <else>
- <choose>
- <if variable="medium">
- <text variable="medium" text-case="capitalize-first"/>
- </if>
- <else>
- <!-- TODO: Replace with term="review" -->
- <!-- TODO: Handle review vs review-of depending on presence of reviewed-title -->
- <!-- TODO: Add reviewed-genre -->
- <text value="Review of"/>
- </else>
- </choose>
- </else>
- </choose>
- <text macro="reviewed-title"/>
- </group>
- <names variable="reviewed-author">
- <label form="verb-short" suffix=" "/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- </group>
- <choose>
- <if variable="genre" match="any">
- <choose>
- <if variable="number" match="none">
- <text variable="medium" text-case="capitalize-first"/>
- </if>
- </choose>
- </if>
- </choose>
- </group>
+ <if variable="reviewed-author reviewed-genre reviewed-title" type="review review-book" match="any">
+ <text macro="reviewed-item"/>
</if>
<else-if type="thesis">
<!-- Thesis type and institution -->
@@ -731,7 +832,7 @@
<group delimiter=" ">
<text variable="genre" text-case="capitalize-first"/>
<group delimiter=" ">
- <text term="author" form="verb"/>
+ <text term="container-author" form="verb"/>
<names variable="interviewer">
<name and="symbol" initialize-with=". " delimiter=", "/>
</names>
@@ -814,22 +915,35 @@
<choose>
<if variable="genre">
<text variable="genre" text-case="capitalize-first"/>
- <!-- TODO: Replace prefix with performer label -->
- <names variable="author" prefix="recorded by ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
+ <group delimiter=" ">
+ <text term="performer" form="verb"/>
+ <names variable="author">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <substitute>
+ <names variable="performer"/>
+ </substitute>
+ </names>
+ </group>
</if>
<else-if variable="medium">
<text variable="medium" text-case="capitalize-first"/>
- <!-- TODO: Replace prefix with performer label -->
- <names variable="author" prefix="recorded by ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
+ <group delimiter=" ">
+ <text term="performer" form="verb"/>
+ <names variable="author">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <substitute>
+ <names variable="performer"/>
+ </substitute>
+ </names>
+ </group>
</else-if>
<else>
- <!-- TODO: Replace prefix with performer label -->
- <names variable="author" prefix="Recorded by ">
+ <text term="performer" form="verb" text-case="capitalize-first"/>
+ <names variable="author">
<name and="symbol" initialize-with=". " delimiter=", "/>
+ <substitute>
+ <names variable="performer"/>
+ </substitute>
</names>
</else>
</choose>
@@ -840,15 +954,23 @@
<choose>
<if variable="medium">
<text variable="medium" text-case="capitalize-first"/>
- <!-- TODO: Replace prefix with performer label -->
- <names variable="author" prefix="recorded by ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
+ <group delimiter=" ">
+ <text term="performer" form="verb"/>
+ <names variable="author">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <substitute>
+ <names variable="performer"/>
+ </substitute>
+ </names>
+ </group>
</if>
<else>
- <!-- TODO: Replace prefix with performer label -->
- <names variable="author" prefix="Recorded by ">
+ <text term="performer" form="verb" text-case="capitalize-first"/>
+ <names variable="author">
<name and="symbol" initialize-with=". " delimiter=", "/>
+ <substitute>
+ <names variable="performer"/>
+ </substitute>
</names>
</else>
</choose>
@@ -871,16 +993,17 @@
<text macro="format"/>
</else-if>
<else>
- <!-- For conference presentations, chapters in reports, software, place bracketed after the container title -->
+ <!-- For conference presentations/performances/events, chapters in reports/standards/generic documents, software,
+ place bracketed after the container title -->
<choose>
- <if type="paper-conference speech" match="any">
+ <if type="event paper-conference performance speech" match="any">
<choose>
- <if variable="collection-editor editor editorial-director issue page volume" match="any">
+ <if variable="collection-editor compiler editor editorial-director issue page volume" match="any">
<text macro="format"/>
</if>
</choose>
</if>
- <else-if type="report software" match="none">
+ <else-if type="document report software standard" match="none">
<text macro="format"/>
</else-if>
</choose>
@@ -889,10 +1012,9 @@
</group>
</macro>
<macro name="bracketed-intext">
- <!-- TODO: Add new item types -->
<group prefix="[" suffix="]">
<choose>
- <if variable="reviewed-author reviewed-title" type="review review-book" match="any">
+ <if variable="reviewed-title" match="any">
<group delimiter=" ">
<text term="review-of" text-case="capitalize-first"/>
<text macro="reviewed-title-intext"/>
@@ -937,14 +1059,80 @@
</choose>
</group>
</macro>
+ <macro name="reviewed-item">
+ <!-- Reviewed item -->
+ <group delimiter="; ">
+ <group delimiter=", ">
+ <group delimiter=" ">
+ <choose>
+ <if variable="reviewed-genre">
+ <group delimiter=" ">
+ <text term="review-of" form="long" text-case="capitalize-first"/>
+ <text variable="reviewed-genre" text-case="lowercase"/>
+ </group>
+ </if>
+ <!-- If no `reviewed-genre`, assume that `genre` or `medium` is entered as 'Review of the book' or similar -->
+ <else-if variable="number" match="none">
+ <choose>
+ <if variable="genre">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ <else-if variable="medium">
+ <text variable="medium" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="review-book">
+ <group delimiter=" ">
+ <text term="review-of" form="long" text-case="capitalize-first"/>
+ <text term="book" form="long" text-case="lowercase"/>
+ </group>
+ </else-if>
+ <else>
+ <text term="review-of" form="short" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ </else-if>
+ <else>
+ <choose>
+ <if variable="medium">
+ <text variable="medium" text-case="capitalize-first"/>
+ </if>
+ <else-if type="review-book">
+ <group delimiter=" ">
+ <text term="review-of" form="long" text-case="capitalize-first"/>
+ <text term="book" form="long" text-case="lowercase"/>
+ </group>
+ </else-if>
+ <else>
+ <text term="review-of" form="short" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ </else>
+ </choose>
+ <text macro="reviewed-title"/>
+ </group>
+ <names variable="reviewed-author">
+ <label form="verb-short" suffix=" "/>
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ </names>
+ </group>
+ <choose>
+ <if variable="genre" match="any">
+ <choose>
+ <if variable="number" match="none">
+ <text variable="medium" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ </group>
+ </macro>
<macro name="bracketed-container">
- <!-- TODO: Add new item types -->
<group prefix="[" suffix="]">
<choose>
- <if type="paper-conference speech" match="any">
+ <if type="event paper-conference performance speech" match="any">
<!-- Conference presentations should describe the session [container] in bracketed unless published in a proceedings -->
<choose>
- <if variable="collection-editor editor editorial-director issue page volume" match="none">
+ <if variable="collection-editor compiler editor editorial-director issue page volume" match="none">
<text macro="format"/>
</if>
</choose>
@@ -953,23 +1141,21 @@
<!-- For entries in mobile app reference works, place bracketed after the container-title -->
<text macro="format"/>
</else-if>
- <else-if type="report">
- <!-- For chapters in reports, place bracketed after the container title -->
+ <else-if type="document report standard">
+ <!-- For chapters in report, standards, and generic documents, place bracketed after the container title -->
<text macro="format"/>
</else-if>
</choose>
</group>
</macro>
<macro name="secondary-contributors">
- <!-- TODO: Add new item types -->
- <!-- TODO: Add new creator roles -->
<choose>
- <if type="article-journal article-magazine article-newspaper post-weblog review review-book" match="any">
+ <if type="article-journal article-magazine article-newspaper periodical post-weblog review review-book" match="any">
<text macro="secondary-contributors-periodical"/>
</if>
<else-if type="paper-conference">
<choose>
- <if variable="collection-editor editor editorial-director" match="any">
+ <if variable="collection-editor compiler editor editorial-director" match="any">
<text macro="secondary-contributors-booklike"/>
</if>
<else>
@@ -992,14 +1178,13 @@
</names>
</if>
</choose>
- <names variable="translator" delimiter="; ">
+ <names variable="translator narrator" delimiter="; ">
<name and="symbol" initialize-with=". " delimiter=", "/>
<label form="short" prefix=", " text-case="title"/>
</names>
</group>
</macro>
<macro name="secondary-contributors-booklike">
- <!-- TODO: Add new item types -->
<group delimiter="; ">
<choose>
<if variable="title">
@@ -1009,24 +1194,44 @@
</names>
</if>
</choose>
- <!-- TODO: When editortranslator becomes available, add a test: variable="editortranslator" match="none"; then print translator -->
<choose>
<if type="post webpage" match="none">
<!-- Webpages treat container-title like publisher -->
- <choose>
- <if variable="container-title" match="none">
- <group delimiter="; ">
- <names variable="container-author">
- <label form="verb-short" suffix=" " text-case="title"/>
- <name and="symbol" initialize-with=". " delimiter=", "/>
- </names>
- <names variable="editor translator" delimiter="; ">
- <name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" prefix=", " text-case="title"/>
- </names>
- </group>
- </if>
- </choose>
+ <group delimiter="; ">
+ <names variable="illustrator narrator" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" prefix=", " text-case="title"/>
+ </names>
+ <choose>
+ <if variable="container-title" match="none">
+ <group delimiter="; ">
+ <names variable="container-author">
+ <label form="verb-short" suffix=" " text-case="title"/>
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ </names>
+ <names variable="editor translator" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" prefix=", " text-case="title"/>
+ </names>
+ <names variable="compiler chair organizer curator series-creator executive-producer" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="long" prefix=", " text-case="title"/>
+ </names>
+ </group>
+ </if>
+ <else>
+ <choose>
+ <!-- TODO: Check logic once processors start to automatically populate editor-translator. -->
+ <if variable="editor-translator" match="none">
+ <names variable="translator" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" prefix=", " text-case="title"/>
+ </names>
+ </if>
+ </choose>
+ </else>
+ </choose>
+ </group>
</if>
<else>
<group delimiter="; ">
@@ -1038,6 +1243,14 @@
<name and="symbol" initialize-with=". " delimiter=", "/>
<label form="short" prefix=", " text-case="title"/>
</names>
+ <names variable="illustrator narrator" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" prefix=", " text-case="title"/>
+ </names>
+ <names variable="compiler chair organizer curator series-creator executive-producer" delimiter="; ">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="long" prefix=", " text-case="title"/>
+ </names>
</group>
</else>
</choose>
@@ -1047,13 +1260,11 @@
<choose>
<if variable="archive-place" match="none">
<!-- With `archive-place`: physical archives. Without: online archives. -->
- <!-- TODO: Add archive_collection -->
<text variable="archive_location"/>
</if>
</choose>
</macro>
<macro name="number">
- <!-- TODO: Add new item types -->
<choose>
<if variable="number">
<group delimiter=", ">
@@ -1079,12 +1290,11 @@
</choose>
</macro>
<macro name="locators-booklike">
- <!-- TODO: Add new item types -->
<choose>
- <if type="article-journal article-magazine article-newspaper broadcast interview patent post post-weblog review review-book speech webpage" match="any"/>
+ <if type="article-journal article-magazine article-newspaper broadcast event interview patent performance periodical post post-weblog review review-book speech webpage" match="any"/>
<else-if type="paper-conference">
<choose>
- <if variable="collection-editor editor editorial-director" match="any">
+ <if variable="collection-editor compiler editor editorial-director" match="any">
<group delimiter=", ">
<text macro="version"/>
<text macro="edition"/>
@@ -1103,17 +1313,10 @@
</choose>
</macro>
<macro name="version">
- <choose>
- <if is-numeric="version">
- <group delimiter=" ">
- <label variable="version" text-case="capitalize-first"/>
- <text variable="version"/>
- </group>
- </if>
- <else>
- <text variable="version"/>
- </else>
- </choose>
+ <group delimiter=" ">
+ <label variable="version" text-case="capitalize-first"/>
+ <text variable="version"/>
+ </group>
</macro>
<macro name="edition">
<choose>
@@ -1129,23 +1332,26 @@
</choose>
</macro>
<macro name="volume-booklike">
- <!-- TODO: Add new item types -->
<group delimiter=", ">
<!-- Report series [ex. 52] -->
<choose>
- <if type="report">
+ <if type="document report standard">
<group delimiter=" ">
<text variable="collection-title" text-case="title"/>
<text variable="collection-number"/>
</group>
</if>
</choose>
+ <group delimiter=" ">
+ <label variable="supplement-number" text-case="capitalize-first"/>
+ <text variable="supplement-number"/>
+ </group>
<choose>
<if variable="volume" match="any">
- <!-- TODO: Update using volume-title -->
<choose>
<!-- Non-numeric volumes are already printed as part of the book title -->
- <if is-numeric="volume" match="none"/>
+ <if variable="volume-title"/>
+ <else-if is-numeric="volume" match="none"/>
<else>
<group delimiter=" ">
<label variable="volume" form="short" text-case="capitalize-first"/>
@@ -1176,7 +1382,8 @@
<choose>
<if variable="reviewed-title">
<!-- Not possible to distinguish TV series episode from other reviewed
- works [Ex. 69] -->
+ works without reviewed-container-title [Ex. 69] -->
+ <!-- Adapt for reviewed-container-title if that becomes available -->
<text variable="reviewed-title" font-style="italic"/>
</if>
<else>
@@ -1188,7 +1395,9 @@
<macro name="reviewed-title-intext">
<choose>
<if variable="reviewed-title">
- <!-- Not possible to distinguish TV series episode from other reviewed works [Ex. 69] -->
+ <!-- Not possible to distinguish TV series episode from other reviewed
+ works without reviewed-container-title [Ex. 69] -->
+ <!-- Adapt for reviewed-container-title if that becomes available -->
<text variable="reviewed-title" form="short" font-style="italic" text-case="title"/>
</if>
<else>
@@ -1198,7 +1407,6 @@
</choose>
</macro>
<macro name="format">
- <!-- TODO: Add new item types -->
<choose>
<if variable="genre medium" match="any">
<group delimiter="; ">
@@ -1210,31 +1418,12 @@
<text variable="medium" text-case="capitalize-first"/>
</group>
</if>
- <!-- Generic labels for specific types -->
- <!-- TODO: Add terms for other types? -->
- <else-if type="dataset">
- <text term="dataset"/>
- </else-if>
- <else-if type="software">
- <text term="software" text-case="capitalize-first"/>
- </else-if>
- <else-if type="interview personal_communication" match="any">
- <choose>
- <if variable="archive container-title DOI publisher URL" match="none">
- <text term="personal-communication" text-case="capitalize-first"/>
- </if>
- <else-if type="interview">
- <text term="interview" text-case="capitalize-first"/>
- </else-if>
- </choose>
- </else-if>
- <else-if type="map">
- <text term="map" text-case="capitalize-first"/>
- </else-if>
+ <else>
+ <text macro="generic-type-label"/>
+ </else>
</choose>
</macro>
<macro name="format-intext">
- <!-- TODO: Add new item types -->
<choose>
<if variable="genre" match="any">
<text variable="genre" text-case="capitalize-first"/>
@@ -1242,11 +1431,17 @@
<else-if variable="medium">
<text variable="medium" text-case="capitalize-first"/>
</else-if>
- <!-- Generic labels for specific types -->
- <!-- TODO: Add terms for other types? -->
- <else-if type="dataset">
- <text term="dataset"/>
- </else-if>
+ <else>
+ <text macro="generic-type-label"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="generic-type-label">
+ <!-- Generic labels for specific types -->
+ <choose>
+ <if type="dataset">
+ <text term="dataset" text-case="capitalize-first"/>
+ </if>
<else-if type="software">
<text term="software" text-case="capitalize-first"/>
</else-if>
@@ -1261,21 +1456,47 @@
</choose>
</else-if>
<else-if type="map">
- <text term="map"/>
+ <text term="map" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="collection">
+ <text term="collection" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="song">
+ <text term="song" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="motion_picture">
+ <text term="motion_picture" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="post">
+ <text term="post" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="review">
+ <text term="review" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="review-book">
+ <text term="review-book" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="broadcast">
+ <text term="broadcast" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="figure">
+ <text term="figure" text-case="capitalize-first"/>
+ </else-if>
+ <else-if type="graphic">
+ <text term="graphic" text-case="capitalize-first"/>
</else-if>
</choose>
</macro>
<!-- APA 'source' element contains four parts:
container, event, publisher, access -->
<macro name="container">
- <!-- TODO: Add new item types -->
<choose>
- <if type="article-journal article-magazine article-newspaper post-weblog review review-book" match="any">
+ <if type="article-journal article-magazine article-newspaper periodical post-weblog review review-book" match="any">
<!-- Periodical items -->
<text macro="container-periodical"/>
</if>
<else-if type="paper-conference">
- <!-- Determine if paper-conference is a periodical or booklike -->
+ <!-- Determine if paper-conference is a periodical- or book-like -->
<choose>
<if variable="editor editorial-director collection-editor container-author" match="any">
<text macro="container-booklike"/>
@@ -1309,7 +1530,6 @@
<choose>
<if variable="number">
<!-- Ex. 6: Journal article with article number or eLocator -->
- <!-- This should be localized -->
<group delimiter=" ">
<text term="article-locator" text-case="capitalize-first"/>
<text variable="number"/>
@@ -1323,8 +1543,8 @@
<choose>
<if variable="issued">
<choose>
- <if variable="issue page volume" match="none">
- <!-- TODO: Should I print status as-is, or should I print the in-press term? -->
+ <if variable="issue number page volume" match="none">
+ <!-- We print the status variable directly rather than using in-press, etc. terms. -->
<text variable="status" text-case="capitalize-first"/>
</if>
</choose>
@@ -1333,33 +1553,56 @@
</group>
</macro>
<macro name="container-booklike">
- <!-- TODO: Add new item types -->
<choose>
<if variable="container-title" match="any">
<group delimiter=" ">
- <text term="in" text-case="capitalize-first"/>
+ <choose>
+ <if type="song">
+ <text term="on" text-case="capitalize-first"/>
+ </if>
+ <else>
+ <text term="in" text-case="capitalize-first"/>
+ </else>
+ </choose>
<group delimiter=", ">
- <names variable="editor translator" delimiter=", &amp; ">
- <!-- TODO: Change to editortranslator and move editor to substitute -->
+ <names variable="executive-producer">
<name and="symbol" initialize-with=". " delimiter=", "/>
- <label form="short" text-case="title" prefix=" (" suffix=")"/>
+ <label form="long" text-case="title" prefix=" (" suffix=")"/>
<substitute>
- <names variable="editorial-director"/>
- <names variable="collection-editor"/>
+ <names variable="series-creator"/>
+ <names variable="editor-translator">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" text-case="title" prefix=" (" suffix=")"/>
+ </names>
+ <!-- TODO: Translator omitted here on the assumption that editor-translators are uncommon
+ for chapter citations. If needed, direct entry or automatic population of
+ `editor-translator` can produce combined labels. -->
+ <names variable="editor">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" text-case="title" prefix=" (" suffix=")"/>
+ </names>
+ <names variable="editorial-director">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" text-case="title" prefix=" (" suffix=")"/>
+ </names>
+ <names variable="compiler"/>
+ <choose>
+ <if type="event performance speech" match="any">
+ <names variable="chair"/>
+ <names variable="organizer"/>
+ </if>
+ </choose>
+ <names variable="curator"/>
+ <names variable="collection-editor">
+ <name and="symbol" initialize-with=". " delimiter=", "/>
+ <label form="short" text-case="title" prefix=" (" suffix=")"/>
+ </names>
<names variable="container-author"/>
</substitute>
</names>
<group delimiter=": " font-style="italic">
<text variable="container-title"/>
- <!-- TODO: Replace with volume-title -->
- <choose>
- <if is-numeric="volume" match="none">
- <group delimiter=" ">
- <label variable="volume" form="short" text-case="capitalize-first"/>
- <text variable="volume"/>
- </group>
- </if>
- </choose>
+ <text macro="volume-title"/>
</group>
</group>
<text macro="parenthetical-container"/>
@@ -1369,7 +1612,6 @@
</choose>
</macro>
<macro name="publisher">
- <!-- TODO: Add new item types -->
<group delimiter="; ">
<choose>
<if type="thesis">
@@ -1389,12 +1631,12 @@
<else-if type="paper-conference">
<!-- For paper-conference, don't print publisher if in a journal-like proceedings -->
<choose>
- <if variable="collection-editor editor editorial-director" match="any">
+ <if variable="collection-editor compiler editor editorial-director" match="any">
<text variable="publisher"/>
</if>
</choose>
</else-if>
- <else-if type="article-journal article-magazine article-newspaper post-weblog" match="none">
+ <else-if type="article-journal article-magazine article-newspaper periodical post-weblog review review-book" match="none">
<text variable="publisher"/>
</else-if>
</choose>
@@ -1404,16 +1646,32 @@
<!-- With `archive-place`: physical archives. Without: online archives. -->
<!-- For physical archives, print the location before the archive name.
For electronic archives, these are printed in macro="description". -->
- <!-- TODO: Split "archive_location" into "archive_collection" and "archive_location" -->
<!-- Must test for archive_collection:
With collection: archive_collection (archive_location), archive, archive-place
No collection: archive (archive_location), archive-place
-->
- <text variable="archive_location"/>
+ <choose>
+ <if variable="archive_collection">
+ <group delimiter=" ">
+ <text variable="archive_collection"/>
+ <text variable="archive_location" prefix="(" suffix=")"/>
+ </group>
+ <text variable="archive"/>
+ <text variable="archive-place"/>
+ </if>
+ <else>
+ <group delimiter=" ">
+ <text variable="archive"/>
+ <text variable="archive_location" prefix="(" suffix=")"/>
+ </group>
+ <text variable="archive-place"/>
+ </else>
+ </choose>
</if>
+ <else>
+ <text variable="archive"/>
+ </else>
</choose>
- <text variable="archive"/>
- <text variable="archive-place"/>
</group>
</group>
</macro>
@@ -1439,19 +1697,30 @@
</choose>
</macro>
<macro name="event">
- <!-- TODO: Add new item types (e.g., event, collection, performance) -->
<choose>
<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 -->
+ <if type="paper-conference">
+ <choose>
+ <if variable="collection-editor compiler editor editorial-director issue page volume" match="none">
+ <!-- Don't print event info for conference papers published in a proceedings -->
+ <group delimiter=", ">
+ <text macro="event-title"/>
+ <text variable="event-place"/>
+ </group>
+ </if>
+ </choose>
+ </if>
+ <else>
+ <!-- For other item types, print event info even if published (e.g., for collection catalogs, performance programs.
+ These items aren't given explicit examples in the APA manual, so err on the side of providing too much information. -->
<group delimiter=", ">
<text macro="event-title"/>
<text variable="event-place"/>
</group>
- </if>
+ </else>
</choose>
</if>
</choose>
@@ -1472,19 +1741,30 @@
</macro>
<!-- After 'source', APA also prints publication history (original publication, reprint info, retraction info) -->
<macro name="publication-history">
- <!-- TODO: Add new item types -->
<choose>
- <if type="patent" match="none">
- <group prefix="(" suffix=")">
+ <if type="patent">
+ <text variable="references" prefix="(" suffix=")"/>
+ </if>
+ <else>
+ <group delimiter="; " prefix="(" suffix=")">
+ <!-- Print `status` here for things like "retracted" if it's not printed elsewhere already. -->
+ <choose>
+ <if variable="issued">
+ <choose>
+ <if variable="issue number page volume" match="any">
+ <text variable="status" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ </if>
+ </choose>
<choose>
<if variable="references">
<!-- This provides the option for more elaborate description
- of publication history, such as full "reprinted" references
- (examples 11, 43, 44) or retracted references -->
+ of publication history, such as full "reprinted" references
+ (examples 11, 43, 44) -->
<text variable="references"/>
</if>
<else>
- <!-- TODO: Replace these with terms -->
<group delimiter=" ">
<text term="original-work-published" text-case="capitalize-first"/>
<choose>
@@ -1499,9 +1779,6 @@
</else>
</choose>
</group>
- </if>
- <else>
- <text variable="references" prefix="(" suffix=")"/>
</else>
</choose>
</macro>
@@ -1510,9 +1787,9 @@
<!-- `treaty`: for treaties -->
<!-- `legal_case`: for all legal and court cases -->
<!-- `bill`: for bills, resolutions, federal reports -->
- <!-- `hearing`: TODO for hearings and testimony -->
+ <!-- `hearing`: for hearings and testimony -->
<!-- `legislation`: for statutes, constitutional items, and charters -->
- <!-- `regulation`: TODO codified regulations, uncodified regulations, executive orders -->
+ <!-- `regulation`: codified regulations, uncodified regulations, executive orders -->
<group delimiter=" ">
<choose>
<if type="treaty">
@@ -1682,10 +1959,10 @@
<text variable="genre"/>
<group delimiter=" ">
<choose>
- <!-- TODO: What was the logic for this? Do we still need this? -->
- <!-- If there is no session number or code/record title, print number.
- Is that trying to capture congressional reports/documents? -->
+ <!-- If there is no session number or code/record title, assume
+ assume the item is a congressional report and include 'No.' term. -->
<if variable="chapter-number container-title" match="none">
+ <!-- The item is a congressional report, rather than a bill or resultion. -->
<label variable="number" form="short" text-case="capitalize-first"/>
</if>
</choose>
@@ -1789,14 +2066,14 @@
</choose>
</macro>
<macro name="citation-locator">
- <!-- TODO: Add new locator types? -->
+ <!-- Abbreviate page and paragraph, leave other locator labels in long form, cf. Rule 8.13 -->
<group delimiter=" ">
<choose>
- <if locator="chapter">
- <label variable="locator" text-case="capitalize-first"/>
+ <if locator="page paragraph" match="any">
+ <label variable="locator" form="short"/>
</if>
<else>
- <label variable="locator" form="short"/>
+ <label variable="locator" text-case="capitalize-first"/>
</else>
</choose>
<text variable="locator"/>
@@ -1827,17 +2104,9 @@
</sort>
<layout>
<choose>
- <!-- TODO: Add new item types -->
<if type="bill hearing legal_case legislation regulation treaty" match="any">
<!-- Legal items have different orders and delimiters -->
- <choose>
- <if variable="DOI URL" match="any">
- <text macro="legal-cites"/>
- </if>
- <else>
- <text macro="legal-cites" suffix="."/>
- </else>
- </choose>
+ <text macro="legal-cites"/>
</if>
<else>
<group delimiter=" ">
diff --git a/biblio/citation-style-language/chicago-author-date.csl b/biblio/citation-style-language/chicago-author-date.csl
index ae60f7e679..e759c377e2 100644
--- a/biblio/citation-style-language/chicago-author-date.csl
+++ b/biblio/citation-style-language/chicago-author-date.csl
@@ -29,10 +29,14 @@
<contributor>
<name>Brenton M. Wiernik</name>
</contributor>
+ <contributor>
+ <name>Zeping Lee</name>
+ <email>zepinglee@gmail.com</email>
+ </contributor>
<category citation-format="author-date"/>
<category field="generic-base"/>
<summary>The author-date variant of the Chicago style</summary>
- <updated>2023-12-25T13:06:05-05:00</updated>
+ <updated>2024-05-12T12:13:15-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">
@@ -385,8 +389,19 @@
</if>
<else-if type="article-journal">
<choose>
- <if variable="volume issue" match="any">
- <text variable="page" prefix=": "/>
+ <if variable="volume">
+ <choose>
+ <if variable="issue">
+ <text variable="page" prefix=": "/>
+ </if>
+ <else>
+ <!-- CMoS 15.48: If the month or season is included, it is
+ enclosed in parentheses, and a space follows the colon.
+ Unfortunately we can't check the month in CSL v1.0.2.
+ -->
+ <text variable="page" prefix=":"/>
+ </else>
+ </choose>
</if>
<else>
<text variable="page" prefix=", "/>
@@ -501,6 +516,11 @@
</else>
</choose>
</macro>
+ <macro name="date-sort">
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </macro>
<macro name="day-month">
<date variable="issued">
<date-part name="month"/>
@@ -658,7 +678,7 @@
<bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="&#8212;&#8212;&#8212;" entry-spacing="0">
<sort>
<key macro="contributors"/>
- <key variable="issued"/>
+ <key macro="date-sort"/>
<key variable="title"/>
</sort>
<layout suffix=".">
diff --git a/biblio/citation-style-language/citation-style-language-bib.sty b/biblio/citation-style-language/citation-style-language-bib.sty
index 8a95c5b2ab..2a2af3a7d2 100644
--- a/biblio/citation-style-language/citation-style-language-bib.sty
+++ b/biblio/citation-style-language/citation-style-language-bib.sty
@@ -9,21 +9,21 @@
% The options like `notcategory` can be used multiple times and thus we save
% them into a seq instead of a prop.
\seq_new:N \l__csl_bib_filter_seq
-\int_new:N \g__bib_list_index_int
-\tl_new:N \g__bib_list_index_tl
+\int_new:N \g__csl_bib_list_index_int
+\tl_new:N \g__csl_bib_list_index_tl
\tl_new:N \l__csl_bibliography_tl
\seq_new:N \l__csl_bibliography_seq
\NewDocumentCommand \printbibliography { O { } }
{
- \int_gincr:N \g__bib_list_index_int
- \tl_gset:Nx \g__bib_list_index_tl { \int_use:N \g__bib_list_index_int }
+ \int_gincr:N \g__csl_bib_list_index_int
+ \tl_gset:Nx \g__csl_bib_list_index_tl { \int_use:N \g__csl_bib_list_index_int }
\__csl_set_categories:
% Bibliography filter
\group_begin:
\seq_clear:N \l__csl_bib_filter_seq
\seq_put_right:Nx \l__csl_bib_filter_seq
- { index = \g__bib_list_index_tl }
+ { index = \g__csl_bib_list_index_tl }
\keys_set:nn { csl / bibliography } {#1}
\__csl_serialize_seq:NN \l__csl_bib_filter_seq \l__csl_bib_filter_tl
% Collect the bibliography to token list
@@ -34,7 +34,7 @@
\__csl_collect_bibliography:n
{
\lua_now:e
- { csl.bibliography("\l__csl_bib_filter_tl") }
+ { csl_citation_manager:bibliography("\l__csl_bib_filter_tl") }
}
}
}
@@ -43,7 +43,7 @@
\exp_args:NV \__csl_write_aux_bibliography:n \l__csl_bib_filter_tl
}
% Print the bibliography
- \prop_get:NVNTF \g__csl_bibliographies_prop \g__bib_list_index_tl
+ \prop_get:NVNTF \g__csl_bibliographies_prop \g__csl_bib_list_index_tl
\l__csl_bibliography_tl
{
\bool_if:NT \l__csl_regression_test_bool
@@ -53,11 +53,11 @@
}
\tl_use:N \l__csl_bibliography_tl
}
- { \msg_warning:nn { citation-style-language } { bibliography / empty } }
+ { \msg_warning:nn { citation-style-language } { empty-bibliography } }
\group_end:
}
-\msg_new:nnn { citation-style-language } { bibliography / empty }
+\msg_new:nnn { citation-style-language } { empty-bibliography }
{ The~ bibliography~ is~ empty. }
\DeclareDocumentCommand \bibliography { m }
@@ -108,11 +108,16 @@
\cs_new:Npn \__csl_write_aux_bibliography:n #1
{
\if@filesw
- \iow_now:Nn \@auxout { \csl@aux@bibliography {#1} }
+ \iow_now:Nx \@auxout
+ {
+ \token_to_str:N \csl@aux@bibliography
+ { \int_use:N \g__csl_ref_section_index_int }
+ {#1}
+ }
\fi
}
-\cs_new:Npn \csl@aux@bibliography #1 { }
+\cs_new:Npn \csl@aux@bibliography #1#2 { }
\tl_new:N \l__csl_bib_index_tl
@@ -182,7 +187,7 @@
}
{
\tl_set:Nn \@noitemerr
- { \msg_warning:nn { citation-style-language } { bibliography / empty } }
+ { \msg_warning:nn { citation-style-language } { empty-bibliography } }
\endlist
\group_end:
\exp_args:NV \__csl_print_bib_note:n \l__csl_bib_post_note_tl
@@ -355,6 +360,96 @@
}
+% ### Bibliography sections and segments
+
+
+\int_new:N \g__csl_ref_section_index_int
+\int_new:N \g__csl_max_ref_section_index_int
+\int_gset:Nn \g__csl_ref_section_index_int { 0 }
+\int_gset:Nn \g__csl_max_ref_section_index_int { 0 }
+
+\keys_define:nn { csl / ref-section }
+ {
+ style .code:n =
+ {
+ \tl_set:Nn \l__csl_style_tl {#1}
+ \renewcommand \csl@style {#1}
+ } ,
+ bib-resource .clist_set:N = \l__csl_bib_resources_clist ,
+ locale .tl_set:N = \l__csl_locale_tl ,
+ }
+
+\NewDocumentCommand \refsection { O { } }
+ {
+ \int_gincr:N \g__csl_max_ref_section_index_int
+ \int_gset_eq:NN \g__csl_ref_section_index_int \g__csl_max_ref_section_index_int
+
+ \tl_clear:N \l__csl_style_tl
+ \clist_clear:N \l__csl_bib_resources_clist
+ \tl_clear:N \l__csl_locale_tl
+ \keys_set:nn { csl / ref-section } { #1 }
+ \tl_if_empty:NTF \l__csl_style_tl
+ {
+ \tl_set_eq:NN \l__csl_style_tl \g__csl_global_style_tl
+ \tl_set_eq:NN \csl@style \l__csl_style_tl
+ }
+ {
+ \tl_set_eq:NN \csl@style \l__csl_style_tl
+ \exp_args:NV \__csl_write_aux_bibstyle:n \l__csl_style_tl
+ }
+ \clist_if_empty:NF \l__csl_bib_resources_clist
+ % { \clist_set_eq:NN \l__csl_bib_resources_clist \g__csl_global_bib_resources_clist }
+ {
+ \exp_args:Nx \__csl_write_aux_bibdata:n
+ { \clist_use:Nn \l__csl_bib_resources_clist { , } }
+ }
+ \tl_if_empty:NTF \l__csl_locale_tl
+ { \tl_set_eq:NN \l__csl_locale_tl \g__csl_global_locale_tl }
+ {
+ \exp_args:Nx \__csl_write_aux_options:n
+ { locale = \l__csl_locale_tl }
+ }
+ \sys_if_engine_luatex:TF
+ {
+ \lua_now:e
+ {
+ csl_citation_manager:begin_ref_section(
+ "\l__csl_style_tl",
+ "\clist_use:Nn \l__csl_bib_resources_clist { , }",
+ "\l__csl_locale_tl"
+ )
+ }
+ \str_if_eq:eeTF
+ {
+ \lua_now:n
+ {
+ tex.print(tostring(
+ csl_citation_manager.ref_section.initialized
+ ))
+ }
+ }
+ { true }
+ { \bool_set_true:N \l__csl_engine_initialized_bool }
+ { \bool_set_false:N \l__csl_engine_initialized_bool }
+ \__csl_get_style_class_luatex:
+ }
+ {
+ \__csl_get_style_class:
+ }
+ }
+
+\cs_set_eq:NN \newrefsection \refsection
+
+\cs_new:Npn \endrefsection {
+ \int_compare:nNnT { \g__csl_ref_section_index_int } > { 0 }
+ {
+ \int_gzero:N \g__csl_ref_section_index_int
+ \sys_if_engine_luatex:T
+ { \lua_now:n { csl_citation_manager:end_ref_section() } }
+ }
+}
+
+
% ### Bibliography Headings and Environments
\prop_new:N \l__csl_bib_env_begin_prop
@@ -381,7 +476,7 @@
{
\cs_if_exist:cF { __csl_head_ #1 :n }
{
- \msg_error:nnn { citation-style-language } { bib-heading-undefined }
+ \msg_error:nnn { citation-style-language } { undefined-bib-heading }
{#1}
}
\tl_if_blank:nTF {#2}
@@ -393,7 +488,7 @@
{ \exp_args:NV \label \l__csl_bib_head_label_tl }
}
-\msg_new:nnn { citation-style-language } { bib-heading-undefined }
+\msg_new:nnn { citation-style-language } { undefined-bib-heading }
{ Bibliography~ heading~ '#1'~ undefined. }
\keys_define:nn { csl / bib-heading }
@@ -426,6 +521,10 @@
\expandafter \newcommand \csname __csl_head_ #1 :n \endcsname [1] [ {#2} ]
}
+
+\cs_if_exist:NF \refname
+ { \cs_set:Npn \refname { References } }
+
\cs_if_exist:NTF \chapter
{
% `book` or `report`
@@ -437,19 +536,19 @@
\defbibheading { biblist } [ \biblistname ]
{
\chapter* {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { bibintoc } [ \bibname ]
{
\chapter* {#1}
\addcontentsline { toc } { chapter } {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { biblistintoc } [ \biblistname ]
{
\chapter* {#1}
\addcontentsline { toc } { chapter } {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { bibnumbered } [ \bibname ]
{ \chapter {#1} }
@@ -459,7 +558,7 @@
{
\section* {#1}
\if@twoside
- \markright { \MakeMarkcase {#1} }
+ \markright { \MakeUppercase {#1} }
\fi
}
\defbibheading { subbibintoc } [ \refname ]
@@ -467,7 +566,7 @@
\section* {#1}
\addcontentsline { toc } { section } {#1}
\if@twoside
- \markright { \MakeMarkcase {#1} }
+ \markright { \MakeUppercase {#1} }
\fi
}
\defbibheading { subbibnumbered } [ \refname ]
@@ -483,19 +582,19 @@
\defbibheading { biblist } [ \biblistname ]
{
\section* {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { bibintoc } [ \refname ]
{
\section* {#1}
\addcontentsline { toc } { section } {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { biblistintoc } [ \biblistname ]
{
\section* {#1}
\addcontentsline { toc } { section } {#1}
- \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} }
+ \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} }
}
\defbibheading { bibnumbered } [ \refname ]
{ \section {#1} }
@@ -531,7 +630,7 @@
{
\prop_get:NnNF \l__csl_bib_notes_prop {#1} \l_tmpa_tl
{
- \msg_error:nnn { citation-style-language } { bib-note-undefined }
+ \msg_error:nnn { citation-style-language } { undefined-bib-note }
{#1}
}
\tl_if_empty:NF \l_tmp_tl
@@ -547,7 +646,7 @@
}
}
-\msg_new:nnn { citation-style-language } { bib-note-undefined }
+\msg_new:nnn { citation-style-language } { undefined-bib-note }
{ Bibliography~ note~ '#1'~ undefined. }
@@ -593,7 +692,7 @@
\tl_put_right:Nn \l_tmpa_tl { ##1 = {##2} }
}
\sys_if_engine_luatex:T
- { \lua_now:e { csl.set_categories("\l_tmpa_tl") } }
+ { \lua_now:e { csl_citation_manager:set_categories("\l_tmpa_tl") } }
{
\tl_put_left:Nx \l_tmpa_tl { categories = \c_left_brace_str }
\tl_put_right:NV \l_tmpa_tl \c_right_brace_str
diff --git a/biblio/citation-style-language/citation-style-language-cite.sty b/biblio/citation-style-language/citation-style-language-cite.sty
index 6ebb300536..38128a99d8 100644
--- a/biblio/citation-style-language/citation-style-language-cite.sty
+++ b/biblio/citation-style-language/citation-style-language-cite.sty
@@ -7,13 +7,33 @@
% ## Citation commands
\DeclareDocumentCommand \cite { s o o m }
- { \__csl_cite:nnnn {#1} {#2} {#3} {#4} }
+ {
+ \IfBooleanTF {#1}
+ {
+ \bool_if:NTF \l__csl_note_bool
+ { \__csl_cite_in_text:nnnn {#2} {#3} {#4} { } }
+ { \__csl_cite_in_text:nnnn {#2} {#3} {#4} { suppress-author } }
+ }
+ {
+ \bool_if:NTF \l__csl_note_bool
+ { \__csl_cite_note:nnnn {#2} {#3} {#4} { } }
+ { \__csl_cite_in_text:nnnn {#2} {#3} {#4} { } }
+ }
+ }
\NewDocumentCommand \parencite { s o o m }
- { \__csl_cite:nnnn {#1} {#2} {#3} {#4} }
+ {
+ \IfBooleanTF {#1}
+ {
+ \bool_if:NTF \l__csl_note_bool
+ { \__csl_cite_in_text:nnnn {#2} {#3} {#4} { } }
+ { \__csl_cite_in_text:nnnn {#2} {#3} {#4} { suppress-author } }
+ }
+ { \__csl_cite_parens:nnn {#2} {#3} {#4} }
+ }
\NewDocumentCommand \citep { o o m }
- { \__csl_cite:nnnn { \BooleanFalse } {#1} {#2} {#3} }
+ { \__csl_cite_parens:nnn {#1} {#2} {#3} }
\NewDocumentCommand \textcite { o o m }
{ \__csl_text_cite:nnn {#1} {#2} {#3} }
@@ -22,7 +42,7 @@
{ \__csl_text_cite:nnn {#1} {#2} {#3} }
\NewDocumentCommand \footcite { o o m }
- { \__csl_cite:nnnn { \BooleanFalse } {#1} {#2} {#3} }
+ { \__csl_cite_note:nnnn {#1} {#2} {#3} { } }
% \cites[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}...[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}
@@ -30,20 +50,16 @@
{ \__csl_cites: }
\NewDocumentCommand \citeauthor { o o m }
- { \__csl_cite_author:nnn {#1} {#2} {#3} }
+ { \__csl_cite_in_text:nnnn {#1} {#2} {#3} { author-only } }
% TODO: \citeyear
-% ATM the starred form is the same as non-star form.
-\NewDocumentCommand \citeyearpar { s o o m }
- {
- \IfBooleanT {#1}
- {
- \bool_if:NTF \l__csl_note_bool
- { \msg_error:nn { citation-style-language } { starred-cite-in-note-style } }
- }
- \__csl_cite_suppress_author:nnn {#2} {#3} {#4}
- }
+% Suppresses the author (from `natbib`).
+\NewDocumentCommand \citeyearpar { o o m }
+ { \__csl_cite_in_text:nnnn {#1} {#2} {#3} { suppress-author } }
+
+\NewDocumentCommand \fullcite { o o m }
+ { \__csl_cite_in_text:nnnn {#1} {#2} {#3} { full-cite } }
\seq_new:N \l__csl_cite_keys_seq
@@ -51,36 +67,77 @@
\prop_new:N \l__csl_citation_properties_prop
\prop_new:N \l__csl_citation_info_prop
-% \__csl_cite:nnnn #1#2#3#
-% #1: boolean of star form
-% #2: prenote
-% #3: postnote
-% #4: cite keys
-\cs_new:Npn \__csl_cite:nnnn #1#2#3#4
+% #1: prenote
+% #2: postnote
+% #3: cite keys
+% #4: mode
+\cs_new:Npn \__csl_cite_in_text:nnnn #1#2#3#4
+ {
+ \tl_if_blank:nTF {#3}
+ { \__csl_print_undefined_citation:n {#3} }
+ {
+ \__csl_cite_init:
+ \__csl_collect_citation_items:nnn {#1} {#2} {#3}
+ \__csl_process_citation_info:
+ \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
+ \tl_if_empty:nF {#4}
+ {
+ \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4}
+ }
+ \__csl_make_citation:
+ }
+ }
+
+% #1: prenote
+% #2: postnote
+% #3: cite keys
+% #4: mode
+\cs_new:Npn \__csl_cite_note:nnnn #1#2#3#4
{
- \tl_if_blank:nTF {#4}
- { \__csl_print_undefined_citation:n {#4} }
+ \bool_if:NTF \l__csl_in_note_bool
+ {
+ \tl_if_blank:nTF {#3}
+ { \__csl_print_undefined_citation:n {#3} }
+ {
+ \__csl_cite_init:
+ \__csl_collect_citation_items:nnn {#1} {#2} {#3}
+ \__csl_process_citation_info:
+ \tl_if_empty:nF {#4}
+ {
+ \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4}
+ }
+ \__csl_make_citation:
+ }
+ }
{
- \seq_clear:N \l__csl_cite_keys_seq
- \seq_clear:N \l__csl_citation_items_seq
- \prop_clear:N \l__csl_citation_properties_prop
- \__csl_process_cite_input:nnn {#2} {#3} {#4}
- \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq
- \IfBooleanT {#1}
+ \footnote
{
- \bool_if:NTF \l__csl_note_bool
- { \msg_warning:nn { citation-style-language } { starred-cite-in-note-style } }
+ \tl_if_blank:nTF {#3}
+ { \__csl_print_undefined_citation:n {#3} }
{
- \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
- \prop_put:Nnn \l__csl_citation_properties_prop { mode } { suppress-author }
+ \__csl_cite_init:
+ \__csl_collect_citation_items:nnn {#1} {#2} {#3}
+ \__csl_process_citation_info:
+ \tl_if_empty:nF {#4}
+ {
+ \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4}
+ }
+ \__csl_make_citation:
}
}
- \__csl_make_citation:N \l__csl_citation_info_prop
}
}
-\msg_new:nnn { citation-style-language } { starred-cite-in-note-style }
- { Starred~ variant~ of~ cite~ command~ does~ not~ work~ with~ note~ styles. }
+
+% #1: prenote
+% #2: postnote
+% #3: cite keys
+\cs_new:Npn \__csl_cite_parens:nnn #1#2#3
+ {
+ \bool_if:NTF \l__csl_note_bool
+ { ( \__csl_cite_in_text:nnnn {#1} {#2} {#3} { } ) }
+ { \__csl_cite_in_text:nnnn {#1} {#2} {#3} { } }
+ }
\cs_new:Npn \__csl_text_cite:nnn #1#2#3
@@ -88,29 +145,19 @@
\bool_if:NTF \l__csl_note_bool
{
% In note styles, the authors are printed in-text followed by a note.
- \bool_set_false:N \l__csl_note_bool
- \__csl_cite_author:nnn {#1} {#2} {#3}
- \bool_set_true:N \l__csl_note_bool
- \__csl_cite:nnnn { \BooleanFalse } {#1} {#2} {#3}
- }
- {
- \seq_clear:N \l__csl_cite_keys_seq
- \seq_clear:N \l__csl_citation_items_seq
- \prop_clear:N \l__csl_citation_properties_prop
- \__csl_process_cite_input:nnn {#1} {#2} {#3}
- \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq
- \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
- \prop_put:Nnn \l__csl_citation_properties_prop { mode } { composite }
- \__csl_make_citation:N \l__csl_citation_info_prop
+ \__csl_cite_in_text:nnnn {#1} {#2} {#3} { author-only }
+ \__csl_cite_note:nnnn {#1} {#2} {#3} { }
}
+ { \__csl_cite_in_text:nnnn {#1} {#2} {#3} { composite } }
}
+\bool_new:N \l__csl_multi_cite_bool
+
\cs_new:Npn \__csl_cites:
{
- \seq_clear:N \l__csl_cite_keys_seq
- \seq_clear:N \l__csl_citation_items_seq
- \prop_clear:N \l__csl_citation_properties_prop
+ \__csl_cite_init:
+ \bool_set_true:N \l__csl_multi_cite_bool
\__csl_next_cites:nnn
}
@@ -118,41 +165,35 @@
{
\tl_if_novalue:nTF {#3}
{
- \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq
- \__csl_make_citation:N \l__csl_citation_info_prop
+ \bool_if:NTF \l__csl_note_bool
+ {
+ \footnote
+ {
+ \__csl_process_citation_info:
+ \__csl_make_citation:
+ }
+ }
+ {
+ \__csl_process_citation_info:
+ \__csl_make_citation:
+ }
}
{
- \__csl_process_cite_input:nnn {#1} {#2} {#3}
+ \__csl_collect_citation_items:nnn {#1} {#2} {#3}
\__csl_next_cites:nnn
}
}
-\cs_new:Npn \__csl_cite_author:nnn #1#2#3
- {
- \seq_clear:N \l__csl_cite_keys_seq
- \seq_clear:N \l__csl_citation_items_seq
- \prop_clear:N \l__csl_citation_properties_prop
- \__csl_process_cite_input:nnn {#1} {#2} {#3}
- \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq
- \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
- \prop_put:Nnn \l__csl_citation_properties_prop { mode } { author-only }
- \bool_set_false:N \l__csl_note_bool
- \__csl_make_citation:N \l__csl_citation_info_prop
- }
-
-
-\cs_new:Npn \__csl_cite_suppress_author:nnn #1#2#3
+\cs_new:Npn \__csl_cite_init:
{
+ \bool_set_false:N \l__csl_multi_cite_bool
+ \prop_clear:N \l__csl_citation_info_prop
\seq_clear:N \l__csl_cite_keys_seq
\seq_clear:N \l__csl_citation_items_seq
\prop_clear:N \l__csl_citation_properties_prop
- \__csl_process_cite_input:nnn {#1} {#2} {#3}
- \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq
- \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
- \prop_put:Nnn \l__csl_citation_properties_prop { mode } { suppress-author }
- \bool_set_false:N \l__csl_note_bool
- \__csl_make_citation:N \l__csl_citation_info_prop
+ \tl_clear:N \l__csl_cite_prefix_tl
+ \tl_clear:N \l__csl_cite_suffix_tl
}
@@ -160,7 +201,7 @@
% \l__csl_citation_items_seq
% #1, #2: prenote/postnote
% #3: keys
-\cs_new:Npn \__csl_process_cite_input:nnn #1#2#3
+\cs_new:Npn \__csl_collect_citation_items:nnn #1#2#3
{
\tl_if_novalue:nTF {#2}
{
@@ -188,12 +229,13 @@
\prop_new:N \l__csl_cite_item_prop
-\tl_new:N \l__csl_prefix_tl
-\tl_new:N \l__csl_suffix_tl
+% Collect citation items into \l__csl_citation_items_seq
+% Append "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq
+% #1: prenote
+% #2: postnote
+% #3: key
\cs_new:Npn \__csl_process_cite_item:nnn #1#2#3
- % #1: prenote, #2: postnote, #3: key
- % Save "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq
{
\prop_clear:N \l__csl_cite_item_prop
\prop_put:Nnn \l__csl_cite_item_prop { id } {#3}
@@ -201,11 +243,12 @@
% { \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_clear:N \l__csl_cite_prefix_tl
+ \tl_clear:N \l__csl_cite_suffix_tl
\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
+ \tl_set:Nn \l__csl_cite_prefix_tl {#1}
+ \tl_put_right:NV \l__csl_cite_prefix_tl \l__csl_prefix_separator_tl
}
\tl_if_empty:nF {#2}
{
@@ -215,12 +258,26 @@
\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
+ \tl_set:Nn \l__csl_cite_suffix_tl {#2}
+ \tl_put_left:NV \l__csl_cite_suffix_tl \l__csl_suffix_separator_tl
}
}
}
+ % The affixes are treated as cite item affixes in a multi-cite command
+ % (like `\cites`). Otherwise they are citation affixes.
+ \bool_if:NTF \l__csl_multi_cite_bool
+ {
+ \tl_if_empty:NF \l__csl_cite_prefix_tl
+ { \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_cite_prefix_tl }
+ \tl_if_empty:NF \l__csl_cite_suffix_tl
+ { \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_cite_suffix_tl }
+ }
+ {
+ \tl_if_empty:NF \l__csl_cite_prefix_tl
+ { \prop_put:NnV \l__csl_citation_properties_prop { prefix } \l__csl_cite_prefix_tl }
+ \tl_if_empty:NF \l__csl_cite_suffix_tl
+ { \prop_put:NnV \l__csl_citation_properties_prop { suffix } \l__csl_cite_suffix_tl }
+ }
\__csl_serialize_prop:NN \l__csl_cite_item_prop \l_tmpa_tl
\tl_put_left:NV \l_tmpa_tl { \c_left_brace_str }
\tl_put_right:NV \l_tmpa_tl { \c_right_brace_str }
@@ -229,14 +286,24 @@
\cs_new:Npn \__csl_set_locator:nn #1#2
{
- \prop_put:Nnn \l__csl_cite_item_prop { label } {#1}
- \prop_put:Nnn \l__csl_cite_item_prop { locator } {#2}
+ \tl_if_empty:nTF {#2}
+ { \msg_warning:nnn { citation-style-language } { empty-locator } {#1} }
+ {
+ \prop_put:Nnn \l__csl_cite_item_prop { label } {#1}
+ \prop_put:Nnn \l__csl_cite_item_prop { locator } {#2}
+ }
}
+\msg_new:nnn { citation-style-language } { empty-locator }
+ { Empty~ '#1'~ locator. }
+
+\tl_new:N \l__csl_cite_prefix_tl
+\tl_new:N \l__csl_cite_suffix_tl
+
\keys_define:nn { csl / cite-item }
{
- prefix .prop_put:N = \l__csl_cite_item_prop,
- suffix .prop_put:N = \l__csl_cite_item_prop,
+ prefix .tl_set:N = \l__csl_cite_prefix_tl,
+ suffix .tl_set:N = \l__csl_cite_suffix_tl,
locator .prop_put:N = \l__csl_cite_item_prop,
label .prop_put:N = \l__csl_cite_item_prop,
suppress-author .prop_put:N = \l__csl_cite_item_prop,
@@ -284,17 +351,24 @@
% Load the cite keys and prepare:
% - \l__csl_citation_id_tl
% - \l__csl_citation_properties_prop
-%
-% #1: \l__csl_cite_keys_seq
-% #2: \l__csl_citation_items_seq
-\cs_new:Npn \__csl_process_citation_info:NN #1#2
+\cs_new:Npn \__csl_process_citation_info:
{
- \__csl_process_citation_id:NN \l__csl_citation_id_tl #1
- \__csl_get_note_index:N \l__csl_note_index_tl
+ \__csl_process_citation_id:
+ \__csl_get_note_index:
\prop_put:NnV \l__csl_citation_properties_prop { noteIndex } \l__csl_note_index_tl
+ \__csl_make_chapter_property:
\__csl_add_back_ref_info:
}
+\cs_new:Npn \__csl_make_chapter_property:
+ {
+ \int_if_exist:NT \c@chapter
+ {
+ \prop_put:Nnx \l__csl_citation_properties_prop { chapterIndex }
+ { \int_use:N \c@chapter }
+ }
+ }
+
\tl_new:N \l__csl_back_ref_tl
\prop_new:N \g__csl_back_ref_info_prop
@@ -344,8 +418,7 @@
\tl_new:N \l__csl_citation_properties_tl
% Write citation info to aux and print the citation contents.
-% #1: \l__csl_citation_info_prop
-\cs_new:Npn \__csl_make_citation:N #1
+\cs_new:Npn \__csl_make_citation:
{
\prop_clear:N \l__csl_citation_info_prop
% citationID
@@ -359,13 +432,13 @@
\__csl_serialize_prop:NN \l__csl_citation_info_prop \l__csl_citation_info_tl
% Write to .aux file
% \tl_show:N \l__csl_citation_info_tl
- \exp_args:NV \__csl_write_aux_citation:n \l__csl_citation_info_tl
+ \exp_args:NVV \__csl_write_aux_citation:nn \g__csl_ref_section_index_int \l__csl_citation_info_tl
\bool_if:NT \l__csl_regression_test_bool
{ \tl_show:N \l__csl_citation_info_tl }
% Print the citation string
\prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl
\l__csl_citation_tl
- { \__csl_print_citation:N \l__csl_citation_tl }
+ { \__csl_print_citation: }
{
\bool_if:NTF \l__csl_engine_initialized_bool
{
@@ -376,7 +449,7 @@
\char_set_catcode_other:N \%
\char_set_catcode_other:N \#
\exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl
- \__csl_print_citation:N \l__csl_citation_tl
+ \__csl_print_citation:
\group_end:
}
{
@@ -387,7 +460,7 @@
}
\cs_new:Npn \__csl_cite_aux:n #1
- { \lua_now:e { csl.cite("\lua_escape:n {#1}") } }
+ { \lua_now:e { csl_citation_manager:cite("\lua_escape:n {#1}") } }
% #1: seq
% #2: tl
@@ -420,13 +493,12 @@
\int_new:N \l__csl_citation_count_int
\prop_new:N \g__csl_citations_count_prop
-\cs_new:Npn \__csl_process_citation_id:NN #1#2
- % #1: \l__csl_citation_id_tl
- % #2: \l__csl_cite_keys_seq
- % Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4".
+% Load cite keys from `\l__csl_cite_keys_seq` and make `\l__csl_citation_id_tl`.
+% Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4".
+\cs_new:Npn \__csl_process_citation_id:
{
\tl_set:Nx \l__csl_cite_keys_tl
- { \seq_use:Nn #2 { , } }
+ { \seq_use:Nn \l__csl_cite_keys_seq { , } }
% \prop_show:N \g__csl_citations_count_prop
% \tl_show:N \l__csl_cite_keys_tl
\prop_get:NVNTF \g__csl_citations_count_prop \l__csl_cite_keys_tl
@@ -438,7 +510,7 @@
{ \int_set_eq:NN \l__csl_citation_count_int \c_one_int }
\prop_gput:NVV \g__csl_citations_count_prop \l__csl_cite_keys_tl
\l__csl_citation_count_int
- \tl_set:Nx #1
+ \tl_set:Nx \l__csl_citation_id_tl
{ \l__csl_cite_keys_tl @ \int_use:N \l__csl_citation_count_int }
}
@@ -448,15 +520,11 @@
% 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
+\cs_new:Npn \__csl_get_note_index:
% #1: \l__csl_note_index_tl
{
\bool_if:NTF \l__csl_note_bool
- {
- \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:Nx \l__csl_note_index_tl { \int_use:c { c@ \@mpfn } } }
{
\tl_if_empty:NTF \l__csl_class_tl
{
@@ -464,30 +532,38 @@
\int_set_eq:Nc \l_tmpa_int { c@ \@mpfn }
\int_gincr:N \g__csl_pseudo_note_index_int
\int_add:Nn \l_tmpa_int { \g__csl_pseudo_note_index_int }
- \tl_set:Nx #1 { \int_use:N \l_tmpa_int }
+ \tl_set:Nx \l__csl_note_index_tl { \int_use:N \l_tmpa_int }
}
- { \tl_set:Nx #1 { 0 } }
+ { \tl_set:Nn \l__csl_note_index_tl { 0 } }
}
}
-\cs_new:Npn \__csl_write_aux_citation:n #1
- % #1: citation info "{<citationID>}{{id=ITEM-1},{id=ITEM-2}}{<noteIndex>}"
+\cs_new:Npn \__csl_write_aux_citation:nn #1#2
+ % #1: refsection index (already converted to tl)
+ % #2: citation info "{<citationID>}{{id=ITEM-1},{id=ITEM-2}}{<noteIndex>}"
{
\if@filesw
- \iow_now:Nn \@auxout { \csl@aux@cite {#1} }
+ \iow_now:Nn \@auxout { \csl@aux@cite {#1} {#2} }
\fi
}
+% Should be set to true when located in a footnote, and to false otherwise
+\bool_new:N \l__csl_in_note_bool
+
+\hook_gput_code:nnn { cmd / @makefntext / before } { . }
+ { \bool_set_true:N \l__csl_in_note_bool }
+
+\hook_gput_code:nnn { cmd / @makefntext / after } { . }
+ { \bool_set_false:N \l__csl_in_note_bool }
+
% #1: \l__csl_citation_tl
-\cs_new:Npn \__csl_print_citation:N #1
+\cs_new:Npn \__csl_print_citation:
{
\bool_if:NT \l__csl_regression_test_bool
- { \tl_show:N #1 }
- \bool_if:NTF \l__csl_note_bool
- { \footnote {#1} }
- {#1}
+ { \tl_show:N \l__csl_citation_tl }
+ \l__csl_citation_tl
}
@@ -509,9 +585,7 @@
\bool_if:NT \l__csl_regression_test_bool
{ \tl_show:N \l__csl_citation_tl }
\group_begin:
- \bool_if:NTF \l__csl_note_bool
- { \footnote { \reset@font \l__csl_citation_tl } }
- { \reset@font \l__csl_citation_tl }
+ \reset@font \l__csl_citation_tl
\group_end:
}
@@ -520,8 +594,8 @@
\tl_set:Nn \l__csl_citation_tl { [ \textbf {#1} ] }
}
-% \msg_new:nnn { citation-style-language } { citation / undefined }
-% { Citation~ `#1'~ on~ page~ \thepage \space undefined~ \msg_line_context: . }
+% \msg_new:nnn { citation-style-language } { undefined-citation }
+% { Citation~ '#1'~ on~ page~ \thepage \space undefined~ \msg_line_context: . }
\cs_new:Npn \__csl_warn_citation_undefined:n #1
{
@@ -537,36 +611,39 @@
\cs_new:Npn \__csl_no_cite:n #1
{
- \seq_clear:N \l__csl_cite_keys_seq
- \seq_clear:N \l__csl_citation_items_seq
- \__csl_process_cite_input:nnn { } { } {#1}
+ \__csl_cite_init:
+ \__csl_collect_citation_items:nnn { } { } {#1}
\tl_set:Nx \l__csl_cite_items_tl
{ \seq_use:Nn \l__csl_citation_items_seq { , } }
+ \prop_clear:N \l__csl_citation_properties_prop
+ \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 }
+ \__csl_make_chapter_property:
+ \__csl_serialize_prop:NN \l__csl_citation_properties_prop \l__csl_citation_properties_tl
\tl_set:Nx \l__csl_citation_info_tl
{
citationID = { @nocite } ,
- citationItems = { \l__csl_cite_items_tl } ,
- properties = { noteIndex = { 0 } }
+ citationItems = { \tl_use:N \l__csl_cite_items_tl } ,
+ properties = { \tl_use:N \l__csl_citation_properties_tl }
}
\bool_if:NT \l__csl_regression_test_bool
{ \tl_show:N \l__csl_citation_info_tl }
- \exp_args:NV \__csl_no_cite_write_aux:n \l__csl_citation_info_tl
+ \exp_args:NVV \__csl_no_cite_write_aux:nn \g__csl_ref_section_index_int \l__csl_citation_info_tl
\sys_if_engine_luatex:T
- { \lua_now:n { csl.nocite("#1") } }
+ { \lua_now:n { csl_citation_manager:nocite("#1") } }
\tl_clear:N \l__csl_citation_tl
\bool_if:NT \l__csl_regression_test_bool
{ \tl_show:N \l__csl_citation_tl }
}
-\cs_new:Npn \__csl_no_cite_write_aux:n #1
+\cs_new:Npn \__csl_no_cite_write_aux:nn #1#2
{
\__csl_if_preamble:TF
{
\hook_gput_code:nnn { begindocument } { . }
- { \exp_args:Nx \__csl_write_aux_citation:n { #1 } }
+ { \__csl_write_aux_citation:nn {#1} {#2} }
}
- { \exp_args:Nx \__csl_write_aux_citation:n { #1 } }
+ { \__csl_write_aux_citation:nn {#1} {#2} }
}
@@ -582,10 +659,10 @@
% Used in aux files to register cite items.
% #1: a citation object
-\cs_set:Npn \csl@aux@cite #1
+\cs_set:Npn \csl@aux@cite #1#2
{
\sys_if_engine_luatex:T
- { \lua_now:e { csl.register_citation_info("\lua_escape:n {#1}") } }
+ { \lua_now:e { csl_citation_manager:register_citation_info(#1, "\lua_escape:n {#2}") } }
}
@@ -597,3 +674,10 @@
% #1: cite id
% #2: cite contents
\cs_new:Npn \cslcite #1#2 {#2}
+
+% This command is for use with hyperref.
+% #1: cite id
+\cs_new:Npn \cslundefinedcite #1 {
+ \textbf {#1}
+ \__csl_warn_citation_undefined:n {#1}
+}
diff --git a/biblio/citation-style-language/citation-style-language-compatible.sty b/biblio/citation-style-language/citation-style-language-compatible.sty
index ca44d0e457..8de98b6a9c 100644
--- a/biblio/citation-style-language/citation-style-language-compatible.sty
+++ b/biblio/citation-style-language/citation-style-language-compatible.sty
@@ -89,8 +89,8 @@
{
\BlockquoteDisable
{
- \cs_set_eq:NN \__csl_process_citation_info:NN \use_none:nn
- \cs_set_eq:NN \__csl_make_citation:N \use_none:n
+ \cs_set_eq:NN \__csl_process_citation_info: \relax
+ \cs_set_eq:NN \__csl_make_citation: \relax
}
}
@@ -98,25 +98,33 @@
% ### `hyperref`
\cs_set:Npn \__csl_hyperref_cite_item:nn #1#2
- { \hyper@@link [ cite ] { } { cite. #1 \@extra@b@citeb } { #2 } }
+ {
+ \hyper@@link [ cite ] { }
+ { cite \int_use:N \g__csl_ref_section_index_int . #1 \@extra@b@citeb } { #2 }
+ }
\cs_new:Npn \__csl_hyperref_lbibitem:nn [#1]#2
{
\clist_gput_right:Nn \g__csl_bib_items_clist {#2}
\@skiphyperreftrue
- \H@item[%
- \ifx\Hy@raisedlink\@empty
- \hyper@anchorstart{cite.#2\@extra@b@citeb}%
- \@BIBLABEL{#1}%
- \hyper@anchorend
- \else
- \Hy@raisedlink{%
- \hyper@anchorstart{cite.#2\@extra@b@citeb}\hyper@anchorend
- }%
- \@BIBLABEL{#1}%
- \fi
- \hfill
- ]%
+ \H@item
+ [
+ \ifx \Hy@raisedlink \@empty
+ \hyper@anchorstart
+ { cite \int_use:N \g__csl_ref_section_index_int . #2 \@extra@b@citeb }
+ \@BIBLABEL {#1}
+ \hyper@anchorend
+ \else
+ \Hy@raisedlink
+ {
+ \hyper@anchorstart
+ { cite \int_use:N \g__csl_ref_section_index_int . #2 \@extra@b@citeb }
+ \hyper@anchorend
+ }
+ \@BIBLABEL {#1}
+ \fi
+ \hfill
+ ]
\@skiphyperreffalse
\ignorespaces
}
@@ -128,7 +136,8 @@
\Hy@raisedlink
{
\hyper@anchorstart
- { cite. #1 \@extra@b@citeb } \relax
+ { cite \int_use:N \g__csl_ref_section_index_int . #1 \@extra@b@citeb }
+ \relax
\hyper@anchorend
}
\ignorespaces
@@ -153,3 +162,21 @@
\cs_gset_eq:NN \cslcite \__csl_hyperref_cite_item:nn
}
}
+
+
+% ### `perpage`
+
+\hook_gput_code:nnn { package / perpage / after } { . }
+ {
+ \hook_gput_code:nnn { begindocument } { . }
+ {
+ \cs_if_exist:cT { c@pchk@footnote }
+ {
+ \cs_set:Npn \__csl_make_chapter_property:
+ {
+ \prop_put:Nnx \l__csl_citation_properties_prop { chapterIndex }
+ { \int_use:N \c@page }
+ }
+ }
+ }
+ }
diff --git a/biblio/citation-style-language/citation-style-language-doc.pdf b/biblio/citation-style-language/citation-style-language-doc.pdf
index 0794c8fcdb..5ec6858cc0 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 b93678a051..72b5a5cbaf 100644
--- a/biblio/citation-style-language/citation-style-language-doc.tex
+++ b/biblio/citation-style-language/citation-style-language-doc.tex
@@ -11,6 +11,8 @@
\usepackage{listings}
\NewDocumentCommand\opt{m}{\texttt{#1}}
+\NewDocumentCommand\field{m}{\texttt{#1}}
+\NewDocumentCommand\entrytype{m}{\texttt{#1}}
\lstnewenvironment{LaTeXdemo}{
\lstset{
@@ -49,7 +51,7 @@
}%
}
-\date{2024-04-21 v0.4.9}
+\date{2024-09-15 v0.6.4}
\maketitle
@@ -115,11 +117,7 @@ An example of using \pkg{citation-style-language} package is as follows.
\begin{LaTeXdemo}
\documentclass{...}
- \usepackage{citation-style-language}
- \cslsetup{
- style = ...,
- ...
- }
+ \usepackage[style=apa]{citation-style-language}
\addbibresource{bibfile.json}
\begin{document}
\cite{...}
@@ -155,7 +153,7 @@ The general procedure is similar to the traditional BibTeX workflow.
-\section{Package commands}
+\section{Package setup}
\begin{function}{\cslsetup}
\begin{syntax}
@@ -167,7 +165,7 @@ 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}
- \usepackage[style = apa]{citation-style-langugage}
+ \usepackage[style=apa]{citation-style-langugage}
% OR
\usepackage{citation-style-langugage}
\cslsetup{style = apa}
@@ -214,6 +212,24 @@ The locale falls back to ``\opt{en}'' (English) if the attribute is not set.
When \pkg{babel} package is loaded, the selected main language is implicitly set
as the \opt{locale} for \pkg{citation-style-language}.
+\DescribeOption{ref-section}
+This option automatically starts a new reference section at the given document
+heading such as a chapter or a section. This is equivalent to the
+\cs{newrefsection} command. The following choices are available:
+
+\begin{description}
+ \item[\opt{none}] Disable this feature (default).
+ \item[\opt{part}] Start a reference section at every \cs{part} command.
+ \item[\opt{chapter}] Start a reference section at every \cs{chapter} command.
+ \item[\opt{chapter+}] Start a reference section at every \cs{chapter} and
+ every higher level of sectioning, i.e. \cs{part}.
+ \item[\opt{section}] Start a reference section at every \cs{section} command.
+ \item[\opt{section+}] Start a reference section at every \cs{section} and
+ every higher level of sectioning, i.e. \cs{part} and \cs{chapter}.
+ \item[\opt{subsection}] Start a reference section at every \cs{subsection} command.
+ \item[\opt{subsection+}] Start a reference section at every \cs{subsection} and every higher level of sectioning, i.e. \cs{part}, \cs{chapter} and \cs{section}.
+\end{description}
+
\DescribeOption{bib-font}
Usually, the list of references is printed in the same font style and size as
the main text.
@@ -264,6 +280,8 @@ their extension names and the content should be encoded in UTF-8.
\end{LaTeXdemo}
+\section{Citation commands}
+
\begin{function}{\cite}
\begin{syntax}
\cs{cite}\oarg{options}\marg{keys}
@@ -328,15 +346,25 @@ brackets, which is different from other packages.
\end{syntax}
\end{function}
-\DescribeOption{infix}
These commands proceduce narrative in-text citation where the author name is
part of the running text followed by the year in parentheses.
These commands only work with author-date styles.
+
+\DescribeOption{infix}
An extra option \opt{infix} can be given to specify the text inserted between
then author and year parts. For example, “Kesey’s early work (1962)” can be
produced by |\textcite[infix={'s early work}]{ITEM-1}|.
By default the infix is a space.
+\begin{function}{\footcite}
+ \begin{syntax}
+ \cs{footcite}\oarg{options}\marg{keys}
+ \end{syntax}
+\end{function}
+
+This command is similar to \cs{cite}. It is for compatibility with
+\pkg{biblatex}.
+
\begin{function}{\cites}
\begin{syntax}
\cs{cites}\oarg{options}\marg{key}...[options]\marg{key}
@@ -365,6 +393,25 @@ style), an optional |<intext>| element can be suppplied as a sibling to the
|<citation>| and |<bibliography>| elements in the CSL style (see
\href{https://citeproc-js.readthedocs.io/en/latest/running.html#citation-flags-with-processcitationcluster}{citeproc-js's documentation} for details).
+\begin{function}{\citeyearpar}
+ \begin{syntax}
+ \cs{citeyearpar}\oarg{options}\marg{keys}
+ \end{syntax}
+\end{function}
+
+This command suppresses the author names in the citation.
+It is equivalent to \cs{cite} with \opt{suppress-author} option enabled.
+
+\begin{function}{\fullcite}
+ \begin{syntax}
+ \cs{fullcite}\oarg{options}\marg{keys}
+ \end{syntax}
+\end{function}
+
+This command prints a full citation similar to the bibliographic entry.
+The contents are genreated from the |<bibliography>| element in the CSL style
+rather than the |<citation>| element.
+
\begin{function}{\nocite}
\begin{syntax}
\cs{nocite}\marg{keys}
@@ -377,23 +424,211 @@ If the special key |*| is given (\cs{notecite\{*\}}), all the entries in the
database are included.
+\section{Bibliography commands}
\begin{function}{\printbibliography}
\begin{syntax}
+ \cs{printbibliography}
\cs{printbibliography}\oarg{options}
\end{syntax}
\end{function}
This command prints the reference list.
-Currently no options are available.
+It also accepts an optional argument in square brackets which is a list of
+key-value options. The following options are available.
+
+\begin{variable}{heading}
+ \begin{syntax}
+ heading = \meta{name}
+ \end{syntax}
+\end{variable}
+
+This option selects the section heading style defined with \cs{defbibheading}.
+The default heading for \cs{printbibliography} is \opt{bibliography}.
+
+\begin{variable}{title}
+ \begin{syntax}
+ title = \meta{text}
+ \end{syntax}
+\end{variable}
+This option sets the title in the heading.
-% \begin{function}{\cites}
-% \begin{syntax}
-% \cs{cite}\oarg{options}\marg{keys}
-% \end{syntax}
-% \end{function}
+\begin{variable}{label}
+ \begin{syntax}
+ label = \meta{label}
+ \end{syntax}
+\end{variable}
+This option is equivalent to \cs{label}\marg{label} after the heading so that
+it can be \cs{ref}ed from other parts in the document.
+
+\begin{variable}{prenote, postnote}
+ \begin{syntax}
+ prenote = \meta{name}
+ postnote = \meta{name}
+ \end{syntax}
+\end{variable}
+
+\begin{variable}{type}
+ \begin{syntax}
+ type = \meta{entrytype}
+ \end{syntax}
+\end{variable}
+
+Print only the entries of the given \meta{entrytype}.
+Note that the \meta{entrytype} should be the name of a CSL entry type rather
+than BibTeX entry type (e.g., use |article-journal| rather than |article|).
+
+\begin{variable}{nottype}
+ \begin{syntax}
+ nottype = \meta{entrytype}
+ \end{syntax}
+\end{variable}
+
+Print only the entries that are not \meta{entrycategory}.
+This option may be used multiple times.
+
+\begin{variable}{keyword}
+ \begin{syntax}
+ keyword = \meta{keyword}
+ \end{syntax}
+\end{variable}
+
+Print only the entries whose \field{keyword} field includes the given
+\meta{keyword}. This option may be used multiple times.
+
+\begin{variable}{notkeyword}
+ \begin{syntax}
+ notkeyword = \meta{keyword}
+ \end{syntax}
+\end{variable}
+
+Print only the entries whose \field{keyword} field does not include the given
+\meta{keyword}. This option may be used multiple times.
+
+\begin{variable}{category}
+ \begin{syntax}
+ category = \meta{category}
+ \end{syntax}
+\end{variable}
+
+Print only the entries assigned to the given category.
+This option may be used multiple times.
+
+
+\begin{variable}{notcategory}
+ \begin{syntax}
+ notcategory = \meta{category}
+ \end{syntax}
+\end{variable}
+
+Print only the entries assigned to the given category.
+This option may be used multiple times.
+
+
+\subsection{Bibliography Sections}
+
+The \env{refsection} environment is used in the document body to mark a
+reference section.
+This environment is useful if you want separate, independent
+bibliographies and bibliography lists in each chapter, section, or any other
+part of a document.
+Within a reference section, all cited works are assigned labels which are local
+to the environment. Technically, reference sections are completely independent
+from document divisions such as \cs{chapter} and \cs{section} even though they
+will most likely be used per chapter or section.
+See the refsection package option in § 3.1.2.1 for a way to automate this.
+Also see § 3.14.3 for usage examples.
+
+\begin{function}{\begin{refsection}, \end{refsection}}
+ \begin{syntax}
+ \cs{begin}\{refsection\}
+ \cs{begin}\{refsection\}[style = \meta{style-id}, bib-resource = <datafile>, ...]
+ \end{syntax}
+\end{function}
+
+All citations given outside a \env{refsection} environment are assigned to
+the global section.
+If \cs{printbibliography} is used within a refsection, it will automatically
+select the current section.
+Note that \env{refsection} environments may not be nested.
+Beginning a new reference section automatically ends the active reference context (see § 3.8.10).
+The optional argument is a list of key-value configurations. That following options are available.
+
+
+\DescribeOption{style}
+The \opt{style} option specifies the CSL style used in this reference section.
+If this is not given, the global style will be used by default which is defined
+via package options or \cs{cslsetup}.
+
+\DescribeOption{bib-resource}
+The bibliographic data files are specified with this option.
+In case of multiple data files, remember to enclose the file with curly brackets
+so that the key-values are correctly parsed
+(e.g., \texttt{bib-resource = \{foo.json, bar.bib\}}).
+By default the global bib resources are used if no \opt{bib-resource} is given.
+
+\DescribeOption{locale}
+This option sets the locale used in this reference section.
+By default the global locale is used.
+
+
+\begin{function}{\newrefsection, \endrefsection}
+ \begin{syntax}
+ \cs{newrefsection}[style = \meta{style-id}, bib-resource = <datafile>, ...]
+ \cs{endrefsection}
+ \end{syntax}
+\end{function}
+
+The \cs{newrefsection} command is similar to the \env{refsection} environment
+except that it is a standalone command rather than an environment.
+It automatically ends the previous reference section (if any) and immediately
+starts a new one.
+The \cs{endrefsection} can terminate the current reference section and restore
+to the global section.
+
+
+\subsection{Bibliography Headings}
+
+\begin{function}{\defbibheading}
+ \begin{syntax}
+ \cs{defbibheading}\marg{name}\oarg{title}\marg{code}
+ \end{syntax}
+\end{function}
+
+This command defines a bibliographic heading which can be used with the
+\opt{bibheading} option of \cs{printbibliography}. The \meta{name} is an
+identifier assigned to the defined style.
+If a \opt{title} option is given in the \cs{printbibliography}, it is passed
+to the \opt{code} as |#1|. Otherwise the value \meta{title} in the optional
+argument is used by default. The following is the definition of the default
+heading when used in a \cls{book} class.
+
+\begin{LaTeXdemo}
+ \defbibheading{bibliography}[\bibname]{%
+ \chapter*{#1}%
+ \markboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}%
+ }
+\end{LaTeXdemo}
+
+
+The following are predefined headings which can be used directly.
+
+\begin{description}
+ \item[\opt{bibliography}] The default heading used by \cs{printbibliography}.
+ \item[\opt{subbibliography}] Similar to \opt{bibliography} but one sectioning level lower.
+ \item[\opt{bibintoc}] Similar to \opt{bibliography} but adds an entry to the table of contents.
+ \item[\opt{subbibintoc}] Similar to \opt{subbibliography} but adds an entry to the table of contents.
+ \item[\opt{bibnumbered}] Similar to \opt{bibliography} but uses \cs{chapter}
+ or \cs{section} to create a numbered heading which is also added to the table of contents.
+ \item[\opt{subbibnumbered}] Similar to \opt{subbibliography} but uses \cs{chapter}
+ or \cs{section} to create a numbered heading which is also added to the table of contents.
+ \item[\opt{none}] An empty heading.
+ % \item[\opt{biblist}]
+ % \item[\opt{biblistintoc}]
+ % \item[\opt{biblistnumbered}]
+\end{description}
@@ -441,52 +676,6 @@ An error will be triggered if any of them is loaded together with \pkg{citation-
\item \pkg{splitbib}
\end{itemize}
-
-
-\section{To-do list}
-
-The \pkg{citation-style-language} package is in early development stage and
-some features may not work as expected.
-Bug report are welcome at the GitHub issue tracker
-\footnote{\url{https://github.com/zepinglee/citeproc-lua/issues}}.
-The following is a list of features to be implemented.
-If you need any of them or new features, please post a issue to let me know
-so that I can give it a priority.
-
-\begin{itemize}
- \item The \pkg{citeproc-lua} engine has not passed all the fixures from the
- CSL standard test-suite. The skipped fixtures are lists in
- \href{https://github.com/zepinglee/citeproc-lua/blob/main/tests/citeproc-test-skip.txt}{citeproc-test-skip.txt}
- and they need to be handled (though less than 6\% of test-suite).
-
- \item The Unicode sorting method is provided by \pkg{lua-uca} package and
- CJK scripts are not supported so far.
-
- \item Citation commands that capitalize the first letter (\cs{Cite},
- \cs{Textcite}, etc.).
-
- \item Back references: page numbers of the citations appears after the entry
- item in bibliography (even without the hyperref).
-
- \item \cs{footcite} command.
-
- \item \cs{cite} in a footnote should work as in-text citations (similar to
- \cs{smartcite}).
-
- \item CSL-YAML support.
-
- \item Multiple bibliographies in a document like \pkg{chapterbib} package or
- \texttt{refsection} and \texttt{refsegment} options in \pkg{biblatex}.
-
- \item Journal abbreviation.
-
- \item Sentences case conversion: the title and booktitle fields in BibTeX
- database are converted to sentences case if they are in title case.
-
- \item Distinguish dropping and non-dropping particles in names.
-\end{itemize}
-
-
\end{documentation}
\end{document}
diff --git a/biblio/citation-style-language/citation-style-language-init.sty b/biblio/citation-style-language/citation-style-language-init.sty
index db83bced06..9032b60fee 100644
--- a/biblio/citation-style-language/citation-style-language-init.sty
+++ b/biblio/citation-style-language/citation-style-language-init.sty
@@ -16,8 +16,9 @@
{ \__csl_initialize_lua_module: }
{
\__csl_load_bbl:
- \__csl_read_style_class:
+ \__csl_get_style_class:
}
+ \__csl_set_ref_section_level:
}
@@ -25,19 +26,20 @@
\cs_new:Npn \__csl_write_aux_info:
{
+ \tl_if_empty:NF \l__csl_style_tl
+ { \exp_args:NV \__csl_write_aux_bibstyle:n \l__csl_style_tl }
+ \tl_if_empty:NT \l__csl_style_tl
+ { \tl_set_eq:NN \l__csl_style_tl \g__csl_aux_bibstyle_tl }
\tl_if_empty:NT \l__csl_style_tl
- {
- \tl_set_eq:NN \l__csl_style_tl \g__csl_aux_bibstyle_tl
- \edef \csl@style { \g__csl_aux_bibstyle_tl }
- }
- \tl_if_empty:VTF \l__csl_style_tl
{
\msg_warning:nn { citation-style-language } { missing-style-name }
\tl_set:Nn \l__csl_style_tl { apa }
}
- { \exp_args:NV \__csl_write_aux_bibstyle:n \l__csl_style_tl }
- \clist_if_empty:NTF \l__csl_bib_resources_clist
+ \tl_set_eq:NN \csl@style \l__csl_style_tl
+ \clist_if_empty:NT \l__csl_bib_resources_clist
{ \clist_set_eq:NN \l__csl_bib_resources_clist \g__csl_aux_bib_files_clist }
+ \clist_if_empty:NTF \l__csl_bib_resources_clist
+ { \msg_warning:nn { citation-style-language } { empty-bib-resources } }
{
\exp_args:Nx \__csl_write_aux_bibdata:n
{ \clist_use:Nn \l__csl_bib_resources_clist { , } }
@@ -48,7 +50,11 @@
\cs_new:Npn \__csl_write_aux_bibstyle:n #1
{
\if@filesw
- \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@style {#1} }
+ \iow_now:Nx \@auxout
+ {
+ \token_to_str:N \csl@aux@style
+ { \int_use:N \g__csl_ref_section_index_int } {#1}
+ }
\fi
}
@@ -56,42 +62,60 @@
{
\if@filesw
% Full expansion for files like \jobname.bib
- \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@data {#1} }
+ \iow_now:Nx \@auxout
+ {
+ \token_to_str:N \csl@aux@data
+ { \int_use:N \g__csl_ref_section_index_int } {#1}
+ }
\fi
}
% In earlier time, \bibdata{xxx.json} was used but this causes latexmk unable
% to find xxx.json.bib and it refuses to run the $bibtex procedure.
% John Collins suggests using a different command than \bibdata.
-\cs_new:Npn \csl@aux@data #1
- { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#1} }
+\cs_new:Npn \csl@aux@data #1#2
+ {
+ \str_if_eq:nnT {#1} { 0 }
+ { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#2} }
+ }
\cs_new:Npn \__csl_initialize_lua_module:
{
- \clist_if_empty:NT \l__csl_bib_resources_clist
- { \msg_warning:nn { citation-style-language } { empty-bib-resources } }
+ \bool_if:NT \l__csl_regression_test_bool
+ {
+ \lua_now:n { csl_citation_manager.regression_test = true }
+ }
+ \tl_set:Nx \l_tmpa_tl { \clist_use:Nn \l__csl_bib_resources_clist { , } }
\lua_now:e
{
- csl.init(
+ csl_citation_manager:init(
"\l__csl_style_tl",
- "\l__csl_bib_resources_clist",
+ "\l_tmpa_tl",
"\l__csl_locale_tl"
)
}
-
-
- \str_if_eq:eeT { \lua_now:n { tex.print(csl.initialized) } } { true }
+ \str_if_eq:eeTF
+ {
+ \lua_now:n
+ {
+ tex.print(tostring(
+ csl_citation_manager.ref_section.initialized
+ ))
+ }
+ }
+ { true }
{ \bool_set_true:N \l__csl_engine_initialized_bool }
- \__csl_get_style_class:
+ { \bool_set_false:N \l__csl_engine_initialized_bool }
+ \__csl_get_style_class_luatex:
\@ifpackageloaded { hyperref }
- { \lua_now:n { csl.enable_linking() } }
+ { \lua_now:n { csl_citation_manager:enable_linking() } }
{ }
}
\msg_new:nnn { citation-style-language } { missing-style-name }
- { Missing~ style~ name.\\Will~ use~ default~ APA~ style. }
+ { Missing~ style~ name.~ Will~ use~ default~ APA~ style. }
\msg_new:nnn { citation-style-language } { empty-bib-resources }
{ Empty~ bibliographic~ resources.~ Use~ \token_to_str:N \addbibresource. }
@@ -101,13 +125,16 @@
% 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: {
+\cs_new:Npn \__csl_get_style_class_luatex: {
+ \bool_set_false:N \l__csl_note_bool
\bool_if:NT \l__csl_engine_initialized_bool
{
- \tl_set:Nx \l__csl_class_tl { \lua_now:n { csl.get_style_class() } }
+ \tl_set:Nx \l__csl_class_tl { \lua_now:n { tex.print(csl_citation_manager:get_style_class()) } }
\tl_if_eq:NnT \l__csl_class_tl { note }
{ \bool_set_true:N \l__csl_note_bool }
}
+ \int_compare:nNnT { \g__csl_ref_section_index_int } = { 0 }
+ { \bool_gset_eq:NN \g__csl_global_note_class_bool \l__csl_note_bool }
}
@@ -225,7 +252,7 @@
turkmen = tk-TM,
ukrainian = uk-UA,
urdu = ur-IN,
- UKenglish = en-UK,
+ UKenglish = en-GB,
uppersorbian = hsb-DE,
USenglish = en-US,
usorbian = hsb-DE,
@@ -266,14 +293,16 @@
\cs_new:Npn \__csl_write_aux_options:n #1
{
\if@filesw
- \iow_now:Nn \@auxout { \csl@aux@options {#1} }
+ \iow_now:Nx \@auxout
+ {
+ \token_to_str:N \csl@aux@options
+ { \int_use:N \g__csl_ref_section_index_int } {#1}
+ }
\fi
}
-\cs_new:Npn \csl@aux@options #1 { }
-
+\cs_new:Npn \csl@aux@options #1#2 { }
-\tl_new:N \g__csl_bibliography_setup_tl
% Load .bbl at the beginning of document to save one pass of latex.
% In this procedure, the \cslcitation command is processed and the contents
@@ -283,10 +312,6 @@
% The \@input@ prints "No file ....bbl" in the .log file from which
% the latexmk decides to run $bibtex or not.
\__csl_collect_bibliography:n { \@input@ { \jobname .bbl } }
- % Execute the \cslsetup part to set the style class.
- % \tl_show:N \g__csl_bibliography_setup_tl
- \tl_use:N \g__csl_bibliography_setup_tl
- % \bool_show:N \l__csl_note_bool
}
@@ -302,8 +327,6 @@
% URLs may contain "%" and "#" characters.
\char_set_catcode_other:N \%
\char_set_catcode_other:N \#
- \RenewDocumentCommand \cslsetup { m }
- { \tl_gset:Nn \g__csl_bibliography_setup_tl { \cslsetup { ##1 } } }
\RenewDocumentEnvironment { thebibliography } { m +b }
{
\tl_set:Nn \l__csl_bib_index_tl { 1 }
@@ -321,29 +344,121 @@
\group_end:
}
+% At the moment, the `\csloptions` only reads the style class from `.bbl`
+% generated by `citeproc-lua`.
+% #1: refsection index
+% #2: refsection options
+\NewDocumentCommand \csloptions { m m }
+ { \keys_set:nn { csl / options } { #2 } }
+
+% The class option is in the `<style>=<class>` form
+% (e.g. `\csloptions{class={apa=in-text}}`).
+\keys_define:nn { csl / options }
+ {
+ class .code:n = { \prop_gput_from_keyval:Nn \g__csl_style_class_prop {#1} },
+ }
+
+\prop_new:N \g__csl_style_class_prop
% The `\textcite` bahaves differently with note styles.
% Thus we read the style class from the `.csl` file with non-LuaTeX engines.
\ior_new:N \l__csl_style_ior
-\cs_new:Npn \__csl_read_style_class:
+\cs_new:Npn \__csl_get_style_class:
{
+ \tl_clear:N \l__csl_class_tl
\bool_set_false:N \l__csl_note_bool
+ \prop_get:NVNF \g__csl_style_class_prop \l__csl_style_tl \l__csl_class_tl
+ { \__csl_read_style_class: }
+ \tl_if_empty:NF \l__csl_class_tl
+ {
+ \str_case:VnTF \l__csl_class_tl
+ {
+ { note } { \bool_set_true:N \l__csl_note_bool }
+ { in-text } { \bool_set_false:N \l__csl_note_bool }
+ }
+ {
+ \int_compare:nNnT { \g__csl_ref_section_index_int } = { 0 }
+ {
+ \bool_gset_eq:NN \g__csl_global_note_class_bool \l__csl_note_bool
+ }
+ }
+ {
+ \msg_error:nnV { citation-style-language } { invalid-style-class }
+ \l__csl_class_tl
+ }
+ }
+ }
+
+\cs_new:Npn \__csl_read_style_class:
+ {
\tl_if_blank:VF \l__csl_style_tl
{
\exp_args:NNx \ior_open:Nn \l__csl_style_ior { \l__csl_style_tl .csl }
\ior_map_inline:Nn \l__csl_style_ior
{
% \tl_show:n {##1}
- \tl_if_in:nnT {##1} { class="note" }
+ \tl_if_in:nnTF {##1} { class="note" }
{
\tl_set:Nn \l__csl_class_tl { note }
\bool_set_true:N \l__csl_note_bool
+ \prop_gput:NVn \g__csl_style_class_prop \l__csl_style_tl { note }
\ior_map_break:
}
+ {
+ \tl_if_in:nnT {##1} { class="in-text" }
+ {
+ \tl_set:Nn \l__csl_class_tl { in-text }
+ \bool_set_false:N \l__csl_note_bool
+ \prop_gput:NVn \g__csl_style_class_prop \l__csl_style_tl { in-text }
+ \ior_map_break:
+ }
+ }
}
\ior_close:N \l__csl_style_ior
}
}
-% \msg_new:nnn { citation-style-language } { file / non-exist }
+\msg_new:nnn { citation-style-language } { invalid-style-class }
+ { Invalid~ style~ class~ '#1'. }
+
+% \msg_new:nnn { citation-style-language } { file-non-exist }
% { No~ file~ #1. }
+
+\cs_new:Npn \__csl_set_ref_section_level:
+ {
+ \str_case:Vn \l__csl_bib_ref_section_str
+ {
+ { none } { }
+ { part }
+ { \__csl_patch_ref_section:n { part } }
+ { chapter }
+ { \__csl_patch_ref_section:n { chapter } }
+ { chapter+ }
+ {
+ \__csl_patch_ref_section:n { part }
+ \__csl_patch_ref_section:n { chapter }
+ }
+ { section }
+ { \__csl_patch_ref_section:n { section } }
+ { section+ }
+ {
+ \__csl_patch_ref_section:n { part }
+ \__csl_patch_ref_section:n { chapter }
+ \__csl_patch_ref_section:n { section }
+ }
+ { subsection }
+ { \__csl_patch_ref_section:n { subsection } }
+ { subsection+ }
+ {
+ \__csl_patch_ref_section:n { part }
+ \__csl_patch_ref_section:n { chapter }
+ \__csl_patch_ref_section:n { section }
+ \__csl_patch_ref_section:n { subsection }
+ }
+ }
+ }
+
+\cs_new:Npn \__csl_patch_ref_section:n #1
+ {
+ \hook_gput_code:nnn { cmd / #1 / before } { . } { \newrefsection }
+ }
diff --git a/biblio/citation-style-language/citation-style-language.sty b/biblio/citation-style-language/citation-style-language.sty
index 900d717c92..33ce246978 100644
--- a/biblio/citation-style-language/citation-style-language.sty
+++ b/biblio/citation-style-language/citation-style-language.sty
@@ -9,16 +9,23 @@
\RequirePackage{expl3}
\RequirePackage{xparse}
-\ProvidesExplPackage {citation-style-language} {2024-04-21} {0.4.9}
+\ProvidesExplPackage {citation-style-language} {2024-09-15} {0.6.4}
{Citation Style Language for LaTeX}
\RequirePackage { l3keys2e }
\RequirePackage { url }
+\prop_gput:Nnn \g_msg_module_name_prop { citation-style-language } { CSL }
+\prop_gput:Nnn \g_msg_module_type_prop { citeproc } { Module }
+
+\msg_new:nnn { citeproc } { citeproc-error } {#1}
+\msg_new:nnn { citeproc } { citeproc-warning } {#1}
+
+
% Check incompatible packages
\msg_new:nnn { citation-style-language } { incompatible-package }
- { The~ `#1'~ package~ is~ incompatible~ with~ `citation-style-language'. }
+ { Package~ '#1'~ is~ incompatible~ with~ 'citation-style-language'. }
\clist_map_inline:nn
{
@@ -34,7 +41,13 @@
% Load Lua module in LuaTeX
\sys_if_engine_luatex:T
- { \lua_now:n { csl = require("citeproc-latex") } }
+ {
+ \lua_now:n
+ {
+ citeproc_manager = require("citeproc-manager")
+ csl_citation_manager = citeproc_manager.CslCitationManager:new()
+ }
+ }
% Global options
@@ -44,11 +57,15 @@
\bool_new:N \l__csl_regression_test_bool
+\tl_new:N \g__csl_global_style_tl
\tl_new:N \l__csl_style_tl
\newcommand \csl@style {} % For latex2e interface
\tl_new:N \l__csl_class_tl % TODO: This should be removed
+\bool_new:N \g__csl_global_note_class_bool
\bool_new:N \l__csl_note_bool
+\clist_new:N \g__csl_global_bib_resources_clist
\clist_new:N \l__csl_bib_resources_clist
+\tl_new:N \g__csl_global_locale_tl
\tl_new:N \l__csl_locale_tl
\bool_new:N \l__csl_back_ref_bool
\str_new:N \l__csl_back_ref_type_str
@@ -62,6 +79,7 @@
\tl_new:N \l__csl_bib_item_sep_tl
\tl_new:N \l__csl_bib_par_indent_tl
\tl_new:N \l__csl_bib_hang_tl
+\str_new:N \l__csl_bib_ref_section_str
\keys_define:nn { csl }
@@ -71,14 +89,19 @@
{
\tl_set:Nn \l__csl_style_tl {#1}
\renewcommand \csl@style {#1}
+ \tl_gset:Nn \g__csl_global_style_tl {#1}
} ,
- class .code:n =
+ class .code:n = {} , % Deprecated, should be removed in the next release.
+ bib-resource .code:n =
{
- \tl_set:Nn \l__csl_class_tl {#1}
- \tl_if_eq:NnT \l__csl_class_tl { note }
- { \bool_set_true:N \l__csl_note_bool }
+ \clist_set:Nn \l__csl_bib_resources_clist {#1}
+ \clist_gset_eq:NN \g__csl_global_bib_resources_clist \l__csl_bib_resources_clist
+ } ,
+ locale .code:n =
+ {
+ \tl_set:Nn \l__csl_locale_tl {#1}
+ \tl_gset:Nn \g__csl_global_locale {#1}
} ,
- locale .tl_set:N = \l__csl_locale_tl ,
backref .choices:nn =
{ true, page, section, false }
{ \exp_args:NV \__csl_set_back_ref:n \l_keys_choice_tl } ,
@@ -92,13 +115,10 @@
bib-item-sep .tl_set:N = \l__csl_bib_item_sep_tl ,
bib-par-indent .tl_set:N = \l__csl_bib_par_indent_tl ,
bib-hang .tl_set:N = \l__csl_bib_hang_tl ,
- % The following keys are for easier interaction between LaTeX and
- % citeproc-lua engine and they are not designed for end-users.
- undefined-cites .code:n =
- {
- \clist_map_inline:nn {#1}
- { \__csl_warn_citation_undefined:n {##1} }
- } ,
+ % ref section
+ ref-section .choices:nn =
+ { none, part, chapter, chapter+, section, section+, subsection, subsection+ }
+ { \str_set:NV \l__csl_bib_ref_section_str \l_keys_choice_tl } ,
}
\cs_new:Npn \__csl_set_back_ref:n #1
@@ -124,6 +144,7 @@
bib-entry-page-break = true ,
bib-par-indent = { \parindent } ,
bib-hang = { 1 em } ,
+ ref-section = none ,
}
@@ -138,8 +159,11 @@
}
\tl_new:N \g__csl_aux_bibstyle_tl
-\cs_set:Npn \csl@aux@style #1
- { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#1} }
+\cs_set:Npn \csl@aux@style #1#2
+ {
+ \str_if_eq:nnT {#1} { 0 }
+ { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#2} }
+ }
% Write to an empty `.ccf` file for use with latexmk
diff --git a/biblio/citation-style-language/citeproc-bibtex-data.lua b/biblio/citation-style-language/citeproc-bibtex-data.lua
index 29f5a0c590..fc1d04d4f4 100644
--- a/biblio/citation-style-language/citeproc-bibtex-data.lua
+++ b/biblio/citation-style-language/citeproc-bibtex-data.lua
@@ -1,4 +1,4 @@
--- This file is generated from citeproc-bibtex-data.json by scripts/update-bibtex-data.py
+-- This file is generated from citeproc-bibtex-data.json by scripts/update_bibtex_data.py
return {
description = "BibTeX CSL mapping",
@@ -1272,6 +1272,11 @@ return {
source = "apa.dbx",
type = "literal",
},
+ citations = {
+ csl = nil,
+ source = "publist.dbx",
+ type = "literal",
+ },
citedate = {
csl = nil,
source = "seuthesis.bst",
diff --git a/biblio/citation-style-language/citeproc-bibtex-parser.lua b/biblio/citation-style-language/citeproc-bibtex-parser.lua
index 39f4826ca1..27d6ff3dc8 100644
--- a/biblio/citation-style-language/citeproc-bibtex-parser.lua
+++ b/biblio/citation-style-language/citeproc-bibtex-parser.lua
@@ -117,7 +117,7 @@ local function concat_strings(pieces, strings)
if piece_str then
value = value .. piece_str
else
- util.warning(string.format('String name "%s" is undefined."', piece.name))
+ util.warning(string.format("String name '%s' is undefined.", piece.name))
end
end
end
@@ -311,7 +311,7 @@ end
function bibtex_parser.split_name_parts(str)
str = util.strip(str)
if string.match(str, ",$") then
- util.warning(string.format('Name "%s" has has a comma at the end.', str))
+ util.warning(string.format("Name '%s' has has a comma at the end.", str))
str = string.gsub(str, ",$", '')
end
@@ -339,7 +339,7 @@ function bibtex_parser.split_name_parts(str)
elseif #parts == 3 then
name = bibtex_parser._split_last_jr_first_parts(parts)
elseif #parts > 3 then
- util.error(string.format('Too many commas in name "%s"', str))
+ util.error(string.format("Too many commas in name '%s'", str))
name = bibtex_parser._split_last_jr_first_parts(util.slice(parts, 1, 3))
end
@@ -407,7 +407,7 @@ function bibtex_parser._split_extended_name_format(parts)
key, value = string.match(part, '^"([a-zA-Z]+%-?i?)%s*=%s*(.-)%s*"%s*$')
end
if not key then
- util.error(string.format('Invalid extended name part "%s"', part))
+ util.error(string.format("Invalid extended name part '%s'", part))
end
if key == "given" then
diff --git a/biblio/citation-style-language/citeproc-bibtex2csl.lua b/biblio/citation-style-language/citeproc-bibtex2csl.lua
index cc4cf2580f..a2979748f0 100644
--- a/biblio/citation-style-language/citeproc-bibtex2csl.lua
+++ b/biblio/citation-style-language/citeproc-bibtex2csl.lua
@@ -374,6 +374,9 @@ end
function bibtex2csl._parse_edtf_date(str)
local date_range = util.split(str, "/")
+ if str == "" then
+ return nil
+ end
if #date_range == 1 then
date_range = util.split(str, util.unicode["en dash"])
end
diff --git a/biblio/citation-style-language/citeproc-cli.lua b/biblio/citation-style-language/citeproc-cli.lua
index 83e6d35e9b..6a86fa4b24 100644
--- a/biblio/citation-style-language/citeproc-cli.lua
+++ b/biblio/citation-style-language/citeproc-cli.lua
@@ -11,10 +11,10 @@ local cli = {}
local lpeg = require("lpeg")
require("lualibs")
+local citeproc_manager = require("citeproc-manager")
local citeproc = require("citeproc")
local bibtex2csl -- = require("citeproc-bibtex-parser") -- load on demand
local util = require("citeproc-util")
-local core = require("citeproc-latex-core")
local latex_parser = require("citeproc-latex-parser")
@@ -82,116 +82,6 @@ local function convert_bib(path, output_path)
end
-local balanced = lpeg.P{ "{" * lpeg.V(1)^0 * "}" + (1 - lpeg.S"{}") }
-
-
----@param text string
----@return string?
-local function get_command_argument(text, command)
- if string.match(text, command) then
- local grammar = (lpeg.P(command) * lpeg.S(" \t\r\n")^0 * lpeg.C(balanced) + 1)^0
- local argument = grammar:match(text)
- if not argument then
- return nil
- end
- argument = string.sub(argument, 2, -2)
- return argument
- end
- return nil
-end
-
-
-
----comment
----@param aux_file any
----@return string
----@return string[]
----@return Citation[]
----@return table<string, string>
----@return string[]
-local function read_aux_file(aux_file)
- local csl_style = nil
- local csl_data_files = {}
- local csl_citations = {}
- local csl_options = {}
- local csl_bibliographies = {}
-
- local file = io.open(aux_file)
- if not file then
- util.error(string.format("Couldn't open file %s", aux_file))
- return csl_style, csl_data_files, csl_citations, csl_options, csl_bibliographies
- end
- for line in file:lines() do
- -- TODO: Use lpeg-based method and detect multiple lines
- local style = get_command_argument(line, "\\csl@aux@style")
- if style then
- csl_style = style
- else
- local data = get_command_argument(line, "\\csl@aux@data")
- if data then
- for _, bib_file in ipairs(latex_parser.parse_seq(data)) do
- table.insert(csl_data_files, bib_file)
- end
- else
- local cite = get_command_argument(line, "\\csl@aux@cite")
- if cite then
- local citation = core.make_citation(cite)
- table.insert(csl_citations, citation)
- else
- local options = get_command_argument(line, "\\csl@aux@options")
- if options then
- options = latex_parser.parse_prop(options)
- for key, value in pairs(options) do
- csl_options[key] = value
- end
- else
- local bib = get_command_argument(line, "\\csl@aux@bibliography")
- if bib then
- table.insert(csl_bibliographies, bib)
- else
- local sub_aux_file = get_command_argument(line, "\\@input")
- if sub_aux_file and util.endswith(sub_aux_file, ".aux") then
- local style_name, data_files, citations, opts, bibs = read_aux_file(sub_aux_file)
- if style_name then
- csl_style = style_name
- end
- util.extend(csl_data_files, data_files)
- util.extend(csl_citations, citations)
- util.extend(csl_citations, citations)
- for key, value in pairs(opts) do
- csl_options[key] = value
- end
- util.extend(csl_bibliographies, bibs)
- end
- end
- end
- end
- end
- end
- end
- file:close()
-
- return csl_style, csl_data_files, csl_citations, csl_options, csl_bibliographies
-end
-
-
-local function get_undefined_info(core, citation)
- local res = ""
- for _, cite_item in ipairs(citation.citationItems) do
- if not core.item_dict[cite_item.id] then
- if res ~= "" then
- res = res .. ","
- end
- res = res .. cite_item.id
- end
- end
- if res ~= "" then
- res = string.format("\\cslsetup{undefined-cites={%s}}", res)
- end
- return res
-end
-
-
---@param aux_file string
local function process_aux_file(aux_file)
if not util.endswith(aux_file, ".aux") then
@@ -204,73 +94,17 @@ local function process_aux_file(aux_file)
util.info(banner)
util.info(string.format("The top-level auxiliary file: %s", aux_file))
- local style_name, bib_files, citations, csl_options, bibliographies = read_aux_file(aux_file)
-
- if style_name and style_name ~= "" then
- util.info(string.format("The style file: %s.csl", style_name))
- else
- util.warning("Missing style name. Will use default APA style.")
- style_name = "apa"
- end
-
- if #citations == 0 then
- util.error(string.format("No citation commands in file %s", aux_file))
- end
-
- if #bib_files == 0 then
- util.warning("empty bibliography data files")
- else
- for i, bib_file in ipairs(bib_files) do
- util.info(string.format("Database file #%d: %s", i, bib_file))
- end
- end
-
- local lang = csl_options.locale
-
- local engine = core.init(style_name, bib_files, lang)
- if not engine then
- error("citeproc-lua: fails in initialize engine")
- end
- if csl_options.linking then
- engine:enable_linking()
- end
- local style_class = engine:get_style_class()
-
- if style_class == "in-text" then
- for _, citation in ipairs(citations) do
- citation.properties.noteIndex = 0
- end
- end
-
- local citation_strings = core.process_citations(engine, citations)
-
- -- util.debug(citation_strings)
+ local csl_citation_manager = citeproc_manager.CslCitationManager:new()
- local output_string = string.format("\\cslsetup{class = %s}\n\n", style_class)
-
- for _, citation in ipairs(citations) do
- local citation_id = citation.citationID
- if citation_id ~= "@nocite" then
- local citation_str = citation_strings[citation_id]
- local undefined_entry_info = get_undefined_info(core, citation)
- output_string = output_string .. string.format("\\cslcitation{%s}{%s%s}\n",
- citation_id, undefined_entry_info, citation_str)
- end
- end
-
- output_string = output_string .. "\n"
- local categories_str = csl_options["categories"]
- if categories_str then
- core.set_categories(engine, categories_str)
+ local aux_content = util.read_file(aux_file)
+ if not aux_content then
+ return
end
- for _, bib_filter_str in ipairs(bibliographies) do
- local result = core.make_bibliography(engine, bib_filter_str)
- output_string = output_string .. "\n\n\n" .. result
- end
+ local bbl_str = csl_citation_manager:read_aux_file(aux_content)
local output_path = string.gsub(aux_file, "%.aux$", ".bbl")
- util.write_file(output_string, output_path)
+ util.write_file(bbl_str, output_path)
util.quiet_mode = false;
if util.num_errors > 1 then
diff --git a/biblio/citation-style-language/citeproc-context.lua b/biblio/citation-style-language/citeproc-context.lua
index 13618b407a..3802b854e7 100644
--- a/biblio/citation-style-language/citeproc-context.lua
+++ b/biblio/citation-style-language/citeproc-context.lua
@@ -23,9 +23,11 @@ end
---@class Context
---@field reference ItemData?
----@field format any
+---@field format OutputFormat
---@field cite_id string?
+---@field engine CiteProc
---@field style any Style
+---@field lang LanguageCode
---@field locale Locale?
---@field name_citation any
---@field names_delimiter any
@@ -60,6 +62,7 @@ local Context = {
function Context:new()
local o = {
+ lang = "en-US",
in_bibliography = false
}
setmetatable(o, self)
@@ -297,7 +300,7 @@ end
function Context:get_macro(name)
local res = self.style.macros[name]
if not res then
- util.error(string.format('Undefined macro "%s"', name))
+ util.error(string.format("Undefined macro '%s'", name))
end
return res
end
@@ -348,6 +351,9 @@ function Context:is_english()
end
+---@class IrState
+---@field macro_stack string[]
+---@field suppressed {[string]: boolean}
local IrState = {}
function IrState:new(style, cite_id, cite, reference)
@@ -363,7 +369,7 @@ 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))
+ util.error(string.format("Recursive macro '%s'.", macro_name))
end
table.insert(self.macro_stack, macro_name)
end
diff --git a/biblio/citation-style-language/citeproc-element.lua b/biblio/citation-style-language/citeproc-element.lua
index 2fb19b4848..a704ac1666 100644
--- a/biblio/citation-style-language/citeproc-element.lua
+++ b/biblio/citation-style-language/citeproc-element.lua
@@ -245,6 +245,9 @@ function Element:build_group_ir(engine, state, context)
return ir
end
+---@param str string
+---@param context Context
+---@return InlineElement[]
function Element:render_text_inlines(str, context)
if str == "" then
return {}
@@ -384,10 +387,20 @@ function Element:apply_strip_periods(str)
end
+---@param number string Non-empty string
+---@param variable string
+---@param form string
+---@param context Context
+---@return string
function Element:format_number(number, variable, form, context)
number = util.strip(number)
if variable == "locator" then
- variable = context:get_variable("label")
+ local locator_variable = context:get_variable("label")
+ if not locator_variable or type(locator_variable) ~= "string" then
+ util.error("Invalid locator label")
+ locator_variable = "page"
+ end
+ variable = locator_variable
end
form = form or "numeric"
local number_part_list = self:split_number_parts_lpeg(number, context)
@@ -431,9 +444,11 @@ function Element:format_number(number, variable, form, context)
return res
end
----comment
----@param number any
----@param context any
+---@alias NumberToken {type: string, value: string, delimiter_type: string}
+
+---@param number string
+---@param context Context
+---@return NumberToken[]
function Element:parse_number_tokens(number, context)
local and_text = "and"
local and_symbol = "&"
@@ -465,10 +480,15 @@ function Element:parse_number_tokens(number, context)
value = token,
}
end
- local grammer = l.Ct(token_patt * (delimiter * token_patt)^0)
+ local grammer = l.Ct((token_patt * (delimiter * token_patt)^0)^-1)
local tokens = grammer:match(number)
-- util.debug(tokens)
+ if not tokens then
+ return {}
+ end
+ ---@cast tokens NumberToken[]
+
for i, token in ipairs(tokens) do
if token.type == "string" then
token.value = string.gsub(token.value, "\\%-", "-")
diff --git a/biblio/citation-style-language/citeproc-engine.lua b/biblio/citation-style-language/citeproc-engine.lua
index 4d69b9be15..01966fe219 100644
--- a/biblio/citation-style-language/citeproc-engine.lua
+++ b/biblio/citation-style-language/citeproc-engine.lua
@@ -49,12 +49,35 @@ local SortStringFormat = output.SortStringFormat
local Position = util.Position
+---@alias CitationId string
---@alias ItemId string | number
---@alias NoteIndex integer
----@alias CitationId string
----@alias CitationData {citationID: CitationId, citationItems: CitationItem[], properties: CitationProperties, citation_index: integer}
+---@alias ChapterIndex number
+
+---@class CitationData
+---@field citationID CitationId
+---@field citationItems CitationItem[]
+---@field properties CitationProperties
+---@field citation_index integer
+---@field sorted_items CitationItem[]
+
+---@class CitationItem
+---@field id CiteId
+---@field prefix string?
+---@field suffix string?
+---@field locator string?
+---@field label string?
+---@field position_level Position?
+---@field near_note boolean?
+---@field num_citations integer?
+
+---@class CitationProperties
+---@field noteIndex NoteIndex,
+---@field chapterIndex ChapterIndex,
+---@field mode string?
+---@field prefix string?
+---@field suffix string?
----@alias CitationProperties { noteIndex: integer, mode: string? }
---@class NameVariable
---@field family string?
@@ -93,16 +116,27 @@ local Registry = {}
---@class CiteProc
---@field style Style
----@field sys any
----@field locales Locale[]
----@field system_locales Locale[]
----@field lang string
+---@field sys CiteProcSys
+---@field locales table<LanguageCode, Locale>
+---@field system_locales table<LanguageCode, Locale>
+---@field lang LanguageCode
---@field output_format OutputFormat
---@field opt table
---@field registry Registry
---@field cite_first_note_numbers table<ItemId, NoteIndex>
+---@field cite_last_note_numbers table<ItemId, NoteIndex>
+---@field tainted_item_ids table<ItemId, boolean>
+---@field disam_irs IrNode[]
+---@field cite_irs_by_output table<string, IrNode[]>
+---@field person_names PersonNameIr[]
+---@field person_names_by_output table<string, PersonNameIr[]>
+---@field locale_tags_info_dict table<LanguageCode, table>
local CiteProc = {}
+---@class CiteProcSys
+---@field retrieveLocale fun(LanguageCode): string?
+---@field retrieveItem fun(ItemId): ItemData?
+
---comment
---@param sys table
---@param style string
@@ -119,62 +153,60 @@ function CiteProc.new(sys, style, lang, force_lang)
if sys.retrieveItem == nil then
error("\"citeprocSys.retrieveItem\" required")
end
- ---@type CiteProc
- 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"
+ local parsed_style = Style:parse(style)
+ local engine_lang = parsed_style.default_locale
+ if not engine_lang or force_lang then
+ engine_lang = lang or "en-US"
end
-
- o.output_format = LatexWriter:new()
-
- o.opt = {
- -- Similar to citeproc-js's development_extensions.wrap_url_and_doi
- wrap_url_and_doi = false,
- citation_link = false,
- title_link = false,
- }
-
- o.registry = {
- 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,
- widest_label = "",
- maxoffset = 0,
+ ---@type CiteProc
+ local o = {
+ style = parsed_style,
+ sys = sys,
+ locales = {},
+ system_locales = {},
+ lang = engine_lang,
+ output_format = LatexWriter:new(),
+ opt = {
+ -- Similar to citeproc-js's development_extensions.wrap_url_and_doi
+ wrap_url_and_doi = false,
+ citation_link = false,
+ title_link = false,
+ },
+ registry = {
+ 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,
+ widest_label = "",
+ maxoffset = 0,
+ },
+
+ cite_first_note_numbers = {},
+ cite_last_note_numbers = {},
+
+ tainted_item_ids = {},
+
+ disam_irs = {},
+ -- { <ir1>, <ir2>, ... }
+
+ cite_irs_by_output = {},
+ -- {
+ -- ["Roe, J"] = {<ir1>},
+ -- ["Doe, J"] = {<ir2>, <ir3>},
+ -- ["Doe, John"] = {<ir2>},
+ -- ["Doe, Jack"] = {<ir2>},
+ -- }
+
+ person_names = {},
+ person_names_by_output = {},
+
+ locale_tags_info_dict = {},
}
- o.cite_first_note_numbers = {}
- o.cite_last_note_numbers = {}
- o.note_citations_map = {}
-
- o.tainted_item_ids = {}
-
- o.disam_irs = {}
- -- { <ir1>, <ir2>, ... }
-
- 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
@@ -189,16 +221,6 @@ function CiteProc:get_independent_parent()
return self.style.info.independent_parent
end
-function CiteProc:check_valid_citation_element()
- if not self.style.citation then
- if self.style.info and self.style.info.independent_parent then
- util.error(string.format('This is a dependent style linked to "%s".', self.style.info.independent_parent))
- else
- util.error('No <citation> in style.')
- end
- end
-end
-
---@param ids CiteId[]
function CiteProc:updateItems(ids)
-- util.debug(string.format('updateItems(%s)', table.concat(ids, ", ")))
@@ -213,8 +235,10 @@ function CiteProc:updateItems(ids)
local loaded_ids = {}
for _, id in ipairs(ids) do
- table.insert(cite_items, {id = id})
- loaded_ids[id] = true
+ if not loaded_ids[id] then
+ table.insert(cite_items, {id = id})
+ loaded_ids[id] = true
+ end
end
for _, id in ipairs(self.registry.uncited_list) do
if not loaded_ids[id] then
@@ -232,7 +256,6 @@ function CiteProc:updateItems(ids)
self.registry.previous_citation = nil
self.cite_first_note_numbers = {}
self.cite_last_note_numbers = {}
- self.note_citations_map = {}
for _, item in ipairs(self.registry.registry) do
item.year_suffix_number = nil
@@ -281,100 +304,214 @@ function CiteProc:updateUncitedItems(uncited_ids)
self.registry.previous_citation = nil
self.cite_first_note_numbers = {}
self.cite_last_note_numbers = {}
- self.note_citations_map = {}
end
+---@alias PreCitation [CitationId, NoteIndex, ChapterIndex?]
+---@alias PostCitation [CitationId, NoteIndex, ChapterIndex?]
+
---@param citation CitationData
----@param citationsPre (CitationId | NoteIndex)[]
----@param citationsPost (CitationId | NoteIndex)[]
----@return (table | (integer | string | CitationId)[])[]
-function CiteProc:processCitationCluster(citation, citationsPre, citationsPost)
+---@param citations_pre PreCitation[]
+---@param citations_post PostCitation[]
+---@return [table, [integer, string, CitationId][]]
+function CiteProc:processCitationCluster(citation, citations_pre, citations_post)
-- util.debug(string.format('processCitationCluster(%s)', citation.citationID))
- self:check_valid_citation_element()
- citation = self:normalize_citation_input(citation)
-
- -- 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)
+ self:_check_valid_citation_element()
+ citation = self:_normalize_citation_input(citation)
+ self:_check_input(citation, citations_pre, citations_post)
- 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_)
+ local citation_list, item_ids = self:_build_reconstituted_citation_list(citation, citations_pre, citations_post)
+ self:updateItems(item_ids)
+ if #citation.sorted_items > 1 and self.style.citation.sort then
+ citation.sorted_items = self.style.citation:sorted_citation_items(citation.citationItems, self)
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
- table.insert(self.registry.citations_by_item_id[cite_item.id], citation_)
- end
- end
- self:updateItems(item_ids)
+ local tainted_citation_ids = self:_set_positions(citation_list)
+
+ tainted_citation_ids[citation.citationID] = true
local params = {
bibchange = false,
citation_errors = {},
}
- local output = {}
+ -- TODO: evaluate params.bibchange
- local tainted_citation_ids = self:get_tainted_citation_ids(citation_note_pairs)
- tainted_citation_ids[citation.citationID] = true
+ local result = self:_rerun_changed_cites(tainted_citation_ids)
- -- Citeproc-js marks all related citations as tainted but I don't think it's
- -- necessary.
- if self.style.class == "note" and self.style.has_disambiguate then
- for _, cite_item in ipairs(citation.citationItems) do
- for _, citation_ in ipairs(self.registry.citations_by_item_id[cite_item.id]) do
- tainted_citation_ids[citation_.citationID] = true
- end
- end
+ return {params, result}
+end
+
+-- A variant of processCitationCluster() for easy use with LaTeX.
+-- It should be run after refreshing the registry (updateItems()) with all items
+---@param citation CitationData
+---@return string
+function CiteProc:process_citation(citation)
+ -- util.debug(string.format('process_citation(%s)', citation.citationID))
+ self:_check_valid_citation_element()
+ citation = self:_normalize_citation_input(citation)
+
+ local citations_pre = {}
+ for _, citation_ in ipairs(self.registry.citation_list) do
+ table.insert(citations_pre, {citation_.citationID, citation_.properties.noteIndex})
end
+ self:_check_input(citation, citations_pre, {})
- -- util.debug(tainted_citation_ids)
+ local citation_list, item_ids = self:_build_reconstituted_citation_list(citation, citations_pre, {})
+ -- self:updateItems(item_ids)
+ for i, cite_item in ipairs(citation.citationItems) do
+ self:get_item(cite_item.id)
+ end
+ if #citation.sorted_items > 1 and self.style.citation.sort then
+ citation.sorted_items = self.style.citation:sorted_citation_items(citation.citationItems, self)
+ end
- -- params.bibchange = #tainted_citation_ids > 0
- for citation_id, _ in pairs(tainted_citation_ids) do
- local citation_ = self.registry.citations_by_id[citation_id]
+ self:_set_positions(citation_list)
+ local tainted_citation_ids = {[citation.citationID] = true}
+ local result = self:_rerun_changed_cites(tainted_citation_ids)
+ return result[1][2]
+end
- local citation_index = citation_.citation_index
+function CiteProc:makeCitationCluster(citation_items)
+ local special_form = nil
+ local items = {}
- local mode = citation_.properties.mode
- if mode == "suppress-author" and self.style.class == "note" then
- mode = nil
+ for i, cite_item in ipairs(citation_items) do
+ cite_item = self:_normalize_cite_item(cite_item)
+ 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 cite_item = setmetatable(cite_item, {__index = item_data})
+
+ if not special_form then
+ for _, form in ipairs({"author-only", "suppress-author", "coposite"}) do
+ if cite_item[form] then
+ special_form = form
+ end
+ end
end
- local citation_elemement = self.style.citation
- if mode == "author-only" and self.style.intext then
- citation_elemement = self.style.intext
+
+ -- Set "first-reference-note-number" variable when called from
+ -- processCitationCluster() > updateItems()
+ local citations = self.registry.citations_by_item_id[cite_item.id]
+ if citations and #citations > 0 then
+ cite_item["first-reference-note-number"] = citations[1].properties.noteIndex
+ end
+
+ cite_item.position_level = Position.First
+ if self.cite_first_note_numbers[cite_item.id] then
+ cite_item.position_level = Position.Subsequent
+ else
+ self.cite_first_note_numbers[cite_item.id] = 0
end
- local citation_str = citation_elemement:build_citation_str(citation_, self)
- table.insert(output, {citation_index, citation_str, citation_id})
+ 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 == cite_item.id then
+ preceding_cite = previous_citation.citationItems[1]
+ end
+ end
+ elseif citation_items[i - 1].id == cite_item.id then
+ preceding_cite = citation_items[i - 1]
+ end
+
+ if preceding_cite then
+ cite_item.position_level = self:_get_ibid_position(cite_item, preceding_cite)
+ end
+
+ table.insert(items, cite_item)
+ end
+
+ if self.registry.requires_sorting then
+ self:sort_bibliography()
+ end
+
+ self:_check_valid_citation_element()
+ local citation_element = self.style.citation
+ if special_form == "author-only" and self.style.intext then
+ citation_element = self.style.intext
+ end
+
+ local res = citation_element:build_cluster(items, self)
+
+ -- local context = {
+ -- build = {},
+ -- engine=self,
+ -- }
+ -- local res = self.style:render_citation(items, context)
+
+ self.registry.previous_citation = {
+ citationID = "pseudo-citation",
+ citationItems = items,
+ properties = {
+ noteIndex = 0,
+ }
+ }
+ return res
+end
+
+---@param bibsection any
+---@return [{[string]: string | number | boolean}, string[]]
+function CiteProc:makeBibliography(bibsection)
+ -- The bibsection works as a filter described in
+ -- <https://citeproc-js.readthedocs.io/en/latest/running.html#selective-output-with-makebibliography>.
+ if not self.style.bibliography then
+ return {{}, {}}
+ end
+
+ local res = {}
+
+ self.registry.widest_label = ""
+ self.registry.maxoffset = 0
+
+ local ids = self:_get_sorted_refs()
+ if bibsection then
+ ids = self:_filter_with_bibsection(ids, bibsection)
+ end
+ for _, id in ipairs(ids) do
+ local str = self.style.bibliography:build_bibliography_str(id, self)
+ table.insert(res, str)
+ 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 or false,
+ linespacing = self.style.bibliography.line_spacing,
+ entryspacing = self.style.bibliography.entry_spacing,
+ maxoffset = self.registry.maxoffset,
+ widest_label = self.registry.widest_label,
+ bibstart = bib_start,
+ bibend = bib_end,
+ entry_ids = util.clone(self.registry.reflist),
+ }
- return {params, output}
+ return {params, res}
+end
+
+function CiteProc:_check_valid_citation_element()
+ if not self.style.citation then
+ if self.style.info and self.style.info.independent_parent then
+ util.error(string.format("This is a dependent style linked to '%s'.", self.style.info.independent_parent))
+ else
+ util.error('No <citation> in style.')
+ end
+ end
end
-function CiteProc:normalize_citation_input(citation)
+---@param citation CitationData
+---@return CitationData
+function CiteProc:_normalize_citation_input(citation)
citation = util.deep_copy(citation)
if not citation.citationID then
@@ -385,7 +522,7 @@ function CiteProc:normalize_citation_input(citation)
citation.citationItems = {}
end
for i, cite_item in ipairs(citation.citationItems) do
- citation.citationItems[i] = self:normalize_cite_item(cite_item)
+ citation.citationItems[i] = self:_normalize_cite_item(cite_item)
end
-- Fix missing noteIndex: sort_CitationNumberPrimaryAscendingViaMacroCitation.txt
@@ -395,13 +532,18 @@ function CiteProc:normalize_citation_input(citation)
if not citation.properties.noteIndex then
citation.properties.noteIndex = 0
end
+ if not citation.properties.chapterIndex then
+ citation.properties.chapterIndex = 0
+ end
+
+ citation.sorted_items = util.clone(citation.citationItems)
return citation
end
---@param cite_item CitationItem
---@return CitationItem
-function CiteProc:normalize_cite_item(cite_item)
+function CiteProc:_normalize_cite_item(cite_item)
-- Shallow copy
cite_item = util.clone(cite_item)
cite_item.id = tostring(cite_item.id)
@@ -412,139 +554,262 @@ function CiteProc:normalize_cite_item(cite_item)
cite_item.label = "page"
end
+ local the_context = Context:new()
+ the_context.engine = self
+ the_context.style = self.style
+ the_context.area = self
+ the_context.in_bibliography = false
+ the_context.lang = self.lang
+ the_context.locale = self:get_locale(self.lang)
+ the_context.format = self.output_format
+
if cite_item.prefix then
-- Assert CSL rich-text or HTML-like tagged string
if cite_item.prefix == "" then
cite_item.prefix = nil
- else
- cite_item.prefix_inlines = InlineElement:parse(cite_item.prefix, nil, true)
end
end
if cite_item.suffix then
if cite_item.suffix == "" then
cite_item.suffix = nil
- else
- cite_item.suffix_inlines = InlineElement:parse(cite_item.suffix, nil, true)
end
end
return cite_item
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
+---@param citation CitationData
+---@param citations_pre PreCitation[]
+---@param citations_post PostCitation[]
+function CiteProc:_check_input(citation, citations_pre, citations_post)
+ local citation_info_list = {}
+ do
+ for i, pre_citation in ipairs(citations_pre) do
+ local citation_id = pre_citation[1]
+ local note_index = pre_citation[2]
+ local chapter_number = pre_citation[3] or self.registry.citations_by_id[citation_id].properties.chapterIndex or 0
+ local name = string.format("citationsPre[%d]", i)
+ table.insert(citation_info_list, {citation_id, note_index, chapter_number, name})
+ end
+ table.insert(citation_info_list, {citation.citationID, citation.properties.noteIndex, citation.properties.chapterIndex or 0, "citation"})
+ for i, post_citation in ipairs(citations_post) do
+ local citation_id = post_citation[1]
+ local note_index = post_citation[2]
+ local chapter_number = post_citation[3] or self.registry.citations_by_id[citation_id].properties.chapterIndex or 0
+ local name = string.format("citationsPost[%d]", i)
+ table.insert(citation_info_list, {citation_id, note_index, chapter_number, name})
+ end
+ end
- citation = self:normalize_citation_input(citation)
+ ---@type table<CitationId, boolean>
+ local citation_dict = {}
+ local last_note_number = 0
+ local last_chapter_number = 0
- -- Registor citation
- self.registry.citations_by_id[citation.citationID] = citation
+ for _, citation_info in ipairs(citation_info_list) do
+ local citation_id, note_index, chapter_number, name = table.unpack(citation_info)
+ if citation_dict[citation_id] then
+ error(string.format("Previously referenced citationID '%s' encountered at %s", name))
+ end
+ citation_dict[citation_id] = true
+ if chapter_number and chapter_number > 0 then
+ if chapter_number < last_chapter_number then
+ util.warning(string.format("Chapter index sequence is not sane at %s", name))
+ end
+ if chapter_number ~= last_chapter_number then
+ last_note_number = 0
+ end
+ last_chapter_number = chapter_number
+ end
+ if note_index > 0 then
+ if note_index < last_note_number then
+ util.warning(string.format("Note index sequence is not sane at %s", name))
+ end
+ last_note_number = note_index
+ end
+ end
+
+end
- table.insert(self.registry.citation_list, citation)
+---@param citation CitationData
+---@param citations_pre PreCitation[]
+---@param citations_post PostCitation[]
+---@return CitationData[]
+---@return CiteId[]
+function CiteProc:_build_reconstituted_citation_list(citation, citations_pre, citations_post)
+ self.registry.citations_by_id[citation.citationID] = citation
+ ---@type [CitationId, NoteIndex][]
local citation_note_pairs = {}
- for _, citation_ in ipairs(self.registry.citation_list) do
- table.insert(citation_note_pairs, {citation_.citationID, citation_.properties.noteIndex})
- end
+ util.extend(citation_note_pairs, citations_pre)
+ table.insert(citation_note_pairs, {citation.citationID, citation.properties.noteIndex})
+ util.extend(citation_note_pairs, citations_post)
- -- 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] = {}
+ ---@type CiteId[]
+ local item_ids = {}
+ ---@type table<ItemId, boolean>
+ local item_id_dict = {}
+ ---@type CitationData[]
+ local citation_list = {}
+ ---@type table<CitationId, CitationData>
+ local citations_by_id = {}
+ -- TODO: Remove citations_by_item_id
+ ---@type table<ItemId, CitationData[]>
+ local citations_by_item_id = {}
+
+ for citation_index, pair in ipairs(citation_note_pairs) do
+ local citation_id, note_index = table.unpack(pair)
+ local citation_ = self.registry.citations_by_id[citation_id]
+ if not citation_ then
+ util.error("Citation not in registry.")
end
- table.insert(self.registry.citations_by_item_id[cite_item.id], citation)
- end
+ citation_.citation_index = citation_index
+ citation_.properties.noteIndex = note_index
- -- self:updateItems(item_ids)
- for i, cite_item in ipairs(citation.citationItems) do
- self:get_item(cite_item.id)
+ table.insert(citation_list, citation_)
+ citations_by_id[citation_.citationID] = citation_
+ for _, cite_item in ipairs(citation_.citationItems) do
+ if not item_id_dict[cite_item.id] then
+ item_id_dict[cite_item.id] = true
+ table.insert(item_ids, cite_item.id)
+ citations_by_item_id[cite_item.id] = {}
+ end
+ table.insert(citations_by_item_id[cite_item.id], citation_)
+ end
end
+ self.registry.citation_list = citation_list
+ self.registry.citations_by_id = citations_by_id
+ self.registry.citations_by_item_id = citations_by_item_id
+ return citation_list, item_ids
+end
- local tainted_citation_ids = self:get_tainted_citation_ids(citation_note_pairs)
+---@param citation_list CitationData[]
+---@return table<CitationId, boolean>
+function CiteProc:_set_positions(citation_list)
+ ---@type table<CitationId, boolean>
+ local tainted_citation_ids = {}
- local mode = citation.properties.mode
- if mode == "suppress-author" and self.style.class == "note" then
- mode = nil
+ ---@type {[integer]: CitationData[]}
+ local chapter_citations = {}
+ for _, citation in ipairs(citation_list) do
+ local chapter_number = citation.properties.chapterIndex
+ if not chapter_citations[chapter_number] then
+ chapter_citations[chapter_number] = {}
+ end
+ table.insert(chapter_citations[chapter_number], citation)
end
- local citation_elemement = self.style.citation
- if mode == "author-only" and self.style.intext then
- citation_elemement = self.style.intext
+
+ for _, citations in pairs(chapter_citations) do
+ self:_update_chapter_positions(citations, tainted_citation_ids)
end
- local citation_str = citation_elemement:build_citation_str(citation, self)
+ -- 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 in ipairs(self.registry.citations_by_item_id[item_id]) do
+ tainted_citation_ids[citation.citationID] = true
+ end
+ end
+ end
- return citation_str
+ return tainted_citation_ids
end
-
-function CiteProc:get_tainted_citation_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"},
- -- }
-
- -- Citations with noteIndex == 0 are in-text citations and they may also
- -- have position properties.
+---@param citation_list CitationData[]
+---@param tainted_citation_ids table<CitationId, boolean>
+---@return table<string, boolean>
+function CiteProc:_update_chapter_positions(citation_list, tainted_citation_ids)
+ ---@type CitationData[]
local in_text_citations = {}
+ ---@type CitationData[]
+ local note_citations = {}
+ for _, citation in ipairs(citation_list) do
+ if citation.properties.noteIndex == 0 then
+ table.insert(in_text_citations, citation)
+ else
+ table.insert(note_citations, citation)
+ end
+ end
- 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
+ for _, citations in ipairs({in_text_citations, note_citations}) do
+ ---@type table<CiteId, NoteIndex>
+ local first_ref = {}
+ ---@type table<CiteId, NoteIndex>
+ local last_ref = {}
+ ---@type table<NoteIndex, CitationId[]>
+ local num_citations_in_note = {}
- local prev_citation = previous_citation
- if note_number == 0 then
- -- Find the previous in-text citation.
- prev_citation = in_text_citations[#in_text_citations]
- end
- local previous_cite
- for _, cite_item in ipairs(citation.citationItems) do
- tainted = self:set_cite_item_position(cite_item, note_number, previous_cite, prev_citation, citation)
-
- -- https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html#citations
- -- Citations within the main text of the document have a noteIndex of zero.
- if (self.style.class == "note" and note_number > 0) or citation.properties.mode ~= "author-only" then
- self.cite_last_note_numbers[cite_item.id] = note_number
- previous_cite = cite_item
+ for _, citation in ipairs(citations) do
+ local note_index = citation.properties.noteIndex
+ if not num_citations_in_note[note_index] then
+ num_citations_in_note[note_index] = {}
end
+ table.insert(num_citations_in_note[note_index], citation.citationID)
end
- if tainted then
- tainted_citation_ids[citation.citationID] = true
- end
+ local previous_citation
+ for _, citation in ipairs(citations) do
+ local mode = citation.properties.mode
+ local note_index = citation.properties.noteIndex
+ local previous_cite
+ for _, cite_item in ipairs(citation.sorted_items) do
+ local position_properties = {
+ position_level = cite_item.position_level,
+ ["first-reference-note-number"] = cite_item["first-reference-note-number"],
+ near_note = cite_item.near_note,
+ }
+
+ self:_set_cite_item_position(cite_item, note_index, previous_cite, previous_citation, citation, first_ref, last_ref, num_citations_in_note)
+
+ if self:_check_tainted_position_change(cite_item, position_properties) 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)
- if citation.properties.mode ~= "author-only" then
- if note_number == 0 then
- table.insert(in_text_citations, citation)
- else
+ -- https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html#citations
+ -- Citations within the main text of the document have a noteIndex of zero.
+ if mode ~= "author-only" and mode ~= "full-cite" then
+ if not first_ref[cite_item.id] and note_index > 0 then
+ -- note_index == 0 implied an in-text citation
+ first_ref[cite_item.id] = note_index
+ end
+ last_ref[cite_item.id] = note_index
+ previous_cite = cite_item
+ end
+ end
+
+ if mode ~= "author-only" and mode ~= "full-cite" then
previous_citation = citation
end
end
- 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 in ipairs(self.registry.citations_by_item_id[item_id]) do
- tainted_citation_ids[citation.citationID] = true
+ if self.style.class == "note" and self.style.has_disambiguate then
+ ---@type table<CiteId, CitationData[]>
+ local citations_by_item_id = {}
+ for _, citation in ipairs(citations) do
+ if citation.properties.mode ~= "author-only" and citation.properties.mode ~= "full-cite" then
+ for _, cite_item in ipairs(citation.sorted_items) do
+ if not citations_by_item_id[cite_item.id] then
+ citations_by_item_id[cite_item.id] = {}
+ end
+ table.insert(citations_by_item_id[cite_item.id], citation)
+ end
+ end
+ end
+ for _, citation in ipairs(citations) do
+ if citation.properties.mode ~= "author-only" and citation.properties.mode ~= "full-cite" then
+ for _, cite_item in ipairs(citation.sorted_items) do
+ assert(citations_by_item_id[cite_item.id])
+ local num_citations = #citations_by_item_id[cite_item.id]
+ if not cite_item.num_citations or (num_citations < 2) ~= (cite_item.num_citations < 2) then
+ -- self.tainted_item_ids[cite_item.id] = true
+ for _, citation_ in ipairs(citations_by_item_id[cite_item.id]) do
+ tainted_citation_ids[citation_.citationID] = true
+ end
+ end
+ cite_item.num_citations = num_citations
+ end
+ end
end
end
end
@@ -552,58 +817,41 @@ function CiteProc:get_tainted_citation_ids(citation_note_pairs)
return tainted_citation_ids
end
-function CiteProc:set_cite_item_position(cite_item, note_number, previous_cite, previous_citation, citation)
- local position = Position.First
-
+function CiteProc:_set_cite_item_position(cite_item, note_index, previous_cite, previous_citation, citation, first_ref, last_ref, num_citations_in_note)
-- https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html#citations
-- Citations within the main text of the document have a noteIndex of zero.
- if citation.properties.mode == "author-only" then
+ if citation.properties.mode == "author-only" or citation.properties.mode == "full-cite" then
-- discretionary_IbidInAuthorDateStyleWithoutIntext.txt
- cite_item.position_level = position
- return false
+ cite_item.position_level = Position.First
+ cite_item.near_note = false
+ return
end
- local first_reference_note_number = self.cite_first_note_numbers[cite_item.id]
+ local first_reference_note_number = first_ref[cite_item.id]
if first_reference_note_number then
- position = Position.Subsequent
- elseif note_number > 0 then
- -- note_number == 0 implied an in-text citation
- self.cite_first_note_numbers[cite_item.id] = note_number
+ cite_item.position_level = Position.Subsequent
+ cite_item["first-reference-note-number"] = first_reference_note_number
+ else
+ cite_item.position_level = Position.First
end
- local preceding_cite_item = self:get_preceding_cite_item(cite_item, previous_cite, previous_citation, note_number)
+ local preceding_cite_item = self:_find_preceding_ibid_item(cite_item, previous_cite, previous_citation, note_index, num_citations_in_note)
if preceding_cite_item then
- position = self:_get_cite_position(cite_item, preceding_cite_item)
+ cite_item.position_level = self:_get_ibid_position(cite_item, preceding_cite_item)
end
- local near_note = false
- local last_note_number = self.cite_last_note_numbers[cite_item.id]
+ cite_item.near_note = false
+ local last_note_number = last_ref[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
+ local note_distance = note_index - last_note_number
+ cite_item.near_note = (note_distance <= self.style.citation.near_note_distance)
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)
+function CiteProc:_find_preceding_ibid_item(cite_item, previous_cite, previous_citation, note_index, num_citations_in_note)
if previous_cite then
-- a. the current cite immediately follows on another cite, within the same
-- citation, that references the same item
@@ -618,11 +866,11 @@ function CiteProc:get_preceding_cite_item(cite_item, previous_cite, previous_cit
-- 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]
+ local num_previous_note_citations = #num_citations_in_note[previous_note_number]
+ if (previous_note_number == note_index - 1 and num_previous_note_citations == 1)
+ or previous_note_number == note_index then
+ if #previous_citation.sorted_items == 1 then
+ previous_cite = previous_citation.sorted_items[1]
if previous_cite.id == cite_item.id then
return previous_cite
end
@@ -632,7 +880,7 @@ function CiteProc:get_preceding_cite_item(cite_item, previous_cite, previous_cit
return nil
end
-function CiteProc:_get_cite_position(item, preceding_cite)
+function CiteProc:_get_ibid_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
@@ -652,140 +900,51 @@ function CiteProc:_get_cite_position(item, preceding_cite)
end
end
-function CiteProc:makeCitationCluster(citation_items)
- local special_form = nil
- local items = {}
-
- for i, cite_item in ipairs(citation_items) do
- cite_item = self:normalize_cite_item(cite_item)
- 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 cite_item = setmetatable(cite_item, {__index = item_data})
-
- if not special_form then
- for _, form in ipairs({"author-only", "suppress-author", "coposite"}) do
- if cite_item[form] then
- special_form = form
- end
- end
- end
-
- -- Set "first-reference-note-number" variable when called from
- -- processCitationCluster() > updateItems()
- local citations = self.registry.citations_by_item_id[cite_item.id]
- if citations and #citations > 0 then
- item_data["first-reference-note-number"] = citations[1].properties.noteIndex
+function CiteProc:_check_tainted_position_change(cite_item, position_properties)
+ for key, value in pairs(position_properties) do
+ if cite_item[key] ~= value then
+ return true
end
+ end
+ return false
+end
- cite_item.position_level = Position.First
- if self.cite_first_note_numbers[cite_item.id] then
- cite_item.position_level = Position.Subsequent
- else
- self.cite_first_note_numbers[cite_item.id] = 0
+---@param tainted_citation_ids table<CitationId, boolean>
+---@return [integer, string, CitationId][]
+function CiteProc:_rerun_changed_cites(tainted_citation_ids)
+ local result = {}
+ 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 mode = citation.properties.mode
+ if mode == "suppress-author" and self.style.class == "note" then
+ mode = nil
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 == cite_item.id then
- preceding_cite = previous_citation.citationItems[1]
- end
+ local citation_element = self.style.citation
+ if mode == "author-only" and self.style.intext then
+ citation_element = self.style.intext
+ elseif mode == "full-cite" then
+ if self.style.class == "note" then
+ citation_element = self.style.citation
+ else
+ citation_element = self.style.full_citation
end
- elseif citation_items[i - 1].id == cite_item.id then
- preceding_cite = citation_items[i - 1]
- end
-
- if preceding_cite then
- cite_item.position_level = self:_get_cite_position(cite_item, preceding_cite)
end
- table.insert(items, cite_item)
+ local citation_str = citation_element:build_citation_str(citation, self)
+ table.insert(result, {citation_index, citation_str, citation_id})
end
-
- if self.registry.requires_sorting then
- self:sort_bibliography()
- end
-
- self:check_valid_citation_element()
- local citation_element = self.style.citation
- if special_form == "author-only" and self.style.intext then
- citation_element = self.style.intext
- end
-
- local res = citation_element:build_cluster(items, self)
-
- -- local context = {
- -- build = {},
- -- engine=self,
- -- }
- -- local res = self.style:render_citation(items, context)
-
- self.registry.previous_citation = {
- citationID = "pseudo-citation",
- citationItems = items,
- properties = {
- noteIndex = 0,
- }
- }
- return res
+ return result
end
-function CiteProc:makeBibliography(bibsection)
- -- The bibsection works as a filter described in
- -- <https://citeproc-js.readthedocs.io/en/latest/running.html#selective-output-with-makebibliography>.
- if not self.style.bibliography then
- return {{}, {}}
- end
-
- local res = {}
-
- self.registry.widest_label = ""
- self.registry.maxoffset = 0
-
- local ids = self:get_sorted_refs()
- if bibsection then
- ids = self:filter_with_bibsection(ids, bibsection)
- end
- for _, id in ipairs(ids) do
- local str = self.style.bibliography:build_bibliography_str(id, self)
- table.insert(res, str)
- 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 or false,
- linespacing = self.style.bibliography.line_spacing,
- entryspacing = self.style.bibliography.entry_spacing,
- maxoffset = self.registry.maxoffset,
- widest_label = self.registry.widest_label,
- bibstart = bib_start,
- bibend = bib_end,
- entry_ids = util.clone(self.registry.reflist),
- }
-
- return {params, res}
-end
-
-function CiteProc:get_sorted_refs()
+function CiteProc:_get_sorted_refs()
if self.registry.requires_sorting then
self:sort_bibliography()
end
return self.registry.reflist
end
-function CiteProc:filter_with_bibsection(ids, bibsection)
+function CiteProc:_filter_with_bibsection(ids, bibsection)
if bibsection.quash then
return self:filter_quash(ids, bibsection)
elseif bibsection.select then
@@ -977,7 +1136,6 @@ function CiteProc:_retrieve_item(id)
local res = {}
local item = self.sys.retrieveItem(id)
if not item then
- util.warning(string.format("Didn't find a database entry for '%s'", id))
return nil
end
@@ -1001,14 +1159,11 @@ end
function CiteProc:process_extra_note(item)
if item.note then
local note_fields = {}
+ local note_lines = {}
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 field, value = string.match(line, "^([%w-_ ]+):%s*(.*)$")
+ if field then
local variable_type = util.variable_types[field]
if not item[field] or field == "type" or variable_type == "date" then
if variable_type == "number" then
@@ -1024,11 +1179,14 @@ function CiteProc:process_extra_note(item)
item[field] = value
end
end
+ else
+ table.insert(note_lines, line)
end
end
for field, value in pairs(note_fields) do
item[field] = value
end
+ item.note = table.concat(note_lines, '\n')
end
return item
end
@@ -1054,6 +1212,7 @@ function CiteProc:sort_bibliography()
context.style = self.style
context.area = self.style.bibliography
context.in_bibliography = true
+ context.lang = self.lang
context.locale = self:get_locale(self.lang)
context.name_inheritance = self.style.bibliography.name_inheritance
context.format = SortStringFormat:new()
@@ -1135,7 +1294,7 @@ function CiteProc:get_system_locale(lang)
local locale_str = self.sys.retrieveLocale(lang)
if not locale_str then
- util.warning(string.format("Failed to retrieve locale \"%s\"", lang))
+ util.warning(string.format("Failed to retrieve locale '%s'", lang))
return nil
end
local locale_xml = dom.parse(locale_str)
@@ -1166,6 +1325,10 @@ function Macro:from_node(node)
return o
end
+---@param engine CiteProc
+---@param state IrState
+---@param context Context
+---@return IrNode?
function Macro:build_ir(engine, state, context)
local ir = self:build_group_ir(engine, state, context)
return ir
diff --git a/biblio/citation-style-language/citeproc-ir-node.lua b/biblio/citation-style-language/citeproc-ir-node.lua
index 0aae5e9aee..16eacbd13e 100644
--- a/biblio/citation-style-language/citeproc-ir-node.lua
+++ b/biblio/citation-style-language/citeproc-ir-node.lua
@@ -32,6 +32,8 @@ local GroupVar = {
---@field text string?
---@field formatting any
---@field affixes any
+---@field display any
+---@field quotes LocalizedQuotes
---@field inlines InlineElement[]?
---@field children IrNode[]?
---@field delimiter string?
diff --git a/biblio/citation-style-language/citeproc-journal-data.lua b/biblio/citation-style-language/citeproc-journal-data.lua
index 8eb7720a97..76a30a1344 100644
--- a/biblio/citation-style-language/citeproc-journal-data.lua
+++ b/biblio/citation-style-language/citeproc-journal-data.lua
@@ -7970,6 +7970,7 @@ abbrevs = {
["AMERICAN JOURNAL OF ELECTRONEURODIAGNOSTIC TECHNOLOGY"] = "Am J Electroneurodiagnostic Technol",
["AMERICAN JOURNAL OF EMERGENCY MEDICINE"] = "Am. J. Emerg. Med.",
["AMERICAN JOURNAL OF ENGINEERING EDUCATION"] = "Am J Eng Educ",
+ ["AMERICAN JOURNAL OF ENGINEERING RESEARCH"] = "Am. J. Eng. Res.",
["AMERICAN JOURNAL OF ENOLOGY AND VITICULTURE"] = "Am J Enol Vitic",
["AMERICAN JOURNAL OF ENTREPRENEURSHIP"] = "Am J Entrep",
["AMERICAN JOURNAL OF ENVIRONMENTAL ENGINEERING"] = "Am J Environ Engineer",
@@ -8699,6 +8700,7 @@ abbrevs = {
["ANALOG CIRCUITS AND SIGNAL PROCESSING"] = "Analog Circuits Signal Process.",
["ANALOG CIRCUITS AND SYSTEMS FOR VOLTAGE-MODE AND CURRENT-MODE SENSOR INTERFACING APPLICATIONS"] = "Analog Circ. Sig. Proc.",
["ANALOG CIRCUITS AND SYSTEMS OPTIMIZATION BASED ON EVOLUTIONARY COMPUTATION TECHNIQUES"] = "Stud. Comput. Intell.",
+ ["ANALOG DIALOGUE"] = "Analog Dialogue",
["ANALOG INTEGRATED CIRCUITS AND SIGNAL PROCESSING"] = "Analog Integr Circuits Signal Process",
["ANALOG PHOTONICS"] = "P. Soc. Photo-opt. Ins.",
["ANALOG SCIENCE FICTION/SCIENCE FACT"] = "Analog Sci Fict Sci Fact",
@@ -11946,6 +11948,7 @@ abbrevs = {
["ARCHIVES OF DISEASE IN CHILDHOOD. FETAL AND NEONATAL EDITION"] = "Arch Dis Child Fetal Neonatal Ed",
["ARCHIVES OF DRUG INFORMATION"] = "Arch Drug Inf",
["ARCHIVES OF ECONOMIC HISTORY"] = "Archives Econ. Hist.",
+ ["ARCHIVES OF ELECTRICAL ENGINEERING"] = "Arch. Electr. Eng.",
["ARCHIVES OF EMERGENCY MEDICINE"] = "Arch Emerg Med",
["ARCHIVES OF EMERGENCY MEDICINE AND CRITICAL CARE"] = "Arch Emerg Med Crit Care",
["ARCHIVES OF ENDOCRINOLOGY AND METABOLISM"] = "Arch Endocrinol Metab",
@@ -14409,6 +14412,7 @@ abbrevs = {
["AUTOMATION IN MINING, MINERAL AND METAL PROCESSING 1992"] = "Ifac. Symp. Series.",
["AUTOMATION OF MECHANICAL TESTING"] = "Am. Soc. Test. Mater.",
["AUTOMATION-CONTROL AND INDUSTRIAL ENGINEERING SERIES"] = "Autom.-Control Ind. Eng. Ser.",
+ ["AUTOMATISIERUNGSTECHNIK"] = "Automatisierungstechnik",
["AUTOMATISME"] = "Automatisme",
["AUTOMEDICA"] = "Automedica",
["AUTOMOBILE INSURANCE: ROAD SAFETY, NEW DRIVERS, RISKS, INSURANCE FRAUD AND REGULATION"] = "Ctr. Res. Transp. 25th.",
@@ -22060,6 +22064,7 @@ abbrevs = {
["CES ODONTOLOGIA"] = "CES Odontol.",
["CES ODONTOLOGIA / INSTITUTO DE CIENCIAS DE LA SALUD"] = "CES Odontol",
["CES ODONTOLOGÍA"] = "CES Odontol",
+ ["CES TRANSACTIONS ON ELECTRICAL MACHINES AND SYSTEMS"] = "CES Trans. Electr. Mach. Syst.",
["CES4HEALTH.INFO"] = "CES4healthinfo",
["CESIFO BOOK SERIES"] = "Cesifo Book Ser.",
["CESIFO ECONOMIC STUDIES"] = "CESifo Econ Stud",
@@ -31352,6 +31357,7 @@ abbrevs = {
["DER RADIOLOGE"] = "Radiologe",
["DER SCHWEIZER OPTIKER. L'OPTICIEN SUISSE"] = "Schweiz Opt Opt Suisse",
["DER SPORTARZT VEREINIGT MIT SPORTMEDIZIN"] = "Sportarzt Ver Sportmed",
+ ["DER STAHLBAU"] = "Stahlbau",
["DER TUBERKULOSEARZT"] = "Tuberkulosearzt",
["DER UNFALLCHIRURG"] = "Unfallchirurg",
["DER UROLOGE"] = "Urologe",
@@ -35674,6 +35680,7 @@ abbrevs = {
["ELEKTROMEDIZIN, BIOMEDIZIN UND TECHNIK"] = "Elektromed. Biomed. Tech.",
["ELEKTRONIKA IR ELEKTROTECHNIKA"] = "Elektron. Elektrotech.",
["ELEKTRONISCHE INFORMATIONSRESSOURCEN FUR GERMANISTEN"] = "Bibliothekspraxis.",
+ ["ELEKTROTECHNIK UND INFORMATIONSTECHNIK"] = "Elektrotech. Inf.",
["ELEKTROTECHNIK UND MASCHINENBAU"] = "Elektrotech. Maschinenbau",
["ELEKTROTECHNISCHE ZEITSCHRIFT"] = "Elektrotech. Z.",
["ELEKTROTECHNISCHE ZEITSCHRIFT B-AUSGABE"] = "Elektrotech. Z. Ausg. B.",
@@ -37257,7 +37264,7 @@ abbrevs = {
["EPDIC 3, PTS 1 AND 2"] = "Mater. Sci. Forum.",
["EPDIC 5, PTS 1 AND 2"] = "Mater. Sci. Forum.",
["EPDIC 7: EUROPEAN POWDER DIFFRACTION, PTS 1 AND 2"] = "Mater. Sci. Forum.",
- ["EPE JOURNAL"] = "Epe J.",
+ ["EPE JOURNAL"] = "EPE J.",
["EPEIROTIKE HESTIA"] = "Epeirotike Hestia",
["EPETERIS HETAIREIAS STEREOELLADIKON MELETON"] = "Epet Etaireias Stereoelladikon Meleton",
["EPETERIS TES HETAIREIAS ELEIAKON MELETON"] = "EHEM",
@@ -41949,6 +41956,7 @@ abbrevs = {
["FOUNDATIONS AND FUTURES OF EDUCATION"] = "Found. Futures Educ.",
["FOUNDATIONS AND NOVEL APPROACHES IN DATA MINING"] = "Stud. Comp. Intell.",
["FOUNDATIONS AND TOOLS FOR NEURAL MODELING, PROCEEDINGS"] = "Lect. Notes. Comput. Sc.",
+ ["FOUNDATIONS AND TRENDS IN SYSTEMS AND CONTROL"] = "Found. Trends Syst. Control",
["FOUNDATIONS AND TRENDS${}^CIRCLEDR$ IN SIGNAL PROCESSING"] = "Found. Trends Signal Process.",
["FOUNDATIONS AND TRENDS${}^CIRCLEDR$ IN THEORETICAL COMPUTER SCIENCE"] = "Found. Trends Theor. Comput. Sci.",
["FOUNDATIONS AND TRENDS${}^\\\\CIRCLEDR$ IN SIGNAL PROCESSING"] = "Found. Trends Signal Process.",
@@ -50346,6 +50354,7 @@ abbrevs = {
["IEE PROCEEDINGS-VISION IMAGE AND SIGNAL PROCESSING"] = "Iee P-vis. Image Sign.",
["IEE PROCEEDINGS. NANOBIOTECHNOLOGY"] = "IEE Proc Nanobiotechnol",
["IEE PROCEEDINGS. SYSTEMS BIOLOGY"] = "IEE Proc Syst Biol",
+ ["IEE PROCEEDINGS: ELECTRIC POWER APPLICATIONS"] = "IEE Proc.: Electr. Power Appl.",
["IEE PROCEEDINGS: OPTOLECTRONICS"] = "IEE Proc.: Optoelectron.",
["IEE PROCEEDINGS: SCIENCE, MEASUREMENT & TECHNOLOGY"] = "IEE Proc.: Sci. Meas. Technol.",
["IEE REVIEW"] = "Iee Review",
@@ -50694,6 +50703,8 @@ abbrevs = {
["IEEE NUCLEAR SCIENCE SYMPOSIUM CONFERENCE RECORD. NUCLEAR SCIENCE SYMPOSIUM"] = "IEEE Nucl Sci Symp Conf Rec (1997)",
["IEEE OES AUTONOMOUS UNDERWATER VEHICLES"] = "IEEE Auto. Under. Veh.",
["IEEE OPEN JOURNAL OF ENGINEERING IN MEDICINE AND BIOLOGY"] = "IEEE Open J Eng Med Biol",
+ ["IEEE OPEN JOURNAL OF INDUSTRY APPLICATIONS"] = "IEEE Open J. Ind. Appl.",
+ ["IEEE OPEN JOURNAL OF THE INDUSTRIAL ELECTRONICS SOCIETY"] = "IEEE Open J. Ind. Electron. Soc.",
["IEEE PACIFIC RIM CONFERENCE ON COMMUNICATIONS, COMPUTERS AND SIGNAL PROCESSING"] = "IEEE Pacif.",
["IEEE PACIFIC RIM CONFERENCE ON COMMUNICATIONS, COMPUTERS AND SIGNAL PROCESSING : CONFERENCE PROCEEDINGS"] = "IEEE Pacif.",
["IEEE PACIFIC RIM CONFERENCE ON COMMUNICATIONS, COMPUTERS AND SIGNAL PROCESSING : PROCEEDINGS"] = "IEEE Pacif.",
@@ -51077,6 +51088,7 @@ abbrevs = {
["IEEE/RSJ 2010 INTERNATIONAL CONFERENCE ON INTELLIGENT ROBOTS AND SYSTEMS (IROS 2010)"] = "IEEE. Int. C. Int. Robot.",
["IEEE/SICE/RSJ INTERNATIONAL CONFERENCE ON MULTISENSOR FUSION AND INTEGRATION FOR INTELLIGENT SYSTEMS. IEEE/SICE/RSJ INTERNATIONAL CONFERENCE ON MULTISENSOR FUSION AND INTEGRATION FOR INTELLIGENT SYSTEMS"] = "IEEE SICE RSJ Int Conf Multisens Fusion Integr Intell Syst",
["IEEE/TMS JOURNAL OF ELECTRONIC MATERIALS"] = "IEEE/TMS J. Electron. Mater.",
+ ["IEEJ JOURNAL OF INDUSTRY APPLICATIONS"] = "IEEJ J. Ind. Appl.",
["IEEJ TRANSACTIONS ON ELECTRICAL AND ELECTRONIC ENGINEERING"] = "Ieej T. Electr. Electr.",
["IEEJ TRANSACTIONS ON SENSORS AND MICROMACHINES"] = "IEEJ Trans. Sens. Micromachines",
["IEEM: 2008 INTERNATIONAL CONFERENCE ON INDUSTRIAL ENGINEERING AND ENGINEERING MANAGEMENT"] = "In. C. Ind. Eng. Eng. Man.",
@@ -51117,7 +51129,7 @@ abbrevs = {
["IET NETWORKS"] = "IET Networks",
["IET OPTOELECTRONICS"] = "IET Optoelectron",
["IET POWER AND ENERGY SERIES"] = "IET Power Energy Ser.",
- ["IET POWER ELECTRONICS"] = "Iet Power Electron.",
+ ["IET POWER ELECTRONICS"] = "IET Power Electron.",
["IET POWER ENGINEER"] = "IET Power Eng.",
["IET PROCEEDINGS: SCIENCE, MEASUREMENT & TECHNOLOGY"] = "IET Proc.: Sci. Meas. Technol.",
["IET RADAR SONAR AND NAVIGATION"] = "Iet Radar Sonar Nav.",
@@ -51136,8 +51148,10 @@ abbrevs = {
["IFA CONGRESS SEMINAR SERIES"] = "Ifa Congr. S.",
["IFAC JOURNAL OF SYSTEMS AND CONTROL"] = "IFAC J. Syst. Control",
["IFAC PROCEEDINGS SERIES"] = "Ifac P. Ser.",
+ ["IFAC PROCEEDINGS VOLUMES"] = "IFAC Proc. Vol.",
["IFAC SYMPOSIA SERIES"] = "IFAC Sympos. Ser.",
["IFAC WORKSHOP SERIES"] = "IFAC Workshop Ser.",
+ ["IFAC-PAPERSONLINE"] = "IFAC-Pap.",
["IFAE 2005: 17TH ITALIAN MEETING ON HIGH ENERGY PHYSICS"] = "Aip. Conf. Proc.",
["IFDC SPECIAL PUBLICATION"] = "Ifdc Sp. Pub.",
["IFIP ADVANCES IN INFORMATION AND COMMUNICATION TECHNOLOGY"] = "IFIP Adv Inf Commun Technol",
@@ -55370,6 +55384,7 @@ abbrevs = {
["INTERNATIONAL JOURNAL OF CULTURE AND MENTAL HEALTH"] = "Int J Cult Ment Health",
["INTERNATIONAL JOURNAL OF CURRENT ADVANCED RESEARCH"] = "Int J Curr Adv Res",
["INTERNATIONAL JOURNAL OF CURRENT CHEMISTRY"] = "Int J Curr Chem",
+ ["INTERNATIONAL JOURNAL OF CURRENT ENGINEERING AND SCIENTIFIC RESEARCH"] = "Int. J. Curr. Eng. Sci. Res.",
["INTERNATIONAL JOURNAL OF CURRENT MICROBIOLOGY AND APPLIED SCIENCES"] = "Int J Curr Microbiol Appl Sci",
["INTERNATIONAL JOURNAL OF CURRENT MULTIDISCIPLINARY STUDIES"] = "Int J Curr Multidiscip Stud",
["INTERNATIONAL JOURNAL OF CURRENT PHARMACEUTICAL RESEARCH"] = "Int J Curr Pharm Res",
@@ -56736,6 +56751,7 @@ abbrevs = {
["INTERNATIONAL REQUIREMENTS ENGINEERING CONFERENCE PROCEEDINGS"] = "Int. Requir. Eng. Conf.",
["INTERNATIONAL RESCUER"] = "Int Rescuer",
["INTERNATIONAL RESEARCH IN THE BUSINESS DISCIPLINES"] = "Int. Res. Bus. Discipl.",
+ ["INTERNATIONAL RESEARCH JOURNAL OF ENGINEERING AND TECHNOLOGY"] = "Int. Res. J. Eng. Technol.",
["INTERNATIONAL RESEARCH JOURNAL OF ENVIRONMENTAL SCIENCES"] = "Int Res J Environ Sci",
["INTERNATIONAL RESEARCH JOURNAL OF NATURAL AND APPLIED SCIENCES"] = "Int Res J Nat Appl Sci",
["INTERNATIONAL RESEARCH JOURNAL OF PURE AND APPLIED CHEMISTRY"] = "Int Res J Pure Appl Chem",
@@ -56763,6 +56779,7 @@ abbrevs = {
["INTERNATIONAL REVIEW OF EDUCATION"] = "Int. Rev. Educ.",
["INTERNATIONAL REVIEW OF EDUCATION. INTERNATIONALE ZEITSCHRIFT FUR ERZIEHUNGSWISSENSCHAFT. REVUE INTERNATIONALE DE PEDAGOGIE"] = "Int Rev Educ",
["INTERNATIONAL REVIEW OF EDUCATION. INTERNATIONALE ZEITSCHRIFT FÜR ERZIEHUNGSWISSENSCHAFT. REVUE INTERNATIONALE DE PÉDAGOGIE"] = "Int Rev Educ",
+ ["INTERNATIONAL REVIEW OF ELECTRICAL ENGINEERING"] = "Int. Rev. Electr. Eng.",
["INTERNATIONAL REVIEW OF ELECTRICAL ENGINEERING-IREE"] = "Int. Rev. Electr. Eng-i.",
["INTERNATIONAL REVIEW OF EXPERIMENTAL PATHOLOGY"] = "Int Rev Exp Pathol",
["INTERNATIONAL REVIEW OF EXPERIMENTAL PATHOLOGY, VOL 36: NEW IN VIVO AND IN VITRO IMAGING TECHNIQUES"] = "Int. Rev. Exp. Pathol.",
@@ -62827,6 +62844,7 @@ abbrevs = {
["JOURNAL OF LOSS PREVENTION IN THE PROCESS INDUSTRIES"] = "J Loss Prev Process Ind",
["JOURNAL OF LOW FREQUENCY NOISE & VIBRATION"] = "J. Low Freq. Noise Vib.",
["JOURNAL OF LOW FREQUENCY NOISE VIBRATION AND ACTIVE CONTROL"] = "J. Low Freq. Noise V. A.",
+ ["JOURNAL OF LOW FREQUENCY NOISE, VIBRATION, AND ACTIVE CONTROL"] = "J. Low Freq. Noise Vib. Act. Control",
["JOURNAL OF LOW POWER ELECTRONICS"] = "J Low Power Electron",
["JOURNAL OF LOW TEMPERATURE PHYSICS"] = "J. Low Temp. Phys.",
["JOURNAL OF LOWER GENITAL TRACT DISEASE"] = "J Low Genit Tract Dis",
@@ -64625,6 +64643,7 @@ abbrevs = {
["JOURNAL OF RNAI AND GENE SILENCING : AN INTERNATIONAL JOURNAL OF RNA AND GENE TARGETING RESEARCH"] = "J RNAi Gene Silencing",
["JOURNAL OF ROBOTIC SURGERY"] = "J Robot Surg",
["JOURNAL OF ROBOTIC SYSTEMS"] = "J Robot Syst",
+ ["JOURNAL OF ROBOTICS, NETWORKING AND ARTIFICIAL LIFE"] = "J. Robot. Netw. Artif. Life",
["JOURNAL OF ROCK MECHANICS AND GEOTECHNICAL ENGINEERING"] = "J. Rock Mech. Geotech. Eng.",
["JOURNAL OF ROMAN ARCHAEOLOGY"] = "JRA",
["JOURNAL OF ROMAN MILITARY EQUIPMENT STUDIES"] = "JRMES",
@@ -70823,6 +70842,7 @@ abbrevs = {
["MACHINERY ACOUSTICS 1999: DEVELOPMENT OF LOW-NOISE AND LOW-VIBRATION PRODUCTS"] = "VDI Bericht",
["MACHINERY AND PRODUCTION ENGINEERING"] = "Mach. Prod. Eng.",
["MACHINERY, MATERIALS SCIENCE AND ENGINEERING APPLICATIONS, PTS 1 AND 2"] = "Adv. Mater. Res-switz.",
+ ["MACHINES"] = "Machines",
["MACHINES OF LEONARDO DA VINCI AND FRANZ REULEAUX: KINEMATICS OF MACHINES FROM THE RENAISSANCE TO THE 20TH CENTURY"] = "Hist. Mech. Mach. Sci.",
["MACHINES OF NATURE AND CORPOREAL SUBSTANCES IN LEIBNIZ"] = "New. Synth. Hist. Lib.",
["MACHINES, COMPUTATIONS, AND UNIVERSALITY"] = "Lect. Notes. Comput. Sc.",
@@ -71915,6 +71935,7 @@ abbrevs = {
["MASUI TO SOSEI. HIROSHIMA JOURNAL OF ANESTHESIA"] = "Masui To Sosei",
["MASUI. JAPANESE JOURNAL OF ANESTHESIOLOGY"] = "Masui",
["MASUI. THE JAPANESE JOURNAL OF ANESTHESIOLOGY"] = "Masui",
+ ["MASZYNY ELEKTRYCZNE - ZESZYTY PROBLEMOWE"] = "Masz. Elektr. Zesz. Probl.",
["MASZYNY PRZEPŁYWOWE"] = "Masz. Przepływ.",
["MAT. SERIE A: CONFERENCIAS, SEMINARIOS Y TRABAJOS DE MATEMATICA"] = "MAT Ser. A Conf. Semin. Trab. Mat.",
["MATATU"] = "Matatu",
@@ -77468,6 +77489,7 @@ abbrevs = {
["MOTOR DEVELOPMENT IN EARLY AND LATER CHILDHOOD : LONGITUDINAL APPROACHES"] = "Eur. Network.",
["MOTOR UNIT NUMBER ESTIMATION (MUNE), PROCEEDINGS"] = "Suppl. Clin. Neurophys.",
["MOTORCYCLES"] = "VDI Bericht",
+ ["MOTORTECHNISCHE ZEITSCHRIFT"] = "Mot. Z.",
["MOTRIZ : REVISTA DE EDUCAÇÃO FÍSICA. UNESP"] = "Motriz",
["MOTRIZ-REVISTA DE EDUCACAO FISICA"] = "Motriz.",
["MOTT METAL-INSULATOR TRANSITION"] = "Springer. Tr. Mod. Phys.",
@@ -112401,6 +112423,7 @@ abbrevs = {
["TECHNIQUES ORTHOPEDIQUES"] = "Tech Orthop",
["TECHNIQUES TO ASSESS THE CORROSION ACTIVITY OF STEEL REINFORCED CONCRETE STRUCTURES"] = "Am. Soc. Test. Mater.",
["TECHNISCHE MITTEILUNGEN"] = "Tech. Mitt.",
+ ["TECHNISCHE MITTEILUNGEN AEG-TELEFUNKEN"] = "Tech. Mitt. AEG-Telefunken",
["TECHNISCHE MITTEILUNGEN KRUPP FORSCHUNGSBERICHTE"] = "Tech. Mitt. Krupp Fors.",
["TECHNISCHE MITTEILUNGEN KRUPP WERKSBERICHTE"] = "Tech. Mitt. Krupp Werk.",
["TECHNISCHE RUNDSCHAU"] = "Tech. Rundsch.",
@@ -118101,6 +118124,7 @@ abbrevs = {
["TRANSNATIONALISM IN SOUTHERN AFRICAN LITERATURE"] = "Rout. Res. Postcol. Lit.",
["TRANSNATIONALISM SERIES"] = "Transnatl. Ser.",
["TRANSNATIONALIZATION OF PUBLIC SPHERES"] = "Transform. State.",
+ ["TRANSNAV"] = "TransNav",
["TRANSONIC AERODYNAMICS"] = "Front. App. M.",
["TRANSPACIFIC"] = "Transpacific",
["TRANSPARENCY IN GREY LITERATURE: GREY TECH APPROACHES TO HIGH TECH ISSUES"] = "Gl. Conference. Ser.",
@@ -119694,6 +119718,7 @@ abbrevs = {
["UNIVERSAL HUMAN RIGHTS"] = "Universal Hum. Rights",
["UNIVERSAL HUMAN RIGHTS AND EXTRATERRITORIAL OBLIGATIONS"] = "Pa. Stud. Hum. Rights",
["UNIVERSAL JOURNAL OF AGRICULTURAL RESEARCH"] = "Univers J Agric Res",
+ ["UNIVERSAL JOURNAL OF ELECTRICAL AND ELECTRONIC ENGINEERING"] = "Univers. J. Electr. Electron. Eng.",
["UNIVERSAL JOURNAL OF MICROBIOLOGY RESEARCH"] = "Univers J Microbiol Res",
["UNIVERSAL JOURNAL OF PUBLIC HEALTH"] = "Univers J Public Health",
["UNIVERSAL JURISDICTION: NATIONAL COURTS AND THE PROSECUTION OF SERIOUS CRIMES UNDER INTERNATIONAL LAW"] = "Pa. Stud. Hum. Rights.",
@@ -123439,6 +123464,7 @@ abbrevs = {
["WORLD ECONOMY"] = "World Economy",
["WORLD ECONOMY: A GLOBAL ANALYSIS"] = "Routl. Stud. Mod. World",
["WORLD EDUCATION REPORTS"] = "World Educ Rep",
+ ["WORLD ELECTRIC VEHICLE JOURNAL"] = "World Electr. Veh. J.",
["WORLD ENGLISHES"] = "World English.",
["WORLD ENGLISHES 2000"] = "Lit. St. E. W.",
["WORLD ENGLISHES: A COGNITIVE SOCIOLINGUISTIC APPROACH"] = "Appl. Cogn. Linguist.",
@@ -129270,6 +129296,7 @@ unabbrevs = {
["AM J ELECTRONEURODIAGNOSTIC TECHNOL"] = "American journal of electroneurodiagnostic technology",
["AM J EMERG MED"] = "The American journal of emergency medicine",
["AM J ENG EDUC"] = "American journal of engineering education",
+ ["AM J ENG RES"] = "American Journal of Engineering Research",
["AM J ENOL VITIC"] = "American journal of enology and viticulture",
["AM J ENOL VITICULT"] = "American Journal of Enology and Viticulture",
["AM J ENTREP"] = "American journal of entrepreneurship",
@@ -129994,6 +130021,7 @@ unabbrevs = {
["ANALGESIA (ELMSFORD N Y)"] = "Analgesia (Elmsford, N.Y.)",
["ANALOG CIRC SIG PROC"] = "1v Cmos G(m)-c Filters",
["ANALOG CIRCUITS SIGNAL PROCESS"] = "Analog Circuits and Signal Processing",
+ ["ANALOG DIALOGUE"] = "Analog Dialogue",
["ANALOG INTEGR CIRC S"] = "Analog Integrated Circuits and Signal Processing",
["ANALOG INTEGR CIRCUITS SIGNAL PROCESS"] = "Analog integrated circuits and signal processing",
["ANALOG SCI FICT SCI FACT"] = "Analog science fiction/science fact",
@@ -131845,6 +131873,7 @@ unabbrevs = {
["ARCH DOMIN PEDIATR"] = "Archivos dominicanos de pediatría",
["ARCH DRUG INF"] = "Archives of drug information",
["ARCH EISENHUTTENWES"] = "Archiv Fur Das Eisenhuttenwesen",
+ ["ARCH ELECTR ENG"] = "Archives of Electrical Engineering",
["ARCH ELEKTR UBERTRAG"] = "Archiv Der Elektrischen Und Ubertragung",
["ARCH ELEKTROTECH"] = "Archiv für Elektrotechnik",
["ARCH EMERG MED"] = "Archives of emergency medicine",
@@ -133678,6 +133707,7 @@ unabbrevs = {
["AUTOMATICA (OXF)"] = "Automatica : the journal of IFAC, the International Federation of Automatic Control",
["AUTOMATICA J IFAC"] = "Automatica. A Journal of IFAC, the International Federation of Automatic Control",
["AUTOMATIKA"] = "Automatika",
+ ["AUTOMATISIERUNGSTECHNIK"] = "Automatisierungstechnik",
["AUTOMATISME"] = "Automatisme",
["AUTOMEDICA"] = "Automedica",
["AUTOMOB QUART"] = "Automobile Quarterly",
@@ -138904,6 +138934,7 @@ unabbrevs = {
["CERVIX LOW FEMALE GENITAL TRACT"] = "The Cervix and the lower female genital tract",
["CES LID-ETHNOL CAS"] = "Cesky Lid-ethnologicky Casopis",
["CES ODONTOL"] = "CES odontología",
+ ["CES TRANS ELECTR MACH SYST"] = "CES Transactions on Electrical Machines and Systems",
["CES4HEALTHINFO"] = "CES4Health.info",
["CESIFO BOOK SER"] = "Cesifo Book Series",
["CESIFO ECON STUD"] = "CESifo economic studies",
@@ -145837,7 +145868,8 @@ unabbrevs = {
["ELEKTROKHIMIYA"] = "Elektrokhimiya",
["ELEKTROMED BIOMED TECH"] = "Elektro Medizin; Biomedizin und Technik",
["ELEKTRON DATENVERARB"] = "Electronische Datenverarbeitung",
- ["ELEKTRON ELEKTROTECH"] = "Elektronika Ir Elektrotechnika",
+ ["ELEKTRON ELEKTROTECH"] = "Elektronika ir Elektrotechnika",
+ ["ELEKTROTECH INF"] = "Elektrotechnik und Informationstechnik",
["ELEKTROTECH MASCHINENBAU"] = "Elektrotechnik und Maschinenbau",
["ELEKTROTECH Z"] = "Elektrotechnische Zeitschrift",
["ELEKTROTECH Z AUSG A"] = "Elektrotechnische Zeitschrift Etz-a",
@@ -146581,7 +146613,7 @@ unabbrevs = {
["EPA J"] = "EPA journal",
["EPATOLOGIA"] = "Epatologia",
["EPD CONG"] = "Epd Congress",
- ["EPE J"] = "Epe Journal",
+ ["EPE J"] = "EPE Journal",
["EPEIROTIKE HESTIA"] = "Ēpeirōtikē hestia",
["EPET ETAIREIAS STEREOELLADIKON MELETON"] = "Epetēris Hetaireias Stereoelladikōn Meletōn",
["EPETBOIOTMEL"] = "Επετηρίς της Εταιρείας Βοιωτικών Μελετών",
@@ -149168,6 +149200,7 @@ unabbrevs = {
["FOUND SIGNAL PROCESS"] = "Advanced Topics in System and Signal Theory: A Mathematical Approach",
["FOUND SIGNAL PROCESS COMMUN NETW"] = "Foundations in Signal Processing, Communications and Networking",
["FOUND TRENDS SIGNAL PROCESS"] = "Foundations and Trends${}^\\\\circledR$ in Signal Processing",
+ ["FOUND TRENDS SYST CONTROL"] = "Foundations and Trends in Systems and Control",
["FOUND TRENDS THEOR COMPUT SCI"] = "Foundations and Trends${}^\\\\circledR$ in Theoretical Computer Science",
["FOUND UNDERGRAD RES MATH"] = "Foundations for Undergraduate Research in Mathematics",
["FOUNDATIONS"] = "Foundations",
@@ -153065,6 +153098,7 @@ unabbrevs = {
["IEE PROC-J"] = "Iee Proceedings-j Optoelectronics",
["IEE PROC-NANOBIOTECH"] = "Iee Proceedings-nanobiotechnology",
["IEE PROC-SOFTW"] = "Iee Proceedings-software",
+ ["IEE PROC: ELECTR POWER APPL"] = "IEE Proceedings: Electric Power Applications",
["IEE PROC: OPTOELECTRON"] = "IEE Proceedings: Optolectronics",
["IEE PROC: SCI MEAS TECHNOL"] = "IEE Proceedings: Science, Measurement & Technology",
["IEE REV"] = "Iee Reviews",
@@ -153327,6 +153361,8 @@ unabbrevs = {
["IEEE NUCL SCI CONF R"] = "1996 IEEE Nuclear Science Symposium - Conference Record",
["IEEE NUCL SCI SYMP CONF REC (1997)"] = "IEEE Nuclear Science Symposium conference record. Nuclear Science Symposium",
["IEEE OPEN J ENG MED BIOL"] = "IEEE open journal of engineering in medicine and biology",
+ ["IEEE OPEN J IND APPL"] = "IEEE Open Journal of Industry Applications",
+ ["IEEE OPEN J IND ELECTRON SOC"] = "IEEE Open Journal of the Industrial Electronics Society",
["IEEE PAC VIS SYMP"] = "IEEE Pacific Visualization Symposium : [proceedings]. IEEE Pacific Visualisation Symposium",
["IEEE PACIF"] = "1997 IEEE Pacific Rim Conference On Communications, Computers and Signal Processing",
["IEEE PARALL DISTRIB"] = "IEEE Parallel & Distributed Technology",
@@ -153790,6 +153826,7 @@ unabbrevs = {
["IEEE/OUP CLASS REISSUE"] = "An IEEE/OUP Classic Reissue",
["IEEE/OUP SER ELECTROMAGN WAVE THEORY"] = "IEEE/OUP Series on Electromagnetic Wave Theory",
["IEEE/TMS J ELECTRON MATER"] = "IEEE/TMS Journal of Electronic Materials",
+ ["IEEJ J IND APPL"] = "IEEJ Journal of Industry Applications",
["IEEJ T ELECTR ELECTR"] = "Ieej Transactions On Electrical and Electronic Engineering",
["IEEJ TRANS SENS MICROMACHINES"] = "IEEJ Transactions on Sensors and Micromachines",
["IEICE ELECTRON EXPR"] = "Ieice Electronics Express",
@@ -153836,7 +153873,7 @@ unabbrevs = {
["IET NANOBIOTECHNOL"] = "IET nanobiotechnology",
["IET NETWORKS"] = "IET Networks",
["IET OPTOELECTRON"] = "IET Optoelectronics",
- ["IET POWER ELECTRON"] = "Iet Power Electronics",
+ ["IET POWER ELECTRON"] = "IET Power Electronics",
["IET POWER ENERGY SER"] = "IET Power and Energy Series",
["IET POWER ENG"] = "IET Power Engineer",
["IET PROC: SCI MEAS TECHNOL"] = "IET Proceedings: Science, Measurement & Technology",
@@ -153859,10 +153896,12 @@ unabbrevs = {
["IFA CONGR S"] = "Ifa Congress Seminar Series",
["IFAC J SYST CONTROL"] = "IFAC Journal of Systems and Control",
["IFAC P SER"] = "Computer Applications in Biotechnology 2001 (cab8)",
+ ["IFAC PROC VOL"] = "IFAC Proceedings Volumes",
["IFAC SYMP SERIES"] = "Adaptive Systems in Control and Signal Processing 1992",
["IFAC SYMPOS SER"] = "IFAC Symposia Series",
["IFAC WORK S"] = "Adaptation and Learning in Control and Signal Processing 2001",
["IFAC WORKSHOP SER"] = "IFAC Workshop Series",
+ ["IFAC-PAP"] = "IFAC-PapersOnLine",
["IFCOLOG J LOG APPL"] = "The IfCoLog Journal of Logics and their Applications",
["IFDC SP PUB"] = "Environmental Challenges of Fertilizer Production - An Examination of Progress and Pitfalls",
["IFE"] = "Istoriko-filosofsky ezegodnik (History of philosophy yearbook), ed. by the Inst. of Philosophy of the Acad. of Sciences of URSS",
@@ -155663,6 +155702,7 @@ unabbrevs = {
["INT J CULTURAL STUD"] = "International Journal of Cultural Studies",
["INT J CURR ADV RES"] = "International journal of current advanced research",
["INT J CURR CHEM"] = "International journal of current chemistry",
+ ["INT J CURR ENG SCI RES"] = "International Journal of Current Engineering and Scientific Research",
["INT J CURR MICROBIOL APPL SCI"] = "International journal of current microbiology and applied sciences",
["INT J CURR MULTIDISCIP STUD"] = "International journal of current multidisciplinary studies",
["INT J CURR PHARM RES"] = "International journal of current pharmaceutical research",
@@ -157107,6 +157147,7 @@ unabbrevs = {
["INT RELAT ASIA-PAC"] = "International Relations of The Asia-pacific",
["INT REQUIR ENG CONF"] = "15th IEEE International Requirements Engineering Conference, Proceedings",
["INT RES BUS DISCIPL"] = "Developmental Entrepreneurship: Adversity, Risk, and Isolation",
+ ["INT RES J ENG TECHNOL"] = "International Research Journal of Engineering and Technology",
["INT RES J ENVIRON SCI"] = "International research journal of environmental sciences",
["INT RES J NAT APPL SCI"] = "International research journal of natural and applied sciences",
["INT RES J PURE APPL CHEM"] = "International research journal of pure and applied chemistry",
@@ -157130,6 +157171,7 @@ unabbrevs = {
["INT REV ECON FINANC"] = "International Review of Economics & Finance",
["INT REV ECON FINANCE"] = "International Review of Economics and Finance",
["INT REV EDUC"] = "International review of education. Internationale Zeitschrift für Erziehungswissenschaft. Revue internationale de pédagogie",
+ ["INT REV ELECTR ENG"] = "International Review of Electrical Engineering",
["INT REV ELECTR ENG-I"] = "International Review of Electrical Engineering-iree",
["INT REV ERGON"] = "International Reviews of Ergonomics",
["INT REV EXP PATHOL"] = "International Review of Experimental Pathology",
@@ -162668,6 +162710,7 @@ unabbrevs = {
["J LOUISIANA ST MED S"] = "Journal of The Louisiana State Medical Society",
["J LOW FREQ NOISE V A"] = "Journal of Low Frequency Noise Vibration and Active Control",
["J LOW FREQ NOISE VIB"] = "Journal of Low Frequency Noise & Vibration",
+ ["J LOW FREQ NOISE VIB ACT CONTROL"] = "Journal of Low Frequency Noise, Vibration, and Active Control",
["J LOW GENIT TRACT DI"] = "Journal of Lower Genital Tract Disease",
["J LOW GENIT TRACT DIS"] = "Journal of lower genital tract disease",
["J LOW POWER ELECTRON"] = "Journal of low power electronics",
@@ -164860,6 +164903,7 @@ unabbrevs = {
["J RISK UNCERTAINTY"] = "Journal of Risk and Uncertainty",
["J RNAI GENE SILENCING"] = "Journal of RNAi and gene silencing : an international journal of RNA and gene targeting research",
["J ROBERT H LURIE CANCER CENT NORTHWEST UNIV"] = "The journal of the Robert H. Lurie Cancer Center of Northwestern University",
+ ["J ROBOT NETW ARTIF LIFE"] = "Journal of Robotics, Networking and Artificial Life",
["J ROBOT SURG"] = "Journal of robotic surgery",
["J ROBOT SYST"] = "Journal of robotic systems",
["J ROBOTIC SYST"] = "Journal of Robotic Systems",
@@ -168547,6 +168591,7 @@ unabbrevs = {
["MACH VISION APPL"] = "Machine Vision and Applications",
["MACHINE LEARN SIGN P"] = "2005 IEEE Workshop On Machine Learning for Signal Processing (mlsp)",
["MACHINERY"] = "Machinery",
+ ["MACHINES"] = "Machines",
["MACLEANS"] = "Maclean's",
["MACMILLAN NEW ELECTRON SER"] = "Macmillan New Electronics Series",
["MACQUARIE MG COG SCI"] = "Delusion and Self-deception: Affective and Motivational Influences On Belief Formation",
@@ -169062,6 +169107,7 @@ unabbrevs = {
["MASTOZOOL NEOTROP"] = "Mastozoología neotropical",
["MASUI"] = "Masui. The Japanese journal of anesthesiology",
["MASUI TO SOSEI"] = "Masui to sosei. Hiroshima journal of anesthesia",
+ ["MASZ ELEKTR ZESZ PROBL"] = "Maszyny Elektryczne - Zeszyty Problemowe",
["MASZ PRZEPŁYW"] = "Maszyny Przepływowe",
["MAT"] = "Memorie dell’Accademia delle Scienze di Torino, Classe di Scienze morali, storiche e filologiche",
["MAT APL COMPUT"] = "Sociedade Brasiliera de Matemática Applicada e Computacional",
@@ -171898,6 +171944,7 @@ unabbrevs = {
["MOSCOW UNIV PHYS BULL"] = "Moscow University Physics Bulletin",
["MOSQ NEWS"] = "Mosquito news",
["MOST NEWSL"] = "MOST newsletter",
+ ["MOT Z"] = "Motortechnische Zeitschrift",
["MOTHER"] = "The Mother",
["MOTHER CHILD"] = "Mother and child",
["MOTHER JONES"] = "Mother Jones",
@@ -188240,7 +188287,7 @@ unabbrevs = {
["STAFF PAP INT MONET FUND"] = "Staff papers - International Monetary Fund. International Monetary Fund",
["STAFF PROC"] = "Staff proceedings. Hillcrest Medical Center (Tulsa, Okla.)",
["STAHL EISEN"] = "Stahl Und Eisen",
- ["STAHLBAU"] = "Stahlbau",
+ ["STAHLBAU"] = "Der Stahlbau",
["STAIN TECHNOL"] = "Stain technology",
["STAL"] = "STAL. Sciences et techniques de l'animal de laboratoire",
["STAL ENGL"] = "Stal in English-ussr",
@@ -189971,6 +190018,7 @@ unabbrevs = {
["TECH MANUSCR US ARMY BIOL LAB"] = "Technical manuscript. U.S. Army Biological Laboratories",
["TECH MESS"] = "Technisches Messen",
["TECH MITT"] = "Technische Mitteilungen",
+ ["TECH MITT AEG-TELEFUNKEN"] = "Technische Mitteilungen AEG-Telefunken",
["TECH MITT KRUPP FORS"] = "Technische Mitteilungen Krupp Forschungsberichte",
["TECH MITT KRUPP WERK"] = "Technische Mitteilungen Krupp Werksberichte",
["TECH NEUROSURG"] = "Techniques in Neurosurgery",
@@ -191302,6 +191350,7 @@ unabbrevs = {
["TRANSM DISTRIB"] = "Transmission & Distribution",
["TRANSNAT CORPORATIONS"] = "Transnational Corporations",
["TRANSNATL SER"] = "Rethinking Transnationalism",
+ ["TRANSNAV"] = "TransNav",
["TRANSP CL IMMUN SFMM"] = "Late Graft Loss",
["TRANSP ECON MANAG PO"] = "Future of Intermodal Freight Transport: Operations, Design and Policy",
["TRANSP GEOTECH"] = "Transportation Geotechnics",
@@ -192095,6 +192144,7 @@ unabbrevs = {
["UNIVERS ACCESS HUM COMPUT INTERACT (2017)"] = "Universal access in human-computer interaction : designing novel interactions : 11th International Conference, UAHCI 2017, held as part of HCI International 2017, Vancouver, BC, Canada, July 9-14, 2017, Proceedings. Part II. International Conference on Universal Access in Human-Computer Interaction (11th : 2017 : Vancouver, B.C.)",
["UNIVERS ACCESS INF SOC"] = "Universal access in the information society",
["UNIVERS J AGRIC RES"] = "Universal journal of agricultural research",
+ ["UNIVERS J ELECTR ELECTRON ENG"] = "Universal Journal of Electrical and Electronic Engineering",
["UNIVERS J MICROBIOL RES"] = "Universal journal of microbiology research",
["UNIVERS J PUBLIC HEALTH"] = "Universal journal of public health",
["UNIVERSAL ACCESS INF"] = "Universal Access in The Information Society",
@@ -193919,6 +193969,7 @@ unabbrevs = {
["WORLD ECON"] = "The World economy",
["WORLD ECONOMY"] = "World Economy",
["WORLD EDUC REP"] = "World education reports",
+ ["WORLD ELECTR VEH J"] = "World Electric Vehicle Journal",
["WORLD ENGLISH"] = "World Englishes",
["WORLD ENVIRON REP"] = "World environment report",
["WORLD FARM"] = "World Farming",
diff --git a/biblio/citation-style-language/citeproc-latex-core.lua b/biblio/citation-style-language/citeproc-latex-core.lua
deleted file mode 100644
index 3057c5d1e2..0000000000
--- a/biblio/citation-style-language/citeproc-latex-core.lua
+++ /dev/null
@@ -1,525 +0,0 @@
---
--- Copyright (c) 2021-2024 Zeping Lee
--- Released under the MIT license.
--- Repository: https://github.com/zepinglee/citeproc-lua
---
-
-local core = {}
-
-require("lualibs")
-local json_decode = utilities.json.tolua
-
-local citeproc = require("citeproc")
-local bibtex_data = require("citeproc-bibtex-data")
-local bibtex_parser = require("citeproc-bibtex-parser")
-local latex_parser = require("citeproc-latex-parser")
-local yaml -- = require("citeproc-yaml") -- load on demand
-local bibtex2csl -- = require("citeproc-bibtex2csl") -- load on demand
-local unicode = require("citeproc-unicode")
-local util = citeproc.util
-
-
-core.locale_file_format = "csl-locales-%s.xml"
-core.uncited_ids = {}
-core.uncite_all_items = false
-
-core.item_list = {}
-core.item_dict = {}
-
----@param file_name string
----@param ftype "bib"?
----@param file_info string
----@return string? contents
-function core.read_file(file_name, ftype, file_info)
- if file_info then
- file_info = unicode.capitalize(file_info)
- else
- file_info = "File"
- end
- local path = kpse.find_file(file_name, ftype)
- if not path then
- if ftype and not util.endswith(file_name, ftype) then
- file_name = file_name .. ftype
- end
- util.error(string.format('%s "%s" not found', file_info, file_name))
- return nil
- end
- local file = io.open(path, "r")
- if not file then
- util.error(string.format('Cannot open %s "%s"', file_info, path))
- return nil
- end
- local contents = file:read("*a")
- contents = util.remove_bom(contents)
- file:close()
- return contents
-end
-
-
----@param filename string
----@return string file
----@return string format
----@return string? contents
-local function read_data_file(filename)
- local file = filename
- local format = "json"
- local contents = nil
-
- if util.endswith(filename, ".json") then
- format = "json"
- contents = core.read_file(filename, nil, "database file")
- elseif string.match(filename, "%.ya?ml$") then
- format = "yaml"
- contents = core.read_file(filename, nil, "database file")
- elseif util.endswith(filename, ".bib") then
- format = "bibtex"
- contents = core.read_file(filename, "bib", "database file")
- else
- file = filename .. ".json"
- local path = kpse.find_file(file)
- if path then
- format = "json"
- contents = core.read_file(file, nil, "database file")
- else
- path = kpse.find_file(filename .. ".yaml") or kpse.find_file(filename .. ".yml")
- if path then
- format = "yaml"
- file = filename .. string.match(path, "%.ya?ml$")
- contents = core.read_file(path, nil, "database file")
- else
- path = kpse.find_file(filename, "bib")
- if path then
- file = filename .. ".bib"
- format = "bibtex"
- contents = core.read_file(filename, "bib", "database file")
- else
- util.error(string.format('Cannot find database file "%s"', filename .. ".json"))
- return file, format, nil
- end
- end
- end
- end
- return file, format, contents
-end
-
-
-local function read_data_files(data_files)
- local item_list = {}
- local item_dict = {}
-
- --- Store BibTeX entries for later resolving crossref
- ---@type table<string, BibtexEntry>
- local bibtex_entries = {}
- ---@type table<string, string>
- local bibtex_strings = {}
- for name, macro in pairs(bibtex_data.macros) do
- bibtex_strings[name] = macro.value
- end
- ---@type BibtexEntry[]
- local entries_with_crossref = {}
-
- for _, data_file in ipairs(data_files) do
- -- local file_name, csl_items = read_data_file(data_file)
-
- local csl_items = {}
-
- local file, format, contents = read_data_file(data_file)
-
- if contents then
-
- if format == "json" then
- local ok, res = pcall(json_decode, contents)
- if ok and res then
- ---@cast res CslData
- csl_items = res
- else
- util.error(string.format('JSON decode error in file "%s".', file))
- end
-
- elseif format == "yaml" then
- yaml = yaml or require("citeproc-yaml")
- local ok, res = pcall(yaml.parse, contents)
- if ok and res then
- ---@cast res CslData
- csl_items = res
- else
- util.error(string.format('YAML decode error in file "%s".', file))
- end
-
- elseif format == "bibtex" then
- local bib_data, exceptions = bibtex_parser.parse(contents, bibtex_strings)
- if bib_data then
- bibtex2csl = bibtex2csl or require("citeproc-bibtex2csl")
- csl_items = bibtex2csl.convert_to_csl_data(bib_data, true, true, true, true)
- for _, entry in ipairs(bib_data.entries) do
- if not bibtex_entries[entry.key] then
- bibtex_entries[entry.key] = entry
- if entry.fields.crossref then
- table.insert(entries_with_crossref, entry)
- end
- end
- end
- for string_name, value in pairs(bib_data.strings) do
- bibtex_strings[string_name] = value
- end
- end
- end
-
- for _, item in ipairs(csl_items) do
- local id = item.id
- if item_dict[id] then
- util.warning(string.format('Duplicate entry key "%s" in "%s".', id, file))
- else
- item_dict[id] = item
- table.insert(item_list, item)
- end
- end
-
- end
- end
-
- bibtex_parser.resolve_crossrefs(entries_with_crossref, bibtex_entries)
-
- for _, entry in ipairs(entries_with_crossref) do
- local new_item = bibtex2csl.convert_to_csl_item(entry, true, true, true, true)
- item_dict[new_item.id] = new_item
- for i, item in ipairs(item_list) do
- if item.id == new_item.id then
- item_list[i] = new_item
- break
- end
- end
- end
-
- return item_list, item_dict
-end
-
-
-function core.make_citeproc_sys(data_files)
- core.item_list, core.item_dict = read_data_files(data_files)
- local citeproc_sys = {
- retrieveLocale = function (lang)
- local locale_file_format = core.locale_file_format or "locales-%s.xml"
- local filename = string.format(locale_file_format, lang)
- return core.read_file(filename)
- end,
- retrieveItem = function (id)
- local res = core.item_dict[id]
- return res
- end
- }
-
- return citeproc_sys
-end
-
----comment
----@param style_name string
----@param data_files string[]
----@param lang string?
----@return CiteProc?
-function core.init(style_name, data_files, lang)
- if style_name == "" or #data_files == 0 then
- return nil
- end
- local style = core.read_file(style_name .. ".csl", nil, "style")
- if not style then
- util.error(string.format('Failed to load style "%s.csl"', style_name))
- return nil
- end
-
- local force_lang = nil
- if lang and lang ~= "" then
- force_lang = true
- else
- lang = nil
- end
-
- local citeproc_sys = core.make_citeproc_sys(data_files)
- local engine = citeproc.new(citeproc_sys, style, lang, force_lang)
-
- if engine:is_dependent_style() then
- local default_locale = engine.style.default_locale;
- local parent_style_link = engine:get_independent_parent()
- if not parent_style_link then
- return nil
- end
- local parent_style_id = string.match(string.gsub(parent_style_link, "/+$", ""), "[^/]+$")
- util.info(string.format('Style "%s" is a dependent style linked to "%s".', style_name, parent_style_id))
- style = core.read_file(parent_style_id .. ".csl", nil, "style")
- if not style then
- util.error(string.format('Failed to load style "%s.csl"', parent_style_id))
- return nil
- end
- engine = citeproc.new(citeproc_sys, style, lang, force_lang)
- engine.style.default_locale = default_locale
- end
-
- return engine
-end
-
-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
- return t
-end
-
-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
-
-function core.make_citation(citation_info)
- -- `citation_info`: "citationID={ITEM-1@2},citationItems={{id={ITEM-1},label={page},locator={6}}},properties={noteIndex={3}}"
- -- util.debug(citation_info)
- 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
- local citation_item = parse_latex_prop(item)
- if citation_item.prefix then
- -- util.debug(citation_item.prefix)
- citation_item.prefix = latex_parser.latex_to_pseudo_html(citation_item.prefix, true, false)
- -- util.debug(citation_item.prefix)
- end
- if citation_item.suffix then
- citation_item.suffix = latex_parser.latex_to_pseudo_html(citation_item.suffix, true, false)
- end
- citation.citationItems[i] = citation_item
- end
-
- 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
-
- -- util.debug(citation)
- return citation
-end
-
-
----@param engine CiteProc
----@param citations CitationData[]
----@return table<CitationId, string>
-function core.process_citations(engine, citations)
- local citations_pre = {}
-
- local citation_strings = {}
-
- core.update_cited_and_uncited_ids(engine, citations)
-
- for _, citation in ipairs(citations) do
- if citation.citationID ~= "@nocite" then
- -- local res = engine:processCitationCluster(citation, citations_pre, {})
- -- for _, tuple in ipairs(res[2]) do
- -- local citation_str = tuple[2]
- -- local citation_id = tuple[3]
- -- citation_strings[citation_id] = citation_str
- -- util.debug(citation_str)
- -- end
-
- local citation_str = engine:process_citation(citation)
- citation_strings[citation.citationID] = citation_str
-
- table.insert(citations_pre, {citation.citationID, citation.properties.noteIndex})
- end
- end
-
- return citation_strings
-end
-
-function core.update_cited_and_uncited_ids(engine, citations)
- local id_list = {}
- local id_map = {} -- Boolean map for checking if id in list
- local uncited_id_list = {}
- local uncited_id_map = {}
-
- for _, citation in ipairs(citations) do
- if citation.citationID == "@nocite" then
- for _, cite_item in ipairs(citation.citationItems) do
- if cite_item.id == "*" then
- if not core.uncite_all_items then
- for _, item in ipairs(core.item_list) do
- if not uncited_id_map[item.id] then
- table.insert(uncited_id_list, item.id)
- uncited_id_map[item.id] = true
- end
- end
- core.uncite_all_items = true
- end
- elseif not uncited_id_map[cite_item.id] then
- table.insert(uncited_id_list, cite_item.id)
- uncited_id_map[cite_item.id] = true
- end
- end
-
- else -- Real citation
- for _, cite_item in ipairs(citation.citationItems) do
- if not id_map[cite_item.id] then
- table.insert(id_list, cite_item.id)
- id_map[cite_item.id] = true
- end
- end
-
- end
- end
-
- engine:updateItems(id_list)
- engine:updateUncitedItems(uncited_id_list)
-
-end
-
-
----Convert to a filter object described in
---- <https://citeproc-js.readthedocs.io/en/latest/running.html#selective-output-with-makebibliography>
----@param filter_str string e.g., "type={book},notcategory={csl},notcategory={tex}"
----@return table
-function core.parser_filter(filter_str)
- local conditions = {}
- for i, condition in ipairs(latex_parser.parse_seq(filter_str)) do
- local negative
- local field, value = string.match(condition, "(%w+)%s*=%s*{([^}]+)}")
- if field then
- if string.match(field, "^not") then
- negative = true
- field = string.gsub(field, "^not", "")
- end
- if field == "category" then
- field = "categories"
- end
- if field == "keyword" or field == "type" or field == "categories" then
- table.insert(conditions, {
- field = field,
- value = value,
- negative = negative,
- })
- end
- end
- end
- -- util.debug(conditions)
- return {select = conditions}
-end
-
----comment
----@param engine CiteProc
----@param option_str string
----@return unknown
-function core.make_bibliography(engine, option_str)
- local filter
- local options = {}
- if option_str and option_str ~= "" then
- options = latex_parser.parse_prop(option_str)
- filter = core.parser_filter(option_str)
- end
- local result = engine:makeBibliography(filter)
-
- local params = result[1]
- local bib_items = result[2]
-
- local res = ""
-
- ---@type table<string, any>
- local bib_options = {
- index = options.index or "1"
- }
-
- local bib_option_map = {
- ["second-field-align"] = "second-field-align",
- ["hanging-indent"] = "hangingindent",
- ["entry-spacing"] = "entryspacing",
- ["line-spacing"] = "linespacing",
- ["widest-label"] = "widest_label",
- }
- local bib_option_order = {
- "index",
- "second-field-align",
- "hanging-indent",
- "line-spacing",
- "entry-spacing",
- "widest-label",
- }
-
- for option, param in pairs(bib_option_map) do
- if params[param] then
- bib_options[option] = params[param]
- end
- end
-
- local bib_option_list = {}
- for _, option in ipairs(bib_option_order) do
- local value = bib_options[option]
- if value and value ~= "" then
- table.insert(bib_option_list, string.format("%s = %s", option, tostring(value)))
- end
- end
- local bib_options_str = table.concat(bib_option_list, ", ")
-
- -- util.debug(params.bibstart)
- -- if params.bibstart then
- -- res = res .. params.bibstart
- -- end
-
- local bibstart = string.format("\\begin{thebibliography}{%s}\n", bib_options_str)
- res = res .. bibstart
-
-
- for _, bib_item in ipairs(bib_items) do
- res = res .. "\n" .. bib_item
- end
-
- if params.bibend then
- res = res .. "\n" .. params.bibend
- end
- return res
-end
-
-
-function core.set_categories(engine, categories_str)
- -- util.debug(categories_str)
- local category_dict = latex_parser.parse_prop(categories_str)
- for category, keys in pairs(category_dict) do
- category_dict[category] = latex_parser.parse_seq(keys)
- end
- for category, keys in pairs(category_dict) do
- for _, key in ipairs(keys) do
- local item = engine.registry.registry[key]
- if item then
- if not item.categories then
- item.categories = {}
- end
- if not util.in_list(category, item.categories) then
- table.insert(item.categories, category)
- end
- else
- util.error(string.format("Invalid citation key '%s'.", key))
- end
- end
- end
- -- for id, item in pairs(csl.engine.registry.registry) do
- -- util.debug(id)
- -- util.debug(item.categories)
- -- end
-end
-
-
-return core
diff --git a/biblio/citation-style-language/citeproc-latex-parser.lua b/biblio/citation-style-language/citeproc-latex-parser.lua
index 9eab31b36c..42eb6af5b2 100644
--- a/biblio/citation-style-language/citeproc-latex-parser.lua
+++ b/biblio/citation-style-language/citeproc-latex-parser.lua
@@ -8,7 +8,7 @@ local latex_parser = {}
local bibtex_parser
local latex_data
-local markup
+local markup
local util
if kpse then
latex_data = require("citeproc-latex-data")
@@ -133,10 +133,11 @@ function latex_parser.get_latex_grammar()
local latex_grammar = P{
"latex_text";
latex_text = Ct((specials + control_sequence + math + ligatures + specials + V"group" + plain_text)^0),
- group = P"{" * V"latex_text" * P"}" / function (group_contents)
+ group = C(P"{" * V"latex_text" * P"}") / function (raw, group_contents)
return {
type = "group",
contents = group_contents,
+ raw = raw,
}
end,
}
@@ -348,9 +349,18 @@ function latex_parser.convert_cs_to_inlines(tokens, i, strict, case_protection)
else
-- Unrecognized command
if strict then
- table.insert(inlines, markup.Code:new(token.raw))
+ local raw = token.raw
+ for j = i + 1, #tokens do
+ if type(tokens[j]) == "table" and tokens[j].type == "group" then
+ i = j
+ raw = raw .. latex_parser.convert_token_to_raw(tokens[j])
+ else
+ break
+ end
+ end
+ table.insert(inlines, markup.Code:new(raw))
else
- -- Gobble following groupsas pandoc does:
+ -- Gobble following groups as pandoc does:
-- "Foo \unrecognized{bar}{baz} quz" -> "Foo quz"
for j = i + 1, #tokens do
if type(tokens[j]) == "table" and tokens[j].type == "group" then
@@ -365,6 +375,32 @@ function latex_parser.convert_cs_to_inlines(tokens, i, strict, case_protection)
return inlines, i
end
+---@param token any
+---@return string
+function latex_parser.convert_token_to_raw(token)
+ if type(token) == "string" then
+ return token
+ elseif type(token) == "table" then
+ if token.raw then
+ return token.raw
+ elseif token.type == "group" then
+ local raw = "{"
+ for _, token_ in ipairs(token.contents) do
+ raw = raw .. latex_parser.convert_token_to_raw(token_)
+ end
+ raw = raw .. "}"
+ return raw
+ else
+ error(token.type)
+ return ""
+ end
+ else
+ error(type(token))
+ return ""
+ end
+end
+
+-- TODO: raise a warning for unrecognized LaTeX command like `\switchargs`
function latex_parser.convert_group_to_inlines(token, strict, case_protection, force_add_braces)
if case_protection then
local first_token = token.contents[1]
diff --git a/biblio/citation-style-language/citeproc-latex.lua b/biblio/citation-style-language/citeproc-latex.lua
deleted file mode 100644
index 98a5a24ea0..0000000000
--- a/biblio/citation-style-language/citeproc-latex.lua
+++ /dev/null
@@ -1,183 +0,0 @@
---
--- Copyright (c) 2021-2024 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")
-local latex_parser = require("citeproc-latex-parser")
-
-
-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.init(style_name, bib_files, lang)
- if string.match(bib_files, "^%s*$") then
- bib_files = {}
- else
- bib_files = util.split(util.strip(bib_files), "%s*,%s*")
- end
-
- csl.engine = core.init(style_name, bib_files, lang)
-
- if csl.engine and csl.engine.style.citation 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 _, item in ipairs(core.item_list) do
- if not csl.uncited_id_map[item.id] then
- table.insert(csl.uncited_id_list, item.id)
- csl.uncited_id_map[item.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)
- if citation.citationID == "@nocite" then
- for _, cite_item in ipairs(citation.citationItems) do
- if cite_item.id == "*" then
- -- \nocite all items
- core.uncite_all_items = true
-
- elseif not csl.uncited_id_map[cite_item.id] then
- table.insert(csl.uncited_id_list, cite_item.id)
- csl.uncited_id_map[cite_item.id] = true
- end
- end
-
- else
- 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
-end
-
-
-function csl.enable_linking()
- csl.engine:enable_linking()
-end
-
-
----comment
----@param citation_info string
-function csl.cite(citation_info)
- -- "citationID={ITEM-UNAVAILABLE@1},citationItems={{id={ITEM-UNAVAILABLE}}},properties={noteIndex={1}}"
- if not csl.engine then
- util.error("CSL engine is not initialized.")
- end
-
- -- util.debug(citation_info)
- local citation = core.make_citation(citation_info)
- -- util.debug(citation)
-
- 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
- -- util.debug(citation_str)
-
- -- tex.sprint(citation_str)
- -- tex.setcatcode(35, 12) -- #
- -- tex.setcatcode(37, 12) -- %
- -- token.set_macro("l__csl_citation_tl", citation_str)
- -- Don't use `token.set_macro`.
- -- See <https://github.com/zepinglee/citeproc-lua/issues/42>
- -- and <https://tex.stackexchange.com/questions/519954/backslashes-in-macros-defined-in-lua-code>.
- tex.sprint(string.format("\\expandafter\\def\\csname l__csl_citation_tl\\endcsname{%s}", citation_str))
-
- for _, cite_item in ipairs(citation.citationItems) do
- if not core.item_dict[cite_item.id] then
- tex.print(string.format("\\cslsetup{undefined-cites = {%s}}", cite_item.id))
- end
- end
-
- 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.item_dict) 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(filter_str)
- if not csl.engine then
- util.error("CSL engine is not initialized.")
- return
- end
-
- -- util.debug(filter)
- local result = core.make_bibliography(csl.engine, filter_str)
- -- util.debug(result)
-
- -- token.set_macro("g__csl_bibliography_tl", result)
-
- tex.print(util.split(result, "\n"))
-end
-
-
-function csl.set_categories(categories_str)
- core.set_categories(csl.engine, categories_str)
-end
-
-
-return csl
diff --git a/biblio/citation-style-language/citeproc-lua.1 b/biblio/citation-style-language/citeproc-lua.1
index 1186f832ea..a411466460 100644
--- a/biblio/citation-style-language/citeproc-lua.1
+++ b/biblio/citation-style-language/citeproc-lua.1
@@ -1,4 +1,4 @@
-.TH citeproc-lua 1 "0.4.9"
+.TH citeproc-lua 1 "0.6.4"
.SH NAME
citeproc-lua \- make CSL citations and bibliography for LaTeX
.SH SYNOPSIS
diff --git a/biblio/citation-style-language/citeproc-manager.lua b/biblio/citation-style-language/citeproc-manager.lua
new file mode 100644
index 0000000000..e361d6f6a8
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-manager.lua
@@ -0,0 +1,1049 @@
+--
+-- Copyright (c) 2021-2024 Zeping Lee
+-- Released under the MIT license.
+-- Repository: https://github.com/zepinglee/citeproc-lua
+--
+
+local citeproc_manager = {}
+
+require("lualibs")
+local json_encode = utilities.json.tojson
+local json_decode = utilities.json.tolua
+
+local citeproc = require("citeproc")
+local bibtex_data = require("citeproc-bibtex-data")
+local bibtex_parser = require("citeproc-bibtex-parser")
+local latex_parser = require("citeproc-latex-parser")
+local util = citeproc.util
+local unicode = require("citeproc-unicode")
+
+
+---@param file_name string
+---@param ftype "bib" | nil
+---@param file_info string
+---@return string? contents
+local function read_file(file_name, ftype, file_info)
+ if file_info then
+ file_info = unicode.capitalize(file_info)
+ else
+ file_info = "File"
+ end
+ local path
+ if ftype then
+ path = kpse.find_file(file_name, ftype)
+ else
+ path = kpse.find_file(file_name)
+ end
+
+ if not path then
+ if ftype and not util.endswith(file_name, ftype) then
+ file_name = file_name .. ftype
+ end
+ util.error(string.format("%s '%s' not found", file_info, file_name))
+ return nil
+ end
+ local file = io.open(path, "r")
+ if not file then
+ util.error(string.format("Cannot open %s '%s'", file_info, path))
+ return nil
+ end
+ local contents = file:read("*a")
+ contents = util.remove_bom(contents)
+ file:close()
+ return contents
+end
+
+
+---@param filename string
+---@return string file
+---@return string format
+---@return string? contents
+local function read_data_file(filename)
+ local file = filename
+ local format = "json"
+ local contents = nil
+
+ if util.endswith(filename, ".json") then
+ format = "json"
+ contents = read_file(filename, nil, "database file")
+ elseif string.match(filename, "%.ya?ml$") then
+ format = "yaml"
+ contents = read_file(filename, nil, "database file")
+ elseif util.endswith(filename, ".bib") then
+ format = "bibtex"
+ contents = read_file(filename, "bib", "database file")
+ else
+ file = filename .. ".json"
+ local path = kpse.find_file(file)
+ if path then
+ format = "json"
+ contents = read_file(file, nil, "database file")
+ else
+ path = kpse.find_file(filename .. ".yaml") or kpse.find_file(filename .. ".yml")
+ if path then
+ format = "yaml"
+ file = filename .. string.match(path, "%.ya?ml$")
+ contents = read_file(path, nil, "database file")
+ else
+ path = kpse.find_file(filename, "bib")
+ if path then
+ file = filename .. ".bib"
+ format = "bibtex"
+ contents = read_file(filename, "bib", "database file")
+ else
+ util.error(string.format("Cannot find database file '%s'", filename .. ".json"))
+ return file, format, nil
+ end
+ end
+ end
+ end
+ return file, format, contents
+end
+
+
+---@param data_files FilePath[]
+---@return ItemData[]
+---@return table<ItemId, ItemData>
+local function read_data_files(data_files)
+ local item_list = {}
+ local item_dict = {}
+
+ --- Store BibTeX entries for later resolving crossref
+ ---@type table<string, BibtexEntry>
+ local bibtex_entries = {}
+ ---@type table<string, string>
+ local bibtex_strings = {}
+ for name, macro in pairs(bibtex_data.macros) do
+ bibtex_strings[name] = macro.value
+ end
+ ---@type BibtexEntry[]
+ local entries_with_crossref = {}
+
+ for _, data_file in ipairs(data_files) do
+ -- local file_name, csl_items = read_data_file(data_file)
+
+ local csl_items = {}
+
+ local file, format, contents = read_data_file(data_file)
+
+ if contents then
+
+ if format == "json" then
+ local ok, res = pcall(json_decode, contents)
+ if ok and res then
+ ---@cast res CslData
+ csl_items = res
+ else
+ util.error(string.format("JSON decode error in file '%s'.", file))
+ end
+
+ elseif format == "yaml" then
+ yaml = yaml or require("citeproc-yaml")
+ local ok, res = pcall(yaml.parse, contents)
+ if ok and res then
+ ---@cast res CslData
+ csl_items = res
+ else
+ util.error(string.format("YAML decode error in file '%s'.", file))
+ end
+
+ elseif format == "bibtex" then
+ local bib_data, exceptions = bibtex_parser.parse(contents, bibtex_strings)
+ if bib_data then
+ bibtex2csl = bibtex2csl or require("citeproc-bibtex2csl")
+ csl_items = bibtex2csl.convert_to_csl_data(bib_data, true, true, true, true)
+ for _, entry in ipairs(bib_data.entries) do
+ if not bibtex_entries[entry.key] then
+ bibtex_entries[entry.key] = entry
+ if entry.fields.crossref then
+ table.insert(entries_with_crossref, entry)
+ end
+ end
+ end
+ for string_name, value in pairs(bib_data.strings) do
+ bibtex_strings[string_name] = value
+ end
+ end
+ end
+
+ for _, item in ipairs(csl_items) do
+ local id = item.id
+ if item_dict[id] then
+ util.warning(string.format("Duplicate entry key '%s' in '%s'.", id, file))
+ else
+ item_dict[id] = item
+ table.insert(item_list, item)
+ end
+ end
+
+ end
+ end
+
+ bibtex_parser.resolve_crossrefs(entries_with_crossref, bibtex_entries)
+
+ for _, entry in ipairs(entries_with_crossref) do
+ local new_item = bibtex2csl.convert_to_csl_item(entry, true, true, true, true)
+ item_dict[new_item.id] = new_item
+ for i, item in ipairs(item_list) do
+ if item.id == new_item.id then
+ item_list[i] = new_item
+ break
+ end
+ end
+ end
+
+ return item_list, item_dict
+end
+
+
+---@param item_dict table<ItemId, ItemData>
+---@return CiteProcSys
+local function make_citeproc_sys(item_dict)
+ local citeproc_sys = {
+ retrieveLocale = function (lang)
+ local locale_file_format = "csl-locales-%s.xml"
+ local filename = string.format(locale_file_format, lang)
+ return read_file(filename, nil, "locale file")
+ end,
+ retrieveItem = function (id)
+ local res = item_dict[id]
+ if not res and not luatexbase then
+ util.warning(string.format("Didn't find a database entry for '%s'", id))
+ end
+ return res
+ end
+ }
+ return citeproc_sys
+end
+
+
+---@alias StyleId string
+---@alias FilePath string
+---@alias LanguageCode string
+
+---@class RefSection
+---@field index integer
+---@field initialized boolean
+---@field style_id string?
+---@field bib_resources FilePath[]
+---@field lang LanguageCode?
+---@field engine CiteProc?
+---@field cited_ids ItemId[]
+---@field uncited_ids ItemId[]
+---@field items ItemData[]
+---@field item_dict table<ItemId, ItemData>
+---@field citations CitationData[]
+---@field citations_pre table[]
+---@field bibliography_configs string[]
+---@field style string
+local RefSection = {}
+
+---@return RefSection
+function RefSection:new()
+ ---@type RefSection
+ local ref_section = {
+ index = 0,
+ initialized = false,
+ style_id = nil,
+ bib_resources = {},
+ lang = nil,
+ engine = nil,
+ cited_ids = {},
+ uncited_ids = {},
+ items = {},
+ item_dict = {},
+ citations = {},
+ citations_pre = {},
+ bibliography_configs = {},
+ style = "",
+ }
+ setmetatable(ref_section, self)
+ self.__index = self
+ return ref_section
+end
+
+function RefSection:make_citeproc_engine()
+ if not self.style_id or self.style_id == "" then
+ self.style_id = "apa"
+ end
+ local style = read_file(self.style_id .. ".csl", nil, "style")
+ if not style then
+ return
+ end
+
+ self.items, self.item_dict = read_data_files(self.bib_resources)
+ local citeproc_sys = make_citeproc_sys(self.item_dict)
+
+ local force_lang = false
+ if self.lang and self.lang ~= "" then
+ force_lang = true
+ else
+ self.lang = nil
+ end
+
+ self.style = style
+ -- self.items
+
+ self.engine = citeproc.new(citeproc_sys, style, self.lang, force_lang)
+ self:_check_dependent_style(citeproc_sys)
+
+ if self.engine and self.engine.style.citation then
+ self.initialized = true
+ end
+
+ self.engine:updateItems(self.cited_ids)
+
+ self:_update_uncited_items()
+
+end
+
+---@param citeproc_sys CiteProcSys
+function RefSection:_check_dependent_style(citeproc_sys)
+ if self.engine:is_dependent_style() then
+ local parent_style_link = self.engine:get_independent_parent()
+ if not parent_style_link then
+ return nil
+ end
+ local parent_style_id = string.match(string.gsub(parent_style_link, "/+$", ""), "[^/]+$")
+ util.info(string.format('Style "%s" is a dependent style linked to "%s".', self.style_id, parent_style_id))
+ local style = read_file(parent_style_id .. ".csl", nil, "style")
+ if not style then
+ util.error(string.format("Failed to load style '%s.csl'", parent_style_id))
+ return nil
+ end
+ local default_locale = self.engine.style.default_locale;
+ local force_lang = false
+ if self.lang and self.lang ~= "" then
+ force_lang = true
+ elseif default_locale and default_locale ~= "" then
+ self.lang = default_locale
+ else
+ self.lang = nil
+ end
+ self.engine = citeproc.new(citeproc_sys, style, self.lang, force_lang)
+ end
+end
+
+function RefSection:_update_uncited_items()
+ local uncited_ids = {}
+ for _, id in ipairs(self.uncited_ids) do
+ if id == "*" then
+ for _, item in ipairs(self.items) do
+ table.insert(uncited_ids, item.id)
+ end
+ break
+ else
+ table.insert(uncited_ids, id)
+ end
+ end
+ if self.initialized then
+ self.engine:updateUncitedItems(uncited_ids)
+ end
+ self.uncited_ids = uncited_ids
+end
+
+function RefSection:record_fixture()
+ if not self.fixture then
+ self.fixture = {
+ mode = "citation",
+ description = tex.jobname,
+ result = "",
+ bibliography_result = "",
+ citations = "",
+ ["citation-items"] = "",
+ csl = self.style,
+ input = "",
+ version = "1.0",
+ citation_results = {},
+ }
+ end
+ local fixture = self.fixture
+
+ local cited_id_dict = {}
+ for _, citation in ipairs(self.citations) do
+ for _, cite_item in ipairs(citation.citationItems) do
+ cited_id_dict[cite_item.id] = true
+ end
+ end
+ local input_items = {}
+ for _, item in ipairs(self.items) do
+ if cited_id_dict[item.id] then
+ table.insert(input_items, item)
+ end
+ end
+ fixture.input = json_encode(input_items)
+
+ local citation_items = {}
+ for _, citation in ipairs(self.citations) do
+ table.insert(citation_items, util.clone(citation.citationItems))
+ end
+ fixture["citation-items"] = json_encode(citation_items)
+
+ local citations = {}
+ local citations_pre = {}
+ for _, citation in ipairs(self.citations) do
+ table.insert(citations, {citation, util.clone(citations_pre), {}})
+ table.insert(citations_pre, {citation.citationID, citation.properties.noteIndex})
+ end
+ fixture.citations = string.gsub(json_encode(citations), "{%s*}", "[]")
+
+ local result = {}
+ for i, citation_result in ipairs(fixture.citation_results) do
+ if i == #fixture.citation_results then
+ table.insert(result, string.format(">>[%d] %s", i - 1, citation_result))
+ else
+ table.insert(result, string.format("..[%d] %s", i - 1, citation_result))
+ end
+ end
+ fixture.result = table.concat(result, "\n")
+
+ local fixture_output = {}
+ local function make_block(section, str)
+ return string.format(">>===== %s =====>>\n%s\n<<===== %s =====<<\n", string.upper(section), str, string.upper(section))
+ end
+ for _, section in ipairs({"mode", "description", "result", "bibliography_result", "citations", "citation-items", "csl", "input", "version"}) do
+ if not (section == "bibliography_result" and fixture[section] == "") then
+ table.insert(fixture_output, make_block(section, fixture[section]))
+ end
+ end
+ local fixture_str = table.concat(fixture_output, "\n\n")
+
+ local file_name = string.format("%s.txt", tex.jobname)
+ if self.index > 0 then
+ file_name = string.format("%s-%d.txt", tex.jobname, self.index)
+ end
+
+ local fixture_file = io.open(file_name, "w")
+ if fixture_file then
+ fixture_file:write(fixture_str)
+ fixture_file:close()
+ else
+ error(string.format("Failed to write fixture file '%s'", file_name))
+ end
+end
+
+
+---@class CslCitationManager
+---@field global_ref_section RefSection
+---@field max_ref_section_index integer
+---@field ref_section_index integer
+---@field ref_sections table<integer, RefSection>
+---@field ref_section RefSection
+---@field hyperref_loaded boolean
+---@field regression_test boolean
+local CslCitationManager = {}
+
+---@return CslCitationManager
+function CslCitationManager:new()
+ local ref_section = RefSection:new()
+ ---@type CslCitationManager
+ local o = {
+ -- global_style_id = "apa",
+ -- global_bib_resources = {},
+ -- global_lang = nil,
+ global_ref_section = ref_section,
+ max_ref_section_index = 0,
+ ref_section_index = 0,
+ ref_sections = {
+ [0] = ref_section,
+ },
+ ref_section = ref_section,
+
+ hyperref_loaded = false,
+ regression_test = false,
+ }
+
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+--- The init method is called via \AtBeginDocument after loading .aux file.
+--- The ref_section.cited_ids are already registered.
+---@param style_id StyleId
+---@param bib_resources_str FilePathsString
+---@param lang LanguageCode?
+function CslCitationManager:init(style_id, bib_resources_str, lang)
+ local global_ref_section = self.global_ref_section
+ global_ref_section.style_id = "apa"
+ if style_id and style_id ~= "" then
+ global_ref_section.style_id = style_id
+ end
+ global_ref_section.bib_resources = util.split(util.strip(bib_resources_str), "%s*,%s*")
+ if lang and lang ~= "" then
+ global_ref_section.lang = lang
+ end
+
+ global_ref_section:make_citeproc_engine()
+ if self.hyperref_loaded then
+ global_ref_section.engine:enable_linking()
+ end
+ if self.regression_test then
+ self.global_ref_section:record_fixture()
+ end
+
+ self.ref_section_index = 0
+end
+
+
+function CslCitationManager:get_style_class()
+ if not self.ref_section then
+ return nil
+ end
+ if self.ref_section.engine then
+ return self.ref_section.engine:get_style_class()
+ else
+ return nil
+ end
+end
+
+---@alias FilePathsString string
+
+---@param style_id string?
+---@param bib_resources_str FilePathsString?
+---@param lang LanguageCode?
+function CslCitationManager:begin_ref_section(style_id, bib_resources_str, lang)
+ self.max_ref_section_index = self.max_ref_section_index + 1
+ self.ref_section_index = self.max_ref_section_index
+ self.ref_section = self.ref_sections[self.ref_section_index]
+ if not self.ref_section then
+ self.ref_section = RefSection:new()
+ self.ref_section.index = self.ref_section_index
+ self.ref_sections[self.ref_section_index] = self.ref_section
+ end
+
+ self.ref_section.style_id = style_id or self.global_ref_section.style_id
+ self.ref_section.bib_resources = self.global_ref_section.bib_resources
+ if bib_resources_str and bib_resources_str ~= "" then
+ self.ref_section.bib_resources = util.split(util.strip(bib_resources_str), "%s*,%s*")
+ end
+ self.ref_section.lang = self.global_ref_section.lang
+ if lang and lang ~= "" then
+ self.ref_section.lang = lang
+ end
+ -- self.ref_section.force_lang = force_lang or false
+
+ self.ref_section:make_citeproc_engine()
+
+ if self.hyperref_loaded then
+ self.ref_section.engine:enable_linking()
+ end
+
+ if self.regression_test then
+ self.ref_section:record_fixture()
+ end
+
+end
+
+
+function CslCitationManager:end_ref_section()
+ self.ref_section_index = 0
+ self.ref_section = self.ref_sections[0]
+end
+
+
+---This method is called from the `\csl@aux@cite` command from `.aux` file.
+---@param ref_section_index_str string
+---@param citation_info string
+function CslCitationManager:register_citation_info(ref_section_index_str, citation_info)
+ local ref_section_index = tonumber(ref_section_index_str)
+ if not ref_section_index then
+ util.error(string.format("Invalid refsetion index '%s'", ref_section_index_str))
+ return
+ end
+ local ref_section = self.ref_sections[ref_section_index]
+ if not ref_section then
+ ref_section = RefSection:new()
+ self.ref_sections[ref_section_index] = ref_section
+ ref_section.index = ref_section_index
+ end
+
+ local citation = self:_make_citation(citation_info)
+
+ for _, cite_item in ipairs(citation.citationItems) do
+ if citation.citationID == "@nocite" then
+ table.insert(ref_section.uncited_ids, cite_item.id)
+ else
+ table.insert(ref_section.cited_ids, cite_item.id)
+ end
+ end
+end
+
+function CslCitationManager:enable_linking()
+ self.hyperref_loaded = true
+ if self.ref_section.engine then
+ self.ref_section.engine:enable_linking()
+ end
+end
+
+
+---@param citation_info string
+function CslCitationManager:cite(citation_info)
+ if not self.ref_section then
+ util.error("Refsection is not initialized.")
+ return
+ end
+ local engine = self.ref_section.engine
+ if not engine then
+ util.error("CSL engine is not initialized.")
+ return
+ end
+
+ -- util.debug(citation_info)
+ local citation = self:_make_citation(citation_info)
+ -- util.debug(citation)
+
+ table.insert(self.ref_section.citations, citation)
+
+ local citation_str
+ -- if preview_mode then
+ -- -- TODO: preview mode in first pass of \blockquote of csquotes
+ -- -- citation_str = engine:preview_citation(citation)
+ -- citation_str = ""
+ -- else
+ citation_str = engine:process_citation(citation)
+ -- end
+ -- util.debug(citation_str)
+
+ -- tex.sprint(citation_str)
+ -- tex.setcatcode(35, 12) -- #
+ -- tex.setcatcode(37, 12) -- %
+ -- token.set_macro("l__csl_citation_tl", citation_str)
+ -- Don't use `token.set_macro`.
+ -- See <https://github.com/zepinglee/citeproc-lua/issues/42>
+ -- and <https://tex.stackexchange.com/questions/519954/backslashes-in-macros-defined-in-lua-code>.
+ tex.sprint(string.format("\\expandafter\\def\\csname l__csl_citation_tl\\endcsname{%s}", citation_str))
+
+ if self.regression_test then
+ table.insert(self.ref_section.fixture.citation_results, citation_str)
+ self.ref_section:record_fixture()
+ end
+
+ table.insert(self.ref_section.citations_pre, {citation.citationID, citation.properties.noteIndex})
+end
+
+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
+ return t
+end
+
+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
+
+---@param citation_info string
+---@return CitationData
+function CslCitationManager:_make_citation(citation_info)
+ -- `citation_info`: "citationID={ITEM-1@2},citationItems={{id={ITEM-1},label={page},locator={6}}},properties={noteIndex={3}}"
+ -- util.debug(citation_info)
+ 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
+ local citation_item = parse_latex_prop(item)
+ if citation_item.prefix then
+ -- util.debug(citation_item.prefix)
+ citation_item.prefix = latex_parser.latex_to_pseudo_html(citation_item.prefix, true, false)
+ -- util.debug(citation_item.prefix)
+ end
+ if citation_item.suffix then
+ citation_item.suffix = latex_parser.latex_to_pseudo_html(citation_item.suffix, true, false)
+ end
+ citation.citationItems[i] = citation_item
+ end
+
+ 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
+
+ local chapter_index = citation.properties.chapterIndex
+ if not chapter_index or chapter_index == "" then
+ citation.properties.chapterIndex = nil
+ elseif type(chapter_index) == "string" and string.match(chapter_index, "^%d+$") then
+ citation.properties.chapterIndex = tonumber(chapter_index)
+ else
+ util.error(string.format("Invalid chapter index '%s'.", chapter_index))
+ end
+
+ if citation.properties.prefix then
+ citation.properties.prefix = latex_parser.latex_to_pseudo_html(citation.properties.prefix, true, false)
+ end
+ if citation.properties.suffix then
+ citation.properties.suffix = latex_parser.latex_to_pseudo_html(citation.properties.suffix, true, false)
+ end
+
+ -- util.debug(citation)
+ return citation
+end
+
+---@param ids_string string The list of item IDs separated by commas
+function CslCitationManager:nocite(ids_string)
+ local uncited_ids = util.split(util.strip(ids_string), "%s*,%s*")
+
+ local engine = self.ref_section.engine
+ if not engine then
+ for _, id in ipairs(uncited_ids) do
+ table.insert(self.ref_section.uncited_ids, id)
+ end
+ return
+ end
+
+ for _, id in ipairs(uncited_ids) do
+ if id == "*" then
+ for _, item in ipairs(self.ref_section.items) do
+ table.insert(self.ref_section.uncited_ids, item.id)
+ end
+ break
+ else
+ table.insert(self.ref_section.uncited_ids, id)
+ end
+ end
+ engine:updateUncitedItems(self.ref_section.uncited_ids)
+end
+
+
+---@param filter_str string
+function CslCitationManager:bibliography(filter_str)
+ if not self.ref_section then
+ util.error("Refsection is not initialized.")
+ return
+ end
+ local bib_lines = self:make_bibliography(filter_str)
+ tex.print(util.split(table.concat(bib_lines, "\n"), "\n"))
+
+ if self.regression_test then
+ self.ref_section.fixture.bibliography_result = table.concat(bib_lines, "\n")
+ self.ref_section:record_fixture()
+ end
+end
+
+---@param filter_str string
+---@return string[]
+function CslCitationManager:make_bibliography(filter_str)
+ local engine = self.ref_section.engine
+ if not engine then
+ util.error("CSL engine is not initialized.")
+ return {}
+ end
+ local filter
+ local options = {}
+ if filter_str and filter_str ~= "" then
+ options = latex_parser.parse_prop(filter_str)
+ filter = self:_parser_filter(filter_str)
+ -- util.debug(filter)
+ end
+ local result = engine:makeBibliography(filter)
+
+ local params = result[1]
+ local bib_items = result[2]
+
+ ---@type table<string, any>
+ local bib_options = {
+ index = options.index or "1"
+ }
+
+ local bib_option_map = {
+ ["second-field-align"] = "second-field-align",
+ ["hanging-indent"] = "hangingindent",
+ ["entry-spacing"] = "entryspacing",
+ ["line-spacing"] = "linespacing",
+ ["widest-label"] = "widest_label",
+ }
+ local bib_option_order = {
+ "index",
+ "second-field-align",
+ "hanging-indent",
+ "line-spacing",
+ "entry-spacing",
+ "widest-label",
+ }
+
+ for option, param in pairs(bib_option_map) do
+ if params[param] then
+ bib_options[option] = params[param]
+ end
+ end
+
+ local bib_option_list = {}
+ for _, option in ipairs(bib_option_order) do
+ local value = bib_options[option]
+ if value and value ~= "" then
+ table.insert(bib_option_list, string.format("%s = %s", option, tostring(value)))
+ end
+ end
+ local bib_options_str = table.concat(bib_option_list, ", ")
+
+ local bibstart = string.format("\\begin{thebibliography}{%s}\n", bib_options_str)
+ local bib_lines = {}
+ table.insert(bib_lines, bibstart)
+
+ for _, bib_item in ipairs(bib_items) do
+ table.insert(bib_lines, bib_item)
+ end
+
+ if params.bibend then
+ table.insert(bib_lines, params.bibend)
+ end
+ return bib_lines
+end
+
+function CslCitationManager:set_categories(categories_str)
+ if self.ref_section.engine then
+
+ local category_dict = latex_parser.parse_prop(categories_str)
+ for category, keys in pairs(category_dict) do
+ category_dict[category] = latex_parser.parse_seq(keys)
+ end
+ for category, keys in pairs(category_dict) do
+ for _, key in ipairs(keys) do
+ local item = self.ref_section.engine.registry.registry[key]
+ if item then
+ if not item.categories then
+ -- TODO: Extend ItemData field types
+ item.categories = {}
+ end
+ if not util.in_list(category, item.categories) then
+ table.insert(item.categories, category)
+ end
+ else
+ util.error(string.format("Invalid citation key '%s'.", key))
+ end
+ end
+ end
+ end
+end
+
+local command_info = {
+ {"\\csl@aux@style", 2},
+ {"\\csl@aux@data", 2},
+ {"\\csl@aux@cite", 2},
+ {"\\csl@aux@options", 2},
+ {"\\csl@aux@bibliography", 2},
+ {"\\@input", 1},
+}
+
+local balanced = lpeg.P{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" }
+
+---@param text string
+---@param num_args integer?
+---@return string[]
+local function get_command_arguments(text, command, num_args)
+ num_args = num_args or 1
+ local grammar = lpeg.P(command) * lpeg.Ct((lpeg.S(" \t\r\n")^0 * lpeg.C(balanced))^num_args)
+ local arguments = grammar:match(text)
+ if not arguments then
+ return {}
+ end
+ ---@cast arguments string[]
+ for i, argument in ipairs(arguments) do
+ arguments[i] = string.sub(argument, 2, -2)
+ end
+ return arguments
+end
+
+---Convert to a filter object described in
+--- <https://citeproc-js.readthedocs.io/en/latest/running.html#selective-output-with-makebibliography>
+---@param filter_str string e.g., "type={book},notcategory={csl},notcategory={tex}"
+---@return table
+function CslCitationManager:_parser_filter(filter_str)
+ local conditions = {}
+ for i, condition in ipairs(latex_parser.parse_seq(filter_str)) do
+ local negative
+ local field, value = string.match(condition, "(%w+)%s*=%s*{([^}]+)}")
+ if field then
+ if string.match(field, "^not") then
+ negative = true
+ field = string.gsub(field, "^not", "")
+ end
+ if field == "category" then
+ field = "categories"
+ end
+ if field == "keyword" or field == "type" or field == "categories" then
+ table.insert(conditions, {
+ field = field,
+ value = value,
+ negative = negative,
+ })
+ end
+ end
+ end
+ -- util.debug(conditions)
+ return {select = conditions}
+end
+
+
+
+---@param aux_content string
+---@return string
+function CslCitationManager:read_aux_file(aux_content)
+ local command_arguments = self:_get_csl_commands(aux_content)
+
+ -- First pass, only register infomation
+ for _, command_argument in ipairs(command_arguments) do
+ local command, ref_section_index, content = table.unpack(command_argument)
+
+ local ref_section = self.ref_sections[ref_section_index]
+ self.ref_section = ref_section
+ if not ref_section then
+ ref_section = RefSection:new()
+ self.ref_sections[ref_section_index] = ref_section
+ ref_section.index = ref_section_index
+ self.ref_section = ref_section
+ end
+ if command == "\\csl@aux@style" then
+ ref_section.style_id = content
+ elseif command == "\\csl@aux@data" then
+ util.extend(ref_section.bib_resources, util.split(content, "%s*,%s*"))
+ elseif command == "\\csl@aux@cite" then
+ self:register_citation_info(tostring(ref_section_index), content)
+ -- TODO: refsection bib resources
+ -- elseif command == "\\csl@aux@bibliography" then
+ -- -- table.insert(ref_section.bibliography_configs, content)
+ end
+ end
+
+ local global_style = self.global_ref_section.style_id
+ if global_style and global_style ~= "" then
+ util.info(string.format("Global style file: %s.csl", global_style))
+ else
+ util.warning("Missing global style name. Will use default APA style.")
+ self.global_ref_section.style_id = "apa"
+ end
+
+ -- if #citations == 0 then
+ -- util.error(string.format("No citation commands in file %s", aux_file))
+ -- end
+
+ -- if #bib_files == 0 then
+ -- util.warning("empty bibliography data files")
+ -- else
+ -- for i, bib_file in ipairs(bib_files) do
+ -- util.info(string.format("Database file #%d: %s", i, bib_file))
+ -- end
+ -- end
+
+ -- Second pass, only register infomation
+ local output_lines = {}
+ for _, command_argument in ipairs(command_arguments) do
+ local command, ref_section_index, content = table.unpack(command_argument)
+
+ local ref_section = self.ref_sections[ref_section_index]
+ assert(ref_section)
+ self.ref_section = ref_section
+
+ if command == "\\csl@aux@cite" then
+ if not ref_section.engine then
+ if not ref_section.style_id or ref_section.style_id == "" then
+ ref_section.style_id = self.global_ref_section.style_id
+ end
+ if #ref_section.bib_resources == 0 then
+ ref_section.bib_resources = self.global_ref_section.bib_resources
+ end
+ if not ref_section.lang or ref_section.lang == "" then
+ ref_section.lang = self.global_ref_section.lang
+ end
+ ref_section:make_citeproc_engine()
+ if self.hyperref_loaded then
+ ref_section.engine:enable_linking()
+ end
+ local style_class = ref_section.engine:get_style_class()
+ local style_class_setup = string.format("\\csloptions{%d}{class = {%s = %s}}", ref_section_index, ref_section.style_id, style_class)
+ table.insert(output_lines, style_class_setup)
+ end
+ self:register_citation_info(tostring(ref_section_index), content)
+ if ref_section.engine then
+ local citation = self:_make_citation(content)
+ if citation.citationID == "@nocite" then
+ ref_section:_update_uncited_items()
+ else
+ local citation_str = ref_section.engine:process_citation(citation)
+ table.insert(output_lines, string.format("\\cslcitation{%s}{%s}", citation.citationID, citation_str))
+ end
+ end
+
+ elseif command == "\\csl@aux@bibliography" then
+ if not ref_section.engine then
+ ref_section:make_citeproc_engine()
+ end
+ if ref_section.engine then
+ local bib_lines = self:make_bibliography(content)
+ table.insert(output_lines, "")
+ util.extend(output_lines, bib_lines)
+ table.insert(output_lines, "")
+ end
+
+ elseif command == "\\csl@aux@options" then
+ local options = latex_parser.parse_prop(content)
+ if options.categories then
+ self:set_categories(options.categories)
+ end
+ if options.locale and options.locale ~= "" then
+ ref_section.lang = options.locale
+ end
+ -- TODO: == "true"?
+ if options.linking then
+ self.hyperref_loaded = true
+ end
+ end
+ end
+ return table.concat(output_lines, "\n") .. "\n"
+end
+
+---@param aux_content string
+---@return [string, integer, string][]
+function CslCitationManager:_get_csl_commands(aux_content)
+ ---@type [string, integer, string][]
+ local command_arguments = {}
+ for _, line in ipairs(util.split(aux_content, "%s*\n")) do
+ for _, command_argment in ipairs(command_info) do
+ local command, num_args = table.unpack(command_argment)
+ if util.startswith(line, command) then
+ local arguments = get_command_arguments(line, command, num_args)
+ if command == "\\@input" then
+ local sub_aux_file = arguments[1]
+ self:read_aux_file(sub_aux_file)
+ else
+ local ref_section_index = tonumber(arguments[1])
+ if not ref_section_index then
+ util.error(string.format("Invalid refsection index '%s'.", ref_section_index))
+ return {}
+ end
+ local content = util.strip(arguments[2])
+ table.insert(command_arguments, {command, ref_section_index, content})
+ end
+ break
+
+ end
+ end
+ end
+ return command_arguments
+end
+
+
+citeproc_manager.CslCitationManager = CslCitationManager
+
+return citeproc_manager
diff --git a/biblio/citation-style-language/citeproc-node-bibliography.lua b/biblio/citation-style-language/citeproc-node-bibliography.lua
index d9e868c4e0..35817f7284 100644
--- a/biblio/citation-style-language/citeproc-node-bibliography.lua
+++ b/biblio/citation-style-language/citeproc-node-bibliography.lua
@@ -118,7 +118,6 @@ function Bibliography:build_bibliography_str(id, engine)
context.style = engine.style
context.area = self
context.in_bibliography = true
- -- context.locale = engine:get_locale(engine.lang)
context.name_inheritance = self.name_inheritance
context.format = output_format
context.id = id
@@ -127,6 +126,7 @@ function Bibliography:build_bibliography_str(id, engine)
-- CSL-M: `layout` extension
local active_layout, context_lang = util.get_layout_by_language(self, engine, context.reference)
+ context.lang = context_lang
context.locale = engine:get_locale(context_lang)
local ir = self:build_ir(engine, state, context, active_layout)
diff --git a/biblio/citation-style-language/citeproc-node-choose.lua b/biblio/citation-style-language/citeproc-node-choose.lua
index b3c827dc62..cb1bd77d79 100644
--- a/biblio/citation-style-language/citeproc-node-choose.lua
+++ b/biblio/citation-style-language/citeproc-node-choose.lua
@@ -253,8 +253,8 @@ function If:evaluate_condition(condition, state, context)
local variable = condition.value
local variable_type = util.variable_types[variable] or "standard"
- if variable_type ~= "standard" and variable_type ~= "number" then
- util.warning(string.format('Expecting number variable for condition "is-numeric", got %s "%s"', variable_type, variable))
+ if variable_type ~= "standard" and variable_type ~= "number" then
+ util.warning(string.format("Expecting number variable for condition 'is-numeric', got %s '%s'", variable_type, variable))
return false
end
@@ -263,7 +263,7 @@ function If:evaluate_condition(condition, state, context)
return false
end
if type(value) ~= "string" and type(value) ~= "number" then
- util.error(string.format('Expecting a string or number for variable "%s", got "%s"', variable, type(value)))
+ util.error(string.format("Expecting a string or number for variable '%s', got '%s'", variable, type(value)))
end
return util.is_numeric(value)
@@ -273,7 +273,7 @@ function If:evaluate_condition(condition, state, context)
local variable_type = util.variable_types[variable] or "standard"
if variable_type ~= "date" then
- util.warning(string.format('Expecting date variable for condition "is-uncertain-date", got "%s"', variable_type, variable))
+ util.warning(string.format("Expecting date variable for condition 'is-uncertain-date', got '%s'", variable_type, variable))
return false
end
local value = context:get_variable(variable)
@@ -283,6 +283,10 @@ function If:evaluate_condition(condition, state, context)
return self:is_uncertain_date(value)
elseif condition.condition == "locator" then
+ local locator = context:get_variable("locator")
+ if not locator or locator == "" then
+ return false
+ end
local locator_label = context:get_variable("label")
if locator_label == "sub verbo" then
locator_label = "sub-verbo"
diff --git a/biblio/citation-style-language/citeproc-node-citation.lua b/biblio/citation-style-language/citeproc-node-citation.lua
index 45e1335b30..183d9f6807 100644
--- a/biblio/citation-style-language/citeproc-node-citation.lua
+++ b/biblio/citation-style-language/citeproc-node-citation.lua
@@ -41,6 +41,7 @@ local Micro = output.Micro
local Formatted = output.Formatted
local PlainText = output.PlainText
local InlineElement = output.InlineElement
+local UndefinedCite = output.UndefinedCite
local CiteInline = output.CiteInline
local DisamStringFormat = output.DisamStringFormat
local SortStringFormat = output.SortStringFormat
@@ -177,24 +178,18 @@ end
---@alias CiteId string | number
----@class CitationItem
----@field id CiteId
----@field prefix string?
----@field suffix string?
----@field locator string?
----@field label string?
----@field prefix_inlines InlineElement[]?
----@field suffix_inlines InlineElement[]?
-
---comment
---@param citation_items CitationItem[]
---@param engine CiteProc
----@param properties table
+---@param properties CitationProperties
---@return string
function Citation:build_cluster(citation_items, engine, properties)
properties = properties or {}
local output_format = engine.output_format
+ ---@type CiteIr[]
local irs = {}
+ -- The citation_items are already sorted when evaluate the positions
+ -- To be removed
citation_items = self:sorted_citation_items(citation_items, engine)
for _, cite_item in ipairs(citation_items) do
local ir = self:build_fully_disambiguated_ir(cite_item, output_format, engine, properties)
@@ -226,7 +221,7 @@ function Citation:build_cluster(citation_items, engine, properties)
-- if layout_affixes then
-- layout_prefix = layout_affixes.prefix
-- end
- local prefix_inlines = citation_items[i].prefix_inlines
+ local prefix_inlines = ir.cite_prefix
if prefix_inlines then
-- Prefix is inlines
local prefix_str = output.SortStringFormat:new():output(prefix_inlines, context)
@@ -254,14 +249,15 @@ function Citation:build_cluster(citation_items, engine, properties)
context.style = engine.style
context.area = self
context.in_bibliography = false
+ context.lang = engine.lang
context.locale = engine:get_locale(engine.lang)
context.name_inheritance = self.name_inheritance
context.format = output_format
local previous_ir
for i, ir in ipairs(irs) do
- local cite_prefix = citation_items[i].prefix_inlines
- local cite_suffix = citation_items[i].suffix_inlines
+ local cite_prefix = ir.cite_prefix
+ local cite_suffix = ir.cite_suffix
if not ir.collapse_suppressed then
local cite_inlines = ir:flatten(output_format)
if #cite_inlines > 0 then
@@ -327,14 +323,28 @@ function Citation:build_cluster(citation_items, engine, properties)
has_printed_form = false
end
+ -- Ouput citation affixes
+ if has_printed_form then
+ if properties.prefix and properties.prefix ~= "" then
+ local citation_prefix = util.check_prefix_space_append(properties.prefix)
+ local inlines = InlineElement:parse(citation_prefix, context, true)
+ table.insert(citation_stream, 1, Micro:new(inlines))
+ end
+ if properties.suffix and properties.suffix ~= "" then
+ local citation_suffix = util.check_suffix_prepend(properties.suffix)
+ local inlines = InlineElement:parse(citation_suffix, context, true)
+ table.insert(citation_stream, Micro:new(inlines))
+ end
+ end
+
local author_only_mode = (properties.mode == "author-only" or
(#citation_items >= 1 and citation_items[1]["author-only"]))
if has_printed_form and context.area.layout.affixes and not author_only_mode then
- if irs[1].cite_prefix then
- table.insert(citation_stream, 1, PlainText:new(irs[1].cite_prefix))
+ if irs[1].layout_prefix then
+ table.insert(citation_stream, 1, PlainText:new(irs[1].layout_prefix))
end
- if irs[#irs].cite_suffix then
- table.insert(citation_stream, PlainText:new(irs[#irs].cite_suffix))
+ if irs[#irs].layout_suffix then
+ table.insert(citation_stream, PlainText:new(irs[#irs].layout_suffix))
end
end
@@ -393,6 +403,7 @@ function Citation:sorted_citation_items(items, engine)
context.style = engine.style
context.area = self
context.in_bibliography = false
+ context.lang = engine.lang
context.locale = engine:get_locale(engine.lang)
context.name_inheritance = self.name_inheritance
context.format = SortStringFormat:new()
@@ -413,13 +424,15 @@ end
---@field disam_level integer
---@field disam_str string?
---@field cite_delimiter string?
----@field cite_prefix string?
----@field cite_suffix string?
+---@field layout_prefix string?
+---@field layout_suffix string?
+---@field cite_prefix InlineElement[]?
+---@field cite_suffix InlineElement[]?
---@param cite_item CitationItem
---@param output_format OutputFormat
---@param engine CiteProc
----@param properties table
+---@param properties CitationProperties
---@return CiteIr
function Citation:build_fully_disambiguated_ir(cite_item, output_format, engine, properties)
-- util.debug(cite_item.id)
@@ -433,12 +446,14 @@ function Citation:build_fully_disambiguated_ir(cite_item, output_format, engine,
-- Disambiguation should be based on the subsequent form
-- disambiguate_BasedOnEtAlSubsequent.txt
cite_item.position_level = Position.Subsequent
+ cite_item["first-reference-note-number"] = properties.noteIndex
local disam_ir = self:build_ambiguous_ir(cite_item, output_format, engine)
disam_ir = self:apply_disambiguate_add_givenname(disam_ir, engine)
disam_ir = self:apply_disambiguate_add_names(disam_ir, engine)
disam_ir = self:apply_disambiguate_conditionals(disam_ir, engine)
disam_ir = self:apply_disambiguate_add_year_suffix(disam_ir, engine)
cite_item.position_level = Position.First
+ cite_item["first-reference-note-number"] = nil
end
return cite_ir
@@ -455,7 +470,6 @@ function Citation:build_ambiguous_ir(cite_item, output_format, engine)
context.engine = engine
context.style = engine.style
context.area = self
- -- context.locale = engine:get_locale(engine.lang)
context.name_inheritance = self.name_inheritance
context.format = output_format
context.id = cite_item.id
@@ -464,13 +478,14 @@ function Citation:build_ambiguous_ir(cite_item, output_format, engine)
context.reference = engine.registry.registry[cite_item.id]
local active_layout, context_lang = util.get_layout_by_language(self, engine, context.reference)
+ context.lang = context_lang
context.locale = engine:get_locale(context_lang)
local ir
if context.reference then
ir = self:build_ir(engine, state, context, active_layout)
else
- ir = Rendered:new({Formatted:new({PlainText:new(tostring(cite_item.id))}, {["font-weight"] = "bold"})}, self)
+ ir = Rendered:new({UndefinedCite:new({PlainText:new(tostring(cite_item.id))}, cite_item)}, self)
end
ir.cite_item = cite_item
@@ -482,8 +497,17 @@ function Citation:build_ambiguous_ir(cite_item, output_format, engine)
ir.cite_delimiter = active_layout.delimiter
if active_layout.affixes then
- ir.cite_prefix = active_layout.affixes.prefix
- ir.cite_suffix = active_layout.affixes.suffix
+ ir.layout_prefix = active_layout.affixes.prefix
+ ir.layout_suffix = active_layout.affixes.suffix
+ end
+
+ if cite_item.prefix and cite_item.prefix ~= "" then
+ local cite_prefix = util.check_prefix_space_append(cite_item.prefix)
+ ir.cite_prefix = InlineElement:parse(cite_prefix, context, true)
+ end
+ if cite_item.suffix and cite_item.suffix ~= "" then
+ local cite_suffix = util.check_suffix_prepend(cite_item.suffix)
+ ir.cite_suffix = InlineElement:parse(cite_suffix, context, true)
end
-- Formattings like font-style are ignored for disambiguation.
@@ -1007,7 +1031,6 @@ function Citation:apply_disambiguate_conditionals(cite_ir, engine)
-- Update ir output
local inlines = ir_:flatten(disam_format)
local disam_str = disam_format:output(inlines, nil)
- -- util.debug("update: " .. ir_.cite_item.id .. ": " .. disam_str)
ir_.disam_str = disam_str
if not engine.cite_irs_by_output[disam_str] then
engine.cite_irs_by_output[disam_str] = {}
diff --git a/biblio/citation-style-language/citeproc-node-names.lua b/biblio/citation-style-language/citeproc-node-names.lua
index cc5a21ca55..10781e1213 100644
--- a/biblio/citation-style-language/citeproc-node-names.lua
+++ b/biblio/citation-style-language/citeproc-node-names.lua
@@ -131,7 +131,7 @@ function Names:from_node(node)
child.after_name = true
end
else
- util.warning(string.format('Unknown element "%s".', element_name))
+ util.warning(string.format("Unknown element '%s'.", element_name))
end
end
o:get_delimiter_attribute(node)
diff --git a/biblio/citation-style-language/citeproc-node-number.lua b/biblio/citation-style-language/citeproc-node-number.lua
index b8a55d3c66..0be68cba0f 100644
--- a/biblio/citation-style-language/citeproc-node-number.lua
+++ b/biblio/citation-style-language/citeproc-node-number.lua
@@ -59,8 +59,9 @@ function Number:build_ir(engine, state, context)
local number
if not state.suppressed[self.variable] then
number = context:get_variable(self.variable, self.form)
+ ---@cast number string | number?
end
- if not number then
+ if not number or number == "" then
local ir = Rendered:new({}, self)
ir.group_var = GroupVar.Missing
return ir
diff --git a/biblio/citation-style-language/citeproc-node-sort.lua b/biblio/citation-style-language/citeproc-node-sort.lua
index e97b378bf0..262d11edae 100644
--- a/biblio/citation-style-language/citeproc-node-sort.lua
+++ b/biblio/citation-style-language/citeproc-node-sort.lua
@@ -77,7 +77,7 @@ function Sort:sort(items, state, context)
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))
+ util.warning(string.format("Locale '%s' is not provided by lua-uca. The sorting order may be incorrect.", lang))
end
end
end
diff --git a/biblio/citation-style-language/citeproc-node-style.lua b/biblio/citation-style-language/citeproc-node-style.lua
index e4e4b7ba8c..d910dfdc4f 100644
--- a/biblio/citation-style-language/citeproc-node-style.lua
+++ b/biblio/citation-style-language/citeproc-node-style.lua
@@ -50,6 +50,7 @@ local DisamStringFormat = output.DisamStringFormat
---@field citation Citation
---@field intext Citation?
---@field bibliography Bibliography?
+---@field full_citation Citation This is used for the `\fullcite` command.
---@field has_disambiguate boolean
local Style = Element:derive("style")
@@ -133,6 +134,8 @@ function Style:from_node(node)
end
end
+ o.full_citation = Style._make_full_citation(o.citation, o.bibliography)
+
o.has_disambiguate = false
if #node:query_selector('[disambiguate="true"]') > 0 then
o.has_disambiguate = true
@@ -148,6 +151,74 @@ Style._default_options = {
["demote-non-dropping-particle"] = "display-and-sort",
}
+local function remove_display_attribute(element)
+ if not element.children then
+ return
+ end
+ for i = #element.children, 1, -1 do
+ local child = element.children[i]
+ if child.display == "left-margin" then
+ table.remove(element.children, i)
+ elseif child.display then
+ child.display = nil
+ remove_display_attribute(child)
+ else
+ remove_display_attribute(child)
+ end
+ end
+end
+
+--- This is used for the `\fullcite` command.
+---@param citation Citation
+---@param bibliography Bibliography
+function Style._make_full_citation(citation, bibliography)
+ if not citation then
+ return nil
+ end
+ local full_citation = util.clone(citation)
+
+ full_citation.cite_group_delimiter = nil
+ full_citation.cite_grouping = false
+ full_citation.collapse = nil
+
+ if not bibliography then
+ full_citation.children = {}
+ full_citation.layout = nil
+ full_citation.layouts_by_language = {}
+ return full_citation
+ end
+
+ full_citation.name_inheritance = bibliography.name_inheritance
+ full_citation.children = util.deep_copy(bibliography.children)
+ if bibliography.second_field_align then
+ for _, child in ipairs(full_citation.children) do
+ if child.element_name == "layout" then
+ if #child.children > 1 then
+ table.remove(child.children, 1)
+ end
+ end
+ end
+ end
+ remove_display_attribute(full_citation)
+ full_citation.layout = nil
+ full_citation.layouts_by_language = {}
+ for _, child in ipairs(full_citation.children) do
+ local element_name = child.element_name
+ if element_name == "layout" then
+ if child.locale then
+ for _, lang in ipairs(util.split(util.strip(child.locale))) do
+ full_citation.layouts_by_language[lang] = child
+ end
+ else
+ full_citation.layout = child
+ end
+ elseif element_name == "sort" then
+ full_citation.sort = child
+ end
+ end
+
+ return full_citation
+end
---@class Info: Element
---@field author table?
diff --git a/biblio/citation-style-language/citeproc-node-text.lua b/biblio/citation-style-language/citeproc-node-text.lua
index 99b20f8142..9e15bd358b 100644
--- a/biblio/citation-style-language/citeproc-node-text.lua
+++ b/biblio/citation-style-language/citeproc-node-text.lua
@@ -86,6 +86,7 @@ function Text:build_ir(engine, state, context)
if self.variable then
ir = self:build_variable_ir(engine, state, context)
elseif self.macro then
+ -- util.debug(self.macro)
ir = self:build_macro_ir(engine, state, context)
elseif self.term then
ir = self:build_term_ir(engine, state, context)
@@ -108,9 +109,10 @@ function Text:build_variable_ir(engine, state, context)
if not state.suppressed[variable] then
text = context:get_variable(variable, self.form)
+ ---@case text string | number?
end
- if not text then
+ if not text or text == "" then
local ir = Rendered:new({}, self)
ir.group_var = GroupVar.Missing
return ir
@@ -227,7 +229,12 @@ function Text:build_citation_label_ir(engine, state, context)
end
function Text:build_macro_ir(engine, state, context)
+ ---@type Macro
local macro = context:get_macro(self.macro)
+ if not macro then
+ util.error(string.format("Macro '%s' not found", self.macro))
+ return nil
+ end
-- util.debug(string.format('<macro name="%s">', self.macro))
state:push_macro(self.macro)
local ir = macro:build_ir(engine, state, context)
diff --git a/biblio/citation-style-language/citeproc-output.lua b/biblio/citation-style-language/citeproc-output.lua
index 2b3661c9b1..79bd1220c0 100644
--- a/biblio/citation-style-language/citeproc-output.lua
+++ b/biblio/citation-style-language/citeproc-output.lua
@@ -93,19 +93,31 @@ function InlineElement:new(inlines)
end
-function InlineElement:_debug()
- local text = self._type .. "("
+function InlineElement:_debug(level)
+ level = level or 0
+ local text = ""
+ if level == 0 then
+ text = "\n"
+ end
+ text = text .. self._type
+ if self.formatting then
+ text = text .. " ["
+ for attr, value in pairs(self.formatting) do
+ text = text .. attr .. '="' .. value .. '"'
+ end
+ text = text .. "] "
+ end
+ if self.is_inner then
+ text = text .. " [inner quotes]"
+ end
+ text = text .. "("
if self.value then
text = text .. '"' .. self.value .. '"'
elseif self.inlines then
- local inlines_text = ""
for _, inline in ipairs(self.inlines) do
- if inlines_text ~= "" then
- inlines_text = inlines_text .. ", "
- end
- inlines_text = inlines_text .. inline:_debug()
+ text = text .. "\n" .. string.rep(" ", level + 1) .. inline:_debug(level + 1) .. ", "
end
- text = text .. inlines_text
+ text = text .. "\n" .. string.rep(" ", level)
end
text = text .. ")"
return text
@@ -158,16 +170,17 @@ end
---@class Quoted: InlineElement
---@field is_inner boolean
----@field quotes table
+---@field quotes LocalizedQuotes
local Quoted = InlineElement:derive("Quoted")
---@param inlines InlineElement[]
----@param localized_quotes table?
+---@param localized_quotes LocalizedQuotes?
+---@param is_inner boolean?
---@return Quoted
-function Quoted:new(inlines, localized_quotes)
+function Quoted:new(inlines, localized_quotes, is_inner)
local o = InlineElement.new(self)
o.inlines = inlines
- o.is_inner = false
+ o.is_inner = is_inner or false
if localized_quotes then
o.quotes = localized_quotes
else
@@ -292,6 +305,23 @@ function CiteInline:new(inlines, cite_item)
end
+---@class UndefinedCite: InlineElement
+---@field cite_item CitationItem
+local UndefinedCite = InlineElement:derive("UndefinedCite")
+
+---@param inlines InlineElement[]
+---@param cite_item CitationItem
+---@return UndefinedCite
+function UndefinedCite:new(inlines, cite_item)
+ local o = InlineElement.new(self)
+ o.inlines = inlines
+ o.cite_item = cite_item
+ setmetatable(o, self)
+ return o
+end
+
+
+
---@param text string
---@param context Context?
---@param is_external boolean?
@@ -384,224 +414,457 @@ function InlineElement:parse_csl_rich_text(text)
return inlines
end
-local function tokens2inlines(tokens)
- local inlines = {}
- local i = 1
- while i <= #tokens do
- local token = tokens[i]
- if type(token) == "string" then
- local text = token
- local j = i + 1
- while j <= #tokens and type(tokens[j]) == "string" do
- text = text .. tokens[j]
- j = j + 1
- end
- i = j
- table.insert(inlines, PlainText:new(text))
- else
- table.insert(inlines, token)
- i = i + 1
- end
- end
- return inlines
+
+local P = lpeg.P
+local Ct = lpeg.Ct
+local Cp = lpeg.Cp
+
+-- Lua's regex doesn't support groups and thus we have to implement the same
+-- logic with `lpeg`.
+local code_pattern =
+ Ct(Cp() * P("<code>") * Cp()) * ((1 - P("</code>")) ^ 0) *
+ Ct(Cp() * P("</code>") * Cp())
+ + Ct(Cp() * P("<script>") * Cp()) * ((1 - P("</script>")) ^ 0) *
+ Ct(Cp() * P("</script>") * Cp())
+ + Ct(Cp() * P("<pre>") * Cp()) * ((1 - P("</pre>")) ^ 0) *
+ Ct(Cp() * P("</pre>") * Cp())
+ + Ct(Cp() * P("<math>") * Cp()) * ((1 - P("</math>")) ^ 0) * Ct(Cp() * P("</math>") * Cp())
+ + Ct(Cp() * P("<math-tex>") * Cp()) * ((1 - P("</math-tex>")) ^ 0) * Ct(Cp() * P("</math-tex>") * Cp())
+local basic_tag_pattern = P '<span class="nocase">'
+ + P '<span class="nodecor">'
+ + P '<span style="font-variant:small-caps;">'
+ + P '<sc>'
+ + P '<i>'
+ + P '<b>'
+ + P '<sup>'
+ + P '<sub>'
+ + P ' "'
+ + P " '"
+ + P '("'
+ + P "('"
+ + P "“"
+ + P "‘"
+ + P '</span>'
+ + P '</sc>'
+ + P '</i>'
+ + P '</b>'
+ + P '</sup>'
+ + P '</sub>'
+ + P '"'
+ + P "'"
+ + P "”"
+ + P "’"
+
+local default_tag_pattern = Ct((code_pattern + Ct(Cp() * basic_tag_pattern * Cp()) + P(1)) ^ 0)
+
+local default_openers_info = {
+ ['<span class="nocase">'] = {
+ closer = "</span>",
+ quotes = false,
+ },
+ ['<span class="nodecor">'] = {
+ closer = "</span>",
+ quotes = false,
+ },
+ ['<span style="font-variant:small-caps;">'] = {
+ closer = "</span>",
+ quotes = false,
+ },
+ ['<sc>'] = {
+ closer = "</sc>",
+ quotes = false,
+ },
+ ['<i>'] = {
+ closer = "</i>",
+ quotes = false,
+ },
+ ['<b>'] = {
+ closer = "</b>",
+ quotes = false,
+ },
+ ['<sup>'] = {
+ closer = "</sup>",
+ quotes = false,
+ },
+ ['<sub>'] = {
+ closer = "</sub>",
+ quotes = false,
+ },
+ [' "'] = {
+ closer = '"',
+ quotes = true,
+ },
+ [" '"] = {
+ closer = "'",
+ quotes = true,
+ },
+ ["“"] = {
+ closer = "”",
+ quotes = true,
+ },
+ ["‘"] = {
+ closer = "’",
+ quotes = true,
+ },
+ ['<code>'] = {
+ closer = "</code>",
+ quotes = false,
+ },
+ ['<script>'] = {
+ closer = "</script>",
+ quotes = false,
+ },
+ ['<pre>'] = {
+ closer = "</pre>",
+ quotes = false,
+ },
+ ['<math>'] = {
+ closer = "</math>",
+ quotes = false,
+ },
+ ['<math-tex>'] = {
+ closer = "</math-tex>",
+ quotes = false,
+ },
+}
+
+local function _quoted(str)
+ str = string.gsub(str, "'", "\'")
+ return string.format("'%s'", str)
end
-local function get_inline_element_grammar()
- local P = lpeg.P
- local C = lpeg.C
- local Ct = lpeg.Ct
- local S = lpeg.S
- local V = lpeg.V
- local spaces = P(" ")^1
- local grammar = P{
- "content";
- token = V"italic" + V"bold" + V"sup" + V"sub" + V"sc" + V"small_caps" + V"span_nocase" + V"nodecor" + V"math_tex" + V"math_ml" + V"code" + V"script" + C(1),
- content = Ct((V"token")^0) / tokens2inlines,
- italic = P"<i>" * Ct((V"token" - P"</i>")^0) * P"</i>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["font-style"] = "italic"})
- end,
- bold = P"<b>" * Ct((V"token" - P"</b>")^0) * P"</b>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["font-weight"] = "bold"})
- end,
- sup = P"<sup>" * Ct((V"token" - P"</sup>")^0) * P"</sup>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["vertical-align"] = "sup"})
- end,
- sub = P"<sub>" * Ct((V"token" - P"</sub>")^0) * P"</sub>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["vertical-align"] = "sub"})
- end,
- sc = P"<sc>" * Ct((V"token" - P"</sc>")^0) * P"</sc>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["font-variant"] = "small-caps"})
- end,
- quoted = (
- C(P'"') * Ct((V"token" - P'"')^0) * C(P'"')
- + C(P"'") * Ct((V"token" - P"'")^0) * C(P"'")
- + C(P'“') * Ct((V"token" - P'”')^0) * C(P'”')
- + C(P"‘") * Ct((V"token" - P"’")^0) * C(P"’")
- + C(P"«") * Ct((V"token" - P"»")^0) * C(P"»")
- ) / function (open, tokens, close)
- return Quoted:new(tokens2inlines(tokens), LocalizedQuotes:new(open, close))
- end,
- small_caps = P"<span" * spaces * P'style="font-variant:' * spaces^0 * P'small-caps;">' * Ct((V"token" - P"</span>")^0) * P"</span>" / function (tokens)
- return Formatted:new(tokens2inlines(tokens), {["font-variant"] = "small-caps"})
- end,
- -- nocase = P"<nocase>" * Ct((V"token" - P"</nocase>")^0) * P"</nocase>" / function (tokens)
- -- return NoCase:new(tokens2inlines(tokens))
- -- end,
- span_nocase = P"<span" * spaces * P'class="nocase">' * Ct((V"token" - P"</span>")^0) * P"</span>" / function (tokens)
- return NoCase:new(tokens2inlines(tokens))
- end,
- nodecor = P"<span" * spaces * P'class="nodecor">' * Ct((V"token" - P"</span>")^0) * P"</span>" / function (tokens)
- return NoDecor:new(tokens2inlines(tokens))
- end,
- math_tex = P"<math-tex>" * C((1- P"</math-tex>")^0) * P"</math-tex>" / function (text)
- return MathTeX:new(text)
- end,
- math_ml = P"<math>" * C((1- P"</math>")^0) * P"</math>" / function (text)
- return MathML:new(text)
- end,
- code = P"<code>" * C((1 - P"</code>")^0) * P"</code>" / function (text)
- return Code:new(text)
- end,
- script = P"<script>" * C((1- P"</script>")^0) * P"</script>" / function (text)
- return Code:new(text)
- end,
+---@param locale string
+---@param context Context
+local function make_locale_tag_info(locale, context)
+ if context.engine.locale_tags_info_dict[locale] then
+ return
+ end
+ local localed_quotes = context:get_localized_quotes()
+
+ local tag_pattern = basic_tag_pattern
+ local openers_info = util.deep_copy(default_openers_info)
+
+ if localed_quotes.outer_open and localed_quotes.outer_close then
+ tag_pattern = tag_pattern + P(_quoted(localed_quotes.outer_open))
+ tag_pattern = tag_pattern + P(_quoted(localed_quotes.outer_close))
+
+ openers_info[localed_quotes.outer_open] = {
+ closer = localed_quotes.outer_close,
+ quotes = true,
+ inner = false
+ }
+ end
+
+ if localed_quotes.inner_open and localed_quotes.inner_close then
+ tag_pattern = tag_pattern + P(_quoted(localed_quotes.inner_open))
+ tag_pattern = tag_pattern + P(_quoted(localed_quotes.inner_close))
+
+ openers_info[localed_quotes.inner_open] = {
+ closer = localed_quotes.inner_close,
+ quotes = true,
+ inner = true
+ }
+ end
+
+ context.engine.locale_tags_info_dict[locale] = {
+ tag_pattern = Ct((code_pattern + Ct(Cp() * tag_pattern * Cp()) + P(1)) ^ 0),
+ openers_info = openers_info,
}
- return grammar
end
-local inline_element_grammar = get_inline_element_grammar()
----@param str string
+local straight_quotes_flip = {
+ [" '"] = ' "',
+ [' "'] = " '",
+};
+
+---@param str any
---@param context Context?
----@param is_external boolean?
----@return InlineElement[]
-function InlineElement:parse_html_tags(str, context, is_external)
- local inlines = inline_element_grammar:match(str)
- inlines = InlineElement:parse_quotes(inlines, context, is_external)
- return inlines
+---@return string[]
+---@return string[]
+local function split_tags_and_strings(str, context)
+ local tags = {}
+ local strings = {}
+
+ str = string.gsub(str, '(<span)%s+(style="font%-variant:)%s*(small%-caps);?"[^>]*(>)', '%1 %2%3;"%4');
+
+ str = string.gsub(str, '(<span)%s+(class="nocase")[^>]*(>)', "%1 %2%3");
+ str = string.gsub(str, '(<span)%s+(class="nodecor")[^>]*(>)', "%1 %2%3");
+
+ local tag_pattern = default_tag_pattern
+ local openers_info = default_openers_info
+ if context and context.lang then
+ tag_pattern = context.engine.locale_tags_info_dict[context.lang].tag_pattern
+ end
+
+ local tag_positions_list = lpeg.match(tag_pattern, str)
+ if not tag_positions_list then
+ error('Pattern not match')
+ end
+ local start = 1
+ local stop = 1
+ local new_stop = 1
+ for _, postion_tuple in ipairs(tag_positions_list) do
+ start, new_stop = table.unpack(postion_tuple)
+ table.insert(strings, string.sub(str, stop, start - 1))
+ table.insert(tags, string.sub(str, start, new_stop - 1))
+ stop = new_stop
+ end
+ table.insert(strings, string.sub(str, stop, -1))
+
+ for i, tag in ipairs(tags) do
+ if string.match(tag, "^.['\"]$") then
+ strings[i] = strings[i] .. string.sub(tag, 1, 1)
+ tags[i] = " " .. string.sub(tag, 2)
+ elseif (tag == "'" or tag == '"') and strings[i] == "" and (i == 1 or openers_info[tags[i - 1]]) then
+ -- See `bugreports_NoCaseEscape.txt`.
+ -- '"PIAAC-Longitudinal (PIAAC-L) 2015"'
+ -- <span class=\"nocase\">\"PIAAC-Longitudinal (PIAAC-Lx) 2015\"</span>
+ tags[i] = " " .. tag
+ end
+ end
+
+ return tags, strings
+end
+
+
+---@param tag string
+---@param str string
+---@return string?
+local function _apostrophe_force(tag, str)
+ if tag == "'" or tag == "’" then
+ if str ~= "" and string.match(str, "^[^,.?:; ]") then
+ return util.unicode["right single quotation mark"]
+ end
+ elseif (tag == " '" or tag == "’") and str ~= "" and string.match(str, "^%s") then
+ return util.unicode["right single quotation mark"]
+ end
+ return nil
+end
+
+
+---@param quote string
+---@param openers_info table
+local function set_outer_quote_form(quote, openers_info)
+ openers_info[quote].inner = false;
+ openers_info[straight_quotes_flip[quote]].inner = true;
end
--- TODO: Rewrite with lpeg
+
+---@param tag string
---@param inlines InlineElement[]
+---@param openers_info table
---@param context Context
----@param is_external boolean?
----@return table
-function InlineElement:parse_quotes(inlines, context, is_external)
- local quote_fragments = InlineElement:get_quote_fragments(inlines)
- -- util.debug(quote_fragments)
+---@return InlineElement
+local function make_inline_from_tag(tag, inlines, openers_info, context)
+ if tag == '<span class="nocase">' then
+ return NoCase:new(inlines)
+ elseif tag == '<span class="nodecor">' then
+ return NoDecor:new(inlines)
+ elseif tag == '<span style="font-variant:small-caps;">' then
+ return Formatted:new(inlines, {["font-variant"] = "small-caps"})
+ elseif tag == '<sc>' then
+ return Formatted:new(inlines, {["font-variant"] = "small-caps"})
+ elseif tag == '<i>' then
+ return Formatted:new(inlines, {["font-style"] = "italic"})
+ elseif tag == '<b>' then
+ return Formatted:new(inlines, {["font-weight"] = "bold"})
+ elseif tag == '<sup>' then
+ return Formatted:new(inlines, {["vertical-align"] = "sup"})
+ elseif tag == '<sub>' then
+ return Formatted:new(inlines, {["vertical-align"] = "sub"})
+ elseif openers_info[tag] and openers_info[tag].quotes then
+ local localized_quotes = context:get_localized_quotes()
+ return Quoted:new(inlines, localized_quotes, openers_info[tag].inner)
+ elseif tag == "<code>" or tag == "<script>" or tag == "<pre>" then
+ return Code:new(inlines[1].value)
+ elseif tag == "<math>" or tag == "<math-tex>" then
+ return MathTeX:new(inlines[1].value)
+ else
+ error(string.format("Invalid tag '%s'", tag))
+ return PlainText:new("")
+ end
+end
- local quote_stack = {}
- local text_stack = {{}}
- local localized_quotes
- if context then
- localized_quotes = context:get_localized_quotes()
- else
- localized_quotes = LocalizedQuotes:new()
+--- processTags() in
+--- <https://github.com/Juris-M/citeproc-js/blob/master/src/util_flipflop.js#L474>
+---@param str string
+---@param context Context?
+---@param is_external boolean?
+---@return InlineElement[]
+function InlineElement:parse_html_tags(str, context, is_external)
+ if str == "" then
+ return {}
end
- for _, fragment in ipairs(quote_fragments) do
- local top_text_list = text_stack[#text_stack]
+ str = string.gsub(str, "(\u{00ab}) ", "\u{00ab}\u{202f}")
+ str = string.gsub(str, " (\u{00bb})", "\u{202f}%1")
+ str = string.gsub(str, " ([:;?!])", "\u{202f}%1")
+ -- str = " " .. string.gsub(str, util.unicode["right single quotation mark"], "'")
- if type(fragment) == "table" then
- if fragment.inlines then
- fragment.inlines = self:parse_quotes(fragment.inlines, context, is_external)
- 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
+ local openers_info = default_openers_info
+ if context and context.lang then
+ if not context.engine.locale_tags_info_dict[context.lang] then
+ make_locale_tag_info(context.lang, context)
+ end
+ openers_info = context.engine.locale_tags_info_dict[context.lang].openers_info
+ 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
+ local tags, strings = split_tags_and_strings(str, context)
- 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)
- if is_external then
- -- The text is from prefix or suffix of citationItem.
- -- See flipflop_LeadingMarkupWithApostrophe.txt
- localized_quotes.outer_open = top_quote
- localized_quotes.outer_close = quote
- localized_quotes.inner_open = top_quote
- localized_quotes.inner_close = quote
- end
- local quoted = Quoted:new(top_text_list, localized_quotes)
- table.remove(text_stack)
- table.insert(text_stack[#text_stack], quoted)
+ -- util.debug(tags)
+ -- util.debug(strings)
+ -- if #tags == 0 then
+ -- return {PlainText:new(str)}
+ -- end
+
+ ---@type {tag: string, closer: string, pos: number}[]
+ local opener_stack = {}
+
+ for i, tag in ipairs(tags) do
+ -- util.debug(i)
+ -- util.debug(strings[i])
+ -- util.debug(tag)
+ -- util.debug(opener_stack)
+ local apostrophe = _apostrophe_force(tag, strings[i + 1])
+ if apostrophe then
+ strings[i + 1] = apostrophe .. strings[i + 1]
+ tags[i] = "";
+ else
+ local opener_info = openers_info[tag]
+ local last_opener_info = opener_stack[#opener_stack]
+ if opener_info then
+ if opener_info.quotes and last_opener_info and tag == last_opener_info.tag then
+ local pos = last_opener_info.pos
+ strings[pos + 1] = string.gsub(tag, "^%s", "") .. strings[pos + 1]
+ tags[pos] = "";
+ table.remove(opener_stack)
+ end
+ table.insert(opener_stack, {
+ tag = tag,
+ closer = openers_info[tag].closer,
+ pos = i,
+ })
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
+ -- Closer tag
+ if last_opener_info then
+ if last_opener_info.closer == tag then
+ table.remove(opener_stack)
+ else
+ if tag == "'" or tag == "’" then
+ strings[i + 1] = "’" .. strings[i + 1]
+ tags[i] = ""
+ else
+ while #opener_stack > 0 and opener_stack[#opener_stack].closer ~= tag do
+ local pos = opener_stack[#opener_stack].pos
+ strings[pos + 1] = tags[pos] .. strings[pos + 1]
+ tags[pos] = ""
+ table.remove(opener_stack)
+ end
+ if #opener_stack > 0 then
+ table.remove(opener_stack)
+ else
+ strings[i + 1] = tags[i] .. strings[i + 1]
+ tags[i] = ""
+ end
+ end
+ end
else
- table.insert(top_text_list, PlainText:new(fragment))
+ if tag == "'" or tag == "’" then
+ strings[i + 1] = "’" .. strings[i + 1]
+ tags[i] = ""
+ else
+ strings[i + 1] = tags[i] .. strings[i + 1]
+ tags[i] = ""
+ end
end
end
+ end
+ end
+
+ -- util.debug(opener_stack)
+ -- Process remainders in the stack
+ if #opener_stack > 0 then
+ for _, opener_info in ipairs(opener_stack) do
+ local pos = opener_info.pos
+ local orphan = string.gsub(tags[pos], "^%s", "")
+ orphan = string.gsub(orphan, "'", "’")
+ strings[pos + 1] = orphan .. strings[pos + 1]
+ tags[pos] = ""
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"]
+ -- Remove empty tag
+ for i = #tags, 1, -1 do
+ local tag = tags[i]
+ if tag == "" then
+ strings[i + 1] = strings[i] .. strings[i + 1]
+ table.remove(strings, i)
+ table.remove(tags, i)
+ end
+ end
+
+ -- The first appearance of straight quote is treated as outer quote.
+ for _, tag in ipairs(tags) do
+ -- util.debug(i)
+ -- util.debug(tag)
+ if straight_quotes_flip[tag] then
+ set_outer_quote_form(tag, openers_info)
+ break
+ end
+ end
+
+ -- util.debug(tags)
+ -- util.debug(strings)
+
+ ---@type InlineElement[]
+ local output = {}
+
+ if strings[1] ~= "" then
+ table.insert(output, PlainText:new(strings[1]))
+ end
+
+ ---@type {tag: string, closer: string, pos: number, output_pos: number}[]
+ opener_stack = {}
+
+ for i, tag in ipairs(tags) do
+ if openers_info[tag] then
+ table.insert(opener_stack, {
+ tag = tag,
+ closer = openers_info[tag].closer,
+ pos = i,
+ output_pos = #output + 1
+ })
+ else
+ assert(#opener_stack > 0)
+ local opener_info = opener_stack[#opener_stack]
+ assert(opener_info.closer == tag)
+ local output_pos = opener_info.output_pos
+ local inlines = util.slice(output, output_pos)
+ for j = #output, output_pos, -1 do
+ table.remove(output, j)
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))
+ table.remove(opener_stack)
+ local inline = make_inline_from_tag(opener_info.tag, inlines, openers_info, context)
+ if inline._type == "Quoted" then
+ ---@cast inline Quoted
+ local quotes = context:get_localized_quotes()
+ inline.punctuation_in_quote = quotes.punctuation_in_quote
end
+ table.insert(output, inline)
+ 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
+ if strings[i + 1] ~= "" then
+ table.insert(output, PlainText:new(strings[i + 1]))
end
+
end
- return elements
+ -- util.debug(output)
+ return output
end
local function merge_fragments_at(fragments, i)
@@ -766,6 +1029,9 @@ function OutputFormat:flatten_ir(ir, override_delim)
return inlines
end
+---@param ir IrNode
+---@param override_delim boolean
+---@return InlineElement[]
function OutputFormat:flatten_seq_ir(ir, override_delim)
-- if not ir.children then
-- print(debug.traceback())
@@ -864,6 +1130,7 @@ function OutputFormat:is_sentence_case(inlines)
or util.is_instance(inline, NoCase)
or util.is_instance(inline, NoDecor)
or util.is_instance(inline, CiteInline)
+ or util.is_instance(inline, UndefinedCite)
or (util.is_instance(inline, Formatted)
and inline.formatting["font-variant"] ~= "small-caps"
and inline.formatting["vertical-align"] ~= "sup"
@@ -953,7 +1220,8 @@ function OutputFormat:apply_text_case_inner(inlines, text_case, seen_one, is_upp
(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" or inline._type == "CiteInline" then
+ elseif inline._type == "Formatted" or inline._type == "Quoted"
+ or inline._type == "CiteInline" or inline._type == "UndefinedCite" then
seen_one = self:apply_text_case_inner(inline.inlines, text_case, seen_one, is_uppercase) or seen_one
end
@@ -1146,10 +1414,14 @@ function OutputFormat:affixed(inlines, affixes)
return inlines
end
+---@param inlines InlineElement[]
+---@param affixes table
+---@param localized_quotes LocalizedQuotes
+---@return InlineElement[]
function OutputFormat:affixed_quoted(inlines, affixes, localized_quotes)
inlines = util.clone(inlines)
if localized_quotes then
- inlines = self:quoted(inlines, localized_quotes)
+ inlines = {Quoted:new(inlines, localized_quotes)}
end
if affixes and affixes.prefix and affixes.prefix ~= "" then
table.insert(inlines, 1, PlainText:new(affixes.prefix))
@@ -1160,10 +1432,6 @@ function OutputFormat:affixed_quoted(inlines, affixes, localized_quotes)
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)}
@@ -1214,7 +1482,8 @@ function OutputFormat:flip_flop_inlines(inlines)
["font-weight"] = "normal",
["text-decoration"] = "none",
["vertical-alignment"] = "baseline",
- in_inner_quotes = false,
+ in_quotes = false,
+ inner_quotes = false,
}
self:flip_flop(inlines, flip_flop_state)
end
@@ -1247,9 +1516,13 @@ function OutputFormat:flip_flop(inlines, state)
self:flip_flop(inline.inlines, new_state)
elseif inline._type == "Quoted" then
- inline.is_inner = state.in_inner_quotes
+ ---@cast inline Quoted
+ if state.in_quotes then
+ inline.is_inner = not state.inner_quotes
+ end
local new_state = util.clone(state)
- new_state.in_inner_quotes = not new_state.in_inner_quotes
+ new_state.in_quotes = true
+ new_state.inner_quotes = inline.is_inner
self:flip_flop(inline.inlines, new_state)
elseif inline._type == "NoDecor" then
@@ -1273,7 +1546,6 @@ function OutputFormat:flip_flop(inlines, state)
elseif inline._type == "Code" or
inline._type == "MathML" or
inline._type == "MathTeX" then
- return
elseif inline.inlines then -- Div, ...
self:flip_flop(inline.inlines, state)
@@ -1310,9 +1582,13 @@ function OutputFormat:flip_flop_micro_inlines(inlines, state)
self:flip_flop_micro_inlines(inline.inlines, new_state)
elseif inline._type == "Quoted" then
- inline.is_inner = state.in_inner_quotes
+ ---@cast inline Quoted
+ if state.in_quotes then
+ inline.is_inner = not state.inner_quotes
+ end
local new_state = util.clone(state)
- new_state.in_inner_quotes = not new_state.in_inner_quotes
+ new_state.in_quotes = true
+ new_state.inner_quotes = inline.is_inner
self:flip_flop_micro_inlines(inline.inlines, new_state)
elseif inline._type == "NoDecor" then
@@ -1336,7 +1612,6 @@ function OutputFormat:flip_flop_micro_inlines(inlines, state)
elseif inline._type == "Code" or
inline._type == "MathML" or
inline._type == "MathTeX" then
- return
elseif inline.inlines then -- Div, ...
self:flip_flop_micro_inlines(inline.inlines, state)
@@ -1384,6 +1659,7 @@ end
--- "'Foo,' bar" => ,
---@param inline InlineElement
+---@return boolean
local function find_right_quoted(inline)
if inline._type == "Quoted" and #inline.inlines > 0 then
---@cast inline Quoted
@@ -1475,8 +1751,8 @@ local function normalise_text_elements(inlines)
idx = idx + 1
end
- elseif (first._type == "Formatted" or first._type == "CiteInline")
- and second._type == "PlainText" then
+ elseif (first._type == "Formatted" or first._type == "CiteInline"
+ or first._type == "UndefinedCite") and second._type == "PlainText" then
local success = smash_just_punc(first, second)
if success then
if second.value == "" then
@@ -1572,7 +1848,8 @@ function OutputFormat:move_punctuation(inlines, punctuation_in_quote)
for _, inline in ipairs(inlines) do
if inline._type == "Quoted" or inline._type == "Formatted" or
- inline._type == "Div" or inline._type == "CiteInline" then
+ inline._type == "Div" or inline._type == "CiteInline"
+ or inline._type == "UndefinedCite" then
self:move_punctuation(inline.inlines)
end
end
@@ -1635,6 +1912,9 @@ function Markup:write_inline(inline, context)
elseif inline._type == "CiteInline" then
return self:write_cite(inline, context)
+ elseif inline._type == "UndefinedCite" then
+ return self:write_undefined_cite(inline, context)
+
elseif inline._type == "Code" then
return self:write_code(inline, context)
@@ -1686,6 +1966,11 @@ function Markup:write_cite(inline, context)
return self:write_inlines(inline.inlines, context)
end
+function Markup:write_undefined_cite(inline, context)
+ local bold_inline = Formatted:new({PlainText:new(inline.cite_item.id)}, {["font-weight"] = "bold"})
+ return self:write_formatted(bold_inline, context)
+end
+
function Markup:write_code(inline, context)
return inline.value
end
@@ -1806,7 +2091,7 @@ function LatexWriter:write_display(inline, context)
return res
elseif inline.div == "block" then
- util.warning("display=\"block\" is not supported in LaTeX output.")
+ res = "\n\n" .. res
return res
end
return res
@@ -1831,6 +2116,10 @@ function LatexWriter:write_cite(inline, context)
return str
end
+function LatexWriter:write_undefined_cite(inline, context)
+ return string.format("\\cslundefinedcite{%s}", inline.cite_item.id)
+end
+
function LatexWriter:write_code(inline, context)
return inline.value
end
@@ -1985,6 +2274,8 @@ end
-- Omit formatting and quotes
+
+---@class DisamStringFormat: OutputFormat
local DisamStringFormat = OutputFormat:new()
function DisamStringFormat:output(inlines, context)
@@ -2155,6 +2446,7 @@ output_module.Quoted = Quoted
output_module.Linked = Linked
output_module.Div = Div
output_module.CiteInline = CiteInline
+output_module.UndefinedCite = UndefinedCite
output_module.Code = Code
output_module.MathTeX = MathTeX
output_module.MathTML = MathML
diff --git a/biblio/citation-style-language/citeproc-util.lua b/biblio/citation-style-language/citeproc-util.lua
index 97ac6d010e..46a4c0aaa7 100644
--- a/biblio/citation-style-language/citeproc-util.lua
+++ b/biblio/citation-style-language/citeproc-util.lua
@@ -23,6 +23,10 @@ function util.deep_copy(obj)
local res
if type(obj) == "table" then
res = {}
+ local meta_table = getmetatable(obj)
+ if meta_table then
+ setmetatable(res, meta_table)
+ end
for key, value in pairs(obj) do
res[key] = util.deep_copy(value)
end
@@ -74,7 +78,7 @@ function util.to_boolean(str)
elseif str == "false" then
return false
else
- util.warning(string.format('Invalid boolean string "%s"', str))
+ util.warning(string.format("Invalid boolean string '%s'", str))
return false
end
end
@@ -129,7 +133,7 @@ util.logging_file = nil
function util.set_logging_file(path)
util.logging_file = io.open(path, "w")
if not util.logging_file then
- util.error(string.format('Cannot write to "%s".', path))
+ util.error(string.format("Cannot write to '%s'.", path))
end
util.logging_file = io.open(path, 'a')
end
@@ -146,20 +150,24 @@ util.num_errors = 0
util.num_warnings = 0
+---@param message string
function util.error(message)
util.num_errors = util.num_errors + 1
if luatexbase then
- -- The luatexbase.module_error() prints the traceback, which causes panic
- -- luatexbase.module_error("citeproc", message)
-
- -- TODO: Enhance the error output. Make it like `\msg_error`.
- texio.write_nl("term", "\n")
- tex.error("Module citeproc Error: " .. message)
-
- -- tex.print(string.format("\\PackageError{citation-style-language}{%s}{}", message))
-
+ -- Run in LuaLaTeX
+ tex.print(string.format("\\csname msg_error:nnn\\endcsname{citeproc}{citeproc-error}{%s}", message))
+ -- Don't use the following methods.
+ -- `error()` prints long traceback when run in LuaLaTeX.
+ -- texio.write_nl("term", "\n")
+ -- `tex.error()` prints annoying `\lua_now:e #1->` when called from LaTeX3 interface.
+ -- `luatexbase.module_error()` prints traceback.
+ -- tex.print(string.format("\\PackageError{CSL}{%s}{}", message))
else
- message = "Error: " .. message
+ -- Run in citeproc-lua script
+ -- This format is used by latexmk. DO NOT change.
+ message = "Error: " .. message
+ -- Following bibtex and biber, the error message is printed to stdout rather than stderr.
+ -- And the error doesn't break the execution of the script.
print(message)
if util.logging_file then
util.logging_file:write(message .. "\n")
@@ -172,12 +180,10 @@ util.warning_enabled = true
function util.warning(message)
util.num_warnings = util.num_warnings + 1
if luatexbase then
- texio.write_nl("term", "\n")
- luatexbase.module_warning("citeproc", message)
-
- -- tex.print(string.format("\\PackageWarning{citation-style-language}{%s}{}", message))
+ tex.print(string.format("\\csname msg_warning:nnn\\endcsname{citeproc}{citeproc-warning}{%s}", message))
else
+ -- This format is used by latexmk. DO NOT change.
message = "Warning: " .. message
if util.logging_file then
util.logging_file:write(message .. "\n")
@@ -203,8 +209,15 @@ local remove_all_metatables = nil
function util.debug(obj)
local text
- if type(obj) == "table" and obj._debug then
- text = obj:_debug()
+ if type(obj) == "table" and (obj._debug or (obj[1] and obj[1]._debug)) then
+ if obj._debug then
+ text = obj:_debug()
+ else
+ text = ""
+ for _, child in ipairs(obj) do
+ text = text .. child:_debug()
+ end
+ end
else
if not inspect then
inspect = require("inspect")
@@ -239,6 +252,9 @@ function util.split(str, sep, maxsplit)
if sep == "" then
util.error("Empty separator")
end
+ if str == "" then
+ return {}
+ end
if string.find(str, sep) == nil then
return { str }
end
@@ -364,6 +380,8 @@ function util.concat_list(first, second)
return res
end
+---@param str string
+---@return string
function util.lstrip (str)
if not str then
error("Invalid input")
@@ -372,6 +390,21 @@ function util.lstrip (str)
return res
end
+---@param str string
+---@param prefix string
+---@return string
+function util.remove_prefix(str, prefix)
+ if type(str) ~= "string" or type(prefix) ~= "string" then
+ error("Invalid input")
+ end
+ if util.startswith(str, prefix) then
+ return string.sub(str, #prefix + 1)
+ end
+ return str
+end
+
+---@param str string
+---@return string
function util.rstrip (str)
if not str then
error("Invalid input")
@@ -380,13 +413,15 @@ function util.rstrip (str)
return res
end
+---@param str string
+---@return string
function util.strip (str)
return util.lstrip(util.rstrip(str))
end
function util.startswith(str, prefix)
if type(str) ~= "string" then
- util.error(string.format('\n%s\n"%s" is not a string.', debug.traceback(), str))
+ util.error(string.format("\n%s\n'%s' is not a string.", debug.traceback(), str))
end
return string.sub(str, 1, #prefix) == prefix
end
@@ -398,6 +433,46 @@ function util.endswith(str, suffix)
return string.sub(str, -#suffix) == suffix
end
+---@param str string
+---@return string
+function util.check_prefix_space_append(str)
+ if str == "" then
+ return str
+ end
+ local last_char = uni_utf8.match(str, ".$")
+ if not last_char then
+ return str
+ end
+ if util.is_romanesque(utf8.codepoint(last_char, 1, #last_char)) then
+ return str .. " "
+ elseif string.match(last_char, "[:.;!?]") then
+ return str .. " "
+ elseif string.match(last_char, "[)%],0-9]") then
+ return str .. " "
+ else
+ return str
+ end
+end
+
+---@param str string
+---@return string
+function util.check_suffix_prepend(str)
+ if str == "" then
+ return str
+ end
+ local first_char = uni_utf8.match(str, "^.")
+ if not first_char then
+ return str
+ end
+ if util.is_romanesque(utf8.codepoint(first_char, 1, #first_char)) then
+ return " " .. str
+ elseif string.match(first_char, "[)%[]") then
+ return " " .. str
+ else
+ return str
+ end
+end
+
---@param str string | number
---@return boolean
function util.is_numeric(str)
@@ -988,7 +1063,7 @@ util.roman_numerals = {
-- Choose
----@enum Postion
+---@enum Position
local Position = {
First = 0,
Subsequent = 1,
@@ -1136,7 +1211,7 @@ function util.read_file(path, allowe_missing)
local file = io.open(path, "r")
if not file then
if not allowe_missing then
- util.error(string.format('Cannot open file "%s".', path))
+ util.error(string.format("Cannot open file '%s'.", path))
end
return nil
end
@@ -1152,7 +1227,7 @@ end
function util.write_file(text, path)
local file = io.open(path, "w")
if not file then
- util.error(string.format('Cannot write to file "%s".', path))
+ util.error(string.format("Cannot write to file '%s'.", path))
return
end
file:write(text)
@@ -1282,7 +1357,7 @@ util.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00"
---@return { authors: integer[], year: integer }
function util.get_trigraph_param(trigraph)
if not trigraph or string.sub(trigraph, 1, 1) ~= "A" then
- util.error(string.format('Bad trigraph definition: "%s"', trigraph))
+ util.error(string.format("Bad trigraph definition: '%s'", trigraph))
end
local param = {
authors = {},
@@ -1299,7 +1374,7 @@ function util.get_trigraph_param(trigraph)
elseif char == "0" then
param.year = param.year + 1
else
- util.error(string.format('Invalid character "%s" in trigraph definition "%s"', char, trigraph))
+ util.error(string.format("Invalid character '%s' in trigraph definition '%s'", char, trigraph))
end
end
return param
diff --git a/biblio/citation-style-language/citeproc.lua b/biblio/citation-style-language/citeproc.lua
index 651b705bb5..c71b90577e 100644
--- a/biblio/citation-style-language/citeproc.lua
+++ b/biblio/citation-style-language/citeproc.lua
@@ -16,7 +16,7 @@ else
util = require("citeproc.util")
end
-citeproc.__VERSION__ = "0.4.9"
+citeproc.__VERSION__ = "0.6.4"
citeproc.new = engine.CiteProc.new
citeproc.util = util
diff --git a/biblio/citation-style-language/csl-locales-de-AT.xml b/biblio/citation-style-language/csl-locales-de-AT.xml
index 833ff58f76..2d27ec8635 100644
--- a/biblio/citation-style-language/csl-locales-de-AT.xml
+++ b/biblio/citation-style-language/csl-locales-de-AT.xml
@@ -20,7 +20,7 @@
<name>Frank Bennett</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>2024-03-09T15:20:54-05:00</updated>
+ <updated>2024-08-27T14:30:55-04:00</updated>
</info>
<style-options punctuation-in-quote="false"/>
<date form="text">
@@ -46,7 +46,7 @@
<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="original-work-published">Ursprünglich erschienen</term>
<term name="personal-communication">persönliche Kommunikation</term>
<term name="podcast">podcast</term>
<term name="podcast-episode">podcast episode</term>
diff --git a/biblio/citation-style-language/csl-locales-de-CH.xml b/biblio/citation-style-language/csl-locales-de-CH.xml
index 47a13f2740..9edebba837 100644
--- a/biblio/citation-style-language/csl-locales-de-CH.xml
+++ b/biblio/citation-style-language/csl-locales-de-CH.xml
@@ -14,7 +14,7 @@
<name>Sebastian Karcher</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>2024-03-09T15:20:54-05:00</updated>
+ <updated>2024-08-27T14:30:55-04:00</updated>
</info>
<style-options punctuation-in-quote="false"/>
<date form="text">
@@ -40,7 +40,7 @@
<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="original-work-published">Ursprünglich erschienen</term>
<term name="personal-communication">persönliche Kommunikation</term>
<term name="podcast">podcast</term>
<term name="podcast-episode">podcast episode</term>
diff --git a/biblio/citation-style-language/csl-locales-de-DE.xml b/biblio/citation-style-language/csl-locales-de-DE.xml
index f7e25ad0f3..903378388a 100644
--- a/biblio/citation-style-language/csl-locales-de-DE.xml
+++ b/biblio/citation-style-language/csl-locales-de-DE.xml
@@ -17,7 +17,7 @@
<name>jakov</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>2024-03-09T15:20:54-05:00</updated>
+ <updated>2024-08-27T14:30:55-04:00</updated>
</info>
<style-options punctuation-in-quote="false"/>
<date form="text">
@@ -43,7 +43,7 @@
<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="original-work-published">Ursprünglich erschienen</term>
<term name="personal-communication">persönliche Kommunikation</term>
<term name="podcast">podcast</term>
<term name="podcast-episode">podcast episode</term>
diff --git a/biblio/citation-style-language/csl-locales-en-US.xml b/biblio/citation-style-language/csl-locales-en-US.xml
index 93e874ce36..d9dd755250 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>2024-03-12T12:31:23-04:00</updated>
+ <updated>2024-08-12T16:22:23-04:00</updated>
</info>
<style-options punctuation-in-quote="true"/>
<date form="text">
@@ -685,7 +685,6 @@
</term>
<!-- VERB ROLE FORMS -->
- <term name="author" form="verb">by</term>
<term name="chair" form="verb">chaired by</term>
<term name="collection-editor" form="verb">edited by</term>
<term name="compiler" form="verb">compiled by</term>
diff --git a/biblio/citation-style-language/csl-locales-zh-TW.xml b/biblio/citation-style-language/csl-locales-zh-TW.xml
index e4a0e9ef05..acd4401987 100644
--- a/biblio/citation-style-language/csl-locales-zh-TW.xml
+++ b/biblio/citation-style-language/csl-locales-zh-TW.xml
@@ -5,7 +5,7 @@
<name>sati-bodhi</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>2024-03-09T15:20:54-05:00</updated>
+ <updated>2024-08-12T16:22:23-04:00</updated>
</info>
<style-options punctuation-in-quote="false"/>
<date form="text">
@@ -433,7 +433,6 @@
<single>series creator</single>
<multiple>series creators</multiple>
</term>
- <term name="author">作者</term>
<term name="director">導演</term>
<term name="editor">編輯</term>
<term name="editorial-director">主編</term>
@@ -485,7 +484,6 @@
<single>cre.</single>
<multiple>cres.</multiple>
</term>
- <term name="author" form="short">作者</term>
<term name="director" form="short">導演</term>
<term name="editor" form="short">編輯</term>
<term name="editorial-director" form="short">主編</term>
@@ -511,7 +509,6 @@
<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="author" form="verb">著</term>
<term name="container-author" form="verb">著</term>
<term name="director" form="verb">指導</term>
<term name="editor" form="verb">編輯</term>
diff --git a/biblio/citation-style-language/ieee.csl b/biblio/citation-style-language/ieee.csl
index 9ac71c63ea..98b666b83e 100644
--- a/biblio/citation-style-language/ieee.csl
+++ b/biblio/citation-style-language/ieee.csl
@@ -44,8 +44,8 @@
<category citation-format="numeric"/>
<category field="engineering"/>
<category field="generic-base"/>
- <summary>IEEE style as per the 2021 guidelines, V 01.29.2021.</summary>
- <updated>2024-01-11T14:39:58-05:00</updated>
+ <summary>IEEE style as per the 2023 guidelines, V 11.29.2023.</summary>
+ <updated>2024-07-15T10:30:07-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">
@@ -56,6 +56,7 @@
</date>
<terms>
<term name="chapter" form="short">ch.</term>
+ <term name="chapter-number" form="short">ch.</term>
<term name="presented at">presented at the</term>
<term name="available at">available</term>
</terms>
@@ -120,6 +121,7 @@
<substitute>
<names variable="editor"/>
<names variable="translator"/>
+ <text macro="director"/>
</substitute>
</names>
</macro>
@@ -129,6 +131,12 @@
<label form="short" prefix=", " text-case="capitalize-first"/>
</names>
</macro>
+ <macro name="director">
+ <names variable="director">
+ <name and="text" et-al-min="7" et-al-use-first="1" initialize-with=". "/>
+ <et-al font-style="italic"/>
+ </names>
+ </macro>
<macro name="locators">
<group delimiter=", ">
<text macro="edition"/>
@@ -148,7 +156,7 @@
</macro>
<macro name="title">
<choose>
- <if type="bill book graphic legal_case legislation motion_picture song" match="any">
+ <if type="bill book graphic legal_case legislation motion_picture song standard software" match="any">
<text variable="title" font-style="italic"/>
</if>
<else>
@@ -374,6 +382,10 @@
<text macro="collection"/>
<text macro="publisher"/>
<text macro="issued"/>
+ <group delimiter=" ">
+ <label variable="chapter-number" form="short"/>
+ <text variable="chapter-number"/>
+ </group>
<text macro="page"/>
</group>
<text macro="access"/>
@@ -399,6 +411,26 @@
</group>
<text macro="access"/>
</else-if>
+ <else-if type="software">
+ <group delimiter=". " suffix=".">
+ <text macro="title"/>
+ <text macro="issued" prefix="(" suffix=")"/>
+ <text variable="genre"/>
+ <text macro="publisher"/>
+ </group>
+ <text macro="access"/>
+ </else-if>
+ <else-if type="article">
+ <group delimiter=", " suffix=".">
+ <text macro="title"/>
+ <text macro="issued"/>
+ <group delimiter=": ">
+ <text macro="publisher" font-style="italic"/>
+ <text variable="number"/>
+ </group>
+ </group>
+ <text macro="access"/>
+ </else-if>
<else-if type="webpage post-weblog post" match="any">
<group delimiter=", " suffix=".">
<text macro="title"/>
@@ -423,6 +455,18 @@
</group>
<text macro="access"/>
</else-if>
+ <else-if type="standard">
+ <group delimiter=", " suffix=".">
+ <text macro="title"/>
+ <group delimiter=" ">
+ <text variable="genre"/>
+ <text variable="number"/>
+ </group>
+ <text macro="geographic-location"/>
+ <text macro="issued"/>
+ </group>
+ <text macro="access"/>
+ </else-if>
<!-- Generic/Fallback Formats -->
<else-if type="bill book graphic legal_case legislation report song" match="any">
<group delimiter=", " suffix=". ">
diff --git a/biblio/citation-style-language/modern-humanities-research-association.csl b/biblio/citation-style-language/modern-humanities-research-association.csl
index d8bd97c596..73f0d89a10 100644
--- a/biblio/citation-style-language/modern-humanities-research-association.csl
+++ b/biblio/citation-style-language/modern-humanities-research-association.csl
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="note" version="1.0" demote-non-dropping-particle="sort-only" page-range-format="chicago" default-locale="en-GB">
<info>
- <title>Modern Humanities Research Association 3rd edition (note with bibliography)</title>
+ <title>Modern Humanities Research Association 4th edition (note with bibliography)</title>
<title-short>MHRA</title-short>
<id>http://www.zotero.org/styles/modern-humanities-research-association</id>
<link href="http://www.zotero.org/styles/modern-humanities-research-association" rel="self"/>
@@ -17,10 +17,13 @@
<name>Andrew Dunning</name>
<uri>https://orcid.org/0000-0003-0464-5036</uri>
</contributor>
+ <contributor>
+ <name>Patrick O'Brien</name>
+ </contributor>
<category citation-format="note"/>
<category field="generic-base"/>
<summary>MHRA format with full notes and bibliography</summary>
- <updated>2023-12-09T18:40:26-06:00</updated>
+ <updated>2024-05-14T10:11:14-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">
@@ -334,10 +337,7 @@
<text variable="publisher"/>
</if>
<else>
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
+ <text variable="publisher"/>
</else>
</choose>
</macro>
@@ -360,7 +360,10 @@
<macro name="pages">
<choose>
<if type="article-journal">
- <text variable="page" prefix=", "/>
+ <group delimiter=" " prefix=", ">
+ <label variable="page" form="short"/>
+ <text variable="page"/>
+ </group>
</if>
<else>
<choose>
@@ -411,7 +414,7 @@
</group>
<choose>
<if variable="DOI">
- <text variable="DOI" prefix=" &lt;https://doi.org/" suffix="&gt;"/>
+ <text variable="DOI" prefix=", doi:"/>
</if>
<else>
<choose>
diff --git a/biblio/ctan-bibdata/ctan.bib b/biblio/ctan-bibdata/ctan.bib
index e1d9a37141..54e15eb06a 100644
--- a/biblio/ctan-bibdata/ctan.bib
+++ b/biblio/ctan-bibdata/ctan.bib
@@ -1,7 +1,7 @@
%% bib file of all CTAN packages
%% (C) Herbert Voß
%%
-%% created at 22-05-2024, 02:00:03
+%% created at 26-09-2024, 02:00:03
%%
%% This file is provided under the terms of the LPPL v1.3 or
@@ -246,8 +246,8 @@
title = {The \texttt{abraces} package},
subtitle = {Asymmetric over-/underbraces in maths},
author = {Werner Grundlingh},
- date = {2022-11-06},
- version = {2.1},
+ date = {2024-08-02},
+ version = {2.2},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/abraces},
url = {https://ctan.org/pkg/abraces},
@@ -479,8 +479,8 @@
title = {The \texttt{acmart} package},
subtitle = {Class for typesetting publications of ACM},
author = {Boris Veytsman},
- date = {2024-04-18},
- version = {2.07},
+ date = {2024-08-26},
+ version = {2.09},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/acmart},
url = {https://ctan.org/pkg/acmart},
@@ -570,8 +570,8 @@
title = {The \texttt{acronym} package},
subtitle = {Expand acronyms at least once},
author = {Tobias Oetiker and Heiko Oberdiek},
- date = {2020-04-11},
- version = {1.47},
+ date = {2024-09-19},
+ version = {1.49},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/acronym},
url = {https://ctan.org/pkg/acronym},
@@ -910,7 +910,7 @@
title = {The \texttt{adjustbox} package},
subtitle = {Graphics package-alike macros for “general” boxes},
author = {Martin Scharrer},
- date = {2022-10-26},
+ date = {2024-08-23},
version = {1.3a},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/adjustbox},
@@ -1343,6 +1343,17 @@
url = {https://ctan.org/pkg/aifont},
}
+@manual{ctan-aiplans,
+ title = {The \texttt{aiplans} package},
+ subtitle = {A TikZ-based library for drawing POCL plans},
+ author = {Yikai Ge},
+ date = {2024-09-16},
+ version = {1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/graphics/pgf/contrib/aiplans},
+ url = {https://ctan.org/pkg/aiplans},
+}
+
@manual{ctan-ajl,
title = {The \texttt{ajl} package},
subtitle = {BibTeX style for AJL},
@@ -1499,8 +1510,8 @@
title = {The \texttt{algolrevived} package},
subtitle = {A revival of Frutiger's Algol alphabet},
author = {Michael Sharpe},
- date = {2020-11-05},
- version = {1.052},
+ date = {2024-05-27},
+ version = {1.054},
license = {ofl,lppl1.3c},
mirror = {https://mirror.ctan.org/fonts/algolrevived},
url = {https://ctan.org/pkg/algolrevived},
@@ -1627,7 +1638,7 @@
title = {The \texttt{alltt} package},
subtitle = {Everything in tt font, but obey commands and line endings},
author = {Leslie Lamport and Johannes L. Braams and {The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-01},
version = {2.0g},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -2262,7 +2273,7 @@
title = {The \texttt{animate} package},
subtitle = {Create PDF and SVG animations from graphics files and inline graphics},
author = {Alexander Grahn},
- date = {2023-06-18},
+ date = {2024-09-17},
version = {},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/animate},
@@ -2586,8 +2597,8 @@
title = {The \texttt{aomart} package},
subtitle = {Typeset articles for the Annals of Mathematics},
author = {Boris Veytsman},
- date = {2022-05-30},
- version = {1.27},
+ date = {2024-06-09},
+ version = {1.28},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/aomart},
url = {https://ctan.org/pkg/aomart},
@@ -3026,7 +3037,7 @@
title = {The \texttt{aramaic-serto} package},
subtitle = {Fonts and \LaTeX{} for Syriac written in Serto},
author = {Johannes Heinecke},
- date = {2017-04-18},
+ date = {2024-07-25},
version = {1.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/language/aramaic/serto},
@@ -3102,7 +3113,7 @@
title = {The \texttt{arcs} package},
subtitle = {Draw arcs over and under text},
author = {Gianfranco Boggio-Togna},
- date = {2016-06-24},
+ date = {2024-06-20},
version = {1},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/arcs},
@@ -3128,8 +3139,8 @@
title = {The \texttt{argumentation} package},
subtitle = {Create abstract argumentation frameworks via TikZ},
author = {Lars Bengel},
- date = {2023-12-03},
- version = {1.1},
+ date = {2024-09-25},
+ version = {1.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/argumentation},
url = {https://ctan.org/pkg/argumentation},
@@ -3251,8 +3262,8 @@
title = {The \texttt{array} package},
subtitle = {Extending the array and tabular environments},
author = {Frank Mittelbach and {The LaTeX Project Team}},
- date = {2023-11-01},
- version = {2.5g},
+ date = {2024-06-02},
+ version = {2.6c},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/array},
@@ -3377,7 +3388,7 @@
title = {The \texttt{article} package},
subtitle = {Default class for composing an article},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-02},
version = {1.4n},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -3580,8 +3591,8 @@
title = {The \texttt{asmeconf} package},
subtitle = {A \LaTeX{} template for ASME conference papers},
author = {John H. Lienhard},
- date = {2024-02-06},
- version = {1.37},
+ date = {2024-08-01},
+ version = {1.38},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/asmeconf},
url = {https://ctan.org/pkg/asmeconf},
@@ -3591,8 +3602,8 @@
title = {The \texttt{asmejour} package},
subtitle = {A template for ASME journal papers},
author = {John H. Lienhard},
- date = {2024-02-06},
- version = {1.22},
+ date = {2024-07-25},
+ version = {1.23},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/asmejour},
url = {https://ctan.org/pkg/asmejour},
@@ -3696,6 +3707,17 @@
url = {https://ctan.org/pkg/astyped},
}
+@manual{ctan-asy-overview,
+ title = {The \texttt{asy-overview} package},
+ subtitle = {A brief overview of the Asymptote language for drawing mathematical graphics},
+ author = {Jim Hefferon},
+ date = {2024-06-14},
+ version = {1.04},
+ license = {cc-by-sa-4},
+ mirror = {https://mirror.ctan.org/info/asy-overview},
+ url = {https://ctan.org/pkg/asy-overview},
+}
+
@manual{ctan-asyfig,
title = {The \texttt{asyfig} package},
subtitle = {Commands for using Asymptote figures},
@@ -3756,8 +3778,8 @@
title = {The \texttt{asymptote} package},
subtitle = {2D and 3D \TeX{}-Aware Vector Graphics Language},
author = {John Bowman and Andy Hammerlindl},
- date = {2024-03-25},
- version = {2.89},
+ date = {2024-08-15},
+ version = {2.91},
license = {lgpl3},
mirror = {https://mirror.ctan.org/graphics/asymptote},
url = {https://ctan.org/pkg/asymptote},
@@ -3889,17 +3911,12 @@
title = {The \texttt{atveryend} package},
subtitle = {Hooks at the very end of a document},
author = {Heiko Oberdiek},
- date = {2019-12-12},
- version = {1.11},
- license = {lppl1.3},
+ date = {2024-08-07},
+ version = {1.12},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/atveryend},
url = {https://ctan.org/pkg/atveryend},
- annotation = {This \LaTeX{} packages provides two hooks for
- that are executed after the hook of :
- can be used for code that is to be executed
- right after the last before the `' file
- is closed. is used for code after closing
- and final reading of the `' file.},
+ annotation = {This \LaTeX{} package provides some wrapper commands around \LaTeX{} hooks.},
}
@manual{ctan-aucklandthesis,
@@ -4326,7 +4343,7 @@
title = {The \texttt{avremu} package},
subtitle = {An 8-Bit Microcontroller Simulator written in \LaTeX{}},
author = {Christian Dietrich},
- date = {2017-04-18},
+ date = {2024-07-25},
version = {0.1},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/avremu},
@@ -4638,9 +4655,9 @@
title = {The \texttt{babel-french} package},
subtitle = {Babel contributed support for French},
author = {Daniel Flipo},
- date = {2024-02-29},
- version = {3.5s},
- license = {lppl1.3},
+ date = {2024-07-26},
+ version = {3.6c},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/babel-contrib/french},
url = {https://ctan.org/pkg/babel-french},
annotation = {The package, formerly known as , establishes
@@ -5194,8 +5211,8 @@
title = {The \texttt{babel} package},
subtitle = {Multilingual support for \LaTeX{}, LuaLaTeX, \XeLaTeX{}, and Plain \TeX{}},
author = {Javier Bezos López and Johannes L. Braams},
- date = {2024-05-18},
- version = {24.5},
+ date = {2024-09-18},
+ version = {24.10},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/required/babel/base},
url = {https://ctan.org/pkg/babel},
@@ -5647,8 +5664,8 @@
title = {The \texttt{BasicLaTeX-ru} package},
subtitle = {An introduction to \LaTeX{}, in Russian},
author = {Alexey Kuznetsov},
- date = {2021-07-07},
- version = {1.0},
+ date = {2024-08-10},
+ version = {2.0},
license = {cc-by-nc-sa4},
mirror = {https://mirror.ctan.org/info/russian/basiclatex-ru},
url = {https://ctan.org/pkg/basiclatex-ru},
@@ -5861,7 +5878,7 @@
title = {The \texttt{bbold} package},
subtitle = {Sans serif blackboard bold},
author = {Alan Jeffrey},
- date = {2016-06-24},
+ date = {2024-07-09},
version = {1.01},
license = {bsd},
mirror = {https://mirror.ctan.org/fonts/bbold},
@@ -6081,7 +6098,7 @@
title = {The \texttt{beamerposter} package},
subtitle = {Extend beamer and a0poster for custom sized posters},
author = {Philippe Dreuw and Thomas Deselaers},
- date = {2018-04-23},
+ date = {2024-07-25},
version = {1.13},
license = {lppl,gpl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/beamerposter},
@@ -6114,8 +6131,8 @@
title = {The \texttt{beamertheme-arguelles} package},
subtitle = {Simple, typographic beamer theme},
author = {Michele Piazzai},
- date = {2024-02-27},
- version = {2.4.0},
+ date = {2024-06-11},
+ version = {2.4.2},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/beamer-contrib/themes/beamertheme-arguelles},
url = {https://ctan.org/pkg/beamertheme-arguelles},
@@ -6151,6 +6168,17 @@
url = {https://ctan.org/pkg/beamertheme-detlevcm},
}
+@manual{ctan-beamertheme-edmaths,
+ title = {The \texttt{beamertheme-edmaths} package},
+ subtitle = {A beamer theme for the University of Edinburgh (UoE)},
+ author = {Josh Fogg},
+ date = {2024-09-01},
+ version = {0.99},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/beamer-contrib/themes/beamertheme-edmaths},
+ url = {https://ctan.org/pkg/beamertheme-edmaths},
+}
+
@manual{ctan-beamertheme-epyt,
title = {The \texttt{beamertheme-epyt} package},
subtitle = {A simple and clean theme for \LaTeX{} beamer class},
@@ -6173,6 +6201,17 @@
url = {https://ctan.org/pkg/beamertheme-focus},
}
+@manual{ctan-beamertheme-gotham,
+ title = {The \texttt{beamertheme-gotham} package},
+ subtitle = {A versatile and extendable beamer theme based on Metropolis},
+ author = {Romain NOËL},
+ date = {2024-09-22},
+ version = {1.1.0.b},
+ license = {lppl1.3c,cc-by-sa-4},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/beamer-contrib/themes/beamertheme-gotham},
+ url = {https://ctan.org/pkg/beamertheme-gotham},
+}
+
@manual{ctan-beamertheme-light,
title = {The \texttt{beamertheme-light} package},
subtitle = {A minimal beamer style},
@@ -6283,8 +6322,8 @@
title = {The \texttt{beamertheme-tcolorbox} package},
subtitle = {A beamer inner theme which reproduces standard beamer blocks using tcolorboxes},
author = {{Unknown}},
- date = {2024-04-29},
- version = {0.7},
+ date = {2024-09-23},
+ version = {0.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/beamer-contrib/themes/beamertheme-tcolorbox},
url = {https://ctan.org/pkg/beamertheme-tcolorbox},
@@ -6424,7 +6463,7 @@
title = {The \texttt{beautybook} package},
subtitle = {A beautiful book template for maths and science},
author = {Shilong Lu},
- date = {2024-03-17},
+ date = {2024-07-03},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/beautybook},
@@ -6816,6 +6855,24 @@
url = {https://ctan.org/pkg/bib2ml},
}
+@manual{ctan-bib2qr,
+ title = {The \texttt{bib2qr} package},
+ subtitle = {Cite BibTeX entries with QR codes},
+ author = {Christian Schreinemachers},
+ date = {2024-08-01},
+ version = {0.2},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/bib2qr},
+ url = {https://ctan.org/pkg/bib2qr},
+ annotation = {This package provides functionality to cite BibTeX entries
+ with QR codes for easy sharing and referencing.
+ The target of the QR code is the entry’s digital object
+ identifier (DOI), or URL if no DOI exists.
+ It is realised via the \LaTeX{} packages
+ and
+ .},
+}
+
@manual{ctan-bib2xhtml,
title = {The \texttt{bib2xhtml} package},
subtitle = {Convert BibTeX Files into XHTML},
@@ -6968,8 +7025,8 @@
title = {The \texttt{biber-linux-musl} package},
subtitle = {Biber binaries for Linux-MUSL},
author = {Philip Kime and Alexander Krumeich},
- date = {2024-03-25},
- version = {2.20},
+ date = {2024-06-03},
+ version = {2.20-1},
license = {artistic2},
mirror = {https://mirror.ctan.org/biblio/biber/biber-linux-musl},
url = {https://ctan.org/pkg/biber-linux-musl},
@@ -7553,8 +7610,8 @@
title = {The \texttt{biblatex-ieee} package},
subtitle = {IEEE style files for BibLaTeX},
author = {Joseph Wright},
- date = {2021-12-07},
- version = {1.3f},
+ date = {2024-08-14},
+ version = {1.3g},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/biblatex-contrib/biblatex-ieee},
url = {https://ctan.org/pkg/biblatex-ieee},
@@ -7812,8 +7869,8 @@
title = {The \texttt{biblatex-oxref} package},
subtitle = {BibLaTeX styles inspired by the Oxford Guide to Style},
author = {Alex Ball},
- date = {2023-11-23},
- version = {3.2},
+ date = {2024-08-26},
+ version = {3.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/biblatex-contrib/biblatex-oxref},
url = {https://ctan.org/pkg/biblatex-oxref},
@@ -7834,8 +7891,8 @@
title = {The \texttt{biblatex-phys} package},
subtitle = {A BibLaTeX implementation of the AIP and APS bibliography style},
author = {Joseph Wright},
- date = {2020-06-21},
- version = {1.1b},
+ date = {2024-07-26},
+ version = {1.1c},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/biblatex-contrib/biblatex-phys},
url = {https://ctan.org/pkg/biblatex-phys},
@@ -7845,8 +7902,8 @@
title = {The \texttt{biblatex-publist} package},
subtitle = {BibLaTeX bibliography support for publication lists},
author = {Jürgen Spitzmüller},
- date = {2024-05-09},
- version = {2.9},
+ date = {2024-08-21},
+ version = {2.13},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/biblatex-contrib/biblatex-publist},
url = {https://ctan.org/pkg/biblatex-publist},
@@ -7878,8 +7935,8 @@
title = {The \texttt{biblatex-sbl} package},
subtitle = {Society of Biblical Literature (SBL) style files for BibLaTeX},
author = {David Purton},
- date = {2022-06-18},
- version = {0.14},
+ date = {2024-06-09},
+ version = {0.15},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/biblatex-contrib/biblatex-sbl},
url = {https://ctan.org/pkg/biblatex-sbl},
@@ -8341,10 +8398,10 @@
title = {The \texttt{bibtexperllibs} package},
subtitle = {BibTeX Perl Libraries},
author = {Gerhard Gossen and Boris Veytsman},
- date = {2023-11-19},
- version = {1.9},
+ date = {2024-09-03},
+ version = {1.91},
license = {gpl1,artistic,pd},
- mirror = {https://mirror.ctan.org/support/bibtexperllibs},
+ mirror = {https://mirror.ctan.org/biblio/bibtex/utils/bibtexperllibs},
url = {https://ctan.org/pkg/bibtexperllibs},
}
@@ -8858,8 +8915,8 @@
title = {The \texttt{bithesis} package},
subtitle = {Templates for the Beijing Institute of Technology},
author = {Feng Kaiyu},
- date = {2024-05-04},
- version = {3.7.7},
+ date = {2024-05-30},
+ version = {3.7.9},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/unicodetex/latex/bithesis},
url = {https://ctan.org/pkg/bithesis},
@@ -9148,7 +9205,7 @@
title = {The \texttt{bm} package},
subtitle = {Access bold symbols in maths mode},
author = {David Carlisle and Frank Mittelbach and {The LaTeX Project Team}},
- date = {2023-11-01},
+ date = {2024-06-02},
version = {1.2f},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
@@ -9212,8 +9269,8 @@
title = {The \texttt{bmstu-iu8} package},
subtitle = {A class for IU8 reports},
author = {{Unknown}},
- date = {2022-01-25},
- version = {1.2},
+ date = {2024-09-09},
+ version = {1.4},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/bmstu-iu8},
url = {https://ctan.org/pkg/bmstu-iu8},
@@ -9380,6 +9437,17 @@
url = {https://ctan.org/pkg/bondgraphs},
}
+@manual{ctan-bonum-otf,
+ title = {The \texttt{bonum-otf} package},
+ subtitle = {Support for the OpenType font Bonum},
+ author = {Herbert Voß},
+ date = {2024-07-26},
+ version = {0.01},
+ license = {lppl1.3},
+ mirror = {https://mirror.ctan.org/fonts/bonum-otf},
+ url = {https://ctan.org/pkg/bonum-otf},
+}
+
@manual{ctan-book-examples,
title = {The \texttt{book-examples} package},
subtitle = {A collection of examples from published \TeX{}-related books},
@@ -9404,7 +9472,7 @@
title = {The \texttt{book} package},
subtitle = {A class for typesetting books},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-02},
version = {1.4n},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -9496,8 +9564,8 @@
@manual{ctan-bookshelf,
title = {The \texttt{bookshelf} package},
subtitle = {Create a nice image from a BibTeX file},
- author = {Peter Flynn},
- date = {2020-05-26},
+ author = {Peter Flynn and Boris Veytsman},
+ date = {2024-07-20},
version = {0.5},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/graphics/bookshelf},
@@ -10269,8 +10337,8 @@
title = {The \texttt{bxjatoucs} package},
subtitle = {Convert Japanese character code to Unicode},
author = {Takayuki Yato},
- date = {2019-10-24},
- version = {0.2},
+ date = {2024-07-26},
+ version = {0.3a},
license = {mit},
mirror = {https://mirror.ctan.org/language/japanese/BX/bxjatoucs},
url = {https://ctan.org/pkg/bxjatoucs},
@@ -10280,8 +10348,8 @@
title = {The \texttt{BXjscls} package},
subtitle = {Japanese document class collection for all major engines},
author = {Takayuki Yato},
- date = {2024-01-29},
- version = {2.9b},
+ date = {2024-07-19},
+ version = {2.9c},
license = {bsd2},
mirror = {https://mirror.ctan.org/language/japanese/BX/bxjscls},
url = {https://ctan.org/pkg/bxjscls},
@@ -10342,8 +10410,8 @@
title = {The \texttt{bxpdfver} package},
subtitle = {Specify version and compression level of output PDF files},
author = {Takayuki Yato},
- date = {2022-04-30},
- version = {0.6},
+ date = {2024-08-03},
+ version = {0.8},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/bxpdfver},
url = {https://ctan.org/pkg/bxpdfver},
@@ -10989,6 +11057,17 @@
url = {https://ctan.org/pkg/cascadia-code},
}
+@manual{ctan-cascadiamono-otf,
+ title = {The \texttt{cascadiamono-otf} package},
+ subtitle = {Support for the OpenType font CascadiaMono (with CascadiaCode fontspec config files)},
+ author = {Cédric Pierquet},
+ date = {2024-09-16},
+ version = {0.1},
+ license = {lppl1.3},
+ mirror = {https://mirror.ctan.org/fonts/cascadiamono-otf},
+ url = {https://ctan.org/pkg/cascadiamono-otf},
+}
+
@manual{ctan-cascadilla,
title = {The \texttt{cascadilla} package},
subtitle = {Typeset papers conforming to the stylesheet of the Cascadilla Proceedings Project},
@@ -11231,16 +11310,18 @@
}
@manual{ctan-catppuccinpalette,
- title = {The \texttt{catppuccinpalette} package},
+ title = {The \texttt{catppuccinPalette} package},
subtitle = {Provides (x)colors of catppuccin theme},
- author = {Lukas Heindl},
- date = {2024-05-21},
- version = {1.0.1},
- license = {lppl1.3},
+ author = {{Goudham} and Lukas Heindl},
+ date = {2024-08-18},
+ version = {1.1.0},
+ license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/catppuccinpalette},
url = {https://ctan.org/pkg/catppuccinpalette},
- annotation = {A package providing (x)colors of the
- palette/theme.},
+ annotation = {is a nice pastel theme in four flavours/styles
+ (Latte, Frappé, Macchiato, Mocha).
+ This package defines these themes as
+ colors.},
}
@manual{ctan-causets,
@@ -11665,8 +11746,8 @@
title = {The \texttt{changebar} package},
subtitle = {Generate changebars in \LaTeX{} documents},
author = {Johannes L. Braams and Michael Fine},
- date = {2024-01-09},
- version = {3.7d},
+ date = {2024-07-19},
+ version = {3.7e},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/changebar},
url = {https://ctan.org/pkg/changebar},
@@ -11695,8 +11776,8 @@
title = {The \texttt{changelog} package},
subtitle = {Typesetting keepachangelog.com style changelogs},
author = {Rebecca Turner},
- date = {2023-02-17},
- version = {2.5.0},
+ date = {2024-09-17},
+ version = {2.5.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/changelog},
url = {https://ctan.org/pkg/changelog},
@@ -12008,7 +12089,7 @@
title = {The \texttt{chemformula-ru} package},
subtitle = {Using the chemformula package with babel-russian settings},
author = {Alexey Kuznetsov},
- date = {2024-03-09},
+ date = {2024-07-10},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/chemformula-ru},
@@ -12731,8 +12812,8 @@
title = {The \texttt{circledtext} package},
subtitle = {Create circled text},
author = {Nan Geng},
- date = {2022-05-05},
- version = {1.1.0},
+ date = {2024-09-09},
+ version = {1.1.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/circledtext},
url = {https://ctan.org/pkg/circledtext},
@@ -12744,8 +12825,8 @@
title = {The \texttt{Circuit\_macros} package},
subtitle = {M4 macros for electric circuit diagrams},
author = {Dwight Aplevich},
- date = {2024-01-01},
- version = {10.5},
+ date = {2024-05-30},
+ version = {10.6},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/circuit_macros},
url = {https://ctan.org/pkg/circuit-macros},
@@ -12755,8 +12836,8 @@
title = {The \texttt{CircuiTikZ} package},
subtitle = {Draw electrical networks with TikZ},
author = {Massimo Redaelli and Stefan Lindner and Stefan Erhardt and Romano Giannetti},
- date = {2024-05-05},
- version = {1.6.8},
+ date = {2024-08-03},
+ version = {1.7.0},
license = {lppl,gpl},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/circuitikz},
url = {https://ctan.org/pkg/circuitikz},
@@ -12788,8 +12869,8 @@
title = {The \texttt{citation-style-language} package},
subtitle = {Bibliography formatting with Citation Style Language},
author = {Zeping Lee},
- date = {2024-04-21},
- version = {0.4.9},
+ date = {2024-09-14},
+ version = {0.6.4},
license = {mit,cc-by-sa-3},
mirror = {https://mirror.ctan.org/biblio/citation-style-language},
url = {https://ctan.org/pkg/citation-style-language},
@@ -12966,8 +13047,8 @@
title = {The \texttt{cjs-rcs-article} package},
subtitle = {Article class for The Canadian Journal of Statistics},
author = {Vincent Goulet},
- date = {2023-12-03},
- version = {1.0},
+ date = {2024-07-31},
+ version = {1.1a},
license = {lppl1.3c,cc-by-sa-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/cjs-rcs-article},
url = {https://ctan.org/pkg/cjs-rcs-article},
@@ -13010,7 +13091,7 @@
title = {The \texttt{classes} package},
subtitle = {The source of \LaTeX{}’s standard classes},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-01},
version = {1.4n},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -13477,7 +13558,7 @@
title = {The \texttt{cmactex} package},
subtitle = {TeX for the Macintosh},
author = {Tom Kiffe},
- date = {2023-01-11},
+ date = {2024-07-25},
version = {4.5},
license = {shareware},
mirror = {https://mirror.ctan.org/systems/mac/cmactex},
@@ -14183,7 +14264,7 @@
title = {The \texttt{color} package},
subtitle = {Colour control for \LaTeX{} documents},
author = {David Carlisle and {The LaTeX Project Team}},
- date = {2022-06-08},
+ date = {2024-06-02},
version = {1.3d},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/graphics},
@@ -14225,9 +14306,9 @@
@manual{ctan-coloredbelts,
title = {The \texttt{coloredbelts} package},
- subtitle = {Insert colored belts (vectorial format) in documents (to presetn skills, for example)},
+ subtitle = {Insert colored belts in documents (to present skills, for example)},
author = {Cédric Pierquet},
- date = {2023-11-05},
+ date = {2024-09-09},
version = {0.1.0},
license = {lppl1.3c,cc-by-sa-3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/coloredbelts},
@@ -14238,8 +14319,8 @@
title = {The \texttt{coloredtheorem} package},
subtitle = {A colourful boxed theorem environment},
author = {João M. Lourenço},
- date = {2024-04-12},
- version = {1.0.2},
+ date = {2024-09-16},
+ version = {1.0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/coloredtheorem},
url = {https://ctan.org/pkg/coloredtheorem},
@@ -14378,8 +14459,8 @@
title = {The \texttt{colortbl} package},
subtitle = {Add colour to \LaTeX{} tables},
author = {David Carlisle},
- date = {2024-02-20},
- version = {1.0g},
+ date = {2024-07-06},
+ version = {1.0i},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/colortbl},
url = {https://ctan.org/pkg/colortbl},
@@ -14547,6 +14628,17 @@
url = {https://ctan.org/pkg/commado},
}
+@manual{ctan-commalists-tools,
+ title = {The \texttt{commalists-tools} package},
+ subtitle = {Manipulate numeral comma separated lists},
+ author = {Cédric Pierquet},
+ date = {2024-09-25},
+ version = {0.1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/commalists-tools},
+ url = {https://ctan.org/pkg/commalists-tools},
+}
+
@manual{ctan-commath,
title = {The \texttt{commath} package},
subtitle = {Mathematics typesetting support},
@@ -15936,10 +16028,10 @@
title = {The \texttt{count1to} package},
subtitle = {Make use of count1 to count9},
author = {Martin Schröder and Marei Peischl},
- date = {2020-11-24},
- version = {2.1},
+ date = {2024-06-23},
+ version = {2.11},
license = {lppl},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/ms},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/count1to},
url = {https://ctan.org/pkg/count1to},
}
@@ -16110,11 +16202,11 @@
@manual{ctan-cpssp,
title = {The \texttt{cpssp} package},
subtitle = {Draw protein secondary structures},
- author = {Wolfgang Skala},
- date = {2016-06-24},
+ author = {Wolfgang Esser-Skala},
+ date = {2024-06-13},
version = {1.0},
license = {lppl},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/cpssp},
+ mirror = {https://mirror.ctan.org/obsolete/macros/latex/contrib/cpssp},
url = {https://ctan.org/pkg/cpssp},
}
@@ -16357,7 +16449,7 @@
title = {The \texttt{crossrefware} package},
subtitle = {Scripts for working with crossref.org},
author = {Boris Veytsman},
- date = {2024-02-04},
+ date = {2024-09-07},
version = {},
license = {gpl},
mirror = {https://mirror.ctan.org/support/crossrefware},
@@ -16458,8 +16550,8 @@
title = {The \texttt{cs-techrep} package},
subtitle = {Technical Reports in Computer Science and Software Engineering},
author = {Christoph P. Neumann},
- date = {2024-04-10},
- version = {0.2},
+ date = {2024-09-17},
+ version = {0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/cs-techrep},
url = {https://ctan.org/pkg/cs-techrep},
@@ -16613,6 +16705,17 @@
url = {https://ctan.org/pkg/cstex},
}
+@manual{ctan-csthm,
+ title = {The \texttt{csthm} package},
+ subtitle = {Customized theorem environments for computer science documents},
+ author = {Agni Datta},
+ date = {2024-09-16},
+ version = {1.2},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/csthm},
+ url = {https://ctan.org/pkg/csthm},
+}
+
@manual{ctan-cstypo,
title = {The \texttt{cstypo} package},
subtitle = {Czech typography rules enforced through LuaTeX hooks},
@@ -17033,8 +17136,8 @@
title = {The \texttt{customenvs} package},
subtitle = {Custom environments (MCQ, list with picked items, ...)},
author = {Cédric Pierquet},
- date = {2024-05-18},
- version = {0.1.5},
+ date = {2024-09-15},
+ version = {0.2.3},
license = {lppl1.3c,cc-by-sa-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/customenvs},
url = {https://ctan.org/pkg/customenvs},
@@ -17123,8 +17226,8 @@
title = {The \texttt{cweb} package},
subtitle = {A Web system in C},
author = {Donald E. Knuth and Andreas Scherer and Silvio Levy},
- date = {2023-12-03},
- version = {4.11},
+ date = {2024-08-13},
+ version = {4.12},
license = {knuth},
mirror = {https://mirror.ctan.org/web/c_cpp/cweb},
url = {https://ctan.org/pkg/cweb},
@@ -17408,8 +17511,8 @@
title = {The \texttt{dashrulex} package},
subtitle = {Draw dashed rules},
author = {Qu Yi},
- date = {2024-03-25},
- version = {1.00c},
+ date = {2024-07-18},
+ version = {1.01a},
license = {cc-by-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/dashrulex},
url = {https://ctan.org/pkg/dashrulex},
@@ -18195,8 +18298,8 @@
title = {The \texttt{dccpaper} package},
subtitle = {Typeset papers for the International Journal of Digital Curation},
author = {Alex Ball},
- date = {2023-08-11},
- version = {2.4},
+ date = {2024-08-23},
+ version = {2.5},
license = {lppl1.3c,cc-by-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/dccpaper},
url = {https://ctan.org/pkg/dccpaper},
@@ -18534,8 +18637,8 @@
title = {The \texttt{delimset} package},
subtitle = {Typeset and declare sets of delimiters with convenient size control},
author = {Niklas Beisert},
- date = {2018-12-30},
- version = {1.1},
+ date = {2024-07-17},
+ version = {2.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/delimset},
url = {https://ctan.org/pkg/delimset},
@@ -18909,8 +19012,8 @@
title = {The \texttt{digestif} package},
subtitle = {Editor plugin for \LaTeX{}, ConTeXt etc.},
author = {Augusto Stoffel},
- date = {2022-12-08},
- version = {0.5.1},
+ date = {2024-09-01},
+ version = {0.6},
license = {gpl3+,lppl1.3,fdl},
mirror = {https://mirror.ctan.org/support/digestif},
url = {https://ctan.org/pkg/digestif},
@@ -19244,8 +19347,8 @@
title = {The \texttt{doc} package},
subtitle = {Format \LaTeX{} documentation},
author = {Frank Mittelbach and {The LaTeX Project Team}},
- date = {2024-01-15},
- version = {3.0m},
+ date = {2024-06-01},
+ version = {3.0p},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/doc},
@@ -19341,7 +19444,7 @@
title = {The \texttt{docstrip} package},
subtitle = {Remove comments from file},
author = {Frank Mittelbach and {The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-01},
version = {2.6b},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -19428,6 +19531,17 @@
creates a correct hyperlink to the target of the DOI.},
}
+@manual{ctan-doibanner,
+ title = {The \texttt{doibanner} package},
+ subtitle = {Generate DOI banners and links},
+ author = {Christian Schreinemachers},
+ date = {2024-07-28},
+ version = {0.3},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/doibanner},
+ url = {https://ctan.org/pkg/doibanner},
+}
+
@manual{ctan-doipubmed,
title = {The \texttt{doipubmed} package},
subtitle = {Special commands for use in bibliographies},
@@ -19443,6 +19557,17 @@
file is also provided.},
}
+@manual{ctan-domaincoloring,
+ title = {The \texttt{domaincoloring} package},
+ subtitle = {Draw colored represenations of complex functions},
+ author = {Herbert Voß},
+ date = {2024-09-16},
+ version = {0.05},
+ license = {lppl1.3},
+ mirror = {https://mirror.ctan.org/macros/luatex/latex/domaincoloring},
+ url = {https://ctan.org/pkg/domaincoloring},
+}
+
@manual{ctan-domitian,
title = {The \texttt{domitian} package},
subtitle = {Drop-in replacement for Palatino},
@@ -20045,8 +20170,8 @@
title = {The \texttt{dtk-bibliography} package},
subtitle = {Bibliography of “Die \TeX{}nische Komödie”},
author = {Uwe Ziegenhagen},
- date = {2024-03-08},
- version = {2024-01},
+ date = {2024-09-14},
+ version = {2024-03},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/info/dtk-bibliography},
url = {https://ctan.org/pkg/dtk-bibliography},
@@ -20056,8 +20181,8 @@
title = {The \texttt{dtk} package},
subtitle = {Document class for the journal of DANTE},
author = {Herbert Voß and Rolf Niepraschk},
- date = {2024-02-23},
- version = {2.10e},
+ date = {2024-07-10},
+ version = {2.10f},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/usergrps/dante/dtk},
url = {https://ctan.org/pkg/dtk},
@@ -20321,7 +20446,7 @@
title = {The \texttt{DVIasm} package},
subtitle = {A utility for editing DVI files},
author = {Jin-Hwan Cho and Khaled Hosny and Hironobu Yamashita},
- date = {2023-08-23},
+ date = {2024-07-25},
version = {},
license = {gpl3+},
mirror = {https://mirror.ctan.org/dviware/dviasm},
@@ -20761,8 +20886,8 @@
title = {The \texttt{dynkin-diagrams} package},
subtitle = {Draw Dynkin, Coxeter, and Satake diagrams using TikZ},
author = {Benjamin McKay},
- date = {2023-06-02},
- version = {3.1415926535897932384},
+ date = {2024-07-06},
+ version = {3.14159265358979323846},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/dynkin-diagrams},
url = {https://ctan.org/pkg/dynkin-diagrams},
@@ -20873,8 +20998,8 @@
title = {The \texttt{easybook} package},
subtitle = {Easily typesetting Chinese theses or books},
author = {Qu Yi},
- date = {2024-05-16},
- version = {2024br},
+ date = {2024-09-24},
+ version = {2024dx},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/easybook},
url = {https://ctan.org/pkg/easybook},
@@ -20885,8 +21010,8 @@
with the general framework design of the dissertation of many
universities in China, providing multiple commands and
interfaces allows users to easily customize the thesis template.
- Its basic macro package easybase can also be used with CTeX and
- standard document classes.},
+ Its basic macro package can also be used with
+ CTeX and standard document classes.},
}
@manual{ctan-easydtx,
@@ -21423,7 +21548,7 @@
title = {The \texttt{edmac} package},
subtitle = {Typeset critical editions},
author = {John Lavagnino and Dominik Wujastyk},
- date = {2021-08-26},
+ date = {2024-09-10},
version = {3.17},
license = {gpl2},
mirror = {https://mirror.ctan.org/macros/plain/contrib/edmac},
@@ -21441,6 +21566,17 @@
url = {https://ctan.org/pkg/edmargin},
}
+@manual{ctan-edmaths,
+ title = {The \texttt{edmaths} package},
+ subtitle = {A report and thesis class file for the University of Edinburgh (UoE)},
+ author = {Josh Fogg},
+ date = {2024-09-01},
+ version = {0.99},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/edmaths},
+ url = {https://ctan.org/pkg/edmaths},
+}
+
@manual{ctan-ednotes,
title = {The \texttt{ednotes} package},
subtitle = {Typeset scholarly editions},
@@ -21888,8 +22024,8 @@
title = {The \texttt{elpres} package},
subtitle = {A simple class for electronic presentations},
author = {Volker Kiefel},
- date = {2021-08-10},
- version = {1.0.1},
+ date = {2024-05-29},
+ version = {1.1},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/elpres},
url = {https://ctan.org/pkg/elpres},
@@ -22055,7 +22191,7 @@
title = {The \texttt{emisa} package},
subtitle = {A \LaTeX{} package for preparing manuscripts for the journal EMISA},
author = {Martin Sievers and Stefan Strecker},
- date = {2020-11-26},
+ date = {2024-07-20},
version = {2.3.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/emisa},
@@ -22486,6 +22622,17 @@
the font can be found in the documentation of chessfss.},
}
+@manual{ctan-ensps-colorscheme,
+ title = {The \texttt{ensps-colorscheme} package},
+ subtitle = {Color palette and styling of ENS Paris-Saclay},
+ author = {Aliaume Lopez},
+ date = {2024-06-14},
+ version = {0.0.1},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/ensps-colorscheme},
+ url = {https://ctan.org/pkg/ensps-colorscheme},
+}
+
@manual{ctan-enumerate,
title = {The \texttt{enumerate} package},
subtitle = {Enumerate with redefinable labels},
@@ -22563,6 +22710,26 @@
url = {https://ctan.org/pkg/envelope},
}
+@manual{ctan-enverb,
+ title = {The \texttt{enverb} package},
+ subtitle = {Read an environment verbatim},
+ author = {Jonathan P. Spratte},
+ date = {2024-09-01},
+ version = {1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/enverb},
+ url = {https://ctan.org/pkg/enverb},
+ annotation = {This package allows you to collect the contents of an
+ environment verbatim, and provides that inside the macro
+ . What you then do with that content
+ is up to you. It also allows you to place arbitrary content
+ at the start and end of each line (which doesn’t have to be verbatim).
+ The two convenience macros and
+ can be used to typeset the contents
+ and wrap the contents inside another verbatim environment,
+ respectively.},
+}
+
@manual{ctan-environ,
title = {The \texttt{environ} package},
subtitle = {A new interface for environments in \LaTeX{}},
@@ -22807,7 +22974,7 @@
title = {The \texttt{epsfig} package},
subtitle = {Include Encapsulated PostScript in \LaTeX{} documents},
author = {Sebastian Rahtz and David Carlisle and {The LaTeX Project Team}},
- date = {2021-06-01},
+ date = {2024-06-02},
version = {1.7b},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/graphics},
@@ -22969,8 +23136,8 @@
title = {The \texttt{epstopdf} package},
subtitle = {Convert EPS to PDF using Ghostscript},
author = {Gerben Wierda and Sebastian Rahtz and Thomas Esser and Heiko Oberdiek and Karl Berry},
- date = {2024-04-29},
- version = {2.34},
+ date = {2024-07-12},
+ version = {2.36},
license = {other-free},
mirror = {https://mirror.ctan.org/support/epstopdf},
url = {https://ctan.org/pkg/epstopdf},
@@ -23269,8 +23436,8 @@
title = {The \texttt{esami} package},
subtitle = {Typeset exams with scrambled questions and answers},
author = {Grazia Messineo and Salvatore Vassallo},
- date = {2023-07-22},
- version = {2.8},
+ date = {2024-07-07},
+ version = {2.9},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/esami},
url = {https://ctan.org/pkg/esami},
@@ -23889,6 +24056,17 @@
url = {https://ctan.org/pkg/euroitc},
}
+@manual{ctan-euromoney,
+ title = {The \texttt{euromoney} package},
+ subtitle = {Vectorial coins and banknotes in euro, with stacking option},
+ author = {Cédric Pierquet},
+ date = {2024-09-16},
+ version = {0.1.1},
+ license = {lppl1.3c,pd},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/euromoney},
+ url = {https://ctan.org/pkg/euromoney},
+}
+
@manual{ctan-europasscv,
title = {The \texttt{europasscv} package},
subtitle = {Unofficial class for the new version of the Europass curriculum vitae},
@@ -24474,7 +24652,7 @@
title = {The \texttt{expl3} package},
subtitle = {Wrapper package for experimental \LaTeX{}3},
author = {{The LaTeX Project Team}},
- date = {2024-04-30},
+ date = {2024-09-23},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/l3kernel},
@@ -24649,6 +24827,17 @@
url = {https://ctan.org/pkg/extsizes},
}
+@manual{ctan-ezedits,
+ title = {The \texttt{ezedits} package},
+ subtitle = {Commands for tracking document changes and notes},
+ author = {Joseph A. Smiga},
+ date = {2024-09-16},
+ version = {1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/ezedits},
+ url = {https://ctan.org/pkg/ezedits},
+}
+
@manual{ctan-fac,
title = {The \texttt{fac} package},
subtitle = {Macros for FAC journal},
@@ -24858,8 +25047,8 @@
title = {The \texttt{fancyhdr} package},
subtitle = {Extensive control of page headers and footers in \LaTeX{}2e},
author = {Pieter van Oostrum},
- date = {2024-04-24},
- version = {4.2},
+ date = {2024-07-23},
+ version = {4.3.1},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/fancyhdr},
url = {https://ctan.org/pkg/fancyhdr},
@@ -25457,9 +25646,9 @@
@manual{ctan-fge,
title = {The \texttt{fge} package},
- subtitle = {A font for Frege's Grundgesetze der Arithmetik},
+ subtitle = {A font for Frege’s Grundgesetze der Arithmetik},
author = {J.J. Green},
- date = {2023-09-20},
+ date = {2024-06-28},
version = {1.25},
license = {lppl},
mirror = {https://mirror.ctan.org/fonts/fge},
@@ -25886,6 +26075,25 @@
url = {https://ctan.org/pkg/fillform},
}
+@manual{ctan-fillwith,
+ title = {The \texttt{fillwith} package},
+ subtitle = {Fill vertical space with solid rules or dotted lines},
+ author = {Clea F. Rees},
+ date = {2024-09-01},
+ version = {0.3},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/fillwith},
+ url = {https://ctan.org/pkg/fillwith},
+ annotation = {A \LaTeX{} package for filling vertical space with something
+ rather than nothing.
+ Currently supported somethings are solid rules and dotted lines,
+ with or without numbers.
+ The package uses a mixture of plain-ish macros, \LaTeX{}2e and
+ methods, but a key-value
+ approach to configuration should make the document-level
+ interface relatively sane, even if nothing else is.},
+}
+
@manual{ctan-findbib,
title = {The \texttt{findbib} package},
subtitle = {Find bibliographic details from SPIRES},
@@ -26711,8 +26919,8 @@
title = {The \texttt{fmtcount} package},
subtitle = {Display the value of a \LaTeX{} counter in a variety of formats},
author = {Nicola Talbot and Vincent Belaïche and Erik Nijenhuis},
- date = {2024-02-11},
- version = {3.07},
+ date = {2024-08-31},
+ version = {3.08},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/fmtcount},
url = {https://ctan.org/pkg/fmtcount},
@@ -27099,8 +27307,9 @@
title = {The \texttt{fontenc} package},
subtitle = {Standard package for selecting font encodings},
author = {{The LaTeX Project Team}},
- date = {2016-06-24},
+ date = {2024-05-29},
license = {lppl},
+ mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/fontenc},
}
@@ -27230,8 +27439,8 @@
title = {The \texttt{fontscale} package},
subtitle = {A flexible interface for setting font sizes},
author = {Oliver Beery},
- date = {2024-05-17},
- version = {1.3.0},
+ date = {2024-09-11},
+ version = {2.4.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/fontscale},
url = {https://ctan.org/pkg/fontscale},
@@ -27255,8 +27464,8 @@
title = {The \texttt{fontsetup} package},
subtitle = {A front-end to fontspec, for selected fonts with math support},
author = {Antonis Tsolomitis},
- date = {2024-02-24},
- version = {2.1.1},
+ date = {2024-09-12},
+ version = {2.2.1},
license = {gpl3},
mirror = {https://mirror.ctan.org/macros/unicodetex/latex/fontsetup},
url = {https://ctan.org/pkg/fontsetup},
@@ -27282,8 +27491,8 @@
@manual{ctan-fontsmpl,
title = {The \texttt{fontsmpl} package},
subtitle = {Print a sample of a font},
- author = {Alan Jeffrey},
- date = {2021-01-03},
+ author = {{The LaTeX Project Team} and Alan Jeffrey},
+ date = {2024-07-09},
version = {0.11},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
@@ -27637,8 +27846,8 @@
title = {The \texttt{fourier} package},
subtitle = {Using Utopia fonts in \LaTeX{} documents},
author = {Michel Bovani},
- date = {2022-02-07},
- version = {2.3},
+ date = {2024-09-09},
+ version = {2.4},
license = {lppl},
mirror = {https://mirror.ctan.org/fonts/fourier-GUT},
url = {https://ctan.org/pkg/fourier},
@@ -27767,6 +27976,17 @@
url = {https://ctan.org/pkg/framed},
}
+@manual{ctan-framedsyntax,
+ title = {The \texttt{FramedSyntax} package},
+ subtitle = {Typeset the syntax of commands and environments within coloured boxes},
+ author = {Claudio Beccari},
+ date = {2024-09-16},
+ version = {0.2.8},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/framedsyntax},
+ url = {https://ctan.org/pkg/framedsyntax},
+}
+
@manual{ctan-francais-bst,
title = {The \texttt{francais-bst} package},
subtitle = {Bibliographies conforming to French typographic standards},
@@ -28400,11 +28620,18 @@
title = {The \texttt{fvextra} package},
subtitle = {Extensions and patches for fancyvrb},
author = {Geoffrey Poore},
- date = {2024-05-16},
- version = {1.7.0},
+ date = {2024-09-14},
+ version = {1.8.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/fvextra},
url = {https://ctan.org/pkg/fvextra},
+ annotation = {This package provides several extensions to
+ , including
+ automatic line breaking and improved math mode.
+ It also patches some
+ internals.
+ Parts of fvextra were originally developed as part of
+ pythontex and minted.},
}
@manual{ctan-fweb,
@@ -28754,6 +28981,21 @@
url = {https://ctan.org/pkg/gelasio},
}
+@manual{ctan-gelasiomath,
+ title = {The \texttt{gelasiomath} package},
+ subtitle = {Math and small cap additions to Gelasio fonts},
+ author = {Michael Sharpe},
+ date = {2024-07-08},
+ version = {1.00},
+ license = {ofl,lppl1.3},
+ mirror = {https://mirror.ctan.org/fonts/gelasiomath},
+ url = {https://ctan.org/pkg/gelasiomath},
+ annotation = {The package offers math support for the package,
+ using symbols from newtxmath, Roman math letters from Gelasio and Greek math letters
+ based on XCharter Greek. Also added small caps based on XCharter small caps and other
+ minor features to Gelasio.},
+}
+
@manual{ctan-gellmu,
title = {The \texttt{GELLMU} package},
subtitle = {LaTeX-like markup for writing XML documents},
@@ -28893,7 +29135,7 @@
title = {The \texttt{gentium-original} package},
subtitle = {Gentium font and support files},
author = {Thomas A. Schmitz and Mojca Miklavec},
- date = {2022-05-26},
+ date = {2024-07-25},
version = {},
license = {ofl},
mirror = {https://mirror.ctan.org/obsolete/fonts/gentium},
@@ -28904,7 +29146,7 @@
title = {The \texttt{gentium-tug} package},
subtitle = {Gentium fonts (in two formats) and support files},
author = {Karl Berry and Mojca Miklavec and Pavel Farar and Thomas A. Schmitz},
- date = {2022-06-01},
+ date = {2024-07-25},
version = {1.102},
license = {ofl,other-free},
mirror = {https://mirror.ctan.org/fonts/gentium-tug},
@@ -29443,8 +29685,8 @@
title = {The \texttt{gitinfo-lua} package},
subtitle = {Display git project information in your \LaTeX{} projects},
author = {Erik Nijenhuis},
- date = {2024-04-11},
- version = {1.1.0},
+ date = {2024-09-14},
+ version = {1.2.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/luatex/latex/gitinfo-lua},
url = {https://ctan.org/pkg/gitinfo-lua},
@@ -30381,9 +30623,9 @@
title = {The \texttt{graphics-pln} package},
subtitle = {LaTeX-style graphics for Plain \TeX{} users},
author = {David Carlisle},
- date = {2023-11-09},
+ date = {2024-06-20},
version = {},
- license = {lppl1},
+ license = {lppl},
mirror = {https://mirror.ctan.org/macros/plain/graphics},
url = {https://ctan.org/pkg/graphics-pln},
}
@@ -30392,8 +30634,8 @@
title = {The \texttt{graphics} package},
subtitle = {Standard \LaTeX{} graphics},
author = {David Carlisle and {The LaTeX Project Team}},
- date = {2022-06-08},
- version = {1.4e},
+ date = {2024-06-02},
+ version = {1.4g},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/graphics},
url = {https://ctan.org/pkg/graphics},
@@ -30833,8 +31075,8 @@
title = {The \texttt{gridset} package},
subtitle = {Grid, a.k.a. in-register, setting},
author = {Markus Kohm},
- date = {2020-02-12},
- version = {0.3},
+ date = {2024-08-17},
+ version = {0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/gridset},
url = {https://ctan.org/pkg/gridset},
@@ -31506,9 +31748,9 @@
title = {The \texttt{harmony} package},
subtitle = {Typeset harmony symbols, etc., for musicology},
author = {Dagny Wegner and Arnim Wegner},
- date = {2016-06-24},
+ date = {2024-08-16},
version = {},
- license = {lppl},
+ license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/harmony},
url = {https://ctan.org/pkg/harmony},
annotation = {The package harmony.sty uses the packages
@@ -31669,6 +31911,17 @@
url = {https://ctan.org/pkg/headerfooter},
}
+@manual{ctan-hebdomon,
+ title = {The \texttt{Hebdomon} package},
+ subtitle = {A document class for report writing in university settings},
+ author = {Daniel T. McGuiness},
+ date = {2024-09-01},
+ version = {0.1},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/hebdomon},
+ url = {https://ctan.org/pkg/hebdomon},
+}
+
@manual{ctan-hebrew-fonts,
title = {The \texttt{hebrew-fonts} package},
subtitle = {Input encodings, font encodings and font definition files for Hebrew},
@@ -31972,9 +32225,9 @@
title = {The \texttt{heria} package},
subtitle = {A \LaTeX{} class for Horizon Europe RIA and IA grant proposals},
author = {Tristan Miller},
- date = {2023-12-11},
- version = {3.2.1.0},
- license = {lppl1.3},
+ date = {2024-09-04},
+ version = {3.4.1.3},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/heria},
url = {https://ctan.org/pkg/heria},
}
@@ -33010,8 +33263,8 @@
title = {The \texttt{hvqrurl} package},
subtitle = {Insert a QR code in the margin},
author = {Herbert Voß},
- date = {2024-05-14},
- version = {0.08},
+ date = {2024-05-26},
+ version = {0.09},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/hvqrurl},
url = {https://ctan.org/pkg/hvqrurl},
@@ -33099,10 +33352,10 @@
title = {The \texttt{hypcap} package},
subtitle = {Adjusting the anchors of captions},
author = {Heiko Oberdiek},
- date = {2018-01-06},
- version = {1.12},
- license = {lppl1.3},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/oberdiek/hypcap.dtx},
+ date = {2024-08-07},
+ version = {1.13},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/hypcap},
url = {https://ctan.org/pkg/hypcap},
}
@@ -33110,8 +33363,8 @@
title = {The \texttt{hypdestopt} package},
subtitle = {Hyperref destination optimizer},
author = {Heiko Oberdiek},
- date = {2020-09-07},
- version = {2.7},
+ date = {2024-08-07},
+ version = {2.8},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/hypdestopt},
url = {https://ctan.org/pkg/hypdestopt},
@@ -33207,8 +33460,8 @@
title = {The \texttt{hyperref} package},
subtitle = {Extensive support for hypertext in \LaTeX{}},
author = {Heiko Oberdiek and Sebastian Rahtz and {Oberdiek Package Support Group} and {The LaTeX Project Team}},
- date = {2024-01-21},
- version = {7.01h},
+ date = {2024-07-10},
+ version = {7.01j},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/hyperref},
url = {https://ctan.org/pkg/hyperref},
@@ -33393,8 +33646,8 @@
title = {The \texttt{iaria-lite} package},
subtitle = {Write documents for the IARIA publications},
author = {Christoph P. Neumann},
- date = {2024-04-10},
- version = {0.2},
+ date = {2024-09-17},
+ version = {0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/iaria-lite},
url = {https://ctan.org/pkg/iaria-lite},
@@ -33404,8 +33657,8 @@
title = {The \texttt{iaria} package},
subtitle = {Write documents for the IARIA publications},
author = {Christoph P. Neumann},
- date = {2024-04-10},
- version = {0.2},
+ date = {2024-09-17},
+ version = {0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/iaria},
url = {https://ctan.org/pkg/iaria},
@@ -33605,8 +33858,8 @@
title = {The \texttt{IdeaVault} package},
subtitle = {Idea (concept) management package},
author = {Tomasz M. Czarkowski},
- date = {2024-03-27},
- version = {1.0.1},
+ date = {2024-06-25},
+ version = {1.0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/luatex/latex/ideavault},
url = {https://ctan.org/pkg/ideavault},
@@ -33997,8 +34250,8 @@
title = {The \texttt{ifthen} package},
subtitle = {Conditional commands in \LaTeX{} documents},
author = {Leslie Lamport and David Carlisle and {The LaTeX Project Team}},
- date = {2024-01-15},
- version = {1.1d},
+ date = {2024-06-01},
+ version = {1.1e},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/ifthen},
@@ -34218,7 +34471,7 @@
title = {The \texttt{imfellflowers} package},
subtitle = {IM Fell Flower OpenType fonts},
author = {Bob Tennent},
- date = {2023-08-15},
+ date = {2024-07-25},
version = {},
license = {nosell},
mirror = {https://mirror.ctan.org/fonts/imfellflowers},
@@ -34569,8 +34822,8 @@
title = {The \texttt{innerscript} package},
subtitle = {Small modifications to math formatting},
author = {Conrad Kosowsky},
- date = {2023-11-06},
- version = {1.2},
+ date = {2024-08-19},
+ version = {1.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/luatex/latex/innerscript},
url = {https://ctan.org/pkg/innerscript},
@@ -34587,7 +34840,7 @@
title = {The \texttt{inputenc} package},
subtitle = {Accept different input encodings},
author = {Alan Jeffrey and Frank Mittelbach and {The LaTeX Project Team}},
- date = {2021-06-01},
+ date = {2024-06-01},
version = {1.3d},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -34733,8 +34986,8 @@
title = {The \texttt{Install-LaTeX-Guide-zh-cn} package},
subtitle = {A short introduction to \LaTeX{} installation written in Chinese},
author = {Ran Wang},
- date = {2024-03-31},
- version = {2024.4.1},
+ date = {2024-09-01},
+ version = {2024.9.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/info/install-latex-guide-zh-cn},
url = {https://ctan.org/pkg/install-latex-guide-zh-cn},
@@ -34836,6 +35089,23 @@
url = {https://ctan.org/pkg/interfaces},
}
+@manual{ctan-interlinear,
+ title = {The \texttt{interlinear} package},
+ subtitle = {A package for creating interlinear glossed texts with customizable formatting},
+ author = {Akpoué Kouamé Josué},
+ date = {2024-09-01},
+ version = {1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/interlinear},
+ url = {https://ctan.org/pkg/interlinear},
+ annotation = {The package facilitates the creation of interlinear glossed texts,
+ commonly used in linguistic examples. It is based on the
+ package and builds upon its functionality to provide enhanced features. It offers extensive
+ customization options, allowing users to control font styles, formatting, and layout.
+ With predefined styles and margin note customization, provides a flexible
+ solution for presenting linguistic data.},
+}
+
@manual{ctan-interpol,
title = {The \texttt{interpol} package},
subtitle = {Add interpolation to MetaPost graph package},
@@ -35047,8 +35317,8 @@
title = {The \texttt{iran-bibtex} package},
subtitle = {Iran Manual of Style Citation Guide for BibTeX},
author = {Farshad Rasuli},
- date = {2024-05-06},
- version = {0.4.1},
+ date = {2024-08-04},
+ version = {0.4.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/biblio/bibtex/contrib/iran-bibtex},
url = {https://ctan.org/pkg/iran-bibtex},
@@ -35266,8 +35536,8 @@
title = {The \texttt{isosafety} package},
subtitle = {Provides ISO signs and colors according to the standards 7010 and 3864},
author = {Ben Steinhauer},
- date = {2023-11-09},
- version = {1.1},
+ date = {2024-09-08},
+ version = {1.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/isosafety},
url = {https://ctan.org/pkg/isosafety},
@@ -35457,8 +35727,8 @@
title = {The \texttt{iwonamath} package},
subtitle = {LaTeX support for scaled Iwona math fonts},
author = {Boris Veytsman},
- date = {2023-09-04},
- version = {1.0},
+ date = {2024-07-19},
+ version = {1.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/iwonamath},
url = {https://ctan.org/pkg/iwonamath},
@@ -35907,7 +36177,7 @@
title = {The \texttt{jlreq} package},
subtitle = {Japanese document class based on requirements for Japanese text layout},
author = {Noriyuki Abe},
- date = {2024-02-16},
+ date = {2024-08-23},
version = {},
license = {bsd2},
mirror = {https://mirror.ctan.org/macros/jptex/latex/jlreq},
@@ -35978,8 +36248,8 @@
title = {The \texttt{jnuexam} package},
subtitle = {Exam class for Jinan University},
author = {Jianrui Lyu},
- date = {2024-03-14},
- version = {2024E},
+ date = {2024-07-09},
+ version = {2024F},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/jnuexam},
url = {https://ctan.org/pkg/jnuexam},
@@ -36005,8 +36275,8 @@
title = {The \texttt{joinbox} package},
subtitle = {Join boxes vertically or horizontally},
author = {Nan Geng},
- date = {2023-08-21},
- version = {1.0.2},
+ date = {2024-09-09},
+ version = {1.0.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/joinbox},
url = {https://ctan.org/pkg/joinbox},
@@ -36184,8 +36454,8 @@
title = {The \texttt{jsonparse} package},
subtitle = {Parse, store and access JSON data in \LaTeX{} documents},
author = {Jasper Habicht},
- date = {2024-05-09},
- version = {0.8.6},
+ date = {2024-08-27},
+ version = {0.9.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/jsonparse},
url = {https://ctan.org/pkg/jsonparse},
@@ -36239,8 +36509,8 @@
title = {The \texttt{Junicode} package},
subtitle = {A TrueType and OpenType font family for mediaevalists},
author = {Peter S. Baker and Bob Tennent},
- date = {2024-04-24},
- version = {2.206},
+ date = {2024-07-21},
+ version = {2.209},
license = {ofl,lppl},
mirror = {https://mirror.ctan.org/fonts/junicode},
url = {https://ctan.org/pkg/junicode},
@@ -36250,8 +36520,8 @@
title = {The \texttt{junicodevf} package},
subtitle = {A TrueType variable font family for mediaevalists},
author = {Peter S. Baker and Bob Tennent},
- date = {2024-01-09},
- version = {2.206},
+ date = {2024-07-21},
+ version = {2.209},
license = {ofl,lppl},
mirror = {https://mirror.ctan.org/fonts/junicodevf},
url = {https://ctan.org/pkg/junicodevf},
@@ -36261,8 +36531,8 @@
title = {The \texttt{jupynotex} package},
subtitle = {Include whole or partial Jupyter notebooks in \LaTeX{} documents},
author = {Facundo Batista},
- date = {2020-10-28},
- version = {0.1},
+ date = {2024-09-24},
+ version = {1.0},
license = {apache2},
mirror = {https://mirror.ctan.org/macros/latex/contrib/jupynotex},
url = {https://ctan.org/pkg/jupynotex},
@@ -36356,7 +36626,7 @@
title = {The \texttt{jwjournal} package},
subtitle = {A personal class for writing journals},
author = {Jinwen XU},
- date = {2023-12-18},
+ date = {2024-09-02},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/jwjournal},
@@ -36481,8 +36751,8 @@
title = {The \texttt{kaytannollista-latexia} package},
subtitle = {Practical manual for \LaTeX{} (Finnish)},
author = {Teemu Likonen},
- date = {2024-02-12},
- version = {2024.2},
+ date = {2024-07-12},
+ version = {2024.7},
license = {cc-by-sa-4},
mirror = {https://mirror.ctan.org/info/kaytannollista-latexia},
url = {https://ctan.org/pkg/kaytannollista-latexia},
@@ -36692,6 +36962,23 @@
url = {https://ctan.org/pkg/keystroke},
}
+@manual{ctan-keytheorems,
+ title = {The \texttt{keytheorems} package},
+ subtitle = {An l3keys interface to amsthm},
+ author = {Matthew Bertucci},
+ date = {2024-09-23},
+ version = {0.1.4},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/keytheorems},
+ url = {https://ctan.org/pkg/keytheorems},
+ annotation = {An -implementation of a
+ key-value interface to ,
+ implementing most of the functionality provided by
+ .
+ Several issues encountered with thmtools are avoided
+ (see the README for a list) and a few new features are added.},
+}
+
@manual{ctan-keyval,
title = {The \texttt{keyval} package},
subtitle = {Process 'key=value' schemes},
@@ -36927,8 +37214,8 @@
title = {The \texttt{knuth-hint} package},
subtitle = {HINT collection of typeset C/WEB sources in \TeX{} Live},
author = {Andreas Scherer},
- date = {2024-03-16},
- version = {2.2},
+ date = {2024-08-12},
+ version = {2.5},
license = {pd,knuth},
mirror = {https://mirror.ctan.org/info/knuth-hint},
url = {https://ctan.org/pkg/knuth-hint},
@@ -36977,8 +37264,8 @@
title = {The \texttt{knuth-pdf} package},
subtitle = {PDF collection of typeset C/WEB sources in \TeX{} Live},
author = {Andreas Scherer},
- date = {2024-03-16},
- version = {2.2},
+ date = {2024-08-12},
+ version = {2.5},
license = {pd},
mirror = {https://mirror.ctan.org/info/knuth-pdf},
url = {https://ctan.org/pkg/knuth-pdf},
@@ -37147,7 +37434,7 @@
title = {The \texttt{KorigamiK} package},
subtitle = {Typeset articles using KorigamiK’s document class},
author = {Kushagra Lakhwani},
- date = {2023-08-24},
+ date = {2024-08-03},
version = {1.0},
license = {gpl3+},
mirror = {https://mirror.ctan.org/macros/latex/contrib/korigamik},
@@ -37501,7 +37788,7 @@
title = {The \texttt{l3backend} package},
subtitle = {LaTeX3 backend drivers},
author = {{The LaTeX Project Team}},
- date = {2024-04-30},
+ date = {2024-07-25},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/l3backend},
@@ -37512,7 +37799,7 @@
title = {The \texttt{l3build} package},
subtitle = {A testing and building system for (La)TeX},
author = {{The LaTeX Project Team}},
- date = {2024-02-08},
+ date = {2024-05-27},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3build},
@@ -37523,7 +37810,7 @@
title = {The \texttt{l3docstrip} package},
subtitle = {Strip documentation in \LaTeX{}3 source},
author = {{The LaTeX Project Team}},
- date = {2024-04-30},
+ date = {2024-09-23},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/l3kernel},
@@ -37534,7 +37821,7 @@
title = {The \texttt{l3experimental} package},
subtitle = {Experimental \LaTeX{}3 concepts},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-07-25},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3experimental},
@@ -37545,7 +37832,7 @@
title = {The \texttt{l3kernel-dev} package},
subtitle = {Development pre-release of l3kernel},
author = {{The LaTeX Project Team}},
- date = {2024-05-11},
+ date = {2024-09-10},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/required/l3kernel},
@@ -37561,7 +37848,7 @@
title = {The \texttt{l3kernel} package},
subtitle = {LaTeX3 programming conventions},
author = {{The LaTeX Project Team}},
- date = {2024-04-30},
+ date = {2024-09-23},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/l3kernel},
@@ -37572,7 +37859,7 @@
title = {The \texttt{l3keys2e} package},
subtitle = {LaTeX2e option processing using \LaTeX{}3 keys},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-08-28},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3packages},
@@ -37583,7 +37870,7 @@
title = {The \texttt{l3packages} package},
subtitle = {High-level \LaTeX{}3 concepts},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-08-28},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3packages},
@@ -37594,7 +37881,7 @@
title = {The \texttt{l3regex} package},
subtitle = {Regular expression facilities for \LaTeX{}},
author = {{The LaTeX Project Team}},
- date = {2024-04-30},
+ date = {2024-09-23},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/l3kernel/l3regex.dtx},
@@ -37815,7 +38102,7 @@
title = {The \texttt{lambda-lists} package},
subtitle = {Lists in \TeX{}'s mouth},
author = {Alan Jeffrey},
- date = {2016-06-24},
+ date = {2024-07-09},
version = {},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/generic/lambda-lists},
@@ -37993,8 +38280,8 @@
title = {The \texttt{lastpage} package},
subtitle = {Reference last page for Page N of M type footers},
author = {Hans-Martin Münch and Jeffrey Goldberg},
- date = {2024-04-27},
- version = {2.1a},
+ date = {2024-07-07},
+ version = {2.1c},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/lastpage},
url = {https://ctan.org/pkg/lastpage},
@@ -38031,8 +38318,8 @@
title = {The \texttt{latex-amsmath-dev} package},
subtitle = {Development pre-release of the \LaTeX{} amsmath bundle},
author = {{The LaTeX Project Team}},
- date = {2024-03-27},
- version = {2024-06-01 pre-release 2},
+ date = {2024-06-03},
+ version = {2024-11-01 pre-release 0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/required/amsmath},
url = {https://ctan.org/pkg/latex-amsmath-dev},
@@ -38047,7 +38334,7 @@
title = {The \texttt{latex-amsmath} package},
subtitle = {AMS mathematical facilities for \LaTeX{}},
author = {{The LaTeX Project Team}},
- date = {2023-11-01},
+ date = {2024-06-02},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/amsmath},
@@ -38058,8 +38345,8 @@
title = {The \texttt{latex-base-dev} package},
subtitle = {Development pre-release of the \LaTeX{} kernel},
author = {{The LaTeX Project Team}},
- date = {2024-03-27},
- version = {2024-06-01 pre-release 2},
+ date = {2024-08-23},
+ version = {2024-11-01 pre-release 3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/base},
url = {https://ctan.org/pkg/latex-base-dev},
@@ -38076,8 +38363,8 @@
title = {The \texttt{latex-base} package},
subtitle = {Base sources of \LaTeX{}},
author = {{The LaTeX Project Team} and Frank Mittelbach},
- date = {2024-02-11},
- version = {2023-11-01 PL1},
+ date = {2024-06-26},
+ version = {2024-06-01 PL2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/latex-base},
@@ -38166,8 +38453,8 @@
title = {The \texttt{cyrillic} package},
subtitle = {Support for Cyrillic fonts in \LaTeX{}},
author = {{The LaTeX Project Team}},
- date = {2022-06-16},
- version = {2022-06-01-PL1},
+ date = {2024-06-02},
+ version = {},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/required/cyrillic},
url = {https://ctan.org/pkg/latex-cyrillic},
@@ -38199,8 +38486,8 @@
title = {The \texttt{latex-doc} package},
subtitle = {Documentation supplied as part of the \LaTeX{} distribution},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
- version = {2023-11-01 PL1},
+ date = {2024-06-26},
+ version = {2024-06-01 PL2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/latex-doc},
@@ -38257,8 +38544,8 @@
title = {The \texttt{latex-firstaid} package},
subtitle = {First aid for external \LaTeX{} files and packages that need updating},
author = {{The LaTeX Project Team}},
- date = {2024-03-01},
- version = {1.1c},
+ date = {2024-06-26},
+ version = {1.1f},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/firstaid},
url = {https://ctan.org/pkg/latex-firstaid},
@@ -38289,8 +38576,8 @@
title = {The \texttt{latex-git-log} package},
subtitle = {Typeset git log information},
author = {Robin Schneider},
- date = {2020-02-27},
- version = {1.0.0},
+ date = {2024-05-31},
+ version = {1.1.0},
license = {gpl3+},
mirror = {https://mirror.ctan.org/support/latex-git-log},
url = {https://ctan.org/pkg/latex-git-log},
@@ -38300,8 +38587,8 @@
title = {The \texttt{latex-graphics-dev} package},
subtitle = {Development pre-release of the \LaTeX{} graphics bundle},
author = {{The LaTeX Project Team}},
- date = {2023-11-02},
- version = {2024-06-01 pre-release 0},
+ date = {2024-08-15},
+ version = {2024-11-01 pre-release 2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/required/graphics},
url = {https://ctan.org/pkg/latex-graphics-dev},
@@ -38316,7 +38603,7 @@
title = {The \texttt{latex-graphics} package},
subtitle = {The \LaTeX{} standard graphics bundle},
author = {{The LaTeX Project Team}},
- date = {2022-11-01},
+ date = {2024-06-02},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/graphics},
@@ -38349,8 +38636,8 @@
title = {The \texttt{latex-lab-dev} package},
subtitle = {LaTeX laboratory: Development pre-release},
author = {{The LaTeX Project Team}},
- date = {2024-03-27},
- version = {2024-06-01 pre-release 2},
+ date = {2024-08-23},
+ version = {2024-11-01 pre-release 3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/required/latex-lab},
url = {https://ctan.org/pkg/latex-lab-dev},
@@ -38367,7 +38654,7 @@
title = {The \texttt{latex-lab} package},
subtitle = {LaTeX laboratory},
author = {{The LaTeX Project Team}},
- date = {2023-11-01},
+ date = {2024-06-02},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/latex-lab},
@@ -38504,8 +38791,8 @@
title = {The \texttt{latex-tools-dev} package},
subtitle = {Development pre-release of the \LaTeX{} tools bundle},
author = {{The LaTeX Project Team}},
- date = {2024-03-27},
- version = {2024-06-01 pre-release 2},
+ date = {2024-08-15},
+ version = {2024-11-01 pre-release 2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex-dev/required/tools},
url = {https://ctan.org/pkg/latex-tools-dev},
@@ -38520,8 +38807,8 @@
title = {The \texttt{latex-tools} package},
subtitle = {The \LaTeX{} standard tools bundle},
author = {{The LaTeX Project Team}},
- date = {2023-11-21},
- version = {2023-11-01c},
+ date = {2024-06-14},
+ version = {2024-06-01a},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/latex-tools},
@@ -38602,8 +38889,8 @@
title = {The \texttt{latex} package},
subtitle = {A \TeX{} macro package that defines \LaTeX{}},
author = {{The LaTeX Project Team} and Leslie Lamport},
- date = {2024-01-15},
- version = {2023-11-01 PL1},
+ date = {2024-06-26},
+ version = {2024-06-01 PL2},
license = {lppl1.3c},
url = {https://ctan.org/pkg/latex},
}
@@ -38798,8 +39085,8 @@
title = {The \texttt{latexbug} package},
subtitle = {Bug-classification for \LaTeX{} related bugs},
author = {{The LaTeX Project Team}},
- date = {2022-06-14},
- version = {1.0n},
+ date = {2024-06-17},
+ version = {1.0o},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/latexbug},
url = {https://ctan.org/pkg/latexbug},
@@ -38926,8 +39213,8 @@
title = {The \texttt{latexdiff} package},
subtitle = {Determine and mark up significant differences between \LaTeX{} files},
author = {Frederik Tilmann},
- date = {2022-11-09},
- version = {1.3.3},
+ date = {2024-08-24},
+ version = {1.3.4},
license = {gpl3},
mirror = {https://mirror.ctan.org/support/latexdiff},
url = {https://ctan.org/pkg/latexdiff},
@@ -38998,8 +39285,8 @@
title = {The \texttt{latexindent} package},
subtitle = {Indent a \LaTeX{} document, highlighting the programming structure},
author = {Chris Hughes},
- date = {2024-05-12},
- version = {3.24.1},
+ date = {2024-07-18},
+ version = {3.24.4},
license = {gpl3},
mirror = {https://mirror.ctan.org/support/latexindent},
url = {https://ctan.org/pkg/latexindent},
@@ -39134,6 +39421,17 @@
.},
}
+@manual{ctan-latexscreenshooter,
+ title = {The \texttt{LaTeXScreenShooter} package},
+ subtitle = {Capture screenshots within \LaTeX{} documents},
+ author = {Quentin Vaney and Xavier Freléchoz},
+ date = {2024-06-30},
+ version = {},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/graphics/latexscreenshooter},
+ url = {https://ctan.org/pkg/latexscreenshooter},
+}
+
@manual{ctan-latexwide,
title = {The \texttt{LaTeX-WIDE} package},
subtitle = {Multifunctional editor for \LaTeX{}},
@@ -39263,7 +39561,7 @@
title = {The \texttt{lazylist} package},
subtitle = {Lists in \TeX{}’s “mouth”},
author = {Alan Jeffrey},
- date = {2016-06-24},
+ date = {2024-07-09},
version = {1.0a},
license = {lppl1.2},
mirror = {https://mirror.ctan.org/macros/latex/contrib/lazylist},
@@ -39564,8 +39862,8 @@
title = {The \texttt{LeteSansMath} package},
subtitle = {Lato-based OpenType Math font for LuaTeX and XeTeX},
author = {Daniel Flipo and Chenjing Bu},
- date = {2024-05-12},
- version = {0.40},
+ date = {2024-07-18},
+ version = {0.41},
license = {ofl,lppl1.3c},
mirror = {https://mirror.ctan.org/fonts/lete-sans-math},
url = {https://ctan.org/pkg/lete-sans-math},
@@ -39697,8 +39995,8 @@
title = {The \texttt{lettrine} package},
subtitle = {Typeset dropped capitals},
author = {Daniel Flipo},
- date = {2024-01-20},
- version = {2.60},
+ date = {2024-06-26},
+ version = {2.61},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/lettrine},
url = {https://ctan.org/pkg/lettrine},
@@ -39994,8 +40292,8 @@
title = {The \texttt{libertinus-fonts} package},
subtitle = {The Libertinus font family},
author = {Khaled Hosny and Caleb Maclennan},
- date = {2021-02-26},
- version = {7.040},
+ date = {2024-09-21},
+ version = {7.050},
license = {ofl},
mirror = {https://mirror.ctan.org/fonts/libertinus-fonts},
url = {https://ctan.org/pkg/libertinus-fonts},
@@ -40016,7 +40314,7 @@
title = {The \texttt{libertinus-type1} package},
subtitle = {Support for using Libertinus fonts with \LaTeX{}/pdfLaTeX},
author = {Bob Tennent},
- date = {2023-06-23},
+ date = {2024-09-22},
version = {},
license = {gpl2,ofl,lppl},
mirror = {https://mirror.ctan.org/fonts/libertinus-type1},
@@ -40038,8 +40336,8 @@
title = {The \texttt{LibertinusT1Math} package},
subtitle = {A Type 1 font and \LaTeX{} support for Libertinus Math},
author = {Michael Sharpe},
- date = {2024-01-15},
- version = {2.0.4},
+ date = {2024-06-03},
+ version = {2.0.6},
license = {ofl,lppl},
mirror = {https://mirror.ctan.org/fonts/libertinust1math},
url = {https://ctan.org/pkg/libertinust1math},
@@ -40126,8 +40424,8 @@
title = {The \texttt{lie-hasse} package},
subtitle = {Draw Hasse diagrams},
author = {Benjamin McKay},
- date = {2021-03-24},
- version = {1.0},
+ date = {2024-07-09},
+ version = {1.01},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/lie-hasse},
url = {https://ctan.org/pkg/lie-hasse},
@@ -40260,6 +40558,17 @@
url = {https://ctan.org/pkg/linearb},
}
+@manual{ctan-linearregression,
+ title = {The \texttt{linearregression} package},
+ subtitle = {Calculate and display linear regressions},
+ author = {Battista Benciolini},
+ date = {2024-06-14},
+ version = {},
+ license = {lppl},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/linearregression},
+ url = {https://ctan.org/pkg/linearregression},
+}
+
@manual{ctan-linebreaker,
title = {The \texttt{linebreaker} package},
subtitle = {Prevent overflow boxes with LuaLaTeX},
@@ -40513,8 +40822,8 @@
title = {The \texttt{listings} package},
subtitle = {Typeset source code listings using \LaTeX{}},
author = {Jobst Hoffmann and Brooks Moses and Carsten Heinz},
- date = {2024-03-12},
- version = {1.10a},
+ date = {2024-09-23},
+ version = {1.10c},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/listings},
url = {https://ctan.org/pkg/listings},
@@ -40632,8 +40941,8 @@
title = {The \texttt{LiteSolution} package},
subtitle = {A \LaTeX{} class for typesetting solutions of problems in exams, textbooks, etc.},
author = {Mingyu Xia},
- date = {2024-05-07},
- version = {2.2b},
+ date = {2024-08-15},
+ version = {2.4a},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/litesolution},
url = {https://ctan.org/pkg/litesolution},
@@ -40647,8 +40956,8 @@
title = {The \texttt{LiteTable} package},
subtitle = {Class schedules with colorful course blocks},
author = {Mingyu Xia},
- date = {2024-03-02},
- version = {2.4c},
+ date = {2024-09-25},
+ version = {3.0B},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/litetable},
url = {https://ctan.org/pkg/litetable},
@@ -40839,8 +41148,8 @@
title = {The \texttt{lni} package},
subtitle = {Official class for the “Lecture Notes in Informatics”},
author = {Martin Sievers},
- date = {2024-01-08},
- version = {1.8.1},
+ date = {2024-07-23},
+ version = {1.10},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/lni},
url = {https://ctan.org/pkg/lni},
@@ -41078,8 +41387,8 @@
title = {The \texttt{longmath} package},
subtitle = {Nested delimiter groups extending over multiple array cells or lines},
author = {Hans-Jürgen Matschull},
- date = {2024-03-27},
- version = {0.1},
+ date = {2024-07-04},
+ version = {1.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/latex/longmath},
url = {https://ctan.org/pkg/longmath},
@@ -41107,8 +41416,8 @@
title = {The \texttt{longtable} package},
subtitle = {Allow tables to flow over page boundaries},
author = {David Carlisle and David Kastrup and {The LaTeX Project Team}},
- date = {2023-11-01},
- version = {4.19},
+ date = {2024-06-02},
+ version = {4.20},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/longtable},
@@ -41694,8 +42003,8 @@
title = {The \texttt{lstaddons} package},
subtitle = {Add-on packages for listings: autogobble and line background},
author = {Martin Scharrer},
- date = {2022-10-26},
- version = {0.1},
+ date = {2024-08-20},
+ version = {0.2},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/lstaddons},
url = {https://ctan.org/pkg/lstaddons},
@@ -41752,8 +42061,8 @@
title = {The \texttt{lt3luabridge} package},
subtitle = {Execute Lua code in any \TeX{} engine that exposes the shell},
author = {Vít Starý Novotný},
- date = {2024-02-14},
- version = {2.1.0},
+ date = {2024-07-04},
+ version = {2.2.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/generic/lt3luabridge},
url = {https://ctan.org/pkg/lt3luabridge},
@@ -41933,7 +42242,7 @@
title = {The \texttt{ltxdoc} package},
subtitle = {Class for documented \LaTeX{} macro files},
author = {David Carlisle and {The LaTeX Project Team}},
- date = {2023-06-09},
+ date = {2024-06-01},
version = {2.1j},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -42250,8 +42559,8 @@
title = {The \texttt{luaaddplot} package},
subtitle = {An extension to pgfplots’ \textbackslash{}addplot macro},
author = {Reinhard Kotucha},
- date = {2022-03-30},
- version = {1.0},
+ date = {2024-09-22},
+ version = {1.0a},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/generic/luaaddplot},
url = {https://ctan.org/pkg/luaaddplot},
@@ -42355,8 +42664,8 @@
title = {The \texttt{luafindfont} package},
subtitle = {Search fonts in the LuaTeX font database},
author = {Herbert Voß},
- date = {2023-06-24},
- version = {0.13},
+ date = {2024-08-26},
+ version = {0.14},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/support/luafindfont},
url = {https://ctan.org/pkg/luafindfont},
@@ -42594,6 +42903,17 @@
url = {https://ctan.org/pkg/luamesh},
}
+@manual{ctan-luamml,
+ title = {The \texttt{LuaMML} package},
+ subtitle = {Automatically generate MathML from LuaLaTeX math mode material},
+ author = {Marcel Krüger},
+ date = {2024-09-01},
+ version = {0.1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/luatex/latex/luamml},
+ url = {https://ctan.org/pkg/luamml},
+}
+
@manual{ctan-luamodulartables,
title = {The \texttt{luamodulartables} package},
subtitle = {Generate modular addition and multiplication tables},
@@ -42616,8 +42936,8 @@
title = {The \texttt{luamplib} package},
subtitle = {Use LuaTeX’s built-in MetaPost interpreter},
author = {Hans Hagen and Taco Hoekwater and Élie Roux and Manuel Pégourié-Gonnard and Philipp Gesang and Dohyun Kim},
- date = {2024-05-21},
- version = {2.31.0},
+ date = {2024-08-03},
+ version = {2.34.5},
license = {gpl2},
mirror = {https://mirror.ctan.org/macros/luatex/generic/luamplib},
url = {https://ctan.org/pkg/luamplib},
@@ -42830,8 +43150,8 @@
title = {The \texttt{luatexja} package},
subtitle = {Typeset Japanese with Lua(La)TeX},
author = {Hironori Kitagawa},
- date = {2024-05-14},
- version = {20240514.0},
+ date = {2024-09-08},
+ version = {20240909.0},
license = {bsd},
mirror = {https://mirror.ctan.org/macros/luatex/generic/luatexja},
url = {https://ctan.org/pkg/luatexja},
@@ -42896,8 +43216,8 @@
title = {The \texttt{luaxml} package},
subtitle = {Lua library for reading and serialising XML files},
author = {Michal Hoftich},
- date = {2024-02-23},
- version = {0.1r},
+ date = {2024-07-14},
+ version = {0.2},
license = {other-free},
mirror = {https://mirror.ctan.org/macros/luatex/generic/luaxml},
url = {https://ctan.org/pkg/luaxml},
@@ -42990,6 +43310,17 @@
for the package.},
}
+@manual{ctan-luwiantype,
+ title = {The \texttt{LuwianType} package},
+ subtitle = {Typesetting package for Hieroglyphic Luwian},
+ author = {Jonathan Walls},
+ date = {2024-07-21},
+ version = {1.2},
+ license = {lppl1.3c,ofl},
+ mirror = {https://mirror.ctan.org/fonts/luwiantype},
+ url = {https://ctan.org/pkg/luwiantype},
+}
+
@manual{ctan-luximono,
title = {The \texttt{LuxiMono} package},
subtitle = {Free monospace fonts},
@@ -43306,13 +43637,13 @@
title = {The \texttt{magicwatermark} package},
subtitle = {An easy and flexible way to set watermarks},
author = {Lijun Guo},
- date = {2022-06-27},
- version = {1.0.1},
+ date = {2024-08-16},
+ version = {1.2B},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/magicwatermark},
url = {https://ctan.org/pkg/magicwatermark},
annotation = {This package can flexibly set and clear watermarks.
- It is based on
+ It is based on
and
, encapsulated by \LaTeX{}3.
All watermark content is placed inside a TikZ node
@@ -43345,8 +43676,9 @@
title = {The \texttt{mailing} package},
subtitle = {Macros for mail merging},
author = {Johannes L. Braams},
- date = {2016-06-24},
- license = {lppl},
+ date = {2024-07-21},
+ version = {1.0c},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mailing},
url = {https://ctan.org/pkg/mailing},
annotation = {This package is for use when sending a large number of letters,
@@ -44009,8 +44341,8 @@
title = {The \texttt{markdown} package},
subtitle = {Converting and rendering markdown documents inside \TeX{}},
author = {Vít Starý Novotný},
- date = {2024-04-30},
- version = {3.5.0-0-gfd01a252},
+ date = {2024-08-30},
+ version = {3.7.0-0-g98dece19},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/generic/markdown},
url = {https://ctan.org/pkg/markdown},
@@ -44159,9 +44491,9 @@
title = {The \texttt{mathastext} package},
subtitle = {Use the text font in maths mode},
author = {Jean-François Burnol},
- date = {2023-12-29},
- version = {1.3zb},
- license = {lppl1.3},
+ date = {2024-07-27},
+ version = {1.4b},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mathastext},
url = {https://ctan.org/pkg/mathastext},
}
@@ -44992,8 +45324,8 @@
title = {The \texttt{media9} package},
subtitle = {Multimedia inclusion package with Adobe Reader-9/X compatibility},
author = {Alexander Grahn},
- date = {2022-08-04},
- version = {1.25},
+ date = {2024-09-16},
+ version = {1.29},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/media9},
url = {https://ctan.org/pkg/media9},
@@ -45316,8 +45648,8 @@
title = {The \texttt{mercatormap} package},
subtitle = {Spherical Mercator coordinate systems and Web Mercator tile integration},
author = {Thomas F. Sturm},
- date = {2020-08-06},
- version = {1.02},
+ date = {2024-08-05},
+ version = {1.2.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mercatormap},
url = {https://ctan.org/pkg/mercatormap},
@@ -45681,8 +46013,8 @@
title = {The \texttt{mf2pt1} package},
subtitle = {Convert stylized Metafont to PostScript Type 1},
author = {Scott Pakin},
- date = {2021-12-04},
- version = {2.7},
+ date = {2024-07-07},
+ version = {2.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/support/mf2pt1},
url = {https://ctan.org/pkg/mf2pt1},
@@ -45720,6 +46052,17 @@
url = {https://ctan.org/pkg/mf2tex},
}
+@manual{ctan-mfb-oldstyle,
+ title = {The \texttt{mfb-oldstyle} package},
+ subtitle = {MFB Oldstyle serif fonts},
+ author = {Daniel Benjamin Miller},
+ date = {2024-09-01},
+ version = {1.0},
+ license = {cc0},
+ mirror = {https://mirror.ctan.org/fonts/mfb-oldstyle},
+ url = {https://ctan.org/pkg/mfb-oldstyle},
+}
+
@manual{ctan-mfbook,
title = {The \texttt{mfbook} package},
subtitle = {The source of The Metafontbook},
@@ -46099,10 +46442,10 @@
title = {The \texttt{miktex-portable} package},
subtitle = {A version of MikTeX to carry around},
author = {Christian Schenk},
- date = {2024-01-29},
- version = {23.10},
+ date = {2024-09-23},
+ version = {24.1},
license = {other-free},
- mirror = {https://mirror.ctan.org/systems/win32/miktex/setup/windows-x64/basic-miktex-23.10-x64.exe},
+ mirror = {https://mirror.ctan.org/systems/win32/miktex/setup/windows-x64/basic-miktex-24.1-x64.exe},
url = {https://ctan.org/pkg/miktex-portable},
annotation = {The portable edition allows you to run MiKTeX from a portable storage device.
Please note that there is no seperate installer. Just download the
@@ -46113,8 +46456,8 @@
title = {The \texttt{miktex} package},
subtitle = {A free \TeX{} distribution for MS-Windows},
author = {Christian Schenk},
- date = {2022-08-04},
- version = {22.7},
+ date = {2024-09-22},
+ version = {24.4},
license = {other-free},
mirror = {https://mirror.ctan.org/systems/win32/miktex},
url = {https://ctan.org/pkg/miktex},
@@ -46280,7 +46623,7 @@
title = {The \texttt{miniltx} package},
subtitle = {An abstract of \LaTeX{} facilities for use with Plain \TeX{}},
author = {David Carlisle and Karl Berry},
- date = {2023-11-09},
+ date = {2024-06-20},
version = {},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/plain/graphics/miniltx.tex},
@@ -46453,8 +46796,8 @@
title = {The \texttt{minted} package},
subtitle = {Highlighted source code for \LaTeX{}},
author = {Geoffrey Poore and Konrad Rudolph},
- date = {2023-12-18},
- version = {2.9},
+ date = {2024-09-23},
+ version = {3.0.0},
license = {lppl1.3,bsd3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/minted},
url = {https://ctan.org/pkg/minted},
@@ -46508,8 +46851,8 @@
title = {The \texttt{mismath} package},
subtitle = {Miscellaneous mathematical macros},
author = {Antoine Missier},
- date = {2024-05-03},
- version = {3.0},
+ date = {2024-06-16},
+ version = {3.1},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mismath},
url = {https://ctan.org/pkg/mismath},
@@ -46540,8 +46883,8 @@
title = {The \texttt{mitthesis} package},
subtitle = {A \LaTeX{} template for an MIT thesis},
author = {John H. Lienhard},
- date = {2023-11-02},
- version = {1.11},
+ date = {2024-09-06},
+ version = {1.16},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mitthesis},
url = {https://ctan.org/pkg/mitthesis},
@@ -46686,8 +47029,8 @@
title = {The \texttt{mlacls} package},
subtitle = {LaTeX class for MLA papers},
author = {Seth Price},
- date = {2023-05-17},
- version = {1.0},
+ date = {2024-09-13},
+ version = {1.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/mlacls},
url = {https://ctan.org/pkg/mlacls},
@@ -46954,9 +47297,9 @@
@manual{ctan-moderncv,
title = {The \texttt{moderncv} package},
subtitle = {A modern curriculum vitae class},
- author = {Xavier Danaux and Stephan Lachnit},
- date = {2022-02-21},
- version = {2.3.1},
+ author = {Xavier Danaux and Stephan Lachnit and Daniel Adlkofer},
+ date = {2024-07-18},
+ version = {2.4.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/moderncv},
url = {https://ctan.org/pkg/moderncv},
@@ -47104,8 +47447,8 @@
title = {The \texttt{moloch} package},
subtitle = {Beamer based on Metropolis theme},
author = {Johan Larsson},
- date = {2024-04-05},
- version = {0.3.0},
+ date = {2024-07-09},
+ version = {0.4.0},
license = {cc-by-sa-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/beamer-contrib/themes/moloch},
url = {https://ctan.org/pkg/moloch},
@@ -47245,6 +47588,17 @@
url = {https://ctan.org/pkg/morehype},
}
+@manual{ctan-moremath,
+ title = {The \texttt{moremath} package},
+ subtitle = {Additional commands for typesetting maths},
+ author = {Marcel Ilg},
+ date = {2024-08-20},
+ version = {0.5.0},
+ license = {lppl1.3},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/moremath},
+ url = {https://ctan.org/pkg/moremath},
+}
+
@manual{ctan-moresize,
title = {The \texttt{moresize} package},
subtitle = {Allows font sizes up to 35.83pt},
@@ -47458,6 +47812,17 @@
url = {https://ctan.org/pkg/mpgraphics},
}
+@manual{ctan-mpkiviat,
+ title = {The \texttt{mpkiviat} package},
+ subtitle = {MetaPost package to draw Kiviat diagrams},
+ author = {Maxime Chupin},
+ date = {2024-05-28},
+ version = {0.1},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/graphics/metapost/contrib/macros/mpkiviat},
+ url = {https://ctan.org/pkg/mpkiviat},
+}
+
@manual{ctan-mpman-ru,
title = {The \texttt{mpman-ru} package},
subtitle = {A Russian translation of the MetaPost manual},
@@ -47527,10 +47892,9 @@
@manual{ctan-ms,
title = {The \texttt{ms} package},
subtitle = {Various \LaTeX{} packages by Martin Schröder},
- author = {Martin Schröder and Marei Peischl},
- date = {2021-01-19},
+ author = {Martin Schröder},
+ date = {2024-06-23},
license = {lppl},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/ms},
url = {https://ctan.org/pkg/ms},
}
@@ -47571,8 +47935,8 @@
title = {The \texttt{msu-thesis} package},
subtitle = {Class for Michigan State University Master’s and PhD theses},
author = {Alan Munn},
- date = {2024-05-16},
- version = {4.2b},
+ date = {2024-07-08},
+ version = {4.3b},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/msu-thesis},
url = {https://ctan.org/pkg/msu-thesis},
@@ -47791,8 +48155,8 @@
title = {The \texttt{multicol} package},
subtitle = {Intermix single and multiple columns},
author = {Frank Mittelbach and {The LaTeX Project Team}},
- date = {2023-06-09},
- version = {1.9f},
+ date = {2024-06-02},
+ version = {1.9h},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/multicol},
@@ -47947,10 +48311,10 @@
title = {The \texttt{multitoc} package},
subtitle = {Set table of contents in multiple columns},
author = {Martin Schröder and Marei Peischl},
- date = {2020-11-24},
- version = {2.01},
+ date = {2024-06-23},
+ version = {2.02},
license = {lppl},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/ms},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/multitoc},
url = {https://ctan.org/pkg/multitoc},
}
@@ -48208,7 +48572,7 @@
title = {The \texttt{mxedruli} package},
subtitle = {A pair of fonts for different Georgian alphabets},
author = {Johannes Heinecke},
- date = {2017-04-18},
+ date = {2024-07-25},
version = {3.3c},
license = {lppl},
mirror = {https://mirror.ctan.org/fonts/georgian/mxedruli},
@@ -48383,8 +48747,8 @@
title = {The \texttt{naive-ebnf} package},
subtitle = {EBNF in plain text},
author = {Yegor Bugayenko},
- date = {2023-08-11},
- version = {0.0.15},
+ date = {2024-09-06},
+ version = {0.0.16},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/naive-ebnf},
url = {https://ctan.org/pkg/naive-ebnf},
@@ -49067,8 +49431,8 @@
title = {The \texttt{NewComputerModern} package},
subtitle = {Computer Modern fonts including matching non-latin alphabets},
author = {Antonis Tsolomitis},
- date = {2024-01-11},
- version = {5.1},
+ date = {2024-09-08},
+ version = {6.0.0},
license = {gfl},
mirror = {https://mirror.ctan.org/fonts/newcomputermodern},
url = {https://ctan.org/pkg/newcomputermodern},
@@ -49212,8 +49576,8 @@
title = {The \texttt{newtx} package},
subtitle = {Alternative uses of the TX fonts, with improved metrics},
author = {Michael Sharpe},
- date = {2024-04-02},
- version = {1.744},
+ date = {2024-09-23},
+ version = {1.754},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/fonts/newtx},
url = {https://ctan.org/pkg/newtx},
@@ -49323,8 +49687,8 @@
title = {The \texttt{nfssfont} package},
subtitle = {Typesetting font tables using \LaTeX{}’s NFSS notation},
author = {Frank Mittelbach and {The LaTeX Project Team}},
- date = {2024-01-15},
- version = {2.2e},
+ date = {2024-06-02},
+ version = {2.2f},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/nfssfont},
@@ -49367,7 +49731,7 @@
title = {The \texttt{niceframe-type1} package},
subtitle = {Type 1 versions of the fonts recommended in niceframe},
author = {Rolf Niepraschk},
- date = {2023-08-17},
+ date = {2024-07-19},
version = {},
license = {lppl},
mirror = {https://mirror.ctan.org/fonts/niceframe},
@@ -49398,8 +49762,8 @@
title = {The \texttt{nicematrix} package},
subtitle = {Improve the typesetting of mathematical matrices with PGF},
author = {François Pantigny},
- date = {2024-04-23},
- version = {6.27b},
+ date = {2024-08-22},
+ version = {6.28c},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/nicematrix},
url = {https://ctan.org/pkg/nicematrix},
@@ -49681,8 +50045,8 @@
title = {The \texttt{nodetree} package},
subtitle = {Visualize node lists in a tree view},
author = {Josef Friedrich},
- date = {2023-09-10},
- version = {2.3.0},
+ date = {2024-09-17},
+ version = {2.4.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/generic/nodetree},
url = {https://ctan.org/pkg/nodetree},
@@ -50044,8 +50408,8 @@
title = {The \texttt{notomath} package},
subtitle = {Math support for Noto fonts},
author = {Michael Sharpe},
- date = {2023-08-22},
- version = {1.03},
+ date = {2024-06-03},
+ version = {1.031},
license = {ofl,lppl1.3},
mirror = {https://mirror.ctan.org/fonts/notomath},
url = {https://ctan.org/pkg/notomath},
@@ -50448,6 +50812,17 @@
dedicated to the new journal :},
}
+@manual{ctan-nxuthesis,
+ title = {The \texttt{NxuThesis} package},
+ subtitle = {Thesis template for Ningxia University},
+ author = {Xianyuan Bao},
+ date = {2024-05-28},
+ version = {1.0.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/unicodetex/latex/nxuthesis},
+ url = {https://ctan.org/pkg/nxuthesis},
+}
+
@manual{ctan-oands,
title = {The \texttt{oands} package},
subtitle = {Glyphs used when transliterating ancient scripts},
@@ -50472,7 +50847,7 @@
title = {The \texttt{oberdiek} package},
subtitle = {A bundle of packages submitted by Heiko Oberdiek},
author = {Heiko Oberdiek},
- date = {2023-12-05},
+ date = {2024-07-27},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/oberdiek},
@@ -50571,8 +50946,8 @@
title = {The \texttt{ocgx2} package},
subtitle = {Drop-in replacement for ‘ocgx’ and ‘ocg-p’},
author = {Alexander Grahn},
- date = {2024-03-18},
- version = {0.57},
+ date = {2024-09-16},
+ version = {0.60},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/ocgx2},
url = {https://ctan.org/pkg/ocgx2},
@@ -51097,8 +51472,8 @@
title = {The \texttt{OpTeX} package},
subtitle = {LuaTeX format based on Plain \TeX{} and OPmac},
author = {Petr Olšák},
- date = {2024-02-14},
- version = {1.14},
+ date = {2024-06-28},
+ version = {1.15},
license = {pd},
mirror = {https://mirror.ctan.org/macros/optex},
url = {https://ctan.org/pkg/optex},
@@ -51167,9 +51542,9 @@
title = {The \texttt{orcidlink} package},
subtitle = {Insert hyperlinked ORCiD logo},
author = {Leo Stein},
- date = {2023-12-30},
- version = {1.0.5},
- license = {lppl1.3c},
+ date = {2024-06-27},
+ version = {1.1.0},
+ license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/orcidlink},
url = {https://ctan.org/pkg/orcidlink},
}
@@ -51272,7 +51647,7 @@
title = {The \texttt{osa} package},
subtitle = {Macros for Optical Society of America Journals, etc},
author = {{Optical Society of America}},
- date = {2017-04-18},
+ date = {2024-07-25},
license = {noinfo},
mirror = {https://mirror.ctan.org/macros/latex/contrib/osa},
url = {https://ctan.org/pkg/osa},
@@ -51480,8 +51855,8 @@
title = {The \texttt{OutilsGeomTikZ} package},
subtitle = {Some geometric tools, with TikZ},
author = {Cédric Pierquet},
- date = {2023-12-14},
- version = {0.1.5},
+ date = {2024-08-29},
+ version = {0.1.6},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/outilsgeomtikz},
url = {https://ctan.org/pkg/outilsgeomtikz},
@@ -51574,8 +51949,8 @@
title = {The \texttt{overarrows} package},
subtitle = {Custom extensible arrows over math expressions},
author = {Julien Labbé},
- date = {2023-02-15},
- version = {1.1},
+ date = {2024-07-11},
+ version = {1.2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/overarrows},
url = {https://ctan.org/pkg/overarrows},
@@ -51817,8 +52192,8 @@
title = {The \texttt{pagelayout} package},
subtitle = {Layout graphic rich documents},
author = {Friedemann Bartels},
- date = {2024-01-17},
- version = {1.1.0},
+ date = {2024-07-31},
+ version = {1.1.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/pagelayout},
url = {https://ctan.org/pkg/pagelayout},
@@ -51998,8 +52373,8 @@
title = {The \texttt{PanneauxRoute} package},
subtitle = {Commands to display French road signs (vector graphics)},
author = {Cédric Pierquet},
- date = {2023-11-24},
- version = {0.1.0},
+ date = {2024-09-15},
+ version = {0.1.2},
license = {lppl1.3c,cc-by-sa-3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/panneauxroute},
url = {https://ctan.org/pkg/panneauxroute},
@@ -52178,8 +52553,8 @@
title = {The \texttt{parnotes} package},
subtitle = {Notes after every paragraph (or elsewhere)},
author = {Chelsea Hughes},
- date = {2019-07-23},
- version = {3b},
+ date = {2024-06-12},
+ version = {3c},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/parnotes},
url = {https://ctan.org/pkg/parnotes},
@@ -52304,8 +52679,8 @@
title = {The \texttt{pas-tableur} package},
subtitle = {Create a spreadsheet layout},
author = {Stéphane Pasquet},
- date = {2023-04-16},
- version = {2.05},
+ date = {2024-09-14},
+ version = {2.06},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/pas-tableur},
url = {https://ctan.org/pkg/pas-tableur},
@@ -52341,6 +52716,17 @@
.},
}
+@manual{ctan-passopt,
+ title = {The \texttt{passopt} package},
+ subtitle = {Passing options to packages or classes},
+ author = {Qu Yi},
+ date = {2024-07-21},
+ version = {1.01a},
+ license = {cc-by-4},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/passopt},
+ url = {https://ctan.org/pkg/passopt},
+}
+
@manual{ctan-patch,
title = {The \texttt{patch} package},
subtitle = {Patch loaded packages, etc.},
@@ -52834,8 +53220,8 @@
title = {The \texttt{pdfjam} package},
subtitle = {Shell scripts interfacing to pdfpages},
author = {David Firth and Reuben Thomas},
- date = {2024-05-09},
- version = {3.11},
+ date = {2024-06-28},
+ version = {3.12},
license = {gpl2+},
mirror = {https://mirror.ctan.org/support/pdfjam},
url = {https://ctan.org/pkg/pdfjam},
@@ -52871,8 +53257,8 @@
title = {The \texttt{pdfmanagement-testphase} package},
subtitle = {LaTeX PDF management testphase bundle},
author = {{The LaTeX Project Team}},
- date = {2024-04-09},
- version = {0.96h},
+ date = {2024-09-13},
+ version = {0.96l},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/pdfmanagement-testphase},
url = {https://ctan.org/pkg/pdfmanagement-testphase},
@@ -52934,8 +53320,8 @@
title = {The \texttt{pdfpages} package},
subtitle = {Include PDF documents in \LaTeX{}},
author = {Andreas Matthias},
- date = {2024-01-21},
- version = {0.5y},
+ date = {2024-09-01},
+ version = {0.6b},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/pdfpages},
url = {https://ctan.org/pkg/pdfpages},
@@ -53162,8 +53548,8 @@
title = {The \texttt{pdfx} package},
subtitle = {PDF/X and PDF/A support for pdfTeX, LuaTeX and XeTeX},
author = {C. V. Radhakrishnan and Hàn Thế Thành and Peter Selinger and Ross Moore},
- date = {2019-03-10},
- version = {1.6.3},
+ date = {2024-07-01},
+ version = {1.6.5f},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/pdfx},
url = {https://ctan.org/pkg/pdfx},
@@ -53173,8 +53559,8 @@
title = {The \texttt{pdfxup} package},
subtitle = {Create n-up PDF pages with minimal margins},
author = {Nicolas Markey},
- date = {2024-03-15},
- version = {2.11},
+ date = {2024-06-13},
+ version = {2.12},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/support/pdfxup},
url = {https://ctan.org/pkg/pdfxup},
@@ -53217,7 +53603,7 @@
title = {The \texttt{penlight} package},
subtitle = {Penlight Lua libraries made available to LuaLaTeX users},
author = {Kale Ewasiuk},
- date = {2023-07-23},
+ date = {2024-09-16},
version = {},
license = {mit},
mirror = {https://mirror.ctan.org/macros/luatex/generic/penlight},
@@ -53231,7 +53617,7 @@
title = {The \texttt{penlightplus} package},
subtitle = {Additions to the Penlight Lua libraries},
author = {Kale Ewasiuk},
- date = {2024-03-15},
+ date = {2024-08-17},
version = {},
license = {mit},
mirror = {https://mirror.ctan.org/macros/luatex/generic/penlightplus},
@@ -53440,8 +53826,8 @@
title = {The \texttt{pgf-PeriodicTable} package},
subtitle = {Create custom periodic tables of elements},
author = {Hugo Gomes},
- date = {2024-04-03},
- version = {2.1.0a},
+ date = {2024-09-08},
+ version = {2.1.4},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pgf-periodictable},
url = {https://ctan.org/pkg/pgf-periodictable},
@@ -53477,8 +53863,8 @@
title = {The \texttt{pgf-spectra} package},
subtitle = {Draw continuous or discrete spectra using PGF/TikZ},
author = {Hugo Gomes},
- date = {2023-04-27},
- version = {3.0.1},
+ date = {2024-07-07},
+ version = {3.0.1a},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pgf-spectra},
url = {https://ctan.org/pkg/pgf-spectra},
@@ -53511,7 +53897,7 @@
title = {The \texttt{pgf} package},
subtitle = {Create PostScript and PDF graphics in \TeX{}},
author = {{The PGF/TikZ Team} and Till Tantau and Christian Feuersänger and Henri Menke},
- date = {2023-01-15},
+ date = {2024-07-19},
version = {3.1.10},
license = {lppl1.3c,gpl2,fdl},
mirror = {https://mirror.ctan.org/graphics/pgf/base},
@@ -53521,10 +53907,10 @@
@manual{ctan-pgfgantt,
title = {The \texttt{pgfgantt} package},
subtitle = {Draw Gantt charts with TikZ},
- author = {Wolfgang Skala},
- date = {2018-01-10},
- version = {5.0},
- license = {lppl1.3},
+ author = {Wolfgang Esser-Skala},
+ date = {2024-06-19},
+ version = {5.0a},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pgfgantt},
url = {https://ctan.org/pkg/pgfgantt},
}
@@ -53576,9 +53962,9 @@
@manual{ctan-pgfmolbio,
title = {The \texttt{pgfmolbio} package},
subtitle = {Draw graphs typically found in molecular biology texts},
- author = {Wolfgang Skala},
- date = {2016-06-24},
- version = {0.21},
+ author = {Wolfgang Esser-Skala},
+ date = {2024-06-17},
+ version = {0.21a},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/latex/pgfmolbio},
url = {https://ctan.org/pkg/pgfmolbio},
@@ -53623,7 +54009,7 @@
title = {The \texttt{pgfornament-han} package},
subtitle = {pgfornament library for Chinese traditional motifs and patterns},
author = {LianTze Lim},
- date = {2023-10-30},
+ date = {2024-09-23},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pgfornament-han},
@@ -53634,8 +54020,8 @@
title = {The \texttt{pgfornament} package},
subtitle = {Drawing of Vectorian ornaments with PGF/TikZ},
author = {Alain Matthes},
- date = {2020-05-28},
- version = {1.2},
+ date = {2024-08-14},
+ version = {1.3},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tkz/pgfornament},
url = {https://ctan.org/pkg/pgfornament},
@@ -53667,6 +54053,20 @@
url = {https://ctan.org/pkg/pgfplotstable},
}
+@manual{ctan-pgfplotsthemebeamer,
+ title = {The \texttt{pgfplotsthemebeamer} package},
+ subtitle = {Use colours from the current beamer theme in pgfplots},
+ author = {{Unknown}},
+ date = {2024-08-07},
+ version = {0.2},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pgfplotsthemebeamer},
+ url = {https://ctan.org/pkg/pgfplotsthemebeamer},
+ annotation = {A \LaTeX{} package for using colours from the current
+ theme in
+ diagrams.},
+}
+
@manual{ctan-pgothic,
title = {The \texttt{pgothic} package},
subtitle = {Fonts based on the Gothic Textura Prescisus manuscript book-hand},
@@ -53923,8 +54323,8 @@
title = {The \texttt{photobook} package},
subtitle = {A document class for typesetting photo books},
author = {Alex A. Naanou},
- date = {2023-09-17},
- version = {0.1.29},
+ date = {2024-07-19},
+ version = {0.1.31},
license = {bsd3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/photobook},
url = {https://ctan.org/pkg/photobook},
@@ -54297,8 +54697,8 @@
title = {The \texttt{piton} package},
subtitle = {Typeset informatic listings with LPEG of LuaLaTeX},
author = {François Pantigny},
- date = {2024-05-12},
- version = {3.0a},
+ date = {2024-09-22},
+ version = {4.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/latex/piton},
url = {https://ctan.org/pkg/piton},
@@ -54416,8 +54816,8 @@
title = {The \texttt{pkgcheck} package},
subtitle = {CTAN package checker},
author = {Manfred Lotz},
- date = {2023-05-17},
- version = {3.1.0},
+ date = {2024-08-27},
+ version = {3.2.0},
license = {apache2,mit},
mirror = {https://mirror.ctan.org/support/pkgcheck},
url = {https://ctan.org/pkg/pkgcheck},
@@ -54622,8 +55022,8 @@
title = {The \texttt{plantuml} package},
subtitle = {Support for rendering UML diagrams using PlantUML},
author = {Oliver Kopp},
- date = {2023-05-13},
- version = {0.3.2},
+ date = {2024-09-17},
+ version = {0.4.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/luatex/latex/plantuml},
url = {https://ctan.org/pkg/plantuml},
@@ -54654,7 +55054,7 @@
title = {The \texttt{platex-tools} package},
subtitle = {pLaTeX standard tools bundle},
author = {Hironobu Yamashita},
- date = {2023-02-26},
+ date = {2024-08-18},
version = {},
license = {bsd3},
mirror = {https://mirror.ctan.org/macros/jptex/latex/platex-tools},
@@ -54944,10 +55344,10 @@
title = {The \texttt{pmdraw} package},
subtitle = {Draw elements of the diagram monoids},
author = {Matthias Fresacher},
- date = {2024-04-09},
- version = {1.3},
+ date = {2024-06-02},
+ version = {1.4},
license = {lppl1.3},
- mirror = {https://mirror.ctan.org/graphics/pmdraw},
+ mirror = {https://mirror.ctan.org/graphics/pgf/contrib/pmdraw},
url = {https://ctan.org/pkg/pmdraw},
}
@@ -54966,8 +55366,8 @@
title = {The \texttt{pmhanguljamo} package},
subtitle = {Poor man’s Hangul Jamo input method},
author = {Kangsoo Kim},
- date = {2023-03-05},
- version = {1.0.2},
+ date = {2024-06-10},
+ version = {1.1},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/language/korean/pmhanguljamo},
url = {https://ctan.org/pkg/pmhanguljamo},
@@ -55177,8 +55577,8 @@
title = {The \texttt{polyglossia} package},
subtitle = {An alternative to babel for \XeLaTeX{} and LuaLaTeX},
author = {François Charette and Arthur Rosendahl and Jürgen Spitzmüller},
- date = {2024-03-07},
- version = {2.1},
+ date = {2024-09-23},
+ version = {2.3},
license = {mit,lppl1.3,cc0},
mirror = {https://mirror.ctan.org/macros/unicodetex/latex/polyglossia},
url = {https://ctan.org/pkg/polyglossia},
@@ -55233,6 +55633,20 @@
limited optional behaviour.},
}
+@manual{ctan-polyomino,
+ title = {The \texttt{polyomino} package},
+ subtitle = {Polyominoes using TikZ and \LaTeX{}3},
+ author = {Matthias Floré},
+ date = {2024-08-07},
+ version = {1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/graphics/pgf/contrib/polyomino},
+ url = {https://ctan.org/pkg/polyomino},
+ annotation = {This package is based on the package
+ and can be used to draw polyominoes.
+ It is possible to define custom styles, pics and grids.},
+}
+
@manual{ctan-polytable,
title = {The \texttt{polytable} package},
subtitle = {Tabular-like environments with named columns},
@@ -55708,8 +56122,8 @@
title = {The \texttt{preview} package},
subtitle = {Extract bits of a \LaTeX{} source for output},
author = {David Kastrup and {The AUCTeX Team}},
- date = {2024-01-17},
- version = {13.3},
+ date = {2024-06-30},
+ version = {14.0.6},
license = {gpl3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/preview},
url = {https://ctan.org/pkg/preview},
@@ -55860,8 +56274,8 @@
title = {The \texttt{ProfCollege} package},
subtitle = {A \LaTeX{} package for French maths teachers in college},
author = {Christophe Poulain},
- date = {2024-05-18},
- version = {0.99-A-f},
+ date = {2024-09-05},
+ version = {0.99-A-j},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/profcollege},
url = {https://ctan.org/pkg/profcollege},
@@ -55882,19 +56296,19 @@
title = {The \texttt{ProfLycee} package},
subtitle = {A \LaTeX{} package for French maths teachers in high school},
author = {Cédric Pierquet},
- date = {2024-05-11},
- version = {3.04b},
- license = {lppl1.3c},
+ date = {2024-09-22},
+ version = {3.05a},
+ license = {lppl1.3c,cc0},
mirror = {https://mirror.ctan.org/macros/latex/contrib/proflycee},
url = {https://ctan.org/pkg/proflycee},
}
@manual{ctan-profmaquette,
- title = {The \texttt{profmaquette} package},
+ title = {The \texttt{ProfMaquette} package},
subtitle = {Use exercises in different types of documents},
author = {Christophe Poulain},
- date = {2024-05-03},
- version = {0.94},
+ date = {2024-09-17},
+ version = {0.99},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/profmaquette},
url = {https://ctan.org/pkg/profmaquette},
@@ -56137,8 +56551,8 @@
title = {The \texttt{prtec} package},
subtitle = {A template for PRTEC conference papers},
author = {John H. Lienhard},
- date = {2019-08-20},
- version = {1.06},
+ date = {2024-07-08},
+ version = {1.07},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/prtec},
url = {https://ctan.org/pkg/prtec},
@@ -56832,8 +57246,8 @@
title = {The \texttt{pst-coil} package},
subtitle = {A PSTricks package for coils, etc},
author = {Herbert Voß and Timothy Van Zandt},
- date = {2022-04-06},
- version = {1.07},
+ date = {2024-08-13},
+ version = {1.08},
license = {lppl},
mirror = {https://mirror.ctan.org/graphics/pstricks/contrib/pst-coil},
url = {https://ctan.org/pkg/pst-coil},
@@ -56904,8 +57318,8 @@
title = {The \texttt{pst-diffraction} package},
subtitle = {Print diffraction patterns from various apertures},
author = {Manuel Luque and Herbert Voß},
- date = {2022-04-06},
- version = {2.03},
+ date = {2024-07-15},
+ version = {2.06a},
license = {lppl},
mirror = {https://mirror.ctan.org/graphics/pstricks/contrib/pst-diffraction},
url = {https://ctan.org/pkg/pst-diffraction},
@@ -57357,8 +57771,8 @@
title = {The \texttt{pst-node} package},
subtitle = {Nodes and node connections in PSTricks},
author = {Timothy Van Zandt and Michael Sharpe and Herbert Voß},
- date = {2022-01-31},
- version = {1.43},
+ date = {2024-07-11},
+ version = {1.45},
license = {lppl},
mirror = {https://mirror.ctan.org/graphics/pstricks/contrib/pst-node},
url = {https://ctan.org/pkg/pst-node},
@@ -57405,8 +57819,8 @@
title = {The \texttt{pst-optic} package},
subtitle = {Drawing optics diagrams},
author = {Manuel Luque and Herbert Voß},
- date = {2024-05-17},
- version = {1.03},
+ date = {2024-06-02},
+ version = {1.04},
license = {lppl},
mirror = {https://mirror.ctan.org/graphics/pstricks/contrib/pst-optic},
url = {https://ctan.org/pkg/pst-optic},
@@ -57991,8 +58405,8 @@
title = {The \texttt{pstricks-base} package},
subtitle = {PostScript macros for \TeX{}},
author = {Herbert Voß and Denis Girou and Timothy Van Zandt},
- date = {2024-02-02},
- version = {3.19c},
+ date = {2024-07-09},
+ version = {3.20},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/graphics/pstricks/base},
url = {https://ctan.org/pkg/pstricks-base},
@@ -58122,7 +58536,7 @@
title = {The \texttt{ptex-manual} package},
subtitle = {Japanese pTeX manual},
author = {{Japanese TeX Development Community}},
- date = {2023-09-02},
+ date = {2024-06-15},
version = {},
license = {bsd3},
mirror = {https://mirror.ctan.org/info/ptex-manual},
@@ -58323,8 +58737,8 @@
title = {The \texttt{pwebmac} package},
subtitle = {Consolidated WEB macros for DVI and PDF output},
author = {Andreas Scherer},
- date = {2023-12-03},
- version = {4.11},
+ date = {2024-08-12},
+ version = {5.0},
license = {pd},
mirror = {https://mirror.ctan.org/web/pwebmac},
url = {https://ctan.org/pkg/pwebmac},
@@ -58361,8 +58775,8 @@
title = {The \texttt{pxchfon} package},
subtitle = {Japanese font setup for pLaTeX and upLaTeX},
author = {Takayuki Yato},
- date = {2023-08-29},
- version = {2.0},
+ date = {2024-08-23},
+ version = {2.2},
license = {mit},
mirror = {https://mirror.ctan.org/macros/jptex/latex/pxchfon},
url = {https://ctan.org/pkg/pxchfon},
@@ -58413,8 +58827,8 @@
title = {The \texttt{pxjahyper} package},
subtitle = {Hyperref support for pLaTeX},
author = {Takayuki Yato},
- date = {2023-02-28},
- version = {1.3},
+ date = {2024-08-25},
+ version = {1.5},
license = {mit},
mirror = {https://mirror.ctan.org/macros/jptex/latex/pxjahyper},
url = {https://ctan.org/pkg/pxjahyper},
@@ -58948,8 +59362,8 @@
title = {The \texttt{quizztex} package},
subtitle = {Create quizzes like in TV shows},
author = {Cédric Pierquet},
- date = {2023-11-05},
- version = {0.1.2},
+ date = {2024-09-10},
+ version = {0.1.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/quizztex},
url = {https://ctan.org/pkg/quizztex},
@@ -59075,6 +59489,17 @@
package.},
}
+@manual{ctan-quran-es,
+ title = {The \texttt{quran-es} package},
+ subtitle = {Spanish Translations for the quran package},
+ author = {Seiied-Mohammad-Javad Razavian},
+ date = {2024-09-16},
+ version = {0.1},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/xetex/latex/quran-es},
+ url = {https://ctan.org/pkg/quran-es},
+}
+
@manual{ctan-quran-id,
title = {The \texttt{quran-id} package},
subtitle = {Indonesian translation extension to the quran package},
@@ -59101,8 +59526,8 @@
title = {The \texttt{quran} package},
subtitle = {An easy way to typeset any part of The Holy Quran},
author = {Seiied-Mohammad-Javad Razavian},
- date = {2023-08-01},
- version = {2.2},
+ date = {2024-09-07},
+ version = {2.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/unicodetex/latex/quran},
url = {https://ctan.org/pkg/quran},
@@ -59245,13 +59670,24 @@
title = {The \texttt{randexam} package},
subtitle = {Make an exam paper and its randomized variants},
author = {Jianrui Lyu},
- date = {2024-02-18},
- version = {2024E},
+ date = {2024-07-09},
+ version = {2024F},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/randexam},
url = {https://ctan.org/pkg/randexam},
}
+@manual{ctan-randintlist,
+ title = {The \texttt{randintlist} package},
+ subtitle = {Creating random integer number lists , with repeating and sorting options},
+ author = {Cédric Pierquet},
+ date = {2024-09-25},
+ version = {0.1.1},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/randintlist},
+ url = {https://ctan.org/pkg/randintlist},
+}
+
@manual{ctan-random,
title = {The \texttt{random} package},
subtitle = {Generating “random” numbers in \TeX{}},
@@ -59856,8 +60292,8 @@
title = {The \texttt{regulatory} package},
subtitle = {Flexible drafting of legal documents, especially in Dutch},
author = {Erik Nijenhuis},
- date = {2024-01-27},
- version = {0.0.3},
+ date = {2024-09-05},
+ version = {0.0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/regulatory},
url = {https://ctan.org/pkg/regulatory},
@@ -59878,8 +60314,8 @@
title = {The \texttt{reledpar} package},
subtitle = {Typeset scholarly editions in parallel texts},
author = {Maïeul Rouquette},
- date = {2024-05-11},
- version = {2.25.6a},
+ date = {2024-07-23},
+ version = {2.25.7},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/reledmac},
url = {https://ctan.org/pkg/reledpar},
@@ -60008,7 +60444,7 @@
title = {The \texttt{report} package},
subtitle = {Typeset a multi-chapter report},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
+ date = {2024-06-02},
version = {1.4n},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -60022,16 +60458,11 @@
title = {The \texttt{reptheorem} package},
subtitle = {Repetition of theorem environments},
author = {Jesse Straat},
- date = {2024-03-30},
- version = {1.0},
+ date = {2024-09-23},
+ version = {1.2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/reptheorem},
url = {https://ctan.org/pkg/reptheorem},
- annotation = {When writing a large manuscript, it is sometimes beneficial to repeat a theorem (or lemma or...)
- at an earlier or later point for didactical purposes. However, 's
- built-in restatable only allows replicating theorems they have been stated, and only in the same document.
- Reptheorem solves the issue by making use of the file, and also introduces its own
- file extension, , to replicate theorems in other files.},
}
@manual{ctan-required,
@@ -60105,8 +60536,8 @@
title = {The \texttt{ResolSysteme} package},
subtitle = {Work on linear systems using xint or pyluatex},
author = {Cédric Pierquet},
- date = {2024-04-02},
- version = {0.1.6},
+ date = {2024-07-04},
+ version = {0.1.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/resolsysteme},
url = {https://ctan.org/pkg/resolsysteme},
@@ -60131,8 +60562,8 @@
title = {The \texttt{responsive} package},
subtitle = {Responsive design methods for \LaTeX{}},
author = {Michal Hoftich},
- date = {2023-12-20},
- version = {0.1},
+ date = {2024-07-14},
+ version = {0.1a},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/responsive},
url = {https://ctan.org/pkg/responsive},
@@ -60301,7 +60732,7 @@
title = {The \texttt{RGB} package},
subtitle = {Tables of RGB colour parameters},
author = {Maurizio Loreti},
- date = {2019-07-06},
+ date = {2024-07-25},
version = {1.2},
license = {other-free},
mirror = {https://mirror.ctan.org/info/colour/rgb},
@@ -60797,8 +61228,8 @@
title = {The \texttt{rpgicons} package},
subtitle = {Icons for tabletop role-playing games},
author = {Jasper Habicht},
- date = {2024-05-15},
- version = {1.8.3},
+ date = {2024-08-08},
+ version = {1.8.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/rpgicons},
url = {https://ctan.org/pkg/rpgicons},
@@ -60892,7 +61323,7 @@
title = {The \texttt{RST} package},
subtitle = {Drawing rhetorical structure analysis diagrams in \LaTeX{}},
author = {David Reitter},
- date = {2017-04-18},
+ date = {2024-07-25},
version = {1.3},
license = {other-nonfree},
mirror = {https://mirror.ctan.org/macros/latex/contrib/rst},
@@ -60973,6 +61404,17 @@
url = {https://ctan.org/pkg/rtsched},
}
+@manual{ctan-rub-kunstgeschichte,
+ title = {The \texttt{rub-kunstgeschichte} package},
+ subtitle = {A class for the art history institute at Ruhr University Bochum},
+ author = {Joran Schneyer},
+ date = {2024-09-06},
+ version = {0.2.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/rub-kunstgeschichte},
+ url = {https://ctan.org/pkg/rub-kunstgeschichte},
+}
+
@manual{ctan-rubik,
title = {The \texttt{rubik} package},
subtitle = {Document Rubik cube configurations and rotation sequences},
@@ -61406,7 +61848,7 @@
title = {The \texttt{sanskrit} package},
subtitle = {Sanskrit support},
author = {Václav Haisman and Charles Wikner},
- date = {2022-09-24},
+ date = {2024-08-11},
version = {2.2.4},
license = {lppl},
mirror = {https://mirror.ctan.org/language/sanskrit},
@@ -61957,8 +62399,8 @@
title = {The \texttt{scontents} package},
subtitle = {Stores \LaTeX{} contents in memory or files},
author = {Pablo González Luengo},
- date = {2022-04-04},
- version = {2.0},
+ date = {2024-06-15},
+ version = {2.1},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/scontents},
url = {https://ctan.org/pkg/scontents},
@@ -62142,6 +62584,30 @@
url = {https://ctan.org/pkg/scrextend},
}
+@manual{ctan-scrhack,
+ title = {The \texttt{scrhack} package},
+ subtitle = {Compatibility package to emulate the former KOMA-Script package scrhack},
+ author = {Markus Kohm},
+ date = {2024-09-17},
+ version = {3.42},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/scrhack},
+ url = {https://ctan.org/pkg/scrhack},
+ annotation = {Up to version 3.41, the scrhack package was part of
+ .
+ It was originally intended to improve the compatibility of
+ third-party packages with KOMA-Script.
+ However, most of the so-called hacks also added additional
+ functionality to the corresponding third-party package.
+ On the other hand, it was sometimes urgent to react to a change
+ in such a third-party package, which was difficult to do
+ from within a large collection like KOMA-Script.
+ Therefore, the scrhack part of KOMA-Script was split into
+ several independent packages.
+ And the scrhack spin-off was made to emulate the former
+ KOMA-Script package of the same name.},
+}
+
@manual{ctan-scrindex,
title = {The \texttt{scrindex} package},
subtitle = {Make index package work with Koma-script classes},
@@ -62447,8 +62913,8 @@
title = {The \texttt{se2thesis} package},
subtitle = {A Thesis Class for the Chair of Software Engineering II at the University of Passau, Germany},
author = {Stephan Lukasczyk},
- date = {2024-05-17},
- version = {4.0.1},
+ date = {2024-09-19},
+ version = {4.3.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/se2thesis},
url = {https://ctan.org/pkg/se2thesis},
@@ -62690,8 +63156,8 @@
title = {The \texttt{semesterplannerLua} package},
subtitle = {Draw timetables and other organizational matters useful for planning a semester},
author = {Lukas Heindl},
- date = {2024-05-20},
- version = {1.1.1},
+ date = {2024-05-28},
+ version = {1.1.2},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/luatex/latex/semesterplannerlua},
url = {https://ctan.org/pkg/semesterplannerlua},
@@ -62767,8 +63233,8 @@
title = {The \texttt{sepfootnotes} package},
subtitle = {Support footnotes and endnotes from separate files},
author = {Eduardo C. Lourenço de Lima},
- date = {2016-07-19},
- version = {0.3c},
+ date = {2024-07-06},
+ version = {0.3d},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/sepfootnotes},
url = {https://ctan.org/pkg/sepfootnotes},
@@ -63491,8 +63957,8 @@
title = {The \texttt{shortvrb} package},
subtitle = {Abbreviated verbatim commands},
author = {{The LaTeX Project Team}},
- date = {2024-01-15},
- version = {3.0m},
+ date = {2024-06-02},
+ version = {3.0p},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
url = {https://ctan.org/pkg/shortvrb},
@@ -63600,8 +64066,8 @@
title = {The \texttt{showkeys} package},
subtitle = {Show label, ref, cite and bib keys},
author = {David Carlisle},
- date = {2023-11-01},
- version = {3.19},
+ date = {2024-06-02},
+ version = {3.21},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/showkeys},
@@ -63722,8 +64188,8 @@
title = {The \texttt{sidenotes} package},
subtitle = {Typeset notes containing rich content, in the margin},
author = {Andy Thomas},
- date = {2020-03-24},
- version = {1.00a},
+ date = {2024-09-12},
+ version = {1.20},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/sidenotes},
url = {https://ctan.org/pkg/sidenotes},
@@ -63803,8 +64269,8 @@
title = {The \texttt{sillypage} package},
subtitle = {John Cleese’s Silly Walk as page numbering style},
author = {Paulo Roberto Massa Cereda},
- date = {2023-03-04},
- version = {1.6},
+ date = {2024-07-24},
+ version = {1.7},
license = {cc-by-sa-4,lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/sillypage},
url = {https://ctan.org/pkg/sillypage},
@@ -63814,8 +64280,8 @@
title = {The \texttt{sim-os-menus} package},
subtitle = {Insert 'terminal' or 'context menu' or 'viewers' like in an OS},
author = {Cédric Pierquet},
- date = {2023-11-17},
- version = {0.1.1},
+ date = {2024-09-18},
+ version = {0.1.2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/sim-os-menus},
url = {https://ctan.org/pkg/sim-os-menus},
@@ -63890,8 +64356,8 @@
title = {The \texttt{simpleicons} package},
subtitle = {Simple Icons for \LaTeX{}},
author = {Inesh Bose},
- date = {2024-04-12},
- version = {11.12.0},
+ date = {2024-09-20},
+ version = {13.10.0},
license = {cc-by-1},
mirror = {https://mirror.ctan.org/fonts/simpleicons},
url = {https://ctan.org/pkg/simpleicons},
@@ -63955,7 +64421,7 @@
title = {The \texttt{simpler-wick} package},
subtitle = {Simpler Wick contractions},
author = {Joshua Ellis},
- date = {2017-04-18},
+ date = {2024-07-25},
version = {1.0.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/simpler-wick},
@@ -64100,8 +64566,8 @@
title = {The \texttt{siunitx} package},
subtitle = {A comprehensive (SI) units package},
author = {Joseph Wright},
- date = {2024-05-06},
- version = {3.3.17},
+ date = {2024-08-23},
+ version = {3.3.21},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/siunitx},
url = {https://ctan.org/pkg/siunitx},
@@ -64111,8 +64577,8 @@
title = {The \texttt{SJTUTeX} package},
subtitle = {LaTeX classes for Shanghai Jiao Tong University},
author = {Zilong Li and Weijian Wu},
- date = {2024-04-05},
- version = {2.1.2},
+ date = {2024-06-30},
+ version = {2.1.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/sjtutex},
url = {https://ctan.org/pkg/sjtutex},
@@ -65259,8 +65725,8 @@
title = {The \texttt{spath3} package},
subtitle = {Manipulate “soft paths” in PGF},
author = {Andrew Stacey},
- date = {2022-10-26},
- version = {2.7},
+ date = {2024-05-31},
+ version = {2.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/spath3},
url = {https://ctan.org/pkg/spath3},
@@ -65270,8 +65736,8 @@
title = {The \texttt{spbmark} package},
subtitle = {Customize superscripts and subscripts},
author = {Qu Yi},
- date = {2024-05-19},
- version = {1.46j},
+ date = {2024-07-14},
+ version = {1.46n},
license = {cc-by-4},
mirror = {https://mirror.ctan.org/macros/latex/contrib/spbmark},
url = {https://ctan.org/pkg/spbmark},
@@ -65304,6 +65770,17 @@
url = {https://ctan.org/pkg/spectralsequences},
}
+@manual{ctan-spelatex,
+ title = {The \texttt{SpeLaTeX} package},
+ subtitle = {Create PDF documents with hyperlinks to audiofragments},
+ author = {Walter Daems},
+ date = {2024-09-10},
+ version = {0.92},
+ license = {lppl1.3},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/spelatex},
+ url = {https://ctan.org/pkg/spelatex},
+}
+
@manual{ctan-spelling,
title = {The \texttt{spelling} package},
subtitle = {Support for spell-checking of LuaTeX documents},
@@ -65525,10 +66002,10 @@
title = {The \texttt{SQLTeX} package},
subtitle = {An SQL Preprocessor for \LaTeX{}},
author = {Oscar van Eijk},
- date = {2022-02-04},
- version = {2.1},
+ date = {2024-09-22},
+ version = {3.0},
license = {lppl},
- mirror = {https://mirror.ctan.org/support/SQLTeX},
+ mirror = {https://mirror.ctan.org/support/sqltex},
url = {https://ctan.org/pkg/sqltex},
}
@@ -65805,6 +66282,22 @@
url = {https://ctan.org/pkg/standalone},
}
+@manual{ctan-standardsectioning,
+ title = {The \texttt{standardsectioning} package},
+ subtitle = {Define sectioning commands identical to the standard classes},
+ author = {Markus Kohm},
+ date = {2024-06-14},
+ version = {0.9},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/standardsectioning},
+ url = {https://ctan.org/pkg/standardsectioning},
+ annotation = {The package implements the sectioning commands fully
+ compatible with the standard classes.
+ This is intended, e.g., to make the KOMA-Script classes
+ work with packages like ,
+ which depend on the implementation of these commands.},
+}
+
@manual{ctan-stanli,
title = {The \texttt{stanli} package},
subtitle = {TikZ Library for Structural Analysis},
@@ -66054,8 +66547,8 @@
title = {The \texttt{SticksToo} package},
subtitle = {A reworking of STIX2},
author = {Michael Sharpe},
- date = {2021-10-18},
- version = {1.035},
+ date = {2024-09-23},
+ version = {1.036},
license = {ofl,lppl1.3},
mirror = {https://mirror.ctan.org/fonts/stickstoo},
url = {https://ctan.org/pkg/stickstoo},
@@ -66233,7 +66726,7 @@
title = {The \texttt{structuredlog} package},
subtitle = {Report files opened and closed in the log, including nesting level},
author = {{The LaTeX Project Team}},
- date = {2024-02-11},
+ date = {2024-06-02},
version = {1.0o},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -66331,6 +66824,17 @@
url = {https://ctan.org/pkg/styledcmd},
}
+@manual{ctan-suanpan-l3,
+ title = {The \texttt{suanpan-l3} package},
+ subtitle = {Traditional Chinese 7-bids suanpan (abacus) package based on l3draw},
+ author = {Nan Geng},
+ date = {2024-09-08},
+ version = {1.2.2},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/suanpan-l3},
+ url = {https://ctan.org/pkg/suanpan-l3},
+}
+
@manual{ctan-suanpan,
title = {The \texttt{suanpan} package},
subtitle = {MetaPost macros for drawing Chinese and Japanese abaci},
@@ -66379,9 +66883,9 @@
title = {The \texttt{subeqn} package},
subtitle = {Package for subequation numbering},
author = {Donald Arseneau and Johannes L. Braams},
- date = {2016-06-24},
- version = {2.0b},
- license = {lppl},
+ date = {2024-07-21},
+ version = {2.0c},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/subeqn},
url = {https://ctan.org/pkg/subeqn},
}
@@ -66390,9 +66894,9 @@
title = {The \texttt{subeqnarray} package},
subtitle = {Equation array with sub numbering},
author = {Johannes L. Braams},
- date = {2016-06-24},
- version = {2.1c},
- license = {lppl},
+ date = {2024-07-21},
+ version = {2.1e},
+ license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/subeqnarray},
url = {https://ctan.org/pkg/subeqnarray},
}
@@ -66622,8 +67126,8 @@
title = {The \texttt{supertabular} package},
subtitle = {A multi-page tables package},
author = {Johannes L. Braams},
- date = {2020-02-02},
- version = {4.1g},
+ date = {2024-07-20},
+ version = {4.2c},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/supertabular},
url = {https://ctan.org/pkg/supertabular},
@@ -67027,8 +67531,8 @@
title = {The \texttt{synthslant} package},
subtitle = {Synthetically slant text},
author = {Chris Spiel},
- date = {2024-05-11},
- version = {0.1},
+ date = {2024-07-09},
+ version = {0.1a},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/synthslant},
url = {https://ctan.org/pkg/synthslant},
@@ -67038,7 +67542,7 @@
title = {The \texttt{syntonly} package},
subtitle = {Run a document through \LaTeX{} for syntax checking},
author = {Frank Mittelbach and Rainer Schöpf and {The LaTeX Project Team}},
- date = {2019-10-04},
+ date = {2024-06-01},
version = {2.1e},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/base},
@@ -67109,7 +67613,7 @@
title = {The \texttt{t-angles} package},
subtitle = {Draw tangles, trees, Hopf algebra operations and other pictures},
author = {Volodymyr Lyubashenko and Yurii Bespalov},
- date = {2017-04-18},
+ date = {2024-07-25},
license = {gpl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/t-angles},
url = {https://ctan.org/pkg/t-angles},
@@ -67311,8 +67815,8 @@
title = {The \texttt{tableof} package},
subtitle = {Tagging tables of contents},
author = {Jean-François Burnol},
- date = {2021-07-05},
- version = {1.4c},
+ date = {2024-09-17},
+ version = {1.4d},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tableof},
url = {https://ctan.org/pkg/tableof},
@@ -67391,8 +67895,8 @@
title = {The \texttt{tablvar} package},
subtitle = {Typesetting pretty tables of signs and variations according to French usage},
author = {Antoine Missier},
- date = {2023-12-26},
- version = {2.0},
+ date = {2024-08-10},
+ version = {2.1},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tablvar},
url = {https://ctan.org/pkg/tablvar},
@@ -67559,8 +68063,8 @@
title = {The \texttt{tabularx} package},
subtitle = {Tabulars with adjustable-width columns},
author = {David Carlisle and {The LaTeX Project Team}},
- date = {2023-11-01},
- version = {2.11c},
+ date = {2024-06-02},
+ version = {2.12a},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/tabularx},
@@ -67570,8 +68074,8 @@
title = {The \texttt{tabulary} package},
subtitle = {Tabular with variable width columns balanced},
author = {David Carlisle},
- date = {2018-01-06},
- version = {0.10},
+ date = {2024-06-06},
+ version = {0.11},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tabulary},
url = {https://ctan.org/pkg/tabulary},
@@ -67632,13 +68136,17 @@
@manual{ctan-tagpdf,
title = {The \texttt{tagpdf} package},
- subtitle = {Tools for experimenting with tagging using pdfLaTeX and LuaLaTeX},
+ subtitle = {Code for PDF tagging using pdfLaTeX and LuaLaTeX},
author = {{The LaTeX Project Team} and Ulrike Fischer},
- date = {2024-04-13},
- version = {0.99b},
+ date = {2024-09-17},
+ version = {0.99f},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tagpdf},
url = {https://ctan.org/pkg/tagpdf},
+ annotation = {The package contains the core code for tagging and accessibility
+ used by the \LaTeX{} kernel in the Tagged PDF project. See
+
+ for more information.},
}
@manual{ctan-talk,
@@ -67730,6 +68238,17 @@
url = {https://ctan.org/pkg/tango-weevil},
}
+@manual{ctan-tango,
+ title = {The \texttt{tango} package},
+ subtitle = {A \LaTeX{} document class for math teachers},
+ author = {Michel Bovani},
+ date = {2024-07-21},
+ version = {0.8.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/luatex/latex/tango},
+ url = {https://ctan.org/pkg/tango},
+}
+
@manual{ctan-tangocolors,
title = {The \texttt{tangocolors} package},
subtitle = {Use colors from the Tango color palette},
@@ -67840,8 +68359,8 @@
title = {The \texttt{tblr-extras} package},
subtitle = {Extra libraries for tabularray for caption and babel compatibility},
author = {Manuel Merino},
- date = {2024-05-14},
- version = {1.1},
+ date = {2024-06-25},
+ version = {1.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tblr-extras},
url = {https://ctan.org/pkg/tblr-extras},
@@ -67900,8 +68419,8 @@
title = {The \texttt{tcolorbox} package},
subtitle = {Coloured boxes, for \LaTeX{} examples and theorems, etc},
author = {Thomas F. Sturm},
- date = {2024-01-10},
- version = {6.2.0},
+ date = {2024-08-23},
+ version = {6.3.0},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tcolorbox},
url = {https://ctan.org/pkg/tcolorbox},
@@ -68033,11 +68552,13 @@
title = {The \texttt{telprint} package},
subtitle = {Format German phone numbers},
author = {Heiko Oberdiek},
- date = {2018-01-06},
- version = {1.11},
- license = {lppl1.3},
- mirror = {https://mirror.ctan.org/macros/latex/contrib/oberdiek/telprint.dtx},
+ date = {2024-08-07},
+ version = {1.12},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/telprint},
url = {https://ctan.org/pkg/telprint},
+ annotation = {The package provides a command for formatting
+ German telephone numbers.},
}
@manual{ctan-telugu,
@@ -68773,8 +69294,8 @@
title = {The \texttt{tex-vpat} package},
subtitle = {TeX Accessibility Conformance Report},
author = {Boris Veytsman},
- date = {2023-04-03},
- version = {2.3},
+ date = {2024-08-18},
+ version = {2.4},
license = {cc-by-3},
mirror = {https://mirror.ctan.org/info/tex-vpat},
url = {https://ctan.org/pkg/tex-vpat},
@@ -69347,8 +69868,8 @@
title = {The \texttt{TeXLab} package},
subtitle = {LaTeX Language Server},
author = {Eric Förster and Patrick Förster},
- date = {2024-05-01},
- version = {5.16.0},
+ date = {2024-07-08},
+ version = {5.19.0},
license = {gpl3},
mirror = {https://mirror.ctan.org/support/texlab},
url = {https://ctan.org/pkg/texlab},
@@ -69527,8 +70048,8 @@
title = {The \texttt{texlogfilter} package},
subtitle = {Filter \LaTeX{} engines output or log file},
author = {Julien Labbé},
- date = {2024-02-14},
- version = {1.3},
+ date = {2024-06-14},
+ version = {1.4},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/support/texlogfilter},
url = {https://ctan.org/pkg/texlogfilter},
@@ -69732,8 +70253,8 @@
title = {The \texttt{texplate} package},
subtitle = {A tool for creating document structures based on templates},
author = {Paulo Roberto Massa Cereda},
- date = {2023-05-17},
- version = {1.0.4},
+ date = {2024-08-02},
+ version = {1.0.6},
license = {bsd3},
mirror = {https://mirror.ctan.org/support/texplate},
url = {https://ctan.org/pkg/texplate},
@@ -69844,8 +70365,8 @@
title = {The \texttt{texshop} package},
subtitle = {TeX front end for use on MacOS X},
author = {Dick Koch},
- date = {2024-05-17},
- version = {5.35},
+ date = {2024-09-13},
+ version = {5.44},
license = {gpl},
mirror = {https://mirror.ctan.org/support/texshop},
url = {https://ctan.org/pkg/texshop},
@@ -70126,8 +70647,8 @@
title = {The \texttt{texvc} package},
subtitle = {Use MediaWiki \LaTeX{} commands},
author = {Moritz Schubotz},
- date = {2018-03-05},
- version = {1.1},
+ date = {2024-07-08},
+ version = {1.2},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/texvc},
url = {https://ctan.org/pkg/texvc},
@@ -70403,8 +70924,8 @@
title = {The \texttt{thermodynamics} package},
subtitle = {Macros for multicomponent thermodynamics documents},
author = {Karl D. Hammond},
- date = {2023-12-06},
- version = {2.01},
+ date = {2024-06-14},
+ version = {2.02},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/thermodynamics},
url = {https://ctan.org/pkg/thermodynamics},
@@ -70600,8 +71121,8 @@
title = {The \texttt{3DLDF} package},
subtitle = {Three-dimensional drawing with MetaPost output},
author = {Laurence Finston},
- date = {2018-01-06},
- version = {1.1.5.1},
+ date = {2024-08-08},
+ version = {3.0},
license = {gpl},
mirror = {https://mirror.ctan.org/graphics/3DLDF},
url = {https://ctan.org/pkg/threedldf},
@@ -70750,8 +71271,8 @@
title = {The \texttt{thuthesis} package},
subtitle = {Thesis template for Tsinghua University},
author = {Ruini Xue and {Tsinghua University TUNA Association}},
- date = {2024-05-20},
- version = {7.5.1},
+ date = {2024-07-01},
+ version = {7.5.2},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/thuthesis},
url = {https://ctan.org/pkg/thuthesis},
@@ -70832,6 +71353,17 @@
incorporates existing changes.},
}
+@manual{ctan-tiet-question-paper,
+ title = {The \texttt{tiet-question-paper} package},
+ subtitle = {A \LaTeX{} question paper class for the TIET},
+ author = {Raghav B. Venkataramaiyer},
+ date = {2024-06-30},
+ version = {},
+ license = {mit},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/tiet-question-paper},
+ url = {https://ctan.org/pkg/tiet-question-paper},
+}
+
@manual{ctan-tif2eps,
title = {The \texttt{tif2eps} package},
subtitle = {A PostScript program for converting TIFF files to EPS},
@@ -71305,8 +71837,8 @@
title = {The \texttt{tikz3d-fr} package},
subtitle = {Work with some 3D figures},
author = {Cédric Pierquet},
- date = {2023-07-22},
- version = {0.1.2},
+ date = {2024-09-16},
+ version = {0.1.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/tikz3d-fr},
url = {https://ctan.org/pkg/tikz3d-fr},
@@ -71882,7 +72414,7 @@
title = {The \texttt{titleps} package},
subtitle = {Page style control},
author = {Javier Bezos López},
- date = {2023-10-17},
+ date = {2024-07-25},
version = {2.15},
license = {mit},
mirror = {https://mirror.ctan.org/macros/latex/contrib/titlesec},
@@ -72059,8 +72591,8 @@
title = {The \texttt{tkz-elements} package},
subtitle = {A Lua library for drawing Euclidean geometry with TikZ or tkz-euclide},
author = {Alain Matthes},
- date = {2024-04-29},
- version = {2.25c},
+ date = {2024-07-16},
+ version = {2.30c},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tkz/tkz-elements},
url = {https://ctan.org/pkg/tkz-elements},
@@ -72111,8 +72643,8 @@
title = {The \texttt{tkz-grapheur} package},
subtitle = {A \LaTeX{} package with tools for graph plotting (and TikZ)},
author = {Cédric Pierquet},
- date = {2024-05-19},
- version = {0.1.0},
+ date = {2024-09-08},
+ version = {0.1.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/tkz-grapheur},
url = {https://ctan.org/pkg/tkz-grapheur},
@@ -72554,7 +73086,7 @@
title = {The \texttt{topcapt} package},
subtitle = {Place captions above figures or tables},
author = {Robin Fairbairns and David Carlisle},
- date = {2018-09-15},
+ date = {2024-07-22},
version = {1.2},
license = {lppl},
mirror = {https://mirror.ctan.org/macros/latex/contrib/misc/topcapt.sty},
@@ -72710,8 +73242,8 @@
title = {The \texttt{tqft} package},
subtitle = {Drawing TQFT diagrams with TikZ/PGF},
author = {Andrew Stacey},
- date = {2017-06-01},
- version = {2.1},
+ date = {2024-06-01},
+ version = {2.3},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tqft},
url = {https://ctan.org/pkg/tqft},
@@ -72811,8 +73343,8 @@
subtitle = {A package for creating tramlines (lines above and below a title used
by lawyers in the UK)},
author = {Elijah Z Granet},
- date = {2023-01-30},
- version = {1.1.0},
+ date = {2024-07-18},
+ version = {1.1.1},
license = {lppl1.3c,cc-by-sa-3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tramlines},
url = {https://ctan.org/pkg/tramlines},
@@ -73104,7 +73636,7 @@
title = {The \texttt{treesvr} package},
subtitle = {Tree macros},
author = {Peter Vanroose},
- date = {2016-06-24},
+ date = {2024-05-29},
version = {},
license = {lppl1.2},
mirror = {https://mirror.ctan.org/macros/latex/contrib/treesvr},
@@ -73148,7 +73680,7 @@
title = {The \texttt{trig} package},
subtitle = {Simple trigonometric functions},
author = {David Carlisle and {The LaTeX Project Team}},
- date = {2021-11-12},
+ date = {2024-06-02},
version = {1.11},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/graphics},
@@ -73479,8 +74011,8 @@
title = {The \texttt{tuda-ci} package},
subtitle = {LaTeX templates of Technische Universität Darmstadt},
author = {Marei Peischl},
- date = {2024-05-07},
- version = {3.38},
+ date = {2024-07-03},
+ version = {3.41},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tuda-ci},
url = {https://ctan.org/pkg/tuda-ci},
@@ -73645,8 +74177,8 @@
title = {The \texttt{tutodoc} package},
subtitle = {Typeset tutorial-like documentations},
author = {Christophe Bal},
- date = {2024-01-07},
- version = {1.1.0},
+ date = {2024-09-25},
+ version = {1.3.0},
license = {gpl3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/tutodoc},
url = {https://ctan.org/pkg/tutodoc},
@@ -73691,7 +74223,7 @@
title = {The \texttt{twemoji-colr} package},
subtitle = {Twemoji font in COLR/CPAL layered format},
author = {Xiangdong Zeng},
- date = {2022-10-28},
+ date = {2024-08-03},
version = {0.7.0},
license = {cc-by-sa-4,apache2},
mirror = {https://mirror.ctan.org/fonts/twemoji-colr},
@@ -74051,8 +74583,8 @@
title = {The \texttt{typog} package},
subtitle = {Typographic fine-tuning and micro-typographic enhancements},
author = {Chris Spiel},
- date = {2024-05-11},
- version = {0.3},
+ date = {2024-07-09},
+ version = {0.4},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/typog},
url = {https://ctan.org/pkg/typog},
@@ -74145,8 +74677,8 @@
title = {The \texttt{uantwerpendocs} package},
subtitle = {Course texts, master theses, and exams in University of Antwerp style},
author = {Walter Daems},
- date = {2024-04-09},
- version = {4.6},
+ date = {2024-08-27},
+ version = {4.8},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/uantwerpendocs},
url = {https://ctan.org/pkg/uantwerpendocs},
@@ -74561,8 +75093,8 @@
title = {The \texttt{ulthese} package},
subtitle = {Thesis class and templates for Université Laval},
author = {Pierre Lasou and Vincent Goulet},
- date = {2021-08-10},
- version = {5.3a},
+ date = {2024-07-03},
+ version = {6.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/ulthese},
url = {https://ctan.org/pkg/ulthese},
@@ -74726,8 +75258,8 @@
title = {The \texttt{UnBTeX} package},
subtitle = {A class for theses at University of Brasilia (UnB)},
author = {Henrique Cezar Ferreira},
- date = {2024-03-01},
- version = {1.5.1},
+ date = {2024-07-04},
+ version = {1.5.2},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/unbtex},
url = {https://ctan.org/pkg/unbtex},
@@ -75011,8 +75543,8 @@
title = {The \texttt{unicodefonttable} package},
subtitle = {A Unicode font table generator},
author = {Frank Mittelbach},
- date = {2024-03-02},
- version = {1.0h},
+ date = {2024-06-06},
+ version = {1.0i},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/unicodefonttable},
url = {https://ctan.org/pkg/unicodefonttable},
@@ -75207,8 +75739,8 @@
title = {The \texttt{univie-ling} package},
subtitle = {Papers, theses and research proposals in (Applied) Linguistics at Vienna University},
author = {Jürgen Spitzmüller},
- date = {2024-05-09},
- version = {2.5},
+ date = {2024-09-20},
+ version = {2.8},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/univie-ling},
url = {https://ctan.org/pkg/univie-ling},
@@ -75786,8 +76318,8 @@
title = {The \texttt{ut-thesis} package},
subtitle = {University of Toronto thesis style},
author = {François Pitt and Jesse Knight},
- date = {2023-02-09},
- version = {3.1.7},
+ date = {2024-07-26},
+ version = {3.1.8},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/ut-thesis},
url = {https://ctan.org/pkg/ut-thesis},
@@ -76086,8 +76618,8 @@
title = {The \texttt{varioref} package},
subtitle = {Intelligent page references},
author = {Frank Mittelbach},
- date = {2023-06-09},
- version = {1.6f},
+ date = {2024-06-02},
+ version = {1.6g},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/varioref},
@@ -76320,8 +76852,8 @@
title = {The \texttt{verbatim} package},
subtitle = {Reimplementation of and extensions to \LaTeX{} verbatim},
author = {Rainer Schöpf and {The LaTeX Project Team}},
- date = {2023-11-21},
- version = {1.5v},
+ date = {2024-06-02},
+ version = {1.5x},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/verbatim},
@@ -76457,9 +76989,9 @@
title = {The \texttt{verifycommand} package},
subtitle = {Verifies definitions are unchanged, such as before patching},
author = {Brian Dunn},
- date = {2024-01-21},
- version = {1.00},
- license = {lppl1.3c},
+ date = {2024-09-03},
+ version = {1.10},
+ license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/verifycommand},
url = {https://ctan.org/pkg/verifycommand},
}
@@ -77418,8 +77950,8 @@
title = {The \texttt{wheelchart} package},
subtitle = {Diagrams with circular or other shapes using TikZ and \LaTeX{}3},
author = {Matthias Floré},
- date = {2024-03-08},
- version = {3.0},
+ date = {2024-07-29},
+ version = {4.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/wheelchart},
url = {https://ctan.org/pkg/wheelchart},
@@ -77840,9 +78372,9 @@
@manual{ctan-wordle,
title = {The \texttt{wordle} package},
subtitle = {Create wordle grids},
- author = {Cédric Pierquet},
- date = {2023-09-04},
- version = {0.1.1},
+ author = {Andrew Mathas and Cédric Pierquet},
+ date = {2024-08-18},
+ version = {0.3.0},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/graphics/pgf/contrib/wordle},
url = {https://ctan.org/pkg/wordle},
@@ -77964,11 +78496,25 @@
url = {https://ctan.org/pkg/wrapfig2},
}
+@manual{ctan-wrapstuff-doc-en,
+ title = {The \texttt{wrapstuff-doc-en} package},
+ subtitle = {English version of the wrapstuff package documentation},
+ author = {Siyu Wu},
+ date = {2024-07-21},
+ version = {0.3},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/info/wrapstuff-doc-en},
+ url = {https://ctan.org/pkg/wrapstuff-doc-en},
+ annotation = {This package provides an English translation
+ of the documentation for the
+ package.},
+}
+
@manual{ctan-wrapstuff,
title = {The \texttt{wrapstuff} package},
subtitle = {Wrapping text around stuff},
author = {Qing Lee},
- date = {2022-08-07},
+ date = {2024-07-19},
version = {0.3},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/wrapstuff},
@@ -77994,8 +78540,8 @@
title = {The \texttt{WriteOnGrid} package},
subtitle = {Write on grid lines},
author = {Cédric Pierquet},
- date = {2024-04-12},
- version = {0.1.6},
+ date = {2024-09-01},
+ version = {0.1.7},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/writeongrid},
url = {https://ctan.org/pkg/writeongrid},
@@ -78145,8 +78691,8 @@
title = {The \texttt{xcharter-math} package},
subtitle = {XCharter-based OpenType Math font for LuaTeX and XeTeX},
author = {Daniel Flipo},
- date = {2024-03-01},
- version = {0.62},
+ date = {2024-07-10},
+ version = {0.63},
license = {ofl,lppl1.3c},
mirror = {https://mirror.ctan.org/fonts/xcharter-math},
url = {https://ctan.org/pkg/xcharter-math},
@@ -78160,8 +78706,8 @@
title = {The \texttt{XCharter} package},
subtitle = {Extension of Bitstream Charter fonts},
author = {Michael Sharpe},
- date = {2023-07-27},
- version = {1.25},
+ date = {2024-06-19},
+ version = {1.26},
license = {other-free,lppl1.3},
mirror = {https://mirror.ctan.org/fonts/xcharter},
url = {https://ctan.org/pkg/xcharter},
@@ -78628,7 +79174,7 @@
title = {The \texttt{xetex} package},
subtitle = {An extended variant of \TeX{} for use with Unicode sources},
author = {Jonathan Kew and Arthur Rosendahl and Khaled Hosny and {The TeX Live Team}},
- date = {2022-01-25},
+ date = {2024-07-25},
license = {x11},
url = {https://ctan.org/pkg/xetex},
}
@@ -78718,7 +79264,7 @@
title = {The \texttt{xfp} package},
subtitle = {Interface to the \LaTeX{}3 floating point unit},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-08-28},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3packages},
@@ -78729,7 +79275,7 @@
title = {The \texttt{xfrac} package},
subtitle = {Split-level fractions},
author = {Morten Høgholm and Lars Madsen and Will Robertson and Joseph Wright and {The LaTeX Project Team}},
- date = {2024-02-17},
+ date = {2024-06-04},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/xfrac},
@@ -78745,7 +79291,7 @@
title = {The \texttt{xgalley} package},
subtitle = {Control text feeding onto the page},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-07-25},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3experimental/xgalley.dtx},
@@ -78837,8 +79383,8 @@
title = {The \texttt{xindex} package},
subtitle = {Unicode-compatible index generation},
author = {Herbert Voß},
- date = {2024-05-17},
- version = {0.60},
+ date = {2024-09-22},
+ version = {0.61},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/indexing/xindex},
url = {https://ctan.org/pkg/xindex},
@@ -78868,6 +79414,17 @@
url = {https://ctan.org/pkg/xindy},
}
+@manual{ctan-xint-regression,
+ title = {The \texttt{xint-regression} package},
+ subtitle = {Classic regressions, with xint},
+ author = {Cédric Pierquet},
+ date = {2024-06-14},
+ version = {0.1.0},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/xint-regression},
+ url = {https://ctan.org/pkg/xint-regression},
+}
+
@manual{ctan-xint,
title = {The \texttt{xint} package},
subtitle = {Expandable arbitrary precision floating point and integer operations},
@@ -79145,7 +79702,7 @@
title = {The \texttt{xparse} package},
subtitle = {A generic document command parser},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-08-28},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3packages},
@@ -79276,8 +79833,8 @@
title = {The \texttt{xr-hyper} package},
subtitle = {Inter-document hyper-references},
author = {David Carlisle and {Oberdiek Package Support Group}},
- date = {2024-01-21},
- version = {7.01h},
+ date = {2024-07-10},
+ version = {7.01j},
license = {lppl1.3},
mirror = {https://mirror.ctan.org/macros/latex/contrib/hyperref},
url = {https://ctan.org/pkg/xr-hyper},
@@ -79287,8 +79844,8 @@
title = {The \texttt{xr} package},
subtitle = {References to other \LaTeX{} documents},
author = {David Carlisle and Jean-Pierre Drucbert and {The LaTeX Project Team}},
- date = {2023-11-01},
- version = {5.06},
+ date = {2024-06-02},
+ version = {6.00},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/required/tools},
url = {https://ctan.org/pkg/xr},
@@ -79305,6 +79862,17 @@
url = {https://ctan.org/pkg/xrefwarn},
}
+@manual{ctan-xreview,
+ title = {The \texttt{xreview} package},
+ subtitle = {Reviewing \LaTeX{} documents made easy(er)},
+ author = {Lorenzo Peri},
+ date = {2024-09-01},
+ version = {1.0},
+ license = {mit},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/xreview},
+ url = {https://ctan.org/pkg/xreview},
+}
+
@manual{ctan-xsavebox,
title = {The \texttt{xsavebox} package},
subtitle = {Saveboxes for repeating content without code replication, based on PDF Form XObjects},
@@ -79410,7 +79978,7 @@
title = {The \texttt{xtemplate} package},
subtitle = {A high-level interface for declaring document commands},
author = {{The LaTeX Project Team}},
- date = {2024-03-14},
+ date = {2024-08-28},
version = {},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/l3packages},
@@ -79639,7 +80207,7 @@
title = {The \texttt{YAMLvars} package},
subtitle = {A YAML parser and tool for easy \LaTeX{} definition creation},
author = {Kale Ewasiuk},
- date = {2023-12-08},
+ date = {2024-08-17},
version = {},
license = {mit},
mirror = {https://mirror.ctan.org/macros/luatex/latex/yamlvars},
@@ -80300,8 +80868,8 @@
title = {The \texttt{zref-clever} package},
subtitle = {Clever \LaTeX{} cross-references based on zref},
author = {{Unknown}},
- date = {2024-05-21},
- version = {0.4.5},
+ date = {2024-08-23},
+ version = {0.4.6},
license = {lppl1.3c},
mirror = {https://mirror.ctan.org/macros/latex/contrib/zref-clever},
url = {https://ctan.org/pkg/zref-clever},
@@ -80345,6 +80913,17 @@
url = {https://ctan.org/pkg/zref},
}
+@manual{ctan-zugferd,
+ title = {The \texttt{zugferd} package},
+ subtitle = {ZUGFeRD and Faktur-X invoicing using \LaTeX{}},
+ author = {Marei Peischl},
+ date = {2024-09-16},
+ version = {0.8},
+ license = {lppl1.3c},
+ mirror = {https://mirror.ctan.org/macros/latex/contrib/zugferd},
+ url = {https://ctan.org/pkg/zugferd},
+}
+
@manual{ctan-zwgetfdate,
title = {The \texttt{zwgetfdate} package},
subtitle = {Get package or file date},