diff options
author | Manuel Pégourié-Gonnard <mpg@elzevir.fr> | 2009-11-24 19:46:08 +0000 |
---|---|---|
committer | Manuel Pégourié-Gonnard <mpg@elzevir.fr> | 2009-11-24 19:46:08 +0000 |
commit | aa1420a6770a5148a153b2b1e4283fb91a9a3d3b (patch) | |
tree | d9582016d27249d388221be878ae5b3c2e6d6265 /Master | |
parent | 01da98ba6f4010aa1cf6163e019c8ebeb24f68bd (diff) |
Texdoc 0.60.
git-svn-id: svn://tug.org/texlive/trunk@16153 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf/doc/man/man1/texdoc.1 | 20 | ||||
-rw-r--r-- | Master/texmf/doc/man/man1/texdoc.man1.pdf | bin | 5407 -> 5529 bytes | |||
-rw-r--r-- | Master/texmf/doc/texdoc/News | 12 | ||||
-rw-r--r-- | Master/texmf/doc/texdoc/texdoc.pdf | bin | 195730 -> 192095 bytes | |||
-rw-r--r-- | Master/texmf/doc/texdoc/texdoc.tex | 748 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/config.tlu | 126 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/constants.tlu | 36 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/functions.tlu | 48 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/main.tlu | 15 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/score.tlu | 226 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/search.tlu | 364 | ||||
-rwxr-xr-x | Master/texmf/scripts/texdoc/texdoc.tlu | 11 | ||||
-rw-r--r-- | Master/texmf/scripts/texdoc/view.tlu | 77 | ||||
-rw-r--r-- | Master/texmf/texdoc/texdoc.cnf | 134 |
14 files changed, 1083 insertions, 734 deletions
diff --git a/Master/texmf/doc/man/man1/texdoc.1 b/Master/texmf/doc/man/man1/texdoc.1 index 1de3dc1a163..685917fbf8e 100644 --- a/Master/texmf/doc/man/man1/texdoc.1 +++ b/Master/texmf/doc/man/man1/texdoc.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. -.TH TEXDOC "1" "November 2009" "texdoc 0.50" "User Commands" +.TH TEXDOC "1" "November 2009" "texdoc 0.60" "User Commands" .SH NAME texdoc \- find & view documentation in TeX Live .SH SYNOPSIS @@ -13,9 +13,6 @@ the usual \fB\-\-help\fR and \fB\-\-version\fR options are also accepted. \fB\-f\fR, \fB\-\-files\fR Print the name of the config files being used. .TP -\fB\-e\fR, \fB\-\-extensions\fR=\fIL\fR -Require file extensions to be in the list L. -.TP \fB\-w\fR, \fB\-\-view\fR Use view mode: start a viewer. .TP @@ -23,13 +20,16 @@ Use view mode: start a viewer. Use mixed mode (view or list). .TP \fB\-l\fR, \fB\-\-list\fR -Use list mode: don't start a viewer. +Use list mode: show a list of results. .TP -\fB\-s\fR, \fB\-\-search\fR -Search for name as a substring. +\fB\-s\fR, \fB\-\-showall\fR +Use showall mode: show also "bad" results. .TP \fB\-r\fR, \fB\-\-regex\fR -Search for name as a lua regex. +Use regex mode. (Deprecated.) +.TP +\fB\-e\fR, \fB\-\-extensions\fR=\fIL\fR +Set ext_list=L. (Deprecated.) .TP \fB\-a\fR, \fB\-\-alias\fR Use the alias table. @@ -46,8 +46,8 @@ Use plain lists, no interaction required. \fB\-v\fR, \fB\-\-verbosity\fR=\fIN\fR Set verbosity level to N. .TP -\fB\-d\fR, \fB\-\-debug\fR -Set verbosity level to maximum. +\fB\-d\fR, \fB\-\-debug\fR[=\fIlist\fR] +Activate debug for selected items (default all). .TP \fB\-M\fR, \fB\-\-machine\fR Use a more machine\-friendly output format. diff --git a/Master/texmf/doc/man/man1/texdoc.man1.pdf b/Master/texmf/doc/man/man1/texdoc.man1.pdf Binary files differindex 0bdc7b39053..45f5498511f 100644 --- a/Master/texmf/doc/man/man1/texdoc.man1.pdf +++ b/Master/texmf/doc/man/man1/texdoc.man1.pdf diff --git a/Master/texmf/doc/texdoc/News b/Master/texmf/doc/texdoc/News index 6de6cec2915..1412794498f 100644 --- a/Master/texmf/doc/texdoc/News +++ b/Master/texmf/doc/texdoc/News @@ -1,3 +1,15 @@ +Version 0.60 +------------ + +Changed the search/alias/score logic. See section 2 of the manual for details, +but here is a primer: +- alias now /adds/ patterns to be search, it is no more a substitution +- new scoring system, partially confugurable, with improved heuristics + +The beginning of the manual has been completely rewritten. + +Bug have been fixed as usual, and probably some others introduced... + Version 0.50 ------------ diff --git a/Master/texmf/doc/texdoc/texdoc.pdf b/Master/texmf/doc/texdoc/texdoc.pdf Binary files differindex 1e11d7435c1..815f4bd0b47 100644 --- a/Master/texmf/doc/texdoc/texdoc.pdf +++ b/Master/texmf/doc/texdoc/texdoc.pdf diff --git a/Master/texmf/doc/texdoc/texdoc.tex b/Master/texmf/doc/texdoc/texdoc.tex index 4939833527e..9d4a4677f39 100644 --- a/Master/texmf/doc/texdoc/texdoc.tex +++ b/Master/texmf/doc/texdoc/texdoc.tex @@ -2,20 +2,24 @@ % written by Manuel Pégourié-Gonnard in 2008, 2009 % distributed under the terms of GPL v3 or later +%!TEX encoding=latin1 +%!TEX program=pdflatex + +\setlength\overfullrule{5pt} + \documentclass[a4paper, oneside]{scrartcl} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage{fixltx2e} -\usepackage{lmodern} \edef\ttmodern{\ttdefault} -\usepackage[osf]{mathpazo} -\renewcommand\sfdefault{uop} % optima -\renewcommand\ttdefault{lmvtt} % lm tt proportional +\usepackage{tgbonum} +\usepackage{tgheros} +\usepackage[scaled=1.10]{inconsolata} \renewcommand\familydefault{\sfdefault} \normalfont \newcommand\otherfamily{\rmfamily} -\newcommand\mylangle{\textlangle} -\newcommand\myrangle{\textrangle} +\newcommand\mylangle{$\langle$} +\newcommand\myrangle{$\rangle$} \usepackage{xargs, xspace, fancyvrb, xcolor, pifont, calc, ifmtarg, mathstyle} @@ -23,7 +27,8 @@ \titlelabel{\makebox[0pt][r]{\thetitle\kern1pc}} \titleformat{\subsubsection}[runin]{\otherfamily\itshape}{% \makebox[0pt][r]{\thetitle\kern1pc}}{% - 0pt}{}[\maybedot\space --- ] + 0pt}{}[\maybedot\space --- \kern0pt] +\titlespacing{\subsubsection}{0pt}{0.5\baselineskip}{0pt} \usepackage{enumitem} \newlength\lssep \setlength\lssep{\smallskipamount} @@ -34,7 +39,7 @@ \usepackage[bookmarks=true]{hyperref} \hypersetup{% bookmarksnumbered=true, bookmarksopen=true, bookmarksopenlevel=2, - pdftitle=texdoc: finding and viewing TeX documentation, + pdftitle=texdoc: find and view documentation in TeX Live, pdfauthor=Manuel Pégourié-Gonnard, pdfsubject=texdoc's user manual, pdfkeywords={texdoc, TeX Live, manual}} @@ -62,8 +67,6 @@ \definecolor{input}{rgb}{1.0,0,0} \newcommand\inputcolorname{red} \hypersetup{colorlinks=true, linkcolor=links, urlcolor=links, citecolor=links} -\newcommand\textpa[1]{% % noms d'extensions (package) - {\normalfont\color{special}\otherfamily #1}} \newcommand\cofont{% % code \color{code}\normalfont\ttfamily} \newcommand\textco[1]{{\cofont#1}} @@ -78,7 +81,7 @@ \newcommand\file{\nolinkurl} % take care of nbsp -\catcode`\ 10\relax +\catcode`\ 10\relax \newcommand\meta[1]{% % variantes à remplacer {\color{special}\mylangle\textme{#1}\myrangle}} @@ -138,296 +141,286 @@ }{% \endcommandes} +\makeatletter \newenvironment{htcode}{% % code en hors-texte \SaveVerbatim[samepage, gobble=2]{verbmat}% }{% \endSaveVerbatim \par\medskip\noindent\hspace*{\parindent}% \BUseVerbatim{verbmat}% - \par\medskip} + \par\medskip\@endpetrue} +\makeatother \DefineShortVerb{\©} \setkomafont{title}{} \setkomafont{subtitle}{\Large} \deffootnote[1.5em]{1.5em}{1em}{\textsuperscript{\thefootnotemark}\thinspace} -\newcommand\texdoc{\textpa{texdoc}\xspace} +\newcommand\texdoc{texdoc\xspace} +\newcommand\tdml{\href{mailto:texdoc@tug.org}{texdoc mailing list}\xspace} \title{\texdoc} -\subtitle{Finding \& viewing \TeX documentation - } +\subtitle{Find \& view documentation in \TeX\ Live} \author{\url{http://tug.org/texdoc/}\\ Manuel Pégourié-Gonnard} -\date{v0.47 2009-10-12} +\date{v0.60 2009-11-24} \begin{document} \VerbatimFootnotes \maketitle -\section{Basic Usage, Modes}\label{s-basics} +\section{Quick guide} -\begin{cmdsubsec}{Normal (view) mode}{ss-view} - texdoc «name» -\end{cmdsubsec} +\subsection{Basics} -The simplest way to use \texdoc is just to type\footnote{In a command line. If - you don't know how to open one, look for Start$\to$Execute and type ©cmd© on - Windows, or use the ``terminal'' icon on Mac OS X. If you are using another - flavour of Unix, you probably know what to do.} ©texdoc© followed by the -name of the package whose documentation you want to read. It usually finds -the documentation for you and opens it in the appropriate reader. That's it: -easy and usually fast. The rest of this manual describes what to do if -this doesn't work exactly as you like and you want to customise things, and -how to do more extensive searchs. +Open a command line\footnote{On windows, use ``Execute'' from the Start menu + and type ©cmd©. On Mac OS X, use the ``terminal'' icon on Mac OS X. If you + are using another flavour of Unix, you probably know what to do.} and type +©texdoc «name»©: the documentation of the ©«name»© package will pop up. Of +course, replace ©«name»© with the actual name of the package you want to learn +about. You can also look for the documentation of more than one package at +once: just give many names as arguments. + +The rest of this section describes the most usual options, like how to +see all documentation related to a package or use a different viewer. + +\subsection{Modes}\label{ss-modes} + +\texdoc has different modes that determine how results will be handled. The +default mode, called ``view'' mode, is to open the first (supposedly the best) +result in a viewer. It is rather handy when you know what you want to read, +and want to access it quickly. On the other hand, there may be other relevant +documents for the given ©«name»©, which are ignored in view mode. + +The so-called ``list mode'' makes \texdoc list all relevant documentation and +ask you which one you want to view. It is useful when there a other +interesting sources of information besides the package's main documentation. + +There is also a ``mixed'' mode, intended to combine the best of view mode and +list mode: if there is only one relevant result, then \texdoc opens it in a +viewer, else it offers you a menu. + +Usually, \texdoc shows you only results it considers relevant. If there are no +``good'' results, it falls back to less relevant results. You can force +\texdoc to show you also ``bad'' results even when there are good ones by +using the ``showall'' mode. (This implies using a menu rather than starting a +viewer.) + +You can select with command-line options: use ©texdoc «option» «name»© with +one of the following options: ©-w© or ©--view© for view mode, ©-m© or +©--mixed© for mixed mode, ©-l© or ©--list© for list mode, ©-s© or ©--showall© +for showall mode. + +If you always (or mostly) use the same mode, it is probably easier to +select it in a configuration file than to always use the command-line +option. For this, see the next section. + +\subsection{Configuration files}\label{ss-quick-file} + +\texdoc use various configuration files, which you can see using the ©-f© or +©--files© options. The second entry in this list is marked with a star ©(*)©: +it is the file you should use for your personal preferences as a user; you may +need to create it (and the parents directories). + +In order to select you favorite mode, just insert a line ©mode = «yourmode»© +in this files, where ©«yourmode»© is one of ©view©, ©mixed©, ©list© or +©showall©. + +The configuration files can be used to tweak \texdoc in many ways, the most +useful of which is probably the selection of the viewers for various types of +documents, explained in the next section. + +\subsection{Viewers} + +\texdoc's mechanism for choosing a viewer varies according to your platform. +On Windows and MacOS, it uses your file associations like when you +double-click files in the Explorer or the Finder (except for the text viewer, +which is always a pager). On Unix, it tries to find a viewer in the path from +a list of ``known' viewers. + +You may want to select a different viewer for some kind of file. This is +achieved by the various ©viewer_«ext»© configuration options, where ©«ext»© is +the extension corresponding to the file type. For example, if you want to set +xpdf as your default PDF viewer, and run it in the background, insert the line +©viewer_pdf = xpdf %s &© in your configuration file. Here, ©%s© stands for the +name of the file to view. + +\subsection{Conclusion} + +We have now covered the most common needs. The next part explains +how \texdoc proceeds to find the best results. +The default configuration file tries hard to set appropriate values so that +you have a good out-of-the-box experience, but you may want to understand the +underlying mechanisms and adapt them to your needs. The final part is a full +reference for configuration options, including points omitted in the present +part. + +Your feedback is very welcome of the \tdml. Feel free to post comments, bug +reports, suggestions for improvements (inc. new aliases), even without +subscribing. + +\clearpage + +\section{File search, aliases, score} + +\subsection{An overview of how texdoc works} + +When you type ©texdoc «keyword»©, texdoc browses the trees containing +documentation (given by the \href{http://www.tug.org/kpathsea/} {kpathsea} +variable ©TEXDOCS©), lists all files containing ©«keyword»© in their name +(including the directory name) and give them a score based on some simple +heuristics. For example, a file named ©«keyword».pdf©, will get a high score, +©«keyword»-doc© will be preferred over ©«keyword»whatever©, files in a +directory named exactly ©«keyword»© get a bonus, etc. + +There is also some filtering based on extensions: only files with known +extensions are listed, and some extensions get a lesser score. Also, there is +some score adjustments based on keywords; by default, Makefile's get a very +bad score since they are almost never documentation.\footnote{They often end + up in the doc tree, since the source of documentation is often in the same + directory as the documentation itself in \TeX\ Live. Other source files are + discriminated by extension.} + +Then, depending on the mode, the file with the highest score is opened in a +viewer, or the list of results is shown. Usually, only results with a positive +score are displayed, except in showall mode. Result with very bad score (-100 +and below) are never displayed. + +\medskip + +However, this model works only if the documentation for ©«keyword»© has +©«keyword»© in its name, which is not always true. The documentation of the +memoir class is in ©memman.pdf©, for example, but it will be found anyway +since it is in a directory named memoir. But there are more complicated cases: +the documentation for mathptmx is in ©psnfss2e.pdf©, which is quite more +complicated to guess.\footnote{But not totally impossible: using the \TeX\ + Live database, texdoc can know which documentation files are associated with + a given ©.sty© file. Here, it could guess that the documentation is either + ©psfonts.pdf© of ©psnfss2e.pdf©. This will probably be done in a future + version.} + +Here comes the notion of \emph{alias}: in the default configuration file, +mathptmx is aliased to psnfss2e, so that when you type ©texdoc mathptmx©, +texdoc knows it has to look also for psnfss2e. Note that texdoc will also look +for the original name, and that a name can be aliased to more than one new +name (this is new in texdoc 0.60). + +\medskip + +We will soon see how you can configure this, but let's give a few definitions +about how a file can match keyword first (all matching is case-insensitive): +\begin{enumerate} + \item The keyword is a substring of the file name. + \item The keyword is a ``subword'' of the file name; words are defined as a + sequence of alphanumeric characters delimited by punctuation characters + (there is no space in file names in \TeX\ Live) and a subword is a + substring both ends of which are a word boundary. + \item The keyword can match ``exactly'' the file name: that is, the file + name is the keyword + and extension. +\end{enumerate} -Before the description of \texdoc's different modes, just a word words about -the typographic conventions in this manual. Things like ©«name»© in the above -title mean that they should be replaced by what you actually want. For -example, if you want to read \package{hyperref}'s manual, type -©texdoc hyperref©. Sometimes there will be complete examples like this: +\subsection{Alias directives}\label{ss-alias} \begin{htcode} - þ texdoc -s babelbib þ - 1 /usr/local/texlive/2008/texmf-dist/doc/latex/babelbib/babelbib.pdf - 2 /usr/local/texlive/2008/texmf-dist/doc/latex/babelbib/tugboat-babelbib.pdf - 3 /usr/local/texlive/2008/texmf-dist/doc/latex/babelbib/ChangeLog - 4 /usr/local/texlive/2008/texmf-dist/doc/latex/babelbib/README - Please enter the number of the file to view, anything else to skip: ¶2¶ + alias «original keyword» = «name» + alias(«score») «original keyword» = «name» \end{htcode} -In this case, what you actually type is in \textcolor{input}{\inputcolorname}, -and the funny symbol \textco{\prompt} represents your shell's prompt, which -can actually be something like ©C:\>© or ©name@host:~%© or funnier. - -\bigskip - -\texdoc's normal mode of operation is to find the more appropriate document -for your request and open it. But sometimes it has a weird notion of -``appropriate'', and you'd better look at the list of all results and choose -to see oen or more of them. For this, \texdoc offers various modes, like the -``search mode'' illustrated above. - -\begin{cmdsubsec}{Search mode}{ss-search} - texdoc -s «name» - texdoc --search «name» -\end{cmdsubsec} - -With the two (equivalent) commands above, \texdoc also looks for documentation -for ©«name»©, but using the \emph{search mode}, which differs from the -normal mode (called \emph{view mode}) on two points: -\begin{itemize} - \item It doesn't start a viewer and offers you a \emph{menu} instead. - \item It always do a \emph{full search}. -\end{itemize} -The first point is rather straightforward on the example. The second deserves -more explanation. - -Usually, \texdoc looks for files named ©«name».pdf© or ©«name».html© etc. (see -\ref{cf-ext_list}), where ©«name»© means what you asked for, in \texlive's -documentation directories, and if cannot find such a file, it tries a full -search: it finds all files which have ©«name»© in their name, or in the -directory's name. In search mode, \texdoc always performs a full search. - -Now look carefully at the previous example. The purpose of search mode is to -allow you to find related documentation, such as the -\href{http://www.tug.org/TUGboat/}{TUGboat} article on \package{babelbib}, -which you might want to read, whereas in normal mode \texdoc offers you no -choice and just displays the user manual ©babelbib.pdf©. On the other hand, -the view mode is much faster when you know exactly what you want to read. - -To try and make you happy, \texdoc offers two other modes, introduced below. - -\begin{cmdsubsec}{List mode}{ss-list} - texdoc -l «name» - texdoc --list «name» -\end{cmdsubsec} - -The \emph{list mode} uses a normal search, but forces \texdoc to give you a -menu instead of choosing itself the documentation to display. It is usefull -when there are many files with the same name but different contents, or many -versions of the same file on your system. - +You can define your own aliases in \texdoc's configuration files +(see~\ref{ss-quick-file} or \ref{ss-prec}). For example, +insert\footnote{Actually, you don't need to do this, the default configuration + file already includes this directive.} \begin{htcode} - þ texdoc -l tex þ - 1 /usr/local/texlive/2008/texmf/doc/man/man1/tex.pdf - 2 /usr/local/texlive/2008/texmf-doc/doc/english/knuth/tex/tex.pdf - Please enter the number of the file to view, anything else to skip: + alias mathptmx = psnfss2e \end{htcode} - -Here the first file is the manual page\footnote{converted in pdf. To allow - texdoc to find and display real man pages in man format, - see~\ref{cf-ext_list}.} of the ©tex© command, while the second is \TeX{}'s -documented source code\dots - -\begin{cmdsubsec}{Mixed mode}{ss-mixed} - texdoc -m «name» - texdoc --mixed «name» -\end{cmdsubsec} - -As the name says, \emph{mixed mode} is an attempt to provide you the best of -the normal (view) and list modes, by mixing them in the following way: If -only one file is found, then \texdoc opens it, and if many are found, it -displays a menu to let you choose. You may want to make this mode the -default, see~\ref{cf-mode}. - -\begin{cmdsubsec}{What's a <name>?}{ss-name} - texdoc «name1» «name2» «...» - texdoc «name.ext» -\end{cmdsubsec} - -To conclude this section on basics, let us just mention two points concerning -the ©«name»© in all previous sections. Is is usually a single name without -extension, but you can also use many names at once: then, depending on the -mode, \texdoc will either open all the corresponding documentation or show you -menus for each of the names you mentioned. For each name, you can also -specifiy the file exention\footnote{It should be an allowed extension, - see~\ref{cf-ext_list}, and preferably have a associated viewer defined, - see~\ref{cf-viewer_*}.} if you want, eg ©texdoc texlive-en.html© lets you -read the \texlive manual in html rather than in pdf format. - -\bigskip - -You can now stop reading this manual unless you have special needs. If you -want to understand the curious ©aliased too© messages that you will sometimes -see, and control them, read section~\ref{s-alias}. If you have problems -viewing certain type of files or want to choose you preferred reader, look at -section~\ref{s-viewer}. Finally, section~\ref{s-ref} is the full -reference concerning \texdoc configuration: while you probably don't want to -read it all at once, you can consult~\ref{cf-mode} if you want to select your -preferred mode and make it the default. - -Finally, be aware of the ©-h© or ©--help© option which provides you a quick -reminder of all available command-line options. - -\section{Aliases, or name substitution}\label{s-alias} - -\subsection{Basic concept}\label{ss-alias-basics} - -The usual search modes of \texdoc assume that the name of the documentation -file is the name of the package, or contains it (at least in the directory -name). However, this is not always true, due either to the author choosing a -fancy name, or packaging peculiarities. To try helping the user to find the -doc even in these cases, \texdoc provides an alias mechanism and comes with a -list of circa 200 pre-defined aliases. +in order to alias mathptmx to psnfss2e. Precisely, it means that files +matching exactly psnfss2e will be added to the result list when you look for +mathptmx, and get a score of 10 (default score for alias results). This is +greater than the results of heuristic scoring: it means that results found via +aliases will always rank before results associated to the original keyword. + +If you want the results associated to a particular alias to have a custom +score instead of the default 10, you can use the optional argument to the +alias directive. This can be usefull if you associate many aliases to +a keyword and want one of them to show up first. + +You can have a look at the configuration file provided (the last shown by +©texdoc -f©) for examples. If you feel one of the aliases you defined locally +should be added to the default configuration, please share it on the \tdml. + +Please note than aliasing is case-insensitive, and the aliases don't cascade: +only aliases associated to the original keyword are used. +Aliases are additive: if you define your own aliases for a keyword in your +configuration file, and there are also aliases for the same keyword in the +default configuration, they will add up. You can prevent the default aliases +from begin applied for a particular keyword by saying ©stopalias «keyword»© in +your personal configuration file. It will keep the aliases defined before +this directive (if any) and prevent all further aliasing on this keyword. + +If, for some reason, you want to prevent any alias from begin used for one +particular session of texdoc, you can use the ©-A© or ©--noalias© command-line +option (see~\ref{cl-a}). + +\subsection{Score directives}\label{ss-score} \begin{htcode} - þ texdoc -l geometry þ - texdoc info: geometry aliased to geometry/manual.pdf - 1 /usr/local/texlive/2008/texmf-dist/doc/latex/geometry/manual.pdf - Please enter the number of the file to view, anything else to skip: ¶0¶ + adjscore «pattern» = «score adjustment» + adjscore(«keyword») «pattern» = «score adjustment» \end{htcode} -The concept of alias is very\footnote{See~\ref{ss-alias-rem} for why it is - actually \emph{too} simple.} simple: as you can see of the above example, -when you type and ©geometry© is aliased to ©geometry/manual.pdf©, then -everything happens as if you actually typed ©texdoc geometry/manual.pdf© -(without any further alias substitution), and \texdoc informs you that -something happened so you can understand the results -(see~\ref{cf-verbosity_level} to get rid of this message): - -\begin{cmdsubsec}{Command line options}{ss-alias-cl} - texdoc -a «options» «name» - texdoc --alias «options» «name» - texdoc -A «options» «name» - texdoc --noalias «options» «name» -\end{cmdsubsec} - -By default, aliased are used in view, list and mixed modes, and disabled in -search mode. But you may want to disable it, because the default alias doesn't -do what you want\footnote{In this case, please report it to - \mailto{texdoc@tug.org}, so that the faulty alias can be updated.} or for -another reason. In this case, you just have to add ©-A© or ©--noalias© to the -options, like: +It is possible to adjust the score of results containing some pattern as a +subword, either globally (for the result of all searches) or only +when searching with a particular keyword. This is done in the +configuration file (\ref{ss-quick-file} or \ref{ss-prec}) using the +©adjustscore© directive. Here are a few examples from the default +configuration file. \begin{htcode} - þ texdoc -A -l geometry þ - 1 /usr/local/texlive/2008/texmf-doc/doc/polish/tex-virtual-academy-pl/ - latex2e/macro/geometry.html - Please enter the number of the file to view, anything else to skip: ¶0¶ + adjscore /Makefile = -1000 + adjscore /tex-virtual-academy-pl/ = -50 + adjscore(tex) texdoc = -10 \end{htcode} -On the contrary, you can force aliasing in search mode by using the ©-a© or -©--alias© option, though it may not prove very useful. +All files named ©Makefile© (and also files names ©Makefile-foo© if there are +any): are ``killed'' : by adjusting their score with such a large negative +value, their final score will most probably be less than -100, so they will +never be displayed. Files from the ©tex-virtual-academy-pl© directory, on the +other hand, are not killed but just get a malus, since they are a common +source of ``fake'' matches which hide better results (even for the lucky ones +who can read polish). -\subsection{Your own aliases}\label{ss-alias-own} +The third directive gives a malus for results containing ©texdoc© only if the +search keyword is ©tex©. Otherwise, such results would get a high score +because the heuristic scoring would think ©texdoc© is the name of \TeX's +documentation. The value -10 is enough to ensure that those results will have +a negative score, so wil not be displayed unless ``showall'' mode is active. -You can define your own aliases, or override the default ones, in \texdoc's -configuration files. You can get a list of those files by typing ©texdoc -f©. -For personal aliases, it is recommended that you use the second file, marked -by a star (see~\ref{ss-prec} for details). You'll probably need to -create in and one or two of the directories containing it. +\textbf{Warning}: Values of scores (like the default score for aliases, the +range of heuristic scoring, etc.) may change in a future version of texdoc. +Scoring is quite new and may need some adjustments. So, don't be surprised if +you need to adapt your scoring directives after a future update of texdoc. +This warning will disappear at some point. -Creating an alias is easy: you just insert a line like -\begin{htcode} - alias geometry = geometry/manual.pdf -\end{htcode} -in your configuration file, and it's all. You can have a look at the -configuration file provided (the last one showed by ©texdoc -f©) for examples. -If you want to permanently unalias something, just insert a line -©«name»=«name»©: it will overwrite the previous alias. - -\subsection{Remarks on aliases}\label{ss-alias-rem} - -Please be aware that this alias feature, or at least its intensive use to try -to find the ``right'' documentation for a given package, should be temporary. -Indeed, one problem is that currently aliases do \emph{hide} other files, while -it is desirable that they just \emph{add} results in some case. However, -defining a coherent behaviour (and how to maintain the needed database) -requires work and time, and is therefore reported to future versions. - -In this vein, it would be desirable to have a notion of ``category'', like -user documentation of a package, or man page of a program, or reference manual -of a program, or documented source code of a package or program, or\dots If -you have ideas about desirable categories and ways they should be handled, -feel free to share them at the usual address. - -\section{Viewer selection}\label{s-viewer} - -A list of default viewers is defined in \texdoc, depending on your platform -(Windows, MacOS X, other Unix). On Windows and MacOS, it uses your file -associations like when you double-click files in the Explorer or the Finder. -On Unix, it tries to find a viewer in the path from a list of ``known' -viewers. - -If you want to use another viewer, you have two ways of telling this to -\texdoc: in your configuration file or using environment variables. If you -hesitate, the configuration file is the recommended way. - -To find your configuration file, type ©texdoc -f© and pick the file marked -with a star (unless you are a system administrator or your home is shared -between many machines whith different architectures, see~\ref{ss-prec}); you -may need to create the file and a few directories. Then you can add lines -like: - -\begin{htcode} - viewer_pdf = (xpdf %s) & - viewer_txt = less -\end{htcode} +\subsection{File extensions} -Here the ©%s© stands for the name of the file to view. The first line sets -©xpdf© as the pdf viewer, and use a bit of shell syntax to force it to run in -the background (the ©()© are here for compatibility with zip support, -see~\ref{s-bugs}). The second line sets ©less© as the text viewer: it doesn't -use ©%s©, which means the filename will be placed at the end of the command. +The allowed file extensions are defined by the configuration item ©ext_list© +(default: pdf, html, txt, ps, dvi, no extension). You can configure it with +a line ©ext_list = «your, list»© in a configuration file. Be aware +that it will completely override the default list, not add to it. An empty +string in the list means files without extension (no dot in the name), while a +star means any extension. -The default extensions allowed are ©pdf©, ©html©, ©txt©, ©dvi©, ©ps©, and no -extension. The ©txt© viewer is used for files without extension. -See~\ref{cf-ext_list} for how to allow for more extensions. +For scoring purposes, there is also a ©badext_list© parameter: files whose +extension is ``bad'' according to this list will get a lesser score (currently +0). This only affect heuristic scoring (results found from the original +keyword, not from aliases). -The corresponding environment variables are ©PDFVIEWER©, ©BROWSER©, ©PAGER©, -©DVIVIEWER©, ©PSVIEWER©. They follow the same convention as values from the -configuration files, and override them if they are set. Since some of those -variable are shared by other programs, you can override them just for \texdoc -by adding ©_texdoc© at the end, like in ©BROWSER_texdoc©. +\clearpage -\section{Full reference}\label{s-ref} +\section{Full reference} -The most useful command-line options, configuration values and all -environment variables have been presented. Here we complete our presentation -and review all in a systematic way. - -\subsection{Precedence}\label{ss-prec} +\subsection{Precedence of configuration sources}\label{ss-prec} Values for a particular setting can come from several sources. They are treated in the following order, where first value found is always used: @@ -460,9 +453,10 @@ its default config file) in your home: see \href{http://tug.org/texdoc/}{the \subsection{Command-line options}\label{ss-cl} -Most of the command-line options correspond to an option that can be set from -the config files. For them, we refer the reader to the description of the -corresponding configuration option. +All command-line options (except the first three below) correspond to +configuration item that can be set in the configuration files: we refer +the reader to the corresponding section for the meaning of this configuration +item. \begin{cmdsubsub}{-h, --help}{cl-h} -h, --help @@ -471,7 +465,7 @@ corresponding configuration option. Shows a quick help message (namely a list of command-line options) and exits successfully. -\begin{cmdsubsub}{-V, --version}{cl-v} +\begin{cmdsubsub}{-V, --version}{cl-V} -V, --version \end{cmdsubsub} @@ -482,56 +476,67 @@ Show the current version of the program and exits successfully. \end{cmdsubsub} Shows the list of the configuration files for the current installation and -platform, with their status (active or not found) and a star marking the -recommended file for user settings. +platform, with their status (active, not found, or disabled +(see~\ref{cf-lastfile_switch})) and exits successfully. -\begin{cmdsubsub}{-w, -l, -m, -s, -r, --view, --list, --mixed, --search, +\begin{cmdsubsub}{-w, -l, -m, -s, -r, --view, --list, --mixed, --showall, --regex}{cl-mode} - -w, --view, -l, --list, -m, --mixed, -s, --search, -r, --regex + -w, --view, -l, --list, -m, --mixed, -s, --showall, -r, --regex \end{cmdsubsub} -See~\ref{cf-mode}. +\hfill Set ©mode© to the given value, see~\ref{cf-mode}. \begin{cmdsubsub}{-a, -A, --alias, --noalias}{cl-a} -a, --alias, -A, --noalias \end{cmdsubsub} -See~\ref{s-alias}. +Set ©alias_switch© true (resp. false), see~\ref{cf-alias_switch} \begin{cmdsubsub}{-i, -I, --interact, --nointeract}{cl-i} -i, --interact, -I, --nointeract \end{cmdsubsub} -See~\ref{cf-interact}. +Set ©interact_switch© to true (resp. false), see~\ref{cf-interact_switch}. \begin{cmdsubsub}{-e, --extensions}{cl-e} -e=«l», --extensions=«l» \end{cmdsubsub} -See~\ref{cf-ext_list}. \emph{But} be aware that on the command line there -should be no space at all, neither in the list (unless quoted according to you -shell's convention) not between the ©-e© or ©--extension© option, the equal -sign, and the list. Also take care to quote the special value ©*© if -necessary. The equal sign is optional. +Set ©ext_list©, see~\ref{cf-ext_list}. \textbf{Warning}: this command-line +option is deprecated and will likely be removed soon. It is recommended to set +©ext_list© in a configuration file instead. Please protest on the \tdml if you +want to keep this command-line option. + +\begin{cmdsubsub}{-v, --verbosity}{cl-v} + -v=«n», --verbosity=«n» +\end{cmdsubsub} + +Set ©verbosity_level© to ©«n»©, see~\ref{cf-verbosity_level}. Be aware that you +must avoid spaces on the command line, and the ©=© sign is optional. + +\begin{cmdsubsub}{-d, --debug}{cl-d} + -d, -d=«list», --debug, --debug=«list» +\end{cmdsubsub} + +Set ©debug_list©, see~\ref{cf-debug_list}. If not list is given, activates all +available debug items. -\begin{cmdsubsub}{-v, --verbosity, -d, --debug}{cl-n} - -v=«n», --verbosity=«n», -d, --debug +\begin{cmdsubsub}{-M, --machine}{cl-M} + -M, --machine \end{cmdsubsub} -See~\ref{cf-verbosity_level} and be aware that you must avoid spaces on the -command line, and the ©=© sign is optional. The ©--debug© option sets -verbosity at the maximum level. +Set ©machine_switch© to true, see~\ref{cf-machine_switch}. \subsection{Environment variables}\label{ss-envvar} They all correspond to some ©viewer_«ext»© setting, and the reader is referred -to~\ref{s-viewer} and~\ref{cf-viewer_*} for details. Also, environment -variables used by older versions of \texdoc are accepted. You can append -©_texdoc© to every name in the first column: this wins over every other name. +to~\ref{cf-viewer_*} for details. Also, environment variables used by older +versions of \texdoc are accepted. You can append ©_texdoc© to every name in +the first column: this wins over every other name. \begin{center} - \begin{tabular}{@{}l*3{@{ }l}@{}} - New name & Old name 1 & Old name 2 & Config. param.\\ + \begin{tabular}{*4l} + New name & Old name 1 & Old name 2 & Config. item\\ ©PAGER© & ©TEXDOCVIEW_txt© & ©TEXDOC_VIEWER_TXT© & ©viewer_txt© \\ ©BROWSER© & ©TEXDOCVIEW_html© & ©TEXDOC_VIEWER_HTML© & ©viewer_html© \\ ©DVIVIEWER© & ©TEXDOCVIEW_dvi© & ©TEXDOC_VIEWER_DVI© & ©viewer_dvi© \\ @@ -540,69 +545,69 @@ variables used by older versions of \texdoc are accepted. You can append \end{tabular} \end{center} -\subsection{Configuration files}\label{ss-conf} +\subsection{Configuration items}\label{ss-conf} -\subsubsection{General structure}\label{sss-sonf-struct} +\subsubsection{Structure of configuration files}\label{sss-sonf-struct} Configuration files are line-oriented text files. Comments begin with a ©#© and run to the end of line. Lines containing only space are ignored. Space at the beginning or end of a line, as well as around an ©=© sign, is ignored. Apart from comments and empty lines, each line must be of one of the following -forms: +forms. \begin{htcode} - «config_param» = «value» - alias «name» = «target» + «configuration item» = «value» + alias «original keyword» = «name» + alias(«score») «original keyword» = «name» + stopalias «original keyword» + adjscore «pattern» = «score adjustment» + adjscore(«keyword») «pattern» = «score adjustment» \end{htcode} -where ©«config_parameter»© consists of only letters, digits or ©-© signs, -©«name»© of letters, digits, ©-© and ©_© signs. ©«value»© and ©«target»© are -free strings (except that not every ©«value»© is valid for every -©«config_param»©, see below) and nothing in it need not be quoted (actually, -quotes will be interpreted as part of the value, not as quotation marks). +We will concentrate on the ©«configuration item»© part here, since other +directives have already been presented (\ref{ss-alias} and \ref{ss-score}). -Lines which do not obey these rules raise a warning. However, unrecognised -values of ©«config_param»© raise no warning at the moment. +In the above, ©«value»© never needs to be quoted: quotes would be interpreted +as part of the value, not as quotation marks (this also holds for the other +directives). -The ©«value»© is usually interpreted as a string, except when ©«config_param»© -ends with: +Lines which do not obey these rules raise a warning, as well as unrecognised +values of ©«configuration item»©. The ©«value»© can be an arbitrary string, +except when the name of the ©«configuration item»© ends with: \begin{enumerate} \item ©_list©, then ©«value»© is a coma-separated list of strings. Space around commas is ignored. Two consecutive comas or a coma at the beginning or end of the list means the empty string at the corresponding place. \item ©_switch©, then ©«value»© must be either ©true© or ©false© - (case-sensitive). - \item ©_level©, then ©«value»© is a non-negative integer. + (lowercase). + \item ©_level©, then ©«value»© is an integer. \end{enumerate} +In these cases, an improper ©«value»© will raise a warning too. \begin{cmdsubsub}{mode}{cf-mode} - mode = «view, list, mixed, search, regex» + mode = «view, list, mixed, showall, regex» \end{cmdsubsub} -Set the mode to the given value. Default is ©view©. The first three values -©view©, ©list©, ©mixed© use the same searching method: first search a file -whose name is the ©«name»© on the command line and whose extension is in -©ext_list© (see~\ref{cf-ext_list}), and if nothing is found, then do a full -search. This means that a file matches if ©«name»© is a substring of its -path+name (and its extension is in the list). Here path does not mean the full -path, but only the part below ©TEXMF/doc©. The ©search© mode forces a full -search. - -The last mode, ©regex©, looks for ©«name»© in the path+filename as a Lua -regex. If you don't know Lua regexes you should be aware that the escape -character is ©%© and the ©-© sign is a special character (which means the same -as ©*?© in Perl regexes). For more details, see the Lua -\href{http://www.lua.org/manual/}{reference manual} or the book -\href{http://www.lua.org/pil/}{\emph{programming in Lua}}. You might want to -use\footnote{The quotes in the example are just to make the shell happy.} -©-e='*'© if your regex uses the ©$© anchor.%stopzone - -\begin{cmdsubsub}{interact}{cf-interact} +Set the mode to the given value. Default is ©view©. All mode except regex +have been presented in~\ref{ss-modes}. + +In regex mode, the given name is interpreted as a Lua regex, and only files +whose full name (including path) matches it are found. Alias and score +mechanisms are disabled. \textbf{Warning}: this mode is deprecated and will +likely be removed soon. Please protest on the \tdml if you want it to stay. + +\begin{cmdsubsub}{interact}{cf-interact_switch} interact_switch = «true, false» \end{cmdsubsub} Turn on or off interaction. Default is on. Turning interaction off prevents \texdoc to ask you to choose a file to view when there are multiple choices, -and merely just print the list of files found. +so it just prints the list of files found. + +\begin{cmdsubsub}{alias}{cf-alias_switch} + alias_switch = «true, false» +\end{cmdsubsub} + +Turn on or off aliasing. Default is on. \begin{cmdsubsub}{ext_list}{cf-ext_list} ext_list = «list» @@ -612,8 +617,9 @@ Set the list of recognised extensions to ©«list»©. Default is \begin{htcode} pdf, html, txt, dvi, ps, \end{htcode} -This list is used to filter and sort the results (with the default value: pdf -first, etc). Two special values are recognised: +This list is used to filter and sort the results that have the same +score(with the default value: pdf first, etc). Two special values are +recognised: \begin{itemize} \item \emph{The empty element}. This means files without extensions, or more precisely without a dot in their name. This is meant for files like @@ -624,7 +630,7 @@ first, etc). Two special values are recognised: There is a very special case: if the searched ©«name»© has ©.sty© extension, \texdoc enters a special search mode for ©.sty© files (not located in the same -place as real documentation files) for this ©«name»©, independantly of the +place as real documentation files) for this ©«name»©, indepandantly of the current value of ©ext_list© and ©mode© (unless it is the ©regex© mode). In an ideal world, this wouldn't be necessary since every sty file would have a proper documentation in pdf, html or plain text, but\dots @@ -635,93 +641,81 @@ For each ©«ext»© in ©ext_list© there should be a corresponding \texdoc to be able to find man pages and display them with the ©man© command, you can use \begin{htcode} - ext_list = 1, 5, pdf, html, txt, dvi, ps, + ext_list = pdf, html, 1, 5, txt, dvi, ps, viewer_1 = man viewer_5 = man \end{htcode} -(This also makes man pages in man format take precedence over their pdf -versions.) + +\begin{cmdsubsub}{badext_list}{cf-badext_list} + badext_list = «list» +\end{cmdsubsub} + +Set the list of ``bad'' extensions to ©«list»©. Default is ``©txt,©''. Files +with those extensions get a heuristic score of 0. \begin{cmdsubsub}{viewer_*}{cf-viewer_*} viewer_«ext» = «cmd» \end{cmdsubsub} Set the viewer command for files with extension ©«ext»© to ©«cmd»©. For files -without extension, ©viewer_txt© is used, and there's not ©viewer_© variable. +without extension, ©viewer_txt© is used, and there's no ©viewer_© variable. In ©«cmd»©, ©%s© can be used as a placeholder for the file name, which is otherwise inserted at the end of the command. The command can be a arbitrary shell construct. -\begin{cmdsubsub}{alias}{cf-alias} - alias «name» = «othername» +\begin{cmdsubsub}{verbosity_level}{cf-verbosity_level} + verbosity_level = «n» \end{cmdsubsub} -Everything has already been said in section~\ref{s-alias}. +Set the verbosity level to ©«n»©. 3 means errors, warnings and informational +message will be printed (on stdout); 2 means only errors and warnings, 1 only +errors and 0 nothing (not recommended). -\begin{cmdsubsub}{verbosity_level}{cf-verbosity_level} - verbosity_level = «n» +\begin{cmdsubsub}{debug_list}{cf-debug_list} + debug_list = «list» \end{cmdsubsub} -Set the verbosity level to ©«n»©. This determines whether \texdoc will print -or not errors or debug information (to stderr). Default level is 3. The -numeric codes are as follow: -\begin{enumerate}[start=0] - \item Print nothing (not recommended). - \item Print only error messages. - \item Also print warnings. - \item Also print information messages. - \item[n] Also print debug(n-3) information messages. -\end{enumerate} +Set the list of activated debug items (default: none). For a list of available +items, see the source code, file ©constants.tlu©, variable ©known_debugs©. +Debug information is printed on standard error. + +\begin{cmdsubsub}{machine_switch}{cf-machine_switch} + machine_switch = «true, false» +\end{cmdsubsub} -Currently, debug goes from 1 to 3 : ©debug1© prints the command used to view a -file just before executing it, ©debug2© prints information about setting -configuration paramters, and ©debug3© about the search paths used. +Turn on or off machine-readable output (default: off). With this option +active, the value of ©interact_switch© is forced to ©false©, and each line of +output is +\begin{htcode} + «argument»\t«score»\t«filename» +\end{htcode} +where ©«argument»© is the name of the argument to which the results correspond +(mainly useful if there were many arguments), ©\t© is the tab (ascii 9) +character, and the other entries are pretty self-explanatory. Nothing else is +printed on stdout, except if a internal error occurs (in which case exit code +will be 1). In the future, more tab-separated fields may be added at the end +of the line, but the first 3 fields will remain unchanged. \begin{cmdsubsub}{lastfile_switch}{cf-lastfile_switch} lastfile_switch = «true, false» \end{cmdsubsub} -Prevents \texdoc from reading any other configuration file after this one. -Mainly useful for installing a newer version of \texdoc in your home (see the +If set to true, prevents \texdoc from reading any other configuration file +after this one (they will be reported as ``disabled'' by ©texdoc -f©). Mainly +useful for installing a newer version of \texdoc in your home and preventing +the default configuration file from older versions to be used(see the \href{http://tug.org/texdoc/}{web site} for instructions on how to do so). \subsection{Exit codes}\label{ss-exit} -The current exit code are as follow: +The current exit codes are: \begin{enumerate}[start=0] \item Success. - \item Syntax error. - \item Documentation not found for at least one argument. + \item Internal error. + \item Usage error. \end{enumerate} -\section{Bugs, warnings}\label{s-bugs} - -There is currently no known bug (fingers crossed). But a few things you should -be warned about. - -First of all, \texdoc doesn't always succeed in finding documentation (or -finds so many results that it is not useful). Moreover, it cannot handle very -correctly packages with many relevant documentation files at the moment -(see~\ref{ss-alias-rem}). Ideas about how to improve this are most welcome at -the usual address. - -Second, support for zipped documentation, which have been ``available'' in -previous versions of \texdoc, is now disabled by default. The reasons are that -this support wasn't portable (didn't work on windows for example), and -moreover we won't ship compressed documentation in \texlive. However, the -code has not been totally removed and should be easy to activate again. If you -want to use this feature, please: -\begin{enumerate} - \item Look in \texdoc's code for instructions (look for the ©support_zipped© - variable and change it to true). - \item Check that the zip commands in texdoc's default match whatever command - is available on your system. -\end{enumerate} - -Finally, \texdoc is also missing a GUI version (texdoctk has never been the -GUI version of \texdoc, and is unmaintained and probably unmaintainable -anyway). This is on the list, but the time line is rather unclear at the -moment. +\clearpage \section{Licence}\label{s-licence} @@ -752,10 +746,8 @@ Previous work (texdoc program) in the public domain: \end{itemize} \bigskip -\begin{center}\Large\rmfamily +\begin{center}\Large\rmfamily\bfseries Happy \TeX{}ing! \end{center} \end{document} - - diff --git a/Master/texmf/scripts/texdoc/config.tlu b/Master/texmf/scripts/texdoc/config.tlu index 1098d39b7ea..304ae9d3dca 100644 --- a/Master/texmf/scripts/texdoc/config.tlu +++ b/Master/texmf/scripts/texdoc/config.tlu @@ -9,16 +9,17 @@ local L = {} load_env(L, { 'export_symbols', 'string', 'table', 'os', 'kpse', 'lfs', 'io', - 'arg', 'ipairs', 'pairs', 'tonumber', 'tostring', 'setmetatable', 'next', 'print', 'assert', 'error', + 'err_print', 'win32_hook', 'deb_print', + 'confline_to_alias', 'confline_to_score', 'C', - 'err_print', 'win32_hook', - 'config', 'alias' + 'config', }) ------------------------ hide config and alias tables ----------------------- +-------------------------- hide the config table --------------------------- +-- config is read-only function set_read_only(table, name) assert(next(table) == nil, 'Internal error: '..name..' should be empty at this point.') @@ -32,9 +33,9 @@ function set_read_only(table, name) end real_set_config = set_read_only(config, 'config') -real_set_alias = set_read_only(alias, 'alias') ----------------------------- general functions ----------------------------- + +------------------------- general config functions ------------------------- -- set a config parameter, but don't overwrite it if already set -- three special types: *_list (list), *_switch (boolean), *_level (number) @@ -82,13 +83,13 @@ function set_config_element (key, value, context) else -- string real_set_config(key, value) end - -- special case: if we just set verbosity_level, print version info now - if key == 'verbosity_level' then - err_print(arg[0]..' version '..C.version, 'debug1') + -- special case: if we just set debug_list, print version info now + if key == 'debug_list' then + deb_print('version', C.fullname..' version '..C.version) end -- now tell what we have just done, for debugging - err_print('Setting "'..key..'='..value..'" ' - ..context_to_string(context)..'.', 'debug2') + deb_print('config', + "Setting '"..key.."="..value.."' "..context_to_string(context)..'.') end -- a helper function for warning messages in the above @@ -97,7 +98,7 @@ function config_warn (key, value, context, unknown) and 'Unknown option "'..key..'"' or 'Illegal value "'..tostring(value)..'" for option "'..key..'"' local ending = '. Skipping.' - err_print (begin..' '..context_to_string(context)..ending, 'warning') + err_print('warning', begin..' '..context_to_string(context)..ending) end -- interpreting 'context' for the previous functions @@ -123,19 +124,12 @@ function set_config_list (conf, context) end end --- set an alias (w/o overwriting) -function set_alias (key, value) - if alias[key] == nil then - real_set_alias(key, value) - end -end - ------------------------ options from command line ------------------------- -- set config from the command line -- Please make sure to update C.usage_msg accordingly -- and set a default value in setup_config_from_defaults() if relevant. -function setup_config_from_cl () +function setup_config_from_cl(arg) local curr_arg local function set_config_elt(key, val) set_config_element(key, val, {src='cl', name=curr_arg}) @@ -161,8 +155,12 @@ function setup_config_from_cl () set_config_elt('mode', 'mixed') elseif (curr_arg == '-l') or (curr_arg == '--list') then set_config_elt('mode', 'list') - elseif (curr_arg == '-s') or (curr_arg == '--search') then - set_config_elt ('mode', 'search') + elseif (curr_arg == '-s') or (curr_arg == '--showall') then + set_config_elt ('mode', 'showall') + elseif (curr_arg == '--search') then + set_config_elt ('mode', 'showall') + err_print('warning', '--search has been renamed to --showall') + err_print('warning', 'Please use the new name.') elseif (curr_arg == '-r') or (curr_arg == '--regex') then set_config_elt ('mode', 'regex') -- interaction @@ -178,25 +176,44 @@ function setup_config_from_cl () set_config_elt('alias_switch', 'false') elseif (curr_arg == '-a') or (curr_arg == '--alias') then set_config_elt('alias_switch', 'true') - -- verbosity + -- debug elseif (curr_arg == '-d') or (curr_arg == '--debug') then - set_config_elt('verbosity_level', C.err_max) + set_config_elt('debug_list', 'all') + elseif string.match(curr_arg, '^%-d=') then + local value = string.gsub(curr_arg, '^%-d=', '') + set_config_elt('debug_list', value) + elseif string.match(curr_arg, '^%-%-debug=') then + local value = string.gsub(curr_arg, '^%-%-debug=', '') + set_config_elt('debug_list', value) + -- verbosity elseif string.match(curr_arg, '^%-v') then local value = string.gsub(curr_arg, '^%-v=?', '') set_config_elt('verbosity_level', value) elseif string.match(curr_arg, '^%-%-verbosity') then local value = string.gsub(curr_arg, '^%-%-verbosity=?', '') set_config_elt('verbosity_level', value) - -- extensions list + -- extensions list (deprecated) elseif string.match(curr_arg, '^%-e') then local value = string.gsub(curr_arg, '^%-e=?', '') set_config_elt('ext_list', value) + err_print('warning', + '-e is deprecated and will likely be removed soon.') + err_print('warning', + 'ext_list should be set in a configuration file instead.') + err_print('warning', + 'Please protest on the texdoc mailing list if you need this.') elseif string.match(curr_arg, '^%-%-extensions') then local value = string.gsub(curr_arg, '^%-%-extensions=?', '') set_config_elt('ext_list', value) + err_print('warning', + '--extensions is deprecated and will likely be removed soon.') + err_print('warning', + 'ext_list should be set in a configuration file instead.') + err_print('warning', + 'Please protest on the texdoc mailing list if you need this.') -- problem else - err_print ("unknown option: "..curr_arg, "error") + err_print('error', "unknown option: "..curr_arg) print (C.error_msg) os.exit(2) end @@ -234,32 +251,37 @@ function read_config_file(configfile) local cnf = assert(io.open(configfile, 'r')) local lineno = 0 while true do - local key, val local line=cnf:read('*line') lineno = lineno + 1 if line == nil then break end -- EOF line = string.gsub(line, '%s*#.*$', '') -- comments begin with # line = string.gsub(line, '%s*$', '') -- remove trailing spaces line = string.gsub(line, '^%s*', '') -- remove leading spaces - key, val = string.match(line, '^([%a%d_]+)%s*=%s*(.+)') - if key and val then - set_config_element(key, val, { - src='file', file=configfile, line=lineno}) - else - key, val = string.match(line, '^alias%s+([%a%d_-]+)%s*=%s*(.+)') - if key and val then - set_alias(key, val) - else - if (not string.match (line, '^%s*$')) then - err_print ('syntax error in '..configfile.. - ' at line '..lineno..'.', 'warning') - end - end + -- try to interpret the line + local ok = string.match(line, '^%s*$') + or confline_to_alias(line, configfile, lineno) + or confline_to_score(line, configfile, lineno) + or confline_to_config(line, configfile, lineno) + -- complain if it failed + if not ok then + err_print('warning', + 'syntax error in '..configfile..' at line '..lineno..'.') end end cnf:close() end +-- interpret a confline as a config setting or return false +function confline_to_config(line, file, pos) + local key, val = string.match(line, '^([%a%d_]+)%s*=%s*(.+)') + if key and val then + set_config_element(key, val, {src='file', file=file, line=pos}) + return true + end + return false +end + + -- return a table with config file and if they exist function get_config_files () local platform = string.match (kpse.var_value ('SELFAUTOLOC'), '.*/(.*)$') @@ -442,7 +464,8 @@ function setup_config_from_defaults() interact_switch = 'true', machine_switch = 'false', verbosity_level = '2', - ext_list = 'pdf, html, txt, man1.pdf, man5.pdf, ps, dvi, ', + ext_list = 'pdf, html, txt, ps, dvi, ', + badext_list = 'txt, ', } -- must be set after mode! set_config_elt ('alias_switch', alias_from_mode(config.mode)) @@ -470,14 +493,25 @@ end -------------------------- set all configuration --------------------------- -- populate the config and alias arrays -function setup_config_and_alias() +function setup_config_and_alias(arg) -- setup config from all sources - setup_config_from_cl() + setup_config_from_cl(arg) setup_config_from_env() setup_config_from_files() setup_config_from_defaults() - -- we were waiting for config.verbosity_level to be know to do this - show_config_files(function(s) err_print(s, 'debug1') end) + -- regex mode is deprecated + if config.mode == 'regex' then + err_print('warning', + 'Regex mode is deprecated and will likely be removed soon.') + err_print('warning', + 'Please protest on the texdoc mailing list if you need this.') + end + -- machine mode implies no interaction + if config.machine_switch == true then + real_set_config('interact_switch', false) + end + -- we were waiting for config.debug_list to be know to do this + show_config_files(function(s) deb_print('files', s) end) end -- finally export a few symbols diff --git a/Master/texmf/scripts/texdoc/constants.tlu b/Master/texmf/scripts/texdoc/constants.tlu index 6ff1fb079e1..b1a0bcc4e19 100644 --- a/Master/texmf/scripts/texdoc/constants.tlu +++ b/Master/texmf/scripts/texdoc/constants.tlu @@ -8,12 +8,14 @@ See texdoc.tlu for details. local L = {} load_env(L, { 'setmetatable', 'next', 'assert', 'error', + 'arg', 'C', }) -- progname and version -progname = 'texdoc' -version = '0.50' +fullname = arg[0] +progname = 'texdoc' +version = '0.60' -- make sure to update setup_config_from_cl() accordingly -- and set a default value in setup_config_from_defaults() if relevant @@ -23,18 +25,18 @@ With no NAME, it can print configuration information (-f, --files); the usual --help and --version options are also accepted. Usage: texdoc [OPTIONS]... [NAME]... -f, --files Print the name of the config files being used. - -e, --extensions=L Require file extensions to be in the list L. -w, --view Use view mode: start a viewer. -m, --mixed Use mixed mode (view or list). - -l, --list Use list mode: don't start a viewer. - -s, --search Search for name as a substring. - -r, --regex Search for name as a lua regex. + -l, --list Use list mode: show a list of results. + -s, --showall Use showall mode: show also "bad" results. + -r, --regex Use regex mode. (Deprecated.) + -e, --extensions=L Set ext_list=L. (Deprecated.) -a, --alias Use the alias table. -A, --noalias Don't use the alias table. -i, --interact Use interactive menus. -I, --nointeract Use plain lists, no interaction required. -v, --verbosity=N Set verbosity level to N. - -d, --debug Set verbosity level to maximum. + -d, --debug[=list] Activate debug for selected items (default all). -M, --machine Use a more machine-friendly output format. Environment: PAGER, BROWSER, PDFVIEWER, PSVIEWER, DVIVIEWER. Files: <texmf>/texdoc/texdoc.cnf files, see the -f option. @@ -56,7 +58,9 @@ known_options = { 'machine_switch', 'alias_switch', 'ext_list', + 'badext_list', 'verbosity_level', + 'debug_list', 'lastfile_switch', 'rm_dir', 'rm_file', @@ -68,13 +72,19 @@ err_priority = { error = 1, warning = 2, info = 3, - debug1 = 4, - debug2 = 5, - debug3 = 6, - debug4 = 7, - debug5 = 8, } -err_max = 8 + +known_debugs = { + version = {}, + files = {}, + config = {'files'}, + view = {}, + texdocs = {}, + filesea = {}, + lsrsea = {}, + kpse = {'texdocs', 'filesea', 'lsrsea'}, + score = {}, +} place_holder = '%%s' -- used for viewer commands diff --git a/Master/texmf/scripts/texdoc/functions.tlu b/Master/texmf/scripts/texdoc/functions.tlu index faee493f156..4db39c2482f 100644 --- a/Master/texmf/scripts/texdoc/functions.tlu +++ b/Master/texmf/scripts/texdoc/functions.tlu @@ -9,7 +9,7 @@ local L = {} load_env(L, { 'export_symbols', 'string', 'io', 'os', - 'ipairs', + 'pairs', 'ipairs', 'C', 'config', }) @@ -27,7 +27,7 @@ else end -- generic error display function (see the error_priority constant) -function err_print (msg, lvl) +function err_print (lvl, msg) -- be careful: maybe config.verbosity_level is not set yet local verbosity_level = config.verbosity_level or 2 if C.err_priority[lvl] <= verbosity_level then @@ -35,6 +35,49 @@ function err_print (msg, lvl) end end +do --scope of active_debugs +local active_debugs + +-- generic debug function +function deb_print(cat, msg) + -- make sure active_debugs is set + if not active_debugs then set_active_debugs() end + -- print message it belongs to an active category + if active_debugs and active_debugs[cat] or cat == 'XXX' then + io.stderr:write ("texdoc debug-"..cat..": "..msg.."\n") + end +end + +-- set active_debugs +function set_active_debugs() + if not config.debug_list then return end + active_debugs = {} + -- all debug options imply version info + if config.debug_list[1] then + active_debugs.version = true + else + return + end + -- if 'all' is the first keyword, just activate all categories + if config.debug_list[1] == 'all' then + for deb in pairs(C.known_debugs) do + active_debugs[deb] = true end + return + end + -- activate options from the list + for _, deb in ipairs(config.debug_list) do + local deps = C.known_debugs[deb] + if deps then + active_debugs[deb] = true + for _, d in ipairs(deps) do active_debugs[d] = true end + else + err_print('warning', "Unknown debug category '"..deb.."'.") + end + end +end + +end -- scope of active_debugs + -- if zip is support and file is base..'.'..zip with zip in zipext_list, -- return base, zip -- otherwise, returns file, nil function parse_zip(file) @@ -53,6 +96,7 @@ end -- finally export a few symbols export_symbols(L, { 'err_print', + 'deb_print', 'win32_hook', 'parse_zip', }) diff --git a/Master/texmf/scripts/texdoc/main.tlu b/Master/texmf/scripts/texdoc/main.tlu index 1d538904662..c5ff50d2ded 100644 --- a/Master/texmf/scripts/texdoc/main.tlu +++ b/Master/texmf/scripts/texdoc/main.tlu @@ -11,19 +11,17 @@ load_env(L, { 'print', 'ipairs', 'arg', 'C', - 'config', 'setup_config_and_alias', - 'get_docfiles', - 'sort_docfiles', + 'get_doclist', 'deliver_results', }) -- setup config options and aliases from various places -setup_config_and_alias() +setup_config_and_alias(arg) -- make sure we actually have argument(s) if not arg[1] then - print (C.usage_msg) + print(C.usage_msg) os.exit(2) end @@ -32,9 +30,8 @@ local docname for _, docname in ipairs(arg) do -- do we have more then one argument? local multiarg = not not arg[2] - -- get results and sort them - local docfiles = get_docfiles(docname) - sort_docfiles(docfiles) + -- get results + local doclist = get_doclist(docname) -- deliver results to the user - deliver_results(docname, docfiles, multiarg) + deliver_results(docname, doclist, multiarg) end diff --git a/Master/texmf/scripts/texdoc/score.tlu b/Master/texmf/scripts/texdoc/score.tlu index 734f4b5b7d8..6c8bc2c77f2 100644 --- a/Master/texmf/scripts/texdoc/score.tlu +++ b/Master/texmf/scripts/texdoc/score.tlu @@ -9,29 +9,193 @@ local L = {} load_env(L, { 'export_symbols', 'string', 'table', - 'ipairs', - 'config', 'parse_zip', + 'pairs', 'ipairs', 'tostring', 'tonumber', 'assert', + 'config', 'parse_zip', 'err_print', 'deb_print', }) --- sort docfiles -function sort_docfiles(df) - table.sort(df, docfile_order) +-- shared variables +local global_adjscore, spec_adjscore = {}, {} + +------------------------- configuration directives ------------------------- + +-- interpret a confline as a score directive or return false +function confline_to_score(line, file, pos) + local keyw, pat, val + -- try global adjscore + pat, val = string.match(line, '^adjscore%s+([%w%p]+)%s*=%s*([%d+-.]+)') + if pat and val then + return set_score_table(global_adjscore, pat, val) + end + -- try keyword specific adjscore + keyw, pat, val = string.match(line, + '^adjscore%(([%w%p]+)%)%s+([%w%p]+)%s*=%s*([%d+-.]+)') + if keyw and pat and val then + keyw = string.lower(keyw) + spec_adjscore[keyw] = spec_adjscore[keyw] or {} + return set_score_table(spec_adjscore[keyw], pat, val) + end + return false end --- compare docfiles: (see search.tlu for structure) --- 1. exact is better than non-exact, --- 2. then extensions are ordered as in ext_list, --- 3. then trees, --- 4. then filenames lexicographically. --- return true is a is better than b -function docfile_order (a, b) - if a.exact and not b.exact then +-- set key in score table to val, without overriding +function set_score_table(tab, key, val) + local k = string.lower(key) + local v = tonumber(val) + if v then + if tab[k] == nil then tab[k] = v end return true - elseif b.exact and not a.exact then - return false - elseif a.tree < b.tree then + end + return false +end + +---------------------------- score computation ----------------------------- + +-- set the scores for a doclist +function set_list_scores(list, original_kw) + for _, df in ipairs(list) do + set_score(df, original_kw) + end +end + +-- set the score of a docfile +function set_score(df, original_kw) + -- scoring is irrelevant in regex mode + if config.mode == 'regex' then df.score = 0 return end + deb_print('score', 'Start scoring '..df.realpath) + deb_print('score', 'Name used: '..df.name) + -- scoring is case-insenstitive (patterns are already lowercased) + local name = string.lower(df.name) + -- get score from patterns + local score = 0 + for _, pat in ipairs(df.matches) do + local s = 0 + local p = string.lower(pat.name) + if pat.original then + s = df.tree > -1 and heuristic_score(name, p) or 1 + elseif is_exact(name, p) then + s = pat.score or 10 -- default alias score + deb_print('score', string.format( + "Matching alias '%s', score: %d", pat.name, s)) + end + if s > score then score = s end + end + deb_print('score', 'Max pattern score: '..tostring(score)) + -- adjust from keyword-specific tables + if df.tree > -1 and spec_adjscore[original_kw] then + for pat, val in pairs(spec_adjscore[original_kw]) do + if val and is_subword(name, pat) then + if score > 0 or val < 0 then score = score + val end + deb_print('score', string.format( + "Adjust by '%d' from specific pattern '%s'", val, pat)) + end + end + end + -- adjust from global tables + if df.tree > -1 then + for pat, val in pairs(global_adjscore) do + if val and is_subword(name, pat) then + if score > 0 or val < 0 then score = score + val end + deb_print('score', string.format( + "Adjust by '%d' from global pattern '%s'", val, pat)) + end + end + end + deb_print('score', 'Final score: '..tostring(score)) + df.score = score +end + +-- suffixes for heuristic match +local suffixes = { + 'doc', '-doc', '_doc', '.doc', '/doc', + 'manual', '/manual', '-manual', + '-user', + '-man', +} + +-- compute a heuristic score 0 <= s < 10 +function heuristic_score(file, pat) + deb_print('score', 'Start heuristic scoring with pattern: '..pat) + -- if extension is bad, score is 0 + local ext = config.ext_list[ext_pos(file)] + if ext and config.badext_list_inv[ext] then + deb_print('score', 'Bad extension, heuristic score 0') + return 0 + end + -- score management + local score = 0 + local function upscore(s, reason) + if s > score then + score = s + deb_print('score', 'New heuristic score: '..tostring(s) + ..'. Reason: '..reason) + end + end + local slash = not not string.find(pat, '/', 1, true) + -- look for exact or subword match + if is_exact(file, pat) then + upscore(4, 'exact match') + elseif is_subword(file, pat) then + upscore(1, 'subword match') + end + -- try derivatives unless pat contains a slash + if not slash then + for _, suffix in ipairs(suffixes) do + local deriv = pat..suffix + if is_exact(file, deriv) then + upscore(3, 'exact match for derived pattern: '..deriv) + elseif is_subword(file, deriv) then + upscore(2, 'subword match for derived pattern: '..deriv) + end + end + end + -- bonus for being in the right directory + if score > 0 and not slash + and string.find('/'..file, '/'..pat..'/', 1, true) then + upscore(score + 0.5, 'directory bonus') + end + -- done + deb_print('score', 'Final heuristic score: '..tostring(score)) + return score +end + +-- says if file is an exact match for pat +function is_exact(file, pat) + file = parse_zip(file) + local slashes = string.gsub(pat, '[^/]+', '[^/]+') + basename = string.match(file, slashes..'$') + if not basename then return nil end + if basename == pat then return true end + for _, ext in ipairs(config.ext_list) do + if ext ~= '' and ext ~= '*' and basename == pat..'.'..ext then + return true + end + end + return false +end + +-- say if pat is a "subword" of str +function is_subword(str, pat) + local i, j = string.find(str, pat, 1, true) + return not not (i and j + and (i == 1 or is_delim(str, i) or is_delim(str, i-1)) + and (j == #str or is_delim(str, j) or is_delim(str, j+1))) +end + +-- say if character i of str is a delimiter (ponctuation) +function is_delim(str, i) + return not not string.find(string.sub(str, i, i), '%p') +end + +-- compare two docfile's: (see search.tlu for structure) +-- 1. by score +-- 2. then by extensions (ordered as in ext_list), +-- 3. then by tree, +-- 4. then lexicographically by filename. +-- return true if a is better than b +function docfile_order (a, b) + if a.score > b.score then return true - elseif b.tree < a.tree then + elseif a.score < b.score then return false else a.ext_pos = a.ext_pos or ext_pos(a.name) @@ -40,6 +204,10 @@ function docfile_order (a, b) return true elseif a.ext_pos > b.ext_pos then return false + elseif a.tree > b.tree then + return true + elseif a.tree < b.tree then + return false else return (a.name < b.name) end @@ -68,7 +236,29 @@ function ext_pos(file) return pos or (config.ext_list_max + 1) end +----------------------------- public functions ----------------------------- + +-- return the "quality" of docfile +function docfile_quality(df) + if df.score > 0 then + return 'good' + elseif df.score > -100 then + return 'bad' + else + return 'killed' + end +end + +-- sort a doclist +function sort_doclist(dl, original_kw) + dl:stop() + set_list_scores(dl, original_kw) + table.sort(dl, docfile_order) +end + -- export a few symbols export_symbols(L, { - 'sort_docfiles', + 'sort_doclist', + 'docfile_quality', + 'confline_to_score', }) diff --git a/Master/texmf/scripts/texdoc/search.tlu b/Master/texmf/scripts/texdoc/search.tlu index fcb044d5189..fa35cce2754 100644 --- a/Master/texmf/scripts/texdoc/search.tlu +++ b/Master/texmf/scripts/texdoc/search.tlu @@ -9,25 +9,115 @@ local L = {} load_env(L, { 'export_symbols', 'os', 'string', 'table', 'lfs', 'kpse', 'io', - 'ipairs', 'assert', 'tonumber', 'type', 'print', 'tostring', - 'err_print', 'win32_hook', 'parse_zip', - 'config', 'alias', 'C', + 'ipairs', 'assert', 'error', 'tostring', 'setmetatable', + 'deb_print', 'err_print', 'win32_hook', 'parse_zip', + 'get_patterns', 'sort_doclist', 'docfile_quality', + 'config', 'C', }) ----------------------------- the docfiles list ----------------------------- +-- shared by all functions in this file +local s_doclist --- shared by all functions below -local s_doc_files +----------------------- docfile and doclist objects ------------------------ --- structure of the s_docfiles variable --- s_docfiles = { --- [1] = docfile1, docfiles2, ..., +-- doclist = { +-- [1] = docfile1, [2] = docfiles2, ..., +-- inv = { realpath1 = index1, ... } -- } +-- +-- The inv subtable is such that for all i +-- doclist.inv(doclist[i].realpath) == i + +local Doclist = {} +Doclist.__index = Doclist + +-- create a new list of docfiles +function Doclist:new() + local dl = { inv = {} } + setmetatable(dl, self) + return dl +end + +-- add a docfile to a list +function Doclist:add(df) + local index = self.inv[df.realpath] + if index then + self[index]:mergein(df) + else + local newindex = #self + 1 + self[newindex] = df + self.inv[df.realpath] = newindex + end +end + +-- stops a doclist +function Doclist:stop() + self.inv = nil +end + -- docfile = { --- name = filename relative to tree, absolute if tree == nil, --- tree = number of the tree in doc_roots, --- exact = <boolean> does pattern match exactly, +-- name = filename (used for scoring only) +-- tree = code of the tree, see below +-- matches = {pattern1, pattern2, ...} -- } +-- if tree > 1, this is the index of the tree in TEXDOCS +-- if tree = 0, then name is relative to TLROOT (file found from tlpdb only) +-- tree = - 1 if and only if file is a sty file. Here name is absolute. + +local Docfile = {} +Docfile.__index = Docfile + +-- create a new docfile objet using initilisation info +-- fields : name (relative to tree), tree, pattern +function Docfile:new(info) + df = {} + setmetatable(df, self) + -- get realpath, tree and prepare name + df.tree = info.tree + if info.tree > 0 then + df.realpath = texdocs_tree_to_path(info.tree, info.name) + elseif info.tree == 0 then + error('Unimplemented') + df.realpath = get_tlroot()..'/'..info.name + info.name = string.gsub(info.name, '^texmf(-dist)?/doc/', '', 1) + elseif info.tree == -1 then + df.realpath = info.name + else + error('Internal error: bad tree number') + end + -- remove first component of name if at least two directory levels + if info.tree > -1 then + local name = string.match(info.name, '^..-/(.+/.+)$') + if name then + df.name = '/'..name + else + df.name = info.name + end + else + df.name = info.name + end + -- initialise the list of matches + if info.pattern then + df.matches = { info.pattern } + else + df.matches = {} + end + return df +end + +-- merge a second docfile objet into self +function Docfile:mergein(df) + if df.tree > self.tree then + self.name = df.name + self.tree = df.tree + end + for _, m in ipairs(df.matches) do + table.insert(self.matches, m) + end +end + +-- from score.tlu +Docfile.quality = docfile_quality ------------------ get results from TEXDOCS (Ã la kpse) ------------------- @@ -49,71 +139,57 @@ function get_texdocs () local kpse_texdocs = kpse.expand_var("$TEXDOCS") -- expand the path and turn it into a lua list local raw_doc_roots = string.explode(kpse.expand_braces(kpse_texdocs), sep) - err_print('Search paths:', 'debug3') - for i, dir in ipairs(raw_doc_roots) do - doc_roots[i] = {} + local max = #raw_doc_roots + 1 + for j, dir in ipairs(raw_doc_roots) do + local i = max - j + local dr = {} local n + -- get path, !! and // values dir, n = string.gsub (dir, '//$', '') - doc_roots[i].recursion_allowed = (n == 1) - doc_roots[i].path, n = string.gsub (dir, '^!!', '') - doc_roots[i].index_mandatory = (n == 1) - err_print(string.format('%s (index_mandatory=%s, recursion_allowed=%s)', - doc_roots[i].path, - tostring(doc_roots[i].index_mandatory), - tostring(doc_roots[i].recursion_allowed)), - 'debug3') + dr.recursion_allowed = (n == 1) + dr.path, n = string.gsub (dir, '^!!', '') + dr.index_mandatory = (n == 1) + deb_print('texdocs', string.format( + 'texdocs[%d] = %s (index_mandatory=%s, recursion_allowed=%s)', + i, dr.path, + tostring(dr.index_mandatory), + tostring(dr.recursion_allowed))) + -- decide if we should use a ls-R index, the filesystem, or do nothing + local root, shift = lsr_root(dr.path) + if root and shift and dr.recursion_allowed then + dr.lsr = root + dr.lsr_shift = shift + deb_print('texdocs', string.format( + 'texdocs[%d] using index: %s (shift=%s)', i, root, shift)) + elseif not dr.index_mandatory and lfs.isdir(dr.path) then + dr.searchfs = true + deb_print('texdocs', string.format( + 'texdocs[%d] using filesystem search', i)) + end + -- register this in docroots + doc_roots[i] = dr end end --- return the real path of a docfile -function real_path(docfile) - if docfile.tree == nil then return docfile.name end +-- return the real path from a texdocs tree number + relative path +function texdocs_tree_to_path(tree, rel) if doc_roots == nil then get_texdocs() end - return win32_hook(doc_roots[docfile.tree].path..'/'..docfile.name) + return win32_hook(doc_roots[tree].path..'/'..rel) end -- find docfiles in texdocs directories -function get_docfiles_texdocs (pattern) - s_docfiles = {} +function get_doclist_texdocs(patlist) if doc_roots == nil then get_texdocs() end - for code, doc_root in ipairs (doc_roots) do - root, shift = lsr_root (doc_root.path) - if root and shift and doc_root.recursion_allowed then - err_print("Looking in tree '"..doc_root.path - .."' using ls-R file'" ..root.."/ls-R'.", 'debug4') - scan_lsr(root, code, shift, pattern) - elseif (not doc_root.index_mandatory) - and lfs.isdir(doc_root.path) then - err_print("Looking in tree '"..doc_root.path - .."' using filesystem.", 'debug4') - scan_tree(code, doc_root.path, '', - pattern, doc_root.recursion_allowed) + for code, dr in ipairs(doc_roots) do + if dr.lsr then + scan_lsr(patlist, code, dr.lsr, dr.lsr_shift) + elseif dr.searchfs then + scan_tree(patlist, code, dr.path, '', dr.recursion_allowed) end end - return s_docfiles -end - --- merge two components of a path, taking care of empty components -function merge_path (a, b) - return ((a == '') or (b == '')) and a..b or a..'/'..b end --- scan a tree without ls-R file -function scan_tree (code, base, cwd, pattern, recurse) - err_print("Entering directory: "..cwd, 'debug4') - for file in lfs.dir(base..'/'..cwd) do - if file ~= '.' and file ~= '..' then - local f = (cwd == '') and file or cwd..'/'..file - if lfs.isdir(base..'/'..f) then - if recurse then scan_tree(code, base, f, pattern, recurse) end - else - local df = process_file(file, f, code, pattern, true) - if df then table.insert(s_docfiles, df) end - end - end - end - err_print("Leaving directory: "..cwd, 'debug4') -end +end -- scope of doc_roots -- find a ls-R file in a parent directory an return it or nil function lsr_root (path) @@ -131,10 +207,27 @@ function lsr_root (path) end end +-- scan a tree without ls-R file +function scan_tree (patlist, code, base, cwd, recurse) + deb_print('filesea', "Entering directory: "..cwd) + for file in lfs.dir(base..'/'..cwd) do + if file ~= '.' and file ~= '..' then + local f = (cwd == '') and file or cwd..'/'..file + if lfs.isdir(base..'/'..f) then + if recurse then scan_tree(patlist, code, base, f, recurse) end + else + local df = process_file(patlist, file, f, code, true) + if df then s_doclist:add(df) end + end + end + end + deb_print('filesea', "Leaving directory: "..cwd) +end + -- scan a ls-R file -function scan_lsr (cwd, code, shift, pattern) +function scan_lsr(patlist, code, cwd, shift) local is_dir = {} -- is_dir[path] = true iff path is a dir - local results = {} + local results = Doclist:new() local isdoc = false local current_dir local l = #shift @@ -152,106 +245,125 @@ function scan_lsr (cwd, code, shift, pattern) isdoc = true current_dir = string.sub (dir_line, l+1) is_dir[current_dir] = true - err_print('Scanning directory: '..current_dir, 'debug4') + deb_print('lsrsea', 'Scanning directory: '..current_dir) elseif isdoc then - err_print("Finished scanning: "..shift, 'debug4') + deb_print('lsrsea', "Finished scanning: "..shift) break -- we're exiting the ./doc (or shift) dir, so it's over end elseif isdoc then - local df = process_file( - line, merge_path(current_dir, line), code, pattern) - if df then table.insert(results, df) end + local df = process_file(patlist, line, current_dir..'/'..line, code) + if df then results:add(df) end end end lsr:close() -- add non-directories to the list for _, df in ipairs(results) do if not is_dir[df.name] then - table.insert(s_docfiles, df) + s_doclist:add(df) end end end -end -- scope of doc_roots - ------------------------------- select results ------------------------------ - -- says if file has a 'good' extenstion according to ext_list -function check_ext(file, pattern) - local good_ext, exact_match = false, false +function check_ext(file) + file = string.lower(file) -- remove zipext if applicable file = parse_zip(file) -- then do the normal thing - local l, pat = string.len(pattern) + 1, pattern..'.' for _, e in ipairs(config.ext_list) do if e == '*' then - good_ext = true - if string.sub(file, 1, l) == pat then exact_match = true end + return true elseif (e == '') then - if not string.find(file, '.', 1, true) then good_ext = true end - if file == pattern then exact_match = true end + if not string.find(file, '.', 1, true) then + return true + end else - if string.sub(file, -string.len(e)) == e then good_ext = true end - if file == pattern..'.'..e then exact_match = true end + local dot_e = '.'..e + if string.sub(file, -string.len(dot_e)) == dot_e then + return true + end end end - return good_ext, exact_match + return false end --- return a docfile entry if it "matches", nil ortherwise -function process_file (file, pathfile, code, pattern) - err_print('Processing file: '..pathfile, 'debug5') - file = string.lower(file) - local base, ext = string.match(file, '^(.*)%.(.*)$') - if string.find(string.lower(pathfile), pattern, - 1, config.regex ~= 'regex') then - local good_ext, exact_match = check_ext(file, pattern) - err_print(string.format("File '%s' matches; good_ext=%s, exact=%s", - pathfile, tostring(good_ext), tostring(exact_match)), 'debug5') - if good_ext then - return { - name = pathfile, - tree = code, - exact = exact_match, - } +-- return a docfile object if file "matches", nil ortherwise +function process_file(patlist, file, pathfile, code) + deb_print('kpse', 'Processing file: '..pathfile) + local docfile + local pattern + for _, pattern in ipairs(patlist) do + if string.find(string.lower(pathfile), string.lower(pattern.name), + 1, config.mode ~= 'regex') then + local good_ext = check_ext(file) + deb_print('kpse', string.format( + "File '%s' matches '%s'; good_ext=%s", + pathfile, pattern.name, tostring(good_ext))) + if good_ext then + local info = { + name = pathfile, + tree = code, + pattern = pattern, + } + if docfile then + docfile:mergein(Docfile:new(info)) + else + docfile = Docfile:new(info) + end + end end end - return nil + return docfile end ------------------------- get results from elsewhere ------------------------ +---------------------------- look for sty files ---------------------------- --- for sty files, we obviously don't want to look in TEXDOCS... -function get_docfiles_sty (styname) - return {{ - name = kpse.find_file(styname) , - exact = true, - tree = nil, - }} +-- add doclist entries for sty files in patlist +function get_doclist_sty(patlist) + for _, pat in ipairs(patlist) do + local file = kpse.find_file(pat.name) + if file then + local df = Docfile:new({ + name = file, + tree = -1, + pattern = pat, + }) + s_doclist:add(df) + end + end end ------------------------------ main function ------------------------------- -- find docfiles according to pattern -function get_docfiles(pattern) - local no_regex = (config.mode ~= 'regex') - -- apply aliases if relevant - if no_regex and config.alias_switch and alias[pattern] then - err_print (pattern.." aliased to "..alias[pattern], 'info') - pattern = alias[pattern] - end - -- search using the appropriate function - if string.match(string.lower(pattern), '%.([^/.]*)$') == 'sty' - and no_regex then - return get_docfiles_sty(pattern) - else - pattern = string.lower(pattern) - return get_docfiles_texdocs(pattern) +function get_doclist(pattern) + -- get patterns (inc. aliases) + local normal, sty = normal_vs_sty(get_patterns(pattern)) + -- initialise result list + s_doclist = Doclist:new() + -- get results + get_doclist_sty(sty) + get_doclist_texdocs(normal) + -- finally, sort results + sort_doclist(s_doclist, pattern) + return s_doclist +end + +-- separate sty patterns from the rest +function normal_vs_sty(list) + if config.mode == 'regex' then return list, {} end + local normal, sty = {}, {} + for _, p in ipairs(list) do + if string.match(string.lower(p.name), '%.([^/.]*)$') == 'sty' then + table.insert(sty, p) + else + table.insert(normal, p) + end end + return normal, sty end -- finally export a few symbols export_symbols(L, { - 'real_path', - 'get_docfiles', + 'get_doclist', }) diff --git a/Master/texmf/scripts/texdoc/texdoc.tlu b/Master/texmf/scripts/texdoc/texdoc.tlu index 013d731d1af..28470c597e7 100755 --- a/Master/texmf/scripts/texdoc/texdoc.tlu +++ b/Master/texmf/scripts/texdoc/texdoc.tlu @@ -54,17 +54,18 @@ end -- initialize kpathsea kpse.set_program_name(arg[-1], 'texdoc') --- declare global variables; they will be made read-only later +-- declare global variables; +-- they will be made read-only as soon as they are set C = {} -- constants config = {} -- configuration settings -alias = {} -- aliases -- actually load the components now -texdoc_load('constants') -- makes C read-only +texdoc_load('constants') texdoc_load('functions') -texdoc_load('config') -- makes config and alias read-only -texdoc_load('search') +texdoc_load('alias') texdoc_load('score') +texdoc_load('config') +texdoc_load('search') texdoc_load('view') -- execute main() diff --git a/Master/texmf/scripts/texdoc/view.tlu b/Master/texmf/scripts/texdoc/view.tlu index 5a94508bff2..b2f8d68a139 100644 --- a/Master/texmf/scripts/texdoc/view.tlu +++ b/Master/texmf/scripts/texdoc/view.tlu @@ -9,11 +9,10 @@ local L = {} load_env(L, { 'export_symbols', 'string', 'os', 'table', 'io', - 'tonumber', 'ipairs', 'print', + 'tonumber', 'ipairs', 'print', 'assert', 'config', - 'real_path', 'C', - 'err_print', 'parse_zip', + 'deb_print', 'err_print', 'parse_zip', }) ----------------------------- view a document ------------------------------ @@ -21,7 +20,7 @@ load_env(L, { -- view a document -- see search.tlu for the structure of the argument function view_doc(docfile) - return view_file(real_path(docfile)) + return view_file(docfile.realpath) end -- get viewer and viewer_replacement before calling try_viewing @@ -39,19 +38,21 @@ function view_file (filename) if zipext then local unzip_cmd = config['unzip_'..zipext] if not unzip_cmd then - err_print("No unzip command for ."..zipext..' files, skipping ' - ..filename, 'error') + 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('Failed to create tempdir to unzip.', 'error') + err_print('error', 'Failed to create tempdir to unzip.') return false end local basename = string.match(nozipname, '.*/(.*)$') or nozipname local tmpfile = '"'..tmpdir..'/'..basename..'"' - if not os.execute(unzip_cmd..' "'..filename..'">'..tmpfile) then - err_print("Failed to unzip '"..filename.."'", 'error') + 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 @@ -68,16 +69,11 @@ function view_file (filename) -- special case : sty files use txt viewer if viewext == 'sty' then viewext = 'txt' end if not config['viewer_'..viewext] then - err_print ("cannot find a viewer for file\n\t"..filename.. - "\nUsing viewer_txt as a fallback. Set the 'viewer_"..viewext.. - "' variable in texdoc.cnf to avoid this.", "warning") + err_print('warning', + "No viewer_"..viewext.." defined, using viewer_txt.") viewext = 'txt' - if not config['viewer_'..viewext] then - err_print ("text viewer not found. This ".. - "should not happen, sorry. Skipping\n\t"..filename, "error") - return false - end end + assert(config['viewer_'..viewext], 'Internal error: no viewer found.') return try_viewing(config['viewer_'..viewext], viewer_replacement) end @@ -89,9 +85,9 @@ function try_viewing (view_command, viewer_replacement) else view_command = view_command..' '..viewer_replacement end - err_print(view_command, 'debug1') + deb_print('view', 'View comand: '..view_command) if not os.execute(view_command) then - err_print("Failed to execute '"..view_command.."'", "error") + err_print('error', "Failed to execute '"..view_command.."'") return false end return true @@ -100,18 +96,17 @@ end ----------------------------- display results ------------------------------ -- print a list of files (structure: see search.tlu) as a menu --- if showall is false, stops as soon a non-exact match is encountered --- (unimplemented right now, waiting for the scoring routine) -function print_menu(name, docfiles, showall) +-- 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 docfiles[max_lines+1] then + if config.interact_switch and doclist[max_lines+1] then -- there may be too many lines, count them local n if showall then - n = #docfiles + n = #doclist else n = 0 - while docfiles[n+1] and docfiles[n+1].exact do + while doclist[n+1] and doclist[n+1]:quality() == 'good' do n = n + 1 end end @@ -126,30 +121,30 @@ function print_menu(name, docfiles, showall) end end local i, doc - for i, doc in ipairs (docfiles) do - if (doc.exact == false) and not showall then break end + 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 - local score = doc.exact and 1 or 0 - print(name, score, real_path(doc)) + print(name, doc.score, doc.realpath) else - print(string.format('%2d %s', i, real_path(doc))) + 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 docfiles[num] then - view_doc(docfiles[num]) + if num and doclist[num] then + view_doc(doclist[num]) end end end ----------------------- deliver results base on mode ----------------------- -function deliver_results(name, docfiles, many) +function deliver_results(name, doclist, many) -- ensure that results were found or apologize - if not docfiles[1] then + 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 @@ -157,21 +152,21 @@ function deliver_results(name, docfiles, many) return end -- shall we show all of them or only the "good" ones? - local showall = (config.mode == 'regex') or (config.mode == 'search') - if not showall and not docfiles[1].exact then + local showall = (config.mode == 'regex') or (config.mode == 'showall') + if not showall and doclist[1]:quality() ~= 'good' then showall = true - err_print ("No exact match, trying full search mode.", "info") + 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 docfiles[2] - or not docfiles[2].exact and not showall) then - view_doc(docfiles[1]) + 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, docfiles, showall) + print_menu(name, doclist, showall) end end diff --git a/Master/texmf/texdoc/texdoc.cnf b/Master/texmf/texdoc/texdoc.cnf index 9b671ed6903..fbbed8c65aa 100644 --- a/Master/texmf/texdoc/texdoc.cnf +++ b/Master/texmf/texdoc/texdoc.cnf @@ -47,9 +47,49 @@ # # mode = view # interact_switch = true -# alias_switch = true # but false if mode is 'regex' -# ext_list = pdf, html, txt, man1.pdf, man5.pdf, ps, dvi, # empty string at end -# verbosity_level = 3 +# alias_switch = true +# ext_list = pdf, html, txt, ps, dvi, # Note: empty string at end +# badext_list = txt, # Note: empty string at end +# verbosity_level = 2 # Print: 0 nothing, 1 errors, 2 warnings, 3: infos +# debug_list = # the empty list +# machine_switch = false + +### Score ### + +# Only results with positive scores are displayed (unless mode is 'showall'). +# Results with score <= 100 are never displayed. +# +# You can adjust the score of results containing a pattern with adjscore, +# either globally or only for specific keywords + +# Makefile's are never documentation, -1000 should be enough to kill them +adjscore /Makefile = -1000 + +# tex-virtual-academy provides a lot of fake matches +adjscore /tex-virtual-academy-pl/ = -50 + +# Uncomment this to make the man pages have a greater priority +#adjscore .man1. = 5 +#adjscore .man5. = 5 + +# 'texdoc' may look like "tex's documentation" but it isn't... +adjscore(tex) texdoc = -10 +adjscore(tex) tex-gyre = -10 +adjscore(tex) tex-ps = -10 + +# avoid too many results to be shown for 'latex' +# package names +adjscore(latex) guide-to-latex = -10 # only usefull with the book +adjscore(latex) latex-web-companion = -10 +adjscore(latex) tufte-latex = -10 +adjscore(latex) cweb-latex = -10 +adjscore(latex) duerer-latex = -10 +adjscore(latex) cjw-latex = -10 +adjscore(latex) ocr-latex = -10 +# file names +adjscore(latex) Content_LaTeX_Package_Demo = -10 +adjscore(latex) example_latex = -10 +adjscore(latex) test_latex = -10 ### Aliases ### @@ -207,111 +247,39 @@ alias overcite = /cite/README ## a few easy patterns -# egrep 'manual\.pdf\>' docfiles.list -alias cjhebrew = cjhebrew/manual -alias elpres = elpres-manual -alias interactiveworkbook = interactiveworkbookmanual -alias msc = msc/manual +# egrep 'manual\.pdf\>' alias pdfslide = pdfslide/demo -alias pdftricks = pdftricks/manual -alias pst-qtree = pst-qtree-manual -alias sciposter = scipostermanual -alias sectionbox = sectionboxmanual alias t-angles = t-manual alias texmate = texmate2manual alias tree-dvips = tree-manual -alias lingmacros = lingmacros-manual -alias velthuis = velthuis/manual -alias wallpaper = wallpapermanual -# egrep 'user\.pdf\>' docfiles.list +# egrep 'user\.pdf\>' alias cweb-latex = cweb-user -alias footnpag = footnpag-user alias seminar = sem-user -alias rcs = rcs-user -# egrep 'doc\.pdf\>' docfiles.list -alias testflow = testflow_doc -alias arev = arevdoc +# egrep 'doc\.pdf\>' alias barcode = eandoc.pdf alias barr = diaxydoc.pdf -alias clock = clockdoc alias doublestroke = dsdoc.pdf alias enctex = encdoc-e alias enctex-cz = encdoc -alias ethiop = ethiodoc -alias exam = examdoc -alias fge = fge-doc -alias figbib = figbib_doc -alias greektex = greektexdoc -alias gu = gudoc -alias hitec = hitec_doc alias hyplain = hydoc.pdf alias jurabib = jbendoc alias jurabib-de = jbgerdoc alias juramisc = jmgerdoc -alias mathdesign = mathdesign-doc -alias linguex = linguex-doc alias marvosym = marvodoc -alias mciteplus = mciteplus_doc -alias musixtex = generic/musixtex/musixdoc.pdf -alias mwcls = mwclsdoc +alias musixtex = musixdoc alias ofs = ofsdoc-e -alias ofs-cz = ofsdoc-e -alias petiteannonce = petiteannonce.doc.pdf +alias ofs-cz = ofsdoc alias petri-nets = pndoc -alias pgf-soroban = pgf-soroban-doc -alias pinlabel = pinlabdoc -alias prosper = prosper-doc -alias pst-3dplot = pst-3dplot-doc -alias pst-asr = pst-asr-doc -alias pst-bar = pst-bar-doc -alias pst-barcode = pst-barcode-doc -alias pst-circ = pst-circ-doc -alias pst-coil = pst-coil-doc -alias pst-coxcoor = pst-coxcoor_doc -alias pst-coxeterp = pst-coxeterp_doc -alias pst-eps = pst-eps-doc -alias pst-fractal = pst-fractal-doc -alias pst-fun = pst-fun-doc -alias pst-func = pst-func-doc alias pst-geo = pst-map3d-doc -alias pst-grad = pst-grad-doc -alias pst-jtree = pst-jtree-doc -alias pst-light3d = pst-light3d-doc -alias pst-math = pst-math-doc -alias pst-optexp = pst-optexp-doc -alias pst-optic = pst-optic-doc -alias pst-osci = pst-osci-doc -alias pst-pad = pst-pad-doc -alias pst-solides3d = pst-solides3d-doc -alias pst-soroban = pst-soroban-doc -alias pst-stru = pst-stru-doc -alias pst-text = pst-text-doc -alias pst-uml = pst-uml-doc -alias pst-vue3d = pst-vue3d-doc -alias pstricks-add = pstricks-add-doc -alias pxfonts = pxfontsdocA4 -alias rotpages = rotpages-doc alias sanskrit = sktdoc -alias sdrt = sdrt-doc -alias synproof = synproof-doc -alias talk = talkdoc -alias teubner = teubner-doc -alias tikz-inet = tikz-inet-doc -alias toptesi = toptesi-doc -alias txfonts = txfontsdocA4 -alias uebungsblatt = uebungsblatt-doc -alias upmethodology = upmethodology-doc -alias wasy = wasydoc -alias xyling = xyli-doc ## aliases basically borrowed from texdoctk.dat with some adaptations alias texguide = usrguide alias lehman = fontinstallationguide alias uktugfaq = newfaq -alias datenumber = datenumber/doc. alias datenumber-de = datenumber/docgerman alias index = ind alias genfont1 = fntguide @@ -325,18 +293,15 @@ alias cmsuper = cm-super/README alias euro = eurosamp alias fourier = fourier-doc-en alias lmfonts = lm-info -alias skt = sktdoc alias t1enc1 = fontsmpl alias yfonts = yfonts/readme alias mfpic1 = mfpguide alias dutch = rapdoc alias montex = mlsquick alias MeX = base/mex.html -# alias gentlpl = gentl-pl # temporarily rm'ed from TL (sources needed) alias akademia = tex-virtual-academy-pl/index.html alias cyrillic = cyrillic/00readme.txt alias otibet = otibet/unidoc -alias memoir = memman alias layouts = layman alias texsis = texsis/base/README alias startex = startex/base/guide @@ -368,7 +333,6 @@ alias adrconv = adrguide alias tangles = t-angles/t-manual alias mathenv = mdwtab alias nath = nathguide -alias gauss = gauss-doc alias gnlogic = gn-logic14 alias footnote1 = mdwtools/footnote alias footnote2 = yafoot/yafoot-man @@ -394,12 +358,10 @@ alias musictex = musicdoc alias acmtrans = acmtr2e alias aastex = aastex/aasguide alias ieee = IEEEtran_HOWTO -alias ieeepes = ieeepes_doc alias nrc = nrc/userguide alias kluwer = kluwer/usrman alias spie = spie/article alias psgo = psgo/README -alias skak = skakdoc alias cv = curve/curve alias preprint = preprint/00readme.txt alias sffms = sffms_manual |