diff options
-rwxr-xr-x | Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua | 94 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/checkcites/README | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/checkcites/checkcites-doc.pdf | bin | 289025 -> 288652 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/support/checkcites/checkcites-doc.tex | 33 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/checkcites/checkcites.lua | 94 |
5 files changed, 195 insertions, 30 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua b/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua index c6ff0e396af..349b0c1fc3d 100755 --- a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua +++ b/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua @@ -211,6 +211,36 @@ local function extract(lines) return result end +-- Extracts the cross-references found +-- in lines of the bibligraphy file. +-- @param lines Line of a file. +-- @return Table containing cross-references. +local function crossref(lines) + local result, lookup, key, hit = {}, '' + for _, line in ipairs(lines) do + key, hit = string.match(line, + '^%s*%@(%w+%s*){%s*(.+),') + if key and allowed(key) then + lookup = normalize(hit) + else + key, hit = string.match(line, + '^%s*(%w+)%s*=%s*(.+)$') + if key then + key = string.lower(key) + if key == 'crossref' then + if string.sub(hit, -1) == ',' then + hit = string.sub(hit, 2, -3) + else + hit = string.sub(hit, 2, -2) + end + result[lookup] = hit + end + end + end + end + return result +end + -- Adds the extension if the file does not have it. -- @param file File. -- @param extension Extension. @@ -411,6 +441,21 @@ local function flatten(t) return result end +-- Organizes a key/value table of tables into only one table. +-- @param t Table. +-- @return Flattened key/value table. +local function organize(t) + local result = {} + for _, v in ipairs(t) do + for j, k in pairs(v) do + if not result[j] then + result[j] = k + end + end + end + return result +end + -- Applies a function to elements of a table. -- @param c Table. -- @param f Function. @@ -453,7 +498,7 @@ local operations = {} -- @param citations Citations. -- @param references References. -- @return Integer representing the status. -operations.unused = function(citations, references) +operations.unused = function(citations, references, crossrefs) print() print(pad('-', 74)) print(wrap('Report of unused references in your TeX ' .. @@ -461,6 +506,20 @@ operations.unused = function(citations, references) 'bibliography files, but not cited in ' .. 'the TeX source file)', 74)) print(pad('-', 74)) + + local z = {} + for _, citation in ipairs(citations) do + if crossrefs[citation] then + table.insert(z, crossrefs[citation]) + end + end + + for _, i in ipairs(z) do + if not exists(i, citations) then + table.insert(citations, i) + end + end + local r = difference(references, citations) print() print(wrap('Unused references in your TeX document: ' .. @@ -479,7 +538,7 @@ end -- @param citations Citations. -- @param references References. -- @return Integer value indicating the status. -operations.undefined = function(citations, references) +operations.undefined = function(citations, references, crossrefs) print() print(pad('-', 74)) print(wrap('Report of undefined references in your TeX ' .. @@ -487,6 +546,20 @@ operations.undefined = function(citations, references) 'TeX source file, but not present in the ' .. 'bibliography files)', 74)) print(pad('-', 74)) + + local z = {} + for _, citation in ipairs(citations) do + if crossrefs[citation] then + table.insert(z, crossrefs[citation]) + end + end + + for _, i in ipairs(z) do + if not exists(i, citations) then + table.insert(citations, i) + end + end + local r = difference(citations, references) print() print(wrap('Undefined references in your TeX document: ' .. @@ -505,10 +578,10 @@ end -- @param citations Citations. -- @param references References. -- @return Integer value indicating the status. -operations.all = function(citations, references) +operations.all = function(citations, references, crossrefs) local x, y - x = operations.unused(citations, references) - y = operations.undefined(citations, references) + x = operations.unused(citations, references, crossrefs) + y = operations.undefined(citations, references, crossrefs) if x + y > 0 then return 1 else @@ -555,6 +628,7 @@ local function checkcites(args) { short = 'U', long = 'undefined', argument = false }, { short = 'v', long = 'version', argument = false }, { short = 'h', long = 'help', argument = false }, + { short = 'c', long = 'crossrefs', argument = false }, { short = 'b', long = 'backend', argument = true } } @@ -596,8 +670,8 @@ local function checkcites(args) if keys['version'] or keys['help'] then if keys['version'] then print() - print(wrap('checkcites.lua, version 2.1 (dated July ' .. - '26, 2019)', 74)) + print(wrap('checkcites.lua, version 2.3 (dated September ' .. + '1, 2019)', 74)) print(pad('-', 74)) print(wrap('You can find more details about this ' .. @@ -623,6 +697,7 @@ local function checkcites(args) print('-a,--all list all unused and undefined references') print('-u,--unused list only unused references in your bibliography files') print('-U,--undefined list only undefined references in your TeX source file') + print('-c,--crossrefs enable cross-reference checks (disabled by default)') print('-b,--backend <arg> set the backend-based file lookup policy') print('-h,--help print the help message') print('-v,--version print the script version') @@ -773,6 +848,9 @@ local function checkcites(args) local references = flatten(apply(bibliography, function(a) return extract(read(a)) end)) + local crossrefs = (keys['crossrefs'] and organize(apply(bibliography, + function(a) return crossref(read(a)) end))) or {} + print() print(wrap('Fantastic, I found ' .. tostring(#references) .. ' ' .. plural(#references, 'reference', @@ -782,7 +860,7 @@ local function checkcites(args) plural(((check == 'all' and 2) or 1), 'report is', 'reports are') .. ' generated.', 74)) - return operations[check](citations, references) + return operations[check](citations, references, crossrefs) end -- Call and exit diff --git a/Master/texmf-dist/doc/support/checkcites/README b/Master/texmf-dist/doc/support/checkcites/README index 24ac583f264..e0c2713ae7d 100644 --- a/Master/texmf-dist/doc/support/checkcites/README +++ b/Master/texmf-dist/doc/support/checkcites/README @@ -1,5 +1,5 @@ -checkcites.lua -- Version 2.1 from July 26, 2019. -================================================= +checkcites.lua -- Version 2.3 from September 1, 2019. +===================================================== License ------- diff --git a/Master/texmf-dist/doc/support/checkcites/checkcites-doc.pdf b/Master/texmf-dist/doc/support/checkcites/checkcites-doc.pdf Binary files differindex 3bd33069ae6..f135ce61d17 100644 --- a/Master/texmf-dist/doc/support/checkcites/checkcites-doc.pdf +++ b/Master/texmf-dist/doc/support/checkcites/checkcites-doc.pdf diff --git a/Master/texmf-dist/doc/support/checkcites/checkcites-doc.tex b/Master/texmf-dist/doc/support/checkcites/checkcites-doc.tex index 447505587c8..4263733103e 100644 --- a/Master/texmf-dist/doc/support/checkcites/checkcites-doc.tex +++ b/Master/texmf-dist/doc/support/checkcites/checkcites-doc.tex @@ -20,7 +20,7 @@ \newcommand{\checkcites}{\texttt{checkcites}} \newcommand{\email}[1]{\small\texttt{#1}} -\newcommand{\version}{Version 2.1 from July 26, 2019.} +\newcommand{\version}{Version 2.3 from September 1, 2019.} \newenvironment{infoblock}[1] {\par\addvspace{\medskipamount} @@ -66,9 +66,10 @@ straightforward language and it has an interpreter available on every modern \TeX\ distribution. \begin{infoblock}{Attention!} -\checkcites\ is known to run with the most recent \verb|texlua| and -\verb|lua| interpreters. Unfortunately, the code is incompatible with -interpreters prior to the Lua 5.1 language specification. +From version 2.1 on, \checkcites\ relies on specific libraries available +in the \verb|texlua| ecosystem and thus is not be supported in vanilla +\verb|lua| interpreters. Please make sure to use this script with an +updated \verb|texlua| interpreter in order to ensure the correct behaviour. \end{infoblock} \section{How the script works} @@ -226,7 +227,7 @@ $ checkcites | _| | -_| _| '_| _| | _| -_|_ -| |___|_|_|___|___|_,_|___|_|_| |___|___| -checkcites.lua -- a reference checker script (v2.1) +checkcites.lua -- a reference checker script (v2.3) Copyright (c) 2012, 2019, Enrico Gregorio, Paulo Roberto Massa Cereda -------------------------------------------------------------------------- @@ -271,6 +272,7 @@ Usage: checkcites.lua [ [ --all | --unused | --undefined ] [ --backend -a,--all list all unused and undefined references -u,--unused list only unused references in your bibliography files -U,--undefined list only undefined references in your TeX source file +-c,--crossrefs enable cross-reference checks (disabled by default) -b,--backend <arg> set the backend-based file lookup policy -h,--help print the help message -v,--version print the script version @@ -322,7 +324,7 @@ $ checkcites document.aux | _| | -_| _| '_| _| | _| -_|_ -| |___|_|_|___|___|_,_|___|_|_| |___|___| -checkcites.lua -- a reference checker script (v2.1) +checkcites.lua -- a reference checker script (v2.3) Copyright (c) 2012, 2019, Enrico Gregorio, Paulo Roberto Massa Cereda Great, I found 4 citations in 1 file. I also found 1 bibliography file. Let @@ -463,7 +465,7 @@ $ checkcites --backend biber document.bcf | _| | -_| _| '_| _| | _| -_|_ -| |___|_|_|___|___|_,_|___|_|_| |___|___| -checkcites.lua -- a reference checker script (v2.1) +checkcites.lua -- a reference checker script (v2.3) Copyright (c) 2012, 2019, Enrico Gregorio, Paulo Roberto Massa Cereda Great, I found 4 citations in 1 file. I also found 1 bibliography file. Let @@ -491,7 +493,18 @@ Undefined references in your TeX document: 1 \end{verbatim} \end{terminal} -That is all, folks! +If you rely on cross-references in your bibliography file, \checkcites\ might complain about +unused entries. We can try the experimental feature available from version 2.3 on that attempts +to check cross-references through the \verb|--crossrefs| command line flag: + +\begin{terminal} +\begin{verbatim} +$ checkcites --crossrefs document.aux +\end{verbatim} +\end{terminal} + +This feature is disabled by default and it is known to work with both \verb|bibtex| and \verb|biber| +backends. Please report if you find an issue. That is all, folks! \section{License} \label{sec:license} @@ -502,8 +515,4 @@ License}. If you want to support \LaTeX{} development by a donation, the best way to do this is donating to the \href{http://www.tug.org/}{TeX Users Group}. -\begin{infoblock}{Official code repository} -\url{http://github.com/cereda/checkcites} -\end{infoblock} - \end{document} diff --git a/Master/texmf-dist/scripts/checkcites/checkcites.lua b/Master/texmf-dist/scripts/checkcites/checkcites.lua index c6ff0e396af..349b0c1fc3d 100755 --- a/Master/texmf-dist/scripts/checkcites/checkcites.lua +++ b/Master/texmf-dist/scripts/checkcites/checkcites.lua @@ -211,6 +211,36 @@ local function extract(lines) return result end +-- Extracts the cross-references found +-- in lines of the bibligraphy file. +-- @param lines Line of a file. +-- @return Table containing cross-references. +local function crossref(lines) + local result, lookup, key, hit = {}, '' + for _, line in ipairs(lines) do + key, hit = string.match(line, + '^%s*%@(%w+%s*){%s*(.+),') + if key and allowed(key) then + lookup = normalize(hit) + else + key, hit = string.match(line, + '^%s*(%w+)%s*=%s*(.+)$') + if key then + key = string.lower(key) + if key == 'crossref' then + if string.sub(hit, -1) == ',' then + hit = string.sub(hit, 2, -3) + else + hit = string.sub(hit, 2, -2) + end + result[lookup] = hit + end + end + end + end + return result +end + -- Adds the extension if the file does not have it. -- @param file File. -- @param extension Extension. @@ -411,6 +441,21 @@ local function flatten(t) return result end +-- Organizes a key/value table of tables into only one table. +-- @param t Table. +-- @return Flattened key/value table. +local function organize(t) + local result = {} + for _, v in ipairs(t) do + for j, k in pairs(v) do + if not result[j] then + result[j] = k + end + end + end + return result +end + -- Applies a function to elements of a table. -- @param c Table. -- @param f Function. @@ -453,7 +498,7 @@ local operations = {} -- @param citations Citations. -- @param references References. -- @return Integer representing the status. -operations.unused = function(citations, references) +operations.unused = function(citations, references, crossrefs) print() print(pad('-', 74)) print(wrap('Report of unused references in your TeX ' .. @@ -461,6 +506,20 @@ operations.unused = function(citations, references) 'bibliography files, but not cited in ' .. 'the TeX source file)', 74)) print(pad('-', 74)) + + local z = {} + for _, citation in ipairs(citations) do + if crossrefs[citation] then + table.insert(z, crossrefs[citation]) + end + end + + for _, i in ipairs(z) do + if not exists(i, citations) then + table.insert(citations, i) + end + end + local r = difference(references, citations) print() print(wrap('Unused references in your TeX document: ' .. @@ -479,7 +538,7 @@ end -- @param citations Citations. -- @param references References. -- @return Integer value indicating the status. -operations.undefined = function(citations, references) +operations.undefined = function(citations, references, crossrefs) print() print(pad('-', 74)) print(wrap('Report of undefined references in your TeX ' .. @@ -487,6 +546,20 @@ operations.undefined = function(citations, references) 'TeX source file, but not present in the ' .. 'bibliography files)', 74)) print(pad('-', 74)) + + local z = {} + for _, citation in ipairs(citations) do + if crossrefs[citation] then + table.insert(z, crossrefs[citation]) + end + end + + for _, i in ipairs(z) do + if not exists(i, citations) then + table.insert(citations, i) + end + end + local r = difference(citations, references) print() print(wrap('Undefined references in your TeX document: ' .. @@ -505,10 +578,10 @@ end -- @param citations Citations. -- @param references References. -- @return Integer value indicating the status. -operations.all = function(citations, references) +operations.all = function(citations, references, crossrefs) local x, y - x = operations.unused(citations, references) - y = operations.undefined(citations, references) + x = operations.unused(citations, references, crossrefs) + y = operations.undefined(citations, references, crossrefs) if x + y > 0 then return 1 else @@ -555,6 +628,7 @@ local function checkcites(args) { short = 'U', long = 'undefined', argument = false }, { short = 'v', long = 'version', argument = false }, { short = 'h', long = 'help', argument = false }, + { short = 'c', long = 'crossrefs', argument = false }, { short = 'b', long = 'backend', argument = true } } @@ -596,8 +670,8 @@ local function checkcites(args) if keys['version'] or keys['help'] then if keys['version'] then print() - print(wrap('checkcites.lua, version 2.1 (dated July ' .. - '26, 2019)', 74)) + print(wrap('checkcites.lua, version 2.3 (dated September ' .. + '1, 2019)', 74)) print(pad('-', 74)) print(wrap('You can find more details about this ' .. @@ -623,6 +697,7 @@ local function checkcites(args) print('-a,--all list all unused and undefined references') print('-u,--unused list only unused references in your bibliography files') print('-U,--undefined list only undefined references in your TeX source file') + print('-c,--crossrefs enable cross-reference checks (disabled by default)') print('-b,--backend <arg> set the backend-based file lookup policy') print('-h,--help print the help message') print('-v,--version print the script version') @@ -773,6 +848,9 @@ local function checkcites(args) local references = flatten(apply(bibliography, function(a) return extract(read(a)) end)) + local crossrefs = (keys['crossrefs'] and organize(apply(bibliography, + function(a) return crossref(read(a)) end))) or {} + print() print(wrap('Fantastic, I found ' .. tostring(#references) .. ' ' .. plural(#references, 'reference', @@ -782,7 +860,7 @@ local function checkcites(args) plural(((check == 'all' and 2) or 1), 'report is', 'reports are') .. ' generated.', 74)) - return operations[check](citations, references) + return operations[check](citations, references, crossrefs) end -- Call and exit |