diff options
author | Karl Berry <karl@freefriends.org> | 2024-09-01 20:46:02 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-09-01 20:46:02 +0000 |
commit | ba22db1db9d53e12dff193c5ec6c02eeeacefc77 (patch) | |
tree | fb415e9ff2de570b8d22c76d10caaf1792fd6f71 /Master/texmf-dist | |
parent | 47033713446d65fe218881cd26bfa2880601864d (diff) |
citation-style-language (1sep24)
git-svn-id: svn://tug.org/texlive/trunk@72157 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
16 files changed, 328 insertions, 167 deletions
diff --git a/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md b/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md index 671e47d76e5..4a08dd63029 100644 --- a/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md +++ b/Master/texmf-dist/doc/latex/citation-style-language/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.6.3] - 2024-08-28 + +### Added + +- Add support for citation affixes. + +### Fixed + +- Fix `\ref` with underscore in citation affixes ([#74](https://github.com/zepinglee/citeproc-lua/issues/74)). + ## [0.6.2] - 2024-08-21 ### Added @@ -15,14 +25,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Fix note position in multiple chapters ([#72](https://github.com/zepinglee/citeproc-lua/discussions/72)). +- Fix note position in multiple chapters ([#72](https://github.com/zepinglee/citeproc-lua/issues/72)). - Fix incorrect locale map of UKenglish. ## [0.6.1] - 2024-08-15 ### Fixed -- Fix parsing quotation marks ([#71](https://github.com/zepinglee/citeproc-lua/discussions/71)). +- Fix parsing quotation marks ([#71](https://github.com/zepinglee/citeproc-lua/issues/71)). ## [0.6.0] - 2024-07-31 @@ -231,7 +241,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial CTAN release. -[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.2...HEAD +[Unreleased]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.3...HEAD +[0.6.3]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.2...v0.6.3 [0.6.2]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.1...v0.6.2 [0.6.1]: https://github.com/zepinglee/citeproc-lua/compare/v0.6.0...v0.6.1 [0.6.0]: https://github.com/zepinglee/citeproc-lua/compare/v0.5.1...v0.6.0 diff --git a/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf b/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf Binary files differindex ac336a3925f..1ca15f70276 100644 --- a/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf +++ b/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.pdf diff --git a/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex b/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex index 7522ad0664a..385fef912f5 100644 --- a/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex +++ b/Master/texmf-dist/doc/latex/citation-style-language/citation-style-language-doc.tex @@ -51,7 +51,7 @@ }% } -\date{2024-08-21 v0.6.2} +\date{2024-08-28 v0.6.3} \maketitle diff --git a/Master/texmf-dist/doc/man/man1/citeproc-lua.1 b/Master/texmf-dist/doc/man/man1/citeproc-lua.1 index 2c523ef3149..a23c8b7228a 100644 --- a/Master/texmf-dist/doc/man/man1/citeproc-lua.1 +++ b/Master/texmf-dist/doc/man/man1/citeproc-lua.1 @@ -1,4 +1,4 @@ -.TH citeproc-lua 1 "0.6.2" +.TH citeproc-lua 1 "0.6.3" .SH NAME citeproc-lua \- make CSL citations and bibliography for LaTeX .SH SYNOPSIS diff --git a/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf b/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf Binary files differindex c0d7cb013ec..6bbb9759bc3 100644 --- a/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf +++ b/Master/texmf-dist/doc/man/man1/citeproc-lua.man1.pdf diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua index c64f279e8e3..d1fdc99e02d 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-bibtex-data.lua @@ -4205,6 +4205,11 @@ return { csl = nil, source = "adrbirthday.bst", }, + citations = { + csl = nil, + source = "publist.dbx", + type = "literal", + }, }, macros = { acmcs = { diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua index 4bfab23c4ad..0f5e35c385d 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-engine.lua @@ -53,9 +53,20 @@ local Position = util.Position ---@alias ItemId string | number ---@alias NoteIndex integer ---@alias ChapterIndex number ----@alias CitationData {citationID: CitationId, citationItems: CitationItem[], properties: CitationProperties, citation_index: integer} ----@alias CitationProperties { noteIndex: NoteIndex, chapterIndex: ChapterIndex, mode: string? } +---@class CitationData +---@field citationID CitationId +---@field citationItems CitationItem[] +---@field properties CitationProperties +---@field citation_index integer + +---@class CitationProperties +---@field noteIndex NoteIndex, +---@field chapterIndex ChapterIndex, +---@field mode string? +---@field prefix string? +---@field suffix string? + ---@class NameVariable ---@field family string? @@ -94,15 +105,22 @@ local Registry = {} ---@class CiteProc ---@field style Style ----@field sys any ----@field locales Locale[] ----@field system_locales Locale[] ----@field lang string +---@field sys CiteProcSys +---@field locales table<LanguageCode, Locale> +---@field system_locales table<LanguageCode, Locale> +---@field lang LanguageCode ---@field output_format OutputFormat ---@field opt table ---@field registry Registry ---@field cite_first_note_numbers table<ItemId, NoteIndex> ----@field locale_tags_info_dict {[LanguageCode]: table} +---@field cite_last_note_numbers table<ItemId, NoteIndex> +---@field note_citations_map table<NoteIndex, CitationId[]> +---@field tainted_item_ids table<ItemId, boolean> +---@field disam_irs IrNode[] +---@field cite_irs_by_output table<string, IrNode[]> +---@field person_names PersonNameIr[] +---@field person_names_by_output table<string, PersonNameIr[]> +---@field locale_tags_info_dict table<LanguageCode, table> local CiteProc = {} ---@class CiteProcSys @@ -125,64 +143,61 @@ function CiteProc.new(sys, style, lang, force_lang) if sys.retrieveItem == nil then error("\"citeprocSys.retrieveItem\" required") end - ---@type CiteProc - local o = {} - - o.style = Style:parse(style) - - o.sys = sys - o.locales = {} - o.system_locales = {} - - o.lang = o.style.default_locale - if not o.lang or force_lang then - o.lang = lang or "en-US" + local parsed_style = Style:parse(style) + local engine_lang = parsed_style.default_locale + if not engine_lang or force_lang then + engine_lang = lang or "en-US" end - - o.output_format = LatexWriter:new() - - o.opt = { - -- Similar to citeproc-js's development_extensions.wrap_url_and_doi - wrap_url_and_doi = false, - citation_link = false, - title_link = false, - } - - o.registry = { - citations_by_id = {}, -- A map - citation_list = {}, -- A list - citations_by_item_id = {}, -- A map from item id to a map of citations - registry = {}, -- A map of bibliographic meta data - reflist = {}, -- list of cited ids - uncited_list = {}, - previous_citation = nil, - requires_sorting = false, - widest_label = "", - maxoffset = 0, + ---@type CiteProc + local o = { + style = parsed_style, + sys = sys, + locales = {}, + system_locales = {}, + lang = engine_lang, + output_format = LatexWriter:new(), + opt = { + -- Similar to citeproc-js's development_extensions.wrap_url_and_doi + wrap_url_and_doi = false, + citation_link = false, + title_link = false, + }, + registry = { + citations_by_id = {}, -- A map + citation_list = {}, -- A list + citations_by_item_id = {}, -- A map from item id to a map of citations + registry = {}, -- A map of bibliographic meta data + reflist = {}, -- list of cited ids + uncited_list = {}, + previous_citation = nil, + requires_sorting = false, + widest_label = "", + maxoffset = 0, + }, + + cite_first_note_numbers = {}, + cite_last_note_numbers = {}, + note_citations_map = {}, + + tainted_item_ids = {}, + + disam_irs = {}, + -- { <ir1>, <ir2>, ... } + + cite_irs_by_output = {}, + -- { + -- ["Roe, J"] = {<ir1>}, + -- ["Doe, J"] = {<ir2>, <ir3>}, + -- ["Doe, John"] = {<ir2>}, + -- ["Doe, Jack"] = {<ir2>}, + -- } + + person_names = {}, + person_names_by_output = {}, + + locale_tags_info_dict = {}, } - o.cite_first_note_numbers = {} - o.cite_last_note_numbers = {} - o.note_citations_map = {} - - o.tainted_item_ids = {} - - o.disam_irs = {} - -- { <ir1>, <ir2>, ... } - - o.cite_irs_by_output = {} - -- { - -- ["Roe, J"] = {<ir1>}, - -- ["Doe, J"] = {<ir2>, <ir3>}, - -- ["Doe, John"] = {<ir2>}, - -- ["Doe, Jack"] = {<ir2>}, - -- } - - o.person_names = {} - o.person_names_by_output = {} - - o.locale_tags_info_dict = {} - setmetatable(o, { __index = CiteProc }) return o end @@ -444,15 +459,11 @@ function CiteProc:normalize_cite_item(cite_item) -- Assert CSL rich-text or HTML-like tagged string if cite_item.prefix == "" then cite_item.prefix = nil - else - cite_item.prefix_inlines = InlineElement:parse(cite_item.prefix, the_context, true) end end if cite_item.suffix then if cite_item.suffix == "" then cite_item.suffix = nil - else - cite_item.suffix_inlines = InlineElement:parse(cite_item.suffix, the_context, true) end end diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua index 55235ff3166..42eb6af5b2e 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-latex-parser.lua @@ -133,10 +133,11 @@ function latex_parser.get_latex_grammar() local latex_grammar = P{ "latex_text"; latex_text = Ct((specials + control_sequence + math + ligatures + specials + V"group" + plain_text)^0), - group = P"{" * V"latex_text" * P"}" / function (group_contents) + group = C(P"{" * V"latex_text" * P"}") / function (raw, group_contents) return { type = "group", contents = group_contents, + raw = raw, } end, } @@ -348,9 +349,18 @@ function latex_parser.convert_cs_to_inlines(tokens, i, strict, case_protection) else -- Unrecognized command if strict then - table.insert(inlines, markup.Code:new(token.raw)) + local raw = token.raw + for j = i + 1, #tokens do + if type(tokens[j]) == "table" and tokens[j].type == "group" then + i = j + raw = raw .. latex_parser.convert_token_to_raw(tokens[j]) + else + break + end + end + table.insert(inlines, markup.Code:new(raw)) else - -- Gobble following groupsas pandoc does: + -- Gobble following groups as pandoc does: -- "Foo \unrecognized{bar}{baz} quz" -> "Foo quz" for j = i + 1, #tokens do if type(tokens[j]) == "table" and tokens[j].type == "group" then @@ -365,6 +375,31 @@ function latex_parser.convert_cs_to_inlines(tokens, i, strict, case_protection) return inlines, i end +---@param token any +---@return string +function latex_parser.convert_token_to_raw(token) + if type(token) == "string" then + return token + elseif type(token) == "table" then + if token.raw then + return token.raw + elseif token.type == "group" then + local raw = "{" + for _, token_ in ipairs(token.contents) do + raw = raw .. latex_parser.convert_token_to_raw(token_) + end + raw = raw .. "}" + return raw + else + error(token.type) + return "" + end + else + error(type(token)) + return "" + end +end + -- TODO: raise a warning for unrecognized LaTeX command like `\switchargs` function latex_parser.convert_group_to_inlines(token, strict, case_protection, force_add_braces) if case_protection then diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua index ae65fdd5e0b..4f824feab24 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-manager.lua @@ -582,6 +582,13 @@ function CslCitationManager:_make_citation(citation_info) util.error(string.format("Invalid chapter index '%s'.", chapter_index)) end + if citation.properties.prefix then + citation.properties.prefix = latex_parser.latex_to_pseudo_html(citation.properties.prefix, true, false) + end + if citation.properties.suffix then + citation.properties.suffix = latex_parser.latex_to_pseudo_html(citation.properties.suffix, true, false) + end + -- util.debug(citation) return citation end @@ -857,9 +864,12 @@ function CslCitationManager:read_aux_file(aux_content) self:register_citation_info(tostring(ref_section_index), content) if ref_section.engine then local citation = self:_make_citation(content) - local citation_str = ref_section.engine:process_citation(citation) - - table.insert(output_lines, string.format("\\cslcitation{%s}{%s}", citation.citationID, citation_str)) + if citation.citationID == "@nocite" then + ref_section:_update_uncited_items() + else + local citation_str = ref_section.engine:process_citation(citation) + table.insert(output_lines, string.format("\\cslcitation{%s}{%s}", citation.citationID, citation_str)) + end end elseif command == "\\csl@aux@bibliography" then diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua index 8a9189ca06b..839c22e1b51 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-node-citation.lua @@ -184,17 +184,16 @@ end ---@field suffix string? ---@field locator string? ---@field label string? ----@field prefix_inlines InlineElement[]? ----@field suffix_inlines InlineElement[]? ---comment ---@param citation_items CitationItem[] ---@param engine CiteProc ----@param properties table +---@param properties CitationProperties ---@return string function Citation:build_cluster(citation_items, engine, properties) properties = properties or {} local output_format = engine.output_format + ---@type CiteIr[] local irs = {} citation_items = self:sorted_citation_items(citation_items, engine) for _, cite_item in ipairs(citation_items) do @@ -227,7 +226,7 @@ function Citation:build_cluster(citation_items, engine, properties) -- if layout_affixes then -- layout_prefix = layout_affixes.prefix -- end - local prefix_inlines = citation_items[i].prefix_inlines + local prefix_inlines = ir.cite_prefix if prefix_inlines then -- Prefix is inlines local prefix_str = output.SortStringFormat:new():output(prefix_inlines, context) @@ -262,8 +261,8 @@ function Citation:build_cluster(citation_items, engine, properties) local previous_ir for i, ir in ipairs(irs) do - local cite_prefix = citation_items[i].prefix_inlines - local cite_suffix = citation_items[i].suffix_inlines + local cite_prefix = ir.cite_prefix + local cite_suffix = ir.cite_suffix if not ir.collapse_suppressed then local cite_inlines = ir:flatten(output_format) if #cite_inlines > 0 then @@ -329,14 +328,28 @@ function Citation:build_cluster(citation_items, engine, properties) has_printed_form = false end + -- Ouput citation affixes + if has_printed_form then + if properties.prefix and properties.prefix ~= "" then + local citation_prefix = util.check_prefix_space_append(properties.prefix) + local inlines = InlineElement:parse(citation_prefix, context, true) + table.insert(citation_stream, 1, Micro:new(inlines)) + end + if properties.suffix and properties.suffix ~= "" then + local citation_suffix = util.check_suffix_prepend(properties.suffix) + local inlines = InlineElement:parse(citation_suffix, context, true) + table.insert(citation_stream, Micro:new(inlines)) + end + end + local author_only_mode = (properties.mode == "author-only" or (#citation_items >= 1 and citation_items[1]["author-only"])) if has_printed_form and context.area.layout.affixes and not author_only_mode then - if irs[1].cite_prefix then - table.insert(citation_stream, 1, PlainText:new(irs[1].cite_prefix)) + if irs[1].layout_prefix then + table.insert(citation_stream, 1, PlainText:new(irs[1].layout_prefix)) end - if irs[#irs].cite_suffix then - table.insert(citation_stream, PlainText:new(irs[#irs].cite_suffix)) + if irs[#irs].layout_suffix then + table.insert(citation_stream, PlainText:new(irs[#irs].layout_suffix)) end end @@ -416,8 +429,10 @@ end ---@field disam_level integer ---@field disam_str string? ---@field cite_delimiter string? ----@field cite_prefix string? ----@field cite_suffix string? +---@field layout_prefix string? +---@field layout_suffix string? +---@field cite_prefix InlineElement[]? +---@field cite_suffix InlineElement[]? ---@param cite_item CitationItem ---@param output_format OutputFormat @@ -485,8 +500,17 @@ function Citation:build_ambiguous_ir(cite_item, output_format, engine) ir.cite_delimiter = active_layout.delimiter if active_layout.affixes then - ir.cite_prefix = active_layout.affixes.prefix - ir.cite_suffix = active_layout.affixes.suffix + ir.layout_prefix = active_layout.affixes.prefix + ir.layout_suffix = active_layout.affixes.suffix + end + + if cite_item.prefix and cite_item.prefix ~= "" then + local cite_prefix = util.check_prefix_space_append(cite_item.prefix) + ir.cite_prefix = InlineElement:parse(cite_prefix, context, true) + end + if cite_item.suffix and cite_item.suffix ~= "" then + local cite_suffix = util.check_suffix_prepend(cite_item.suffix) + ir.cite_suffix = InlineElement:parse(cite_suffix, context, true) end -- Formattings like font-style are ignored for disambiguation. diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua index c0ff5e5731a..12d2b14ee95 100644 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc-util.lua @@ -433,6 +433,46 @@ function util.endswith(str, suffix) return string.sub(str, -#suffix) == suffix end +---@param str string +---@return string +function util.check_prefix_space_append(str) + if str == "" then + return str + end + local last_char = uni_utf8.match(str, ".$") + if not last_char then + return str + end + if util.is_romanesque(utf8.codepoint(last_char, 1, #last_char)) then + return str .. " " + elseif string.match(last_char, "[:.;!?]") then + return str .. " " + elseif string.match(last_char, "[)%],0-9]") then + return str .. " " + else + return str + end +end + +---@param str string +---@return string +function util.check_suffix_prepend(str) + if str == "" then + return str + end + local first_char = uni_utf8.match(str, "^.") + if not first_char then + return str + end + if util.is_romanesque(utf8.codepoint(first_char, 1, #first_char)) then + return " " .. str + elseif string.match(first_char, "[)%[]") then + return " " .. str + else + return str + end +end + ---@param str string | number ---@return boolean function util.is_numeric(str) diff --git a/Master/texmf-dist/scripts/citation-style-language/citeproc.lua b/Master/texmf-dist/scripts/citation-style-language/citeproc.lua index 47e7fca5a42..31b624b4d93 100755 --- a/Master/texmf-dist/scripts/citation-style-language/citeproc.lua +++ b/Master/texmf-dist/scripts/citation-style-language/citeproc.lua @@ -16,7 +16,7 @@ else util = require("citeproc.util") end -citeproc.__VERSION__ = "0.6.2" +citeproc.__VERSION__ = "0.6.3" citeproc.new = engine.CiteProc.new citeproc.util = util diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty index d72cb1d1eb3..38128a99d82 100644 --- a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty @@ -76,17 +76,15 @@ \tl_if_blank:nTF {#3} { \__csl_print_undefined_citation:n {#3} } { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \prop_clear:N \l__csl_citation_properties_prop - \__csl_process_cite_input:nnn {#1} {#2} {#3} - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq + \__csl_cite_init: + \__csl_collect_citation_items:nnn {#1} {#2} {#3} + \__csl_process_citation_info: \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } \tl_if_empty:nF {#4} { \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4} } - \__csl_make_citation:N \l__csl_citation_info_prop + \__csl_make_citation: } } @@ -101,16 +99,14 @@ \tl_if_blank:nTF {#3} { \__csl_print_undefined_citation:n {#3} } { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \prop_clear:N \l__csl_citation_properties_prop - \__csl_process_cite_input:nnn {#1} {#2} {#3} - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq + \__csl_cite_init: + \__csl_collect_citation_items:nnn {#1} {#2} {#3} + \__csl_process_citation_info: \tl_if_empty:nF {#4} { \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4} } - \__csl_make_citation:N \l__csl_citation_info_prop + \__csl_make_citation: } } { @@ -119,16 +115,14 @@ \tl_if_blank:nTF {#3} { \__csl_print_undefined_citation:n {#3} } { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \prop_clear:N \l__csl_citation_properties_prop - \__csl_process_cite_input:nnn {#1} {#2} {#3} - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq + \__csl_cite_init: + \__csl_collect_citation_items:nnn {#1} {#2} {#3} + \__csl_process_citation_info: \tl_if_empty:nF {#4} { \prop_put:Nnn \l__csl_citation_properties_prop { mode } {#4} } - \__csl_make_citation:N \l__csl_citation_info_prop + \__csl_make_citation: } } } @@ -158,11 +152,12 @@ } +\bool_new:N \l__csl_multi_cite_bool + \cs_new:Npn \__csl_cites: { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \prop_clear:N \l__csl_citation_properties_prop + \__csl_cite_init: + \bool_set_true:N \l__csl_multi_cite_bool \__csl_next_cites:nnn } @@ -174,27 +169,39 @@ { \footnote { - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq - \__csl_make_citation:N \l__csl_citation_info_prop + \__csl_process_citation_info: + \__csl_make_citation: } } { - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq - \__csl_make_citation:N \l__csl_citation_info_prop + \__csl_process_citation_info: + \__csl_make_citation: } } { - \__csl_process_cite_input:nnn {#1} {#2} {#3} + \__csl_collect_citation_items:nnn {#1} {#2} {#3} \__csl_next_cites:nnn } } +\cs_new:Npn \__csl_cite_init: + { + \bool_set_false:N \l__csl_multi_cite_bool + \prop_clear:N \l__csl_citation_info_prop + \seq_clear:N \l__csl_cite_keys_seq + \seq_clear:N \l__csl_citation_items_seq + \prop_clear:N \l__csl_citation_properties_prop + \tl_clear:N \l__csl_cite_prefix_tl + \tl_clear:N \l__csl_cite_suffix_tl + } + + % Appends the cite key into \l__csl_cite_keys_seq and cite-items into % \l__csl_citation_items_seq % #1, #2: prenote/postnote % #3: keys -\cs_new:Npn \__csl_process_cite_input:nnn #1#2#3 +\cs_new:Npn \__csl_collect_citation_items:nnn #1#2#3 { \tl_if_novalue:nTF {#2} { @@ -222,12 +229,13 @@ \prop_new:N \l__csl_cite_item_prop -\tl_new:N \l__csl_prefix_tl -\tl_new:N \l__csl_suffix_tl +% Collect citation items into \l__csl_citation_items_seq +% Append "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq +% #1: prenote +% #2: postnote +% #3: key \cs_new:Npn \__csl_process_cite_item:nnn #1#2#3 - % #1: prenote, #2: postnote, #3: key - % Save "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq { \prop_clear:N \l__csl_cite_item_prop \prop_put:Nnn \l__csl_cite_item_prop { id } {#3} @@ -235,11 +243,12 @@ % { \prop_put:Nnn \l__csl_cite_item_prop { suppress-author } { true } } % \bool_if:T \l__csl_author_only_bool % { \prop_put:Nnn \l__csl_cite_item_prop { author-only } { true } } + \tl_clear:N \l__csl_cite_prefix_tl + \tl_clear:N \l__csl_cite_suffix_tl \tl_if_empty:nF {#1} { - \tl_set:Nn \l__csl_prefix_tl {#1} - \tl_put_right:NV \l__csl_prefix_tl \l__csl_prefix_separator_tl - \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_prefix_tl + \tl_set:Nn \l__csl_cite_prefix_tl {#1} + \tl_put_right:NV \l__csl_cite_prefix_tl \l__csl_prefix_separator_tl } \tl_if_empty:nF {#2} { @@ -249,12 +258,26 @@ \regex_match:nnTF { \d+ } {#2} { \__csl_set_locator:nn { page } {#2} } { - \tl_set:Nn \l__csl_suffix_tl {#2} - \tl_put_left:NV \l__csl_suffix_tl \l__csl_suffix_separator_tl - \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_suffix_tl + \tl_set:Nn \l__csl_cite_suffix_tl {#2} + \tl_put_left:NV \l__csl_cite_suffix_tl \l__csl_suffix_separator_tl } } } + % The affixes are treated as cite item affixes in a multi-cite command + % (like `\cites`). Otherwise they are citation affixes. + \bool_if:NTF \l__csl_multi_cite_bool + { + \tl_if_empty:NF \l__csl_cite_prefix_tl + { \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_cite_prefix_tl } + \tl_if_empty:NF \l__csl_cite_suffix_tl + { \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_cite_suffix_tl } + } + { + \tl_if_empty:NF \l__csl_cite_prefix_tl + { \prop_put:NnV \l__csl_citation_properties_prop { prefix } \l__csl_cite_prefix_tl } + \tl_if_empty:NF \l__csl_cite_suffix_tl + { \prop_put:NnV \l__csl_citation_properties_prop { suffix } \l__csl_cite_suffix_tl } + } \__csl_serialize_prop:NN \l__csl_cite_item_prop \l_tmpa_tl \tl_put_left:NV \l_tmpa_tl { \c_left_brace_str } \tl_put_right:NV \l_tmpa_tl { \c_right_brace_str } @@ -274,10 +297,13 @@ \msg_new:nnn { citation-style-language } { empty-locator } { Empty~ '#1'~ locator. } +\tl_new:N \l__csl_cite_prefix_tl +\tl_new:N \l__csl_cite_suffix_tl + \keys_define:nn { csl / cite-item } { - prefix .prop_put:N = \l__csl_cite_item_prop, - suffix .prop_put:N = \l__csl_cite_item_prop, + prefix .tl_set:N = \l__csl_cite_prefix_tl, + suffix .tl_set:N = \l__csl_cite_suffix_tl, locator .prop_put:N = \l__csl_cite_item_prop, label .prop_put:N = \l__csl_cite_item_prop, suppress-author .prop_put:N = \l__csl_cite_item_prop, @@ -325,13 +351,10 @@ % Load the cite keys and prepare: % - \l__csl_citation_id_tl % - \l__csl_citation_properties_prop -% -% #1: \l__csl_cite_keys_seq -% #2: \l__csl_citation_items_seq -\cs_new:Npn \__csl_process_citation_info:NN #1#2 +\cs_new:Npn \__csl_process_citation_info: { - \__csl_process_citation_id:NN \l__csl_citation_id_tl #1 - \__csl_get_note_index:N \l__csl_note_index_tl + \__csl_process_citation_id: + \__csl_get_note_index: \prop_put:NnV \l__csl_citation_properties_prop { noteIndex } \l__csl_note_index_tl \__csl_make_chapter_property: \__csl_add_back_ref_info: @@ -395,8 +418,7 @@ \tl_new:N \l__csl_citation_properties_tl % Write citation info to aux and print the citation contents. -% #1: \l__csl_citation_info_prop -\cs_new:Npn \__csl_make_citation:N #1 +\cs_new:Npn \__csl_make_citation: { \prop_clear:N \l__csl_citation_info_prop % citationID @@ -416,7 +438,7 @@ % Print the citation string \prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl \l__csl_citation_tl - { \__csl_print_citation:N \l__csl_citation_tl } + { \__csl_print_citation: } { \bool_if:NTF \l__csl_engine_initialized_bool { @@ -427,7 +449,7 @@ \char_set_catcode_other:N \% \char_set_catcode_other:N \# \exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl - \__csl_print_citation:N \l__csl_citation_tl + \__csl_print_citation: \group_end: } { @@ -471,13 +493,12 @@ \int_new:N \l__csl_citation_count_int \prop_new:N \g__csl_citations_count_prop -\cs_new:Npn \__csl_process_citation_id:NN #1#2 - % #1: \l__csl_citation_id_tl - % #2: \l__csl_cite_keys_seq - % Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4". +% Load cite keys from `\l__csl_cite_keys_seq` and make `\l__csl_citation_id_tl`. +% Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4". +\cs_new:Npn \__csl_process_citation_id: { \tl_set:Nx \l__csl_cite_keys_tl - { \seq_use:Nn #2 { , } } + { \seq_use:Nn \l__csl_cite_keys_seq { , } } % \prop_show:N \g__csl_citations_count_prop % \tl_show:N \l__csl_cite_keys_tl \prop_get:NVNTF \g__csl_citations_count_prop \l__csl_cite_keys_tl @@ -489,7 +510,7 @@ { \int_set_eq:NN \l__csl_citation_count_int \c_one_int } \prop_gput:NVV \g__csl_citations_count_prop \l__csl_cite_keys_tl \l__csl_citation_count_int - \tl_set:Nx #1 + \tl_set:Nx \l__csl_citation_id_tl { \l__csl_cite_keys_tl @ \int_use:N \l__csl_citation_count_int } } @@ -499,11 +520,11 @@ % Save the note number to \l__csl_note_index_tl % TODO: multiple citations in a note -\cs_new:Npn \__csl_get_note_index:N #1 +\cs_new:Npn \__csl_get_note_index: % #1: \l__csl_note_index_tl { \bool_if:NTF \l__csl_note_bool - { \tl_set:Nx #1 { \int_use:c { c@ \@mpfn } } } + { \tl_set:Nx \l__csl_note_index_tl { \int_use:c { c@ \@mpfn } } } { \tl_if_empty:NTF \l__csl_class_tl { @@ -511,9 +532,9 @@ \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn } \int_gincr:N \g__csl_pseudo_note_index_int \int_add:Nn \l_tmpa_int { \g__csl_pseudo_note_index_int } - \tl_set:Nx #1 { \int_use:N \l_tmpa_int } + \tl_set:Nx \l__csl_note_index_tl { \int_use:N \l_tmpa_int } } - { \tl_set:Nn #1 { 0 } } + { \tl_set:Nn \l__csl_note_index_tl { 0 } } } } @@ -538,11 +559,11 @@ % #1: \l__csl_citation_tl -\cs_new:Npn \__csl_print_citation:N #1 +\cs_new:Npn \__csl_print_citation: { \bool_if:NT \l__csl_regression_test_bool - { \tl_show:N #1 } - #1 + { \tl_show:N \l__csl_citation_tl } + \l__csl_citation_tl } @@ -590,16 +611,19 @@ \cs_new:Npn \__csl_no_cite:n #1 { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \__csl_process_cite_input:nnn { } { } {#1} + \__csl_cite_init: + \__csl_collect_citation_items:nnn { } { } {#1} \tl_set:Nx \l__csl_cite_items_tl { \seq_use:Nn \l__csl_citation_items_seq { , } } + \prop_clear:N \l__csl_citation_properties_prop + \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } + \__csl_make_chapter_property: + \__csl_serialize_prop:NN \l__csl_citation_properties_prop \l__csl_citation_properties_tl \tl_set:Nx \l__csl_citation_info_tl { citationID = { @nocite } , - citationItems = { \l__csl_cite_items_tl } , - properties = { noteIndex = { 0 } } + citationItems = { \tl_use:N \l__csl_cite_items_tl } , + properties = { \tl_use:N \l__csl_citation_properties_tl } } \bool_if:NT \l__csl_regression_test_bool { \tl_show:N \l__csl_citation_info_tl } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty index 84da32c79b8..8de98b6a9c6 100644 --- a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty @@ -89,8 +89,8 @@ { \BlockquoteDisable { - \cs_set_eq:NN \__csl_process_citation_info:NN \use_none:nn - \cs_set_eq:NN \__csl_make_citation:N \use_none:n + \cs_set_eq:NN \__csl_process_citation_info: \relax + \cs_set_eq:NN \__csl_make_citation: \relax } } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty index f54f8d0e85e..f6039b4008c 100644 --- a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty @@ -9,7 +9,7 @@ \RequirePackage{expl3} \RequirePackage{xparse} -\ProvidesExplPackage {citation-style-language} {2024-08-21} {0.6.2} +\ProvidesExplPackage {citation-style-language} {2024-08-28} {0.6.3} {Citation Style Language for LaTeX} \RequirePackage { l3keys2e } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/styles/apa.csl b/Master/texmf-dist/tex/latex/citation-style-language/styles/apa.csl index d59376693f0..a78e7f315fd 100644 --- a/Master/texmf-dist/tex/latex/citation-style-language/styles/apa.csl +++ b/Master/texmf-dist/tex/latex/citation-style-language/styles/apa.csl @@ -14,7 +14,7 @@ <category citation-format="author-date"/> <category field="psychology"/> <category field="generic-base"/> - <updated>2024-08-06T11:26:59-04:00</updated> + <updated>2024-08-24T12:16:51-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"> @@ -1619,9 +1619,6 @@ <if variable="archive DOI URL" match="none"> <text variable="publisher"/> </if> - <else> - <text variable="archive"/> - </else> </choose> </if> <else-if type="post webpage" match="any"> @@ -1660,17 +1657,21 @@ <text variable="archive_location" prefix="(" suffix=")"/> </group> <text variable="archive"/> + <text variable="archive-place"/> </if> <else> <group delimiter=" "> <text variable="archive"/> <text variable="archive_location" prefix="(" suffix=")"/> </group> + <text variable="archive-place"/> </else> </choose> </if> + <else> + <text variable="archive"/> + </else> </choose> - <text variable="archive-place"/> </group> </group> </macro> |