/usr/share/texmf-texlive/scripts/texdoc/view.tlu is in texlive-base 2009-15.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | -- view a document and/or display the list of results in texdoc
--[[
Copyright 2008, 2009 Manuel Pégourié-Gonnard
Distributed under the terms of the GNU GPL version 3 or later.
See texdoc.tlu for details.
--]]
local L = {}
load_env(L, {
'export_symbols',
'string', 'os', 'table', 'io',
'tonumber', 'ipairs', 'print', 'assert',
'config',
'C',
'deb_print', 'err_print', 'parse_zip',
})
----------------------------- view a document ------------------------------
-- view a document
-- see search.tlu for the structure of the argument
function view_doc(docfile)
return view_file(docfile.realpath)
end
-- get viewer and viewer_replacement before calling try_viewing
-- returns false of failure, true on success
-- viewer_replacement is either:
-- 1. the filename, quoted with "
-- 2. the filename, quoted with " followed by some rm commands
-- The second case happens when the doc was zipped. In the case, this function
-- unzips it in a tempdir so that the viewer command can use the unzipped file.
function view_file (filename)
local viewer, viewer_replacement
-- check if the file is zipped
local nozipname, zipext = parse_zip(filename)
-- determine viewer_replacement
if zipext then
local unzip_cmd = config['unzip_'..zipext]
if not unzip_cmd then
err_print('error',
"No unzip command for ."..zipext..' files, skipping '..filename)
return false
end
local tmpdir = os.tmpdir("/tmp/texdoc.XXXXXX")
if not tmpdir then
err_print('error', 'Failed to create tempdir to unzip.')
return false
end
local basename = string.match(nozipname, '.*/(.*)$') or nozipname
local tmpfile = '"'..tmpdir..'/'..basename..'"'
local unzip = unzip_cmd..' "'..filename..'">'..tmpfile
deb_print('view', "Unzip command: "..unzip)
if not os.execute(unzip) then
err_print('error', "Failed to unzip '"..filename.."'")
os.remove(tmpfile)
os.remove(tmpdir)
return false
end
viewer_replacement = ''..tmpfile..'; '
..config.rm_file..' '..tmpfile..'; '
..config.rm_dir..' '..tmpdir
filename = nozipname
else
viewer_replacement = '"'..filename..'"'
end
-- files without extension are assumed to be text
local viewext = string.match(filename,'.*%.([^/]*)$') or 'txt'
-- special case : sty files use txt viewer
if viewext == 'sty' then viewext = 'txt' end
if not config['viewer_'..viewext] then
err_print('warning',
"No viewer_"..viewext.." defined, using viewer_txt.")
viewext = 'txt'
end
assert(config['viewer_'..viewext], 'Internal error: no viewer found.')
return try_viewing(config['viewer_'..viewext], viewer_replacement)
end
-- view a file, if possible
function try_viewing (view_command, viewer_replacement)
if string.match (view_command, C.place_holder) then
view_command = string.gsub(
view_command, C.place_holder, viewer_replacement)
else
view_command = view_command..' '..viewer_replacement
end
deb_print('view', 'View comand: '..view_command)
if not os.execute(view_command) then
err_print('error', "Failed to execute '"..view_command.."'")
return false
end
return true
end
----------------------------- display results ------------------------------
-- print a list of files (structure: see search.tlu) as a menu
-- if showall is false, stops as soon a bad result is encountered
function print_menu(name, doclist, showall)
local max_lines = tonumber(config.max_lines) or 20
if config.interact_switch and doclist[max_lines+1] then
-- there may be too many lines, count them
local n
if showall then
n = #doclist
else
n = 0
while doclist[n+1] and doclist[n+1]:quality() == 'good' do
n = n + 1
end
end
if n > max_lines then
io.write (n, " results. Display them all? (y/N) ")
local ans = io.read('*line')
if not ((ans == 'y') or (ans == 'Y')
-- io.read had a bug wrt windows eol on some versions of texlua
or (ans == '\ry') or (ans == '\rY')) then
return
end
end
end
local i, doc
for i, doc in ipairs (doclist) do
if doc:quality() == 'killed' then break end
if doc:quality() ~= 'good' and not showall then break end
if config.machine_switch == true then
print(name, doc.score, doc.realpath)
else
print(string.format('%2d %s', i, doc.realpath))
end
end
if config.interact_switch then
io.write ("Please enter the number of the file to view, ",
"anything else to skip: ")
local num = tonumber(io.read('*line'))
if num and doclist[num] then
view_doc(doclist[num])
end
end
end
----------------------- deliver results base on mode -----------------------
function deliver_results(name, doclist, many)
-- ensure that results were found or apologize
if not doclist[1] or doclist[1]:quality() == 'killed' then
if not config.machine_switch then
local msg = string.gsub(C.notfound_msg, C.notfound_msg_ph, name)
print(msg) -- get rid of gsub's 2nd value
end
return
end
-- shall we show all of them or only the "good" ones?
local showall = (config.mode == 'regex') or (config.mode == 'showall')
if not showall and doclist[1]:quality() ~= 'good' then
showall = true
err_print('info', 'No good result found, showing all results.')
end
-- view result or show menu based on mode and number of results
if (config.mode == 'view')
or config.mode == 'mixed' and (not doclist[2]
or (doclist[2]:quality() ~= 'good' and not showall)) then
view_doc(doclist[1])
else
if many and not config.machine_switch then
print ("*** Results for: "..name.." ***")
end
print_menu(name, doclist, showall)
end
end
-- finally export a few symbols
export_symbols(L, {
'deliver_results',
})
|