From 0dfb7e26e14f646b7d6229ff769a24ef5da7ac38 Mon Sep 17 00:00:00 2001 From: Jonathan Harker Date: Tue, 20 Oct 2026 11:48:18 +1300 Subject: [PATCH 1/9] Fix supplied ref=CITEREF error when item has editors but no authors --- module_citeq.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/module_citeq.lua b/module_citeq.lua index 6bfb259..b731e1f 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -901,7 +901,13 @@ local function _cite_q (citeq_args) if names.authors_overridden or (#names.authors == 0 and names.editors_overridden) then -- if names are supplied manually, then don't mess with supplied ref parameter elseif citeq_args.ref and 'none' ~= citeq_args.ref then - local citeref = make_citeref(names.authors or names.editors, pubyear) + local refnames + if #names.authors > 0 then + refnames = names.authors + else + refnames = names.editors + end + local citeref = make_citeref(refnames, pubyear) if citeq_args.ref == citeref then citeq_args.ref = nil -- avoid CS1 maint: ref duplicates default else From a12122b03ffd268a22fc9ccde38ff13dec435d01 Mon Sep 17 00:00:00 2001 From: Jonathan Harker Date: Tue, 20 Oct 2026 12:34:18 +1300 Subject: [PATCH 2/9] Refactor tracking categories to a set-like table, separate from error output --- module_citeq.lua | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/module_citeq.lua b/module_citeq.lua index b731e1f..1ae2e63 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -9,7 +9,8 @@ local cite_cfg = mw.loadData ('Module:Cite/config') local cfg = mw.loadData ('Module:Cite_Q/config') local cs1_module = 'Module:Citation/CS1' -- don't load the module yet, may not be needed local cs1_cfg = mw.loadData('Module:Citation/CS1/Configuration') -local opt_cat = '' +local opt_cat = {} +local cq_errors = '' local max_authors_displayed = 10 -- Don't look up all 500+ author items (is this in CS1 config somewhere?) @@ -59,6 +60,14 @@ local function in_array( needle, haystack ) return false end +--[[--------------------------< T A B L E S E T _ A D D >------------------------------------------------------ +Add needle to the haystack if it's not already there. +]] +local function tableset_add(haystack, needle) + if needle == nil or in_array(needle, haystack) then return false end + table.insert(haystack, needle) + return true +end --[[--------------------------< A C C E P T _ V A L U E >------------------------------------------------------- Accept WD value by framing in ((...)) if param_val is equal to keyword; else pass-through WD value as is. @@ -252,8 +261,9 @@ local function makelink(v, out, maxpos, wdl, namestyle) } else -- use anonymous + tableset_add(opt_cat, cfg.i18n_t.trackingcats["unknown-author"]) label = { - label = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper) .. (cfg.i18n_t.trackingcats["unknown-author"] or ""), + label = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper), qid = 'Q4233718', } end @@ -886,11 +896,10 @@ local function _cite_q (citeq_args) end -- add category and display error if name errors found - local name_cat = cfg.i18n_t.trackingcats['missing-author-first-last-names'] - if #missing_names > 0 and not string.find(opt_cat, name_cat, 1, true) then - opt_cat = opt_cat .. name_cat + if #missing_names > 0 and not in_array('missing-author-first-last-names', opt_cat) then + tableset_add(opt_cat, cfg.i18n_t.trackingcats['missing-author-first-last-names']) -- TODO: format and i18n this string - opt_cat = opt_cat .. ' {{[[Template:Cite Q|Cite Q]]}}: Missing first/last names in Wikidata for ' .. table.concat(missing_names, ', ') .. ' ([[Template:Cite Q#Error messages|help]]) ' + cq_errors = cq_errors .. ' {{[[Template:Cite Q|Cite Q]]}}: Missing first/last names in Wikidata for ' .. table.concat(missing_names, ', ') .. ' ([[Template:Cite Q#Error messages|help]]) ' end -- change edition to ordinal if it's set and numeric @@ -913,7 +922,7 @@ local function _cite_q (citeq_args) else local tpara = frame:expandTemplate{ title = 'para', args = {'ref', citeq_args.ref} } -- TODO: format and i18n this string - opt_cat = opt_cat .. ' {{[[Template:Cite Q|Cite Q]]}}: supplied ' .. tpara .. ' does not match value generated from Wikidata: ' .. citeref .. ' ([[Template:Cite Q#Error messages|help]]) ' + cq_errors = cq_errors .. ' {{[[Template:Cite Q|Cite Q]]}}: supplied ' .. tpara .. ' does not match value generated from Wikidata: ' .. citeref .. ' ([[Template:Cite Q#Error messages|help]]) ' end end @@ -978,7 +987,7 @@ local function _cite_q (citeq_args) -- Indicator if item has been retracted local retract = '' if citeq_args.retracted_by then - opt_cat = opt_cat .. cfg.i18n_t.trackingcats.retracted + tableset_add(opt_cat, cfg.i18n_t.trackingcats.retracted) local retract_id = string.gsub(citeq_args.retracted_by, 'Q', '') local retr_params = { citeq = 'yes', @@ -1033,7 +1042,7 @@ local function _cite_q (citeq_args) -- Indicator if item has corrigendum/erratum local erratumid = "" if citeq_args.erratum then - opt_cat = opt_cat .. cfg.i18n_t.trackingcats.erratum + tableset_add(opt_cat, cfg.i18n_t.trackingcats.erratum) local erratum_params = { citeq = 'yes', id = frame:expandTemplate{ @@ -1059,7 +1068,7 @@ local function _cite_q (citeq_args) -- Indicator if item has an expression of concern notice (P14891) local eoc = "" if citeq_args['expression-of-concern'] then - opt_cat = opt_cat .. cfg.i18n_t.trackingcats['expression-of-concern'] + tableset_add(opt_cat, cfg.i18n_t.trackingcats['expression-of-concern']) local eoc_params = { citeq = 'yes', id = frame:expandTemplate{ @@ -1083,11 +1092,11 @@ local function _cite_q (citeq_args) citeq_args['eoc-intentional'] = nil if citeq_args.replaced_by then - opt_cat = opt_cat .. cfg.i18n_t.trackingcats.replaced + tableset_add(opt_cat, cfg.i18n_t.trackingcats.replaced) citeq_args.replaced_by = nil end if not citeq_args.title then -- emit category link if missing title - opt_cat = opt_cat .. cfg.i18n_t.trackingcats['no-label-or-title']; + tableset_add(opt_cat, cfg.i18n_t.trackingcats['no-label-or-title']) end -- Disable CiteSeerX IDs for now @@ -1108,9 +1117,10 @@ local function _cite_q (citeq_args) else output = frame:expandTemplate{ -- render the template title = "Cite "..template, args = citeq_args - } .. cfg.i18n_t.trackingcats["unknown-template"] + } + tableset_add(opt_cat, cfg.i18n_t.trackingcats["unknown-template"]) end - return output .. erratumid .. eoc .. retract .. opt_cat + return output .. erratumid .. eoc .. retract .. table.concat(opt_cat, ' ') .. cq_errors end local function cite_q (frame) From dc7f9358db6ab84855e48974a40ffc4952b9fc36 Mon Sep 17 00:00:00 2001 From: Jonathan Harker Date: Tue, 20 Oct 2026 12:37:04 +1300 Subject: [PATCH 3/9] Add tracking category for supplied ref mismatch --- module_citeq.lua | 1 + module_citeq_config.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/module_citeq.lua b/module_citeq.lua index 1ae2e63..66c7367 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -920,6 +920,7 @@ local function _cite_q (citeq_args) if citeq_args.ref == citeref then citeq_args.ref = nil -- avoid CS1 maint: ref duplicates default else + tableset_add(opt_cat, cfg.i18n_t.trackingcats['supplied-ref']) local tpara = frame:expandTemplate{ title = 'para', args = {'ref', citeq_args.ref} } -- TODO: format and i18n this string cq_errors = cq_errors .. ' {{[[Template:Cite Q|Cite Q]]}}: supplied ' .. tpara .. ' does not match value generated from Wikidata: ' .. citeref .. ' ([[Template:Cite Q#Error messages|help]]) ' diff --git a/module_citeq_config.lua b/module_citeq_config.lua index 35dc8fa..560edae 100644 --- a/module_citeq_config.lua +++ b/module_citeq_config.lua @@ -33,6 +33,7 @@ local i18n_t = { ["unknown-author"] = "", -- [[Category:Cite Q - author unknown]] removed as misplaced; someone is welcome to restore it if it is placed outside of the template parameter value ["unknown-template"] = "[[Category:Cite Q - template unknown]]", ["missing-author-first-last-names"] = "[[Category:Cite Q - authors with missing given and family names]]", + ["supplied-ref"] = "[[Category:Cite Q - supplied citeref does not match]]", }, } From 4724cd3c55e31e691d203352afaebfe5c81cdc1a Mon Sep 17 00:00:00 2001 From: Trappist the monk Date: Mon, 26 Oct 2026 03:19:00 +1300 Subject: [PATCH 4/9] remove all non-cs1 parameters in one place before rendering any output --- module_citeq.lua | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/module_citeq.lua b/module_citeq.lua index 66c7367..5ae2ae6 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -114,21 +114,23 @@ local function getStyledNames(names, style) end end --- Concatenate up to the first four names, and the year, into a CITEREF and return it +-- Concatenate up to the first four names (at least one name required), and the year (optional), into a CITEREF and return it; return nil else local function make_citeref(names, year) local refs = {} for i, v in ipairs(names) do - local name = v.last or v.label or '' - refs[i] = mw.text.trim(name) - if i == 4 then break end + local name = v.last or v.label; + if not name then break end; -- no v.last or v.label? abandon the ipairs() loop + refs[i] = mw.text.trim (name); + if i == 4 then break end -- collect only four names end - table.insert(refs, year) - local id = table.concat(refs) or '' - if id == '' then - return '' - else - return "CITEREF" .. id + + if 0 < #refs then -- don't add when there are no names in ; CITEREFYYYY is more-or-less meaningless + table.insert (refs, year); -- add + table.insert (refs, 1, 'CITEREF'); -- and insert the 'CITEREF' prefix + return table.concat (refs); -- concatenate and done end + + return; -- no names so return nil end -- function to fetch a value to display @@ -913,13 +915,13 @@ local function _cite_q (citeq_args) local refnames if #names.authors > 0 then refnames = names.authors - else + elseif #names.editors > 0 then refnames = names.editors end - local citeref = make_citeref(refnames, pubyear) - if citeq_args.ref == citeref then - citeq_args.ref = nil -- avoid CS1 maint: ref duplicates default - else + local citeref = refnames and make_citeref (refnames, pubyear) or nil; -- nil when no authors and no editors + if citeq_args.ref == citeref then -- CITEREF from wikidata authors / editors matches the value provided in |ref= + citeq_args.ref = nil -- unset to avoid CS1 maint: ref duplicates default maintenance message / category + elseif citeref then -- CITEREF from wikidata authors / editors is different from the value provided in |ref= tableset_add(opt_cat, cfg.i18n_t.trackingcats['supplied-ref']) local tpara = frame:expandTemplate{ title = 'para', args = {'ref', citeq_args.ref} } -- TODO: format and i18n this string @@ -1009,9 +1011,13 @@ local function _cite_q (citeq_args) end retract = ' ' .. frame:expandTemplate{ title = "Retracted", args = retr_params } end - -- remove non-CS1 retraction properties - citeq_args.retracted_by = nil + + citeq_args.retracted_by = nil -- remove non-CS1 parameters citeq_args['retracted-intentional'] = nil + citeq_args['instance-of'] = nil + if citeq_args['name-list-style'] and citeq_args['name-list-style'] == 'apa' then + citeq_args['name-list-style'] = nil + end -- clean up any blank parameters for k, v in pairs(citeq_args) do @@ -1103,12 +1109,6 @@ local function _cite_q (citeq_args) -- Disable CiteSeerX IDs for now citeq_args.citeseerx = nil - -- remove any remaining non-CS1 fields - citeq_args['instance-of'] = nil - if citeq_args['name-list-style'] and citeq_args['name-list-style'] == 'apa' then - citeq_args['name-list-style'] = nil - end - -- render the template local lc_template = template and template:lower() or "citation" local output From ca015c4f68a05d5453e823851d25a78655115a21 Mon Sep 17 00:00:00 2001 From: Trappist the monk Date: Mon, 26 Oct 2026 03:48:00 +1300 Subject: [PATCH 5/9] =?UTF-8?q?[[|