Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is it possible to generate a TeX-file with all information needed about the installed packages of a TeXLive distribution?

If you want only certain elements of the table, you can use this snippet. :-)

\begin{filecontents*}{\jobname.lua}
 dofile( assert( kpse.find_file( "tlpdb.tlu", "texmfscripts" ) ) )
 tlpdb = read_tlpdb( kpse.var_value("SELFAUTOPARENT") )
 for name, pkg in pairs( tlpdb ) do 
  texio.write_nl( name )
  tex.print( "\\section*{" )
  tex.print( name )
  tex.print( "}" )
  tex.print( "" )
  if pkg.longdesc ~= nil then
    tex.write( tostring(pkg.longdesc) )
    tex.print( "" )
  end
  if pkg. revision ~= nil then
    tex.write( tostring(pkg.longdesc) )
    tex.print( "" )
  tex.print( "\\clearpage" )
end
\end{filecontents*}
share|improve this question
add comment

2 Answers

up vote 12 down vote accepted

The information about installed packages is stored in a plain text database <installation root>/tlpkg/texlive.tlpdb. For a simple list of packages in a database you can use this one-liner:

awk '/^name/ {print $2}' texlive.tlpdb

For anything more complicated you would need to parse the database file yourself (if you know perl or lua you could use some code from TeX Live for that purpose).

Edit: here's an example using luatex that prints info about each package on a separate page (Edit2: with package names sorted alphabetically).

\begin{filecontents*}{\jobname.lua}
dofile( assert( kpse.find_file( "tlpdb.tlu", "texmfscripts" ) ) )
tlpdb = read_tlpdb( kpse.var_value( "SELFAUTOPARENT" ) )
pkglist = {}
for name in pairs( tlpdb ) do 
  table.insert( pkglist, name )
end
table.sort( pkglist )
for i, name in ipairs( pkglist ) do 
  texio.write_nl( name )
  tex.print( "PACKAGE: " .. name )
  tex.print( "" )
  for field, value in pairs( tlpdb[name] ) do 
    if type( value ) ~= "table" then
      tex.write( field .. ": " .. tostring( value ) )
      tex.print( "" )
    end
  end
  tex.print( "\\clearpage" )
end
\end{filecontents*}
\documentclass{article}
\begin{document}
\directlua{ dofile "\jobname.lua" }
\end{document}
share|improve this answer
add comment

I took up the challenge with pdf(La)TeX (and the code could easily be modified to use only eTeX). It ain't pretty. It should produce a ~5000 pages long pdf file with all the info (and it takes forever to compile... like, 4hrs). I had to hard-code the path of the texlive install (first line of the code).

\def\tlpath{/usr/local/texlive/2011}
\documentclass{book}
\usepackage[T1]{fontenc}
\makeatletter
\newread\tl@read
\openin\tl@read \tlpath/tlpkg/texlive.tlpdb\relax
\newif\if@tl@itemize
\def\tl@analyse#1 {%
  \ifcsname #1\endcsname
    \csname #1\expandafter\endcsname
  \else
    \tl@open@if@new{#1}{#1\begin{itemize}}\@tl@itemizetrue{}%
    \def\tl@current{#1}%
    \expandafter\tl@unknown
  \fi}
\def\tl@open@if@new#1#2#3#4%
  {%
    \ifnum\pdfstrcmp{#1}{\tl@current}=0\relax
      \g@addto@macro\tl@text{#4}%
    \else
      \ifx\tl@text\empty\else
        \if@tl@itemize
          \g@addto@macro\tl@text{\end{itemize}}%
        \fi
      \fi
      \@tl@itemizefalse
      #3%
      \g@addto@macro\tl@text{\item#2}%
    \fi
    \def\tl@current{#1}%
  }
\def\tl@unknown#1\relax{%
  \if@tl@itemize
    \g@addto@macro\tl@text{\item#1}%
  \else
    \g@addto@macro\tl@text{#1}%
  \fi}
\let\tl@current\empty
\let\tl@name\empty
\def\tl@i{}
\def\tl@i@relax#1#2\relax{#1}
\def\tl@flush{%
  \tl@open@if@new{*}{}{\@gobblefour{}}{}%
  \ifx\tl@name\empty\else
    \ifnum\pdfstrcmp{\expandafter\tl@i@relax\tl@name\relax}{\tl@i}=0\relax
    \else
      \edef\tl@i{\expandafter\tl@i@relax\tl@name\relax}%
      \chapter{Packages starting with \tl@i}%
    \fi
    \section{\rmfamily\tl@name
      \ifx\tl@category\empty\else\space(\tl@category)\fi
      \ifx\tl@revision\empty\else \space r. \tl@revision\fi}%
    \begin{itemize}\tl@text\end{itemize}%
  \fi
  \let\tl@text\empty\let\tl@category\empty
  \let\tl@name\empty\let\tl@revision\empty}
\def\name#1\relax{\tl@flush\def\tl@name{#1}}
\def\category#1\relax{\def\tl@category{#1}}
\def\revision#1\relax{\def\tl@revision{#1}}
\def\tl@oneliner#1#2#3\relax{\tl@open@if@new{#1}{#2: #3}{}{}}
\def\tl@def@oneliner#1#2{\expandafter\def\csname#1\endcsname
  {\tl@oneliner{#1}{#2}}}
\tl@def@oneliner{catalogue}{Catalogue}
\tl@def@oneliner{shortdesc}{Short description}
\tl@def@oneliner{relocated}{Relocated}
\tl@def@oneliner{containersize}{Container size}
\tl@def@oneliner{containermd5}{Container md5}
\tl@def@oneliner{doccontainersize}{Doc container size}
\tl@def@oneliner{doccontainermd5}{Doc container md5}
\tl@def@oneliner{srccontainersize}{Source container size}
\tl@def@oneliner{srccontainermd5}{Source container md5}
\tl@def@oneliner{catalogue-ctan}{On CTAN}
\tl@def@oneliner{catalogue-date}{Dated}
\tl@def@oneliner{catalogue-license}{License}
\tl@def@oneliner{catalogue-version}{Version}
\def\longdesc#1\relax{\tl@open@if@new{longdesc}{Long description: #1}{}{#1}}
\def\docfiles#1\relax{\tl@open@if@new{docfiles}%
  {Doc files: #1\@gobble}{\def\tl@current{}}{}}
\def\runfiles#1\relax{\tl@open@if@new{runfiles}%
  {Run files: #1\@gobble}{\def\tl@current{}}{}}
\def\srcfiles#1\relax{\tl@open@if@new{srcfiles}%
  {Source files: #1\@gobble}{\def\tl@current{}}{}}
\begin{document}
\title{All of the packages in \TeX{}live}
\author{}
\maketitle
\tableofcontents
\endlinechar=-1\relax
\loop
\readline\tl@read to\tl@line
  \ifx\empty\tl@line
    \clearpage
  \else
    \expandafter\tl@analyse\tl@line\relax
  \fi
\unless\ifeof\tl@read
\repeat
\end{document}
share|improve this answer
2  
You can avoid hard coding the path: \usepackage{catchfile}\CatchFileDef{\tlpath}{|"kpsewhich --var-value SELFAUTOPARENT"}{} \begingroup\makeatletter \edef\x{\endgroup\edef\noexpand\tlpath{\noexpand\zap@space\tlpath\space\noexpand‌​\@empty}}\x Works also without calling with the --shell-escape option (TeX Live 2010 or later) –  egreg Dec 19 '11 at 18:25
    
The final pdf had 5203 pages (not counting the toc: I'm not ready to compile a second time). –  Bruno Le Floch Dec 19 '11 at 18:33
    
@egreg: I wasn't expecting it to be possible without --shell-escape. –  Bruno Le Floch Dec 19 '11 at 18:34
    
kpsewhich is one of the allowed programs for the restricted shell escape, along with bibtex, bibtex8, makeindex and repstopdf. –  egreg Dec 19 '11 at 18:36
    
@egreg: thanks. The macros I'm using here are too slow to be of any practical use anyways, so I won't bump the question just to add your suggestion. I hope you don't mind. –  Bruno Le Floch Dec 19 '11 at 18:52
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.