[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#449229: tex-common: texdoc finds html pages from catalogue first



Ralf Stubner <ralf.stubner@web.de> wrote:

> Possbile solutions:
>
> * put 90TeXDoc.cnf as 40TeXDoc.cnf before 45TeXinputs.cnf
> * replace the definitions in 45TeXinputs.cnf by those in 90TeXDoc.cnf
>   and remove the latter file

I think we have already included these variables upstream, and Debian
should put them at the corresponding place. 

> * fix texdoc so that it does not matter if a file is compressed or not

You could give texdoclua a test, which I sent to the texlive list
already, and attach again to this mail.  Although I've written it, I'm
not sure whether the problem is fixed there, but I hope it is.

Regards, Frank



-- 
Frank Küster
Debian Developer (teTeX/TeXLive)

#!/usr/bin/env texlua
--[[ Written in lua by Frank Küster (2007) based on the shell script by
Thomas Esser, David Aspinall, and Simon Wilkinson.
Public domain.]]
--[[ Changelog
 0.3 2007-06-28
 - added changelog
 - better OS detection for default viewer settings
 - removed some debugging code
 - -s now works in dirs without ls-R, too

 0.2 2007-06-28
 - implemented reading of configuration from texmf.cnf
 - fixed "-s" option

 0.1
 - initial public release 
]]

progname = 'texdoc';
version = '0.2';
usage = '      Usage: ' .. progname ..' [-h|--help] name\
	 -h|--help\t\t Show this help\
         -V|--version\t\t Print the version of the program\
         -v|--verbose\t\t Show the command being used to display the documentation\
         -l|--list\t\t List matching files, do not start a viewer.\
         -s|--search\t\t search for name as a pattern';


if not arg[1] then
   print (usage);
   return
end

mode = 'view';
verbose = false;
while table.maxn(arg) > 0 and string.match(arg[1],'^%-') do
   curr_arg = table.remove(arg,1)
   if string.match (curr_arg,'-h') or string.match (curr_arg,'--help') then
      print (usage);
      os.exit(0);
   elseif string.match (curr_arg,'-V') or string.match (curr_arg,'--version') then
      print (progname .. ' version: ' .. version );
      os.exit(0);
   elseif string.match (curr_arg,'-v') or string.match (curr_arg,'--verbose') then
      verbose = true;
   elseif string.match (curr_arg,'-l') or string.match (curr_arg,'--list'   ) then
      mode = 'list';
   elseif string.match (curr_arg,'-s') or string.match (curr_arg,'--search'   ) then
      mode = 'search';
   end
end

--[[ function definitions ]]
function list_iter (t)
   local i = 0
   local n = table.getn(t)
   return function ()
	     i = i + 1
	     if i <= n then return t[i] end
	  end
end


-- [[ functions for the search option ]]
no_lsr_doctrees = {};
function get_lsr_files ()
   local lsr_files = {};
   local pathlist = kpse.expand_braces('$TEXDOCS');
   for path in string.gmatch(pathlist, "[^:;]+") do
      path = string.gsub(path,'//$','')
      local tree_root
      tree_root = string.gsub(path,'doc$','')
      tree_root = string.gsub(tree_root,'^!!','')
      if lfs.isfile(tree_root .. "ls-R") then
	 table.insert(lsr_files,tree_root .. "ls-R")
      else
	 if not string.match(path,'^%.$') and lfs.isdir(path) then
	    table.insert(no_lsr_doctrees,path)
	 end
      end -- does lsRfile exist?
   end -- for path
   local i = 0
   local n = table.getn(lsr_files)
   -- TODO: We completely ignore trees without ls-R files.  Since I
   -- don't know how to get the output of "find" without resorting to
   -- temporary files, anyway, I don't care.
   return function ()
	     i = i +1
	     if i <= n then return lsr_files[i] end
	  end
	     
end -- get_lsr_files()

function deluaficate(oldpat)
   local newpat
   -- better use long strings here, no escaping of \ needed there.
   newpat = string.gsub(oldpat,'([^\\])%-','%1%%%-')
   newpat = string.gsub(newpat,'\\','')
   return newpat
end --deluaficate

docdirs = {}
docfiles = {}
function pattern_search (pattern)
   pattern = deluaficate(pattern)
   -- populate docdirs and doclines list
   for database in get_lsr_files() do
      local texmf_tree = string.gsub(database,'ls%-R$','')
      is_docline = false
      local this_dir -- changed to each individual docdir
      for line in io.lines(database) do
	 if string.match(line,'^./') then
	    -- a directory
	    this_dir = string.gsub(line,'^./',texmf_tree)
	    this_dir = string.gsub(this_dir,':$','/')
	    if string.match(line,'^./doc') then
	       -- the next file lines are in docdir "this_dir"
	       is_docline = true
	       -- save it in the docdirs table
	       table.insert(docdirs,this_dir)
	    else
	       is_docline = false
	    end -- docdir
	 elseif string.match(line,'^%s*$') then
	    -- empty line, do nothing
	 -- now we have only file lines left, are they a docline?
	 elseif is_docline then
	    local fullpath = this_dir .. line
-- 	    print(fullpath)
	    table.insert(docfiles,fullpath)
	 end -- line starting with ./
      end -- for line
   end -- for database
   for no_lsr_dir in list_iter(no_lsr_doctrees) do
      recurse_tree(no_lsr_dir)
   end

   print("Directories that match:")
   for dir in list_iter(docdirs) do
      if string.match(dir,pattern) then
	 print (dir)
      end
   end -- for dir
   print()
   print("Files that match:")
   for file in list_iter(docfiles) do
      if string.match(file,pattern) then
	 print (file)
      end
   end -- for file

end -- function pattern_search()

function recurse_tree (path)
    for file in lfs.dir(path) do
        if file ~= "." and file ~= ".." then
            local f = path..'/'..file
            local attr = lfs.attributes (f)
	    if attr then -- else stale symlink
	       if attr.mode == "directory" then
		  table.insert(docdirs,f)
		  recurse_tree (f)
	       else
		  table.insert(docfiles,f)
	       end
            end
        end
    end
 end --function recurse_tree


--[[ functions for parsing texmf.cnf ]]
function set_var_from_texmf(oldvalue,texmfvar)
   local newvalue
   newvalue = kpse.var_value(texmfvar)
   if newvalue then
      return newvalue
   else
      return oldvalue
   end
end
function set_listvar_from_texmf(oldvalue,texmfvar)
   local list_as_string
   local templist = {}
   list_as_string = set_var_from_texmf('',texmfvar)
   for element in string.gmatch(list_as_string,'[^,;:]+') do
      table.insert(templist,element)
   end
   if table.maxn(templist) > 0 then
      return templist
   else
      return oldvalue
   end
end -- set_listvar_from_texmf

function set_listvar_from_expand_braces(oldvalue,texmfvar)
   local list_as_string
   local templist = {}
   list_as_string = kpse.expand_braces(texmfvar)
   for element in string.gmatch(list_as_string,'[^,;:]*:') do
      element = string.gsub(element,':','')
      table.insert(templist,element)
   end
   if table.maxn(templist) > 0 then
      return templist
   else
      return oldvalue
   end
end -- set_listvar_from_expand_braces

--[[ initialize kpathsea ]]
kpse.set_program_name("texdoc")

-- [[ initialize some variables ]]
texdoc_formats = {'dvi','pdf','ps','txt','html'}

if string.find(os.getenv("PATH"),";") then
   -- probably Windows (or OS/2)
   -- which commands should we use for unzipping?
   texdoc_unzip = { 
      gz = "gzip -d -c ",
      bz2 = "bzip2 -d -c "
   };
   texdoc_viewer = {
      dvi  = '(start /wait %s ) &',
      html = '(start /wait %s) &',
      pdf = '(start /wait %s) &',
      ps = '(start /wait %s) &',
      txt = '(start /wait %s) &',
      tex = '(start /wait %s) &'
   };
   rmfile_command = 'del /F ';
   rmdir_command = 'rmdir ';
else
   -- probably UNIX-like
   texdoc_unzip = { 
      gz = "gzip -d -c ",
      bz2 = "bzip2 -d -c "
   };
   texdoc_viewer = { 
      dvi  = '(xdvi %s ) &',
      html = '(see %s) &',
      pdf = '(xpdf %s) &',
      ps = '(gv %s) &',
      txt = '(less %s )',
      tex = '(less %s )'
   };
   rmfile_command = 'rm -f ';
   rmdir_command = 'rmdir ';
end

texdoc_zipformats = {'','gz','bz2'};
texdoc_formats = {'','dvi','html','pdf','ps','txt','tex'};
extlist = {'','.dvi', '.dvi.gz', '.dvi.bz2', '.pdf', '.pdf.gz', '.pdf.bz2', '.ps', '.ps.gz', '.ps.bz2', '.txt', '.txt.gz', '.txt.bz2', '.html'};

-- [[ override hardcoded variables with values from texmf.cnf ]]
rmfile_command = set_var_from_texmf(rmfile_command,'TEXDOC_RMFILE')
rmdir_command = set_var_from_texmf(rmdir_command,'TEXDOC_RMDIR')
texdoc_formats = set_listvar_from_texmf(texdoc_formats,'TEXDOC_FORMATS')
for format in list_iter(texdoc_formats) do
   viewer_var = 'TEXDOC_VIEWER_' .. string.upper(format)
   texdoc_viewer[format] = set_var_from_texmf(texdoc_viewer[format],viewer_var)
end
texdoc_zipformats = set_listvar_from_texmf(texdoc_zipformats,'TEXDOC_ZIPFORMATS')
for zipext in list_iter(texdoc_zipformats) do
   viewer_var = 'TEXDOC_UNZIP_' .. string.upper(zipext)
   texdoc_unzip[zipext] = set_var_from_texmf(texdoc_unzip[zipext],viewer_var)
end
extlist = set_listvar_from_expand_braces(extlist,'$TEXDOCEXT');
-- we want an empty string for ext at the beginning, so that it works
-- to specify the complete filename.  Doesn't matter when there's one
-- more empty string, but we can easily avoid two in a row
if not extlist[1] == '' then
   insert(extlist,1,'')
end


for docname in list_iter (arg) do
   if string.match(mode,'search') then
      pattern_search(docname);
   elseif string.match(mode,'view') or string.match(mode,'list') then
      for ext in list_iter(extlist) do
	 filename = kpse.find_file(docname .. ext , "TeX system documentation")

	 if filename then
	    if string.match (mode, 'list') then
	       print(filename);
	    else
	       -- mode is view, is unzipping needed?
	       zipext = string.match(ext,'%..*%.(.*)');
	       if zipext then
		  unzip_command = texdoc_unzip[zipext];
		  viewext = string.match(ext,'%.(.*)%..*$');
		  basebame_pattern = '.*/(.*%.' .. viewext .. ')';
		  basename = string.match(filename,basebame_pattern);

		  -- uncompress only once per file, in case it is given more
		  -- than once (dvi besides ps or so)
		  -- TODO: to be done

		  tmpdir = os.tmpname();
		  is_ok_tmpdir,error_string = lfs.mkdir(tmpdir)
		  if is_ok_tmpdir then
		     -- 		  needs_cleanup = true;
		  else
		     print(error_string);
		     os.exit(1);
		  end
		  
		  unzip_commandline = unzip_command .. filename .. " > " .. tmpdir .. "/" .. basename;
		  if os.execute(unzip_commandline) then
		     filename = tmpdir .. "/" .. basename;
		  else
		     print("Error executing \n" .. unzip_commandline);
		  end
		  viewer_replacement = filename .. ';' .. rmfile_command .. filename .. ';' .. rmdir_command .. tmpdir;
	       else
		  if ext == '' then
		     -- fallback if complete filename has been specified
		     ext = string.match(filename,'.*(%..*)$')
		     if not ext then
			-- still no extension for filenames like README
			ext = 'txt';
		     end
		  end
		  viewer_replacement = filename;
		  viewext = string.match(ext,'%.(.*)$');
		  if not viewext or not texdoc_viewer[viewext] then
		     -- complete filename specified, unknown extension, use "txt"
		     viewext = 'txt'
		  end
	       end -- zipped or not
	       view_command = string.gsub(texdoc_viewer[viewext],'%%s',viewer_replacement)
	       if verbose then
		  print(view_command);
	       end
	       view_result = os.execute(view_command);
	       if view_result then
		  do break end;
	       else
		  print("Error executing \n" .. view_command);
	       end
	    end -- list or view
	 end -- found a filename with that extension or not?
      end -- for ext
   end -- if construct "case mode in"
end -- for docname

-- cleanup_tmpdir();

Reply to: