[tex-live] texdoc in luatex

Frank Küster frank at kuesterei.ch
Tue Jun 26 16:36:27 CEST 2007

Frank Küster <frank at kuesterei.ch> wrote:

> Thanks, I've started working on "texdoclua".  

So here is the next iteration.  It basically does what it is supposed

$ texdoclua -h 
      Usage: texdoc [-h|--help] name
	 -h|--help		 Show this help
         -v|--version		 Print the version of the program
         -l|--list		 List matching files, do not start a viewer.
         -s|--search		 search for name as a pattern

Some remarks:

- I like it, it's lightning fast, and it doesn't even need the
  NODOC_PATTERN I had to use in the bash version

- the shebang line is not yet fixed, since the Debian package doesn't
  install /usr/bin/texlua yet.

- The search option now accepts lua patterns instead of egrep patterns.
  It shouldn't be too hard to use egrep instead, but for sure it's
  slower (one external egrep process for each file in a documentation

  So the question is whether people actually use the egrep features.

  Myself, I use -s mostly if I don't remember whether the doc for that
  list layout package I'm searching is called "$package.ps",
  "manual.dvi" or "user.pdf", but it must be in a directory containing
  "list", probably "par.*list".  This works as before.  You can even
  search for c[oau]ncrete if you're not sure about english
  pronounciation/spelling relations, but 'colo(u|)r' does not work (but
  it works with the egrep patterns in bash texdoc).

  I'd really appreciate if people could comment on this.

- All variables are still hardcoded, reading them from texmf.cnf is the
  next step.

TIA, Frank

Frank Küster
Single Molecule Spectroscopy, Protein Folding @ Inst. f. Biochemie, Univ. Zürich
Debian Developer (teTeX/TeXLive)

-------------- next part --------------
--[[ Written in lua by Frank Küster (2007) based on the shell script by
Thomas Esser, David Aspinall, and Simon Wilkinson.
Public domain.]]

progname = 'texdoc';
version = '0.1';
usage = '      Usage: ' .. progname ..' [-h|--help] name\
	 -h|--help\t\t Show this help\
         -v|--version\t\t Print the version of the program\
         -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);

if string.match (arg[1],'^-') then
   if string.match (arg[1],'-h') or string.match (arg[1],'--help') then
      print (usage);
   elseif string.match (arg[1],'-v') or string.match (arg[1],'--version') then
      print (progname .. ' version: ' .. version );
   elseif string.match (arg[1],'-l') or string.match (arg[1],'--list'   ) then
      mode = 'list';
      iter_arg_start = 1;
   elseif string.match (arg[1],'-s') or string.match (arg[1],'--search'   ) then
      mode = 'search';
      iter_arg_start = 1;
   mode = 'view';
   iter_arg_start = 0;

--[[ 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

function list_iter_arg (t,start)
   local i = start
   local n = table.getn(t)
   return function ()
	     i = i + 1
	     if i <= n then return t[i] end

local tmpdir;
function cleanup_tmpdir ()
   local is_successful
   local error_string
   if needs_cleanup then
      is_successful,error_string = lfs.rmdir (tmpdir);
      if is_successful then
	 print ("removing worked");
	 print ("removing failed");
	 print (error_string);

-- [[ functions for the search option ]]

function get_lsr_files ()
   local lsr_files = {};
   local pathlist = kpse.expand_braces('$TEXDOCS');
   for path in string.gmatch(pathlist, "[^:]*") do
      path = string.gsub(path,'doc//$','')
      path = string.gsub(path,'^!!','')
      if lfs.isfile(path .. "ls-R") then
	 table.insert(lsr_files,path .. "ls-R")
      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 -- get_lsr_files()

docdirs = {}
docfiles = {}
function pattern_search (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
	       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 = texmf_tree .. this_dir .. line
-- 	    print(fullpath)
	 end -- line starting with ./
      end -- for line
   end -- for database

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

end -- function pattern_search()

--[[ initialize kpathsea ]]

-- [[ initialize some variables ]]
verbose = false;
nodoc_pattern = [=[\.tfm|\.afm|\.enc|\.pfb|\.pfa|\.pfm|\.vf|\.fd|\.ttf|\.htf|\.mf|\.otf|\.[[:digit:]]*pk]=];
extlist = {'.dvi', '.dvi.gz', '.dvi.bz2', '.pdf', '.pdf.gz', '.pdf.bz2', '.ps', '.ps.gz', '.ps.bz2', '.txt', '.txt.gz', '.txt.bz2', '.html'};
texdoc_unzip = { gz = "gzip -d -c ", bz2 = "bzip2 -d -c "};
texdoc_viewer = { 
   dvi  = '(xdvi %s ) &',
   html = '(see %s) &',
   pdf = '(see %s) &'
rmfile_command = 'rm -f ';
rmdir_command = 'rmdir ';

-- needs_cleanup = false;

for docname in list_iter_arg (arg,iter_arg_start) do
   if string.match(mode,'search') then
   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
	       -- 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;
		  unzip_commandline = unzip_command .. filename .. " > " .. tmpdir .. "/" .. basename;
		  if os.execute(unzip_commandline) then
		     filename = tmpdir .. "/" .. basename;
		     print("Error executing \n" .. unzip_commandline);
		  viewer_replacement = filename .. ';' .. rmfile_command .. filename .. ';' .. rmdir_command .. tmpdir;
		  viewer_replacement = filename;
		  viewext = string.match(ext,'%.(.*)$');
	       end -- zipped or not
	       view_command = string.gsub(texdoc_viewer[viewext],'%%s',viewer_replacement)
	       view_result = os.execute(view_command);
	       if view_result then
		  do break end;
		  print("Error executing \n" .. view_command);
	    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();

More information about the tex-live mailing list