summaryrefslogtreecommitdiff
path: root/Build/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-08-28 23:42:31 +0000
committerKarl Berry <karl@freefriends.org>2019-08-28 23:42:31 +0000
commit3d0058ed9e3df17f31a9e6b939260830ba274bca (patch)
tree56bc01ea8769c6d06fbd97151100df2688adcd02 /Build/source
parent70c10a95a1cdccdb1ed742a058424bd06dd20032 (diff)
checkcites (29aug19)
git-svn-id: svn://tug.org/texlive/trunk@51977 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source')
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/checkcites/checkcites.lua240
1 files changed, 155 insertions, 85 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua b/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua
index cdd0df14ef9..c6ff0e396af 100755
--- a/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua
+++ b/Build/source/texk/texlive/linked_scripts/checkcites/checkcites.lua
@@ -1,7 +1,7 @@
#!/usr/bin/env texlua
-- -----------------------------------------------------------------
-- checkcites.lua
--- Copyright 2012, 2017, Enrico Gregorio, Paulo Roberto Massa Cereda
+-- Copyright 2012, 2019, Enrico Gregorio, Paulo Roberto Massa Cereda
--
-- This work may be distributed and/or modified under the conditions
-- of the LaTeX Project Public License, either version 1.3 of this
@@ -145,6 +145,19 @@ local function read(file)
return lines
end
+-- Gets a pluralized word based on a counter.
+-- @param i Counter.
+-- @param a Word in singular.
+-- @param b Word in plural.
+-- @return Either the first or second word based on the counter.
+local function plural(i, a, b)
+ if i == 1 then
+ return a
+ else
+ return b
+ end
+end
+
-- Normalizes the string, removing leading and trailing spaces.
-- @param str String.
-- @return Normalized string without leading and trailing spaces.
@@ -167,15 +180,28 @@ local function blacklist(a)
return false
end
+-- Checks if the key is allowed.
+-- @param v The key itself.
+-- @return Boolean value if the key is allowed.
+local function allowed(key)
+ local keys = { 'string', 'comment' }
+ for _, v in ipairs(keys) do
+ if string.lower(key) == v then
+ return false
+ end
+ end
+ return true
+end
+
-- Extracts the biblographic key.
-- @param lines Lines of a file.
-- @return Table containing bibliographic keys.
local function extract(lines)
local result = {}
for _, line in ipairs(lines) do
- local hit = string.match(line,
- '^%s*%@%w+%s*{%s*(.+),')
- if hit then
+ local key, hit = string.match(line,
+ '^%s*%@(%w+%s*){%s*(.+),')
+ if key and allowed(key) then
if not exists(result, hit) then
hit = normalize(hit)
table.insert(result, hit)
@@ -185,17 +211,48 @@ local function extract(lines)
return result
end
--- Gets a pluralized word based on a counter.
--- @param i Counter.
--- @param a Word in singular.
--- @param b Word in plural.
--- @return Either the first or second word based on the counter.
-local function plural(i, a, b)
- if i == 1 then
- return a
+-- Adds the extension if the file does not have it.
+-- @param file File.
+-- @param extension Extension.
+-- @return File with proper extension.
+local function sanitize(file, extension)
+ extension = '.' .. extension
+ if string.sub(file, -#extension) ~= extension then
+ file = file .. extension
+ end
+ return file
+end
+
+-- Checks if a file exists.
+-- @param file File.
+-- @return Boolean value indicating if the file exists.
+local function valid(file)
+ local handler = io.open(file, 'r')
+ if handler then
+ handler:close()
+ return true
else
- return b
+ return false
+ end
+end
+
+-- Wraps a string based on a line width.
+-- @param str String.
+-- @param size Line width.
+-- @return Wrapped string.
+local function wrap(str, size)
+ local parts = split(str, '[^%s]+')
+ local r, l = '', ''
+ for _, v in ipairs(parts) do
+ if (#l + #v) > size then
+ r = r .. '\n' .. l
+ l = v
+ else
+ l = normalize(l .. ' ' .. v)
+ end
end
+ r = normalize(r .. '\n' .. l)
+ return r
end
-- Backend namespace
@@ -203,11 +260,12 @@ local backends = {}
-- Gets data from auxiliary files (BibTeX).
-- @param lines Lines of a file.
+-- @param rec Recursive switch.
-- @return Boolean indicating if an asterisk was found.
-- @return Table containing the citations.
-- @return Table containing the bibliography files.
-backends.bibtex = function(lines)
- local citations, bibliography = {}, {}
+backends.bibtex = function(lines, rec)
+ local citations, bibliography, invalid = {}, {}, {}
local asterisk, parts, hit = false
for _, line in ipairs(lines) do
hit = string.match(line, '^%s*\\citation{(.+)}$')
@@ -234,18 +292,52 @@ backends.bibtex = function(lines)
table.insert(bibliography, v)
end
end
+ else
+ hit = string.match(line, '^%s*\\@input{(.+)}$')
+ if rec and hit then
+ hit = sanitize(hit, 'aux')
+ if not valid(hit) then
+ table.insert(invalid, hit)
+ else
+ local a, b, c = backends.bibtex(read(hit), false)
+ asterisk = asterisk or a
+ for _, v in ipairs(b) do
+ if not exists(citations, v) then
+ table.insert(citations, v)
+ end
+ end
+ for _, v in ipairs(c) do
+ if not exists(bibliography, v) then
+ table.insert(bibliography, v)
+ end
+ end
+ end
+ end
end
end
end
+ if #invalid ~= 0 then
+ print()
+ print(wrap('Warning: there ' .. plural(#invalid,
+ 'is an invalid reference ', 'are ' ..
+ 'invalid references ') .. 'to the ' ..
+ 'following auxiliary ' .. plural(#invalid,
+ 'file ', 'files ') .. 'that could not ' ..
+ 'be resolved at runtime:', 74))
+ for _, v in ipairs(invalid) do
+ print('=> ' .. v)
+ end
+ end
return asterisk, citations, bibliography
end
-- Gets data from auxiliary files (Biber).
-- @param lines Lines of a file.
+-- @param _ To be discarded with biber.
-- @return Boolean indicating if an asterisk was found.
-- @return Table containing the citations.
-- @return Table containing the bibliography files.
-backends.biber = function(lines)
+backends.biber = function(lines, _)
local citations, bibliography = {}, {}
local asterisk, parts, hit = false
for _, line in ipairs(lines) do
@@ -294,28 +386,16 @@ end
-- Repeats the provided char a certain number of times.
-- @param c Char.
--- @param w Number of times.
+-- @param size Number of times.
-- @return String with a char repeated a certain number of times.
-local function pad(c, w)
+local function pad(c, size)
local r = c
- while #r < w do
+ while #r < size do
r = r .. c
end
return r
end
--- Adds the extension if the file does not have it.
--- @param file File.
--- @param extension Extension.
--- @return File with proper extension.
-local function sanitize(file, extension)
- extension = '.' .. extension
- if string.sub(file, -#extension) ~= extension then
- file = file .. extension
- end
- return file
-end
-
-- Flattens a table of tables into only one table.
-- @param t Table.
-- @return Flattened table.
@@ -343,23 +423,13 @@ local function apply(c, f)
return result
end
--- Wraps a string based on a line width.
--- @param str String.
--- @param size Line width.
--- @return Wrapped string.
-local function wrap(str, size)
- local parts = split(str, '[^%s]+')
- local r, l = '', ''
- for _, v in ipairs(parts) do
- if (#l + #v) > size then
- r = r .. '\n' .. l
- l = v
- else
- l = normalize(l .. ' ' .. v)
- end
- end
- r = normalize(r .. '\n' .. l)
- return r
+-- Search the TeX tree for the file.
+-- @param library The library reference.
+-- @param file The filename.
+-- @param extension The extension.
+-- @return String pointing to the file location.
+local function lookup(library, file, extension)
+ return library.find_file(file, extension)
end
-- Prints the script header.
@@ -370,8 +440,8 @@ print("| _| | -_| _| '_| _| | _| -_|_ -|")
print("|___|_|_|___|___|_,_|___|_|_| |___|___|")
print()
print(wrap('checkcites.lua -- a reference ' ..
- 'checker script (v2.0)', 74))
- print(wrap('Copyright (c) 2012, 2017, ' ..
+ 'checker script (v2.1)', 74))
+ print(wrap('Copyright (c) 2012, 2019, ' ..
'Enrico Gregorio, Paulo ' ..
'Roberto Massa Cereda', 74))
end
@@ -446,36 +516,37 @@ operations.all = function(citations, references)
end
end
--- Checks if a file exists.
--- @param file File.
--- @return Boolean value indicating if the file exists.
-local function valid(file)
- local handler = io.open(file, 'r')
- if handler then
- handler:close()
- return true
- else
- return false
- end
-end
-
-- Filters a table of files, keeping the inexistent ones.
-- @param files Table.
+-- @param lib Search library.
+-- @param enabled Boolean switch to enable lookup.
+-- @param extension Extension for lookup.
-- @return Table of inexistent files.
-local function validate(files)
- local result = {}
+-- @return Table of existent files.
+local function validate(files, lib, enabled, extension)
+ local bad, good = {}, {}
for _, v in ipairs(files) do
if not valid(v) then
- table.insert(result, v)
+ if enabled and lookup(lib, v, extension) then
+ table.insert(good, lookup(lib, v, extension))
+ else
+ table.insert(bad, v)
+ end
+ else
+ table.insert(good, v)
end
end
- return result
+ return bad, good
end
-- Main function.
-- @param args Command line arguments.
-- @return Integer value indicating the status
local function checkcites(args)
+
+ local kpse = require('kpse')
+ kpse.set_program_name('texlua')
+
header()
local parameters = {
@@ -525,8 +596,8 @@ local function checkcites(args)
if keys['version'] or keys['help'] then
if keys['version'] then
print()
- print(wrap('checkcites.lua, version 2.0 (dated August ' ..
- '25, 2017)', 74))
+ print(wrap('checkcites.lua, version 2.1 (dated July ' ..
+ '26, 2019)', 74))
print(pad('-', 74))
print(wrap('You can find more details about this ' ..
@@ -611,16 +682,16 @@ local function checkcites(args)
return sanitize(a, (backend == 'bibtex'
and 'aux') or 'bcf') end)
- local vld = validate(auxiliary)
- if #vld ~= 0 then
+ local invalid, _ = validate(auxiliary, kpse, false, 'aux')
+ if #invalid ~= 0 then
print()
print(pad('-', 74))
print(wrap('I am sorry, but I was unable to ' ..
- 'locate ' .. plural(#vld, 'this file',
+ 'locate ' .. plural(#invalid, 'this file',
'these files') .. ' (the extension ' ..
'is automatically set based on the ' ..
'"' .. backend .. '" backend):', 74))
- for _, v in ipairs(vld) do
+ for _, v in ipairs(invalid) do
print('=> ' .. v)
end
@@ -631,13 +702,13 @@ local function checkcites(args)
'" to files if not provided.', 74))
print()
- print(wrap('Please make sure the ' .. plural(#vld,
+ print(wrap('Please make sure the ' .. plural(#invalid,
'path is', 'paths are') .. ' ' ..
- 'correct and the ' .. plural(#vld,
+ 'correct and the ' .. plural(#invalid,
'file exists', 'files exist') .. '. ' ..
'There is nothing I can do at the moment. ' ..
'Refer to the user documentation for ' ..
- 'details on the file lookup. If ' .. plural(#vld,
+ 'details on the file lookup. If ' .. plural(#invalid,
'this is not the file', 'these are not the ' ..
'files') .. ' you were expecting, ' ..
'double-check your source file or ' ..
@@ -647,7 +718,7 @@ local function checkcites(args)
end
local lines = flatten(apply(auxiliary, read))
- local asterisk, citations, bibliography = backends[backend](lines)
+ local asterisk, citations, bibliography = backends[backend](lines, true)
print()
print(wrap('Great, I found ' .. tostring(#citations) .. ' ' ..
@@ -671,27 +742,27 @@ local function checkcites(args)
bibliography = apply(bibliography, function(a)
return sanitize(a, 'bib') end)
- vld = validate(bibliography)
- if #vld ~= 0 then
+ invalid, bibliography = validate(bibliography, kpse, true, 'bib')
+ if #invalid ~= 0 then
print()
print(pad('-', 74))
print(wrap('I am sorry, but I was unable to locate ' ..
- plural(#vld, 'this file', 'these files') .. ' ' ..
+ plural(#invalid, 'this file', 'these files') .. ' ' ..
'(the extension is automatically set to ' ..
'".bib", if not provided):', 74))
- for _, v in ipairs(vld) do
+ for _, v in ipairs(invalid) do
print('=> ' .. v)
end
print()
- print(wrap('Please make sure the ' .. plural(#vld,
+ print(wrap('Please make sure the ' .. plural(#invalid,
'path is', 'paths are') .. ' ' ..
- 'correct and the ' .. plural(#vld,
+ 'correct and the ' .. plural(#invalid,
'file exists', 'files exist') .. '. ' ..
'There is nothing I can do at the moment. ' ..
'Refer to to the user documentation ' ..
'for details on bibliography lookup. If ' ..
- plural(#vld, 'this is not the file',
+ plural(#invalid, 'this is not the file',
'these are not the files') .. ' you were ' ..
'expecting (wrong bibliography), double-check ' ..
'your source file. The script will end ' ..
@@ -718,4 +789,3 @@ end
os.exit(checkcites(arg))
-- EOF
-