texlive[75059] Master/texmf-dist: citation-style-language (29apr25)
commits+karl at tug.org
commits+karl at tug.org
Tue Apr 29 21:47:32 CEST 2025
Revision: 75059
https://tug.org/svn/texlive?view=revision&revision=75059
Author: karl
Date: 2025-04-29 21:47:32 +0200 (Tue, 29 Apr 2025)
Log Message:
-----------
citation-style-language (29apr25)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md
trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf
trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex
trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.1
trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-parser.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex2csl.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-cli.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-context.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-element.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-ir-node.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-journal-data.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-bibliography.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-choose.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-date.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-group.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-label.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-layout.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-locale.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-names.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-number.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-sort.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-style.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-text.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-nodes.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-output.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-unicode.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-yaml.lua
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc.lua
trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty
trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty
trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty
trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty
trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-ro-RO.xml
trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-th-TH.xml
trunk/Master/texmf-dist/tex/latex/citation-style-language/styles/modern-humanities-research-association.csl
Added Paths:
-----------
trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-lua-uni-words.lua
Modified: trunk/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md 2025-04-29 19:47:32 UTC (rev 75059)
@@ -7,6 +7,24 @@
## [Unreleased]
+## [0.8.0] - 2025-04-29
+
+### Added
+
+- Convert BibTeX entry keys to NFC
+- The entry keys are case-folded for comparing.
+- Add citation option `unsorted`.
+
+### Fixed
+
+- Fix an infinite loop bug of unrecognized `babel` language name ([#65](https://github.com/zepinglee/citeproc-lua/issues/65)).
+- Bib2csl: The hyphens in `number` fields are correctly escaped when converted to CSL-JSON.
+- Bib2csl: Map `shorthand` field to CSL `citation-label` variable.
+- BibTeX parser: Fix hyphen in family name.
+- Fix a bug in EDTF parsing.
+- Bib2csl: Fix a sentence case conversion bug that words after colons are not capitalized.
+- Fix an error when `hyperref` is loaded before CSL ([#91](https://github.com/zepinglee/citeproc-lua/issues/91)).
+
## [0.7.0] - 2025-02-23
### Added
@@ -80,6 +98,7 @@
- Add support for multiple bibliographies (`refsection` environment).
- Add global `ref-section` option.
+- Add support for `biber`'s `%`-style inline comment in `.bib` files.
### Fixed
@@ -98,13 +117,13 @@
- 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
+### Changed
- Check if the `\cite` command is in a footnote.
## [0.4.9] - 2024-04-21
-## Added
+### Added
- Add normal paragraph style for list of references ([#60](https://github.com/zepinglee/citeproc-lua/discussions/60)).
@@ -281,7 +300,8 @@
- Initial CTAN release.
-[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.7.0...HEAD
+[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.8.0...HEAD
+[0.8.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.8...v0.7.0
[0.6.8]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.7...v0.6.8
[0.6.7]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.6...v0.6.7
Modified: trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex 2025-04-29 19:47:32 UTC (rev 75059)
@@ -51,7 +51,7 @@
}%
}
-\date{2025-02-23 v0.7.0}
+\date{2025-04-29 v0.8.0}
\maketitle
@@ -310,6 +310,16 @@
\cite[prefix = {See }, page = 42]{ITEM-1}
\end{LaTeXdemo}
+\DescribeOption{unsorted}
+Some styles specify the order of items in the citations (e.g., alphabetical
+or chronological) and the \opt{unsorted} option can be used to disable this
+behavior. This is useful in cases like citing secondary sources. The following
+exapmle produces “(Rabitt, 1982, as cited in Lyon 2014)”.
+
+\begin{LaTeXdemo}
+ \cites{rabitt1982}[prefix={, as cited in}, unsorted = true]{lyon2014}
+\end{LaTeXdemo}
+
\begin{table}
\centering
\caption{The locators supported in CSL v1.0.2.}
Modified: trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.1 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.1 2025-04-29 19:47:32 UTC (rev 75059)
@@ -1,4 +1,4 @@
-.TH citeproc-lua 1 "0.7.0"
+.TH citeproc-lua 1 "0.8.0"
.SH NAME
citeproc-lua \- make CSL citations and bibliography for LaTeX
.SH SYNOPSIS
Modified: trunk/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -478,6 +478,7 @@
},
legmaterial = {
csl = "legislation",
+ notes = "APA §11.6: Legislative materials include federal testimony, hearings, bills, resolutions, reports, and related documents.",
source = "apa.dbx",
},
letter = {
@@ -1696,8 +1697,8 @@
type = "entrykey",
},
entrysubtype = {
- csl = nil,
- notes = "Not supported.",
+ csl = "genre",
+ notes = "May be used to determine the entry type (article-magazine).",
source = "biblatex",
type = "literal",
},
@@ -3191,8 +3192,8 @@
type = "option",
},
relatedstring = {
- csl = nil,
- notes = "Not supported.",
+ csl = "genre",
+ notes = "The style apa.csl assumes that `genre` is entered as “Review of the book” or similar.",
source = "biblatex",
type = "literal",
},
@@ -3433,8 +3434,8 @@
type = "literal",
},
shorthand = {
- csl = nil,
- notes = "Not supported.",
+ csl = "citation-label",
+ notes = "A special designation to be used by the citation style instead of the usual label.",
source = "biblatex",
type = "literal",
},
@@ -3792,7 +3793,7 @@
type = "literal",
},
titleaddon = {
- csl = nil,
+ csl = "genre",
source = "biblatex",
type = "literal",
},
@@ -4482,6 +4483,7 @@
},
primary_fields = {
annotation = "note",
+ archive = "archive",
["archive-place"] = "archive-place",
author = "author",
bookauthor = "container-author",
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-parser.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-parser.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-parser.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -38,12 +38,11 @@
local Cc = lpeg.Cc
local Cf = lpeg.Cf
local Cg = lpeg.Cg
-local Cmt = lpeg.Cmt
-local Cp = lpeg.Cp
local Ct = lpeg.Ct
local V = lpeg.V
+--- at diagnostic disable codestyle-check
-- Learned from <http://boston.conman.org/2020/06/05.1>.
local function case_insensitive_pattern(str)
local char = R("AZ", "az") / function (c) return P(c:lower()) + P(c:upper()) end
@@ -60,8 +59,10 @@
-- Based on the grammar described at <https://github.com/aclements/biblib>.
local function get_bibtex_grammar()
- local comment = (1 - P"@")^0
- local space = S(" \t\r\n")^0
+ local inline_comment = P"%" * (1-P"\n")^0 * P"\n"
+ local comment = (inline_comment + 1 - P"@")^0
+ -- local ws = S(" \t\r\n")^0
+ local ws = (S" \t\r\n" + inline_comment)^0
local comment_cmd = case_insensitive_pattern("comment")
local balanced = P{ "{" * V(1)^0 * "}" + (1 - S"{}") }
local ident = (- R"09") * (R"\x20\x7F" - S" \t\"#%'(),={}")^1
@@ -75,31 +76,31 @@
name = string.lower(name),
}
end
- local value = Ct(piece * (space * P"#" * space * piece)^0)
+ local value = Ct(piece * (ws * P"#" * ws * piece)^0)
- local string_body = Cg(ident / string.lower, "name") * space * P"=" * space * Cg(value, "contents")
- local string_cmd = Ct(Cg(Cc"string", "category") * case_insensitive_pattern("string") * space * (
- P"{" * space * string_body * space * P"}"
- + P"(" * space * string_body * space * P")"
+ local string_body = Cg(ident / string.lower, "name") * ws * P"=" * ws * Cg(value, "contents")
+ local string_cmd = Ct(Cg(Cc"string", "category") * case_insensitive_pattern("string") * ws * (
+ P"{" * ws * string_body * ws * P"}"
+ + P"(" * ws * string_body * ws * P")"
))
local preamble_body = Cg(value, "contents")
- local preamble_cmd = Ct(Cg(Cc"preamble", "category") * case_insensitive_pattern("preamble") * space * (
- P"{" * space * preamble_body * space * P"}"
- + P"(" * space * preamble_body * space * P")"
+ local preamble_cmd = Ct(Cg(Cc"preamble", "category") * case_insensitive_pattern("preamble") * ws * (
+ P"{" * ws * preamble_body * ws * P"}"
+ + P"(" * ws * preamble_body * ws * P")"
))
local key = (1 - S", \t}\r\n")^0
local key_paren = (1 - S", \t\r\n")^0
- local field_value_pair = (ident / string.lower) * space * P"=" * space * value -- * record_success_position()
+ local field_value_pair = (ident / string.lower) * ws * P"=" * ws * value -- * record_success_position()
- local entry_body = Cf(Ct"" * (P"," * space * Cg(field_value_pair))^0 * (P",")^-1, rawset)
- local entry = Ct(Cg(Cc"entry", "category") * Cg(ident / string.lower, "type") * space * (
- P"{" * space * Cg(key, "key") * space * Cg(entry_body, "fields")^-1 * space * (P"}")
- + P"(" * space * Cg(key_paren, "key") * space * Cg(entry_body, "fields")^-1 * space * (P")")
+ local entry_body = Cf(Ct"" * (P"," * ws * Cg(field_value_pair))^0 * (P",")^-1, rawset)
+ local entry = Ct(Cg(Cc"entry", "category") * Cg(ident / string.lower, "type") * ws * (
+ P"{" * ws * Cg(key, "key") * ws * Cg(entry_body, "fields")^-1 * ws * (P"}")
+ + P"(" * ws * Cg(key_paren, "key") * ws * Cg(entry_body, "fields")^-1 * ws * (P")")
))
- local command_or_entry = P"@" * space * (comment_cmd + preamble_cmd + string_cmd + entry)
+ local command_or_entry = P"@" * ws * (comment_cmd + preamble_cmd + string_cmd + entry)
-- The P(-1) causes nil parsing result in case of error.
local bibtex_grammar = Ct(comment * (command_or_entry * comment)^0) * P(-1)
@@ -106,6 +107,7 @@
return bibtex_grammar
end
+--- at diagnostic enable codestyle-check
local function concat_strings(pieces, strings)
@@ -114,7 +116,7 @@
if type(piece) == "string" then
value = value .. piece
elseif type(piece) == "table" and piece.category == "string" then
- local piece_str = strings[piece.name]
+ local piece_str = strings[bibtex_parser.normalize_key(piece.name)]
if piece_str then
value = value .. piece_str
else
@@ -162,9 +164,8 @@
return obj
end
---- at alias EntryKey string
---- at alias BibtexEntry { key: EntryKey, type: string, fields: table<string, string> }
+--- at alias BibtexEntry { key: string, type: string, fields: table<string, string> }
--- at class BibtexData
--- at field entries BibtexEntry[]
--- at field entries_by_id table<string, BibtexEntry>
@@ -173,7 +174,6 @@
--- at alias Exception table
----comment
--- at param bib_str string
--- at param strings table<string, string>?
--- at return BibtexData?
@@ -216,8 +216,9 @@
elseif object.category == "string" then
local string_value = concat_strings(object.contents, strings)
- strings[object.name] = string_value
- res.strings[object.name] = string_value
+ local normalized_name = bibtex_parser.normalize_key(object.name)
+ strings[normalized_name] = string_value
+ res.strings[normalized_name] = string_value
elseif object.category == "preamble" then
local value = concat_strings(object.contents, strings)
@@ -227,8 +228,8 @@
res.preamble = value
end
- -- elseif object.category == "comment" then
- -- Is this really needed?
+ -- elseif object.category == "comment" then
+ -- Is this really needed?
elseif object.category == "exception" then
-- TODO
@@ -271,7 +272,7 @@
return object
end
-
+--- at diagnostic disable codestyle-check
-- continuation byte
local utf8_cont = lpeg.R("\128\191")
@@ -292,6 +293,7 @@
+ P(1) / function (c) return P(c) end
return Cf(char^1, function (a, b) return a * b end):match(str)
end
+--- at diagnostic enable codestyle-check
--- at alias NameDict table<string, string>
@@ -301,9 +303,11 @@
--- at param str NameStr name field value
--- at return NameStr[]
function bibtex_parser.split_names(str)
+ --- at diagnostic disable codestyle-check
local delimiter_and = ignore_case("and") * (space + -1)
local name = (balanced - space * delimiter_and)^1
local names = Ct(((white_space * delimiter_and) + C(name))^0)
+ --- at diagnostic enable codestyle-check
return names:match(str)
end
@@ -314,17 +318,19 @@
str = util.strip(str)
if string.match(str, ",$") then
util.warning(string.format("Name '%s' has has a comma at the end.", str))
- str = string.gsub(str, ",$", '')
+ str = string.gsub(str, ",$", "")
end
+ --- at diagnostic disable codestyle-check
local comma = P","
local comma_part = (balanced - comma)^0
local comma_parts = Ct(C(comma_part) * (comma * white_space * C(comma_part))^0)
+ --- at diagnostic enable codestyle-check
local parts = comma_parts:match(str)
local is_biblatex_extended_format = false
if #parts > 0 and (string.match(parts[1], "^[a-zA-Z]+%-?i?%s*=")
- or string.match(parts[1], '^"[a-zA-Z]+%-?i?%s*=.*"$')) then
+ or string.match(parts[1], '^"[a-zA-Z]+%-?i?%s*=.*"$')) then
is_biblatex_extended_format = true
end
@@ -430,8 +436,10 @@
key = "jr-i"
end
+ --- at diagnostic disable codestyle-check
local braced_pattern = P"{" * C(balanced^0) * P"}" * P(-1)
local stripped = braced_pattern:match(value)
+ --- at diagnostic enable codestyle-check
if stripped then
value = stripped
end
@@ -442,13 +450,15 @@
end
function bibtex_parser._split_first_von_last_parts(str)
- local word_sep = P"-" + P"~" + P(util.unicode['no-break space'])
+ --- at diagnostic disable codestyle-check
+ local word_sep = P" " + P"~" + P(util.unicode['no-break space'])
local word_tokens = Ct(C(utf8_balanced - space_char - word_sep)^0)
local words_and_seps = Ct(word_tokens * (C(space + word_sep) * word_tokens)^0)
local pieces = words_and_seps:match(str)
+ --- at diagnostic enable codestyle-check
local words = {}
- local seps = { "" }
+ local seps = {""}
for _, piece in ipairs(pieces) do
if type(piece) == "table" then
@@ -475,9 +485,6 @@
end
end
- -- util.debug(von_start)
- -- util.debug(von_stop)
-
local name = {}
if von_stop > 0 then
@@ -496,9 +503,11 @@
end
function bibtex_parser._split_von_last_parts(str)
+ --- at diagnostic disable codestyle-check
local word_sep = P"-" + P"~" + P(util.unicode['no-break space'])
local word_tokens = Ct(C(utf8_balanced - space_char - word_sep)^0)
local words_and_seps = Ct(word_tokens * (C(space + word_sep) * word_tokens)^0)
+ --- at diagnostic enable codestyle-check
local pieces = words_and_seps:match(str)
local words = {}
@@ -538,17 +547,24 @@
--- at param parts string[]
--- at return NameDict
function bibtex_parser._split_last_jr_first_parts(parts)
- local name = bibtex_parser._split_von_last_parts(parts[1])
- if parts[2] ~= "" then
- name.jr = parts[2]
- end
- if parts[3] ~= "" then
- name.first = parts[3]
- end
- return name
+ local name = bibtex_parser._split_von_last_parts(parts[1])
+ if parts[2] ~= "" then
+ name.jr = parts[2]
+ end
+ if parts[3] ~= "" then
+ name.first = parts[3]
+ end
+ return name
end
+function bibtex_parser.normalize_key(entry_key)
+ local normalized_key = unicode.NFC(entry_key)
+ normalized_key = unicode.casefold(normalized_key)
+ return normalized_key
+end
+
+
--- Note that BibTeX find crossref in a case-insensitive manner (see
--- `article-crossref` in `xampl.bib`) which is unlike biber/biblatex.
--- This function is case-sensitive.
@@ -558,7 +574,7 @@
if not entry_dict then
entry_dict = {}
for _, entry in ipairs(entry_list) do
- entry_dict[entry.key] = entry
+ entry_dict[bibtex_parser.normalize_key(entry.key)] = entry
end
end
for _, entry in ipairs(entry_list) do
@@ -566,7 +582,7 @@
--- at type string?
local ref_key = entry.fields.crossref
while ref_key do
- local crossref_entry = entry_dict[ref_key]
+ local crossref_entry = entry_dict[bibtex_parser.normalize_key(ref_key)]
if crossref_entry then
ref_entry = crossref_entry
for field, value in pairs(ref_entry.fields) do
@@ -576,7 +592,8 @@
end
ref_key = ref_entry.fields.crossref
else
- util.warning(string.format("Didn't find a database entry for crossref '%s' in entry '%s'.", ref_key, ref_entry.key))
+ util.warning(string.format("Didn't find a database entry for crossref '%s' in entry '%s'.", ref_key,
+ ref_entry.key))
ref_entry.fields.crossref = nil
ref_key = nil
end
@@ -588,7 +605,6 @@
bibtex_parser._default_parser = BibtexParser:new()
----comment
--- at param bib_str string input string
--- at param strings table<string, string>? strings
--- at return BibtexData?, Exception[]
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex2csl.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex2csl.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex2csl.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -13,7 +13,7 @@
local latex_parser
local unicode
local util
-local using_luatex, kpse = pcall(require, "kpse")
+local using_luatex, _ = pcall(require, "kpse")
if using_luatex then
uni_utf8 = require("unicode").utf8
bibtex_parser = require("citeproc-bibtex-parser")
@@ -33,9 +33,6 @@
--- at alias CslData CslItem[]
-local parser = bibtex_parser.BibtexParser:new()
-
-
---Parse BibTeX content and convert to CSL-JSON
--- at param str string
--- at param keep_unknown_commands boolean? Keep unknown latex markups in <code>.
@@ -43,7 +40,8 @@
--- at param sentence_case_title boolean? Convert `title` and `booktitle` to sentence case.
--- at param check_sentence_case boolean? Check titles that are already sentence cased and do not conver them.
--- at return CslData?, Exception[]
-function bibtex2csl.parse_bibtex_to_csl(str, keep_unknown_commands, case_protection, sentence_case_title, check_sentence_case)
+function bibtex2csl.parse_bibtex_to_csl(str, keep_unknown_commands, case_protection, sentence_case_title,
+ check_sentence_case)
local strings = {}
for name, macro in pairs(bibtex_data.macros) do
strings[name] = macro.value
@@ -51,8 +49,10 @@
local bib_data, exceptions = bibtex_parser.parse(str, strings)
local csl_json_items = nil
if bib_data then
+ -- TODO: Ideally we should load all .bib files and then resolve crossrefs and related
bibtex_parser.resolve_crossrefs(bib_data.entries, bibtex_data.entries_by_id)
- csl_json_items = bibtex2csl.convert_to_csl_data(bib_data, keep_unknown_commands, case_protection, sentence_case_title, check_sentence_case)
+ csl_json_items = bibtex2csl.convert_to_csl_data(bib_data, keep_unknown_commands, case_protection,
+ sentence_case_title, check_sentence_case)
end
return csl_json_items, exceptions
end
@@ -64,19 +64,25 @@
--- at param sentence_case_title boolean?
--- at param check_sentence_case boolean?
--- at return CslData
-function bibtex2csl.convert_to_csl_data(bib, keep_unknown_commands, case_protection, sentence_case_title, check_sentence_case)
+function bibtex2csl.convert_to_csl_data(bib, keep_unknown_commands, case_protection, sentence_case_title,
+ check_sentence_case)
local csl_data = {}
-- BibTeX looks for crossref in a case-insensitive manner.
- local entries_by_id = {}
+ local bib_entry_dict = {}
+ local csl_item_dict = {}
+
for _, entry in ipairs(bib.entries) do
- entries_by_id[unicode.casefold(entry.key)] = entry
- end
+ bib_entry_dict[unicode.casefold(entry.key)] = entry
+ local item = bibtex2csl.convert_to_csl_item(entry, keep_unknown_commands, case_protection, sentence_case_title,
+ check_sentence_case)
- for _, entry in ipairs(bib.entries) do
- local item = bibtex2csl.convert_to_csl_item(entry, keep_unknown_commands, case_protection, sentence_case_title, check_sentence_case)
table.insert(csl_data, item)
+ csl_item_dict[item.id] = item
end
+
+ bibtex2csl.resolve_related(csl_item_dict, bib_entry_dict)
+
return csl_data
end
@@ -87,7 +93,8 @@
--- at param sentence_case_title boolean?
--- at param check_sentence_case boolean?
--- at return CslItem
-function bibtex2csl.convert_to_csl_item(entry, keep_unknown_commands, case_protection, sentence_case_title, check_sentence_case, disable_journal_abbreviation)
+function bibtex2csl.convert_to_csl_item(entry, keep_unknown_commands, case_protection, sentence_case_title,
+ check_sentence_case, disable_journal_abbreviation)
--- at type CslItem
local item = {
id = entry.key,
@@ -159,6 +166,28 @@
-- Merge title, maintitle, subtitle, titleaddon
bibtex2csl.process_titles(entry)
+ -- biblatex-apa
+ if entry.fields.howpublished then
+ local howpublished = string.lower(entry.fields.howpublished)
+ if howpublished == "advance online publication" then
+ -- TODO: get_locale_term("advance online publication" )
+ item.status = "Advance online publication"
+ elseif howpublished == "manunpub" then
+ -- biblatex-apa
+ item.genre = "Unpublished manuscript"
+ elseif howpublished == "maninprep" then
+ -- biblatex-apa
+ item.genre = "Manuscript in preparation"
+ elseif howpublished == "mansub" then
+ -- biblatex-apa
+ item.genre = "Manuscript submitted for publication"
+ end
+ end
+ if entry.fields.pubstate
+ and string.lower(entry.fields.pubstate) == "inpress" then
+ -- TODO: get_locale_term("advance online publication" )
+ item.status = "in press"
+ end
end
@@ -165,18 +194,22 @@
--- at param entry BibtexEntry
function bibtex2csl.process_titles(entry)
local fields = entry.fields
+ -- title and subtitle
if fields.subtitle then
- if not fields.shorttitle then
- fields.shorttitle = fields.title
- end
if fields.title then
fields.title = util.join_title(fields.title, fields.subtitle)
+ if not fields.shorttitle then
+ fields.shorttitle = fields.title
+ end
else
fields.title = fields.subtitle
end
+ fields.subtitle = nil
end
+
+ -- booktitle and booksubtitle
if fields.booksubtitle then
- if not fields.shorttitle then
+ if not fields["container-title-short"] then
fields["container-title-short"] = fields.booktitle
end
if fields.booktitle then
@@ -184,7 +217,43 @@
else
fields.booktitle = fields.booksubtitle
end
+ fields.booksubtitle = nil
end
+
+ -- mainsubtitle
+ if fields.mainsubtitle then
+ if fields.maintitle then
+ fields.maintitle = util.join_title(fields.maintitle, fields.mainsubtitle)
+ else
+ fields.maintitle = fields.mainsubtitle
+ end
+ end
+
+ -- maintitle
+ if fields.maintitle then
+ if entry.type == "audio" or entry.type == "video" then
+ -- maintitle is the container-title
+ fields["container-title"] = fields.maintitle
+ elseif fields.booktitle then
+ -- maintitle is with booktitle
+ if not fields["volume-title"] then
+ fields["volume-title"] = fields.booktitle
+ fields.booktitle = fields.maintitle
+ end
+ else
+ -- maintitle is with title
+ if fields.title then
+ if not fields["volume-title"] then
+ fields["volume-title"] = fields.title
+ fields.title = fields.maintitle
+ end
+ else
+ -- This is unlikelu to happen.
+ fields.title = fields.maintitle
+ end
+ end
+ end
+
if fields.journalsubtitle then
if fields.journaltitle then
fields.journaltitle = util.join_title(fields.journaltitle, fields.journalsubtitle)
@@ -191,16 +260,15 @@
elseif fields.journal then
fields.journal = util.join_title(fields.journal, fields.journal)
end
+ fields.journalsubtitle = nil
end
if fields.issuesubtitle then
- if not fields.shorttitle then
- fields["volume-title-short"] = fields.issuetitle
- end
if fields.issuetitle then
fields.issuetitle = util.join_title(fields.issuetitle, fields.issuesubtitle)
else
fields.issuetitle = fields.issuesubtitle
end
+ fields.issuesubtitle = nil
end
end
@@ -215,7 +283,8 @@
--- at param check_sentence_case boolean?
--- at return string? csl_field
--- at return string | table | number? csl_value
-function bibtex2csl.convert_field(bib_field, value, keep_unknown_commands, case_protection, sentence_case_title, language, check_sentence_case)
+function bibtex2csl.convert_field(bib_field, value, keep_unknown_commands, case_protection, sentence_case_title,
+ language, check_sentence_case)
local field_data = bibtex_data.fields[bib_field]
if not field_data then
return nil, nil
@@ -234,7 +303,7 @@
local field_type = field_data.type
local csl_value
if field_type == "name" then
- -- 1. unicode 2. prify (remove LaTeX markups) 3. plain text 4. split name parts
+ -- 1. unicode 2. prify (remove LaTeX markups) 3. plain text 4. split name parts
value = latex_parser.latex_to_unicode(value)
local names = bibtex_parser.split_names(value)
csl_value = {}
@@ -244,17 +313,19 @@
end
elseif field_type == "date" then
- csl_value = latex_parser.latex_to_pseudo_html(value, false, false)
- csl_value = bibtex2csl._parse_edtf_date(csl_value)
+ if string.match(value, "\\") then
+ -- "{\noopsort{1973c}}1981"
+ value = latex_parser.latex_to_pseudo_html(value, false, false)
+ end
+ -- "-3000~" should not be converted to "-3000 "
+ csl_value = util.parse_edtf(value)
elseif bib_field == "title" or bib_field == "shorttitle"
or bib_field == "booktitle" or bib_field == "container-title-short" then
- -- util.debug(value)
-- 1. unicode 2. sentence case 3. html tag
if sentence_case_title and (not language or util.startswith(language, "en")) then
- -- util.debug(value)
- csl_value = latex_parser.latex_to_sentence_case_pseudo_html(value, keep_unknown_commands, case_protection, check_sentence_case)
- -- util.debug(csl_value)
+ csl_value = latex_parser.latex_to_sentence_case_pseudo_html(value, keep_unknown_commands, case_protection,
+ check_sentence_case)
else
csl_value = latex_parser.latex_to_pseudo_html(value, keep_unknown_commands, case_protection)
end
@@ -281,10 +352,9 @@
function bibtex2csl.convert_to_csl_name(bibtex_name)
if bibtex_name.last and not (bibtex_name.first or bibtex_name.von or bibtex_name.jr)
- and string.match(bibtex_name.last, "^%b{}$") then
- -- util.debug(bibtex_name)
+ and string.match(bibtex_name.last, "^%b{}$") then
return {
- literal = string.sub(bibtex_name.last, 2, -2)
+ literal = string.sub(bibtex_name.last, 2, -2),
}
end
local csl_name = {
@@ -297,11 +367,126 @@
end
+local arxiv_url_prefix = "https://arxiv.org/abs/"
+local pubmed_url_prefix = "https://www.ncbi.nlm.nih.gov/pubmed/"
+local pubmed_central_url_prefix = "https://www.ncbi.nlm.nih.gov/pmc/articles/"
+
+
--- at param item CslItem
--- at param entry BibtexEntry
function bibtex2csl.post_process_special_fields(item, entry, disable_journal_abbreviation)
local bib_type = entry.type
local bib_fields = entry.fields
+
+ -- biblatex-apa
+ if item.type == "article-journal" and entry.fields.entrysubtype == "nonacademic" then
+ item.type = "article-magazine"
+ item.genre = nil
+
+ elseif item.type == "motion_picture" then
+ if entry.fields.entrysubtype == "tvseries" then
+ item.type = "broadcast"
+ if item.genre == "tvseries" then
+ item.genre = "TV series"
+ end
+ elseif entry.fields.entrysubtype == "tvepisode" then
+ item.type = "broadcast"
+ if item.genre == "tvepisode" then
+ item.genre = "TV series episode"
+ end
+ end
+
+ elseif item.type == "song" then
+ if entry.fields.entrysubtype == "podcast" then
+ item.type = "broadcast"
+ if item.genre == "podcast" then
+ item.genre = "Audio podcast"
+ end
+
+ elseif entry.fields.entrysubtype == "podcastepisode" then
+ item.type = "broadcast"
+ if item.genre == "podcastepisode" then
+ item.genre = "Audio podcast episode"
+ end
+
+ elseif entry.fields.entrysubtype == "interview" then
+ item.type = "interview"
+
+ elseif entry.fields.entrysubtype == "speech" then
+ item.type = "speech"
+
+ end
+
+ elseif item.type == "graphic" then
+ item["archive-place"] = item["publisher-place"]
+
+ if entry.fields.entrysubtype == "map" then
+ item.type = "map"
+ end
+
+ elseif item.type == "webpage" then
+
+ -- eprinttype is mapped to
+ -- - `archive` for Google books;
+ -- - `container-title` for twitter post;
+ -- - `publisher` for arXiv preprint;
+
+ local eprint_type_map = {
+ facebook = "post",
+ instagram = "post",
+ reddit = "post",
+ twitter = "post",
+ arxiv = "preprint",
+ psyarxiv = "preprint",
+ pubmed = "preprint",
+ ["pubmed central"] = "preprint",
+ }
+
+ -- Biblatex's `online` type can be mapped to `post`, `preprint`
+ -- local eprinttype = entry.fields.eprinttype or entry.fields.archiveprefix
+ if item.archive then
+ local eprint_type = eprint_type_map[string.lower(item.archive)]
+ if eprint_type then
+ item.type = eprint_type
+ elseif item.number then
+ item.type = "preprint"
+ elseif entry.fields.eprint then
+ item.type = "preprint"
+ item.numerb = entry.fields.eprint
+ elseif item.DOI then
+ item.type = "preprint"
+ elseif item.URL then
+ if util.startswith(item.URL, arxiv_url_prefix) then
+ item.type = "preprint"
+ elseif util.startswith(item.URL, pubmed_url_prefix) then
+ item.type = "preprint"
+ elseif util.startswith(item.URL, pubmed_central_url_prefix) then
+ item.type = "preprint"
+ end
+ end
+ if item.type == "preprint" then
+ if not item.publisher then
+ item.publisher = item.archive
+ item.archive = nil
+ end
+ if not item.number then
+ item.number = entry.fields.eprint
+ end
+ else
+ if not item["container-title"] then
+ item["container-title"] = item.archive
+ item.archive = nil
+ end
+ end
+ end
+
+ end
+
+ -- event-date
+ if item["event-date"] and not item.issued then
+ item.issued = util.deep_copy(item["event-date"])
+ end
+
-- event-title: for compatibility with CSL v1.0.1 and earlier versions
if item["event-title"] then
item.event = item["event-title"]
@@ -315,6 +500,15 @@
end
end
+ if not item.genre then
+ if bib_type == "phdthesis" then
+ -- from APA
+ item.genre = "Doctoral dissertation"
+ elseif bib_type == "mastersthesis" then
+ item.genre = "Master’s thesis"
+ end
+ end
+
-- month
-- local month = bib_fields.month
local month_text = bib_fields.month
@@ -350,7 +544,7 @@
elseif item["collection-title"] and not item["collection-number"] then
item["collection-number"] = bib_fields.number
elseif not item.number then
- item.number = bib_fields.number
+ item.number = string.gsub(bib_fields.number, "([^-])%-([^-])", "%1\\-%2")
end
end
@@ -359,7 +553,7 @@
if item.publisher or bib_type == "inproceedings" or bib_type == "proceedings" then
if not item.organizer then
item.organizer = {
- literal = bib_fields.organization
+ literal = bib_fields.organization,
}
end
elseif not item.publisher then
@@ -379,6 +573,46 @@
item.PMID = bib_fields.eprint
end
+ if item.URL then
+ if item.type == "preprint" and util.startswith(item.URL, arxiv_url_prefix) then
+ if not item.publisher then
+ item.publisher = "arXiv"
+ item.archive = nil
+ end
+ if not item.number then
+ item.number = util.remove_prefix(item.URL, pubmed_url_prefix)
+ end
+ end
+
+ if util.startswith(item.URL, pubmed_url_prefix) then
+ if not item.publisher then
+ item.publisher = "PubMed"
+ item.archive = nil
+ end
+ if not item.PMID then
+ item.PMID = util.remove_prefix(item.URL, pubmed_url_prefix)
+ end
+ end
+
+ if util.startswith(item.URL, pubmed_central_url_prefix) then
+ if not item.publisher then
+ item.publisher = "PubMed Central"
+ item.archive = nil
+ end
+ if not item.PMCID then
+ item.PMCID = util.remove_prefix(item.URL, pubmed_central_url_prefix)
+ end
+ end
+ end
+
+ -- `APA Education [@APAEducation], (2018, June 29). College students are forming menta/-health c/ubs-and they're making a difference @washingtonpost [Thumbnail with link attached]`
+ -- The `[Thumbnail with link attached]` should not be italicized.
+ -- if bib_fields.titleaddon and item.genre and item.genre ~= bib_fields.titleaddon then
+ -- if item.title then
+ -- item.title = string.format("%s [%s]", item.title, bib_fields.titleaddon)
+ -- end
+ -- end
+
end
@@ -406,43 +640,59 @@
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
+local original_field_dict = {
+ author = "original-author",
+ issued = "original-date",
+ publisher = "original-publisher",
+ ["publisher-place"] = "original-publisher-place",
+ title = "original-title",
+}
- local literal = { literal = str }
+local reviewed_field_dict = {
+ author = "reviewed-author",
+ genre = "reviewed-genre",
+ title = "reviewed-title",
+}
- if #date_range > 2 then
- return literal
- end
- local date = {}
- date["date-parts"] = {}
- for _, date_part in ipairs(date_range) do
- local date_ = bibtex2csl._parse_single_date(date_part)
- if not date_ then
- return literal
- end
- table.insert(date["date-parts"], date_)
- end
- return date
-end
+--- at param csl_item_dict table<string, CslItem>
+--- at param bib_entry_dict table<string, BibtexEntry>
+function bibtex2csl.resolve_related(csl_item_dict, bib_entry_dict)
+ for _, entry in pairs(bib_entry_dict) do
+ local related_key = entry.fields.related
+ local related_type = entry.fields.relatedtype
+ if related_key then
+ local related_bib_entry = bib_entry_dict[unicode.casefold(related_key)]
+ if related_bib_entry then
+ local csl_item = csl_item_dict[entry.key]
+ local related_csl_item = csl_item_dict[related_bib_entry.key]
+ if related_type == "reprintof" or related_type == "reprintfrom" then
+ for original_field, new_field in pairs(original_field_dict) do
+ if not csl_item[new_field] and related_csl_item[original_field] then
+ csl_item[new_field] = util.deep_copy(related_csl_item[original_field])
+ end
+ end
+ elseif related_type == "translationof" or related_type == "translationfrom" then
+ for original_field, new_field in pairs(original_field_dict) do
+ if not csl_item[new_field] and related_csl_item[original_field] then
+ csl_item[new_field] = util.deep_copy(related_csl_item[original_field])
+ end
+ end
-function bibtex2csl._parse_single_date(str)
- local date = {}
- for _, date_part in ipairs(util.split(str, "%-")) do
- if not string.match(date_part, "^%d+$") then
- return nil
+ elseif related_type == "reviewof" then
+ for reviewed_field, new_field in pairs(reviewed_field_dict) do
+ if not csl_item[new_field] and related_csl_item[reviewed_field] then
+ csl_item[new_field] = util.deep_copy(related_csl_item[reviewed_field])
+ end
+ end
+
+ end
+ else
+ util.warning(string.format('Related entry "%s" of "%s" not found.', related_key, entry.key))
+ end
end
- table.insert(date, tonumber(date_part))
end
- return date
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-cli.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-cli.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-cli.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -1,4 +1,3 @@
-
--
-- Copyright (c) 2021-2025 Zeping Lee
-- Released under the MIT license.
@@ -8,40 +7,39 @@
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 bibtex2csl -- = require("citeproc-bibtex2csl") -- load on demand
local util = require("citeproc-util")
-local latex_parser = require("citeproc-latex-parser")
-- http://lua-users.org/wiki/AlternativeGetOpt
-local function getopt( arg, options )
+local function getopt(arg, options)
local tab = {}
for k, v in ipairs(arg) do
- if string.sub( v, 1, 2) == "--" then
- local x = string.find( v, "=", 1, true )
- if x then tab[ string.sub( v, 3, x-1 ) ] = string.sub( v, x+1 )
- else tab[ string.sub( v, 3 ) ] = true
+ if string.sub(v, 1, 2) == "--" then
+ local x = string.find(v, "=", 1, true)
+ if x then
+ tab[string.sub(v, 3, x - 1)] = string.sub(v, x + 1)
+ else
+ tab[string.sub(v, 3)] = true
end
- elseif string.sub( v, 1, 1 ) == "-" then
+ elseif string.sub(v, 1, 1) == "-" then
local y = 2
local l = string.len(v)
local jopt
- while ( y <= l ) do
- jopt = string.sub( v, y, y )
- if string.find( options, jopt, 1, true ) then
+ while (y <= l) do
+ jopt = string.sub(v, y, y)
+ if string.find(options, jopt, 1, true) then
if y < l then
- tab[ jopt ] = string.sub( v, y+1 )
+ tab[jopt] = string.sub(v, y + 1)
y = l
else
- tab[ jopt ] = arg[ k + 1 ]
+ tab[jopt] = arg[k + 1]
end
else
- tab[ jopt ] = true
+ tab[jopt] = true
end
y = y + 1
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-context.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-context.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-context.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -10,7 +10,7 @@
local LocalizedQuotes
local util
-local using_luatex, kpse = pcall(require, "kpse")
+local using_luatex, _ = pcall(require, "kpse")
if using_luatex then
unicode = require("citeproc-unicode")
LocalizedQuotes = require("citeproc-output").LocalizedQuotes
@@ -64,7 +64,7 @@
function Context:new()
local o = {
lang = "en-US",
- in_bibliography = false
+ in_bibliography = false,
}
setmetatable(o, self)
self.__index = self
@@ -75,8 +75,8 @@
local variable_type = util.variable_types[name]
if variable_type == "number" then
return self:get_number(name)
- -- elseif variable_type == "date" then
- -- return self:get_date(name)
+ -- elseif variable_type == "date" then
+ -- return self:get_date(name)
elseif variable_type == "name" then
return self:get_name(name)
else
@@ -260,9 +260,9 @@
end
break
end
- -- name_ParsedDroppingParticleWithApostrophe.txt
- -- given: "François Hédelin d'" =>
- -- given: "François Hédelin", dropping-particle: "d'"
+ -- name_ParsedDroppingParticleWithApostrophe.txt
+ -- given: "François Hédelin d'" =>
+ -- given: "François Hédelin", dropping-particle: "d'"
if string.match(part, "^%l+'?$") or string.match(part, "^%l+’$") then
table.insert(dp_parts, 1, part)
end
@@ -291,7 +291,6 @@
-- name["non-dropping-particle"] = last_word
-- name.given = table.concat(util.slice(words, 1, -2), " ")
-- end
--- util.debug(name)
-- end
function Context:get_localized_date(form)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-element.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-element.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-element.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -82,7 +82,7 @@
function Element:set_attribute(node, attribute)
local value = node:get_attribute(attribute)
if value then
- local key = string.gsub(attribute, "%-" , "_")
+ local key = string.gsub(attribute, "%-", "_")
self[key] = value
end
end
@@ -90,10 +90,10 @@
function Element:set_bool_attribute(node, attribute)
local value = node:get_attribute(attribute)
if value == "true" then
- local key = string.gsub(attribute, "%-" , "_")
+ local key = string.gsub(attribute, "%-", "_")
self[key] = true
elseif value == "false" then
- local key = string.gsub(attribute, "%-" , "_")
+ local key = string.gsub(attribute, "%-", "_")
self[key] = false
end
end
@@ -101,7 +101,7 @@
function Element:set_number_attribute(node, attribute)
local value = node:get_attribute(attribute)
if value then
- local key = string.gsub(attribute, "%-" , "_")
+ local key = string.gsub(attribute, "%-", "_")
self[key] = tonumber(value)
end
end
@@ -193,10 +193,7 @@
local group_var = GroupVar.UnresolvedPlain
for _, child_element in ipairs(self.children) do
- -- util.debug(child_element.element_name)
local child_ir = child_element:build_ir(engine, state, context)
- -- util.debug(child_ir)
- -- util.debug(child_ir.group_var)
if child_ir then
-- cs:group and its child elements are suppressed if
@@ -241,8 +238,6 @@
ir.sort_key = ir_sort_key
ir.group_var = group_var
- -- util.debug(ir)
-
return ir
end
@@ -409,7 +404,6 @@
-- {"1", "", " & "}
-- {"5", "8", ", "}
-- }
- -- util.debug(number_part_list)
for _, number_parts in ipairs(number_part_list) do
if form == "roman" then
@@ -457,18 +451,18 @@
and_text = context.locale:get_simple_term("and") or "and"
and_symbol = context.locale:get_simple_term("and", "symbol") or "&"
end
- -- util.debug(and_symbol)
+ --- at diagnostic disable codestyle-check
local space = l.S(" \t\r\n")
local delimiter_patt = space^0 * l.P(",") * space^0 * l.P(and_text) * space^1
- + space^0 * l.P(",") * space^0 * l.P(and_symbol) * space^0
- + space^0 * l.P(",") * space^0 * l.P("&") * space^0
- + space^1 * l.P(and_text) * space^1
- + space^0 * l.P(and_symbol) * space^0
- + space^0 * l.P("&") * space^0
- + space^0 * l.P(",") * space^0
- + space^0 * l.P("-") * space^0
- + space^0 * l.P(util.unicode["en dash"]) * space^0
+ + space^0 * l.P(",") * space^0 * l.P(and_symbol) * space^0
+ + space^0 * l.P(",") * space^0 * l.P("&") * space^0
+ + space^1 * l.P(and_text) * space^1
+ + space^0 * l.P(and_symbol) * space^0
+ + space^0 * l.P("&") * space^0
+ + space^0 * l.P(",") * space^0
+ + space^0 * l.P("-") * space^0
+ + space^0 * l.P(util.unicode["en dash"]) * space^0
local delimiter = l.C(delimiter_patt^1) / function (delimiter)
return {
type = "delimiter",
@@ -482,8 +476,8 @@
}
end
local grammer = l.Ct((token_patt * (delimiter * token_patt)^0)^-1)
+ --- at diagnostic enable codestyle-check
local tokens = grammer:match(number)
- -- util.debug(tokens)
if not tokens then
return {}
@@ -509,7 +503,7 @@
token.type = "number"
else
stop_index = i
- if i > 1 and tokens[i-1].type == "delimiter" then
+ if i > 1 and tokens[i - 1].type == "delimiter" then
stop_index = i - 1
end
break
@@ -519,7 +513,7 @@
if string.match(token.value, "^%s*-%s*$")
or string.match(token.value, "^%s*–%s*$") then
token.delimiter_type = "range"
- if i > 2 and tokens[i-2].delimiter_type == "range" then
+ if i > 2 and tokens[i - 2].delimiter_type == "range" then
stop_index = i
break
end
@@ -551,7 +545,7 @@
local number_parts = {}
for i, token in ipairs(tokens) do
if token.type == "number" then
- if i == 1 or tokens[i-1].delimiter_type == "and" then
+ if i == 1 or tokens[i - 1].delimiter_type == "and" then
table.insert(number_parts, {token.value, "", ""})
else
number_parts[#number_parts][2] = token.value
@@ -568,7 +562,6 @@
end
end
end
- -- util.debug(number_parts)
return number_parts
end
@@ -605,9 +598,9 @@
end
-- if string.match(start, "^%a*%d+%a*$") and string.match(stop, "^%a*%d+%a*$") then
-- if s
- table.insert(number_part_list, {start, stop, delim})
+ table.insert(number_part_list, {start, stop, delim})
-- else
- -- table.insert(number_part_list, {start .. "-" .. stop, "", delim})
+ -- table.insert(number_part_list, {start .. "-" .. stop, "", delim})
-- end
else
table.insert(number_part_list, {start, stop, delim})
@@ -664,7 +657,7 @@
return stop
end
- local start_prefix, start_num = string.match(start, "^(.-)(%d+)$")
+ local start_prefix, start_num = string.match(start, "^(.-)(%d+)$")
local stop_prefix, stop_num = string.match(stop, "^(.-)(%d+)$")
if start_prefix ~= stop_prefix then
-- Not valid range: "n11564-1568" -> "n11564-1568"
@@ -692,7 +685,6 @@
number_parts[2] = stop
end
----comment
--- at param start string
--- at param stop string
--- at return string
@@ -736,15 +728,11 @@
return string.sub(start, 1, #start - #stop) .. stop
end
----comment
--- at param start string
--- at param stop string
--- at param threshold integer? Number of minimal digits
--- at return string
function Element:_format_range_minimal(start, stop, threshold)
- -- util.debug(start)
- -- util.debug(stop)
- -- util.debug(threshold)
threshold = threshold or 1
if #start < #stop then
return stop
@@ -757,7 +745,6 @@
end
end
local res = string.sub(stop, -threshold)
- -- util.debug(res)
return res
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -15,7 +15,7 @@
local output
local util
-local using_luatex, kpse = pcall(require, "kpse")
+local using_luatex, _ = pcall(require, "kpse")
if using_luatex then
dom = require("luaxml-domobject")
context = require("citeproc-context")
@@ -41,8 +41,6 @@
local Locale = node_locale.Locale
local Context = context.Context
local IrState = context.IrState
-local InlineElement = output.InlineElement
--- local OutputFormat = output.OutputFormat
local LatexWriter = output.LatexWriter
local HtmlWriter = output.HtmlWriter
local SortStringFormat = output.SortStringFormat
@@ -78,6 +76,7 @@
--- at field mode string?
--- at field prefix string?
--- at field suffix string?
+--- at field unsorted boolean?
--- at class NameVariable
@@ -138,7 +137,6 @@
--- at field retrieveLocale fun(LanguageCode): string?
--- at field retrieveItem fun(ItemId): ItemData?
----comment
--- at param sys table
--- at param style string
--- at param lang string?
@@ -208,7 +206,7 @@
locale_tags_info_dict = {},
}
- setmetatable(o, { __index = CiteProc })
+ setmetatable(o, {__index = CiteProc})
return o
end
@@ -224,7 +222,6 @@
--- at param ids CiteId[]
function CiteProc:updateItems(ids)
- -- util.debug(string.format('updateItems(%s)', table.concat(ids, ", ")))
self.registry.reflist = {}
self.registry.registry = {}
self.person_names = {}
@@ -316,7 +313,6 @@
--- at param citations_post PostCitation[]
--- at 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)
self:_check_input(citation, citations_pre, citations_post)
@@ -323,7 +319,7 @@
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
+ if #citation.sorted_items > 1 and self.style.citation.sort and not citation.properties.unsorted then
citation.sorted_items = self.style.citation:sorted_citation_items(citation.citationItems, self)
end
@@ -347,7 +343,6 @@
--- at param citation CitationData
--- at 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)
@@ -359,10 +354,10 @@
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
+ for _, 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
+ if #citation.sorted_items > 1 and self.style.citation.sort and not citation.properties.unsorted then
citation.sorted_items = self.style.citation:sorted_citation_items(citation.citationItems, self)
end
@@ -435,6 +430,9 @@
citation_element = self.style.intext
end
+ if #items > 1 and self.style.citation.sort then
+ items = self.style.citation:sorted_citation_items(items, self)
+ end
local res = citation_element:build_cluster(items, self)
-- local context = {
@@ -448,7 +446,7 @@
citationItems = items,
properties = {
noteIndex = 0,
- }
+ },
}
return res
end
@@ -507,7 +505,7 @@
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.')
+ util.error("No <citation> in style.")
end
end
end
@@ -594,11 +592,13 @@
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"})
+ 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 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
@@ -763,7 +763,8 @@
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)
+ 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
@@ -820,7 +821,8 @@
return tainted_citation_ids
end
-function CiteProc:_set_cite_item_position(cite_item, note_index, previous_cite, previous_citation, citation, first_ref, last_ref, num_citations_in_note)
+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" or citation.properties.mode == "full-cite" then
@@ -838,7 +840,8 @@
cite_item.position_level = Position.First
end
- local preceding_cite_item = self:_find_preceding_ibid_item(cite_item, previous_cite, previous_citation, note_index, num_citations_in_note)
+ 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
cite_item.position_level = self:_get_ibid_position(cite_item, preceding_cite_item)
@@ -854,7 +857,8 @@
end
-- Find the preceding cite referencing the same item
-function CiteProc:_find_preceding_ibid_item(cite_item, previous_cite, previous_citation, note_index, num_citations_in_note)
+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
@@ -968,10 +972,6 @@
function CiteProc:match_bibsection_object(item, bibsection_object)
local field = bibsection_object.field
local value = bibsection_object.value
- -- util.debug(item.id)
- -- util.debug(field)
- -- util.debug(value)
- -- util.debug(item[field])
local match = false
if value == "" then
if not item[field] or item[field] == "" then
@@ -993,7 +993,6 @@
if bibsection_object.negative then
match = not match
end
- -- util.debug(match)
return match
end
@@ -1111,7 +1110,7 @@
el = element_class:from_node(node)
end
if el then
- for i, child in ipairs(node:get_children()) do
+ for _, child in ipairs(node:get_children()) do
if child:is_element() then
local child_element = CiteProc.create_element_tree(child)
if child_element then
@@ -1180,7 +1179,6 @@
local note_fields = {}
local note_lines = {}
for _, line in ipairs(util.split(item.note, "%s*\r?\n%s*")) do
- -- util.debug(line)
local field, value = string.match(line, "^([%w-_ ]+):%s*(.*)$")
if field then
local variable_type = util.variable_types[field]
@@ -1205,7 +1203,7 @@
for field, value in pairs(note_fields) do
item[field] = value
end
- item.note = table.concat(note_lines, '\n')
+ item.note = table.concat(note_lines, "\n")
end
return item
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-ir-node.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-ir-node.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-ir-node.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -107,6 +107,15 @@
level = level or 0
local ir_info_str = ""
local ir_info = {}
+ if self.group_var == GroupVar.Plain then
+ table.insert(ir_info, "[Plain]")
+ elseif self.group_var == GroupVar.Important then
+ table.insert(ir_info, "[Important]")
+ elseif self.group_var == GroupVar.Missing then
+ table.insert(ir_info, "[Missing]")
+ elseif self.group_var == GroupVar.UnresolvedPlain then
+ table.insert(ir_info, "[UnresolvedPlain]")
+ end
if self.delimiter then
table.insert(ir_info, string.format('delimiter: "%s"', self.delimiter))
end
@@ -117,7 +126,7 @@
table.insert(ir_info, "person_name_irs: " .. tostring(#self.person_name_irs))
end
if #ir_info > 0 then
- ir_info_str = string.format("{%s}", table.concat(ir_info, ' '))
+ ir_info_str = string.format("{%s}", table.concat(ir_info, " "))
end
local element_info = self._element.element_name
for _, attr in ipairs({"name", "variable"}) do
@@ -125,7 +134,8 @@
element_info = element_info .. string.format(' %s="%s"', attr, self._element[attr])
end
end
- local text = string.format("\n%s [%s] %s <%s> %s", string.rep(" ", level), self.group_var, self._type, element_info, ir_info_str)
+ local text = string.format("\n%s [%s] %s <%s> %s", string.rep(" ", level), self.group_var, self._type,
+ element_info, ir_info_str)
if self.children and #self.children > 0 then
for _, child_ir in ipairs(self.children) do
text = text .. child_ir:_debug(level + 1)
@@ -144,7 +154,6 @@
end
function IrNode:capitalize_first_term()
- -- util.debug(self)
if self._type == "Rendered" and self._element then
local element = self._element
--- at cast element Text
@@ -264,7 +273,6 @@
-- end
-
irnode.IrNode = IrNode
irnode.Rendered = Rendered
irnode.YearSuffix = YearSuffix
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-journal-data.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-journal-data.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-journal-data.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -5410,6 +5410,7 @@
["archives médicales de l'ouest: angers/nantes/rennes"] = "Arch Med Ouest",
["archives méditerranéennes de médecine"] = "Arch Mediterr Med",
["archives neerlandaises des sciences exactes et naturelles"] = "Arch. Neerl. Sci. Exactes Nat.",
+ ["archives neerlandaises des sciences exactes et naturelles. serie ii"] = "Arch. Neerl. Sci. Exactes Nat. Ser. II",
["archives neerlandaises sci exactes et naturelles"] = "Arch. Neerl. Sci. Exactes Nat.",
["archives néerlandaises de physiologie de l'homme et des animaux"] = "Arch Neerl Physiol Homme Anim",
["archives of academic emergency medicine"] = "Arch Acad Emerg Med",
@@ -14128,6 +14129,7 @@
["crystallography reviews"] = "Crystallogr. Rev.",
["csa journal (denver, colo.)"] = "CSA J (Denver)",
["cscw : proceedings of the conference on computer-supported cooperative work. conference on computer-supported cooperative work"] = "CSCW Conf Comput Support Coop Work",
+ ["csd communications"] = "CSDS Commun.",
["csee journal of power and energy systems"] = "CSEE J. Power Energy Syst",
["csh protocols"] = "CSH Protoc",
["csiam transactions on applied mathematics"] = "CSIAM Trans. Appl. Math.",
@@ -19592,6 +19594,7 @@
["frontiers in systems neuroscience"] = "Front Syst Neurosci",
["frontiers in the history of science"] = "Front. Hist. Sci.",
["frontiers in the internet of things"] = "Front. Internet Things",
+ ["frontiers in theoretical physics"] = "Front. Theor. Phys.",
["frontiers in thermal engineering"] = "Front. Therm. Eng.",
["frontiers in toxicology"] = "Front. Toxicol.",
["frontiers in transplantation"] = "Front. Transplant.",
@@ -25139,6 +25142,7 @@
["international journal of modern physics"] = "Int. J. Modern Phys. D",
["international journal of modern physics a"] = "Int. J. Mod. Phys. A",
["international journal of modern physics a. particles and fields. gravitation. cosmology"] = "Internat. J. Modern Phys. A",
+ ["international journal of modern physics a. particles and fields. gravitation. cosmology. astrophysics. accelerator physics"] = "Internat. J. Modern Phys. A",
["international journal of modern physics a: particles and fields; gravitation; cosmology; nuclear physics"] = "Int. J. Mod. Phys. A",
["international journal of modern physics b"] = "Int. J. Mod. Phys. B",
["international journal of modern physics b: condensed matter physics, statistical physics, applied physics"] = "Int. J. Mod. Phys. B",
@@ -25703,6 +25707,7 @@
["international journal of travel medicine and global health"] = "Int J Travel Med Glob Health",
["international journal of trichology"] = "Int J Trichology",
["international journal of tropical agriculture = antarrāshtriya ūshnakatibandhīya kr̥shi-śodha patrikā"] = "Int J Trop Agric",
+ ["international journal of tropical and subtropical horticulture"] = "Int. J. Trop. Subtrop. Hortic.",
["international journal of tropical disease & health"] = "Int J Trop Dis Health",
["international journal of tropical insect science"] = "Int. J. Trop. Insect Sci.",
["international journal of tryptophan research"] = "Int. J. Tryptophan Res.",
@@ -41328,6 +41333,7 @@
["orbis economicus"] = "Orbis Econ.",
["orbis terrarum. internationale zeitschrift für historische geographie der alten welt"] = "OrbTerr",
["orbit (amsterdam, netherlands)"] = "Orbit",
+ ["orbita mathematicae"] = "Orbita Math.",
["orchids (west palm beach, fla.)"] = "Orchids",
["order (dordrecht, netherlands)"] = "Order (Dordr)",
["order. a journal on the theory of ordered sets and its applications"] = "Order",
@@ -51776,6 +51782,7 @@
["summer computer simulation conference : (scsc 2014) : 2014 summer simulation multi-conference : monterey, california, usa, 6-10 july 2014. summer computer simulation conference (2014 : monterey, calif.)"] = "Summer Comput Simul Conf (2014)",
["summer computer simulation conference : (scsc 2015) : 2015 summer simulation multi-conference (summersim'15) : chicago, illinois, usa, 26-29 july 2015. summer computer simulation conference (2015 : chicago, illinois)"] = "Summer Comput Simul Conf (2015)",
["summit on translational bioinformatics"] = "Summit Transl Bioinform",
+ ["sums readings"] = "SUMS Read.",
["sun (baltimore, md. : 1837)"] = "Sun",
["sunday times (london, england : 1931)"] = "Sunday Times",
["suny series in ancient greek philosophy"] = "SUNY Ser. Anc. Greek Philos.",
@@ -52213,6 +52220,7 @@
["targeted oncology"] = "Target Oncol",
["tartu ülikooli toimetised"] = "Tartu Ül. Toimetised",
["tata institute of fundamental research lectures on mathematics and physics"] = "Tata Inst. Fund. Res. Lectures on Math. and Phys.",
+ ["tata institute of fundamental research studies in mathematics"] = "Tata Inst. Fundam. Res. Stud. Math.",
["tatra mountains mathematical publications"] = "Tatra Mt. Math. Publ.",
["tập chí khoa học kỹ thuật nông lâm nghiệp"] = "Tap Chi Khoa Hoc Ky Thuat Nong Lam Nghiep",
["tāksūnūmī va bīyūsīstimātīk"] = "Taksunumi Biyusistimatik",
@@ -53294,6 +53302,7 @@
["the european journal of surgery = acta chirurgica"] = "Eur J Surg",
["the european journal of surgery. supplement. : = acta chirurgica. supplement"] = "Eur J Surg Suppl",
["the european journal of the history of economic thought"] = "Eur J Hist Econ Thought",
+ ["the european journal on artificial intelligence"] = "Eur. J. Artif. Intell.",
["the european legacy, toward new paradigms : journal of the international society for the study of european ideas"] = "Eur Leg Towar New Paradig",
["the european physical journal"] = "Eur. Phys. J. D",
["the european physical journal a"] = "Eur. Phys. J. A",
@@ -64364,6 +64373,7 @@
["arch natschutz landschforsch"] = "Archiv für Naturschutz und Landschaftsforschung",
["arch neerl physiol homme anim"] = "Archives néerlandaises de physiologie de l'homme et des animaux",
["arch neerl sci exactes nat"] = "Archives Neerlandaises des Sciences Exactes et Naturelles",
+ ["arch neerl sci exactes nat ser ii"] = "Archives Neerlandaises des Sciences Exactes et Naturelles. Serie II",
["arch neurobiol (madr)"] = "Archivos de neurobiologiá",
["arch neurocir"] = "Archivos de neurocirugía",
["arch neurol"] = "Archives of Neurology",
@@ -71718,6 +71728,7 @@
["crystals (basel)"] = "Crystals",
["csa j (denver)"] = "CSA journal (Denver, Colo.)",
["cscw conf comput support coop work"] = "CSCW : proceedings of the Conference on Computer-Supported Cooperative Work. Conference on Computer-Supported Cooperative Work",
+ ["csds commun"] = "CSD Communications",
["csee j power energy syst"] = "CSEE Journal of Power and Energy Systems",
["csh protoc"] = "CSH protocols",
["csiam trans appl math"] = "CSIAM Transactions on Applied Mathematics",
@@ -74830,6 +74841,7 @@
["eur j appl physiol occup physiol"] = "European journal of applied physiology and occupational physiology",
["eur j archaeol"] = "European journal of archaeology",
["eur j arrhythm electrophysiol"] = "European journal of arrhythmia & electrophysiology",
+ ["eur j artif intell"] = "The European Journal on Artificial Intelligence",
["eur j basic appl histochem"] = "European journal of basic and applied histochemistry",
["eur j behav anal"] = "European journal of behavior analysis",
["eur j biochem"] = "European Journal of Biochemistry",
@@ -76602,6 +76614,7 @@
["front synaptic neurosci"] = "Frontiers in synaptic neuroscience",
["front syst biol"] = "Frontiers in Systems Biology",
["front syst neurosci"] = "Frontiers in systems neuroscience",
+ ["front theor phys"] = "Frontiers in Theoretical Physics",
["front therm eng"] = "Frontiers in Thermal Engineering",
["front toxicol"] = "Frontiers in Toxicology",
["front transplant"] = "Frontiers in Transplantation",
@@ -82251,6 +82264,7 @@
["int j trop agric"] = "International journal of tropical agriculture = Antarrāshtriya ūshnakatibandhīya kr̥shi-śodha patrikā",
["int j trop dis health"] = "International journal of tropical disease & health",
["int j trop insect sci"] = "International Journal of Tropical Insect Science",
+ ["int j trop subtrop hortic"] = "International Journal of Tropical and Subtropical Horticulture",
["int j tryptophan res"] = "International journal of tryptophan research : IJTR",
["int j tuberc lung dis"] = "The international journal of tuberculosis and lung disease : the official journal of the International Union against Tuberculosis and Lung Disease",
["int j turbo jet engines"] = "International Journal Of Turbo And Jet Engines",
@@ -96740,6 +96754,7 @@
["orale implantol"] = "Orale Implantologie",
["orange cty dent soc bull"] = "Orange County Dental Society Bulletin",
["orbis econ"] = "Orbis Economicus",
+ ["orbita math"] = "Orbita Mathematicae",
["order (dordr)"] = "Order (Dordrecht, Netherlands)",
["ordre natl chir dent cons natl bull off"] = "Bulletin officiel du Conseil national de l'Ordre",
["ore energy resour geol"] = "Ore and Energy Resource Geology",
@@ -105632,6 +105647,7 @@
["summer comput simul conf (2014)"] = "Summer Computer Simulation Conference : (SCSC 2014) : 2014 Summer Simulation Multi-Conference : Monterey, California, USA, 6-10 July 2014. Summer Computer Simulation Conference (2014 : Monterey, Calif.)",
["summer comput simul conf (2015)"] = "Summer Computer Simulation Conference : (SCSC 2015) : 2015 Summer Simulation Multi-Conference (SummerSim'15) : Chicago, Illinois, USA, 26-29 July 2015. Summer Computer Simulation Conference (2015 : Chicago, Illinois)",
["summit transl bioinform"] = "Summit on translational bioinformatics",
+ ["sums read"] = "SUMS Readings",
["sunday times"] = "Sunday times (London, England : 1931)",
["sunday times magazine"] = "The Sunday times magazine",
["suny ser anc greek philos"] = "SUNY Series in Ancient Greek Philosophy",
@@ -106038,6 +106054,7 @@
["targeted oncol"] = "Targeted Oncology",
["tartu ül toimetised"] = "Tartu Ülikooli Toimetised",
["tata inst fund res lectures on math and phys"] = "Tata Institute of Fundamental Research Lectures on Mathematics and Physics",
+ ["tata inst fundam res stud math"] = "Tata Institute of Fundamental Research Studies in Mathematics",
["tatra mt math publ"] = "Tatra Mountains Mathematical Publications",
["taylor & francis syst control book ser"] = "The Taylor & Francis Systems and Control Book Series",
["tạp chi y te cong cong"] = "Tạp chí y tế công cộng",
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -6,7 +6,6 @@
local latex_parser = {}
-local bibtex_parser
local latex_data
local markup
local util
@@ -27,9 +26,7 @@
-- Convert LaTeX string to Unicode string
function latex_parser.latex_to_unicode(str)
local ast = latex_parser.latex_grammar:match(str)
- -- util.debug(ast)
latex_parser.convert_ast_to_unicode(ast)
- -- util.debug(ast)
local res = latex_parser.to_string(ast)
return res
end
@@ -47,10 +44,8 @@
-- Convert LaTeX string to string with HTML-like tags
function latex_parser.latex_to_pseudo_html(str, strict, case_protection)
local ast = latex_parser.latex_grammar:match(str)
- -- util.debug(ast)
latex_parser.convert_ast_to_unicode(ast)
local inlines = latex_parser.convert_tokens_to_inlines(ast, strict, case_protection)
- -- util.debug(inlines)
local pseudo_html_format = markup.PseudoHtml:new()
local res = pseudo_html_format:write_inlines(inlines, {})
return res
@@ -61,19 +56,18 @@
-- case_protection: BibTEX case protection with curly braces
----comment
--- at param str string
--- at param keep_unknown_commands boolean?
--- at param case_protection boolean?
--- at param check_sentence_case boolean?
--- at return string
-function latex_parser.latex_to_sentence_case_pseudo_html(str, keep_unknown_commands, case_protection, check_sentence_case)
+function latex_parser.latex_to_sentence_case_pseudo_html(str, keep_unknown_commands, case_protection,
+ check_sentence_case)
local ast = latex_parser.latex_grammar:match(str)
latex_parser.convert_ast_to_unicode(ast)
local inlines = latex_parser.convert_tokens_to_inlines(ast, keep_unknown_commands, case_protection)
local pseudo_html_format = markup.PseudoHtml:new()
pseudo_html_format:convert_sentence_case(inlines, check_sentence_case)
- -- util.debug(inlines)
local res = pseudo_html_format:write_inlines(inlines, {})
return res
end
@@ -93,14 +87,10 @@
local R = lpeg.R
local S = lpeg.S
local C = lpeg.C
- local Cc = lpeg.Cc
- local Cf = lpeg.Cf
- local Cg = lpeg.Cg
- local Cmt = lpeg.Cmt
- local Cp = lpeg.Cp
local Ct = lpeg.Ct
local V = lpeg.V
+ --- at diagnostic disable: codestyle-check
local space = S(" \t\r\n")^0
local specials = P"~" / util.unicode["no-break space"]
-- + P"\\$" / "$"
@@ -142,6 +132,7 @@
}
end,
}
+ --- at diagnostic enable: codestyle-check
return latex_grammar
end
@@ -157,7 +148,7 @@
["\\enquote"] = "quote",
["\\textsc"] = "sc",
["\\sout"] = "strike", -- from ulem package
- ["\\st"] = "strike", -- from soul package
+ ["\\st"] = "strike", -- from soul package
["\\textsuperscript"] = "sup",
["\\textsubscript"] = "sub",
}
@@ -175,10 +166,9 @@
}
-
function latex_parser.to_string(ast)
local res = ""
- for i, token in ipairs(ast) do
+ for _, token in ipairs(ast) do
if type(token) == "string" then
res = res .. token
elseif type(token) == "table" then
@@ -210,7 +200,6 @@
end
end
----comment
--- at param tokens any
--- at param i any
--- at param command_info string | table
@@ -304,7 +293,7 @@
if inline_type then
local arg_inlines
if command_info.num_args == 1 then
- local next_token = tokens[i+1]
+ local next_token = tokens[i + 1]
if type(next_token) == "table" and next_token.type == "group" then
arg_inlines = latex_parser.convert_tokens_to_inlines(next_token.contents, strict, false)
if case_protection then
@@ -316,7 +305,7 @@
i = i + 1
else -- command_info.num_args == 0
if command_info.inline_type then
- local arg_tokens = util.slice(tokens, i+1, #tokens)
+ local arg_tokens = util.slice(tokens, i + 1, #tokens)
i = #tokens
arg_inlines = latex_parser.convert_tokens_to_inlines(arg_tokens, strict, case_protection)
end
@@ -484,7 +473,7 @@
for i = #inlines, 1, -1 do
if i > 1 then
local inline = inlines[i]
- local prev = inlines[i-1]
+ local prev = inlines[i - 1]
if type(inline) == "table" and inline._type == "Code" and
type(prev) == "table" and prev._type == "Code" then
prev.value = prev.value .. inline.value
@@ -497,7 +486,6 @@
end
-
function latex_parser.convert_ast_to_rich_text(tokens)
local res = {}
@@ -600,20 +588,16 @@
function latex_parser.parse_seq(str)
local P = lpeg.P
- local R = lpeg.R
local S = lpeg.S
local C = lpeg.C
- local Cc = lpeg.Cc
- local Cf = lpeg.Cf
- local Cg = lpeg.Cg
- local Cmt = lpeg.Cmt
- local Cp = lpeg.Cp
local Ct = lpeg.Ct
local V = lpeg.V
+ --- at diagnostic disable: codestyle-check
local balanced = P{"{" * V(1) ^ 0 * "}" + (P"\\{" + P"\\}" + 1 - S"{}")}
local item = P"{" * C(balanced^0) * P"}" + C((balanced - P",")^1)
local seq = Ct((item * P(",")^-1)^0)
+ --- at diagnostic enable: codestyle-check
return seq:match(str)
end
@@ -628,6 +612,7 @@
local Ct = lpeg.Ct
local V = lpeg.V
+ --- at diagnostic disable: codestyle-check
local balanced = P{"{" * V(1)^0 * "}" + (P"\\{" + P"\\}" + 1 - S"{}")}
local key = (R"09" + R"AZ" + R"az" + S"-_./")^1
local value = (P"{" * C(balanced^0) * P"}" + C((balanced - S",=")^0)) / function (s)
@@ -642,6 +627,7 @@
local space = S(" \t\r\n")^0
local pair = C(key) * space * P"=" * space * value * (P(",") * space)^-1
local prop = Cf(Ct"" * space * Cg(pair)^0, rawset)
+ --- at diagnostic enable: codestyle-check
-- if not str then
-- print(debug.traceback())
Added: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-lua-uni-words.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-lua-uni-words.lua (rev 0)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-lua-uni-words.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -0,0 +1,316 @@
+--- at diagnostic disable
+-- lua-uni-words.lua
+-- Copyright 2020--2023 Marcel Krüger
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- This work has the LPPL maintenance status `maintained'.
+--
+-- The Current Maintainer of this work is Marcel Krüger
+
+local extended_pictographic, property do
+ local p = require'lua-uni-parse'
+ local l = lpeg or require'lpeg'
+
+ extended_pictographic = p.parse_file('emoji-data',
+ l.Cg(p.fields(p.codepoint_range, 'Extended_Pictographic' * l.Cc(true))) + p.ignore_line,
+ p.multiset)
+ if not extended_pictographic then
+ error[[Break Property matching failed]]
+ end
+
+ property = p.parse_file('WordBreakProperty',
+ l.Cg(p.fields(p.codepoint_range, l.C(l.R('az', 'AZ', '__')^1))) + p.ignore_line,
+ p.multiset)
+ if not property then
+ error[[Break Property matching failed]]
+ end
+end
+
+local ignorable = { Extend = true, Format = true, ZWJ = true, }
+local controls = { CR = true, LF = true, Newline = true, }
+
+local function context_AHLetter_Mid(cp)
+ local prop = property[cp]
+ if ignorable[prop] then
+ return nil, context_AHLetter_Mid
+ end
+ if prop == 'ALetter' then
+ return false, 'ASTARTED'
+ end
+ if prop == 'Hebrew_Letter' then
+ return false, 'HSTARTED'
+ end
+ return true, 'PRE'
+end
+
+local function context_HLetter_Double(cp)
+ local prop = property[cp]
+ if ignorable[prop] then
+ return nil, context_HLetter_Double
+ end
+ if prop == 'Hebrew_Letter' then
+ return false, 'HSTARTED'
+ end
+ return true, 'PRE'
+end
+
+local function context_Numeric_Mid(cp)
+ local prop = property[cp]
+ if ignorable[prop] then
+ return nil, context_Numeric_Mid
+ end
+ if prop == 'Numeric' then
+ return false, 'NSTARTED'
+ end
+ return true, 'PRE'
+end
+
+local state_map state_map = {
+ START = function(prop)
+ if prop == 'CR' then
+ return 'CR', true
+ end
+ if prop == 'LF' or prop == 'Newline' then
+ return 'START', true
+ end
+ return state_map.PRE(prop), true
+ end,
+ PRE = function(prop)
+ if controls[prop] then
+ return state_map.START(prop)
+ end
+ if ignorable[prop] then
+ return 'PRE', false
+ end
+ if prop == 'WSegSpace' then
+ return 'WHITE', true
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', true
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', true
+ end
+ if prop == 'Numeric' then
+ return 'NSTARTED', true
+ end
+ if prop == 'Katakana' then
+ return 'KSTARTED', true
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', true
+ end
+ if prop == 'Regional_Indicator' then
+ return 'RI', true
+ end
+ return 'PRE', true
+ end,
+ CR = function(prop)
+ if prop == 'LF' then
+ return 'START', false
+ else
+ return state_map.START(prop)
+ end
+ end,
+ WHITE = function(prop)
+ if prop == 'WSegSpace' then
+ return 'WHITE', false
+ else
+ return state_map.PRE(prop)
+ end
+ end,
+ EXTEND = function(prop)
+ if ignorable[prop] then
+ return 'EXTEND', false
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', false
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', false
+ end
+ if prop == 'Katakana' then
+ return 'KSTARTED', false
+ end
+ if prop == 'Numeric' then
+ return 'NSTARTED', false
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', false
+ end
+ return state_map.PRE(prop)
+ end,
+ KSTARTED = function(prop)
+ if ignorable[prop] then
+ return 'KSTARTED', false
+ end
+ if prop == 'Katakana' then
+ return 'Katakana', false
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', false
+ end
+ return state_map.PRE(prop)
+ end,
+ RI = function(prop)
+ if ignorable[prop] then
+ return 'RI', false
+ end
+ if prop == 'Regional_Indicator' then
+ return 'PRE', false
+ end
+ return state_map.PRE(prop)
+ end,
+ ASTARTED = function(prop)
+ if ignorable[prop] then
+ return 'ASTARTED', false
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', false
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', false
+ end
+ if prop == 'Numeric' then
+ return 'NSTARTED', false
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', false
+ end
+ if prop == 'MidLetter' or prop == 'MidNumLet' or prop == 'Single_Quote' then
+ return context_AHLetter_Mid
+ end
+ return state_map.PRE(prop)
+ end,
+ HSTARTED = function(prop)
+ if ignorable[prop] then
+ return 'HSTARTED', false
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', false
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', false
+ end
+ if prop == 'Numeric' then
+ return 'NSTARTED', false
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', false
+ end
+ if prop == 'Single_Quote' then
+ return 'HSINGLE_QUOTE', false
+ end
+ if prop == 'MidLetter' or prop == 'MidNumLet' then
+ return context_AHLetter_Mid
+ end
+ if prop == 'Double_Quote' then
+ return context_HLetter_Double
+ end
+ return state_map.PRE(prop)
+ end,
+ HSINGLE_QUOTE = function(prop)
+ if ignorable[prop] then
+ return 'HSINGLE_QUOTE', false
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', false
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', false
+ end
+ return state_map.PRE(prop)
+ end,
+ NSTARTED = function(prop)
+ if ignorable[prop] then
+ return 'NSTARTED', false
+ end
+ if prop == 'ALetter' then
+ return 'ASTARTED', false
+ end
+ if prop == 'Hebrew_Letter' then
+ return 'HSTARTED', false
+ end
+ if prop == 'Numeric' then
+ return 'NSTARTED', false
+ end
+ if prop == 'ExtendNumLet' then
+ return 'EXTEND', false
+ end
+ if prop == 'MidNum' or prop == 'MidNumLet' or prop == 'Single_Quote' then
+ return context_Numeric_Mid
+ end
+ return state_map.PRE(prop)
+ end,
+}
+
+local from_ZWJ, to_ZWJ = {}, {}
+for k in next, state_map do
+ local zwj_state = 'ZWJ_' .. k
+ from_ZWJ[zwj_state], to_ZWJ[k] = k, zwj_state
+end
+
+
+-- The value of "state" is considered internal and should not be relied upon.
+-- Just pass it to the function as is or pass nil. `nil` should only be passed when the passed codepoint starts a new cluster
+local function read_codepoint(cp, state)
+ local mapped_state = from_ZWJ[state]
+ local new_word
+ local prop = property[cp]
+ state, new_word = state_map[mapped_state or state or 'START'](prop)
+ if mapped_state and extended_pictographic[cp] then
+ new_word = false
+ end
+ if prop == 'ZWJ' then
+ state = to_ZWJ[state]
+ end
+ return new_word, state
+end
+
+-- A Lua iterator for strings -- Only reporting the beginning of every word segment
+local function word_boundaries_start(str)
+ local nextcode, str, i = utf8.codes(str)
+ local state = "START"
+ local saved_i, saved_code
+ return function()
+ local new_word, code
+ repeat
+ i, code = nextcode(str, i)
+ if saved_i then
+ new_word, state = state(code)
+ if new_word ~= nil then
+ i, code, saved_i, saved_code = saved_i, saved_code, nil, nil
+ end
+ else
+ if not i then return end
+ new_word, state = read_codepoint(code, state)
+ if new_word == nil then
+ saved_i, saved_code = i, code
+ end
+ end
+ until new_word
+ return i, code
+ end
+end
+-- A more useful iterator: returns the byterange of the segment in reverse order followed by a string with the word
+local function word_boundaries(str)
+ local iter = word_boundaries_start(str)
+ return function(_, cur)
+ if cur == #str then return end
+ local new = iter()
+ if not new then return #str, cur + 1, str:sub(cur + 1) end
+ return new - 1, cur + 1, str:sub(cur + 1, new - 1)
+ end, nil, iter() - 1
+end
+return {
+ read_codepoint = read_codepoint,
+ word_boundaries_start = word_bounaries_start,
+ word_boundaries = word_boundaries,
+}
Property changes on: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-lua-uni-words.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -16,7 +16,6 @@
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
@@ -123,7 +122,7 @@
util.warning(string.format("Didn't find a database entry for '%s'", id))
end
return res
- end
+ end,
}
return citeproc_sys
end
@@ -205,7 +204,8 @@
if item_dict[entry.key] then
util.warning(string.format("Duplicate entry key '%s' in '%s'.", entry.key, file))
else
- self.bibtex_entries[entry.key] = entry
+ local normalized_key = bibtex_parser.normalize_key(entry.key)
+ self.bibtex_entries[normalized_key] = entry
if entry.fields.crossref then
table.insert(self.entries_with_crossref, entry)
self.item_index[entry.key] = #items + 1
@@ -393,7 +393,8 @@
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))
+ 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
@@ -596,9 +597,7 @@
return
end
- -- util.debug(citation_info)
local citation = self:_make_citation(citation_info)
- -- util.debug(citation)
table.insert(self.ref_section.citations, citation)
@@ -610,7 +609,6 @@
-- else
citation_str = engine:process_citation(citation)
-- end
- -- util.debug(citation_str)
-- tex.sprint(citation_str)
-- tex.setcatcode(35, 12) -- #
@@ -656,7 +654,6 @@
--- at return CitationData
function CslCitationManager:_make_citation(citation_info)
-- `citation_info`: "citationID={ITEM-1 at 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)
@@ -672,9 +669,7 @@
end
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)
@@ -708,7 +703,6 @@
citation.properties.suffix = latex_parser.latex_to_pseudo_html(citation.properties.suffix, true, false)
end
- -- util.debug(citation)
return citation
end
@@ -766,7 +760,6 @@
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)
@@ -775,7 +768,7 @@
--- at type table<string, any>
local bib_options = {
- index = options.index or "1"
+ index = options.index or "1",
}
local bib_option_map = {
@@ -801,11 +794,13 @@
local bib_lines = {}
if #params.entry_ids > 0 then
- local entry_ids_line = string.format("\\csloptions{%d}{entry-ids = {%s}}", self.ref_section.index, table.concat(params.entry_ids, ", "))
+ local entry_ids_line = string.format("\\csloptions{%d}{entry-ids = {%s}}", self.ref_section.index,
+ table.concat(params.entry_ids, ", "))
table.insert(bib_lines, entry_ids_line)
end
if #params.excluded_ids > 0 then
- local excluded_ids_line = string.format("\\csloptions{%d}{excluded-ids = {%s}}", self.ref_section.index, table.concat(params.excluded_ids, ", "))
+ local excluded_ids_line = string.format("\\csloptions{%d}{excluded-ids = {%s}}", self.ref_section.index,
+ table.concat(params.excluded_ids, ", "))
table.insert(bib_lines, excluded_ids_line)
end
@@ -880,7 +875,7 @@
{"\\@input", 1},
}
-local balanced = lpeg.P{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" }
+local balanced = lpeg.P {"{" * ((1 - lpeg.S "{}") + lpeg.V(1)) ^ 0 * "}"}
--- at param text string
--- at param num_args integer?
@@ -887,7 +882,7 @@
--- at 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 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 {}
@@ -905,7 +900,7 @@
--- at return table
function CslCitationManager:_parser_filter(filter_str)
local conditions = {}
- for i, condition in ipairs(latex_parser.parse_seq(filter_str)) do
+ for _, condition in ipairs(latex_parser.parse_seq(filter_str)) do
local negative
local field, value = string.match(condition, "(%w+)%s*=%s*{([^}]+)}")
if field then
@@ -925,12 +920,10 @@
end
end
end
- -- util.debug(conditions)
return {select = conditions}
end
-
--- at param aux_content string
--- at return string
function CslCitationManager:read_aux_file(aux_content)
@@ -958,8 +951,8 @@
elseif command == "\\csl at aux@cite" then
self:register_citation_info(tostring(ref_section_index), content)
-- TODO: refsection bib resources
- -- elseif command == "\\csl at aux@bibliography" then
- -- -- table.insert(ref_section.bibliography_configs, content)
+ -- elseif command == "\\csl at aux@bibliography" then
+ -- -- table.insert(ref_section.bibliography_configs, content)
end
end
@@ -1010,7 +1003,8 @@
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)
+ 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)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-bibliography.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-bibliography.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-bibliography.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -33,7 +33,6 @@
local Context = context.Context
local IrState = context.IrState
local Element = element.Element
-local IrNode = ir_node.IrNode
local Rendered = ir_node.Rendered
local SeqIr = ir_node.SeqIr
local GroupVar = ir_node.GroupVar
@@ -56,7 +55,7 @@
hanging_indent = false,
line_spacing = 1,
entry_spacing = 1,
- subsequent_author_substitute_rule = "complete-all"
+ subsequent_author_substitute_rule = "complete-all",
})
function Bibliography:from_node(node, style)
@@ -106,47 +105,43 @@
return o
end
----comment
--- at param id string
--- at param engine CiteProc
--- at return string?
function Bibliography:build_bibliography_str(id, engine)
- local output_format = engine.output_format
+ local output_format = engine.output_format
- local state = IrState:new()
- local context = Context:new()
- context.engine = engine
- context.style = engine.style
- context.area = self
- context.in_bibliography = true
- context.name_inheritance = self.name_inheritance
- context.format = output_format
- context.id = id
- context.cite = nil
- context.reference = engine:get_item(id)
+ local state = IrState:new()
+ local context = Context:new()
+ context.engine = engine
+ context.style = engine.style
+ context.area = self
+ context.in_bibliography = true
+ context.name_inheritance = self.name_inheritance
+ context.format = output_format
+ context.id = id
+ context.cite = nil
+ context.reference = engine:get_item(id)
- -- 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)
+ -- 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)
- -- util.debug(ir)
- ir.reference = context.reference
+ local ir = self:build_ir(engine, state, context, active_layout)
+ ir.reference = context.reference
- -- Add year-suffix
- self:add_bibliography_year_suffix(ir, engine)
+ -- Add year-suffix
+ self:add_bibliography_year_suffix(ir, engine)
- -- The layout output may be empty: sort_OmittedBibRefNonNumericStyle.txt
- if not ir then
- return nil
- end
+ -- The layout output may be empty: sort_OmittedBibRefNonNumericStyle.txt
+ if not ir then
+ return nil
+ end
- -- util.debug(ir)
- local flat = ir:flatten(output_format)
- -- util.debug(flat)
- local str = output_format:output_bibliography_entry(flat, context)
- return str
+ local flat = ir:flatten(output_format)
+ local str = output_format:output_bibliography_entry(flat, context)
+ return str
end
function Bibliography:build_ir(engine, state, context, active_layout)
@@ -154,7 +149,6 @@
util.error("Missing bibliography layout.")
end
local ir = active_layout:build_ir(engine, state, context)
- -- util.debug(ir)
if self.second_field_align == "flush" and #ir.children >= 2 then
ir.children[1].display = "left-margin"
local right_inline_ir = SeqIr:new(util.slice(ir.children, 2), self)
@@ -238,7 +232,6 @@
ir.first_name_ir.group_var = GroupVar.Missing
else
-- the output of label is not substituted
- -- util.debug(ir.first_name_ir)
ir.first_name_ir.children = {Rendered:new({PlainText:new(text)}, self)}
end
end
@@ -333,13 +326,10 @@
return
end
- local year_suffix_number = ir.reference.year_suffix_number
-
if not ir.year_suffix_irs then
ir.year_suffix_irs = ir:collect_year_suffix_irs()
if #ir.year_suffix_irs == 0 then
local year_ir = ir:find_first_year_ir()
- -- util.debug(year_ir)
if year_ir then
local year_suffix_ir = YearSuffix:new({}, engine.style.citation)
table.insert(year_ir.children, year_suffix_ir)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-choose.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-choose.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-choose.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -50,7 +50,7 @@
local ir = SeqIr:new({}, self)
--- at case ir SeqIr
ir.should_inherit_delim = true
- ir.group_var = GroupVar.UnresolvedPlain
+ ir.group_var = GroupVar.Missing
for _, child in ipairs(self.children) do
if child:evaluate_conditions(engine, state, context) then
@@ -70,8 +70,6 @@
end
end
- -- util.debug(ir)
-
if not context.disambiguate then
context.disambiguate = true
@@ -104,7 +102,7 @@
local o = {
condition = condition,
value = value,
- match_type = match_type or "all"
+ match_type = match_type or "all",
}
setmetatable(o, self)
self.__index = self
@@ -117,9 +115,10 @@
--- at field conditions Condition[]
local If = Element:derive("if", {
conditions = nil,
- match = "all"
+ match = "all",
})
+--- at return If
function If:new()
local o = Element.new(self)
o.conditions = {}
@@ -147,14 +146,25 @@
return o
end
+--- at param node Node
+--- at param attribute string
function If:add_conditions(node, attribute)
local values = node:get_attribute(attribute)
if not values then
return
end
- for _, value in ipairs(util.split(values)) do
- local condition = Condition:new(attribute, value, self.match)
+ if attribute == "type" then
+ local type_dict = {}
+ for _, value in ipairs(util.split(values)) do
+ type_dict[value] = true
+ end
+ local condition = Condition:new(attribute, type_dict, self.match)
table.insert(self.conditions, condition)
+ else
+ for _, value in ipairs(util.split(values)) do
+ local condition = Condition:new(attribute, value, self.match)
+ table.insert(self.conditions, condition)
+ end
end
end
@@ -223,7 +233,6 @@
function If:evaluate_conditions(engine, state, context)
local res = false
- -- util.debug(self.conditions)
for _, condition in ipairs(self.conditions) do
if self:evaluate_condition(condition, state, context) then
if self.match == "any" then
@@ -245,8 +254,6 @@
end
function If:evaluate_condition(condition, state, context)
- -- util.debug(context.cite)
- -- util.debug(condition)
if condition.condition == "disambiguate" then
return context.disambiguate or (context.in_bibliography and context.reference.disambiguate)
@@ -255,7 +262,8 @@
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))
+ util.warning(string.format("Expecting number variable for condition 'is-numeric', got %s '%s'", variable_type,
+ variable))
return false
end
@@ -274,7 +282,8 @@
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)
@@ -299,7 +308,7 @@
elseif condition.condition == "type" then
local item_type = context:get_variable("type")
- return item_type == condition.value
+ return condition.value[item_type] ~= nil
elseif condition.condition == "variable" then
local var = condition.value
@@ -325,7 +334,6 @@
end
function If:check_position(position, context)
- -- util.debug(context.cite)
if context.in_bibliography then
return false
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -50,9 +50,6 @@
local Position = util.Position
--- local DEBUG_DISAMBIGUATE = true
-
-
--- at class Citation: Element
--- at field disambiguate_add_givenname boolean?
--- at field givenname_disambiguation_rule string
@@ -179,7 +176,6 @@
--- at alias CiteId string | number
----comment
--- at param citation_items CitationItem[]
--- at param engine CiteProc
--- at param properties CitationProperties
@@ -189,9 +185,6 @@
local output_format = engine.output_format
--- at 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)
table.insert(irs, ir)
@@ -217,20 +210,20 @@
-- Capitalize first
for i, ir in ipairs(irs) do
- -- local layout_prefix
- -- local layout_affixes = self.layout.affixes
- -- if layout_affixes then
- -- layout_prefix = layout_affixes.prefix
- -- end
+ -- local layout_prefix
+ -- local layout_affixes = self.layout.affixes
+ -- if layout_affixes then
+ -- layout_prefix = layout_affixes.prefix
+ -- end
local prefix_inlines = ir.cite_prefix
if prefix_inlines then
-- Prefix is inlines
local prefix_str = output.SortStringFormat:new():output(prefix_inlines, context)
if (string.match(prefix_str, "[.!?]%s*$")
- -- position_IbidWithPrefixFullStop.txt
- -- `Book A. He said “Please work.” Ibid.`
- or string.match(prefix_str, "[.!?]”%s*$")
- ) and InlineElement.has_space(prefix_inlines) then
+ -- position_IbidWithPrefixFullStop.txt
+ -- `Book A. He said “Please work.” Ibid.`
+ or string.match(prefix_str, "[.!?]”%s*$")
+ ) and InlineElement.has_space(prefix_inlines) then
ir:capitalize_first_term()
end
else
@@ -241,8 +234,6 @@
end
end
- -- util.debug(irs)
-
local citation_stream = {}
local context = Context:new()
@@ -284,10 +275,8 @@
table.insert(citation_stream, Micro:new(cite_prefix))
end
- -- util.debug(ir.cite_item.id)
- -- util.debug(cite_inlines)
-- if context.engine.opt.citation_link then
- cite_inlines = {CiteInline:new(cite_inlines, ir.cite_item)}
+ cite_inlines = {CiteInline:new(cite_inlines, ir.cite_item)}
-- end
util.extend(citation_stream, cite_inlines)
@@ -298,7 +287,7 @@
-- affix_WithCommas.txt
local right_most_str = cite_suffix[#cite_suffix]:get_right_most_string()
if string.match(right_most_str, "[,.;?]%s*$") then
- ir.own_delimiter = string.gsub(cite_delimiter, "^[,.;?]", "")
+ ir.own_delimiter = string.gsub(cite_delimiter, "^[,.;?]", "")
end
end
end
@@ -308,8 +297,6 @@
end
end
- -- util.debug(citation_stream)
-
local has_printed_form = true
if #citation_items == 0 then
-- bugreports_AuthorOnlyFail.txt
@@ -437,7 +424,6 @@
--- at param properties CitationProperties
--- at return CiteIr
function Citation:build_fully_disambiguated_ir(cite_item, output_format, engine, properties)
- -- util.debug(cite_item.id)
local cite_ir = self:build_ambiguous_ir(cite_item, output_format, engine)
cite_ir = self:apply_disambiguate_add_givenname(cite_ir, engine)
cite_ir = self:apply_disambiguate_add_names(cite_ir, engine)
@@ -461,7 +447,6 @@
return cite_ir
end
----comment
--- at param cite_item CitationItem
--- at param output_format OutputFormat
--- at param engine CiteProc
@@ -528,18 +513,6 @@
break
end
end
- if DEBUG_DISAMBIGUATE then
- if ir.is_ambiguous then
- util.debug("[CLASH]")
- util.debug(string.format("%s: %s", cite_item.id, disam_str))
- for ir_index, ir_ in pairs(engine.cite_irs_by_output[disam_str]) do
- util.debug(string.format("%s: %s", ir_.cite_item.id, ir_.disam_str))
- end
- else
- util.debug("[clear]")
- util.debug(string.format("%s: %s", cite_item.id, disam_str))
- end
- end
engine.cite_irs_by_output[disam_str][ir.ir_index] = ir
return ir
@@ -559,10 +532,6 @@
function Citation:apply_disambiguate_add_givenname(cite_ir, engine)
if self.disambiguate_add_givenname then
- if DEBUG_DISAMBIGUATE then
- util.debug("[Method (1)] disambiguate-add-givenname: " .. cite_ir.cite_item.id)
- end
-
local gn_disam_rule = self.givenname_disambiguation_rule
if gn_disam_rule == "all-names" or gn_disam_rule == "all-names-with-initials" then
cite_ir = self:apply_disambiguate_add_givenname_all_names(cite_ir, engine)
@@ -577,16 +546,12 @@
-- TODO: reorganize this code
function Citation:apply_disambiguate_add_givenname_all_names(cite_ir, engine)
- -- util.debug("disambiguate_add_givenname_all_names: " .. cite_ir.cite_item.id)
if not cite_ir.person_name_irs or #cite_ir.person_name_irs == 0 then
return cite_ir
end
- -- util.debug(cite_ir.disam_str)
-
for _, person_name_ir in ipairs(cite_ir.person_name_irs) do
local name_output = person_name_ir.name_output
- -- util.debug(name_output)
if not person_name_ir.person_name_index then
person_name_ir.person_name_index = #engine.person_names + 1
@@ -610,12 +575,6 @@
end
end
- -- util.debug(person_name_ir.name_output)
- -- util.debug(person_name_ir.full_name)
- -- util.debug(#ambiguous_name_irs)
- -- util.debug(person_name_ir.disam_variants_index)
- -- util.debug(person_name_ir.disam_variants)
-
while person_name_ir.disam_variants_index < #person_name_ir.disam_variants do
if #ambiguous_name_irs == 0 then
break
@@ -635,14 +594,11 @@
end
end
- -- util.debug(person_name_ir.name_output)
-
-- update ambiguous_name_irs and ambiguous_same_output_irs
ambiguous_name_irs = {}
ambiguous_same_output_irs = {}
for _, pn_ir in pairs(engine.person_names_by_output[person_name_ir.name_output]) do
if pn_ir.full_name ~= person_name_ir.full_name then
- -- util.debug(pn_ir.full_name .. ": " .. pn_ir.name_output)
table.insert(ambiguous_name_irs, pn_ir)
end
if pn_ir.name_output == person_name_ir.name_output then
@@ -666,7 +622,6 @@
-- update ambiguous_cite_irs and ambiguous_same_output_irs
local ambiguous_cite_irs = {}
for ir_index, ir_ in pairs(engine.cite_irs_by_output[cite_ir.disam_str]) do
- -- util.debug(ir_.cite_item.id)
if ir_.cite_item.id ~= cite_ir.cite_item.id then
table.insert(ambiguous_cite_irs, ir_)
end
@@ -684,7 +639,6 @@
end
local person_name_ir = cite_ir.person_name_irs[1]
local name_output = person_name_ir.name_output
- -- util.debug(name_output)
if not person_name_ir.person_name_index then
person_name_ir.person_name_index = #engine.person_names + 1
@@ -743,20 +697,13 @@
end
function Citation:apply_disambiguate_add_givenname_by_cite(cite_ir, engine)
- -- util.debug(cite_ir.is_ambiguous)
if not cite_ir.is_ambiguous then
return cite_ir
end
- -- util.debug(cite_ir)
if not cite_ir.person_name_irs or #cite_ir.person_name_irs == 0 then
return cite_ir
end
- -- for _, ir_ in ipairs(engine.disam_irs) do
- -- util.debug(ir_.cite_item.id)
- -- util.debug(ir_.disam_str)
- -- end
-
local disam_format = DisamStringFormat:new()
local ambiguous_cite_irs = {}
@@ -772,34 +719,27 @@
end
for i, person_name_ir in ipairs(cite_ir.person_name_irs) do
- -- util.debug(person_name_ir.name_output)
- -- util.debug(person_name_ir.disam_variants)
if #ambiguous_cite_irs == 0 then
cite_ir.is_ambiguous = false
break
end
- -- util.debug(person_name_ir.disam_variants)
while person_name_ir.disam_variants_index < #person_name_ir.disam_variants do
- -- util.debug(person_name_ir.name_output)
local is_different_name = false
for _, ir_ in ipairs(ambiguous_cite_irs) do
if ir_.person_name_irs[i] then
if ir_.person_name_irs[i].full_name ~= person_name_ir.full_name then
- -- util.debug(ir_.cite_item.id)
is_different_name = true
break
end
end
end
- -- util.debug(is_different_name)
if not is_different_name then
break
end
for _, ir_ in ipairs(ambiguous_same_output_irs) do
- -- util.debug(ir_.cite_item.id)
local person_name_ir_ = ir_.person_name_irs[i]
if person_name_ir_ then
if person_name_ir_.disam_variants_index < #person_name_ir_.disam_variants then
@@ -806,7 +746,6 @@
person_name_ir_.disam_variants_index = person_name_ir_.disam_variants_index + 1
local disam_variant = person_name_ir_.disam_variants[person_name_ir_.disam_variants_index]
person_name_ir_.name_output = disam_variant
- -- util.debug(disam_variant)
person_name_ir_.inlines = person_name_ir_.disam_inlines[disam_variant]
-- Update cite ir output
local inlines = ir_:flatten(disam_format)
@@ -824,7 +763,6 @@
ambiguous_cite_irs = {}
ambiguous_same_output_irs = {}
for ir_index, ir_ in pairs(engine.cite_irs_by_output[cite_ir.disam_str]) do
- -- util.debug(ir_.cite_item.id)
if ir_.cite_item.id ~= cite_ir.cite_item.id then
table.insert(ambiguous_cite_irs, ir_)
end
@@ -833,8 +771,6 @@
end
end
- -- util.debug(#ambiguous_cite_irs)
-
if #ambiguous_cite_irs == 0 then
cite_ir.is_ambiguous = false
return cite_ir
@@ -869,7 +805,7 @@
if not cite_ir.name_ir then
cite_ir.name_ir = find_first_name_ir(cite_ir)
end
- local name_ir = cite_ir.name_ir
+ local name_ir = cite_ir.name_ir
if not cite_ir.is_ambiguous then
return cite_ir
@@ -879,16 +815,6 @@
return cite_ir
end
- if DEBUG_DISAMBIGUATE then
- util.debug("[Method (3)] disambiguate-add-names: " .. cite_ir.cite_item.id)
- end
-
- -- if name_ir then
- -- util.debug(cite_ir.disam_str)
- -- util.debug(cite_ir.name_ir.full_name_str)
- -- util.debug(cite_ir.is_ambiguous)
- -- end
-
local disam_format = DisamStringFormat:new()
while cite_ir.is_ambiguous do
@@ -907,7 +833,6 @@
end
end
- -- util.debug(#ambiguous_same_output_irs)
if #ambiguous_cite_irs == 0 then
cite_ir.is_ambiguous = false
break
@@ -921,7 +846,6 @@
break
end
end
- -- util.debug(can_be_disambuguated)
if not can_be_disambuguated then
break
end
@@ -929,7 +853,6 @@
for _, ir_ in ipairs(ambiguous_same_output_irs) do
local added_person_name_ir = ir_.name_ir.name_inheritance:expand_one_name(ir_.name_ir)
if added_person_name_ir then
- -- util.debug("Updated: " .. ir_.cite_item.id)
table.insert(ir_.person_name_irs, added_person_name_ir)
if not added_person_name_ir.person_name_index then
@@ -945,7 +868,6 @@
-- Update ir output
local inlines = ir_:flatten(disam_format)
local disam_str = disam_format:output(inlines, nil)
- -- util.debug(disam_str)
ir_.disam_str = disam_str
if not engine.cite_irs_by_output[disam_str] then
engine.cite_irs_by_output[disam_str] = {}
@@ -954,7 +876,6 @@
end
end
- -- util.debug("disambiguate_add_givenname")
if self.disambiguate_add_givenname then
local gn_disam_rule = self.givenname_disambiguation_rule
@@ -967,13 +888,8 @@
cite_ir.is_ambiguous = self:check_ambiguity(cite_ir, engine)
- -- for _, ir_ in ipairs(engine.disam_irs) do
- -- util.debug(ir_.cite_item.id .. ": " .. ir_.disam_str)
- -- end
-
end
-
return cite_ir
end
@@ -993,10 +909,6 @@
end
function Citation:apply_disambiguate_conditionals(cite_ir, engine)
- if DEBUG_DISAMBIGUATE then
- util.debug("[Method (3)] disambiguate with condition testing “true”: " .. cite_ir.cite_item.id)
- end
-
cite_ir.irs_with_disambiguate_branch = self:collect_irs_with_disambiguate_branch(cite_ir)
local disam_format = DisamStringFormat:new()
@@ -1006,9 +918,6 @@
break
end
- -- util.debug(cite_ir.cite_item.id)
- -- util.debug(cite_ir.disam_str)
-
-- update ambiguous_same_output_irs
local ambiguous_same_output_irs = {}
for _, ir_ in pairs(engine.cite_irs_by_output[cite_ir.disam_str]) do
@@ -1042,11 +951,6 @@
end
cite_ir.is_ambiguous = self:check_ambiguity(cite_ir, engine)
- -- util.debug(cite_ir.is_ambiguous)
- -- for _, ir_ in ipairs(engine.disam_irs) do
- -- util.debug(ir_.cite_item.id .. ": " .. ir_.disam_str)
- -- end
-
end
return cite_ir
end
@@ -1058,20 +962,6 @@
is_ambiguous = true
end
end
- if DEBUG_DISAMBIGUATE then
- if is_ambiguous then
- util.debug("[CLASH]")
- util.debug(string.format("%s, %s", cite_ir.cite_item.id, cite_ir.disam_str))
- for _, ir_ in pairs(engine.cite_irs_by_output[cite_ir.disam_str]) do
- if ir_.cite_item.id ~= cite_ir.cite_item.id then
- util.debug(string.format("%s: %s", ir_.cite_item.id, ir_.disam_str))
- end
- end
- else
- util.debug("[clear]")
- util.debug(string.format("%s, %s", cite_ir.cite_item.id, cite_ir.disam_str))
- end
- end
return is_ambiguous
end
@@ -1101,10 +991,6 @@
return cite_ir
end
- if DEBUG_DISAMBIGUATE then
- util.debug("[Method (4)] disambiguate-add-year-suffix”: " .. cite_ir.cite_item.id)
- end
-
local ambiguous_same_output_irs = self:get_ambiguous_same_output_cite_irs(cite_ir, engine)
table.sort(ambiguous_same_output_irs, function (a, b)
@@ -1126,7 +1012,6 @@
ir_.reference.year_suffix_number = year_suffix_number
ir_.reference["year-suffix"] = self:render_year_suffix(year_suffix_number)
end
- -- util.debug(string.format('%s: %s "%s"', ir_.cite_item.id, tostring(ir_.reference.year_suffix_number), ir_.reference["year-suffix"]))
if not ir_.year_suffix_irs then
ir_.year_suffix_irs = ir_:collect_year_suffix_irs()
@@ -1134,7 +1019,6 @@
-- The style does not have a "year-suffix" variable.
-- Then the year-suffix is appended the first year rendered through cs:date or citation-label
local year_ir = ir_:find_first_year_ir()
- -- util.debug(year_ir)
if year_ir then
local year_suffix_ir = YearSuffix:new({}, self)
table.insert(year_ir.children, year_suffix_ir)
@@ -1147,8 +1031,7 @@
-- Render all the year-suffix irs.
for _, year_suffix_ir in ipairs(ir_.year_suffix_irs) do
- -- util.debug(ir_.reference["year-suffix"])
- year_suffix_ir.inlines = { PlainText:new(ir_.reference["year-suffix"]) }
+ year_suffix_ir.inlines = {PlainText:new(ir_.reference["year-suffix"])}
year_suffix_ir.year_suffix_number = ir_.reference.year_suffix_number
year_suffix_ir.group_var = GroupVar.Important
end
@@ -1156,7 +1039,6 @@
-- DisamStringFormat doesn't render YearSuffix and this can be skipped.
-- local inlines = ir_:flatten(disam_format)
-- local disam_str = disam_format:output(inlines, nil)
- -- util.debug(string.format('update %s: "%s" to "%s"', ir_.cite_item.id, ir_.disam_str, disam_str))
-- ir_.disam_str = disam_str
-- if not engine.cite_irs_by_output[disam_str] then
-- engine.cite_irs_by_output[disam_str] = {}
@@ -1179,7 +1061,6 @@
year_suffix = string.char(i + 97) .. year_suffix
year_suffix_number = (year_suffix_number - 1) // 26
end
- -- util.debug(year_suffix)
return year_suffix
end
@@ -1206,11 +1087,11 @@
local first_rendering_ir = find_first(ir, function (ir_)
return (ir_._element_name == "text"
- or ir_._element_name == "date"
- or ir_._element_name == "number"
- or ir_._element_name == "names"
- or ir_._element_name == "label")
- and ir_.group_var ~= GroupVar.Missing
+ or ir_._element_name == "date"
+ or ir_._element_name == "number"
+ or ir_._element_name == "names"
+ or ir_._element_name == "label")
+ and ir_.group_var ~= GroupVar.Missing
end)
local first_names_ir
if first_rendering_ir and first_rendering_ir._element_name == "names" then
@@ -1291,11 +1172,11 @@
function Citation:_apply_cite_author_only(ir)
local author_ir = find_first(ir, function (ir_)
return (ir_._element_name == "text"
- or ir_._element_name == "date"
- or ir_._element_name == "number"
- or ir_._element_name == "names"
- or ir_._element_name == "label")
- and ir_.group_var ~= GroupVar.Missing
+ or ir_._element_name == "date"
+ or ir_._element_name == "number"
+ or ir_._element_name == "names"
+ or ir_._element_name == "label")
+ and ir_.group_var ~= GroupVar.Missing
end)
if author_ir then
@@ -1310,7 +1191,6 @@
function Citation:_apply_suppress_author(ir)
local author_ir = find_first_names_ir(ir)
if author_ir then
- -- util.debug(author_ir)
author_ir.collapse_suppressed = true
end
return ir
@@ -1321,7 +1201,6 @@
local first_names_ir = find_first_names_ir(ir)
if first_names_ir and engine.style.class ~= "note" then
- -- util.debug(first_names_ir)
first_names_ir.collapse_suppressed = true
end
@@ -1416,7 +1295,7 @@
if i == 1 then
table.insert(current_group, ir)
elseif citation_number and previous_citation_number and
- previous_citation_number + 1 == citation_number then
+ previous_citation_number + 1 == citation_number then
table.insert(current_group, ir)
else
table.insert(cite_groups, current_group)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-date.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-date.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-date.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -25,7 +25,6 @@
end
local Element = element.Element
-local IrNode = ir_node.IrNode
local Rendered = ir_node.Rendered
local SeqIr = ir_node.SeqIr
local GroupVar = ir_node.GroupVar
@@ -243,7 +242,7 @@
else
if #range_part_queue > 0 then
table.insert(irs, self:build_date_range_parts(range_part_queue, variable,
- delimiter, engine, state, context, range_delimiter))
+ delimiter, engine, state, context, range_delimiter))
range_part_queue = {}
end
table.insert(irs, date_part:build_ir(first, engine, state, context))
@@ -252,7 +251,7 @@
end
if #range_part_queue > 0 then
table.insert(irs, self:build_date_range_parts(range_part_queue, variable,
- delimiter, engine, state, context, range_delimiter))
+ delimiter, engine, state, context, range_delimiter))
end
local ir = SeqIr:new(irs, self)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-group.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-group.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-group.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -21,7 +21,6 @@
util = require("citeproc.util")
end
-local SeqIr = ir_node.SeqIr
local Element = element.Element
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-label.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-label.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-label.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -8,7 +8,6 @@
local element
local ir_node
-local output
local util
local using_luatex, kpse = pcall(require, "kpse")
@@ -15,19 +14,15 @@
if using_luatex then
element = require("citeproc-element")
ir_node = require("citeproc-ir-node")
- output = require("citeproc-output")
util = require("citeproc-util")
else
element = require("citeproc.element")
ir_node = require("citeproc.ir-node")
- output = require("citeproc.output")
util = require("citeproc.util")
end
local Element = element.Element
-local IrNode = ir_node.IrNode
local Rendered = ir_node.Rendered
-local PlainText = output.PlainText
-- [Label](https://docs.citationstyles.org/en/stable/specification.html#label)
@@ -55,6 +50,10 @@
return o
end
+--- at param engine CiteProc
+--- at param state table
+--- at param context Context
+--- at return Rendered?
function Label:build_ir(engine, state, context)
-- local variable = context:get_variable(self.variable, self.form)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-layout.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-layout.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-layout.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -77,7 +77,6 @@
ir.formatting = util.clone(self.formatting)
end
end
- -- util.debug(ir)
return ir
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-locale.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-locale.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-locale.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -100,10 +100,10 @@
Locale.form_fallbacks = {
["verb-short"] = {"verb-short", "verb", "long"},
- ["verb"] = {"verb", "long"},
- ["symbol"] = {"symbol", "short", "long"},
- ["short"] = {"short", "long"},
- ["long"] = {"long"},
+ ["verb"] = {"verb", "long"},
+ ["symbol"] = {"symbol", "short", "long"},
+ ["short"] = {"short", "long"},
+ ["long"] = {"long"},
}
@@ -205,7 +205,6 @@
o:process_children_nodes(node)
for _, term in ipairs(o.children) do
local form = term.form
- local gender = term.gender
local gender_form = term.gender_form
local match
if util.startswith(term.name, "ordinal-0") then
@@ -215,17 +214,17 @@
end
local key = term.name
- if form then
- key = key .. '/form-' .. form
+ if form and form ~= "long" then
+ key = key .. "/form-" .. form
end
-- if gender then
-- key = key .. '/gender-' .. gender
-- end
if gender_form then
- key = key .. '/gender-form-' .. gender_form
+ key = key .. "/gender-form-" .. gender_form
end
if match then
- key = key .. '/match-' .. match
+ key = key .. "/match-" .. match
end
if term.name == "ordinal" or util.startswith(term.name, "ordinal-") then
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-names.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-names.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-names.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -27,7 +27,6 @@
util = require("citeproc.util")
end
-local IrNode = ir_node.IrNode
local NameIr = ir_node.NameIr
local PersonNameIr = ir_node.PersonNameIr
local SeqIr = ir_node.SeqIr
@@ -201,7 +200,6 @@
local irs = {}
local num_names = 0
- -- util.debug(self.name)
local index_by_variable = {}
@@ -209,7 +207,8 @@
-- substitute_SubstituteOnlyOnceString.txt
if names_inheritance.variable then
for _, variable in ipairs(util.split(names_inheritance.variable)) do
- local name_ir = names_inheritance.name:build_ir(variable, names_inheritance.et_al, names_inheritance.label, engine, state, context)
+ local name_ir = names_inheritance.name:build_ir(variable, names_inheritance.et_al, names_inheritance.label,
+ engine, state, context)
if name_ir and names_inheritance.name.form == "count" then
num_names = num_names + name_ir.name_count
end
@@ -245,7 +244,8 @@
if editor_name_ir.full_name_str == translator_name_ir.full_name_str then
local names = context:get_variable("editor")
- local editor_translator_label_ir = names_inheritance.name:build_name_label(names_inheritance.label, "editortranslator", names, context)
+ local editor_translator_label_ir = names_inheritance.name:build_name_label(names_inheritance.label,
+ "editortranslator", names, context)
if editor_translator_label_ir then
local first_index = index_by_variable.editor
local second_index = index_by_variable.translator
@@ -273,7 +273,6 @@
ir = NameIr:new({ir}, self)
ir.name_count = num_names
ir.group_var = GroupVar.Important
- -- util.debug(ir)
return ir
end
else
@@ -326,7 +325,7 @@
function Names:substitute_names(result, context)
if not context.build.first_rendered_names then
- return result
+ return result
end
local name_strings = {}
local match_all
@@ -477,7 +476,8 @@
label = nil
end
- local et_al_abbreviation = self.et_al_min and self.et_al_use_first and #names >= self.et_al_min and #names > self.et_al_use_first
+ local et_al_abbreviation = self.et_al_min and self.et_al_use_first and #names >= self.et_al_min and
+ #names > self.et_al_use_first
local use_last = et_al_abbreviation and self.et_al_use_last and self.et_al_use_first <= self.et_al_min - 2
if self.form == "count" then
@@ -656,8 +656,6 @@
(is_sort and context.style.demote_non_dropping_particle == "sort-only"))
local name_part_tokens = self:get_display_order(name, self.form, is_latin, is_sort, is_inverted, demote_ndp)
- -- util.debug(name)
- -- util.debug(name_part_tokens)
local inlines = {}
for i, token in ipairs(name_part_tokens) do
@@ -678,7 +676,7 @@
util.extend(inlines, InlineElement:parse(text, context))
elseif token == "literal" then
- local literal_inlines = self.family:format_text_case(name.literal, context)
+ local literal_inlines = self.family:format_text_case(name.literal, context)
util.extend(inlines, literal_inlines)
elseif token == "space" then
@@ -691,7 +689,6 @@
table.insert(inlines, PlainText:new(self.sort_separator))
end
end
- -- util.debug(inlines)
return inlines
end
@@ -991,7 +988,7 @@
local first_letter = utf8.char(utf8.codepoint(name))
if unicode.islower(first_letter) then
- is_particle = true
+ is_particle = true
elseif #name == 1 then
is_abbreviation = true
else
@@ -1004,8 +1001,8 @@
if is_particle then
name_list[i] = name .. " "
- if i > 1 and not string.match(name_list[i-1], "%s$") then
- name_list[i-1] = name_list[i-1] .. " "
+ if i > 1 and not string.match(name_list[i - 1], "%s$") then
+ name_list[i - 1] = name_list[i - 1] .. " "
end
elseif is_abbreviation then
name_list[i] = name .. with
@@ -1037,11 +1034,11 @@
end
-- Handle the compound names
- if i > 1 and punct_list[i-1] == "-" then
+ if i > 1 and punct_list[i - 1] == "-" then
if is_particle then -- special case "Guo-ping"
name_list[i] = ""
else
- name_list[i-1] = util.rstrip(name_list[i-1])
+ name_list[i - 1] = util.rstrip(name_list[i - 1])
name_list[i] = "-" .. name_list[i]
end
end
@@ -1124,7 +1121,7 @@
table.remove(hidden_name_irs, 1)
if #hidden_name_irs == 0 then
if name_ir.et_al_abbreviation then
- name_ir.et_al_abbreviation = false
+ name_ir.et_al_abbreviation = false
end
if name_ir.use_last then
name_ir.use_last = false
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-number.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-number.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-number.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -8,17 +8,14 @@
local element
local ir_node
-local util
local using_luatex, kpse = pcall(require, "kpse")
if using_luatex then
element = require("citeproc-element")
ir_node = require("citeproc-ir-node")
- util = require("citeproc-util")
else
element = require("citeproc.element")
ir_node = require("citeproc.ir-node")
- util = require("citeproc.util")
end
local Element = element.Element
@@ -35,7 +32,7 @@
--- at field text_case string?
local Number = Element:derive("number")
-function Number:new(node)
+function Number:new()
local o = {
element_name = "number",
form = "numeric",
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-sort.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-sort.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-sort.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -106,12 +106,9 @@
table.insert(key_map[item.id], i)
end
- -- util.debug(key_map)
-
local function compare_entry(item1, item2)
return self.compare_entry(key_map, sort_directions, item1, item2)
end
- -- util.debug(items)
table.sort(items, compare_entry)
return items
@@ -215,7 +212,6 @@
end
local output_format = context.format
local inlines = ir:flatten(output_format)
- -- util.debug(inlines)
local str = output_format:output(inlines)
return str
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-style.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-style.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-style.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -8,8 +8,6 @@
local dom
local element
-local ir_node
-local output
local node_names
local util
@@ -17,25 +15,16 @@
if using_luatex then
dom = require("luaxml-domobject")
element = require("citeproc-element")
- ir_node = require("citeproc-ir-node")
- output = require("citeproc-output")
node_names = require("citeproc-node-names")
util = require("citeproc-util")
else
dom = require("citeproc.luaxml.domobject")
element = require("citeproc.element")
- ir_node = require("citeproc.ir-node")
- output = require("citeproc.output")
node_names = require("citeproc.node-names")
util = require("citeproc.util")
end
local Element = element.Element
-local IrNode = ir_node.IrNode
-local Rendered = ir_node.Rendered
-local SeqIr = ir_node.SeqIr
-local PlainText = output.PlainText
-local DisamStringFormat = output.DisamStringFormat
--- at class Style: Element
@@ -285,7 +274,6 @@
end
-
style_module.Style = Style
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-text.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-text.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-node-text.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -87,7 +87,6 @@
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)
@@ -236,7 +235,6 @@
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)
state:pop_macro(self.macro)
@@ -248,7 +246,6 @@
ir.quotes = context:get_localized_quotes()
end
end
- -- util.debug(ir)
return ir
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-nodes.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-nodes.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-nodes.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -20,60 +20,60 @@
local using_luatex, kpse = pcall(require, "kpse")
if using_luatex then
- style = require("citeproc-node-style")
- citation = require("citeproc-node-citation")
- bibliography = require("citeproc-node-bibliography")
+ style = require("citeproc-node-style")
+ citation = require("citeproc-node-citation")
+ bibliography = require("citeproc-node-bibliography")
locale = require("citeproc-node-locale")
layout = require("citeproc-node-layout")
- text = require("citeproc-node-text")
- date = require("citeproc-node-date")
+ text = require("citeproc-node-text")
+ date = require("citeproc-node-date")
number = require("citeproc-node-number")
- names = require("citeproc-node-names")
- label = require("citeproc-node-label")
- group = require("citeproc-node-group")
+ names = require("citeproc-node-names")
+ label = require("citeproc-node-label")
+ group = require("citeproc-node-group")
choose = require("citeproc-node-choose")
- sort = require("citeproc-node-sort")
+ sort = require("citeproc-node-sort")
else
- style = require("citeproc.node-style")
- citation = require("citeproc.node-citation")
- bibliography = require("citeproc.node-bibliography")
+ style = require("citeproc.node-style")
+ citation = require("citeproc.node-citation")
+ bibliography = require("citeproc.node-bibliography")
locale = require("citeproc.node-locale")
layout = require("citeproc.node-layout")
- text = require("citeproc.node-text")
- date = require("citeproc.node-date")
+ text = require("citeproc.node-text")
+ date = require("citeproc.node-date")
number = require("citeproc.node-number")
- names = require("citeproc.node-names")
- label = require("citeproc.node-label")
- group = require("citeproc.node-group")
+ names = require("citeproc.node-names")
+ label = require("citeproc.node-label")
+ group = require("citeproc.node-group")
choose = require("citeproc.node-choose")
- sort = require("citeproc.node-sort")
+ sort = require("citeproc.node-sort")
end
local nodes = {
- ["style"] = style.Style,
- ["citation"] = citation.Citation,
- ["intext"] = citation.Intext,
+ ["style"] = style.Style,
+ ["citation"] = citation.Citation,
+ ["intext"] = citation.Intext,
["bibliography"] = bibliography.Bibliography,
- ["locale"] = locale.Locale,
- ["term"] = locale.Term,
- ["layout"] = layout.Layout,
- ["text"] = text.Text,
- ["date"] = date.Date,
- ["date-part"] = date.DatePart,
- ["number"] = number.Number,
- ["names"] = names.Names,
- ["name"] = names.Name,
- ["name-part"] = names.NamePart,
- ["et-al"] = names.EtAl,
- ["substitute"] = names.Substitute,
- ["label"] = label.Label,
- ["group"] = group.Group,
- ["choose"] = choose.Choose,
- ["if"] = choose.If,
- ["else"] = choose.Else,
- ["else-if"] = choose.ElseIf,
- ["sort"] = sort.Sort,
- ["key"] = sort.Key,
+ ["locale"] = locale.Locale,
+ ["term"] = locale.Term,
+ ["layout"] = layout.Layout,
+ ["text"] = text.Text,
+ ["date"] = date.Date,
+ ["date-part"] = date.DatePart,
+ ["number"] = number.Number,
+ ["names"] = names.Names,
+ ["name"] = names.Name,
+ ["name-part"] = names.NamePart,
+ ["et-al"] = names.EtAl,
+ ["substitute"] = names.Substitute,
+ ["label"] = label.Label,
+ ["group"] = group.Group,
+ ["choose"] = choose.Choose,
+ ["if"] = choose.If,
+ ["else"] = choose.Else,
+ ["else-if"] = choose.ElseIf,
+ ["sort"] = sort.Sort,
+ ["key"] = sort.Key,
}
return nodes
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-output.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-output.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-output.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -9,21 +9,18 @@
local lpeg = require("lpeg")
local uni_utf8
local unicode
-local dom
local ir_node
local util
-local using_luatex, kpse = pcall(require, "kpse")
+local using_luatex, _ = pcall(require, "kpse")
if using_luatex then
uni_utf8 = require("unicode").utf8
unicode = require("citeproc-unicode")
- dom = require("luaxml-domobject")
ir_node = require("citeproc-ir-node")
util = require("citeproc-util")
else
uni_utf8 = require("lua-utf8")
unicode = require("citeproc.unicode")
- dom = require("citeproc.luaxml.domobject")
ir_node = require("citeproc.ir-node")
util = require("citeproc.util")
end
@@ -33,19 +30,19 @@
--- at class LocalizedQuotes
local LocalizedQuotes = {
- outer_open = util.unicode['left double quotation mark'],
- outer_close = util.unicode['right double quotation mark'],
- inner_open = util.unicode['left single quotation mark'],
- inner_close = util.unicode['right single quotation mark'],
+ outer_open = util.unicode["left double quotation mark"],
+ outer_close = util.unicode["right double quotation mark"],
+ inner_open = util.unicode["left single quotation mark"],
+ inner_close = util.unicode["right single quotation mark"],
punctuation_in_quote = false,
}
function LocalizedQuotes:new(outer_open, outer_close, inner_open, inner_close, punctuation_in_quote)
local o = {
- outer_open = outer_open or util.unicode['left double quotation mark'],
- outer_close = outer_close or util.unicode['right double quotation mark'],
- inner_open = inner_open or util.unicode['left single quotation mark'],
- inner_close = inner_close or util.unicode['right single quotation mark'],
+ outer_open = outer_open or util.unicode["left double quotation mark"],
+ outer_close = outer_close or util.unicode["right double quotation mark"],
+ inner_open = inner_open or util.unicode["left single quotation mark"],
+ inner_close = inner_close or util.unicode["right single quotation mark"],
punctuation_in_quote = punctuation_in_quote,
}
setmetatable(o, self)
@@ -69,13 +66,11 @@
}
-
----comment
--- at param class_name string
--- at return table
function InlineElement:derive(class_name)
local o = {
- _type = class_name,
+ _type = class_name,
}
-- self[class_name] = o
setmetatable(o, self)
@@ -87,7 +82,7 @@
function InlineElement:new(inlines)
local o = {
inlines = inlines,
- _type = self._type,
+ _type = self._type,
}
setmetatable(o, self)
return o
@@ -322,7 +317,6 @@
end
-
--- at param text string
--- at param context Context?
--- at param is_external boolean?
@@ -335,9 +329,7 @@
inlines = self:parse_csl_rich_text(text)
elseif text_type == "string" then
-- String with HTML-like formatting tags
- -- util.debug(text)
inlines = self:parse_html_tags(text, context, is_external)
- -- util.debug(inlines)
elseif text_type == "number" then
inlines = {PlainText:new(tostring(text))}
else
@@ -434,11 +426,11 @@
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 "<sc>"
+ + P "<i>"
+ + P "<b>"
+ + P "<sup>"
+ + P "<sub>"
+ P ' "'
+ P " '"
+ P '("'
@@ -445,12 +437,12 @@
+ P "('"
+ P "“"
+ P "‘"
- + P '</span>'
- + P '</sc>'
- + P '</i>'
- + P '</b>'
- + P '</sup>'
- + P '</sub>'
+ + P "</span>"
+ + P "</sc>"
+ + P "</i>"
+ + P "</b>"
+ + P "</sup>"
+ + P "</sub>"
+ P '"'
+ P "'"
+ P "”"
@@ -471,23 +463,23 @@
closer = "</span>",
quotes = false,
},
- ['<sc>'] = {
+ ["<sc>"] = {
closer = "</sc>",
quotes = false,
},
- ['<i>'] = {
+ ["<i>"] = {
closer = "</i>",
quotes = false,
},
- ['<b>'] = {
+ ["<b>"] = {
closer = "</b>",
quotes = false,
},
- ['<sup>'] = {
+ ["<sup>"] = {
closer = "</sup>",
quotes = false,
},
- ['<sub>'] = {
+ ["<sub>"] = {
closer = "</sub>",
quotes = false,
},
@@ -507,23 +499,23 @@
closer = "’",
quotes = true,
},
- ['<code>'] = {
+ ["<code>"] = {
closer = "</code>",
quotes = false,
},
- ['<script>'] = {
+ ["<script>"] = {
closer = "</script>",
quotes = false,
},
- ['<pre>'] = {
+ ["<pre>"] = {
closer = "</pre>",
quotes = false,
},
- ['<math>'] = {
+ ["<math>"] = {
closer = "</math>",
quotes = false,
},
- ['<math-tex>'] = {
+ ["<math-tex>"] = {
closer = "</math-tex>",
quotes = false,
},
@@ -552,7 +544,7 @@
openers_info[localed_quotes.outer_open] = {
closer = localed_quotes.outer_close,
quotes = true,
- inner = false
+ inner = false,
}
end
@@ -563,7 +555,7 @@
openers_info[localed_quotes.inner_open] = {
closer = localed_quotes.inner_close,
quotes = true,
- inner = true
+ inner = true,
}
end
@@ -600,7 +592,7 @@
local tag_positions_list = lpeg.match(tag_pattern, str)
if not tag_positions_list then
- error('Pattern not match')
+ error("Pattern not match")
end
local start = 1
local stop = 1
@@ -664,15 +656,15 @@
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
+ elseif tag == "<sc>" then
return Formatted:new(inlines, {["font-variant"] = "small-caps"})
- elseif tag == '<i>' then
+ elseif tag == "<i>" then
return Formatted:new(inlines, {["font-style"] = "italic"})
- elseif tag == '<b>' then
+ elseif tag == "<b>" then
return Formatted:new(inlines, {["font-weight"] = "bold"})
- elseif tag == '<sup>' then
+ elseif tag == "<sup>" then
return Formatted:new(inlines, {["vertical-align"] = "sup"})
- elseif tag == '<sub>' then
+ 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()
@@ -714,9 +706,6 @@
local tags, strings = split_tags_and_strings(str, context)
- -- util.debug(tags)
- -- util.debug(strings)
-
-- if #tags == 0 then
-- return {PlainText:new(str)}
-- end
@@ -725,10 +714,6 @@
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]
@@ -785,8 +770,6 @@
end
end
- -- util.debug(opener_stack)
-
-- Process remainders in the stack
if #opener_stack > 0 then
for _, opener_info in ipairs(opener_stack) do
@@ -810,8 +793,6 @@
-- 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
@@ -818,9 +799,6 @@
end
end
- -- util.debug(tags)
- -- util.debug(strings)
-
--- at type InlineElement[]
local output = {}
@@ -837,7 +815,7 @@
tag = tag,
closer = openers_info[tag].closer,
pos = i,
- output_pos = #output + 1
+ output_pos = #output + 1,
})
else
assert(#opener_stack > 0)
@@ -864,17 +842,16 @@
end
- -- util.debug(output)
return output
end
local function merge_fragments_at(fragments, i)
- if type(fragments[i+1]) == "string" then
- fragments[i] = fragments[i] .. fragments[i+1]
- table.remove(fragments, i+1)
+ if type(fragments[i + 1]) == "string" then
+ fragments[i] = fragments[i] .. fragments[i + 1]
+ table.remove(fragments, i + 1)
end
- if type(fragments[i-1]) == "string" then
- fragments[i-1] = fragments[i-1] .. fragments[i]
+ if type(fragments[i - 1]) == "string" then
+ fragments[i - 1] = fragments[i - 1] .. fragments[i]
table.remove(fragments, i)
end
end
@@ -905,7 +882,7 @@
local start_idx = 1
for _, quote_tuple in ipairs(quote_tuples) do
local idx, qt, next_idx = table.unpack(quote_tuple)
- local fragment = string.sub(inline.value, start_idx, idx-1)
+ local fragment = string.sub(inline.value, start_idx, idx - 1)
if fragment ~= "" then
table.insert(fragments, fragment)
end
@@ -942,13 +919,13 @@
if string.match(left, "%s$") and string.match(right, "^%s") then
-- Orphan quote: bugreports_SingleQuote.txt
if fragment == "'" then
- fragments[i] = util.unicode['apostrophe']
+ fragments[i] = util.unicode["apostrophe"]
end
merge_fragments_at(fragments, i)
end
if not string.match(left, "[%s%p]$") and not string.match(right, "^[%s%p]") then
if fragment == "'" then
- fragments[i] = util.unicode['apostrophe']
+ fragments[i] = util.unicode["apostrophe"]
end
merge_fragments_at(fragments, i)
end
@@ -976,12 +953,11 @@
end
function InlineElement:capitalize_first_term()
- -- util.debug(self)
if self._type == "PlainText" then
self.value = unicode.capitalize(self.value)
elseif self._type ~= "Code" and self._type ~= "MathML" and self._type ~= "MathTeX" then
if self.inlines[1] then
- self.inlines[1]:capitalize_first_term()
+ self.inlines[1]:capitalize_first_term()
end
end
end
@@ -1109,7 +1085,6 @@
local words = unicode.words(str)
for _, word in ipairs(words) do
if unicode.islower(word) and not util.stop_words[word] then
- -- util.debug(word)
return true
end
end
@@ -1123,7 +1098,6 @@
for _, inline in ipairs(inlines) do
if util.is_instance(inline, PlainText) then
if is_str_sentence_case(inline.value) then
- -- util.debug(inline.value)
return true
end
@@ -1133,9 +1107,9 @@
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"
- and inline.formatting["vertical-align"] ~= "sub") then
+ and inline.formatting["font-variant"] ~= "small-caps"
+ and inline.formatting["vertical-align"] ~= "sup"
+ and inline.formatting["vertical-align"] ~= "sub") then
if self:is_sentence_case(inline.inlines) then
return true
end
@@ -1152,12 +1126,10 @@
--- at param inlines table[]
--- at param check_sentence_case boolean
function OutputFormat:convert_sentence_case(inlines, check_sentence_case)
- if not inlines or #inlines == 0 then
+ if not inlines or #inlines == 0 then
return
end
local is_uppercase = false -- TODO
- -- util.debug(check_sentence_case)
- -- util.debug(self:is_sentence_case(inlines))
if check_sentence_case then
if self:is_sentence_case(inlines) then
self:apply_text_case_inner(inlines, "capitalize-first", false, is_uppercase)
@@ -1205,24 +1177,21 @@
end
local is_last = (i == #inlines)
if inline._type == "PlainText" then
- -- util.debug(inline.value)
- -- util.debug(text_case)
inline.value = self:transform_case(inline.value, text_case, seen_one, is_last, is_uppercase);
- -- util.debug(inline.value)
seen_one = seen_one or string_contains_word(inline.value)
elseif inline._type == "NoCase" or
- inline._type == "NoDecor" or
- inline._type == "Code" or
- inline._type == "MathML" or
- inline._type == "MathTeX" or
- (inline._type == "Formatted" and inline.formatting["font-variant"] == "small-caps") or
- (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sup") or
- (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sub") then
+ inline._type == "NoDecor" or
+ inline._type == "Code" or
+ inline._type == "MathML" or
+ inline._type == "MathTeX" or
+ (inline._type == "Formatted" and inline.formatting["font-variant"] == "small-caps") or
+ (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sup") or
+ (inline._type == "Formatted" and inline.formatting["vertical-align"] == "sub") then
seen_one = seen_one or inline_contains_word(inline)
elseif inline._type == "Formatted" or inline._type == "Quoted"
- or inline._type == "CiteInline" or inline._type == "UndefinedCite" then
+ 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
@@ -1239,7 +1208,6 @@
return unicode.upper(str)
end
----comment
--- at param str string
--- at param is_first boolean
--- at param transform function
@@ -1250,7 +1218,6 @@
for i, segment in ipairs(segments) do
-- bugreports_ThesisUniversityAppearsTwice.txt: "Ph.D"
if uni_utf8.match(segment, "%a") then
- -- util.debug(segment)
segments[i] = transform(segment)
break
end
@@ -1269,7 +1236,6 @@
Other = 0,
}
----comment
--- at param str string
--- at param seen_one boolean
--- at param is_last_inline boolean
@@ -1277,7 +1243,6 @@
--- at return string
local function transform_each_word(str, seen_one, is_last_inline, transform)
local segments = unicode.split_word_bounds(str)
- -- util.debug(segments)
local segment_type_list = {}
local last_word_idx
@@ -1291,10 +1256,11 @@
elseif uni_utf8.match(segment, "%p") then
segment_type_list[i] = SegmentType.Puctuation
- if segment == "!" or segment == "?" then
+ -- In the case of `Form ({MMPI-2-RF}): Technical Manual`, use `endswith()`.
+ if util.endswith(segment, "!") or util.endswith(segment, "?") then
segment_type_list[i] = SegmentType.EndingPunctuation
- -- elseif segment == ":" or segment == "—" then
- elseif segment == ":" then
+ -- elseif segment == ":" or segment == "—" then
+ elseif util.endswith(segment, ":") then
-- Em dash is not taken into consideration, see "Stability—with Job" in `textcase_TitleWithEmDash.txt`
segment_type_list[i] = SegmentType.Colon
end
@@ -1307,20 +1273,17 @@
for i, segment in ipairs(segments) do
if segment_type_list[i] == SegmentType.Word then
local is_first_word = sentence_begin
- local is_last_word = segment_type_list[i+1] == SegmentType.EndingPunctuation
- or (is_last_inline and i == last_word_idx)
+ local is_last_word = segment_type_list[i + 1] == SegmentType.EndingPunctuation
+ or (is_last_inline and i == last_word_idx)
-- See "Pro-Environmental" in `textcase_StopWordBeforeHyphen.txt`
-- but not "Out-of-Fashion" in `textcase_TitleCaseWithHyphens.txt`.
- local ignore_stop_word = segments[i+1] == "-" and segments[i-1] ~= "-"
+ local ignore_stop_word = segments[i + 1] == "-" and segments[i - 1] ~= "-"
- -- util.debug(segment)
- -- util.debug(after_colon)
-- See "07-x" in `textcase_LastChar.txt`
- if not (segments[i-1] == "-" and unicode.len(segment) == 1) then
+ if not (segments[i - 1] == "-" and unicode.len(segment) == 1) then
segments[i] = transform(segment, is_first_word, after_colon, is_last_word, ignore_stop_word)
end
- -- util.debug(segments[i])
sentence_begin = false
after_colon = false
@@ -1336,7 +1299,6 @@
return table.concat(segments)
end
----comment
--- at param word string
--- at return string
local function transform_capitalize_word_if_lower(word)
@@ -1352,8 +1314,6 @@
-- Entirely non-English
-- e.g. "β" in "β-Carotine"
-- TODO: two-word cases like "due to"
- -- util.debug(word)
- -- util.debug(ignore_stop_word)
local res
if (is_first or is_last or after_end_punct or ignore_stop_word or not util.stop_words[word])
and string.match(word, "%a") and unicode.islower(word) then
@@ -1361,12 +1321,10 @@
else
res = word
end
- -- util.debug(res)
return res
end
local function transform_lowercase_if_capitalize(word, is_first, after_end_punct, is_last, is_stop_word)
- -- util.debug(word)
if not (is_first or after_end_punct) then
local is_capitalize_word = false
local lower_first = string.gsub(word, utf8.charpattern, unicode.lower, 1)
@@ -1448,8 +1406,6 @@
self:move_punctuation(inlines)
- -- util.debug(inlines)
-
return self:write_inlines(inlines, context)
end
@@ -1458,7 +1414,6 @@
--- at return string?
function OutputFormat:output_bibliography_entry(inlines, context)
self:flip_flop_inlines(inlines)
- -- util.debug(inlines)
self:move_punctuation(inlines)
-- TODO:
-- if self.format == "html" then
@@ -1506,9 +1461,9 @@
if value == state[attribute] then
if value == "normal" then
formatting[attribute] = nil
- -- Formatting outside Micro is not reset to "normal".
- -- else
- -- formatting[attribute] = "normal"
+ -- Formatting outside Micro is not reset to "normal".
+ -- else
+ -- formatting[attribute] = "normal"
end
end
new_state[attribute] = value
@@ -1625,9 +1580,9 @@
local function find_left(inline)
if inline._type == "PlainText" then
return inline
- -- elseif inline._type == "Micro" then
- -- return nil
- elseif inline.inlines and #inline.inlines > 0 and inline._type~="Quoted" then
+ -- elseif inline._type == "Micro" then
+ -- return nil
+ elseif inline.inlines and #inline.inlines > 0 and inline._type ~= "Quoted" then
return find_left(inline.inlines[1])
else
return nil
@@ -1637,8 +1592,8 @@
local function find_right(inline)
if inline._type == "PlainText" then
return inline
- -- elseif inline._type == "Micro" then
- -- return nil
+ -- elseif inline._type == "Micro" then
+ -- return nil
elseif inline.inlines and #inline.inlines > 0 and inline._type ~= "Quoted" then
return find_right(inline.inlines[#inline.inlines])
else
@@ -1649,8 +1604,8 @@
local function find_right_in_quoted(inline)
if inline._type == "PlainText" then
return inline
- -- elseif inline._type == "Micro" then
- -- return nil
+ -- elseif inline._type == "Micro" then
+ -- return nil
elseif inline.inlines and #inline.inlines > 0 then
return find_right_in_quoted(inline.inlines[#inline.inlines])
else
@@ -1665,8 +1620,8 @@
if inline._type == "Quoted" and #inline.inlines > 0 then
--- at cast inline Quoted
return find_right_in_quoted(inline.inlines[#inline.inlines]), inline.quotes.punctuation_in_quote
- -- elseif inline._type == "Micro" then
- -- return nil
+ -- elseif inline._type == "Micro" then
+ -- return nil
elseif inline.inlines and #inline.inlines > 0 then
return find_right_quoted(inline.inlines[#inline.inlines])
else
@@ -1677,12 +1632,10 @@
local function smash_string_push(first, second)
local first_char = string.sub(first.value, -1)
local second_char = string.sub(second.value, 1, 1)
- -- util.debug(first_char)
- -- util.debug(second_char)
local punct_map = output_module.quote_punctuation_map
if second_char == " " and (first_char == " " or
- util.endswith(first.value, util.unicode["no-break space"])) then
+ util.endswith(first.value, util.unicode["no-break space"])) then
second.value = string.sub(second.value, 2)
elseif punct_map[first_char] then
if first_char == second_char then
@@ -1703,12 +1656,10 @@
if first and second then
local first_char = string.sub(first.value, -1)
local second_char = string.sub(second.value, 1, 1)
- -- util.debug(first_char)
- -- util.debug(second_char)
local punct_map = output_module.quote_punctuation_map
if second_char == " " and (first_char == " " or
- util.endswith(first.value, util.unicode["no-break space"])) then
+ util.endswith(first.value, util.unicode["no-break space"])) then
second.value = string.sub(second.value, 2)
return true
elseif punct_map[first_char] then
@@ -1735,7 +1686,7 @@
local idx = 1
while idx < #inlines do
local first = inlines[idx]
- local second = inlines[idx+1]
+ local second = inlines[idx + 1]
if first._type == "PlainText" and second._type == "PlainText" then
smash_string_push(first, second)
@@ -1753,7 +1704,7 @@
end
elseif (first._type == "Formatted" or first._type == "CiteInline"
- or first._type == "UndefinedCite") and second._type == "PlainText" then
+ or first._type == "UndefinedCite") and second._type == "PlainText" then
local success = smash_just_punc(first, second)
if success then
if second.value == "" then
@@ -1822,7 +1773,7 @@
-- Move punctuation into quotes as needed
local first, punctuation_in_quote = find_right_quoted(inlines[idx])
- local second = find_left(inlines[idx+1])
+ local second = find_left(inlines[idx + 1])
local success = false
if first and second then
if punctuation_in_quote then
@@ -1891,7 +1842,6 @@
return self:write_escaped(inline, context)
elseif type(inline) == "table" then
- -- util.debug(inline._type)
if inline._type == "PlainText" then
return self:write_escaped(inline.value, context)
@@ -2016,9 +1966,9 @@
["@cite/entry"] = false,
["@bibliography/entry"] = function (str, context)
if string.match(str, "\\bibitem") then
- str = str .. "\n"
+ str = str .. "\n"
else
- str = "\\bibitem{".. context.id .. "}\n" .. str .. "\n"
+ str = "\\bibitem{" .. context.id .. "}\n" .. str .. "\n"
end
return str
end,
@@ -2029,7 +1979,7 @@
}
local latex_escape_table = {
- ["\\"] = "\\textbackslash{}",
+ ["\\"] = "\\textbackslash ",
["{"] = "\\{",
["}"] = "\\}",
["$"] = "\\$",
@@ -2340,7 +2290,7 @@
local PseudoHtml = HtmlWriter:new()
-function PseudoHtml :write_escaped(str, context)
+function PseudoHtml:write_escaped(str, context)
-- str = string.gsub(str, "%&", "&")
-- str = string.gsub(str, "<", "<")
-- str = string.gsub(str, ">", ">")
@@ -2351,7 +2301,7 @@
end
function PseudoHtml:write_math_ml(inline, context)
- return string.format('<math>%s</math>', inline.value)
+ return string.format("<math>%s</math>", inline.value)
end
function PseudoHtml:write_math_tex(inline, context)
@@ -2433,7 +2383,7 @@
[":"] = ";",
[","] = ";,",
["."] = ";",
- }
+ },
}
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-unicode.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-unicode.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-unicode.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -7,19 +7,21 @@
local unicode = {}
local uni_utf8
+local uni_algos_normalize
local uni_algos_words
local uni_algos_case
-local util
local using_luatex, kpse = pcall(require, "kpse")
if using_luatex then
-- Load `slnunicode` if in LuaTeX
uni_utf8 = require("unicode").utf8
- if kpse.find_file("lua-uni-words", "lua") then
- uni_algos_words = require("lua-uni-words")
+ uni_algos_normalize = require("lua-uni-normalize")
+ local ok
+ ok, uni_algos_words = pcall(require, "lua-uni-words")
+ if not ok then
+ ok, uni_algos_words = pcall(require, "citeproc-lua-uni-words")
end
uni_algos_case = require("lua-uni-case")
- util = require("citeproc-util")
else
uni_utf8 = require("lua-utf8")
if not utf8 then
@@ -28,7 +30,6 @@
end
uni_algos_words = require("citeproc.lua-uni-algos.words")
uni_algos_case = require("citeproc.lua-uni-algos.case")
- util = require("citeproc.util")
end
@@ -54,6 +55,13 @@
end
+if using_luatex then
+ unicode.NFC = uni_algos_normalize.NFC
+else
+ unicode.NFC = uni_utf8.normalize_nfc
+end
+
+
---Return a casefolded copy of the string. Casefolded strings may be used for caseless matching.
--- at param str string
--- at param locale string?
@@ -264,10 +272,8 @@
--- at param str string
--- at return string[]
function unicode.split_word_bounds(str)
- -- util.debug(str)
local segments = {}
if uni_algos_words then
- -- util.debug("uni_algos_words")
for _, _, segment in uni_algos_words.word_boundaries(str) do
table.insert(segments, segment)
end
@@ -275,12 +281,12 @@
for i = #segments, 1, -1 do
local segment = segments[i]
if segment == "`" then
- if i < #segments and not uni_utf8.match(segments[i+1], "^%s") then
- segments[i] = segment .. segments[i+1]
- table.remove(segments, i+1)
+ if i < #segments and not uni_utf8.match(segments[i + 1], "^%s") then
+ segments[i] = segment .. segments[i + 1]
+ table.remove(segments, i + 1)
end
- if i > 1 and not uni_utf8.match(segments[i-1], "%s") then
- segments[i-1] = segments[i-1] .. segments[i]
+ if i > 1 and not uni_utf8.match(segments[i - 1], "%s") then
+ segments[i - 1] = segments[i - 1] .. segments[i]
table.remove(segments, i)
end
end
@@ -287,7 +293,6 @@
end
else
- -- util.debug("no uni_algos_words")
-- A naive implementation
local state = CharState.Other
local segment = ""
@@ -316,7 +321,6 @@
table.insert(segments, segment)
end
- -- util.debug(segments)
return segments
end
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -109,15 +109,15 @@
end
-function util.to_ordinal (n)
+function util.to_ordinal(n)
-- assert(type(n) == "number")
local last_digit = n % 10
- if last_digit == 1 and n ~= 11
- then return tostring(n) .. "st"
- elseif last_digit == 2 and n ~= 12
- then return tostring(n) .. "nd"
- elseif last_digit == 3 and n ~= 13
- then return tostring(n) .. "rd"
+ if last_digit == 1 and n ~= 11 then
+ return tostring(n) .. "st"
+ elseif last_digit == 2 and n ~= 12 then
+ return tostring(n) .. "nd"
+ elseif last_digit == 3 and n ~= 13 then
+ return tostring(n) .. "rd"
else
return tostring(n) .. "th"
end
@@ -135,7 +135,7 @@
if not util.logging_file then
util.error(string.format("Cannot write to '%s'.", path))
end
- util.logging_file = io.open(path, 'a')
+ util.logging_file = io.open(path, "a")
end
@@ -239,7 +239,6 @@
end
-- Similar to re.split() in Python
----comment
--- at param str string
--- at param sep string?
--- at param maxsplit integer?
@@ -256,11 +255,11 @@
return {}
end
if string.find(str, sep) == nil then
- return { str }
+ return {str}
end
if maxsplit == nil or maxsplit < 0 then
- maxsplit = -1 -- No limit
+ maxsplit = -1 -- No limit
end
local result = {}
local pattern = "(.-)" .. sep .. "()"
@@ -320,7 +319,7 @@
return res
end
-function util.slice (t, start, stop)
+function util.slice(t, start, stop)
start = start or 1
stop = stop or #t
if start < 0 then
@@ -338,13 +337,13 @@
return new
end
-function util.concat (list, sep)
+function util.concat(list, sep)
-- This helper function omits empty strings in list, which is different from table.concat
-- This function always returns a string, even empty.
local res = ""
for i = 1, #list do
local s = list[i]
- if s and s~= "" then
+ if s and s ~= "" then
if res == "" then
res = s
else
@@ -382,7 +381,7 @@
--- at param str string
--- at return string
-function util.lstrip (str)
+function util.lstrip(str)
if not str then
error("Invalid input")
end
@@ -405,7 +404,7 @@
--- at param str string
--- at return string
-function util.rstrip (str)
+function util.rstrip(str)
if not str then
error("Invalid input")
end
@@ -415,7 +414,7 @@
--- at param str string
--- at return string
-function util.strip (str)
+function util.strip(str)
return util.lstrip(util.rstrip(str))
end
@@ -423,6 +422,9 @@
if type(str) ~= "string" then
util.error(string.format("\n%s\n'%s' is not a string.", debug.traceback(), str))
end
+ if type(prefix) ~= "string" then
+ util.error(string.format("\n%s\n'%s' is not a string.", debug.traceback(), prefix))
+ end
return string.sub(str, 1, #prefix) == prefix
end
@@ -430,7 +432,7 @@
-- if not str or type(str) ~= "string" then
-- print(debug.traceback())
-- end
- return string.sub(str, -#suffix) == suffix
+ return string.sub(str, - #suffix) == suffix
end
--- at param str string
@@ -629,56 +631,55 @@
end
util.primary_dialects = {
- af= "af-ZA",
- ar= "ar",
- bg= "bg-BG",
- ca= "ca-AD",
- cs= "cs-CZ",
- cy= "cy-GB",
- da= "da-DK",
- de= "de-DE",
- el= "el-GR",
- en= "en-US",
- es= "es-ES",
- et= "et-EE",
- eu= "eu",
- fa= "fa-IR",
- fi= "fi-FI",
- fr= "fr-FR",
- he= "he-IL",
- hi= "hi-IN",
- hr= "hr-HR",
- hu= "hu-HU",
- id= "id-ID",
- is= "is-IS",
- it= "it-IT",
- ja= "ja-JP",
- km= "km-KH",
- ko= "ko-KR",
- la= "la",
- lt= "lt-LT",
- lv= "lv-LV",
- mn= "mn-MN",
- nb= "nb-NO",
- nl= "nl-NL",
- nn= "nn-NO",
- pl= "pl-PL",
- pt= "pt-PT",
- ro= "ro-RO",
- ru= "ru-RU",
- sk= "sk-SK",
- sl= "sl-SI",
- sr= "sr-RS",
- sv= "sv-SE",
- th= "th-TH",
- tr= "tr-TR",
- uk= "uk-UA",
- vi= "vi-VN",
- zh= "zh-CN"
+ af = "af-ZA",
+ ar = "ar",
+ bg = "bg-BG",
+ ca = "ca-AD",
+ cs = "cs-CZ",
+ cy = "cy-GB",
+ da = "da-DK",
+ de = "de-DE",
+ el = "el-GR",
+ en = "en-US",
+ es = "es-ES",
+ et = "et-EE",
+ eu = "eu",
+ fa = "fa-IR",
+ fi = "fi-FI",
+ fr = "fr-FR",
+ he = "he-IL",
+ hi = "hi-IN",
+ hr = "hr-HR",
+ hu = "hu-HU",
+ id = "id-ID",
+ is = "is-IS",
+ it = "it-IT",
+ ja = "ja-JP",
+ km = "km-KH",
+ ko = "ko-KR",
+ la = "la",
+ lt = "lt-LT",
+ lv = "lv-LV",
+ mn = "mn-MN",
+ nb = "nb-NO",
+ nl = "nl-NL",
+ nn = "nn-NO",
+ pl = "pl-PL",
+ pt = "pt-PT",
+ ro = "ro-RO",
+ ru = "ru-RU",
+ sk = "sk-SK",
+ sl = "sl-SI",
+ sr = "sr-RS",
+ sv = "sv-SE",
+ th = "th-TH",
+ tr = "tr-TR",
+ uk = "uk-UA",
+ vi = "vi-VN",
+ zh = "zh-CN",
}
-
-- Range delimiter
util.unicode = {
@@ -854,7 +855,7 @@
util.stop_words[word] = true
end
-function util.all (t)
+function util.all(t)
for _, item in ipairs(t) do
if not item then
return false
@@ -863,7 +864,7 @@
return true
end
-function util.any (t)
+function util.any(t)
for _, item in ipairs(t) do
if item then
return true
@@ -915,7 +916,7 @@
{0x2F800, 0x2FA1F}, -- CJK Compatibility Ideographs Supplement
}
-function util.in_list (value, list)
+function util.in_list(value, list)
for _, v in ipairs(list) do
if value == v then
return true
@@ -924,7 +925,7 @@
return false
end
-function util.in_ranges (value, ranges)
+function util.in_ranges(value, ranges)
for _, range in ipairs(ranges) do
if value >= range[1] and value <= range[2] then
return true
@@ -1000,40 +1001,40 @@
end
util.ordinal_to_arabic_map = {
- first = "1",
- second = "2",
- third = "3",
- fourth = "4",
- fifth = "5",
- sixth = "6",
- seventh = "7",
- eighth = "8",
- ninth = "9",
- tenth = "10",
- eleventh = "11",
- twelfth = "12",
- thirteenth = "13",
- fourteenth = "14",
- fifteenth = "15",
- sixteenth = "16",
- seventeenth = "17",
- eighteenth = "18",
- nineteenth = "19",
- twentieth = "20",
- ["twenty-first"] = "21",
- ["twenty-second"] = "22",
- ["twenty-third"] = "23",
- ["twenty-fourth"] = "24",
- ["twenty-fifth"] = "25",
- ["twenty-sixth"] = "26",
+ first = "1",
+ second = "2",
+ third = "3",
+ fourth = "4",
+ fifth = "5",
+ sixth = "6",
+ seventh = "7",
+ eighth = "8",
+ ninth = "9",
+ tenth = "10",
+ eleventh = "11",
+ twelfth = "12",
+ thirteenth = "13",
+ fourteenth = "14",
+ fifteenth = "15",
+ sixteenth = "16",
+ seventeenth = "17",
+ eighteenth = "18",
+ nineteenth = "19",
+ twentieth = "20",
+ ["twenty-first"] = "21",
+ ["twenty-second"] = "22",
+ ["twenty-third"] = "23",
+ ["twenty-fourth"] = "24",
+ ["twenty-fifth"] = "25",
+ ["twenty-sixth"] = "26",
["twenty-seventh"] = "27",
- ["twenty-eighth"] = "28",
- ["twenty-ninth"] = "29",
- thirtieth = "30",
+ ["twenty-eighth"] = "28",
+ ["twenty-ninth"] = "29",
+ thirtieth = "30",
}
-function util.convert_roman (number)
+function util.convert_roman(number)
-- assert(type(number) == "number")
local output = {}
for _, tuple in ipairs(util.roman_numerals) do
@@ -1045,19 +1046,19 @@
end
util.roman_numerals = {
- {"m", 1000},
+ {"m", 1000},
{"cm", 900},
- {"d", 500},
+ {"d", 500},
{"cd", 400},
- {"c", 100},
+ {"c", 100},
{"xc", 90},
- {"l", 50},
+ {"l", 50},
{"xl", 40},
- {"x", 10},
+ {"x", 10},
{"ix", 9},
- {"v", 5},
+ {"v", 5},
{"iv", 4},
- {"i", 1},
+ {"i", 1},
};
@@ -1234,8 +1235,15 @@
file:close()
end
+--- at alias CslDateVariable { date-parts: (string|number)[][]?, season: string|number, circa: boolean, literal: string|number?, raw: string?}
+
+--- at param str string
+--- at return CslDateVariable?
function util.parse_edtf(str)
+ if string.match(str, "^%s*$") then
+ return nil
+ end
local date = {["date-parts"] = {}}
local range_parts = util.split(str, "/")
for i, range_part in ipairs(range_parts) do
@@ -1244,10 +1252,10 @@
end
date["date-parts"][i] = {}
local negative_year = false
- if string.match(range_part, "^Y%-") then
+ if string.match(range_part, "^%-") or string.match(range_part, "^Y%-") then
negative_year = true
end
- range_part = string.gsub(range_part, "^Y[+-]?", "")
+ range_part = string.gsub(range_part, "^Y?[+-]?", "")
if string.match(range_part, "[?~%%]$") then
date.circa = true
range_part = string.gsub(range_part, "[?~%%]$", "")
@@ -1262,20 +1270,34 @@
date_part = string.gsub(date_part, "X", "0")
end
if string.match(date_part, "^%d+$") then
- date_part = tonumber(date_part)
- if date_part > 0 then
- date["date-parts"][i][j] = date_part
+ local date_part_number = tonumber(date_part)
+ if date_part_number > 0 then
+ date["date-parts"][i][j] = date_part_number
else
break
end
- else
- return nil
+ elseif date_part ~= "" then
+ -- util.error(string.format('Invalid EDTF date "%s".', str))
+ return {literal = str}
end
end
if negative_year then
- date["date-parts"][i][1] = - date["date-parts"][i][1]
+ date["date-parts"][i][1] = -1 - date["date-parts"][i][1]
end
end
+
+ local all_empty = true
+ for i, range_part in ipairs(date["date-parts"]) do
+ if #range_part > 0 then
+ all_empty = false
+ break
+ end
+ end
+
+ if all_empty then
+ return nil
+ end
+
return date
end
@@ -1328,7 +1350,6 @@
util.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00"
----comment
--- at param trigraph string
--- at return { authors: integer[], year: integer }
function util.get_trigraph_param(trigraph)
@@ -1346,7 +1367,7 @@
table.insert(param.authors, 1)
elseif char == "a" then
local len = #param.authors
- param.authors[len] = param.authors[len] + 1
+ param.authors[len] = param.authors[len] + 1
elseif char == "0" then
param.year = param.year + 1
else
@@ -1357,7 +1378,6 @@
end
----comment
--- at param item ItemData
--- at return string
function util.get_citation_label(item)
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-yaml.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-yaml.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc-yaml.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -36,7 +36,7 @@
end
-- The items exported from Better BibTeX has a {references = []} structure.
- if type(items) == 'table' and items.references then
+ if type(items) == "table" and items.references then
items = items.references
end
@@ -57,7 +57,7 @@
elseif type(value) == "table" and not value["date-parts"] then
local new_date = {
- ["date-parts"] = {}
+ ["date-parts"] = {},
}
if value.year then
Modified: trunk/Master/texmf-dist/scripts/citation-style-language/citeproc.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/citation-style-language/citeproc.lua 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/scripts/citation-style-language/citeproc.lua 2025-04-29 19:47:32 UTC (rev 75059)
@@ -17,7 +17,7 @@
util = require("citeproc.util")
end
-citeproc.__VERSION__ = "0.7.0"
+citeproc.__VERSION__ = "0.8.0"
citeproc.new = engine.CiteProc.new
citeproc.util = util
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty 2025-04-29 19:47:32 UTC (rev 75059)
@@ -21,6 +21,8 @@
}
}
+\NewCommandCopy \autocite \cite
+
\NewDocumentCommand \parencite { s o o m }
{
\IfBooleanTF {#1}
@@ -49,12 +51,16 @@
\NewDocumentCommand \cites { }
{ \__csl_cites: }
+\NewDocumentCommand \parencites { }
+ { \__csl_cites: }
+
\NewDocumentCommand \citeauthor { o o m }
{ \__csl_cite_in_text:nnnn {#1} {#2} {#3} { author-only } }
-\NewDocumentCommand \citeyear{ o o m }
+\NewDocumentCommand \citeyear { o o m }
{ \__csl_cite_in_text:nnnn {#1} {#2} {#3} { cite-year } }
+
% Suppresses the author (from `natbib`).
\NewDocumentCommand \citeyearpar { o o m }
{ \__csl_cite_in_text:nnnn {#1} {#2} {#3} { suppress-author } }
@@ -66,6 +72,7 @@
\seq_new:N \l__csl_cite_keys_seq
\seq_new:N \l__csl_citation_items_seq
\prop_new:N \l__csl_citation_properties_prop
+\bool_new:N \l__csl_citation_unsorted_bool
\prop_new:N \l__csl_citation_info_prop
% #1: prenote
@@ -193,6 +200,7 @@
\seq_clear:N \l__csl_cite_keys_seq
\seq_clear:N \l__csl_citation_items_seq
\prop_clear:N \l__csl_citation_properties_prop
+ \bool_set_false:N \l__csl_citation_unsorted_bool
\tl_clear:N \l__csl_cite_prefix_tl
\tl_clear:N \l__csl_cite_suffix_tl
}
@@ -342,6 +350,7 @@
volume .code:n = { \__csl_set_locator:nn { volume } {#1} } ,
% Citation properties
infix .prop_put:N = \l__csl_citation_properties_prop,
+ unsorted .bool_set:N = \l__csl_citation_unsorted_bool
}
@@ -359,6 +368,10 @@
\prop_put:NnV \l__csl_citation_properties_prop { noteIndex } \l__csl_note_index_tl
\__csl_make_chapter_property:
\__csl_add_back_ref_info:
+ \bool_if:NT \l__csl_citation_unsorted_bool
+ {
+ \prop_put:Nnn \l__csl_citation_properties_prop { unsorted } { true }
+ }
}
\cs_new:Npn \__csl_make_chapter_property:
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty 2025-04-29 19:47:32 UTC (rev 75059)
@@ -8,7 +8,6 @@
% ### `babel`
-% This should be disabled.
\hook_gput_code:nnn { package / babel / after } { . }
{
\RenewDocumentCommand \nocite { m }
@@ -21,6 +20,31 @@
\cs_set_eq:NN \bbl at cite@choice \relax
\cs_set_eq:NN \@lbibitem \__csl_lbibitem_plain:nn
\cs_set_eq:NN \@bibitem \__csl_bibitem_plain:n
+ %
+ \cs_set:Npn \__csl_get_locale_from_babel:
+ {
+ % `babel`'s main language
+ \tl_if_exist:NT \bbl at main@language
+ {
+ \prop_get:NVNTF \l__csl_language_code_map_prop \bbl at main@language
+ \l__csl_locale_tl
+ {
+ \msg_info:nnVV { citation-style-language }
+ { locale-from-babel-language } \l__csl_locale_tl
+ \bbl at main@language
+ }
+ {
+ \msg_warning:nnV { citation-style-language }
+ { unrecognized-babel-language } \bbl at main@language
+ \tl_clear:N \l__csl_locale_tl
+ }
+ }
+ }
+ %
+ \msg_new:nnn { citation-style-language } { locale-from-babel-language }
+ { CSL~ locale~ "#1"~ from~ babel~ language~ "#2". }
+ \msg_new:nnn { citation-style-language } { unrecognized-babel-language }
+ { Unrecognized~ babel~ language~ "#1". }
}
@@ -97,29 +121,6 @@
% ### `hyperref`
-% The hyperref package also patches \bibcite but it cannot provide hyperlinks
-% when used with csl.
-\bool_new:N \l__csl_hyperref_loaded_bool
-\hook_gput_code:nnn { package / hyperref / after } { . }
- {
- \bool_set_true:N \l__csl_hyperref_loaded_bool
- % Pakcage "hyperref" redefines \@lbibitem and \bibitem and we need to
- % recover them.
- % In non-implicit mode (e.g., loaded by `beamer`), hyperref stops early
- % (`\MaybeStopEarly`) and it doesn't redefine the cite internal commands.
- \cs_if_exist:NT \@extra at b@citeb
- {
- \cs_gset_eq:NN \cslcite \__csl_hyperref_cite_item:nn
- \cs_gset_eq:NN \@lbibitem \__csl_lbibitem:
- \cs_gset_eq:NN \@bibitem \__csl_bibitem:
- \cs_gset_eq:NN \__csl_lbibitem_plain:nn \__csl_hyperref_lbibitem:nn
- \cs_gset_eq:NN \__csl_bibitem_plain:n \__csl_hyperref_bibitem:n
- \cs_gset_eq:NN \__csl_process_entry_ids:n \__csl_hyperref_process_entry_ids:n
- \cs_gset_eq:NN \__csl_process_excluded_ids:n \__csl_hyperref_process_excluded_ids:n
- \cs_gset_eq:NN \__csl_read_entry_ids: \__csl_hyperref_read_entry_ids:
- }
- }
-
\clist_new:N \l__csl_ref_section_entry_ids_clist
\clist_new:N \l__csl_ref_section_excluded_ids_clist
@@ -251,7 +252,33 @@
{ \clist_set:NV \l__csl_ref_section_excluded_ids_clist \l_tmpa_tl }
}
+\bool_new:N \l__csl_hyperref_loaded_bool
+% If `hyperref` is loaded before `csl`, the following code is executed
+% immediately via a one-time hook.
+% Thus we should put it after all of the previous definitions
+% (<https://github.com/zepinglee/citeproc-lua/issues/91>).
+\hook_gput_code:nnn { package / hyperref / after } { . }
+ {
+ \bool_set_true:N \l__csl_hyperref_loaded_bool
+ % Package `hyperref` redefines \@lbibitem and \bibitem and we need to
+ % recover them.
+ % In non-implicit mode (e.g., loaded by `beamer`), hyperref stops early
+ % (`\MaybeStopEarly`) and it doesn't redefine the cite internal commands.
+ \cs_if_exist:NT \@extra at b@citeb
+ {
+ \cs_gset_eq:NN \cslcite \__csl_hyperref_cite_item:nn
+ \cs_gset_eq:NN \@lbibitem \__csl_lbibitem:
+ \cs_gset_eq:NN \@bibitem \__csl_bibitem:
+ \cs_gset_eq:NN \__csl_lbibitem_plain:nn \__csl_hyperref_lbibitem:nn
+ \cs_gset_eq:NN \__csl_bibitem_plain:n \__csl_hyperref_bibitem:n
+ \cs_gset_eq:NN \__csl_process_entry_ids:n \__csl_hyperref_process_entry_ids:n
+ \cs_gset_eq:NN \__csl_process_excluded_ids:n \__csl_hyperref_process_excluded_ids:n
+ \cs_gset_eq:NN \__csl_read_entry_ids: \__csl_hyperref_read_entry_ids:
+ }
+ }
+
+
% ### `perpage`
\hook_gput_code:nnn { package / perpage / after } { . }
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty 2025-04-29 19:47:32 UTC (rev 75059)
@@ -279,13 +279,7 @@
\clist_clear:N \l_tmpa_clist % list of options to write to aux file
% locale
\tl_if_empty:NT \l__csl_locale_tl
- {
- \tl_if_exist:NT \bbl at main@language
- {
- \prop_get:NVN \l__csl_language_code_map_prop \bbl at main@language
- \l__csl_locale_tl
- }
- }
+ { \__csl_get_locale_from_babel: }
\tl_if_empty:NF \l__csl_locale_tl
{
\clist_put_right:Ne \l_tmpa_clist
@@ -303,6 +297,9 @@
}
}
+% This is the hook for `babel` package.
+\cs_new:Npn \__csl_get_locale_from_babel: { }
+
\cs_new:Npn \__csl_write_aux_options:n #1
{
\if at filesw
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty 2025-04-29 19:47:32 UTC (rev 75059)
@@ -9,10 +9,9 @@
\RequirePackage{expl3}
\RequirePackage{xparse}
-\ProvidesExplPackage {citation-style-language} {2025-02-23} {0.7.0}
+\ProvidesExplPackage {citation-style-language} {2025-04-29} {0.8.0}
{Citation Style Language for LaTeX}
-\RequirePackage { l3keys2e }
\RequirePackage { url }
@@ -148,7 +147,7 @@
}
-\ProcessKeysPackageOptions { csl }
+\ProcessKeyOptions [ csl ]
\DeclareDocumentCommand \bibliographystyle { m }
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-ro-RO.xml
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-ro-RO.xml 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-ro-RO.xml 2025-04-29 19:47:32 UTC (rev 75059)
@@ -32,7 +32,7 @@
<term name="loc-cit">loc. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
<term name="no-place">fără loc</term>
<term name="no-place" form="short">f. l.</term>
- <term name="no-publisher">fără editorr</term> <!-- sine nomine -->
+ <term name="no-publisher">fără editor</term> <!-- sine nomine -->
<term name="no-publisher" form="short">f. e.</term>
<term name="on">pe</term>
<term name="op-cit">op. cit.</term> <!-- like ibid., the abbreviated form is the regular form -->
@@ -45,7 +45,7 @@
<term name="radio-series">serie radio</term>
<term name="radio-series-episode">episod de serie radio</term>
<term name="special-issue">număr special</term>
- <term name="special-section">secțiune special</term>
+ <term name="special-section">secțiune specială</term>
<term name="television-broadcast">emisiune de televiziune</term>
<term name="television-series">serial televizat</term>
<term name="television-series-episode">episod al serialului televizat</term>
@@ -77,7 +77,7 @@
<term name="first-reference-note-number" form="short">cf.</term>
<term name="number" form="short">nr.</term>
<term name="edition" form="short">ed.</term>
- <term name="et-al">și colab.</term>
+ <term name="et-al">et al.</term> <!-- Romanian translation of this Latin expression is never used in Romanian styles -->
<term name="forthcoming">în curs de apariție</term>
<term name="from">din</term>
<term name="ibid">ibidem</term>
@@ -184,7 +184,7 @@
<term name="close-quote">”</term>
<term name="open-inner-quote">«</term>
<term name="close-inner-quote">»</term>
- <term name="page-range-delimiter">–</term>
+ <term name="page-range-delimiter">-</term>
<term name="colon">:</term>
<term name="comma">,</term>
<term name="semicolon">;</term>
@@ -394,7 +394,7 @@
</term>
<term name="number-of-volumes" form="short">
<single>vol.</single>
- <multiple>vols.</multiple>
+ <multiple>vol.</multiple>
</term>
<term name="page-first" form="short">
<single>p.</single>
@@ -402,7 +402,7 @@
</term>
<term name="printing" form="short">
<single>print.</single>
- <multiple>prints.</multiple>
+ <multiple>print.</multiple>
</term>
@@ -414,8 +414,8 @@
<term name="part" form="short">part.</term>
<term name="section" form="short">sec.</term>
<term name="supplement" form="short">
- <single>supp.</single>
- <multiple>supps.</multiple>
+ <single>suplim.</single>
+ <multiple>suplim.</multiple>
</term>
<term name="sub-verbo" form="short">
<single>s.v.</single>
@@ -454,8 +454,8 @@
<!-- LONG ROLE FORMS -->
<term name="collection-editor">
- <single>ed.</single>
- <multiple>eds.</multiple>
+ <single>editorul seriei</single>
+ <multiple>editorii seriei</multiple>
</term>
<term name="chair">
<single>președinte</single>
@@ -467,11 +467,11 @@
</term>
<term name="contributor">
<single>contributor</single>
- <multiple>contributorii</multiple>
+ <multiple>contributori</multiple>
</term>
<term name="curator">
<single>curator</single>
- <multiple>curators</multiple>
+ <multiple>curatori</multiple>
</term>
<term name="executive-producer">
<single>producător executiv</single>
@@ -483,7 +483,7 @@
</term>
<term name="host">
<single>gazdă</single>
- <multiple>gazdele</multiple>
+ <multiple>gazde</multiple>
</term>
<term name="narrator">
<single>narator</single>
@@ -544,8 +544,8 @@
<multiple>contrib.</multiple>
</term>
<term name="curator" form="short">
- <single>cur.</single>
- <multiple>cur.</multiple>
+ <single>curat.</single>
+ <multiple>curat.</multiple>
</term>
<term name="executive-producer" form="short">
<single>prod. exec.</single>
@@ -557,23 +557,23 @@
</term>
<term name="organizer" form="short">
<single>org.</single>
- <multiple>orgs.</multiple>
+ <multiple>org.</multiple>
</term>
<term name="performer" form="short">
- <single>perf.</single>
- <multiple>perfs.</multiple>
+ <single>interpr.</single>
+ <multiple>interpr..</multiple>
</term>
<term name="producer" form="short">
<single>prod.</single>
- <multiple>prods.</multiple>
+ <multiple>prod.</multiple>
</term>
<term name="script-writer" form="short">
- <single>writ.</single>
- <multiple>writs.</multiple>
+ <single>scriit.</single>
+ <multiple>scriit.</multiple>
</term>
<term name="series-creator" form="short">
- <single>cre.</single>
- <multiple>cres.</multiple>
+ <single>ed. col.</single>
+ <multiple>ed. col.</multiple>
</term>
<term name="director" form="short">
<single>dir.</single>
@@ -602,23 +602,23 @@
<!-- VERB ROLE FORMS -->
<term name="collection-editor" form="verb">editat de</term>
- <term name="chair" form="verb">chaired by</term>
- <term name="compiler" form="verb">compiled by</term>
- <term name="contributor" form="verb">alături de</term>
- <term name="curator" form="verb">verificat de</term>
+ <term name="chair" form="verb">condus de</term>
+ <term name="compiler" form="verb">compilat de</term>
+ <term name="contributor" form="verb">cu contribuția</term>
+ <term name="curator" form="verb">curator</term>
<term name="executive-producer" form="verb">produs executiv de</term>
<term name="guest" form="verb">cu invitatul</term>
<term name="host" form="verb">găzduit de</term>
<term name="narrator" form="verb">narat de</term>
<term name="organizer" form="verb">organizat de</term>
- <term name="performer" form="verb">performed by</term>
+ <term name="performer" form="verb">realizat de</term>
<term name="producer" form="verb">produs de</term>
<term name="script-writer" form="verb">scris de</term>
- <term name="series-creator" form="verb">creat de</term>
+ <term name="series-creator" form="verb">colecție editată de</term>
<term name="container-author" form="verb">de</term>
<term name="director" form="verb">coordonat de</term>
<term name="editor" form="verb">ediție de</term>
- <term name="editorial-director" form="verb">coordonator</term>
+ <term name="editorial-director" form="verb">coordonat de</term>
<term name="illustrator" form="verb">ilustrații de</term>
<term name="interviewer" form="verb">interviu de</term>
<term name="recipient" form="verb">în</term>
@@ -630,21 +630,21 @@
<!-- SHORT VERB ROLE FORMS -->
<term name="compiler" form="verb-short">comp. de</term>
<term name="contributor" form="verb-short">cu</term>
- <term name="curator" form="verb-short">cur. by</term>
+ <term name="curator" form="verb-short">cur.</term>
<term name="executive-producer" form="verb-short">prod. exec. de</term>
- <term name="guest" form="verb-short">w. guest</term>
- <term name="host" form="verb-short">hosted by</term>
+ <term name="guest" form="verb-short">cu invit.</term>
+ <term name="host" form="verb-short">găzd. de</term>
<term name="narrator" form="verb-short">nar. de</term>
- <term name="organizer" form="verb-short">org. by</term>
- <term name="performer" form="verb-short">perf. by</term>
+ <term name="organizer" form="verb-short">org. de</term>
+ <term name="performer" form="verb-short">interpr. de</term>
<term name="producer" form="verb-short">prod. de</term>
- <term name="script-writer" form="verb-short">scr. de</term>
- <term name="series-creator" form="verb-short">cre. de</term>
+ <term name="script-writer" form="verb-short">scen. de</term>
+ <term name="series-creator" form="verb-short">ed. col. de</term>
<term name="director" form="verb-short">dir.</term>
- <term name="editor" form="verb-short">ed.</term>
- <term name="editorial-director" form="verb-short">coord.</term>
- <term name="illustrator" form="verb-short">ilustr.</term>
- <term name="translator" form="verb-short">trad.</term>
+ <term name="editor" form="verb-short">ed. de</term>
+ <term name="editorial-director" form="verb-short">coord. de</term>
+ <term name="illustrator" form="verb-short">ilustr. de</term>
+ <term name="translator" form="verb-short">trad. de</term>
<term name="editortranslator" form="verb-short">ed. și trad. de</term>
<!-- LONG MONTH FORMS -->
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-th-TH.xml
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-th-TH.xml 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/locales/csl-locales-th-TH.xml 2025-04-29 19:47:32 UTC (rev 75059)
@@ -4,6 +4,9 @@
<translator>
<name>Dusit Laohasinnarong</name>
</translator>
+ <translator>
+ <name>Watcharakorn Kaobath</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>2012-07-04T23:31:02+00:00</updated>
</info>
@@ -52,7 +55,7 @@
<term name="anonymous">นิรนาม</term>
<term name="anonymous" form="short">นิรนาม</term>
<term name="at">ที่</term>
- <term name="available at">available at</term>
+ <term name="available at">เข้าถึงได้จาก</term>
<term name="by">โดย</term>
<term name="circa">โดยประมาณ</term>
<term name="circa" form="short">ประมาณ</term>
Modified: trunk/Master/texmf-dist/tex/latex/citation-style-language/styles/modern-humanities-research-association.csl
===================================================================
--- trunk/Master/texmf-dist/tex/latex/citation-style-language/styles/modern-humanities-research-association.csl 2025-04-29 19:46:50 UTC (rev 75058)
+++ trunk/Master/texmf-dist/tex/latex/citation-style-language/styles/modern-humanities-research-association.csl 2025-04-29 19:47:32 UTC (rev 75059)
@@ -1,37 +1,37 @@
<?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">
+<style xmlns="http://purl.org/net/xbiblio/csl" and="text" class="note" demote-non-dropping-particle="sort-only" et-al-min="4" et-al-use-first="1" page-range-format="minimal-two" version="1.0" default-locale="en-GB">
<info>
- <title>Modern Humanities Research Association 4th 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"/>
- <link href="http://www.mhra.org.uk/Publications/Books/StyleGuide/download.shtml" rel="documentation"/>
+ <link href="https://www.mhra.org.uk/style/" rel="documentation"/>
<author>
<name>Rintze Zelle</name>
- <uri>http://twitter.com/rintzezelle</uri>
+ <uri>https://orcid.org/0000-0003-1779-8883</uri>
</author>
+ <author>
+ <name>Andrew Dunning</name>
+ <uri>https://orcid.org/0000-0003-0464-5036</uri>
+ </author>
<contributor>
<name>Sebastian Karcher</name>
+ <uri>https://orcid.org/0000-0001-8249-7388</uri>
</contributor>
<contributor>
- <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>2024-10-30T12:10:40-04:00</updated>
+ <category field="humanities"/>
+ <summary>MHRA Style Guide full notes and bibliography</summary>
+ <updated>2025-03-19T08:12:42-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">
<terms>
<term name="et-al">and others</term>
- <term name="editor" form="verb-short">ed. by</term>
- <term name="edition" form="short">edn</term>
- <term name="translator" form="verb-short">trans. by</term>
+ <term form="short" name="edition">edn</term>
<term name="folio">
<single>fol.</single>
<multiple>fols</multiple>
@@ -38,27 +38,35 @@
</term>
</terms>
</locale>
- <macro name="author">
- <group delimiter=". ">
- <names variable="author">
- <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=", " suffix="."/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- <text macro="title-note"/>
- </substitute>
- </names>
- <text macro="recipient"/>
- </group>
+ <macro name="title-sort-substitute">
+ <choose>
+ <if match="any" type="bill book graphic legal_case legislation motion_picture report song">
+ <text font-style="italic" form="short" text-case="title" variable="title"/>
+ </if>
+ <else>
+ <text form="short" quotes="true" text-case="title" variable="title"/>
+ </else>
+ </choose>
</macro>
+ <macro name="recipient-short">
+ <names variable="recipient">
+ <label form="verb" suffix=" "/>
+ <name form="short"/>
+ </names>
+ </macro>
<macro name="recipient">
+ <names variable="recipient">
+ <label form="verb" suffix=" "/>
+ <name/>
+ </names>
+ </macro>
+ <macro name="communication-recipient">
<group delimiter=" ">
<choose>
<if type="personal_communication">
<choose>
<if variable="genre">
- <text variable="genre" text-case="capitalize-first"/>
+ <text text-case="capitalize-first" variable="genre"/>
</if>
<else>
<text term="letter" text-case="capitalize-first"/>
@@ -66,245 +74,297 @@
</choose>
</if>
</choose>
- <text macro="recipient-note"/>
+ <text macro="recipient"/>
</group>
</macro>
+ <macro name="contributors-short">
+ <group delimiter=" ">
+ <names variable="author">
+ <name form="short"/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <text macro="title-sort-substitute"/>
+ </substitute>
+ </names>
+ <text macro="recipient-short"/>
+ </group>
+ </macro>
<macro name="contributors-note">
- <names variable="author">
- <name and="text" sort-separator=", " delimiter=", "/>
- <label form="short" prefix=", "/>
- <substitute>
- <text macro="title-note"/>
- </substitute>
- </names>
- <text macro="recipient-note"/>
+ <group delimiter=" ">
+ <names variable="author">
+ <label form="short" prefix=", "/>
+ <substitute>
+ <text macro="title"/>
+ </substitute>
+ </names>
+ <text macro="recipient"/>
+ </group>
</macro>
- <macro name="title-note">
- <choose>
- <if variable="title" match="none">
- <text variable="genre"/>
- </if>
- <else-if type="bill book graphic legislation motion_picture report song" match="any">
- <text variable="title" text-case="title" font-style="italic"/>
- <group delimiter=" " prefix=", ">
- <text term="version"/>
- <text variable="version"/>
- </group>
- </else-if>
- <else-if type="legal_case interview" match="any">
- <text variable="title"/>
- </else-if>
- <else-if variable="reviewed-author">
- <text variable="title" font-style="italic" prefix="review of "/>
- </else-if>
- <else>
- <text variable="title" text-case="title" quotes="true"/>
- </else>
- </choose>
+ <macro name="contributors">
+ <group delimiter=". ">
+ <names variable="author">
+ <name delimiter-precedes-last="always" name-as-sort-order="first"/>
+ <label form="short" prefix=", "/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <text macro="title"/>
+ </substitute>
+ </names>
+ <text macro="communication-recipient"/>
+ </group>
</macro>
<macro name="title-subsequent">
<choose>
- <if variable="title" match="none">
+ <if match="none" variable="title">
<text macro="issued"/>
</if>
- <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
- <text variable="title" font-style="italic" text-case="title" form="short"/>
+ <else-if match="any" type="bill book graphic legal_case legislation motion_picture report song">
+ <text font-style="italic" form="short" text-case="title" variable="title"/>
</else-if>
<else>
- <text variable="title" quotes="true" text-case="title" form="short"/>
+ <text form="short" quotes="true" text-case="title" variable="title"/>
</else>
</choose>
</macro>
- <macro name="title-sort-substitute">
+ <macro name="title">
<choose>
- <if type="bill book graphic legal_case legislation motion_picture report song" match="any">
- <text variable="title" font-style="italic" text-case="title" form="short"/>
+ <if match="none" variable="title">
+ <text variable="genre"/>
</if>
+ <else-if match="any" type="bill book graphic legislation motion_picture report song">
+ <group delimiter=", ">
+ <text font-style="italic" text-case="title" variable="title"/>
+ <group delimiter=" ">
+ <text term="version"/>
+ <text variable="version"/>
+ </group>
+ </group>
+ </else-if>
+ <else-if match="any" type="legal_case interview">
+ <text variable="title"/>
+ </else-if>
+ <else-if variable="reviewed-author">
+ <text font-style="italic" prefix="review of " variable="title"/>
+ </else-if>
<else>
- <text variable="title" quotes="true" text-case="title" form="short"/>
+ <text quotes="true" text-case="title" variable="title"/>
</else>
</choose>
</macro>
<macro name="editor-translator">
<group delimiter=", ">
- <group delimiter=" ">
- <choose>
- <if variable="container-author reviewed-author" match="any">
- <group>
- <names variable="container-author reviewed-author">
- <label form="verb-short" text-case="lowercase" suffix=" "/>
- <name and="text" delimiter=", "/>
- </names>
- </group>
- </if>
- </choose>
- </group>
- <names variable="editor translator director" delimiter=", ">
- <label form="verb-short" text-case="lowercase" suffix=" "/>
- <name and="text" delimiter=", "/>
+ <choose>
+ <if match="any" variable="container-author reviewed-author">
+ <names delimiter=", " variable="container-author reviewed-author">
+ <label form="verb-short" suffix=" "/>
+ <name/>
+ </names>
+ </if>
+ </choose>
+ <names delimiter=", " variable="editor translator director">
+ <label form="verb-short" suffix=" "/>
+ <name/>
</names>
</group>
</macro>
- <macro name="secondary-contributors-note">
+ <macro name="secondary-contributors">
<choose>
- <if type="chapter paper-conference" match="none">
+ <if match="none" type="chapter entry-dictionary entry-encyclopedia paper-conference">
<text macro="editor-translator"/>
</if>
</choose>
</macro>
- <macro name="container-contributors-note">
- <choose>
- <if type="chapter paper-conference" match="any">
- <text macro="editor-translator"/>
- </if>
- </choose>
- </macro>
- <macro name="collection-title">
- <group delimiter=", ">
+ <macro name="container-title">
+ <group delimiter=" ">
<choose>
- <if type="article-journal">
- <text variable="collection-title"/>
- <text variable="collection-number"/>
+ <if match="any" type="chapter entry-dictionary entry-encyclopedia paper-conference">
+ <text term="in"/>
</if>
- <else>
- <text variable="collection-title" text-case="title"/>
- <text variable="collection-number"/>
- </else>
</choose>
+ <text font-style="italic" text-case="title" variable="container-title"/>
</group>
</macro>
- <macro name="locators-note">
+ <macro name="container-contributors">
<choose>
- <if type="article-journal">
- <group delimiter=".">
- <text variable="volume"/>
- <text variable="issue"/>
- </group>
+ <if match="any" type="chapter entry-dictionary entry-encyclopedia paper-conference">
+ <text macro="editor-translator"/>
</if>
- <else-if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
- <group delimiter=", ">
- <text macro="edition-note"/>
- <group>
- <number variable="number-of-volumes" form="numeric"/>
- <text term="volume" form="short" prefix=" " plural="true"/>
- </group>
- </group>
- </else-if>
</choose>
</macro>
- <macro name="volume">
+ <macro name="edition">
<choose>
+ <if match="any" type="bill book chapter entry-dictionary entry-encyclopedia graphic legal_case legislation motion_picture paper-conference report song">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" ">
+ <number form="ordinal" variable="edition"/>
+ <text form="short" term="edition"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="locators">
+ <choose>
<if type="article-journal">
- <group delimiter=".">
- <text variable="volume"/>
- <text variable="issue"/>
+ <group delimiter=", ">
+ <text variable="collection-title"/>
+ <choose>
+ <if variable="volume">
+ <group delimiter=".">
+ <text variable="volume"/>
+ <text variable="issue"/>
+ </group>
+ </if>
+ <else>
+ <group delimiter=" ">
+ <text form="short" term="issue"/>
+ <text variable="issue"/>
+ </group>
+ </else>
+ </choose>
</group>
</if>
- <else-if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
+ <else-if match="any" type="bill book chapter entry-dictionary entry-encyclopedia graphic legal_case legislation motion_picture paper-conference report song">
<group delimiter=", ">
- <text macro="edition-note"/>
- <group>
- <number variable="number-of-volumes" form="numeric"/>
- <text term="volume" form="short" prefix=" " plural="true"/>
+ <group delimiter=", ">
+ <text text-case="title" variable="collection-title"/>
+ <text variable="collection-number"/>
</group>
+ <text macro="edition"/>
+ <group delimiter=" ">
+ <number form="numeric" variable="number-of-volumes"/>
+ <text form="short" plural="true" term="volume"/>
+ </group>
</group>
</else-if>
</choose>
</macro>
- <macro name="issue-note">
+ <macro name="event">
+ <group delimiter=" ">
+ <text term="presented at"/>
+ <text variable="event"/>
+ </group>
+ </macro>
+ <macro name="publisher">
<choose>
- <if type="article-journal">
+ <if type="thesis">
+ <text variable="publisher"/>
+ </if>
+ <else>
<choose>
- <if variable="volume">
- <text macro="issued" prefix=" (" suffix=")"/>
+ <if match="none" variable="publisher">
+ <text variable="publisher-place"/>
</if>
<else>
- <text macro="issued" prefix=", "/>
+ <text variable="publisher"/>
</else>
</choose>
- </if>
- <else-if variable="publisher-place publisher" match="any">
- <group prefix=" (" suffix=")" delimiter=", ">
- <group delimiter=" ">
- <choose>
- <if variable="title" match="none"/>
- <else-if type="thesis speech" match="any">
- <text variable="genre" prefix="unpublished "/>
- </else-if>
- </choose>
- <text macro="event"/>
- </group>
- <text macro="publisher"/>
- <text macro="issued"/>
- </group>
- </else-if>
- <else>
- <text macro="issued" prefix=", "/>
</else>
</choose>
</macro>
- <macro name="locators-specific-note">
+ <macro name="issued">
<choose>
- <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
+ <if match="any" type="report article-newspaper article-magazine personal_communication">
+ <date form="text" variable="issued"/>
+ </if>
+ <else-if match="any" type="article-journal book bill chapter legislation motion_picture paper-conference song thesis">
<choose>
- <if is-numeric="volume">
- <number variable="volume" form="roman" font-variant="small-caps"/>
+ <if is-uncertain-date="issued">
+ <date date-parts="year" form="numeric" prefix="[" suffix="?]" variable="issued"/>
</if>
<else>
- <text variable="volume" font-variant="small-caps"/>
+ <date date-parts="year" form="numeric" variable="issued"/>
</else>
</choose>
+ </else-if>
+ <else>
+ <choose>
+ <if is-uncertain-date="issued">
+ <date form="text" prefix="[" suffix="?]" variable="issued"/>
+ </if>
+ <else>
+ <date form="text" variable="issued"/>
+ </else>
+ </choose>
+ </else>
+ </choose>
+ </macro>
+ <macro name="issue-join-with-space">
+ <choose>
+ <if type="article-journal" variable="volume">
+ <text macro="issue"/>
</if>
+ <else-if type="article-journal" variable="issue">
+ <text macro="issue"/>
+ </else-if>
+ <else-if match="any" variable="publisher-place publisher">
+ <text macro="issue"/>
+ </else-if>
</choose>
</macro>
- <macro name="container-title-note">
+ <macro name="issue-join-with-comma">
<choose>
- <if type="chapter paper-conference" match="any">
- <text term="in" suffix=" "/>
+ <if type="article-journal">
+ <choose>
+ <if match="none" variable="volume issue">
+ <text macro="issue"/>
+ </if>
+ </choose>
</if>
+ <else-if match="none" variable="publisher-place publisher">
+ <text macro="issue"/>
+ </else-if>
</choose>
- <text variable="container-title" text-case="title" font-style="italic"/>
</macro>
- <macro name="edition-note">
+ <macro name="issue">
<choose>
- <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
+ <if type="article-journal">
<choose>
- <if is-numeric="edition">
- <group delimiter=" ">
- <number variable="edition" form="ordinal"/>
- <text term="edition" form="short"/>
- </group>
+ <if match="any" variable="volume issue">
+ <text macro="issued" prefix="(" suffix=")"/>
</if>
<else>
- <text variable="edition"/>
+ <text macro="issued"/>
</else>
</choose>
</if>
+ <else-if match="any" variable="publisher-place publisher">
+ <group delimiter=", " prefix="(" suffix=")">
+ <group delimiter=" ">
+ <choose>
+ <if match="none" variable="title"/>
+ <else-if match="any" type="thesis speech">
+ <text prefix="unpublished " variable="genre"/>
+ </else-if>
+ </choose>
+ <text macro="event"/>
+ </group>
+ <text macro="publisher"/>
+ <text macro="issued"/>
+ </group>
+ </else-if>
+ <else>
+ <text macro="issued"/>
+ </else>
</choose>
</macro>
- <macro name="recipient-note">
- <names variable="recipient" delimiter=", ">
- <label form="verb" prefix=" " suffix=" "/>
- <name and="text" delimiter=", "/>
- </names>
+ <macro name="artwork">
+ <choose>
+ <if match="any" type="graphic">
+ <group delimiter=", ">
+ <text variable="medium"/>
+ <text variable="dimensions"/>
+ </group>
+ </if>
+ </choose>
</macro>
- <macro name="recipient-short">
- <names variable="recipient">
- <label form="verb" prefix=" " suffix=" "/>
- <name form="short" and="text" delimiter=", "/>
- </names>
- </macro>
- <macro name="contributors-short">
- <names variable="author">
- <name form="short" and="text" sort-separator=", " delimiter=", "/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- <text macro="title-sort-substitute"/>
- </substitute>
- </names>
- <text macro="recipient-short"/>
- </macro>
<macro name="locators-newspaper">
<choose>
<if type="article-newspaper">
@@ -313,8 +373,8 @@
<text variable="edition"/>
<text term="edition"/>
</group>
- <group>
- <text term="section" suffix=" "/>
+ <group delimiter=" ">
+ <text term="section"/>
<text variable="section"/>
</group>
</group>
@@ -321,79 +381,78 @@
</if>
</choose>
</macro>
- <macro name="event">
- <group>
- <text term="presented at" suffix=" "/>
- <text variable="event"/>
+ <macro name="pages">
+ <group delimiter=" ">
+ <label form="short" variable="page"/>
+ <text variable="page"/>
</group>
</macro>
- <macro name="publisher">
+ <macro name="volume-number-roman">
<choose>
- <if type="thesis">
- <text variable="publisher"/>
+ <if is-numeric="volume">
+ <number font-variant="small-caps" form="roman" variable="volume"/>
</if>
<else>
- <text variable="publisher"/>
+ <text font-variant="small-caps" variable="volume"/>
</else>
</choose>
</macro>
- <macro name="issued">
+ <macro name="point-locators-volume-note">
<choose>
- <if type="report article-newspaper article-magazine personal_communication" match="any">
- <date variable="issued">
- <date-part name="day" suffix=" "/>
- <date-part name="month" suffix=" "/>
- <date-part name="year"/>
- </date>
+ <if position="first" type="chapter entry-dictionary entry-encyclopedia paper-conference">
+ <group delimiter=", ">
+ <text macro="volume-number-roman"/>
+ <text font-style="italic" text-case="title" variable="volume-title"/>
+ </group>
</if>
- <else>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- </macro>
- <macro name="pages">
- <choose>
- <if type="article-journal">
- <group delimiter=" " prefix=", ">
- <label variable="page" form="short"/>
- <text variable="page"/>
+ <else-if type="book legislation motion_picture report">
+ <group delimiter=", ">
+ <text macro="volume-number-roman"/>
+ <choose>
+ <if position="first">
+ <text font-style="italic" text-case="title" variable="volume-title"/>
+ </if>
+ </choose>
</group>
- </if>
- <else>
- <choose>
- <if variable="volume">
- <text variable="page" prefix=", "/>
- </if>
- <else>
- <label variable="page" form="short" prefix=", " suffix=" "/>
- <text variable="page"/>
- </else>
- </choose>
- </else>
+ </else-if>
</choose>
</macro>
- <macro name="point-locators">
- <text macro="pages"/>
+ <macro name="point-locators-volume">
<choose>
- <if variable="page">
- <group prefix=" (" suffix=")">
- <label variable="locator" form="short" suffix=" "/>
- <text variable="locator"/>
+ <if type="bill book chapter entry-dictionary entry-encyclopedia graphic legal_case legislation motion_picture paper-conference report song">
+ <group delimiter=", ">
+ <text macro="volume-number-roman"/>
+ <text font-style="italic" text-case="title" variable="volume-title"/>
</group>
</if>
- <else>
- <label variable="locator" form="short" prefix=", " suffix=" "/>
- <text variable="locator"/>
- </else>
</choose>
</macro>
<macro name="point-locators-subsequent">
- <label variable="locator" form="short" prefix=", " suffix=" "/>
- <text variable="locator"/>
+ <group delimiter=" ">
+ <label form="short" variable="locator"/>
+ <text variable="locator"/>
+ </group>
</macro>
- <macro name="archive-note">
+ <macro name="point-locators">
+ <group delimiter=" ">
+ <text macro="pages"/>
+ <choose>
+ <if variable="page">
+ <group delimiter=" " prefix="(" suffix=")">
+ <label form="short" variable="locator"/>
+ <text variable="locator"/>
+ </group>
+ </if>
+ <else>
+ <group delimiter=" ">
+ <label form="short" variable="locator"/>
+ <text variable="locator"/>
+ </group>
+ </else>
+ </choose>
+ </group>
+ </macro>
+ <macro name="archive">
<group delimiter=", ">
<text variable="archive-place"/>
<text variable="archive"/>
@@ -400,96 +459,106 @@
<text variable="archive_location"/>
</group>
</macro>
- <macro name="access-note">
+ <macro name="access">
<group delimiter=", ">
<choose>
- <if type="article-journal bill chapter legal_case legislation paper-conference" match="none">
- <text macro="archive-note" prefix=", "/>
+ <if match="none" type="article-journal bill chapter legal_case legislation paper-conference">
+ <text macro="archive"/>
</if>
</choose>
+ <choose>
+ <if variable="DOI">
+ <text prefix="doi:" variable="DOI"/>
+ </if>
+ </choose>
</group>
+ </macro>
+ <macro name="URL">
<choose>
- <if variable="DOI">
- <text variable="DOI" prefix=", doi:"/>
- </if>
- <else>
+ <if match="none" variable="DOI">
<choose>
<if variable="URL">
- <text variable="URL" prefix=" <" suffix=">"/>
- <group prefix=" [" suffix="]">
- <text term="accessed"/>
- <date variable="accessed">
- <date-part name="day" prefix=" "/>
- <date-part name="month" prefix=" "/>
- <date-part name="year" prefix=" "/>
- </date>
+ <group delimiter=" ">
+ <text prefix="<" suffix=">" variable="URL"/>
+ <choose>
+ <if match="none" variable="issued">
+ <group delimiter=" " prefix="[" suffix="]">
+ <text term="accessed"/>
+ <date form="text" variable="accessed"/>
+ </group>
+ </if>
+ </choose>
</group>
</if>
</choose>
- </else>
- </choose>
- </macro>
- <macro name="artwork">
- <choose>
- <if type="graphic" match="any">
- <group delimiter=", ">
- <text variable="medium"/>
- <text variable="dimensions"/>
- </group>
</if>
</choose>
</macro>
- <citation et-al-min="4" et-al-use-first="1" disambiguate-add-names="true" disambiguate-add-givenname="true">
- <layout suffix="." delimiter="; ">
+ <citation disambiguate-add-givenname="true" disambiguate-add-names="true">
+ <layout delimiter="; " suffix=".">
<choose>
<if position="subsequent">
<group delimiter=", ">
<text macro="contributors-short"/>
<text macro="title-subsequent"/>
- <text macro="locators-specific-note"/>
+ <text macro="point-locators-volume-note"/>
+ <text macro="point-locators-subsequent"/>
</group>
- <text macro="point-locators-subsequent"/>
</if>
<else>
- <group delimiter=", ">
- <text macro="contributors-note"/>
- <text macro="title-note"/>
- <text macro="secondary-contributors-note"/>
- <text macro="container-title-note"/>
- <text macro="container-contributors-note"/>
- <text macro="collection-title"/>
- <text macro="locators-note"/>
+ <group delimiter=" ">
+ <group delimiter=", ">
+ <group delimiter=" ">
+ <group delimiter=", ">
+ <text macro="contributors-note"/>
+ <text macro="title"/>
+ <text macro="secondary-contributors"/>
+ <text macro="container-title"/>
+ <text macro="container-contributors"/>
+ <text macro="locators"/>
+ </group>
+ <text macro="issue-join-with-space"/>
+ </group>
+ <text macro="issue-join-with-comma"/>
+ <text macro="point-locators-volume-note"/>
+ <text macro="locators-newspaper"/>
+ <text macro="point-locators"/>
+ <text macro="access"/>
+ </group>
+ <text macro="URL"/>
</group>
- <text macro="issue-note"/>
- <text macro="locators-specific-note" prefix=", "/>
- <text macro="locators-newspaper" prefix=", "/>
- <text macro="point-locators"/>
- <text macro="access-note"/>
</else>
</choose>
</layout>
</citation>
- <bibliography hanging-indent="true" et-al-min="7" et-al-use-first="6" subsequent-author-substitute="———">
+ <bibliography delimiter-precedes-et-al="after-inverted-name" hanging-indent="true" subsequent-author-substitute="——">
<sort>
- <key macro="author"/>
+ <key macro="contributors"/>
<key variable="title"/>
</sort>
<layout>
- <group delimiter=", ">
- <text macro="author"/>
- <text macro="title-note"/>
- <text macro="secondary-contributors-note"/>
- <text macro="container-title-note"/>
- <text macro="container-contributors-note"/>
- <text macro="collection-title"/>
- <text macro="volume"/>
+ <group delimiter=" ">
+ <group delimiter=", ">
+ <group delimiter=" ">
+ <group delimiter=", ">
+ <text macro="contributors"/>
+ <text macro="title"/>
+ <text macro="secondary-contributors"/>
+ <text macro="container-title"/>
+ <text macro="container-contributors"/>
+ <text macro="locators"/>
+ </group>
+ <text macro="issue-join-with-space"/>
+ </group>
+ <text macro="issue-join-with-comma"/>
+ <text macro="point-locators-volume"/>
+ <text macro="artwork"/>
+ <text macro="locators-newspaper"/>
+ <text macro="pages"/>
+ <text macro="access"/>
+ </group>
+ <text macro="URL"/>
</group>
- <text macro="issue-note"/>
- <text macro="locators-specific-note" prefix=", "/>
- <text macro="artwork" prefix=", "/>
- <text macro="locators-newspaper" prefix=", "/>
- <text macro="pages"/>
- <text macro="access-note"/>
</layout>
</bibliography>
</style>
More information about the tex-live-commits
mailing list.