From 78b57f12e537918f0e6f9f9a1d8d0017cb6c86ba Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 16 Dec 2012 00:59:24 +0000 Subject: consolidate texdoctk files in new directory (uninstalled just for the moment) git-svn-id: svn://tug.org/texlive/trunk@28542 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/tetex/README.texdoctk | 298 ---- .../source/texk/texlive/linked_scripts/Makefile.am | 2 - .../source/texk/texlive/linked_scripts/Makefile.in | 2 - .../texk/texlive/linked_scripts/tetex/texdoctk.1 | 217 --- .../texk/texlive/linked_scripts/tetex/texdoctk.pl | 1857 -------------------- Build/source/utils/README | 3 + Build/source/utils/texdoctk/README.texdoctk | 298 ++++ Build/source/utils/texdoctk/texdoctk.1 | 217 +++ Build/source/utils/texdoctk/texdoctk.pl | 1857 ++++++++++++++++++++ 9 files changed, 2375 insertions(+), 2376 deletions(-) delete mode 100644 Build/source/texk/tetex/README.texdoctk delete mode 100644 Build/source/texk/texlive/linked_scripts/tetex/texdoctk.1 delete mode 100755 Build/source/texk/texlive/linked_scripts/tetex/texdoctk.pl create mode 100644 Build/source/utils/texdoctk/README.texdoctk create mode 100644 Build/source/utils/texdoctk/texdoctk.1 create mode 100755 Build/source/utils/texdoctk/texdoctk.pl diff --git a/Build/source/texk/tetex/README.texdoctk b/Build/source/texk/tetex/README.texdoctk deleted file mode 100644 index 54217cb61ce..00000000000 --- a/Build/source/texk/tetex/README.texdoctk +++ /dev/null @@ -1,298 +0,0 @@ - texdoctk v.0.5.3 - -texdoctk is a Perl/Tk-based frontend for easy access of package documentation -for the TeX typesetting system on Unix platforms. It includes the following -files: - - texdoctk - the program source - texdoctk.dat - the database containing the information about the - accessible documentation files for teTeX-texmf - texdocrc.defaults - the system-wide default specification for viewer - and printer settings - texdoctk.1 - manpage - README.texdoctk - this file -The current version is 0.6.0. - -REQUIREMENTS -The program is written in Perl/Tk; it requires Perl 5 and Perl/Tk 8.x. It is -known to run with Perl 5.004_04 or higher and PerlTk 800.015. -The database file texdoctk.dat is made for the teTeX distribution. -Note that the program is *not* a viewer, but an interface to access a document -with the appropriate viewer. Thus, you need to have appropriate viewers for -the different formats to actually read the files. Documentations are available -as .dvi, .ps, .pdf, .html or plain text; some packages are only documented in -the .sty files. For plain text files (.txt, .sty etc.), texdoctk's own text -viewer can be used (default). If a document format is not known, texdoctk -will by default assume that it is plain text and use the text file viewer; -this behaviour can be switched off in the Settings menu. -If you want to print the documentations, you will need converters to turn -non-PS files into PostScript. Here are some suggestions: -dvi->ps: dvips (is part of teTeX) - http://www.radicaleye.com/dvips.html -pdf->ps: pdf2ps - http://www.cs.wisc.edu/~ghost - Acrobat Reader - http://www.adobe.com -html->ps: html2ps - http://user.it.uu.se/~jan/html2ps.html -plain text->ps: a2ps - http://www-inf.enst.fr/~demaille/a2ps/ -To increase the font size automatically for high-resolution screen, the program -xwininfo is used; texdoctk will work without as well, though. - -INSTALLATION -The program texdoctk can be copied into any directory where programs are stored -on your system, e.g. into /usr/local/bin or, probably more adequate, into -/usr/local/teTeX/bin. It assumes that you have the env command in /usr/bin/ -available to determine the location of the Perl executable; therefore, you may -need to change the first line of the code if this is not the case for your -system or if for some reason your Perl executable is not called "perl"; you -will also have to change the perl call in the sub viewslc as well. -The database file texdoctk.dat and the configuration file texdocrc.defaults -must then be put into a subdirectory of the main texmf directory called -texdoctk. If you want to include information for your local system, -generate a file texdoctk-local.dat. Make sure to run texhash after -installation. See the manpage for more info. -Set the defaults in texdocrc.defaults according to your system; you can -replace the settings which are specified in the shipped file, but do not -uncomment variables for items which are not available or applicable for you, -but just leave the value empty by specifying nothing. -The individual users can define their own preferences by copying the system -texdocrc.defaults to ~/.texdocrc and assign new values to the items to be -changed. They can also establish an additional personal database for packages -they might have installed in their respective $HOME; this database must be -called texdoctk-pers.dat and reside in $HOMETEXMF/texdoctk/. -If you meet the requirements concerning the teTeX distribution, I assume that -the texdoctk.dat file should work without failures; if you have another -distribution or if your texmf/doc tree is somehow modified, it may happen that -a file is not found in spite of the program trying to find it elsewhere. You -will have to edit the file then, but make sure to keep the right format for -the entries: -;Short description for listbox (opt. );path in doc directory;optional keywords -(without breaking the line!). If the documentation is included in the .sty file -instead of a proper documentation file, the optional keywords should start with --?- directly after the semicolon, where ? is 0, 1, 2 or 3; these are flags -which indicate in which part of the .sty the instructions are placed. See the -database file and/or the manpage for more details if necessary. -The documentation is grouped into 17 categories; the 18th button of the main -panel is inactive by default. If you have special documents which do not fit -into any of the categories, you can create a block with a new name in -texdoctk-local.dat or texdoctk-pers.dat with the respective entries. -In the settings window you see a checkbox in the html->ps and text->ps -converter menus for switching on/off output redirect. This is due to the fact -that some converters do not write their output into a file but to stdout by -default, so a redirect is needed, e.g. -a2ps myfile.txt >myfile.ps - -DISCLAIMER -texdoctk v.0.6.0 (Sep 23, 2004) - GUI for TeX documentation access -Copyright (C) 2000-2004 Thomas Ruedas -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -ACKNOWLEDGEMENTS -Thomas Esser included the program in the teTeX distribution of TeX and Friends. -He provided me with informations about changes in the texmf tree and made a -number of very useful suggestions. He also has coordinated and kept track of -several additions from other contributors, who fixed bugs and added extensions -e.g. for use under Win32 systems. -Reinhard Kotucha and Andreas Werner made very valuable comments and suggestions -to enhance v.0.3.0, especially about the special treatment of Netscape. -Reinhard Kotucha also made many useful suggestions and provided patches for -v.0.4.0; unfortunately, I could not implement all these ideas yet. -Hans Fredrik Nordhaug made some suggestions, e.g. concerning local and -personal texmf trees, and reported several bugs in different releases; he also -contributed fixes/patches. -Adrian Bunk also has reported a bug and contributed a small manpage for the -program. He made a Debian GNU/Linux package of texdoctk. -Michael Sanders reminded me to set the permissions right in the tarball. -As this is my first application written in PerlTk, it happened that I could -not solve every problem with my book and the other documentation, but had to -ask for help on comp.lang.perl.tk. Paul R. Andersen and Stephen O. Lidie have -given helpful replies and examples for me to try out. -Fabrice Popineau, and possibly others who I don't know, have provided -portability to Win32 platforms for use with fpTeX. Staszek Wawrykiewicz helped -making it ready for use with new TeXLive editions. -Paul Szabo pointed out a potential security risk related to the way names of -temporary files are generated. - -TO DO LIST -Unfortunately, I didn't have time to implement all suggestions made by the -aforementioned people; I hope that I can do that at some later time: -- widget placement in topic toplevels becomes ugly when the toplevel is - stretched or shrunk; should be made more elegant -- raise existing texdoctk window instead of possibly running texdoctk twice; - (this seems to be difficult, because it requires interprocess communication - which is kind of unsafe and requires the use of perl -T) -Possible further long-term enhancements: -- maybe use Williams Catalogue for automatically building database during - installation -- refined printing facility - -BUGS -Netscape error output will be written to stderr even if the quiet mode was set, -because I didn't manage to start it with the "inline" perl script. -Widget placement in topic toplevels becomes ugly when the toplevel is stretched -or shrunk. -The font in the frame labels of the Settings menu are not forced to the default -font; this will become visible e.g. at hi-res screens, where the label font is -not scaled up. -Please let me know if you find bugs or have suggestions for improvements. - -HISTORY/CHANGES -v.0.6.0 Sep 23, 2004 - - Unknown document formats will be opened as plain text with the text - file viewer by default; the Settings menu was given a new button to - toggle this behaviour. - - Allow for texmf-dist and texmf-doc trees for compliance with teTeX 3 - and TeXLive. - - Made an attempt to allow for additional personal user's databases to - be located in $HOMETEXMF, following a long-standing suggestion of - H.F.Nordhaug. Additional local and personal databases do not need - to be copies of the system database; instead their contents will be - appended to the entries of the default list. - - Fixed a bug with the handling of the local texmf tree reported by - Sebastian Luque. - - Updated this README and the manpage. -v.0.5.2 May 20, 2004 - - Changed the name generation of temporary files to something random - in order to address a potential security risk pointed out by Paul - Szabo. - - Replaced -q option for enabling "quiet" behaviour by -v option for - enabling "verbose" behaviour; quiet behaviour is now the default and - was extended to suppress the popup of Warning windows (popmsg level - 1). - - Added a possibility to have the Settings menu write the user's - ~/.texdocrc (older suggestion by R.Kotucha). NB: It is not intended - to write the system-wide texdocrc.defaults, because it does not set - $TEXDOCPATH and $LOCALDOCPATH. - - Button colours are made configurable through the texdocrc files or - the Settings menu. This is intended to fix a problem H.F.Nordhaug - reported with users of newer versions of the KDE, where some button - colours suddenly where messed up. - Validity of entered colours - is checked if X11's showrgb program is available. - - DVIPS_OPTS, PDFPS_OPTS and PRINT_OPTS in texdocrc.defaults are now - obsolete, but still supported. It seemed more reasonable to treat - the contents of DVIPS_CONV, PDFPS_CONV and PRINT_CMD as command lines - (which actually would have already been possible all the time). The - same is true for the viewer variables. - - Command line options can now be grouped (i.e. -av instead of -a -v). - - Cursor changes from arrow to watch in some tasks, to indicate a - process which takes a bit of time. - - fixed some glitches in databases: semicolons at the end of the - pdfTeX-related entries; corrected description of ltxtable (hint by - Rolf Niepraschk) and changed its position; corrected description of - AMSguide (AMS TeX instead of AMS LaTeX) (hint by H.F.Nordhaug) - - several additions by other contributors, for instance support for - Win32 systems -v.0.5.1 April 21, 2001 - - Enhanced right-button search function so that compressed doc files - are also found. - - Fixed a bug in the documentation finding subroutine reported by H.F. - Nordhaug: the compression determination block in sub finddoc was - broken. - - Improved treatment of entering an empty string in the search: - this is now explicitly treated as demand for display of the whole - database, instead of search for a null string. - - Automatic selection of list item in listbox if it contains only one - element; this will frequently happen in search results. In this - context, the autoview flag (option -a) has been introduced in the - texdocrc.defaults and the Settings menu: if it is chosen, the - appropriate viewer will be started automatically in the case of - one-item listboxes. - - Made , , and definitions active in - all widgets; thus, you don't need to type in the main window - to quit, for example. Introduced new global key binding for raising - the main window (). - - Fixed a braindead typo in the texdoc-*.dat files (too dumb to tell). - - Some small changes/updates in the Help text; the button and window - are now named "Help/About". - - Added an emacs perl-mode directive at the end, mostly for my - convenience. -v.0.5.0a April 19, 2001 - - Fixed bug in texdoc-102.dat reported by H.F.Nordhaug: correct path - for multirow is latex/multirow/multirow.sty (instead of - latex/misc/multirow.sty, as in texdoc-100.dat) -v.0.5.0 April 18, 2001 - - For some packages, the only documentation is included in the .sty - file itself. This documentation is now made accessible by extracting - the comments/instructions, writing them into a temporary text file - and calling the text file viewer on it. Thus 38 additional - documentation files are made accessible now. - - implementation of a suggestion by Hans Fredrik Nordhaug: contents of - the local texmf tree ($TEXMFLOCAL) can be included now. Arbitrary - inclusion of additional private texmf trees is not yet possible, - though. - - Two fixes/improvements in the databases by R.Kotucha were made - (concerning epslatex and the MetaPost tutorial) - - R.Kotucha suggested the use of the program xwininfo to determine - screen resolution and switch to a larger font size at hi-res screens. - He provided a patch for this, which I added after a slight - adaptation. - - auto-determination of Perl's path (stolen from some script by Thomas - Esser, IIRC) - - If a beta release of teTeX is used, the teTeX-1.0.2 database will be - used as a default instead of the 1.0.0 database - - introduced new message type with transient windows - - fatal error messages if essential config/database files are not found - - some syntax cosmetics -v.0.4.0 June 11, 2000 - - implementation of several suggestions by Reinhard Kotucha and - Andreas Werner: - * More than 1 document can now be viewed at one time, because the - viewers now run as background processes. They are not killed when - texdoctk itself is quit. - If Netscape is your browser, HTML documents are now loaded into - an existing Netscape window; no new Netscape will be started. This - is to be a bit economic with system resources. - * The Search button resp. now switches on/off the search - entry widget; this is to avoid that multiple entry widgets come up, - because that doesn't make much sense. - * If no TXT_VIEWER is defined, the environment variable $PAGER will - be used, if defined (but see below). - - bugs/fixes and suggestions reported by Hans Fredrik Nordhaug: - * $j for loop in sub srchstr was too short: - $j<$maxind[$i] --> $j<$maxind[$i]+1 - * misplaced last SRCH in keywords branch of sub srchstr: last SRCH - had to be put into inner if block - * added support of zip compression format - - bug/fix reported by Adrian Bunk: - * ambiguous use of redirection flag/sign hor html and text->ps - conversion - - own text viewer for plain text documentation files; this is now the - default in the original texdocrc.defaults - - kpsewhich instead of find is used for rescue file search - - temporary files generated when printing or possibly decompressing (as - in Debian) now get different names to prevent overwriting files which - are still in use - - main, settings, and help windows made non-resizable - - suppressed availability of listbox selection to X selection - - document selection toplevel windows will be raised now instead of - being opened twice or more times if they are already open - - uniform font for all text-containing widgets explicitly set; I had - some weird font configuration when running texdoctk under a CDE - - environment -v.0.3.0 March 11, 2000 - - first full public release - - implementation of some suggestions by Thomas Esser: - use of kpsewhich, changes in directory and database configuration - implemented cd to file directory to ensure rendering of graphics - made viewer message output suppression really quiet - better layout of help window -v.0.2 March 7, 2000 - - first public release (preliminary) -v.0.1 - private trial version, does not exist anymore - -AUTHOR -Thomas Ruedas -tr@geol.ku.dk -http://www.geophysik.uni-frankfurt.de/~ruedas/progs.html diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am index f2df72715b9..297f0ddeb3e 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.am +++ b/Build/source/texk/texlive/linked_scripts/Makefile.am @@ -161,7 +161,6 @@ texmf_dist_other_scripts = \ sty2dtx/sty2dtx.pl \ svn-multi/svn-multi.pl \ tetex/e2pall.pl \ - tetex/texdoctk.pl \ tetex/updmap.pl \ tetex/updmap-sys.sh \ texdoc/texdoc.tlu \ @@ -217,7 +216,6 @@ dist_man_MANS = \ tetex/rubibtex.1 \ tetex/rumakeindex.1 \ tetex/texconfig.1 \ - tetex/texdoctk.1 \ tetex/texlinks.1 \ tetex/updmap.1 \ tetex/updmap.cfg.5 \ diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in index b6c40a624a2..601d42af7e8 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.in +++ b/Build/source/texk/texlive/linked_scripts/Makefile.in @@ -347,7 +347,6 @@ texmf_dist_other_scripts = \ sty2dtx/sty2dtx.pl \ svn-multi/svn-multi.pl \ tetex/e2pall.pl \ - tetex/texdoctk.pl \ tetex/updmap.pl \ tetex/updmap-sys.sh \ texdoc/texdoc.tlu \ @@ -392,7 +391,6 @@ dist_man_MANS = \ tetex/rubibtex.1 \ tetex/rumakeindex.1 \ tetex/texconfig.1 \ - tetex/texdoctk.1 \ tetex/texlinks.1 \ tetex/updmap.1 \ tetex/updmap.cfg.5 \ diff --git a/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.1 b/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.1 deleted file mode 100644 index e7aebb7098a..00000000000 --- a/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.1 +++ /dev/null @@ -1,217 +0,0 @@ -.TH TEXDOCTK 1 -.SH NAME -texdoctk \- GUI for easier access of TeX package and program documentations -.SH SYNOPSIS -.B texdoctk --[aq] -.SH "DESCRIPTION" -.B texdoctk -is a GUI for easier access to a large part of the vast amount -of package and program documentations and tutorials for TeX and its -different derivatives (mainly LaTeX). It is optimized and included in -the teTeX and fpTeX distributions and also available with TeXLive. -.PP -The documentation is grouped into 17 categories; the 18th button of the main -panel is inactive by default and intended for use with local additions (see -section -.B CONFIGURATION -below). -.PP -In the settings window you see a checkbox in the html->ps and text->ps -converter menus for switching on/off output redirect. This is due to the fact -that some converters do not write their output into a file but to stdout by -default, so a redirect is needed, e.g. -.PP -a2ps myfile.txt >myfile.ps -.SH "OPTIONS" -.TP -.I "\-v" -verbose: enable some viewer messages which are otherwise sent to stderr, -as well as some warning popup windows. This can also be set in a -configuration file. -.TP -.I "\-a" -autoview: autostart viewer if a listbox contains only one item (this will -frequently happen in search results). This can also be set in a configuration -file. -.SH "CONFIGURATION" -.PP -The configuration is controlled by the system default configuration file -($TEXMFMAIN)/texdoctk/texdocrc.defaults, most of whose entries can though be -overridden by the users' own optional ~/.texdocrc files and/or command line -options. -.SS The Settings menu and configuration files -.PP -The Settings menu is used to change the user-definable settings of \fBtexdoctk\fP -for the duration of the program call or as new defaults. The latter case is -the purpose of the Save button, which generates or rewrites the user's own -~/.texdocrc file. The system defaults cannot be edited with the Settings -menu. -.TP -Paths -The TEXMF-type paths on the system are reported, and the user can specify the -name of the subdirectory of $HOMETEXMF, where the personal documentation is -stored. -.TP -General viewer behaviour - -.I Suppress error messages -toggle verbose mode (see option -v); default is off. - -.I Autostart viewer for one-item listboxes -if a listbox contains only one item (see option -a) - -.I Use text viewer for unknown file format -i.e. treat the file as plain text. \fBtexdoctk\fP should recognize the usual file -formats and also relate names like README to plain text, but some docs may have -freely invented names. Default is on; if switched off, trying to view such -files will raise an error. The switch does not influence printing: unrecognized -formats cannot be printed. - -.I Change viewer colours -using either RGB triplets in the format #rrggbb or the standardized names. -.TP -DVI/PostScript/PDF/HTML/Plain text -For text files, \fBtexdoctk\fP provides an own viewer. If this viewer is disabled, -but no alternative viewer is specified, \fBtexdoctk\fP tries to read the content -of the environment variable $PAGER. - -If you want to print the documentations, you will need converters to turn -non-PS files into PostScript. Here are some suggestions: - -\& dvi->ps: -dvips (is part of teTeX) (http://www.radicaleye.com/dvips.html) - -\& pdf->ps: -pdf2ps (http://www.cs.wisc.edu/~ghost) or -Acrobat Reader (http://www.adobe.com) - -\& html->ps: html2ps (http://user.it.uu.se/~jan/html2ps.html) - -\& plain text->ps: a2ps (http://www-inf.enst.fr/~demaille/a2ps/) - -The html->ps and text->ps converter menus for switching on/off output redirect. -This is due to the fact that some converters do not write their output into a -file but to stdout by default, so a redirect is needed, e.g. -.B a2ps myfile.txt >myfile.ps -.PP -The system-wide configuration file is ($TEXMFMAIN)/texdoctk/texdocrc.defaults -and should only be writable by the administrator of the installation using any -text editor. The optional user configuration file is ~/.texdocrc and can -override all but those system settings which affect the installation as a -whole. The preferred way of changing it is through the Settings menu. -.SS The databases -\fBtexdoctk\fP comes with a default database file ($TEXMFMAIN)/texdoctk/texdoctk.dat -with a special format. It is divided into 17 sections corresponding to the -17 buttons that are active by default. Each section begins with a line - -@\fIsection_name\fP - -where -.I section_name -is the text as it appears in the button. This title is -followed by the descriptive entries for each documentation, which have this -format: - -\fIpackage-label\fP;Short description for listbox (opt. \fIpackage-name\fP);path in doc directory;optional keywords - -(without breaking the line!). Comments (initiated with a #) and empty lines -are ignored by the program. The second field is the text displayed in the -selection listboxes of \fBtexdoctk\fP, and you will usually want to mention the name -of the package in parens along with it; the first field is a \fBunique\fP label -for the package for internal use of the program which will usually be chosen -identical to the package name, but can be different if there is more than one -documentation file coming with a package. -.PP -The administrator will probably install additional packages in the local texmf -tree. The corresponding documentation can be made accessible by an additional -database $TEXMFLOCAL/texdoctk/texdoctk-local.dat. Furthermore, individual -users possibly install additional packages in an texmf subdirectory of their -$HOME, for which they can make an individual database themselves as -$TEXMFHOME/texdoctk/texdoctk-pers.dat. After creating such files, texhash -must be executed. -.PP -Both types of databases must have the same structure as the system database, -although they need (and should) not include all its sections if there are no -additional entries. For example, if the the package -.I foo -is added to the local tree such that its documentation file is -($TEXMFLOCAL)/doc/latex/foo/foo.dvi and it is decided that it fits best into -the existing category Graphics, texdoctk-local.dat would look like this: - -@Graphics -.br -foo;Create bells and whistles (foo);latex/foo/foo.dvi;decoration - -The entry for -.I foo -will then be appended to the list of entries in the Graphics category. The 18th -button can be activated in the same way, but using a new category name; -possible entries at the beginning of the database which have not been assigned -to a category will be assigned to the default Miscellaneous, making the 18th -button active with that label. Note that you cannot have more than 18 -categories; if there are more, only the one defined last will appear and be -used. -.PP -If the documentation is included in the .sty file instead of a proper -documentation file, the optional keywords should start with --?- directly after the semicolon, where ? is 0, 1, 2 or 3; these are flags -which indicate in which part of the .sty the instructions are placed and -should help \fBtexdoctk\fP to extract the documentation from the style and present -it without the code, which would normally be of little use. -.TP -0 -no specific place, scattered between the code -.TP -1 -at end, behind \\endinput; some .sty files have well-organized documentation -behind the end of the actual code, where TeX doesn't see it upon compilation -.TP -2 -at beginning, terminated by %%%%%%; in some other cases, some usage information -is at the beginning of the .sty as a comment terminated by a line full of % -.TP -3 -as 2, but with a blank line as termination -.PP -See the system database for plenty of examples. - -.SH "FILES" -.PP -\& $TEXMFMAIN/texdoctk/texdocrc.defaults -system-wide configuration file -.PP -\& ~/.texdocrc -(optional) personal configuration file; can also be created with the Settings menu -.PP -\& $TEXMFMAIN/texdoctk/texdoctk.dat -default database file for documentation files of the distribution -.PP -\& $TEXMFLOCAL/texdoctk/texdoctk-local.dat -(optional) local database file for documentation files -.PP -\& $TEXMFHOME/texdoctk/texdoctk-pers.dat -(optional) personal database file of individual users for documentation files -.SH BUGS -Widget placement in topic toplevels becomes ugly when the toplevel is stretched -or shrunk. -.PP -The font in the frame labels of the Settings menu are not forced to the default -font; this will become visible e.g. at hi-res screens, where the label font is -not scaled up. -.PP -Netscape and Mozilla error output will be written to stderr even if the quiet -mode was set. -.SH AUTHOR -.B texdoctk -was written by Thomas Ruedas . -.PP -This manual page was originally written by Adrian Bunk for -the Debian GNU/Linux system (but may be used by others). It is now maintained -by Thomas Ruedas. - -.SH COPYRIGHT -Copyright (C) 2000-2004 Thomas Ruedas -.br -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.pl b/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.pl deleted file mode 100755 index 36497183e3b..00000000000 --- a/Build/source/texk/texlive/linked_scripts/tetex/texdoctk.pl +++ /dev/null @@ -1,1857 +0,0 @@ -#! /usr/bin/env perl -############################################################################### -# texdoctk - GUI for TeX documentation access -# Copyright (C) 2000-2004 Thomas Ruedas -# Updated in 2010 by Manuel Pegourie-Gonnard -# This program is provided under the GNU Public License; see the file -# README.texdoctk for details about requirements, installation, configuration, -# and the full disclaimer. -############################################################################### -my ($version, $date) = ("0.6.1", "2004-11-05"); -use strict; -use Tk; -use Getopt::Long; -Getopt::Long::config('bundling'); -use File::Basename; - -BEGIN { - Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow; -} - -my $IsWin32 = ($^O =~ /MSWin32/i); - -if ($IsWin32) { - require Win32::API; -# Win32::API->import( qw( -# &something -# )); -} - -# initialization of some internal variables -$|=1; -my $quiet=1; -my $autoview; -my $xfmt_viewer=1, -my @tdcolors; -my %butcol; -my $srchentry; -my $srchflag=0; -my $srchtype; # 0 = database, 1 = texdoc -my $tmpfno; -# system variables -my ($texmfmain,$texmfdist,$texmfdoc,$texmflocal,$texmfhome, - $texdocpath,$distdocpath,$docdocpath,$localdocpath,$homedocpath, - $datadir, - $dvi_viewer,$dvips_conv,$ps_viewer,$pdf_viewer, - $pdfps_conv,$html_viewer,$htmlps_conv,$htmlps_redir, - $txt_viewer,$txtps_conv,$txtps_redir,$print_cmd); - -# defaults: unix values -my $qq="'"; -my $HomeEnv=$ENV{HOME}; -my $TeXDocRcDefaults="texdocrc.defaults"; -my $TempDir; $TempDir=$ENV{TMPDIR} or $TempDir="/tmp"; -my $CmdConsole="xterm -e "; - -if ($IsWin32) { - $qq = "\""; - $HomeEnv = $ENV{'USERPROFILE'}; - chomp $HomeEnv; - $TeXDocRcDefaults = "texdocrc-win32.defaults"; - $TempDir = &GetTempPath; - $CmdConsole = "cmd /c "; -} - -my $myrc="${HomeEnv}/.texdocrc"; # optional personal settings file - -my ($line,@dummy); -my @tmpfiles; -# read system-wide defaults from texdocrc.defaults -my $sysrc=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} ${TeXDocRcDefaults}`; -my $database=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk.dat`; -my $locdatabase=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk-local.dat`; -my $homedatabase=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk-pers.dat`; -chomp $locdatabase; -chomp $homedatabase; -chomp $sysrc; -&readrc($sysrc,1); -@dummy=split("/",$sysrc); -pop @dummy; -$datadir=join('/',@dummy); -# possibly use personal settings instead of defaults -if (-e $myrc) { &readrc($myrc,2); } -# command line options -GetOptions('v'=>\$quiet,'a'=>\$autoview); -my $special=0; -my @button; -$button[17]="Miscellaneous"; -my (@packname,@topic,@doc,@keywords,@maxind,%stydoc); -# read database file -my $i=-1; -my $j; -open(DATABASE,"$database") || &fatalmsg("Couldn't open database $database.\n"); -while ($line = ) { - LINETYPE: { - ($line =~ /^\@/) && do { # category - ++$i; - if ($i == $#button) { - pop @button; - push @button,(substr($line,1,-1)); - $special=1; - } else { - $button[$i]=substr($line,1,-1); - } - $j=0; - last LINETYPE; - }; - ($line =~ /^(#|$)/) && do { # comment or empty line - last LINETYPE; - }; -# list item - @dummy=split(";",$line); - $packname[$i][$j]=$dummy[0]; - $topic[$i][$j]=$dummy[1]; - $doc[$i][$j]=$dummy[2]; - $keywords[$i][$j]=$dummy[3]; - if ($doc[$i][$j] =~ /sty$/ && $keywords[$i][$j]) { - $stydoc{"$doc[$i][$j]"}=substr($keywords[$i][$j],1,1); - unless ($stydoc{"$doc[$i][$j]"} =~ /^\d$/) { - $stydoc{"$doc[$i][$j]"}=0; - } - } - $maxind[$i]=$j; - ++$j; - }; -} -close(DATABASE); -# Read site-local and user's database(s) if it/they exist(s) -foreach my $dbfile ($locdatabase,$homedatabase) { - if (-e "$dbfile") { - open(DATABASE,"$dbfile") || - print "Couldn't open additional database $dbfile.\n"; - $i=17; # local/user: if no category is specified in database, add to "Misc" - while ($line = ) { - LINETYPE: { - ($line =~ /^\@/) && do { # category - $i=&arrindex(@button,substr($line,1,-1)); - if ($i >= $#button) { - $i=$#button; - pop @button; - push @button,(substr($line,1,-1)); - $special=1; - } - last LINETYPE; - }; - ($line =~ /^(#|$)/) && do { # comment or empty line - last LINETYPE; - }; -# list item - @dummy=split(";",$line); - $j=&arrindex(@{$packname[$i]},$dummy[0]); - if ($j > $#{$packname[$i]}) { - $packname[$i][$j]=$dummy[0]; - $topic[$i][$j]=$dummy[1]; - $doc[$i][$j]=$dummy[2]; - $keywords[$i][$j]=$dummy[3]; - if ($doc[$i][$j] =~ /sty$/ && $keywords[$i][$j]) { - $stydoc{"$doc[$i][$j]"}=substr($keywords[$i][$j],1,1); - unless ($stydoc{"$doc[$i][$j]"} =~ /^\d$/) { - $stydoc{"$doc[$i][$j]"}=0; - } - } - $maxind[$i]=$j; - ++$j; - } - }; - } - close(DATABASE); - $special=1 if ($i == 17 && $j > 0); - } -} - -# Tk -# hash table for toplevel windows; used to avoid multiple calls of same window -my %tlwins; -my %buttonlist; -# create frames for main window: commands on top, frame for buttons below -my $main=new MainWindow; -$tlwins{'mainwindow'}{'addr'}=$main; -$main->resizable(0,0); -$main->title("TeX Documentation Browser"); -$main->bind('all',''=>\&clean_exit); -$main->bind('all',''=>sub { $main->raise(); }); -$main->bind('all',''=>\&helptext); -$main->bind('all',''=>sub { $main->raise(); &mksrch; }); -$main->bind('all',''=>\&settings); -my $cmdframe=$main->Frame(-background=>"#ffcc99"); -my $buttonframe=$main->Frame; -$cmdframe->pack(-side=>'top',-fill=>'x'); -$buttonframe->pack(-side=>'bottom'); -# normal cursor -my $defcursor=$main->cget(-cursor); -# make buttons for command frame -my $Qbut=$cmdframe->Button(-text=>'Quit',%butcol, - -command=>\&clean_exit)->pack(-side=>'left'); -$tlwins{'mainwindow'}{'buttons'}[0]=$Qbut; -# define common default font for labels and text explicitly -my $deffont=$Qbut->cget(-font); -# ensure readability on high-res screens (suggested by R.Kotucha) -$deffont='Helvetica -16 bold' if &x_resolution > 1200; -$Qbut->configure(-font=>$deffont); -$tlwins{'mainwindow'}{'buttons'}[1]=$cmdframe->Button( - -text=>'Database search', - -font=>$deffont,%butcol, - -command=>[\&mksrch, 0] - )->pack(-side=>'left'); -$tlwins{'mainwindow'}{'buttons'}[2]=$cmdframe->Button( - -text=>'File search', - -font=>$deffont,%butcol, - -command=>[\&mksrch, 1] - )->pack(-side=>'left'); -$tlwins{'mainwindow'}{'buttons'}[3]=$cmdframe->Button(-text=>'Help/About', - -font=>$deffont,%butcol, - -command=>\&helptext - )->pack(-side=>'right'); -$tlwins{'mainwindow'}{'buttons'}[4]=$cmdframe->Button(-text=>'Settings', - -font=>$deffont,%butcol, - -command=>\&settings - )->pack(-side=>'right'); -# make buttons for category button frame -my $lbut=0; -my $l; -foreach (@button) { $l=length $_; $lbut=$l if ( $l > $lbut) } -my @catg; -my ($i2,$i3); -my $nbutt=scalar @button; -my $ncols=$nbutt/3-1; -foreach (0..$ncols) { - $i=$_; - $i2=$i+$nbutt/3; - $i3=$i+2*$nbutt/3; - $catg[$i]=$buttonframe->Button(-text=>$button[$i], - -font=>$deffont,%butcol, - -width=>$lbut, - -command=>[\&tpslct,$i,\@dummy])->grid - ($catg[$i2]=$buttonframe->Button(-text=>$button[$i2], - -font=>$deffont,%butcol, - -width=>$lbut, - -command=>[\&tpslct,$i2,\@dummy]), - $catg[$i3]=$buttonframe->Button(-text=>$button[$i3], - -font=>$deffont,%butcol, - -width=>$lbut, - -command=>[\&tpslct,$i3,\@dummy])); -} -# disable last button (lower right) if no local specials are found in list -my $ncat; -if ($special == 0) { - $catg[$#button]->configure(-state=>'disabled'); - $ncat=$nbutt-1; -} else { - $ncat=$nbutt; -} -for ($i=0,$j=5; $i<@catg; ++$i,++$j) { - $tlwins{'mainwindow'}{'buttons'}[$j]=$catg[$i]; -} -MainLoop; - -########## SUBROUTINES ######################################################## -# toplevel for selecting a topic of a category for viewing or printing -sub tpslct { - my($opt,@srchitems)=@_; - my (@lbitems,@lbdocs,$dspselect,$docselect,$wtitle); - if ($opt >= 0) { -# main window buttons -# see if toplevel window is already there - if (Exists($tlwins{$opt}{'addr'})) { - $tlwins{$opt}{'addr'}->deiconify(); - $tlwins{$opt}{'addr'}->raise(); - return; - } - for ($j=0; $j <= $maxind[$opt]; ++$j) { - push @lbitems,$topic[$opt][$j]; - push @lbdocs,$doc[$opt][$j]; - } - $wtitle=$button[$opt]; - } else { -# search results - my $spec_wtitle=shift @srchitems; - for ($j=0; $j < $#srchitems; $j+=2) { - my $k=$j+1; - push @lbitems,$topic[$srchitems[$j]][$srchitems[$k]]; - push @lbdocs,$doc[$srchitems[$j]][$srchitems[$k]]; - } - $wtitle = ($srchtype ? "File" : "Database") - . " search results for $spec_wtitle"; - } -# toplevel window of category $opt with two frames - my $tpwin=$main->Toplevel(-title=>$wtitle); - $tlwins{$opt}{'addr'}=$tpwin; - my $tpdsp=$tpwin->Frame(-relief=>'groove')->pack(-side=>'top'); - my $tpslc=$tpwin->Frame()->pack(-side=>'top'); -# selection frame with listbox and buttons -# label for listbox - my $tplabel=$tpslc->Label(-text=>($srchtype ? "Files" : "Topics"), - -font=>$deffont)->pack(-anchor=>'w', - -side=>'top'); -# listbox with optional scrollbar - my $tplist=$tpslc->Scrolled("Listbox", - -font=>$deffont, - -scrollbars=>'osoe', -# -height=>0, - -width=>0, - -selectmode=>'single', - -exportselection=>0, - -cursor=>'hand2')->pack(-side=>'left', - -fill=>'y', - -expand=>1); - $tplist->insert('end',@lbitems); # fill topics into listbox -# buttons frame - my $tpbframe=$tpslc->Frame(-borderwidth=>8); - $tpbframe->pack(-side=>'right'); -# make buttons for command frame - my $n_buttons = 0; - $tlwins{$opt}{'buttons'}[$n_buttons++]= - $tpbframe->Button(-text=>'View', - -font=>$deffont,%butcol, - -command=>sub{ &viewslc($docselect,$tpbframe);}, - -width=>6)->pack(-side=>'top'); - if (! $IsWin32) { - $tlwins{$opt}{'buttons'}[$n_buttons++]= - $tpbframe->Button(-text=>'Print', - -font=>$deffont,%butcol, - -command=>sub{ &prtslc($docselect,$tpbframe);}, - -width=>6)->pack(-side=>'top'); - } - $tlwins{$opt}{'buttons'}[$n_buttons++]= - $tpbframe->Button(-text=>'Cancel', - -font=>$deffont,%butcol, - -command=>sub{ destroy $tpwin; undef $tlwins{$opt};}, - -width=>6)->pack(-side=>'bottom'); -# if only 1 item is in the list (most likely in search results), select it - if (scalar @lbitems == 1) { - $tplist->selectionSet(0); - $dspselect=$lbitems[0]; - $docselect=$lbdocs[0]; - &viewslc($docselect,$tpbframe) - if ($autoview && $wtitle =~ /^Search results/); - } -# display frame - my $dsplabel=$tpdsp->Label(-text=>'Selection:', - -font=>$deffont)->pack(-anchor=>'w',, - -fill=>'x', - -side=>'left'); - my $dspslc=$tpdsp->Label(-textvariable=>\$dspselect, - -font=>$deffont, - -borderwidth=>2)->pack(-anchor=>'w', - -fill=>'x', - -side=>'right'); -# handle selection; only one selection possible - $tplist->bind(''=>sub{my ($slctind)=$tplist->curselection(); - $dspselect=$lbitems[$slctind]; - $docselect=$lbdocs[$slctind];}); -# key bindings - $tplist->bind(''=>sub{ - &viewslc($docselect,$tpbframe);}); - $tpwin->bind(''=>sub{ - &viewslc($docselect,$tpbframe);}); - $tpwin->bind(''=>sub{ - &prtslc($docselect,$tpbframe);}); - $tpwin->bind(''=>sub{destroy $tpwin; undef $tlwins{$opt};}); - $tplist->bind(''=>sub{ - if ($docselect) { - &showpath($docselect,$tpbframe); - } else { - &popmsg(2,"No selection;\nuse left mouse button.",$tpbframe); - }}); -} - -# view document selected in listbox -sub viewslc { - my($slc,$parframe)=@_; - my $viewer; - my $itype=-1; - my $browser=0; - my $styflag=0; - unless (defined $slc) { - &popmsg(2,"No selection was made.",$parframe); - return; - } - $parframe->configure(-cursor=>'watch'); - chomp $slc; - my @dummy=split('\.',$slc); - DOC_FORMAT: { # determine document type - ($dummy[-1] =~ /dvi/) && do { $viewer=$dvi_viewer; last DOC_FORMAT; }; - ($dummy[-1] =~ /ps/) && do { $viewer=$ps_viewer; last DOC_FORMAT; }; - ($dummy[-1] =~ /pdf/) && do { $viewer=$pdf_viewer; last DOC_FORMAT; }; - ($dummy[-1] =~ /txt/ || $dummy[-1] =~ /faq$/) && do { - $viewer=($txt_viewer eq "TDK_OWN" || - $txt_viewer =~ /xterm/) ? - $txt_viewer : "${CmdConsole} $txt_viewer"; - last DOC_FORMAT; - }; - ($dummy[-1] =~ /README/i || $dummy[-2] =~ /\/README$/i) && do { - $viewer=($txt_viewer eq "TDK_OWN" || - $txt_viewer =~ /xterm/) ? - $txt_viewer : "${CmdConsole} $txt_viewer"; - last DOC_FORMAT; - }; - ($dummy[-1] =~ /htm/) && do { - $viewer=$html_viewer; - if ($html_viewer =~ /netscape/i) { # check if Netscape is open - my $lockfile="${HomeEnv}/.netscape/lock"; - $browser=1 if (-e $lockfile || -l $lockfile); - } elsif ($html_viewer =~ /mozilla/i) { # check if Mozilla is open - my $mozcheck= - `mozilla -remote 'openFile($texmfmain/doc/index.html)'`; - $browser=1 unless ($?); - } - last DOC_FORMAT; - }; -# some packages have no normal documentation but useful info in the .sty - ($dummy[-1] =~ /sty$/) && do { - $viewer=($txt_viewer eq "TDK_OWN" || - $txt_viewer =~ /xterm/) ? - $txt_viewer : "${CmdConsole} $txt_viewer"; - $slc="../tex/$slc"; # .sty files are in ${tex,local}docpath/../tex/ - $styflag=1; - last DOC_FORMAT; - }; - $parframe->configure(-cursor=>$defcursor); - if ($xfmt_viewer != 1) { - &popmsg(2,"$dummy[-1]: not a known document format",$parframe); - return; - } - }; - if ($viewer eq "") { - if ($xfmt_viewer == 1) { - &popmsg(-1,'Unknown format; assuming plain text.',$parframe); - $viewer=($txt_viewer eq "TDK_OWN" || - $txt_viewer =~ /xterm/) ? - $txt_viewer : "${CmdConsole} $txt_viewer"; - } else { - &popmsg(2,"$dummy[-1]: no viewer available/specified for this format", - $parframe); - $parframe->configure(-cursor=>$defcursor); - return; - } - } -# build complete path and start viewer if file exists - my $slcdoc; - $slcdoc=&finddoc($slcdoc,$slc,$parframe); - if ($slcdoc ne "") { -# change to doc directory in case there are pictures - my $docpath=substr($slcdoc,0,(rindex($slcdoc,'/',(length $slcdoc)))); - chomp $slcdoc; - chdir ($docpath); -# try to get doc out of .sty file - if ($styflag) { - &popmsg(-1,'Trying to extract documentation out of .sty file; -might be cluttered with program comments.', - $parframe); - $slcdoc=&stripsty($slcdoc,substr($slc,7)); - } -# for text files use built-in text viewer if set - if ($IsWin32) { - if ($viewer eq "TDK_OWN") { - &ShellExecute('open', $slcdoc); - $parframe->configure(-cursor=>$defcursor); - return; - } - else { - system("$viewer $slcdoc"); - } - } - else { - if ($viewer eq "TDK_OWN") { - &textview($slcdoc); - $parframe->configure(-cursor=>$defcursor); - return; - } - if ($quiet == 0) { # show messages - if ($browser == 0) { # normal viewers or new Netscape/Mozilla - system("$viewer $slcdoc &"); - } else { # open doc in existing Netscape/Mozilla window - system("$viewer -remote 'openFile($slcdoc)' &"); - &popmsg(-1,"Opening document in existing $viewer window.", - $parframe); - } - } else { # viewer messages written to /dev/null instead of terminal - if ($browser == 0) { # normal viewers or new Netscape/Mozilla - system("perl -we 'use strict; \ -my \$dump=\"\"; \ -open(NULL,\">/dev/null\"); \ -open (VIEWQ,\"$viewer $slcdoc |\"); \ -while (\$dump=) { print NULL \$dump; } \ -close(VIEWQ); \ -close(NULL);' &"); - } else { # open doc in existing window (Netscape or Mozilla) - # not quiet; I didn't get an inline perl call like in - # the other branch working - system("$viewer -remote 'openFile($slcdoc)' &"); - &popmsg(-1,"Opening document in existing $viewer window.", - $parframe); - } - } - } - } - $parframe->configure(-cursor=>$defcursor); -} - -# Tk widget for text document -sub textview { - my($txtfile)=@_; -# see if toplevel window with this file is already there - if (Exists($tlwins{$txtfile}{'addr'})) { - $tlwins{$txtfile}{'addr'}->deiconify(); - $tlwins{$txtfile}{'addr'}->raise(); - return; - } - my $tfv_tk=$main->Toplevel(-title=>"Text file viewer"); - $tfv_tk->resizable(0,1); - $tlwins{$txtfile}{'addr'}=$tfv_tk; - $tfv_tk->Label(-text=>"File: $txtfile", - -font=>$deffont, - -relief=>'ridge', - -borderwidth=>3)->pack(-side=>'top', - -fill=>'x', - -ipady=>10, - -anchor=>'s'); - my $txtbody=$tfv_tk->Scrolled("Text", - -relief=>'flat', - -font=>$deffont, - -height=>20, - -width=>80, - -scrollbars=>"e")->pack(-side=>'top', - -fill=>'y', - -expand=>1); - open(TXTFILE,"$txtfile"); - while () { $txtbody->insert('end',$_); } - close(TXTFILE); - $txtbody->configure(-state=>'disabled'); - $tlwins{$txtfile}{'buttons'}[0]= - $tfv_tk->Button(-text=>'Close', - -font=>$deffont,%butcol, - -command=>sub{ destroy $tfv_tk; - undef $tlwins{$txtfile}; - })->pack(-side=>'bottom', - -fill=>'x'); - $tfv_tk->bind(''=>sub{destroy $tfv_tk; - undef $tlwins{$txtfile}; - }); -} - -# print document selected in listbox -sub prtslc { - my($slc,$parframe)=@_; - $tmpfno=&randname; - my $pstmpfile="${TempDir}/texdoc_$tmpfno.ps"; - push @tmpfiles,$pstmpfile; - my $status; - chomp $slc; - unless (defined $slc) { - &popmsg(2,"No selection was made.",$parframe); - return; - } - if ($print_cmd eq "") { - &popmsg(2,"No printer specified.",$parframe); - return; - } -# build complete path and check existence of file - my @dummy=split('\.',$slc); - if ($dummy[-1] =~ /sty$/) { - $slc="../tex/$slc"; # .sty files are in ${tex,local,home}docpath/../tex - } - my $slcdoc; - $slcdoc=&finddoc($slcdoc,$slc,$parframe); - return if ($slcdoc eq ""); -# change to doc directory in case there are pictures - my $docpath=substr($slcdoc,0,(rindex($slcdoc,'/',(length $slcdoc)))); - chdir ($docpath); - DOC_FORMAT: { # determine document type -# convert dvi files to ps before printing - ($dummy[-1] =~ /dvi/) && do { - if ($dvips_conv eq "") { - &popmsg(2,"No converter available for dvi->ps conversion.", - $parframe); - return; - } - &popmsg(-1,"Converting dvi to ps for printing and sending file to print...",$parframe); - $status=system("$dvips_conv $slcdoc -o $pstmpfile"); - if ($status != 0) { - &popmsg(2,"Error: Conversion dvi->ps failed!",$parframe); - } - last DOC_FORMAT; - }; -# PostScript is printed directly - ($dummy[-1] =~ /ps/) && do { - &popmsg(-1,"Sending file to $print_cmd...",$parframe); - $pstmpfile=$slcdoc; - last DOC_FORMAT; - }; -# convert pdf files to ps before printing - ($dummy[-1] =~ /pdf/) && do { - if ($pdfps_conv eq "") { - &popmsg(2,"No converter available for pdf->ps conversion.", - $parframe); - return; - } - &popmsg(-1,"Converting pdf to ps for printing and sending file to print...",$parframe); - system("$pdfps_conv $slcdoc $pstmpfile"); - last DOC_FORMAT; - }; -# convert html files to ps before printing - ($dummy[-1] =~ /htm/) && do { - if ($htmlps_conv eq "") { - &popmsg(2,"No converter available for html->ps conversion.", - $parframe); - return; - } - &popmsg(-1,"Converting html to ps for printing and sending file to print...",$parframe); - my $htmlps_redir_sign=($htmlps_redir == 1) ? ">" :""; - system("$htmlps_conv $slcdoc $htmlps_redir_sign $pstmpfile"); - last DOC_FORMAT; - }; -# convert txt files to ps before printing - ($dummy[-1] =~ /txt/ || $dummy[-1] =~ /faq$/ - || $dummy[-1] =~ /README/i) && do { - if ($txtps_conv eq "") { - &popmsg(2,"No converter available for txt->ps conversion.", - $parframe); - return; - } - &popmsg(-1,"Converting txt to ps for printing and sending file to print...",$parframe); - my $txtps_redir_sign=($txtps_redir == 1) ? ">" :""; - system("$txtps_conv $slcdoc $txtps_redir_sign $pstmpfile"); - last DOC_FORMAT; - }; -# convert extracted comments from sty files to ps before printing - ($dummy[-1] =~ /sty$/) && do { - if ($txtps_conv eq "") { - &popmsg(2,"No converter available for sty(txt)->ps conversion.", - $parframe); - return; - } - &popmsg(-1,"Converting sty(txt) to ps for printing and sending file to print...",$parframe); -# try to get doc out of .sty file - &popmsg(-1,'Trying to extract documentation out of .sty file; -might be cluttered with program comments.', - $parframe); - $slcdoc=&stripsty($slcdoc,substr($slc,7)); - my $txtps_redir_sign=($txtps_redir == 1) ? ">" :""; - system("$txtps_conv $slcdoc $txtps_redir_sign $pstmpfile"); - last DOC_FORMAT; - }; - &popmsg(2,"$dummy[-1]: cannot print document format",$parframe); - return; - }; - system("$print_cmd $pstmpfile"); -} - -# test existence and search a documentation which is not in specified place -sub finddoc { - my($slcdoc,$slc,$parframe)=@_; - my ($dummy,$status); - SLCDOCFIND: foreach ($texdocpath,$distdocpath,$docdocpath) { - $slcdoc="$_/$slc"; - if (-e $slcdoc) { -# found where it should be - return $slcdoc; - } else { -# see if the documentation file is in the local doc tree... - my @srchslcdoc=($slcdoc); - if ($localdocpath) { - push @srchslcdoc,"$localdocpath/$slc"; - return $srchslcdoc[-1] if (-e $srchslcdoc[-1]); - } -# ... or the user's doc tree... - if ($homedocpath) { - push @srchslcdoc,"$homedocpath/$slc"; - return $srchslcdoc[-1] if (-e $srchslcdoc[-1]); - } -# ... otherwise proceed with searching - $status=-1; -# see if the documentation file is compressed - CMPREND: foreach my $cmprtype ("gz","bz2","zip") { - foreach (@srchslcdoc) { - $dummy="$_.$cmprtype"; - if (-e $dummy) { # yes, it is compressed - $tmpfno=&randname; - my $rawname=basename($slc,""); - $slcdoc="${TempDir}/texdoc_$tmpfno$rawname"; - push @tmpfiles,$slcdoc; - my ($dcmp,$dcmp_opt); - COMPRESS: { # determine compression type - ($cmprtype eq "gz") && do { - $dcmp="gzip"; - $dcmp_opt="-cd"; - last COMPRESS; - }; - ($cmprtype eq "bz2") && do { - $dcmp="bzip2"; - $dcmp_opt="-cd"; - last COMPRESS; - }; - ($cmprtype eq "zip") && do { - $dcmp="zip"; - $dcmp_opt="-p"; - last COMPRESS; - }; - }; -# try to decompress - $status=system("$dcmp $dcmp_opt $dummy > $slcdoc"); - if ($status != 0) { # failure - &popmsg(2, - "$dcmp: Couldn't decompress file, cancelling.", - $parframe); - $slcdoc=""; - return $slcdoc; - } -# last CMPREND; does not work, what we need is: - return $slcdoc; - } - } - } - } - } - if ($status != 0) { - $parframe->configure(-cursor=>'watch'); -# try to find it elsewhere with kpsewhich - my $rawname=basename($slc,""); - $slcdoc=($slcdoc =~ /\.sty$/) ? - `kpsewhich $rawname` : - `kpsewhich --format=${qq}TeX system documentation${qq} $rawname`; - if ($slcdoc eq "") { # nothing found; cancel - &popmsg(2,"$rawname not found, cancelling.",$parframe); - $slcdoc=""; - } - $parframe->configure(-cursor=>$defcursor); - } - return $slcdoc; -} - -# determine existence and show paths of files (Button-3) -sub showpath { - my ($docselect,$tpbframe)=@_; - my $found=0; - if ($docselect =~ /\.sty$/) { - STYPATH: foreach my $fullpath ("$texmfmain/tex/$docselect", - "$texmfdist/tex/$docselect", - "$texmflocal/tex/$docselect", - "$texmfhome/tex/$docselect") { - if (-e $fullpath) { - &popmsg(0,"Selected file:\n$fullpath",$tpbframe); - $found=1; - last STYPATH; - } - } - if (!$found) { - &popmsg(2,"Selected file:\n$docselect\ndoes not exist.",$tpbframe) } - } else { - DOCPATH: foreach my $fullpath ("$texdocpath/$docselect", - "$distdocpath/$docselect", - "$docdocpath/$docselect", - "$localdocpath/$docselect", - "$homedocpath/$docselect") { - foreach ('','.gz','.bz2','.zip') { - my $fullpathext="$fullpath$_"; - if (-e $fullpathext) { - &popmsg(0,"Selected file:\n$fullpathext",$tpbframe); - $found=1; - last DOCPATH; - } - } - } - if (!$found) { - &popmsg(2,"Selected file:\n$docselect\ndoes not exist (neither in normal form nor compressed).",$tpbframe) } - } -} - -# make or destroy search entry widget -sub mksrch { - my ($type) = @_; - if ($srchflag == 1) { - if ($type == $srchtype) { - destroy $srchentry; - $srchflag=0; - } else { - $srchtype = $type; - } - } else { - $srchtype = $type; -# get the search string - $srchentry=$cmdframe->Entry(-cursor=>'xterm', - -font=>$deffont, - -width=>20, - -takefocus=>1)->pack(-side=>'left'); - $srchentry->focus(); - $srchentry->bind(''=>[\&srchstr, $srchentry]); - $srchflag=1; -# key binding - $srchentry->bind(''=>sub{destroy $srchentry; $srchflag=0;}); - $srchentry->bind(''=>sub{destroy $srchentry; $srchflag=0;}); - } -} - -# call search routine and display results -sub srchstr { - my $string; - my @reslist; - $string=$srchentry->get(); -# search - $main->Busy(-recurse => 1); - if ($srchtype == 0) { - @reslist = &srchdb($string); - } else { - @reslist = &srchtd($string); - } - $main->Unbusy(); -# destroy entry widget and show results - destroy $srchentry; - $srchflag=0; - if (scalar @reslist == 0) { - &popmsg(0, ($srchtype == 0 ? 'Database' : 'File'). - " search for $string: no matches found.\n". - "You may want to try a ". - ($srchtype == 0 ? 'File' : 'Databse') . " search.\n\n". - "If nothing else works, CTAN offers an online search form:\n". - "http://ctan.org/search.html\n", - $cmdframe); - } else { - &tpslct(-1, $string, @reslist); - } -} - -# search using texdoc -sub srchtd { - my ($string) = @_; - my @res; - my $tdout = `texdoc -M -l $string`; - if ($?) { - &popmsg(0,"texdoc failed, sorry: $!\n". - "Please report this problem on the texlive mailing list.\n"); - return; - } else { - my $i = 0; - for my $line (split /\n/, $tdout) { - my @fields = split /\t/, $line; - $doc[$ncat][$i] = $fields[2]; - $topic[$ncat][$i] = basename($fields[2]); - $packname[$ncat][$i] = "no package name"; - push @res, ($ncat, $i++); - } - return @res; - } -} - -# search a string in @packname, @topic and @keywords -sub srchdb { - my ($string) = @_; - my (@results, @reslist); - if ($string) { - for ($i=0; $i<$ncat; ++$i) { - for ($j=0; $j<$maxind[$i]+1; ++$j) { - SRCH: { - ($topic[$i][$j] =~ /$string/i) && do { - push @results,($i,$j); - last SRCH; - }; - (defined $keywords[$i][$j]) && do { - if ($keywords[$i][$j] =~ /$string/i) { - push @results,($i,$j); - last SRCH; - } - }; - ($packname[$i][$j] =~ /$string/i) && do { - push @results,($i,$j); - last SRCH; - }; - }; - } - } - } else { # return full database - $string='all database entries'; - for ($i=0; $i<$ncat; ++$i) { - for ($j=0; $j<$maxind[$i]+1; ++$j) { push @results,($i,$j); } - } - } - unless (scalar @results == 0) { -# cancel multiple entries - my ($omit,$pack1,$pack2); - @reslist=($results[0],$results[1]); - for ($i=0; $i<$#results; $i+=2) { - $omit=0; - $pack1=$packname[$results[$i]][$results[$i+1]]; - for ($j=0; $j<$#reslist; $j+=2) { - $pack2=$packname[$reslist[$j]][$reslist[$j+1]]; - if ($pack1 eq $pack2) { $omit=1; last; } - } - if ($omit == 0) { push @reslist,($results[$i],$results[$i+1]); } - } - } - return @reslist; -} - -# extract documentation of .sty files; a flag in the @keywords array shows -# where the doc is located: -# -0-: no specific place; -1-: at end, behind \endinput; -2-: at beginning, -# terminated by %%%%%%; -3-: at beginning, terminated with blank line -sub stripsty { - my ($slcdoc,$slc)=@_; - my @stydoc; - $tmpfno=&randname; - my $tmpslcdoc="${TempDir}/texdoc_$tmpfno.txt"; - push @tmpfiles,$tmpslcdoc; - open (STY,"$slcdoc"); - LOC: { - ($stydoc{$slc} == 0) && do { # no specific place, suck in everything :-( - while ($line = ) { push @stydoc,$line if ($line =~ /^%/); } - last LOC; - }; - ($stydoc{$slc} == 1) && do { # at end, behind \endinput - while ($line = ) { - last if ($line =~ /^\s*\\endinput/ && !($line =~ /^%/)); - } - while ($line = ) { push @stydoc,$line; } - last LOC; - }; - ($stydoc{$slc} == 2) && do { # up to a certain %%%%%%%, hopefully the 1st - for (my $i=0; $i<9; ++$i) { $stydoc[$i]=; } # after the 8th line - while ($line = ) { - last if ($line =~ /^%{4,}/); - push @stydoc,$line; - } - last LOC; - }; - ($stydoc{$slc} == 3) && do { # up to 1st blank/apparently empty line - while ($line = ) { - last if ($line =~ /^\s*$/); - push @stydoc,$line; - } - last LOC; - }; - }; - close(STY); - open(TMPSTY,">$tmpslcdoc"); - foreach (@stydoc) { print TMPSTY $_; } - close(TMPSTY); - return $tmpslcdoc; -} - -# pop up a note or an error or warning message toplevel window -sub popmsg { - my($level,$msg,$parframe)=@_; - my $degree; - LEVEL: { - ($level == -1) && do { $degree="Info"; last LEVEL; }; - ($level == 0) && do { $degree="Note"; last LEVEL; }; - ($level == 1) && do { - return if ($quiet == 1); - $degree="Warning"; - last LEVEL - }; - ($level == 2) && do { $degree="Error"; last LEVEL; }; - }; - my $msgwin=$parframe->Toplevel(-title=>$degree); - my $lbl=$msgwin->Label(-text=>uc($degree), - -font=>$deffont)->pack(-side=>'top', -fill=>'x'); -# get size of message text - my @dummy=split("\n",$msg); - my $nline=scalar @dummy; - my $msgwidth=0; - my $lline; - foreach (@dummy) { - $lline=length $_; - if ($lline > $msgwidth) { $msgwidth=$lline; } - } - my $message=$msgwin->Text(-relief=>'flat', - -font=>$deffont, - -height=>$nline, - -width=>$msgwidth)->pack(-side=>'top'); - $message->insert('end',$msg); - $message->configure(-state=>'disabled'); - if ($level < 0) { # transient message window - $msgwin->after(3000,sub{destroy $msgwin}); - } else { # persistent message window - $msgwin->Button(-text=>'Close', - -font=>$deffont,%butcol, - -command=>sub{destroy $msgwin})->pack(-side=>'bottom', - -fill=>'x'); - $msgwin->bind(''=>sub{destroy $msgwin}); - } -} - -# show/change settings (don't show this to an expert :-/ ) -sub settings { - my ($homedocpath_tmp,$quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, - $dvi_viewer_tmp,$dvips_conv_tmp, - $ps_viewer_tmp,$pdf_viewer_tmp,$pdfps_conv_tmp, - $html_viewer_tmp,$htmlps_conv_tmp,$htmlps_redir_tmp, - $txt_viewer_tmp,$txtps_conv_tmp,$txtps_redir_tmp,$print_cmd_tmp)= - ($homedocpath,$quiet,$autoview,$xfmt_viewer, - $dvi_viewer,$dvips_conv,$ps_viewer, - $pdf_viewer,$pdfps_conv,$html_viewer, - $htmlps_conv,$htmlps_redir,$txt_viewer, - $txtps_conv,$txtps_redir,$print_cmd); - my @tdcolors_tmp=@tdcolors; -# see if toplevel window is already there - if (Exists($tlwins{"setmenu"}{'addr'})) { - $tlwins{"setmenu"}{'addr'}->deiconify(); - $tlwins{"setmenu"}{'addr'}->raise(); - return; - } - my $setmenu=$main->Toplevel(-title=>'Settings'); - $setmenu->resizable(0,0); - $tlwins{"setmenu"}{'addr'}=$setmenu; -# documentation path - my $datlabel; - $datlabel="Database file(s) used: teTeX"; - $datlabel.=", local database" if (-e $locdatabase); - $datlabel.=", user database" if (-e $homedatabase); - my $docframe=$setmenu->Frame(-relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -expand=>1); - my $docframestring="\nDistribution documentation root path(s):\n$texdocpath"; - $docframestring.=", $distdocpath" if (-e $distdocpath); - $docframestring.=", $docdocpath" if (length $docdocpath); - if ($localdocpath && $localdocpath ne $texdocpath) { - $docframestring.="\nLocal documentation root path: $localdocpath\n"; - } - $docframe->Label(-text=>"$docframestring", - -font=>$deffont)->pack(-side=>'top', - -anchor=>'w', - -fill=>'x', - -expand=>1); - if (defined $texmfhome && -d $texmfhome) { - $homedocpath_tmp=basename($homedocpath_tmp,""); - my $usrdocframe=$docframe->Frame(-relief=>'flat')->pack(-side=>'top', - -fill=>'x'); - my $usrdoclabel=$usrdocframe->Label(-text=>"User's documentation root path: $texmfhome/", - -font=>$deffont)->pack(-side=>'left'); - my $usrdocentry=$usrdocframe->Entry(-textvariable=>\$homedocpath_tmp, - -font=>$deffont)->pack(-side=>'left'); - } - $docframe->Label(-text=>"$datlabel.", - -font=>$deffont)->pack(-side=>'top', - -anchor=>'w', - -ipady=>2, - -fill=>'x', - -expand=>1); -# General viewer behaviour - my $genvframe=$setmenu->Frame(-label=>'General viewer behaviour', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>6, - -expand=>1); - my $genvframe1=$genvframe->Frame()->pack(-side=>'left'); - my $genvsub1=$genvframe1->Frame()->pack(-side=>'top', - -anchor=>'w', - -ipady=>3); - my $genvecbut=$genvsub1-> - Checkbutton(-variable=>\$quiet_tmp)->pack(-side=>'left', - -anchor=>'sw'); - my $genvelabel=$genvsub1->Label(-text=>'Suppress error messages', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $genvsub2=$genvframe1->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $genvscbut=$genvsub2-> - Checkbutton(-variable=>\$autoview_tmp)->pack(-side=>'left', - -anchor=>'sw'); - my $genvslabel=$genvsub2->Label(-text=>'Autostart viewer for one-item listboxes', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $genvsub3=$genvframe1->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $genvxcbut=$genvsub3-> - Checkbutton(-variable=>\$xfmt_viewer_tmp)->pack(-side=>'left', - -anchor=>'sw'); - my $genvxlabel=$genvsub3->Label(-text=>'Use text viewer for unknown file format', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); -# colours of GUI - my @tdcolors_d=@tdcolors_tmp; - $tlwins{'setmenu'}{'buttons'}[0]= - $genvframe->Button(-text=>'Change viewer colours', - -command=>sub { - @tdcolors_tmp=&popcolor($setmenu,@tdcolors_tmp); - @tdcolors_d=@tdcolors_tmp; - }, - -font=>$deffont,%butcol)->pack(-side=>'right'); -# DVI - my $dviframe=$setmenu->Frame(-label=>'DVI', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>6, - -expand=>1); - my $dvisub1=$dviframe->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $dvisub2=$dviframe->Frame()->pack(-side=>'top', - -anchor=>'w', - -ipady=>6); - my $dvivlabel=$dvisub1->Label(-text=>'Viewer command', - -anchor=>'w', - -font=>$deffont)->pack(-side=>'left'); - my $dviventry=$dvisub1->Entry(-textvariable=>\$dvi_viewer_tmp, - -font=>$deffont)->pack(-side=>'left'); - my $dviclabel=$dvisub2->Label(-text=>'DVI->PS converter command', - -anchor=>'w', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $dvilbwidth=length 'DVI->PS converter command'; - $dvivlabel->configure(-width=>1.1*$dvilbwidth); - $dviclabel->configure(-width=>1.1*$dvilbwidth); - my $dvicentry=$dvisub2->Entry(-textvariable=>\$dvips_conv_tmp, - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); -# PostScript - my $psframe=$setmenu->Frame(-label=>'PostScript', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>10, - -expand=>1); - my $psvlabel=$psframe->Label(-text=>'Viewer command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'w'); - my $psventry=$psframe->Entry(-textvariable=>\$ps_viewer_tmp, - -font=>$deffont)->pack(-side=>'left'); -# PDF - my $pdfframe=$setmenu->Frame(-label=>'PDF', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>6, - -expand=>1); - my $pdfsub1=$pdfframe->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $pdfsub2=$pdfframe->Frame()->pack(-side=>'top', - -anchor=>'w', - -ipady=>6); - my $pdfvlabel=$pdfsub1->Label(-text=>'Viewer command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'w'); - my $pdfventry=$pdfsub1->Entry(-textvariable=>\$pdf_viewer_tmp, - -font=>$deffont)->pack(-side=>'left'); - my $pdfclabel=$pdfsub2->Label(-text=>'PDF->PS converter command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $pdfcentry=$pdfsub2->Entry(-textvariable=>\$pdfps_conv_tmp, - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); -# HTML - my $htmlframe=$setmenu->Frame(-label=>'HTML', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>6, - -expand=>1); - my $htmlsub1=$htmlframe->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $htmlsub2=$htmlframe->Frame()->pack(-side=>'top', - -anchor=>'w', - -ipady=>6); - my $htmlvlabel=$htmlsub1->Label(-text=>'Viewer command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'w'); - my $htmlventry=$htmlsub1->Entry(-textvariable=>\$html_viewer_tmp, - -font=>$deffont)->pack(-side=>'left'); - my $htmlclabel=$htmlsub2->Label(-text=>'HTML->PS converter command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $htmlcentry=$htmlsub2->Entry(-textvariable=>\$htmlps_conv_tmp, - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $htmlrlabel=$htmlsub2->Label(-text=>'Output redirect needed', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $htmlrcbut=$htmlsub2-> - Checkbutton(-variable=>\$htmlps_redir_tmp)->pack(-side=>'left', - -anchor=>'sw'); -# plain text - my $txtframe=$setmenu->Frame(-label=>'Plain text', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>6, - -expand=>1); - my $txtsub1=$txtframe->Frame()->pack(-side=>'top', - -anchor=>'w'); - my $txtsub2=$txtframe->Frame()->pack(-side=>'top', - -anchor=>'w', - -ipady=>6); - my $txtvlabel=$txtsub1->Label(-text=>'Viewer command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'w'); - my $txtventry=$txtsub1->Entry(-textvariable=>\$txt_viewer_tmp, - -font=>$deffont)->pack(-side=>'left'); - my $txt_view_flag; - if ($txt_viewer_tmp eq "TDK_OWN") { - $txt_view_flag=1; - $txtventry->configure(-state=>'disabled'); - } else { - $txt_view_flag=0; - $txtventry->configure(-state=>'normal'); - } - my $txtvilabel=$txtsub1->Label(-text=>"\tUse texdoctk\'s own viewer", - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $txtvcbut=$txtsub1-> - Checkbutton(-variable=>\$txt_view_flag, - -command=>sub { - if ($txt_view_flag == 1) { - $txt_viewer_tmp="TDK_OWN"; - $txtventry->configure(-state=>'disabled'); - } else { - $txt_viewer_tmp=$txt_viewer; - $txtventry->configure(-state=>'normal'); - $txtventry->focus(); - } - })->pack(-side=>'left', - -anchor=>'sw'); - my $txtclabel=$txtsub2->Label(-text=>'Text->PS converter command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $txtcentry=$txtsub2->Entry(-textvariable=>\$txtps_conv_tmp, - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $txtrlabel=$txtsub2->Label(-text=>'Output redirect needed', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'sw'); - my $txtrcbut=$txtsub2-> - Checkbutton(-variable=>\$txtps_redir_tmp)->pack(-side=>'left', - -anchor=>'sw'); -# printer - my $prtframe=$setmenu->Frame(-label=>'Printer', - -relief=>'groove', - -borderwidth=>2)->pack(-side=>'top', - -fill=>'x', - -ipady=>10, - -expand=>1); - my $prtclabel=$prtframe->Label(-text=>'Command', - -font=>$deffont)->pack(-side=>'left', - -anchor=>'w'); - my $prtcentry=$prtframe->Entry(-textvariable=>\$print_cmd_tmp, - -font=>$deffont)->pack(-side=>'left'); -# buttons and key bindings - my $setbfr=$setmenu->Frame()->pack(-side=>'bottom'); - $tlwins{'setmenu'}{'buttons'}[1]= - $setbfr->Button(-text=>'OK', - -font=>$deffont,%butcol, - -command=>sub{ - $homedocpath="$texmfhome/$homedocpath_tmp"; - ($quiet,$autoview,$xfmt_viewer, - $dvi_viewer,$dvips_conv, - $ps_viewer,$pdf_viewer, - $pdfps_conv,$html_viewer, - $htmlps_conv,$htmlps_redir, - $txt_viewer,$txtps_conv,$txtps_redir,$print_cmd)= - ($quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, - $dvi_viewer_tmp,$dvips_conv_tmp, - $ps_viewer_tmp, - $pdf_viewer_tmp,$pdfps_conv_tmp, - $html_viewer_tmp, - $htmlps_conv_tmp,$htmlps_redir_tmp, - $txt_viewer_tmp,$txtps_conv_tmp, - $txtps_redir_tmp,$print_cmd_tmp); - @tdcolors=@tdcolors_tmp; - %butcol=('-background'=>$tdcolors[0], - '-foreground'=>$tdcolors[1], - '-activebackground'=>$tdcolors[2], - '-activeforeground'=>$tdcolors[3]); - foreach my $tlkey (keys %tlwins) { - foreach (@{$tlwins{$tlkey}{'buttons'}}) { - $_->configure(%butcol); - } - } - if ($txt_viewer eq "" && - defined $ENV{PAGER}) { - $txt_viewer=$ENV{PAGER}; - } - destroy $setmenu}, - -width=>6)->pack(-side=>'left', - -padx=>10, - -pady=>10); - $tlwins{'setmenu'}{'buttons'}[2]= - $setbfr->Button(-text=>'Save', - -font=>$deffont,%butcol, - -command=>sub{ - $setmenu->configure(-cursor=>'watch'); - &popmsg(-1,"Writing settings to $myrc",$setmenu); - my $tdcolors_tmp=join(' ',@tdcolors_tmp); - &writerc($homedocpath_tmp, - $quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, - $tdcolors_tmp, - $dvi_viewer_tmp,$dvips_conv_tmp, - $ps_viewer_tmp, - $pdf_viewer_tmp,$pdfps_conv_tmp, - $html_viewer_tmp, - $htmlps_conv_tmp,$htmlps_redir_tmp, - $txt_viewer_tmp,$txtps_conv_tmp, - $txtps_redir_tmp,$print_cmd_tmp,$setmenu); - $setmenu->configure(-cursor=>$defcursor); - })->pack(-side=>'left', - -padx=>10); - $tlwins{'setmenu'}{'buttons'}[3]= - $setbfr->Button(-text=>'Cancel', - -font=>$deffont,%butcol, - -command=>sub{destroy $setmenu; - undef $tlwins{"setmenu"}; - })->pack(-side=>'left', - -padx=>10); - $setmenu->bind(''=>sub{destroy $setmenu; - undef $tlwins{"setmenu"};}); -} - -# dialog toplevel for color settings -sub popcolor { - my ($parframe,@entryvar)=@_; -# see if toplevel window is already there - if (Exists($tlwins{'chngcol'}{'addr'})) { - $tlwins{'chngcol'}{'addr'}->deiconify(); - $tlwins{'chngcol'}{'addr'}->raise(); - return; - } - my $dlgwin=$parframe->Toplevel(-title=>'Change colours'); - $dlgwin->resizable(0,0); - $tlwins{'chngcol'}{'addr'}=$dlgwin; -# entry widgets for default/active back/foreground - $dlgwin->Label(-text=>'Enter colours as names or RGB #xxxxxx values', - -font=>$deffont)->pack(-side=>'top'); - my $dlgdef=$dlgwin->Frame()->pack(-side=>'top'); - my $dlgact=$dlgwin->Frame()->pack(-side=>'top'); - my $dlgdef1=$dlgdef->Frame()->pack(-side=>'left'); - my $dlgtfr0=$dlgdef1->Frame()->pack(-side=>'top'); - my $dlgtfr1=$dlgdef1->Frame()->pack(-side=>'top'); - my $dlgact1=$dlgact->Frame()->pack(-side=>'left'); - my $dlgtfr2=$dlgact1->Frame()->pack(-side=>'top'); - my $dlgtfr3=$dlgact1->Frame()->pack(-side=>'top'); - $dlgtfr0->Label(-text=>"Default background", - -anchor=>'w', - -width=>18, - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr0->Entry(-textvariable=>\$entryvar[0], - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr1->Label(-text=>"Default foreground", - -anchor=>'w', - -width=>18, - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr1->Entry(-textvariable=>\$entryvar[1], - -font=>$deffont)->pack(-side=>'left'); - my $deflabel=$dlgdef->Label(-text=>'Default', - -relief=>'ridge', - -width=>10, - -height=>2)->pack(-side=>'right', - -padx=>7); - $dlgtfr2->Label(-text=>"Active background", - -anchor=>'w', - -width=>18, - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr2->Entry(-textvariable=>\$entryvar[2], - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr3->Label(-text=>"Active foreground", - -anchor=>'w', - -width=>18, - -font=>$deffont)->pack(-side=>'left'); - $dlgtfr3->Entry(-textvariable=>\$entryvar[3], - -font=>$deffont)->pack(-side=>'left'); - my $actlabel=$dlgact->Label(-text=>'Active', - -background=>$entryvar[2], - -foreground=>$entryvar[3], - -relief=>'ridge', - -width=>10, - -height=>2)->pack(-side=>'right', - -padx=>7); -# buttons - my $setbfr=$dlgwin->Frame()->pack(-side=>'bottom'); - my $chngflag=0; - $tlwins{'chngcol'}{'buttons'}[0]= - $setbfr->Button(-text=>'OK', - -font=>$deffont,%butcol, - -command=>sub { - foreach (@entryvar) { # RGB form with leading # - $_="#$_" if (/^[A-Fa-f0-9]{6}$/); - } - $chngflag=1 if (&colcheck($dlgwin,@entryvar)); - }, - -width=>6)->pack(-side=>'left', - -padx=>5, - -pady=>10); - $tlwins{'chngcol'}{'buttons'}[1]= - $setbfr->Button(-text=>'Preview', - -font=>$deffont,%butcol, - -command=>sub { - foreach (@entryvar) { # RGB form with leading # - $_="#$_" if (/^[A-Fa-f0-9]{6}$/); - } - if (&colcheck($dlgwin,@entryvar)) { - $deflabel-> - configure(-background=>$entryvar[0], - -foreground=>$entryvar[1]); - $actlabel-> - configure(-background=>$entryvar[2], - -foreground=>$entryvar[3]); - } - }, - -width=>6)->pack(-side=>'left', - -padx=>5, - -pady=>10); - $tlwins{'chngcol'}{'buttons'}[2]= - $setbfr->Button(-text=>'Cancel', - -font=>$deffont,%butcol, - -command=>sub{destroy $dlgwin; - undef $tlwins{'chngcol'}; - })->pack(-side=>'right', - -padx=>5, - -pady=>10); - $dlgwin->bind(''=>sub{destroy $dlgwin; - undef $tlwins{'chngcol'}; }); - $dlgwin->waitVariable(\$chngflag); - destroy $dlgwin; - undef $tlwins{'chngcol'}; - return @entryvar; -} - -# check colours set in popcolor; relies on the existence of X11's showrgb -sub colcheck { - my ($dlgwin,@entryvar)=@_; - my $ecnt=0; - foreach (@entryvar) { # all colours defined? - last unless ($_); - ++$ecnt; - } - &popmsg(2,'Some colours undefined.',$dlgwin) if ($ecnt != 4); - my $defcol=0; - if (`which showrgb`) { # test for proper name - my @rgb=`showrgb`; - my @norgb; - foreach my $colour (@entryvar) { - if ($colour =~ /^#[A-Fa-f0-9]{6}$/ || grep /\b$colour\b/i,@rgb) { - ++$defcol; - } else { - push @norgb,$colour; - } - } - if ($defcol != 4) { - my $norgb=join("\n",@norgb); - &popmsg(2,"Some colours invalid:\n$norgb",$dlgwin); - } - } else { $defcol=4; } - return ($ecnt == 4 && $defcol == 4) ? 1 : 0; -} - -# write user's ~/.texdocrc -sub writerc { - use File::Copy qw/cp mv/; - my ($homedocpath_tmp,$quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, - $tdcolors_tmp, - $dvi_viewer_tmp,$dvips_conv_tmp, - $ps_viewer_tmp, - $pdf_viewer_tmp,$pdfps_conv_tmp, - $html_viewer_tmp, - $htmlps_conv_tmp,$htmlps_redir_tmp, - $txt_viewer_tmp,$txtps_conv_tmp, - $txtps_redir_tmp,$print_cmd_tmp,$parframe)=@_; - my $err=0; - mv $myrc,"$myrc.save" if (-e $myrc); - open(MYRC,">$myrc"); - print MYRC "# user's .texdocrc, generated by program\n -# root of user's doc directory (from \$HOMETEXMF) -# can be left empty if \$TEXMFHOME is undefined -HOMEDOCPATH=$homedocpath_tmp -# general viewer behaviour (y or yes to make active) -QUIET=$quiet_tmp -AUTOVIEW=$autoview_tmp -XFMT_VIEWER=$xfmt_viewer_tmp -# button colours: default and active back-/foreground -# names and RGB values are both allowed; use the form #xxxxxx for RGB -TDCOLORS=$tdcolors_tmp -# the following variables contain whole commands, i.e. options can be given -# DVI settings -DVI_VIEWER=$dvi_viewer_tmp -DVIPS_CONV=$dvips_conv_tmp -# PostScript handling -PS_VIEWER=$ps_viewer_tmp -# PDF handling -PDF_VIEWER=$pdf_viewer_tmp -PDFPS_CONV=$pdfps_conv_tmp -# HTML handling -HTML_VIEWER=$html_viewer_tmp -HTMLPS_CONV=$htmlps_conv_tmp -# HTMLPS_REDIR must be on, if the html->ps converter normally writes its output -# to stdout instead of a file (e.g. as html2ps) (y or yes to make active) -HTMLPS_REDIR=$htmlps_redir_tmp -# Plain text handling -# TDK_OWN is texdoctk's own text file viewer -TXT_VIEWER=$txt_viewer_tmp -TXTPS_CONV=$txtps_conv_tmp -# TXTPS_REDIR must be on, if the txt->ps converter normally writes its output -# to stdout instead of a file (e.g. as a2ps) (y or yes to make active) -TXTPS_REDIR=$txtps_redir_tmp -# printer -PRINT_CMD=$print_cmd_tmp -\n# end of config\n"; - close(MYRC); -} - -# help window (toplevel) -sub helptext { -# see if toplevel window is already there - if (Exists($tlwins{"helptext"}{'addr'})) { - $tlwins{"helptext"}{'addr'}->deiconify(); - $tlwins{"helptext"}{'addr'}->raise(); - return; - } - my $help=$main->Toplevel(-title=>'Help/About'); - $help->resizable(0,1); - $tlwins{'helptext'}{'addr'}=$help; - $help->Label(-text=>"texdoctk -TeX documentation browser -v$version ($date)", - -font=>$deffont)->pack(-side=>'top', - -ipady=>10, - -anchor=>'s'); - my $helpbody=$help->Scrolled("Text", - -relief=>'flat', - -font=>$deffont, - -height=>20, - -width=>60, - -scrollbars=>"e")->pack(-side=>'top', - -fill=>'y', - -expand=>1); - my $pos=tell DATA; - while () { - $_ =~ s/\$sysrc/$sysrc/; - last if (/^#/); - $helpbody->insert('end',$_); - } - seek(DATA,$pos,0); - $helpbody->configure(-state=>'disabled'); - $tlwins{'helptext'}{'buttons'}[0]= - $help->Button(-text=>'Close', - -font=>$deffont,%butcol, - -command=>sub{destroy $help; - undef $tlwins{"helptext"}; - })->pack(-side=>'bottom', - -fill=>'x'); - $help->bind(''=>sub{destroy $help; undef $tlwins{"helptext"};}); -} - -# read config file; personal settings override the default settings -sub readrc { - my($rcfile,$icall)=@_; - my ($var,$val); - my $pathflag=0; - my $pathflagl=0; - my $pathflagh=0; - my $tdcolors=''; -# for backward compatibility of converter/printer options - my ($dvips_opts,$pdfps_opts,$print_opts); -# read defaults resp. local/personal settings - CALL: { - ($icall == 1) && do { - open (RC,"$rcfile") || - &fatalmsg("Couldn't open system-wide default config file ${TeXDocRcDefaults}.\n"); - last CALL; - }; - ($icall == 2) && do { - open (RC,"$rcfile") || - &fatalmsg("Couldn't open personal config file ~/.texdocrc.\n"); - last CALL; - }; - }; - while ($line = ) { - next if ($line =~ /^($|#)/); - chomp $line; - ($var,$val)=split("=",$line,2); - RCVARS: { - ($var =~ /texdocpath/i) && do { # TEXDOCPATH - if (length $val > 0) { - $pathflag=1; - eval(join("",("\$",lc($var),"=\$val"))); - } - last RCVARS; - }; - ($var =~ /localdocpath/i) && do { # LOCALDOCPATH - if (length $val > 0) { - $pathflagl=1; - eval(join("",("\$",lc($var),"=\$val"))); - } - last RCVARS; - }; - ($var =~ /homedocpath/i) && do { # HOMEDOCPATH - if ($icall == 2 && length $val > 0) { # set only in ~/.texdocrc - $pathflagh=1; - eval(join("",("\$",lc($var),"=\$val"))); - } - last RCVARS; - }; - # other variables - eval(join("",("\$",lc($var),"=\$val"))); - }; - } - close(RC); -# find texmf/doc, and possibly other distribution texmf trees - if ($rcfile eq $sysrc || $pathflag == 1) { - $texmfmain=`kpsewhich --expand-path=${qq}\$TEXMFMAIN${qq}`; - chomp $texmfmain; - $texdocpath="$texmfmain/$texdocpath"; - $texmfdist=`kpsewhich --expand-path=${qq}\$TEXMFDIST${qq}`; - chomp $texmfdist; - $distdocpath=join('/',"$texmfdist",basename($texdocpath,"")) - if (length $texmfdist); - # TeXLive has this texmf-doc - $texmfdoc=join('/',"$texmfmain-doc",basename($texdocpath,"")); - if (-e $texmfdoc) { - chomp $texmfdoc; - $docdocpath="$texmfdoc/$docdocpath"; - } - } -# find texmf-local/doc, if there is one - if ($rcfile eq $sysrc || $pathflagl == 1) { - $texmflocal=`kpsewhich --expand-path=${qq}\$TEXMFLOCAL${qq}`; - chomp $texmflocal; - if (length $texmflocal) { - # if LOCALDOCPATH is not explicitly defined, it equals TEXDOCPATH - unless (defined $localdocpath) { - $localdocpath=basename($texdocpath,""); - } - $localdocpath="$texmflocal/$localdocpath"; - } - } -# find user's $HOMETEXMF/doc, if there is one - if ($icall == 2 || $pathflagh == 1) { - $texmfhome=`kpsewhich --expand-path=${qq}\$HOMETEXMF${qq}`; - chomp $texmfhome; - if (length $texmfhome) { - # if HOMEDOCPATH is not explicitly defined, it equals TEXDOCPATH - unless (defined $homedocpath) { - $homedocpath=basename($texdocpath,""); - } - $homedocpath="$texmfhome/$homedocpath"; - } - } -# colours: create array - @tdcolors=split(' ',$tdcolors); - if (scalar @tdcolors != 4) { # if old texdocrc file is used - if (!(-e $myrc) || (-e $myrc && $icall == 2)) { - print "NOTE: Button colours not set in $rcfile; using defaults.\n"; - @tdcolors=('#d9d9d9','Black','#ececec','red'); - } - } - %butcol=('-background'=>$tdcolors[0], - '-foreground'=>$tdcolors[1], - '-activebackground'=>$tdcolors[2], - '-activeforeground'=>$tdcolors[3]); -# viewer: suppress viewer warnings/use $PAGER if no $txt_viewer is defined - $quiet=($quiet =~ /y/i || $quiet eq "1") ? 1 : 0; - if (!(defined $txt_viewer) && defined $ENV{PAGER}) { - $txt_viewer=$ENV{PAGER}; - } -# viewer: autostart viewer if listbox of search results contains only 1 item - $autoview=($autoview =~ /y/i || $autoview eq "1") ? 1 : 0; -# viewer: use text viewer to open files with unrecognized format - $xfmt_viewer=($xfmt_viewer =~ /y/i || $xfmt_viewer eq "1") ? 1 : 0; -# converter: output redirection flags for HTML/Text->PS converters - $htmlps_redir=($htmlps_redir =~ /(y|1)/i) ? 1 : 0; - $txtps_redir=($txtps_redir =~ /(y|1)/i) ? 1 : 0; -# for backward compatibility of converter/printer options - $dvips_conv.=" $dvips_opts" if ($dvips_opts); - $pdfps_conv.=" $pdfps_opts" if ($pdfps_opts); - $print_cmd.=" $print_opts" if ($print_opts); -} - -# determine resolution if xwininfo is available -# slightly modified from a patch contributed by Reinhard Kotucha -sub x_resolution { - my $x_res; - if ($IsWin32) { - $x_res = &GetScreenWidth; - } - else { - open(XINF,"xwininfo -root|") or return 1200; - while () { - chop; - if (/Width:/) { ($x_res=$_)=/Width:\s+(\d+)/; last; } - } - close(XINF); - } - return $x_res; -} - -# generate a random name for temporary files -sub randname { - my $namestr; - my @chars=("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); - my $time=time; - my $maxcnt=3+substr($time,-1); - for (my $i=0; $i<=$maxcnt; $i++) { $namestr.=$chars[rand(51)] } - my @tmp=split(/./,$time/$$); - $namestr.=$tmp[1]; - until (length($namestr) > 16) { $namestr.=int(rand(1000000)) } - return $namestr; -} - -# find index of an array entry -sub arrindex { - my @array=@_; - my $item=pop @array; - my $i=0; - foreach (@array) { - last if ($_ eq $item); - ++$i; - } - return $i; -} - -# clean up and exit -sub clean_exit { - foreach (@tmpfiles) { if (-e $_) { unlink $_; } } - exit; -} - -# alternative main window, launched for fatal error messages on startup -sub fatalmsg { - my($msg)=@_; - print STDERR $msg; # also print to stderr -# create frame for main window - my $main=new MainWindow; - $main->resizable(0,0); - $main->title("TeX Documentation Browser"); - $main->bind(''=>sub { exit }); - $main->bind(''=>sub { exit }); - my $msgframe=$main->Frame(-background=>"#ffcc99"); - my $cmdframe=$main->Frame; - $msgframe->pack(-side=>'top'); - $cmdframe->pack(-side=>'bottom',-fill=>'x'); -# make buttons for command frame - my $Qbut=$cmdframe->Button(-text=>'Kill',%butcol, - -command=>sub { exit })->pack(-fill=>'x'); -# define common default font for labels and text explicitly - my @deffont=$Qbut->configure(-font); -# ensure readability on high-res screens (suggested by R.Kotucha) - $deffont='Helvetica -16 bold' if &x_resolution > 1200; - $Qbut->configure(-font=>$deffont); - $msgframe->Label(-text=>'FATAL ERROR', - -font=>$deffont)->pack(-side=>'top', -fill=>'x'); -# get size of message text - my @dummy=split("\n",$msg); - my $nline=scalar @dummy; - my $msgwidth=0; - my $lline; - foreach (@dummy) { - $lline=length $_; - if ($lline > $msgwidth) { $msgwidth=$lline; } - } - my $message=$msgframe->Text(-relief=>'flat', - -font=>$deffont, - -height=>$nline, - -width=>$msgwidth)->pack(-side=>'top'); - $message->insert('end',$msg); - $message->configure(-state=>'disabled'); - MainLoop; -} - -if ($IsWin32) { - sub GetScreenWidth { - my $GetDeviceCaps = new Win32::API('gdi32', 'GetDeviceCaps', 'NN', 'N'); - my $HORZRES = 8; # from WinGDI.h - if(not defined $GetDeviceCaps) { - die "Can't import API GetDeviceCaps: $!\n"; - } - return $GetDeviceCaps->Call(0, $HORZRES); - } - - sub GetTempPath { - my $GetTempPath = new Win32::API('kernel32', 'GetTempPath', 'NP', 'N'); - if(not defined $GetTempPath) { - die "Can't import API GetTempPath: $!\n"; - } - my $lpBuffer = " " x 260; - - $GetTempPath->Call(80, $lpBuffer); - } - - sub ShellExecute { - my ($command, $file) = @_; - my $ShellExecute = new Win32::API('shell32', 'ShellExecute', 'NPPPPN', 'N'); - if(not defined $ShellExecute) { - die "Can't import API ShellExecute: $!\n"; - } - $ShellExecute->Call(0, $command, $file, '', '', 0); - } - - sub GetHomeDir { - my $home = $ENV{'HOME'}; - # Should check for CSIDL_... - return $home; - } -} -__END__ -Many TeX programmers provide more or less detailed manuals for -their programs or packages. They are usually available as .dvi, -.ps, .pdf, .html or plain text files (sometimes included in the -.sty files instead of a separate documentation file) and can be -accessed with this browser, which is simply an interface to find a -documentation more easily. It starts the respective viewer for -reading the selected documentation making use of a database file -which contains the path entries according to the current teTeX -texmf/doc structure; additional usage of a system-wide local and -of individual user texmf trees with corresponding databases is also -possible. -The documentations are grouped in several categories shown in the -main window; pressing one of its buttons lists all documentations -belonging to this topic. -The topic window lets you select one documentation file, view or -send it to the default printer. By right-clicking on the selected -item you get the complete path of the file. -The search button of the main window allows you to search the -database for a string; it does not search file names. Enter the -string and hit to start the search or to -cancel. Just hitting without typing something in will -show the full list of files in the database. -Defaults for the documentation root directory, the viewers, the -converters, certain options and the printer are set in the global -configuration file $sysrc. -However, each user can put a copy of it as .texdocrc into his home -directory to modify them according to his needs; modification or -generation of ~/.texdocrc can also be done with the Settings menu. -Additionally, the settings can be changed temporarily with this -menu. - -The following key shortcuts are defined for use with the browser: - Quit browser - Raise the Main window to the foreground - Search a keyword in database (case insensitive) - Cancel/close subwindow or search entry widget - View selected document (topic windows) - Print selected document (topic windows) - Open settings menu - Kill fatal error message window (same as - ) - Open this help - Equivalent to button press; - OK in selection menu and search - Next/previous widget - -There are the following command line options: - -a autostart viewer if a listbox of search results - contains only one item; can also be set in a - configuration file - -v disable suppression of viewer messages sent to - stderr and of certain permanent message popup - windows, in case this was not set in a - configuration file; default: off - -Some more information is available in the manpage of texdoctk. - -Comments and suggestions to: -Thomas Ruedas -tr@dlc.ku.dk or tex-k@tug.org -# Local Variables: -# mode: perl -# auto-fill-hook: do-auto-fill -# End: -# vim: ts=8 sw=4 noexpandtab diff --git a/Build/source/utils/README b/Build/source/utils/README index ba54521caa8..c0e2fed293a 100644 --- a/Build/source/utils/README +++ b/Build/source/utils/README @@ -28,6 +28,9 @@ psutils p17 - checked 10may12 t1utils 1.37 - checked 10may12 http://www.lcdf.org/type/ +texdoctk - reluctantly maintained here in TL + If anyone would like to resume development, just let us know. + tpic2pdftex 1.97 - checked 10may12 http://mirror.ctan.org/graphics/tpic2pdftex/ diff --git a/Build/source/utils/texdoctk/README.texdoctk b/Build/source/utils/texdoctk/README.texdoctk new file mode 100644 index 00000000000..54217cb61ce --- /dev/null +++ b/Build/source/utils/texdoctk/README.texdoctk @@ -0,0 +1,298 @@ + texdoctk v.0.5.3 + +texdoctk is a Perl/Tk-based frontend for easy access of package documentation +for the TeX typesetting system on Unix platforms. It includes the following +files: + + texdoctk - the program source + texdoctk.dat - the database containing the information about the + accessible documentation files for teTeX-texmf + texdocrc.defaults - the system-wide default specification for viewer + and printer settings + texdoctk.1 - manpage + README.texdoctk - this file +The current version is 0.6.0. + +REQUIREMENTS +The program is written in Perl/Tk; it requires Perl 5 and Perl/Tk 8.x. It is +known to run with Perl 5.004_04 or higher and PerlTk 800.015. +The database file texdoctk.dat is made for the teTeX distribution. +Note that the program is *not* a viewer, but an interface to access a document +with the appropriate viewer. Thus, you need to have appropriate viewers for +the different formats to actually read the files. Documentations are available +as .dvi, .ps, .pdf, .html or plain text; some packages are only documented in +the .sty files. For plain text files (.txt, .sty etc.), texdoctk's own text +viewer can be used (default). If a document format is not known, texdoctk +will by default assume that it is plain text and use the text file viewer; +this behaviour can be switched off in the Settings menu. +If you want to print the documentations, you will need converters to turn +non-PS files into PostScript. Here are some suggestions: +dvi->ps: dvips (is part of teTeX) + http://www.radicaleye.com/dvips.html +pdf->ps: pdf2ps + http://www.cs.wisc.edu/~ghost + Acrobat Reader + http://www.adobe.com +html->ps: html2ps + http://user.it.uu.se/~jan/html2ps.html +plain text->ps: a2ps + http://www-inf.enst.fr/~demaille/a2ps/ +To increase the font size automatically for high-resolution screen, the program +xwininfo is used; texdoctk will work without as well, though. + +INSTALLATION +The program texdoctk can be copied into any directory where programs are stored +on your system, e.g. into /usr/local/bin or, probably more adequate, into +/usr/local/teTeX/bin. It assumes that you have the env command in /usr/bin/ +available to determine the location of the Perl executable; therefore, you may +need to change the first line of the code if this is not the case for your +system or if for some reason your Perl executable is not called "perl"; you +will also have to change the perl call in the sub viewslc as well. +The database file texdoctk.dat and the configuration file texdocrc.defaults +must then be put into a subdirectory of the main texmf directory called +texdoctk. If you want to include information for your local system, +generate a file texdoctk-local.dat. Make sure to run texhash after +installation. See the manpage for more info. +Set the defaults in texdocrc.defaults according to your system; you can +replace the settings which are specified in the shipped file, but do not +uncomment variables for items which are not available or applicable for you, +but just leave the value empty by specifying nothing. +The individual users can define their own preferences by copying the system +texdocrc.defaults to ~/.texdocrc and assign new values to the items to be +changed. They can also establish an additional personal database for packages +they might have installed in their respective $HOME; this database must be +called texdoctk-pers.dat and reside in $HOMETEXMF/texdoctk/. +If you meet the requirements concerning the teTeX distribution, I assume that +the texdoctk.dat file should work without failures; if you have another +distribution or if your texmf/doc tree is somehow modified, it may happen that +a file is not found in spite of the program trying to find it elsewhere. You +will have to edit the file then, but make sure to keep the right format for +the entries: +;Short description for listbox (opt. );path in doc directory;optional keywords +(without breaking the line!). If the documentation is included in the .sty file +instead of a proper documentation file, the optional keywords should start with +-?- directly after the semicolon, where ? is 0, 1, 2 or 3; these are flags +which indicate in which part of the .sty the instructions are placed. See the +database file and/or the manpage for more details if necessary. +The documentation is grouped into 17 categories; the 18th button of the main +panel is inactive by default. If you have special documents which do not fit +into any of the categories, you can create a block with a new name in +texdoctk-local.dat or texdoctk-pers.dat with the respective entries. +In the settings window you see a checkbox in the html->ps and text->ps +converter menus for switching on/off output redirect. This is due to the fact +that some converters do not write their output into a file but to stdout by +default, so a redirect is needed, e.g. +a2ps myfile.txt >myfile.ps + +DISCLAIMER +texdoctk v.0.6.0 (Sep 23, 2004) - GUI for TeX documentation access +Copyright (C) 2000-2004 Thomas Ruedas +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +ACKNOWLEDGEMENTS +Thomas Esser included the program in the teTeX distribution of TeX and Friends. +He provided me with informations about changes in the texmf tree and made a +number of very useful suggestions. He also has coordinated and kept track of +several additions from other contributors, who fixed bugs and added extensions +e.g. for use under Win32 systems. +Reinhard Kotucha and Andreas Werner made very valuable comments and suggestions +to enhance v.0.3.0, especially about the special treatment of Netscape. +Reinhard Kotucha also made many useful suggestions and provided patches for +v.0.4.0; unfortunately, I could not implement all these ideas yet. +Hans Fredrik Nordhaug made some suggestions, e.g. concerning local and +personal texmf trees, and reported several bugs in different releases; he also +contributed fixes/patches. +Adrian Bunk also has reported a bug and contributed a small manpage for the +program. He made a Debian GNU/Linux package of texdoctk. +Michael Sanders reminded me to set the permissions right in the tarball. +As this is my first application written in PerlTk, it happened that I could +not solve every problem with my book and the other documentation, but had to +ask for help on comp.lang.perl.tk. Paul R. Andersen and Stephen O. Lidie have +given helpful replies and examples for me to try out. +Fabrice Popineau, and possibly others who I don't know, have provided +portability to Win32 platforms for use with fpTeX. Staszek Wawrykiewicz helped +making it ready for use with new TeXLive editions. +Paul Szabo pointed out a potential security risk related to the way names of +temporary files are generated. + +TO DO LIST +Unfortunately, I didn't have time to implement all suggestions made by the +aforementioned people; I hope that I can do that at some later time: +- widget placement in topic toplevels becomes ugly when the toplevel is + stretched or shrunk; should be made more elegant +- raise existing texdoctk window instead of possibly running texdoctk twice; + (this seems to be difficult, because it requires interprocess communication + which is kind of unsafe and requires the use of perl -T) +Possible further long-term enhancements: +- maybe use Williams Catalogue for automatically building database during + installation +- refined printing facility + +BUGS +Netscape error output will be written to stderr even if the quiet mode was set, +because I didn't manage to start it with the "inline" perl script. +Widget placement in topic toplevels becomes ugly when the toplevel is stretched +or shrunk. +The font in the frame labels of the Settings menu are not forced to the default +font; this will become visible e.g. at hi-res screens, where the label font is +not scaled up. +Please let me know if you find bugs or have suggestions for improvements. + +HISTORY/CHANGES +v.0.6.0 Sep 23, 2004 + - Unknown document formats will be opened as plain text with the text + file viewer by default; the Settings menu was given a new button to + toggle this behaviour. + - Allow for texmf-dist and texmf-doc trees for compliance with teTeX 3 + and TeXLive. + - Made an attempt to allow for additional personal user's databases to + be located in $HOMETEXMF, following a long-standing suggestion of + H.F.Nordhaug. Additional local and personal databases do not need + to be copies of the system database; instead their contents will be + appended to the entries of the default list. + - Fixed a bug with the handling of the local texmf tree reported by + Sebastian Luque. + - Updated this README and the manpage. +v.0.5.2 May 20, 2004 + - Changed the name generation of temporary files to something random + in order to address a potential security risk pointed out by Paul + Szabo. + - Replaced -q option for enabling "quiet" behaviour by -v option for + enabling "verbose" behaviour; quiet behaviour is now the default and + was extended to suppress the popup of Warning windows (popmsg level + 1). + - Added a possibility to have the Settings menu write the user's + ~/.texdocrc (older suggestion by R.Kotucha). NB: It is not intended + to write the system-wide texdocrc.defaults, because it does not set + $TEXDOCPATH and $LOCALDOCPATH. + - Button colours are made configurable through the texdocrc files or + the Settings menu. This is intended to fix a problem H.F.Nordhaug + reported with users of newer versions of the KDE, where some button + colours suddenly where messed up. - Validity of entered colours + is checked if X11's showrgb program is available. + - DVIPS_OPTS, PDFPS_OPTS and PRINT_OPTS in texdocrc.defaults are now + obsolete, but still supported. It seemed more reasonable to treat + the contents of DVIPS_CONV, PDFPS_CONV and PRINT_CMD as command lines + (which actually would have already been possible all the time). The + same is true for the viewer variables. + - Command line options can now be grouped (i.e. -av instead of -a -v). + - Cursor changes from arrow to watch in some tasks, to indicate a + process which takes a bit of time. + - fixed some glitches in databases: semicolons at the end of the + pdfTeX-related entries; corrected description of ltxtable (hint by + Rolf Niepraschk) and changed its position; corrected description of + AMSguide (AMS TeX instead of AMS LaTeX) (hint by H.F.Nordhaug) + - several additions by other contributors, for instance support for + Win32 systems +v.0.5.1 April 21, 2001 + - Enhanced right-button search function so that compressed doc files + are also found. + - Fixed a bug in the documentation finding subroutine reported by H.F. + Nordhaug: the compression determination block in sub finddoc was + broken. + - Improved treatment of entering an empty string in the search: + this is now explicitly treated as demand for display of the whole + database, instead of search for a null string. + - Automatic selection of list item in listbox if it contains only one + element; this will frequently happen in search results. In this + context, the autoview flag (option -a) has been introduced in the + texdocrc.defaults and the Settings menu: if it is chosen, the + appropriate viewer will be started automatically in the case of + one-item listboxes. + - Made , , and definitions active in + all widgets; thus, you don't need to type in the main window + to quit, for example. Introduced new global key binding for raising + the main window (). + - Fixed a braindead typo in the texdoc-*.dat files (too dumb to tell). + - Some small changes/updates in the Help text; the button and window + are now named "Help/About". + - Added an emacs perl-mode directive at the end, mostly for my + convenience. +v.0.5.0a April 19, 2001 + - Fixed bug in texdoc-102.dat reported by H.F.Nordhaug: correct path + for multirow is latex/multirow/multirow.sty (instead of + latex/misc/multirow.sty, as in texdoc-100.dat) +v.0.5.0 April 18, 2001 + - For some packages, the only documentation is included in the .sty + file itself. This documentation is now made accessible by extracting + the comments/instructions, writing them into a temporary text file + and calling the text file viewer on it. Thus 38 additional + documentation files are made accessible now. + - implementation of a suggestion by Hans Fredrik Nordhaug: contents of + the local texmf tree ($TEXMFLOCAL) can be included now. Arbitrary + inclusion of additional private texmf trees is not yet possible, + though. + - Two fixes/improvements in the databases by R.Kotucha were made + (concerning epslatex and the MetaPost tutorial) + - R.Kotucha suggested the use of the program xwininfo to determine + screen resolution and switch to a larger font size at hi-res screens. + He provided a patch for this, which I added after a slight + adaptation. + - auto-determination of Perl's path (stolen from some script by Thomas + Esser, IIRC) + - If a beta release of teTeX is used, the teTeX-1.0.2 database will be + used as a default instead of the 1.0.0 database + - introduced new message type with transient windows + - fatal error messages if essential config/database files are not found + - some syntax cosmetics +v.0.4.0 June 11, 2000 + - implementation of several suggestions by Reinhard Kotucha and + Andreas Werner: + * More than 1 document can now be viewed at one time, because the + viewers now run as background processes. They are not killed when + texdoctk itself is quit. + If Netscape is your browser, HTML documents are now loaded into + an existing Netscape window; no new Netscape will be started. This + is to be a bit economic with system resources. + * The Search button resp. now switches on/off the search + entry widget; this is to avoid that multiple entry widgets come up, + because that doesn't make much sense. + * If no TXT_VIEWER is defined, the environment variable $PAGER will + be used, if defined (but see below). + - bugs/fixes and suggestions reported by Hans Fredrik Nordhaug: + * $j for loop in sub srchstr was too short: + $j<$maxind[$i] --> $j<$maxind[$i]+1 + * misplaced last SRCH in keywords branch of sub srchstr: last SRCH + had to be put into inner if block + * added support of zip compression format + - bug/fix reported by Adrian Bunk: + * ambiguous use of redirection flag/sign hor html and text->ps + conversion + - own text viewer for plain text documentation files; this is now the + default in the original texdocrc.defaults + - kpsewhich instead of find is used for rescue file search + - temporary files generated when printing or possibly decompressing (as + in Debian) now get different names to prevent overwriting files which + are still in use + - main, settings, and help windows made non-resizable + - suppressed availability of listbox selection to X selection + - document selection toplevel windows will be raised now instead of + being opened twice or more times if they are already open + - uniform font for all text-containing widgets explicitly set; I had + some weird font configuration when running texdoctk under a CDE + - environment +v.0.3.0 March 11, 2000 + - first full public release + - implementation of some suggestions by Thomas Esser: + use of kpsewhich, changes in directory and database configuration + implemented cd to file directory to ensure rendering of graphics + made viewer message output suppression really quiet + better layout of help window +v.0.2 March 7, 2000 + - first public release (preliminary) +v.0.1 - private trial version, does not exist anymore + +AUTHOR +Thomas Ruedas +tr@geol.ku.dk +http://www.geophysik.uni-frankfurt.de/~ruedas/progs.html diff --git a/Build/source/utils/texdoctk/texdoctk.1 b/Build/source/utils/texdoctk/texdoctk.1 new file mode 100644 index 00000000000..e7aebb7098a --- /dev/null +++ b/Build/source/utils/texdoctk/texdoctk.1 @@ -0,0 +1,217 @@ +.TH TEXDOCTK 1 +.SH NAME +texdoctk \- GUI for easier access of TeX package and program documentations +.SH SYNOPSIS +.B texdoctk +-[aq] +.SH "DESCRIPTION" +.B texdoctk +is a GUI for easier access to a large part of the vast amount +of package and program documentations and tutorials for TeX and its +different derivatives (mainly LaTeX). It is optimized and included in +the teTeX and fpTeX distributions and also available with TeXLive. +.PP +The documentation is grouped into 17 categories; the 18th button of the main +panel is inactive by default and intended for use with local additions (see +section +.B CONFIGURATION +below). +.PP +In the settings window you see a checkbox in the html->ps and text->ps +converter menus for switching on/off output redirect. This is due to the fact +that some converters do not write their output into a file but to stdout by +default, so a redirect is needed, e.g. +.PP +a2ps myfile.txt >myfile.ps +.SH "OPTIONS" +.TP +.I "\-v" +verbose: enable some viewer messages which are otherwise sent to stderr, +as well as some warning popup windows. This can also be set in a +configuration file. +.TP +.I "\-a" +autoview: autostart viewer if a listbox contains only one item (this will +frequently happen in search results). This can also be set in a configuration +file. +.SH "CONFIGURATION" +.PP +The configuration is controlled by the system default configuration file +($TEXMFMAIN)/texdoctk/texdocrc.defaults, most of whose entries can though be +overridden by the users' own optional ~/.texdocrc files and/or command line +options. +.SS The Settings menu and configuration files +.PP +The Settings menu is used to change the user-definable settings of \fBtexdoctk\fP +for the duration of the program call or as new defaults. The latter case is +the purpose of the Save button, which generates or rewrites the user's own +~/.texdocrc file. The system defaults cannot be edited with the Settings +menu. +.TP +Paths +The TEXMF-type paths on the system are reported, and the user can specify the +name of the subdirectory of $HOMETEXMF, where the personal documentation is +stored. +.TP +General viewer behaviour + +.I Suppress error messages +toggle verbose mode (see option -v); default is off. + +.I Autostart viewer for one-item listboxes +if a listbox contains only one item (see option -a) + +.I Use text viewer for unknown file format +i.e. treat the file as plain text. \fBtexdoctk\fP should recognize the usual file +formats and also relate names like README to plain text, but some docs may have +freely invented names. Default is on; if switched off, trying to view such +files will raise an error. The switch does not influence printing: unrecognized +formats cannot be printed. + +.I Change viewer colours +using either RGB triplets in the format #rrggbb or the standardized names. +.TP +DVI/PostScript/PDF/HTML/Plain text +For text files, \fBtexdoctk\fP provides an own viewer. If this viewer is disabled, +but no alternative viewer is specified, \fBtexdoctk\fP tries to read the content +of the environment variable $PAGER. + +If you want to print the documentations, you will need converters to turn +non-PS files into PostScript. Here are some suggestions: + +\& dvi->ps: +dvips (is part of teTeX) (http://www.radicaleye.com/dvips.html) + +\& pdf->ps: +pdf2ps (http://www.cs.wisc.edu/~ghost) or +Acrobat Reader (http://www.adobe.com) + +\& html->ps: html2ps (http://user.it.uu.se/~jan/html2ps.html) + +\& plain text->ps: a2ps (http://www-inf.enst.fr/~demaille/a2ps/) + +The html->ps and text->ps converter menus for switching on/off output redirect. +This is due to the fact that some converters do not write their output into a +file but to stdout by default, so a redirect is needed, e.g. +.B a2ps myfile.txt >myfile.ps +.PP +The system-wide configuration file is ($TEXMFMAIN)/texdoctk/texdocrc.defaults +and should only be writable by the administrator of the installation using any +text editor. The optional user configuration file is ~/.texdocrc and can +override all but those system settings which affect the installation as a +whole. The preferred way of changing it is through the Settings menu. +.SS The databases +\fBtexdoctk\fP comes with a default database file ($TEXMFMAIN)/texdoctk/texdoctk.dat +with a special format. It is divided into 17 sections corresponding to the +17 buttons that are active by default. Each section begins with a line + +@\fIsection_name\fP + +where +.I section_name +is the text as it appears in the button. This title is +followed by the descriptive entries for each documentation, which have this +format: + +\fIpackage-label\fP;Short description for listbox (opt. \fIpackage-name\fP);path in doc directory;optional keywords + +(without breaking the line!). Comments (initiated with a #) and empty lines +are ignored by the program. The second field is the text displayed in the +selection listboxes of \fBtexdoctk\fP, and you will usually want to mention the name +of the package in parens along with it; the first field is a \fBunique\fP label +for the package for internal use of the program which will usually be chosen +identical to the package name, but can be different if there is more than one +documentation file coming with a package. +.PP +The administrator will probably install additional packages in the local texmf +tree. The corresponding documentation can be made accessible by an additional +database $TEXMFLOCAL/texdoctk/texdoctk-local.dat. Furthermore, individual +users possibly install additional packages in an texmf subdirectory of their +$HOME, for which they can make an individual database themselves as +$TEXMFHOME/texdoctk/texdoctk-pers.dat. After creating such files, texhash +must be executed. +.PP +Both types of databases must have the same structure as the system database, +although they need (and should) not include all its sections if there are no +additional entries. For example, if the the package +.I foo +is added to the local tree such that its documentation file is +($TEXMFLOCAL)/doc/latex/foo/foo.dvi and it is decided that it fits best into +the existing category Graphics, texdoctk-local.dat would look like this: + +@Graphics +.br +foo;Create bells and whistles (foo);latex/foo/foo.dvi;decoration + +The entry for +.I foo +will then be appended to the list of entries in the Graphics category. The 18th +button can be activated in the same way, but using a new category name; +possible entries at the beginning of the database which have not been assigned +to a category will be assigned to the default Miscellaneous, making the 18th +button active with that label. Note that you cannot have more than 18 +categories; if there are more, only the one defined last will appear and be +used. +.PP +If the documentation is included in the .sty file instead of a proper +documentation file, the optional keywords should start with +-?- directly after the semicolon, where ? is 0, 1, 2 or 3; these are flags +which indicate in which part of the .sty the instructions are placed and +should help \fBtexdoctk\fP to extract the documentation from the style and present +it without the code, which would normally be of little use. +.TP +0 +no specific place, scattered between the code +.TP +1 +at end, behind \\endinput; some .sty files have well-organized documentation +behind the end of the actual code, where TeX doesn't see it upon compilation +.TP +2 +at beginning, terminated by %%%%%%; in some other cases, some usage information +is at the beginning of the .sty as a comment terminated by a line full of % +.TP +3 +as 2, but with a blank line as termination +.PP +See the system database for plenty of examples. + +.SH "FILES" +.PP +\& $TEXMFMAIN/texdoctk/texdocrc.defaults +system-wide configuration file +.PP +\& ~/.texdocrc +(optional) personal configuration file; can also be created with the Settings menu +.PP +\& $TEXMFMAIN/texdoctk/texdoctk.dat +default database file for documentation files of the distribution +.PP +\& $TEXMFLOCAL/texdoctk/texdoctk-local.dat +(optional) local database file for documentation files +.PP +\& $TEXMFHOME/texdoctk/texdoctk-pers.dat +(optional) personal database file of individual users for documentation files +.SH BUGS +Widget placement in topic toplevels becomes ugly when the toplevel is stretched +or shrunk. +.PP +The font in the frame labels of the Settings menu are not forced to the default +font; this will become visible e.g. at hi-res screens, where the label font is +not scaled up. +.PP +Netscape and Mozilla error output will be written to stderr even if the quiet +mode was set. +.SH AUTHOR +.B texdoctk +was written by Thomas Ruedas . +.PP +This manual page was originally written by Adrian Bunk for +the Debian GNU/Linux system (but may be used by others). It is now maintained +by Thomas Ruedas. + +.SH COPYRIGHT +Copyright (C) 2000-2004 Thomas Ruedas +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/Build/source/utils/texdoctk/texdoctk.pl b/Build/source/utils/texdoctk/texdoctk.pl new file mode 100755 index 00000000000..36497183e3b --- /dev/null +++ b/Build/source/utils/texdoctk/texdoctk.pl @@ -0,0 +1,1857 @@ +#! /usr/bin/env perl +############################################################################### +# texdoctk - GUI for TeX documentation access +# Copyright (C) 2000-2004 Thomas Ruedas +# Updated in 2010 by Manuel Pegourie-Gonnard +# This program is provided under the GNU Public License; see the file +# README.texdoctk for details about requirements, installation, configuration, +# and the full disclaimer. +############################################################################### +my ($version, $date) = ("0.6.1", "2004-11-05"); +use strict; +use Tk; +use Getopt::Long; +Getopt::Long::config('bundling'); +use File::Basename; + +BEGIN { + Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow; +} + +my $IsWin32 = ($^O =~ /MSWin32/i); + +if ($IsWin32) { + require Win32::API; +# Win32::API->import( qw( +# &something +# )); +} + +# initialization of some internal variables +$|=1; +my $quiet=1; +my $autoview; +my $xfmt_viewer=1, +my @tdcolors; +my %butcol; +my $srchentry; +my $srchflag=0; +my $srchtype; # 0 = database, 1 = texdoc +my $tmpfno; +# system variables +my ($texmfmain,$texmfdist,$texmfdoc,$texmflocal,$texmfhome, + $texdocpath,$distdocpath,$docdocpath,$localdocpath,$homedocpath, + $datadir, + $dvi_viewer,$dvips_conv,$ps_viewer,$pdf_viewer, + $pdfps_conv,$html_viewer,$htmlps_conv,$htmlps_redir, + $txt_viewer,$txtps_conv,$txtps_redir,$print_cmd); + +# defaults: unix values +my $qq="'"; +my $HomeEnv=$ENV{HOME}; +my $TeXDocRcDefaults="texdocrc.defaults"; +my $TempDir; $TempDir=$ENV{TMPDIR} or $TempDir="/tmp"; +my $CmdConsole="xterm -e "; + +if ($IsWin32) { + $qq = "\""; + $HomeEnv = $ENV{'USERPROFILE'}; + chomp $HomeEnv; + $TeXDocRcDefaults = "texdocrc-win32.defaults"; + $TempDir = &GetTempPath; + $CmdConsole = "cmd /c "; +} + +my $myrc="${HomeEnv}/.texdocrc"; # optional personal settings file + +my ($line,@dummy); +my @tmpfiles; +# read system-wide defaults from texdocrc.defaults +my $sysrc=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} ${TeXDocRcDefaults}`; +my $database=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk.dat`; +my $locdatabase=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk-local.dat`; +my $homedatabase=`kpsewhich --progname=texdoctk --format=${qq}other text files${qq} texdoctk-pers.dat`; +chomp $locdatabase; +chomp $homedatabase; +chomp $sysrc; +&readrc($sysrc,1); +@dummy=split("/",$sysrc); +pop @dummy; +$datadir=join('/',@dummy); +# possibly use personal settings instead of defaults +if (-e $myrc) { &readrc($myrc,2); } +# command line options +GetOptions('v'=>\$quiet,'a'=>\$autoview); +my $special=0; +my @button; +$button[17]="Miscellaneous"; +my (@packname,@topic,@doc,@keywords,@maxind,%stydoc); +# read database file +my $i=-1; +my $j; +open(DATABASE,"$database") || &fatalmsg("Couldn't open database $database.\n"); +while ($line = ) { + LINETYPE: { + ($line =~ /^\@/) && do { # category + ++$i; + if ($i == $#button) { + pop @button; + push @button,(substr($line,1,-1)); + $special=1; + } else { + $button[$i]=substr($line,1,-1); + } + $j=0; + last LINETYPE; + }; + ($line =~ /^(#|$)/) && do { # comment or empty line + last LINETYPE; + }; +# list item + @dummy=split(";",$line); + $packname[$i][$j]=$dummy[0]; + $topic[$i][$j]=$dummy[1]; + $doc[$i][$j]=$dummy[2]; + $keywords[$i][$j]=$dummy[3]; + if ($doc[$i][$j] =~ /sty$/ && $keywords[$i][$j]) { + $stydoc{"$doc[$i][$j]"}=substr($keywords[$i][$j],1,1); + unless ($stydoc{"$doc[$i][$j]"} =~ /^\d$/) { + $stydoc{"$doc[$i][$j]"}=0; + } + } + $maxind[$i]=$j; + ++$j; + }; +} +close(DATABASE); +# Read site-local and user's database(s) if it/they exist(s) +foreach my $dbfile ($locdatabase,$homedatabase) { + if (-e "$dbfile") { + open(DATABASE,"$dbfile") || + print "Couldn't open additional database $dbfile.\n"; + $i=17; # local/user: if no category is specified in database, add to "Misc" + while ($line = ) { + LINETYPE: { + ($line =~ /^\@/) && do { # category + $i=&arrindex(@button,substr($line,1,-1)); + if ($i >= $#button) { + $i=$#button; + pop @button; + push @button,(substr($line,1,-1)); + $special=1; + } + last LINETYPE; + }; + ($line =~ /^(#|$)/) && do { # comment or empty line + last LINETYPE; + }; +# list item + @dummy=split(";",$line); + $j=&arrindex(@{$packname[$i]},$dummy[0]); + if ($j > $#{$packname[$i]}) { + $packname[$i][$j]=$dummy[0]; + $topic[$i][$j]=$dummy[1]; + $doc[$i][$j]=$dummy[2]; + $keywords[$i][$j]=$dummy[3]; + if ($doc[$i][$j] =~ /sty$/ && $keywords[$i][$j]) { + $stydoc{"$doc[$i][$j]"}=substr($keywords[$i][$j],1,1); + unless ($stydoc{"$doc[$i][$j]"} =~ /^\d$/) { + $stydoc{"$doc[$i][$j]"}=0; + } + } + $maxind[$i]=$j; + ++$j; + } + }; + } + close(DATABASE); + $special=1 if ($i == 17 && $j > 0); + } +} + +# Tk +# hash table for toplevel windows; used to avoid multiple calls of same window +my %tlwins; +my %buttonlist; +# create frames for main window: commands on top, frame for buttons below +my $main=new MainWindow; +$tlwins{'mainwindow'}{'addr'}=$main; +$main->resizable(0,0); +$main->title("TeX Documentation Browser"); +$main->bind('all',''=>\&clean_exit); +$main->bind('all',''=>sub { $main->raise(); }); +$main->bind('all',''=>\&helptext); +$main->bind('all',''=>sub { $main->raise(); &mksrch; }); +$main->bind('all',''=>\&settings); +my $cmdframe=$main->Frame(-background=>"#ffcc99"); +my $buttonframe=$main->Frame; +$cmdframe->pack(-side=>'top',-fill=>'x'); +$buttonframe->pack(-side=>'bottom'); +# normal cursor +my $defcursor=$main->cget(-cursor); +# make buttons for command frame +my $Qbut=$cmdframe->Button(-text=>'Quit',%butcol, + -command=>\&clean_exit)->pack(-side=>'left'); +$tlwins{'mainwindow'}{'buttons'}[0]=$Qbut; +# define common default font for labels and text explicitly +my $deffont=$Qbut->cget(-font); +# ensure readability on high-res screens (suggested by R.Kotucha) +$deffont='Helvetica -16 bold' if &x_resolution > 1200; +$Qbut->configure(-font=>$deffont); +$tlwins{'mainwindow'}{'buttons'}[1]=$cmdframe->Button( + -text=>'Database search', + -font=>$deffont,%butcol, + -command=>[\&mksrch, 0] + )->pack(-side=>'left'); +$tlwins{'mainwindow'}{'buttons'}[2]=$cmdframe->Button( + -text=>'File search', + -font=>$deffont,%butcol, + -command=>[\&mksrch, 1] + )->pack(-side=>'left'); +$tlwins{'mainwindow'}{'buttons'}[3]=$cmdframe->Button(-text=>'Help/About', + -font=>$deffont,%butcol, + -command=>\&helptext + )->pack(-side=>'right'); +$tlwins{'mainwindow'}{'buttons'}[4]=$cmdframe->Button(-text=>'Settings', + -font=>$deffont,%butcol, + -command=>\&settings + )->pack(-side=>'right'); +# make buttons for category button frame +my $lbut=0; +my $l; +foreach (@button) { $l=length $_; $lbut=$l if ( $l > $lbut) } +my @catg; +my ($i2,$i3); +my $nbutt=scalar @button; +my $ncols=$nbutt/3-1; +foreach (0..$ncols) { + $i=$_; + $i2=$i+$nbutt/3; + $i3=$i+2*$nbutt/3; + $catg[$i]=$buttonframe->Button(-text=>$button[$i], + -font=>$deffont,%butcol, + -width=>$lbut, + -command=>[\&tpslct,$i,\@dummy])->grid + ($catg[$i2]=$buttonframe->Button(-text=>$button[$i2], + -font=>$deffont,%butcol, + -width=>$lbut, + -command=>[\&tpslct,$i2,\@dummy]), + $catg[$i3]=$buttonframe->Button(-text=>$button[$i3], + -font=>$deffont,%butcol, + -width=>$lbut, + -command=>[\&tpslct,$i3,\@dummy])); +} +# disable last button (lower right) if no local specials are found in list +my $ncat; +if ($special == 0) { + $catg[$#button]->configure(-state=>'disabled'); + $ncat=$nbutt-1; +} else { + $ncat=$nbutt; +} +for ($i=0,$j=5; $i<@catg; ++$i,++$j) { + $tlwins{'mainwindow'}{'buttons'}[$j]=$catg[$i]; +} +MainLoop; + +########## SUBROUTINES ######################################################## +# toplevel for selecting a topic of a category for viewing or printing +sub tpslct { + my($opt,@srchitems)=@_; + my (@lbitems,@lbdocs,$dspselect,$docselect,$wtitle); + if ($opt >= 0) { +# main window buttons +# see if toplevel window is already there + if (Exists($tlwins{$opt}{'addr'})) { + $tlwins{$opt}{'addr'}->deiconify(); + $tlwins{$opt}{'addr'}->raise(); + return; + } + for ($j=0; $j <= $maxind[$opt]; ++$j) { + push @lbitems,$topic[$opt][$j]; + push @lbdocs,$doc[$opt][$j]; + } + $wtitle=$button[$opt]; + } else { +# search results + my $spec_wtitle=shift @srchitems; + for ($j=0; $j < $#srchitems; $j+=2) { + my $k=$j+1; + push @lbitems,$topic[$srchitems[$j]][$srchitems[$k]]; + push @lbdocs,$doc[$srchitems[$j]][$srchitems[$k]]; + } + $wtitle = ($srchtype ? "File" : "Database") + . " search results for $spec_wtitle"; + } +# toplevel window of category $opt with two frames + my $tpwin=$main->Toplevel(-title=>$wtitle); + $tlwins{$opt}{'addr'}=$tpwin; + my $tpdsp=$tpwin->Frame(-relief=>'groove')->pack(-side=>'top'); + my $tpslc=$tpwin->Frame()->pack(-side=>'top'); +# selection frame with listbox and buttons +# label for listbox + my $tplabel=$tpslc->Label(-text=>($srchtype ? "Files" : "Topics"), + -font=>$deffont)->pack(-anchor=>'w', + -side=>'top'); +# listbox with optional scrollbar + my $tplist=$tpslc->Scrolled("Listbox", + -font=>$deffont, + -scrollbars=>'osoe', +# -height=>0, + -width=>0, + -selectmode=>'single', + -exportselection=>0, + -cursor=>'hand2')->pack(-side=>'left', + -fill=>'y', + -expand=>1); + $tplist->insert('end',@lbitems); # fill topics into listbox +# buttons frame + my $tpbframe=$tpslc->Frame(-borderwidth=>8); + $tpbframe->pack(-side=>'right'); +# make buttons for command frame + my $n_buttons = 0; + $tlwins{$opt}{'buttons'}[$n_buttons++]= + $tpbframe->Button(-text=>'View', + -font=>$deffont,%butcol, + -command=>sub{ &viewslc($docselect,$tpbframe);}, + -width=>6)->pack(-side=>'top'); + if (! $IsWin32) { + $tlwins{$opt}{'buttons'}[$n_buttons++]= + $tpbframe->Button(-text=>'Print', + -font=>$deffont,%butcol, + -command=>sub{ &prtslc($docselect,$tpbframe);}, + -width=>6)->pack(-side=>'top'); + } + $tlwins{$opt}{'buttons'}[$n_buttons++]= + $tpbframe->Button(-text=>'Cancel', + -font=>$deffont,%butcol, + -command=>sub{ destroy $tpwin; undef $tlwins{$opt};}, + -width=>6)->pack(-side=>'bottom'); +# if only 1 item is in the list (most likely in search results), select it + if (scalar @lbitems == 1) { + $tplist->selectionSet(0); + $dspselect=$lbitems[0]; + $docselect=$lbdocs[0]; + &viewslc($docselect,$tpbframe) + if ($autoview && $wtitle =~ /^Search results/); + } +# display frame + my $dsplabel=$tpdsp->Label(-text=>'Selection:', + -font=>$deffont)->pack(-anchor=>'w',, + -fill=>'x', + -side=>'left'); + my $dspslc=$tpdsp->Label(-textvariable=>\$dspselect, + -font=>$deffont, + -borderwidth=>2)->pack(-anchor=>'w', + -fill=>'x', + -side=>'right'); +# handle selection; only one selection possible + $tplist->bind(''=>sub{my ($slctind)=$tplist->curselection(); + $dspselect=$lbitems[$slctind]; + $docselect=$lbdocs[$slctind];}); +# key bindings + $tplist->bind(''=>sub{ + &viewslc($docselect,$tpbframe);}); + $tpwin->bind(''=>sub{ + &viewslc($docselect,$tpbframe);}); + $tpwin->bind(''=>sub{ + &prtslc($docselect,$tpbframe);}); + $tpwin->bind(''=>sub{destroy $tpwin; undef $tlwins{$opt};}); + $tplist->bind(''=>sub{ + if ($docselect) { + &showpath($docselect,$tpbframe); + } else { + &popmsg(2,"No selection;\nuse left mouse button.",$tpbframe); + }}); +} + +# view document selected in listbox +sub viewslc { + my($slc,$parframe)=@_; + my $viewer; + my $itype=-1; + my $browser=0; + my $styflag=0; + unless (defined $slc) { + &popmsg(2,"No selection was made.",$parframe); + return; + } + $parframe->configure(-cursor=>'watch'); + chomp $slc; + my @dummy=split('\.',$slc); + DOC_FORMAT: { # determine document type + ($dummy[-1] =~ /dvi/) && do { $viewer=$dvi_viewer; last DOC_FORMAT; }; + ($dummy[-1] =~ /ps/) && do { $viewer=$ps_viewer; last DOC_FORMAT; }; + ($dummy[-1] =~ /pdf/) && do { $viewer=$pdf_viewer; last DOC_FORMAT; }; + ($dummy[-1] =~ /txt/ || $dummy[-1] =~ /faq$/) && do { + $viewer=($txt_viewer eq "TDK_OWN" || + $txt_viewer =~ /xterm/) ? + $txt_viewer : "${CmdConsole} $txt_viewer"; + last DOC_FORMAT; + }; + ($dummy[-1] =~ /README/i || $dummy[-2] =~ /\/README$/i) && do { + $viewer=($txt_viewer eq "TDK_OWN" || + $txt_viewer =~ /xterm/) ? + $txt_viewer : "${CmdConsole} $txt_viewer"; + last DOC_FORMAT; + }; + ($dummy[-1] =~ /htm/) && do { + $viewer=$html_viewer; + if ($html_viewer =~ /netscape/i) { # check if Netscape is open + my $lockfile="${HomeEnv}/.netscape/lock"; + $browser=1 if (-e $lockfile || -l $lockfile); + } elsif ($html_viewer =~ /mozilla/i) { # check if Mozilla is open + my $mozcheck= + `mozilla -remote 'openFile($texmfmain/doc/index.html)'`; + $browser=1 unless ($?); + } + last DOC_FORMAT; + }; +# some packages have no normal documentation but useful info in the .sty + ($dummy[-1] =~ /sty$/) && do { + $viewer=($txt_viewer eq "TDK_OWN" || + $txt_viewer =~ /xterm/) ? + $txt_viewer : "${CmdConsole} $txt_viewer"; + $slc="../tex/$slc"; # .sty files are in ${tex,local}docpath/../tex/ + $styflag=1; + last DOC_FORMAT; + }; + $parframe->configure(-cursor=>$defcursor); + if ($xfmt_viewer != 1) { + &popmsg(2,"$dummy[-1]: not a known document format",$parframe); + return; + } + }; + if ($viewer eq "") { + if ($xfmt_viewer == 1) { + &popmsg(-1,'Unknown format; assuming plain text.',$parframe); + $viewer=($txt_viewer eq "TDK_OWN" || + $txt_viewer =~ /xterm/) ? + $txt_viewer : "${CmdConsole} $txt_viewer"; + } else { + &popmsg(2,"$dummy[-1]: no viewer available/specified for this format", + $parframe); + $parframe->configure(-cursor=>$defcursor); + return; + } + } +# build complete path and start viewer if file exists + my $slcdoc; + $slcdoc=&finddoc($slcdoc,$slc,$parframe); + if ($slcdoc ne "") { +# change to doc directory in case there are pictures + my $docpath=substr($slcdoc,0,(rindex($slcdoc,'/',(length $slcdoc)))); + chomp $slcdoc; + chdir ($docpath); +# try to get doc out of .sty file + if ($styflag) { + &popmsg(-1,'Trying to extract documentation out of .sty file; +might be cluttered with program comments.', + $parframe); + $slcdoc=&stripsty($slcdoc,substr($slc,7)); + } +# for text files use built-in text viewer if set + if ($IsWin32) { + if ($viewer eq "TDK_OWN") { + &ShellExecute('open', $slcdoc); + $parframe->configure(-cursor=>$defcursor); + return; + } + else { + system("$viewer $slcdoc"); + } + } + else { + if ($viewer eq "TDK_OWN") { + &textview($slcdoc); + $parframe->configure(-cursor=>$defcursor); + return; + } + if ($quiet == 0) { # show messages + if ($browser == 0) { # normal viewers or new Netscape/Mozilla + system("$viewer $slcdoc &"); + } else { # open doc in existing Netscape/Mozilla window + system("$viewer -remote 'openFile($slcdoc)' &"); + &popmsg(-1,"Opening document in existing $viewer window.", + $parframe); + } + } else { # viewer messages written to /dev/null instead of terminal + if ($browser == 0) { # normal viewers or new Netscape/Mozilla + system("perl -we 'use strict; \ +my \$dump=\"\"; \ +open(NULL,\">/dev/null\"); \ +open (VIEWQ,\"$viewer $slcdoc |\"); \ +while (\$dump=) { print NULL \$dump; } \ +close(VIEWQ); \ +close(NULL);' &"); + } else { # open doc in existing window (Netscape or Mozilla) + # not quiet; I didn't get an inline perl call like in + # the other branch working + system("$viewer -remote 'openFile($slcdoc)' &"); + &popmsg(-1,"Opening document in existing $viewer window.", + $parframe); + } + } + } + } + $parframe->configure(-cursor=>$defcursor); +} + +# Tk widget for text document +sub textview { + my($txtfile)=@_; +# see if toplevel window with this file is already there + if (Exists($tlwins{$txtfile}{'addr'})) { + $tlwins{$txtfile}{'addr'}->deiconify(); + $tlwins{$txtfile}{'addr'}->raise(); + return; + } + my $tfv_tk=$main->Toplevel(-title=>"Text file viewer"); + $tfv_tk->resizable(0,1); + $tlwins{$txtfile}{'addr'}=$tfv_tk; + $tfv_tk->Label(-text=>"File: $txtfile", + -font=>$deffont, + -relief=>'ridge', + -borderwidth=>3)->pack(-side=>'top', + -fill=>'x', + -ipady=>10, + -anchor=>'s'); + my $txtbody=$tfv_tk->Scrolled("Text", + -relief=>'flat', + -font=>$deffont, + -height=>20, + -width=>80, + -scrollbars=>"e")->pack(-side=>'top', + -fill=>'y', + -expand=>1); + open(TXTFILE,"$txtfile"); + while () { $txtbody->insert('end',$_); } + close(TXTFILE); + $txtbody->configure(-state=>'disabled'); + $tlwins{$txtfile}{'buttons'}[0]= + $tfv_tk->Button(-text=>'Close', + -font=>$deffont,%butcol, + -command=>sub{ destroy $tfv_tk; + undef $tlwins{$txtfile}; + })->pack(-side=>'bottom', + -fill=>'x'); + $tfv_tk->bind(''=>sub{destroy $tfv_tk; + undef $tlwins{$txtfile}; + }); +} + +# print document selected in listbox +sub prtslc { + my($slc,$parframe)=@_; + $tmpfno=&randname; + my $pstmpfile="${TempDir}/texdoc_$tmpfno.ps"; + push @tmpfiles,$pstmpfile; + my $status; + chomp $slc; + unless (defined $slc) { + &popmsg(2,"No selection was made.",$parframe); + return; + } + if ($print_cmd eq "") { + &popmsg(2,"No printer specified.",$parframe); + return; + } +# build complete path and check existence of file + my @dummy=split('\.',$slc); + if ($dummy[-1] =~ /sty$/) { + $slc="../tex/$slc"; # .sty files are in ${tex,local,home}docpath/../tex + } + my $slcdoc; + $slcdoc=&finddoc($slcdoc,$slc,$parframe); + return if ($slcdoc eq ""); +# change to doc directory in case there are pictures + my $docpath=substr($slcdoc,0,(rindex($slcdoc,'/',(length $slcdoc)))); + chdir ($docpath); + DOC_FORMAT: { # determine document type +# convert dvi files to ps before printing + ($dummy[-1] =~ /dvi/) && do { + if ($dvips_conv eq "") { + &popmsg(2,"No converter available for dvi->ps conversion.", + $parframe); + return; + } + &popmsg(-1,"Converting dvi to ps for printing and sending file to print...",$parframe); + $status=system("$dvips_conv $slcdoc -o $pstmpfile"); + if ($status != 0) { + &popmsg(2,"Error: Conversion dvi->ps failed!",$parframe); + } + last DOC_FORMAT; + }; +# PostScript is printed directly + ($dummy[-1] =~ /ps/) && do { + &popmsg(-1,"Sending file to $print_cmd...",$parframe); + $pstmpfile=$slcdoc; + last DOC_FORMAT; + }; +# convert pdf files to ps before printing + ($dummy[-1] =~ /pdf/) && do { + if ($pdfps_conv eq "") { + &popmsg(2,"No converter available for pdf->ps conversion.", + $parframe); + return; + } + &popmsg(-1,"Converting pdf to ps for printing and sending file to print...",$parframe); + system("$pdfps_conv $slcdoc $pstmpfile"); + last DOC_FORMAT; + }; +# convert html files to ps before printing + ($dummy[-1] =~ /htm/) && do { + if ($htmlps_conv eq "") { + &popmsg(2,"No converter available for html->ps conversion.", + $parframe); + return; + } + &popmsg(-1,"Converting html to ps for printing and sending file to print...",$parframe); + my $htmlps_redir_sign=($htmlps_redir == 1) ? ">" :""; + system("$htmlps_conv $slcdoc $htmlps_redir_sign $pstmpfile"); + last DOC_FORMAT; + }; +# convert txt files to ps before printing + ($dummy[-1] =~ /txt/ || $dummy[-1] =~ /faq$/ + || $dummy[-1] =~ /README/i) && do { + if ($txtps_conv eq "") { + &popmsg(2,"No converter available for txt->ps conversion.", + $parframe); + return; + } + &popmsg(-1,"Converting txt to ps for printing and sending file to print...",$parframe); + my $txtps_redir_sign=($txtps_redir == 1) ? ">" :""; + system("$txtps_conv $slcdoc $txtps_redir_sign $pstmpfile"); + last DOC_FORMAT; + }; +# convert extracted comments from sty files to ps before printing + ($dummy[-1] =~ /sty$/) && do { + if ($txtps_conv eq "") { + &popmsg(2,"No converter available for sty(txt)->ps conversion.", + $parframe); + return; + } + &popmsg(-1,"Converting sty(txt) to ps for printing and sending file to print...",$parframe); +# try to get doc out of .sty file + &popmsg(-1,'Trying to extract documentation out of .sty file; +might be cluttered with program comments.', + $parframe); + $slcdoc=&stripsty($slcdoc,substr($slc,7)); + my $txtps_redir_sign=($txtps_redir == 1) ? ">" :""; + system("$txtps_conv $slcdoc $txtps_redir_sign $pstmpfile"); + last DOC_FORMAT; + }; + &popmsg(2,"$dummy[-1]: cannot print document format",$parframe); + return; + }; + system("$print_cmd $pstmpfile"); +} + +# test existence and search a documentation which is not in specified place +sub finddoc { + my($slcdoc,$slc,$parframe)=@_; + my ($dummy,$status); + SLCDOCFIND: foreach ($texdocpath,$distdocpath,$docdocpath) { + $slcdoc="$_/$slc"; + if (-e $slcdoc) { +# found where it should be + return $slcdoc; + } else { +# see if the documentation file is in the local doc tree... + my @srchslcdoc=($slcdoc); + if ($localdocpath) { + push @srchslcdoc,"$localdocpath/$slc"; + return $srchslcdoc[-1] if (-e $srchslcdoc[-1]); + } +# ... or the user's doc tree... + if ($homedocpath) { + push @srchslcdoc,"$homedocpath/$slc"; + return $srchslcdoc[-1] if (-e $srchslcdoc[-1]); + } +# ... otherwise proceed with searching + $status=-1; +# see if the documentation file is compressed + CMPREND: foreach my $cmprtype ("gz","bz2","zip") { + foreach (@srchslcdoc) { + $dummy="$_.$cmprtype"; + if (-e $dummy) { # yes, it is compressed + $tmpfno=&randname; + my $rawname=basename($slc,""); + $slcdoc="${TempDir}/texdoc_$tmpfno$rawname"; + push @tmpfiles,$slcdoc; + my ($dcmp,$dcmp_opt); + COMPRESS: { # determine compression type + ($cmprtype eq "gz") && do { + $dcmp="gzip"; + $dcmp_opt="-cd"; + last COMPRESS; + }; + ($cmprtype eq "bz2") && do { + $dcmp="bzip2"; + $dcmp_opt="-cd"; + last COMPRESS; + }; + ($cmprtype eq "zip") && do { + $dcmp="zip"; + $dcmp_opt="-p"; + last COMPRESS; + }; + }; +# try to decompress + $status=system("$dcmp $dcmp_opt $dummy > $slcdoc"); + if ($status != 0) { # failure + &popmsg(2, + "$dcmp: Couldn't decompress file, cancelling.", + $parframe); + $slcdoc=""; + return $slcdoc; + } +# last CMPREND; does not work, what we need is: + return $slcdoc; + } + } + } + } + } + if ($status != 0) { + $parframe->configure(-cursor=>'watch'); +# try to find it elsewhere with kpsewhich + my $rawname=basename($slc,""); + $slcdoc=($slcdoc =~ /\.sty$/) ? + `kpsewhich $rawname` : + `kpsewhich --format=${qq}TeX system documentation${qq} $rawname`; + if ($slcdoc eq "") { # nothing found; cancel + &popmsg(2,"$rawname not found, cancelling.",$parframe); + $slcdoc=""; + } + $parframe->configure(-cursor=>$defcursor); + } + return $slcdoc; +} + +# determine existence and show paths of files (Button-3) +sub showpath { + my ($docselect,$tpbframe)=@_; + my $found=0; + if ($docselect =~ /\.sty$/) { + STYPATH: foreach my $fullpath ("$texmfmain/tex/$docselect", + "$texmfdist/tex/$docselect", + "$texmflocal/tex/$docselect", + "$texmfhome/tex/$docselect") { + if (-e $fullpath) { + &popmsg(0,"Selected file:\n$fullpath",$tpbframe); + $found=1; + last STYPATH; + } + } + if (!$found) { + &popmsg(2,"Selected file:\n$docselect\ndoes not exist.",$tpbframe) } + } else { + DOCPATH: foreach my $fullpath ("$texdocpath/$docselect", + "$distdocpath/$docselect", + "$docdocpath/$docselect", + "$localdocpath/$docselect", + "$homedocpath/$docselect") { + foreach ('','.gz','.bz2','.zip') { + my $fullpathext="$fullpath$_"; + if (-e $fullpathext) { + &popmsg(0,"Selected file:\n$fullpathext",$tpbframe); + $found=1; + last DOCPATH; + } + } + } + if (!$found) { + &popmsg(2,"Selected file:\n$docselect\ndoes not exist (neither in normal form nor compressed).",$tpbframe) } + } +} + +# make or destroy search entry widget +sub mksrch { + my ($type) = @_; + if ($srchflag == 1) { + if ($type == $srchtype) { + destroy $srchentry; + $srchflag=0; + } else { + $srchtype = $type; + } + } else { + $srchtype = $type; +# get the search string + $srchentry=$cmdframe->Entry(-cursor=>'xterm', + -font=>$deffont, + -width=>20, + -takefocus=>1)->pack(-side=>'left'); + $srchentry->focus(); + $srchentry->bind(''=>[\&srchstr, $srchentry]); + $srchflag=1; +# key binding + $srchentry->bind(''=>sub{destroy $srchentry; $srchflag=0;}); + $srchentry->bind(''=>sub{destroy $srchentry; $srchflag=0;}); + } +} + +# call search routine and display results +sub srchstr { + my $string; + my @reslist; + $string=$srchentry->get(); +# search + $main->Busy(-recurse => 1); + if ($srchtype == 0) { + @reslist = &srchdb($string); + } else { + @reslist = &srchtd($string); + } + $main->Unbusy(); +# destroy entry widget and show results + destroy $srchentry; + $srchflag=0; + if (scalar @reslist == 0) { + &popmsg(0, ($srchtype == 0 ? 'Database' : 'File'). + " search for $string: no matches found.\n". + "You may want to try a ". + ($srchtype == 0 ? 'File' : 'Databse') . " search.\n\n". + "If nothing else works, CTAN offers an online search form:\n". + "http://ctan.org/search.html\n", + $cmdframe); + } else { + &tpslct(-1, $string, @reslist); + } +} + +# search using texdoc +sub srchtd { + my ($string) = @_; + my @res; + my $tdout = `texdoc -M -l $string`; + if ($?) { + &popmsg(0,"texdoc failed, sorry: $!\n". + "Please report this problem on the texlive mailing list.\n"); + return; + } else { + my $i = 0; + for my $line (split /\n/, $tdout) { + my @fields = split /\t/, $line; + $doc[$ncat][$i] = $fields[2]; + $topic[$ncat][$i] = basename($fields[2]); + $packname[$ncat][$i] = "no package name"; + push @res, ($ncat, $i++); + } + return @res; + } +} + +# search a string in @packname, @topic and @keywords +sub srchdb { + my ($string) = @_; + my (@results, @reslist); + if ($string) { + for ($i=0; $i<$ncat; ++$i) { + for ($j=0; $j<$maxind[$i]+1; ++$j) { + SRCH: { + ($topic[$i][$j] =~ /$string/i) && do { + push @results,($i,$j); + last SRCH; + }; + (defined $keywords[$i][$j]) && do { + if ($keywords[$i][$j] =~ /$string/i) { + push @results,($i,$j); + last SRCH; + } + }; + ($packname[$i][$j] =~ /$string/i) && do { + push @results,($i,$j); + last SRCH; + }; + }; + } + } + } else { # return full database + $string='all database entries'; + for ($i=0; $i<$ncat; ++$i) { + for ($j=0; $j<$maxind[$i]+1; ++$j) { push @results,($i,$j); } + } + } + unless (scalar @results == 0) { +# cancel multiple entries + my ($omit,$pack1,$pack2); + @reslist=($results[0],$results[1]); + for ($i=0; $i<$#results; $i+=2) { + $omit=0; + $pack1=$packname[$results[$i]][$results[$i+1]]; + for ($j=0; $j<$#reslist; $j+=2) { + $pack2=$packname[$reslist[$j]][$reslist[$j+1]]; + if ($pack1 eq $pack2) { $omit=1; last; } + } + if ($omit == 0) { push @reslist,($results[$i],$results[$i+1]); } + } + } + return @reslist; +} + +# extract documentation of .sty files; a flag in the @keywords array shows +# where the doc is located: +# -0-: no specific place; -1-: at end, behind \endinput; -2-: at beginning, +# terminated by %%%%%%; -3-: at beginning, terminated with blank line +sub stripsty { + my ($slcdoc,$slc)=@_; + my @stydoc; + $tmpfno=&randname; + my $tmpslcdoc="${TempDir}/texdoc_$tmpfno.txt"; + push @tmpfiles,$tmpslcdoc; + open (STY,"$slcdoc"); + LOC: { + ($stydoc{$slc} == 0) && do { # no specific place, suck in everything :-( + while ($line = ) { push @stydoc,$line if ($line =~ /^%/); } + last LOC; + }; + ($stydoc{$slc} == 1) && do { # at end, behind \endinput + while ($line = ) { + last if ($line =~ /^\s*\\endinput/ && !($line =~ /^%/)); + } + while ($line = ) { push @stydoc,$line; } + last LOC; + }; + ($stydoc{$slc} == 2) && do { # up to a certain %%%%%%%, hopefully the 1st + for (my $i=0; $i<9; ++$i) { $stydoc[$i]=; } # after the 8th line + while ($line = ) { + last if ($line =~ /^%{4,}/); + push @stydoc,$line; + } + last LOC; + }; + ($stydoc{$slc} == 3) && do { # up to 1st blank/apparently empty line + while ($line = ) { + last if ($line =~ /^\s*$/); + push @stydoc,$line; + } + last LOC; + }; + }; + close(STY); + open(TMPSTY,">$tmpslcdoc"); + foreach (@stydoc) { print TMPSTY $_; } + close(TMPSTY); + return $tmpslcdoc; +} + +# pop up a note or an error or warning message toplevel window +sub popmsg { + my($level,$msg,$parframe)=@_; + my $degree; + LEVEL: { + ($level == -1) && do { $degree="Info"; last LEVEL; }; + ($level == 0) && do { $degree="Note"; last LEVEL; }; + ($level == 1) && do { + return if ($quiet == 1); + $degree="Warning"; + last LEVEL + }; + ($level == 2) && do { $degree="Error"; last LEVEL; }; + }; + my $msgwin=$parframe->Toplevel(-title=>$degree); + my $lbl=$msgwin->Label(-text=>uc($degree), + -font=>$deffont)->pack(-side=>'top', -fill=>'x'); +# get size of message text + my @dummy=split("\n",$msg); + my $nline=scalar @dummy; + my $msgwidth=0; + my $lline; + foreach (@dummy) { + $lline=length $_; + if ($lline > $msgwidth) { $msgwidth=$lline; } + } + my $message=$msgwin->Text(-relief=>'flat', + -font=>$deffont, + -height=>$nline, + -width=>$msgwidth)->pack(-side=>'top'); + $message->insert('end',$msg); + $message->configure(-state=>'disabled'); + if ($level < 0) { # transient message window + $msgwin->after(3000,sub{destroy $msgwin}); + } else { # persistent message window + $msgwin->Button(-text=>'Close', + -font=>$deffont,%butcol, + -command=>sub{destroy $msgwin})->pack(-side=>'bottom', + -fill=>'x'); + $msgwin->bind(''=>sub{destroy $msgwin}); + } +} + +# show/change settings (don't show this to an expert :-/ ) +sub settings { + my ($homedocpath_tmp,$quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, + $dvi_viewer_tmp,$dvips_conv_tmp, + $ps_viewer_tmp,$pdf_viewer_tmp,$pdfps_conv_tmp, + $html_viewer_tmp,$htmlps_conv_tmp,$htmlps_redir_tmp, + $txt_viewer_tmp,$txtps_conv_tmp,$txtps_redir_tmp,$print_cmd_tmp)= + ($homedocpath,$quiet,$autoview,$xfmt_viewer, + $dvi_viewer,$dvips_conv,$ps_viewer, + $pdf_viewer,$pdfps_conv,$html_viewer, + $htmlps_conv,$htmlps_redir,$txt_viewer, + $txtps_conv,$txtps_redir,$print_cmd); + my @tdcolors_tmp=@tdcolors; +# see if toplevel window is already there + if (Exists($tlwins{"setmenu"}{'addr'})) { + $tlwins{"setmenu"}{'addr'}->deiconify(); + $tlwins{"setmenu"}{'addr'}->raise(); + return; + } + my $setmenu=$main->Toplevel(-title=>'Settings'); + $setmenu->resizable(0,0); + $tlwins{"setmenu"}{'addr'}=$setmenu; +# documentation path + my $datlabel; + $datlabel="Database file(s) used: teTeX"; + $datlabel.=", local database" if (-e $locdatabase); + $datlabel.=", user database" if (-e $homedatabase); + my $docframe=$setmenu->Frame(-relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -expand=>1); + my $docframestring="\nDistribution documentation root path(s):\n$texdocpath"; + $docframestring.=", $distdocpath" if (-e $distdocpath); + $docframestring.=", $docdocpath" if (length $docdocpath); + if ($localdocpath && $localdocpath ne $texdocpath) { + $docframestring.="\nLocal documentation root path: $localdocpath\n"; + } + $docframe->Label(-text=>"$docframestring", + -font=>$deffont)->pack(-side=>'top', + -anchor=>'w', + -fill=>'x', + -expand=>1); + if (defined $texmfhome && -d $texmfhome) { + $homedocpath_tmp=basename($homedocpath_tmp,""); + my $usrdocframe=$docframe->Frame(-relief=>'flat')->pack(-side=>'top', + -fill=>'x'); + my $usrdoclabel=$usrdocframe->Label(-text=>"User's documentation root path: $texmfhome/", + -font=>$deffont)->pack(-side=>'left'); + my $usrdocentry=$usrdocframe->Entry(-textvariable=>\$homedocpath_tmp, + -font=>$deffont)->pack(-side=>'left'); + } + $docframe->Label(-text=>"$datlabel.", + -font=>$deffont)->pack(-side=>'top', + -anchor=>'w', + -ipady=>2, + -fill=>'x', + -expand=>1); +# General viewer behaviour + my $genvframe=$setmenu->Frame(-label=>'General viewer behaviour', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>6, + -expand=>1); + my $genvframe1=$genvframe->Frame()->pack(-side=>'left'); + my $genvsub1=$genvframe1->Frame()->pack(-side=>'top', + -anchor=>'w', + -ipady=>3); + my $genvecbut=$genvsub1-> + Checkbutton(-variable=>\$quiet_tmp)->pack(-side=>'left', + -anchor=>'sw'); + my $genvelabel=$genvsub1->Label(-text=>'Suppress error messages', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $genvsub2=$genvframe1->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $genvscbut=$genvsub2-> + Checkbutton(-variable=>\$autoview_tmp)->pack(-side=>'left', + -anchor=>'sw'); + my $genvslabel=$genvsub2->Label(-text=>'Autostart viewer for one-item listboxes', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $genvsub3=$genvframe1->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $genvxcbut=$genvsub3-> + Checkbutton(-variable=>\$xfmt_viewer_tmp)->pack(-side=>'left', + -anchor=>'sw'); + my $genvxlabel=$genvsub3->Label(-text=>'Use text viewer for unknown file format', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); +# colours of GUI + my @tdcolors_d=@tdcolors_tmp; + $tlwins{'setmenu'}{'buttons'}[0]= + $genvframe->Button(-text=>'Change viewer colours', + -command=>sub { + @tdcolors_tmp=&popcolor($setmenu,@tdcolors_tmp); + @tdcolors_d=@tdcolors_tmp; + }, + -font=>$deffont,%butcol)->pack(-side=>'right'); +# DVI + my $dviframe=$setmenu->Frame(-label=>'DVI', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>6, + -expand=>1); + my $dvisub1=$dviframe->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $dvisub2=$dviframe->Frame()->pack(-side=>'top', + -anchor=>'w', + -ipady=>6); + my $dvivlabel=$dvisub1->Label(-text=>'Viewer command', + -anchor=>'w', + -font=>$deffont)->pack(-side=>'left'); + my $dviventry=$dvisub1->Entry(-textvariable=>\$dvi_viewer_tmp, + -font=>$deffont)->pack(-side=>'left'); + my $dviclabel=$dvisub2->Label(-text=>'DVI->PS converter command', + -anchor=>'w', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $dvilbwidth=length 'DVI->PS converter command'; + $dvivlabel->configure(-width=>1.1*$dvilbwidth); + $dviclabel->configure(-width=>1.1*$dvilbwidth); + my $dvicentry=$dvisub2->Entry(-textvariable=>\$dvips_conv_tmp, + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); +# PostScript + my $psframe=$setmenu->Frame(-label=>'PostScript', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>10, + -expand=>1); + my $psvlabel=$psframe->Label(-text=>'Viewer command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'w'); + my $psventry=$psframe->Entry(-textvariable=>\$ps_viewer_tmp, + -font=>$deffont)->pack(-side=>'left'); +# PDF + my $pdfframe=$setmenu->Frame(-label=>'PDF', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>6, + -expand=>1); + my $pdfsub1=$pdfframe->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $pdfsub2=$pdfframe->Frame()->pack(-side=>'top', + -anchor=>'w', + -ipady=>6); + my $pdfvlabel=$pdfsub1->Label(-text=>'Viewer command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'w'); + my $pdfventry=$pdfsub1->Entry(-textvariable=>\$pdf_viewer_tmp, + -font=>$deffont)->pack(-side=>'left'); + my $pdfclabel=$pdfsub2->Label(-text=>'PDF->PS converter command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $pdfcentry=$pdfsub2->Entry(-textvariable=>\$pdfps_conv_tmp, + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); +# HTML + my $htmlframe=$setmenu->Frame(-label=>'HTML', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>6, + -expand=>1); + my $htmlsub1=$htmlframe->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $htmlsub2=$htmlframe->Frame()->pack(-side=>'top', + -anchor=>'w', + -ipady=>6); + my $htmlvlabel=$htmlsub1->Label(-text=>'Viewer command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'w'); + my $htmlventry=$htmlsub1->Entry(-textvariable=>\$html_viewer_tmp, + -font=>$deffont)->pack(-side=>'left'); + my $htmlclabel=$htmlsub2->Label(-text=>'HTML->PS converter command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $htmlcentry=$htmlsub2->Entry(-textvariable=>\$htmlps_conv_tmp, + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $htmlrlabel=$htmlsub2->Label(-text=>'Output redirect needed', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $htmlrcbut=$htmlsub2-> + Checkbutton(-variable=>\$htmlps_redir_tmp)->pack(-side=>'left', + -anchor=>'sw'); +# plain text + my $txtframe=$setmenu->Frame(-label=>'Plain text', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>6, + -expand=>1); + my $txtsub1=$txtframe->Frame()->pack(-side=>'top', + -anchor=>'w'); + my $txtsub2=$txtframe->Frame()->pack(-side=>'top', + -anchor=>'w', + -ipady=>6); + my $txtvlabel=$txtsub1->Label(-text=>'Viewer command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'w'); + my $txtventry=$txtsub1->Entry(-textvariable=>\$txt_viewer_tmp, + -font=>$deffont)->pack(-side=>'left'); + my $txt_view_flag; + if ($txt_viewer_tmp eq "TDK_OWN") { + $txt_view_flag=1; + $txtventry->configure(-state=>'disabled'); + } else { + $txt_view_flag=0; + $txtventry->configure(-state=>'normal'); + } + my $txtvilabel=$txtsub1->Label(-text=>"\tUse texdoctk\'s own viewer", + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $txtvcbut=$txtsub1-> + Checkbutton(-variable=>\$txt_view_flag, + -command=>sub { + if ($txt_view_flag == 1) { + $txt_viewer_tmp="TDK_OWN"; + $txtventry->configure(-state=>'disabled'); + } else { + $txt_viewer_tmp=$txt_viewer; + $txtventry->configure(-state=>'normal'); + $txtventry->focus(); + } + })->pack(-side=>'left', + -anchor=>'sw'); + my $txtclabel=$txtsub2->Label(-text=>'Text->PS converter command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $txtcentry=$txtsub2->Entry(-textvariable=>\$txtps_conv_tmp, + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $txtrlabel=$txtsub2->Label(-text=>'Output redirect needed', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'sw'); + my $txtrcbut=$txtsub2-> + Checkbutton(-variable=>\$txtps_redir_tmp)->pack(-side=>'left', + -anchor=>'sw'); +# printer + my $prtframe=$setmenu->Frame(-label=>'Printer', + -relief=>'groove', + -borderwidth=>2)->pack(-side=>'top', + -fill=>'x', + -ipady=>10, + -expand=>1); + my $prtclabel=$prtframe->Label(-text=>'Command', + -font=>$deffont)->pack(-side=>'left', + -anchor=>'w'); + my $prtcentry=$prtframe->Entry(-textvariable=>\$print_cmd_tmp, + -font=>$deffont)->pack(-side=>'left'); +# buttons and key bindings + my $setbfr=$setmenu->Frame()->pack(-side=>'bottom'); + $tlwins{'setmenu'}{'buttons'}[1]= + $setbfr->Button(-text=>'OK', + -font=>$deffont,%butcol, + -command=>sub{ + $homedocpath="$texmfhome/$homedocpath_tmp"; + ($quiet,$autoview,$xfmt_viewer, + $dvi_viewer,$dvips_conv, + $ps_viewer,$pdf_viewer, + $pdfps_conv,$html_viewer, + $htmlps_conv,$htmlps_redir, + $txt_viewer,$txtps_conv,$txtps_redir,$print_cmd)= + ($quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, + $dvi_viewer_tmp,$dvips_conv_tmp, + $ps_viewer_tmp, + $pdf_viewer_tmp,$pdfps_conv_tmp, + $html_viewer_tmp, + $htmlps_conv_tmp,$htmlps_redir_tmp, + $txt_viewer_tmp,$txtps_conv_tmp, + $txtps_redir_tmp,$print_cmd_tmp); + @tdcolors=@tdcolors_tmp; + %butcol=('-background'=>$tdcolors[0], + '-foreground'=>$tdcolors[1], + '-activebackground'=>$tdcolors[2], + '-activeforeground'=>$tdcolors[3]); + foreach my $tlkey (keys %tlwins) { + foreach (@{$tlwins{$tlkey}{'buttons'}}) { + $_->configure(%butcol); + } + } + if ($txt_viewer eq "" && + defined $ENV{PAGER}) { + $txt_viewer=$ENV{PAGER}; + } + destroy $setmenu}, + -width=>6)->pack(-side=>'left', + -padx=>10, + -pady=>10); + $tlwins{'setmenu'}{'buttons'}[2]= + $setbfr->Button(-text=>'Save', + -font=>$deffont,%butcol, + -command=>sub{ + $setmenu->configure(-cursor=>'watch'); + &popmsg(-1,"Writing settings to $myrc",$setmenu); + my $tdcolors_tmp=join(' ',@tdcolors_tmp); + &writerc($homedocpath_tmp, + $quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, + $tdcolors_tmp, + $dvi_viewer_tmp,$dvips_conv_tmp, + $ps_viewer_tmp, + $pdf_viewer_tmp,$pdfps_conv_tmp, + $html_viewer_tmp, + $htmlps_conv_tmp,$htmlps_redir_tmp, + $txt_viewer_tmp,$txtps_conv_tmp, + $txtps_redir_tmp,$print_cmd_tmp,$setmenu); + $setmenu->configure(-cursor=>$defcursor); + })->pack(-side=>'left', + -padx=>10); + $tlwins{'setmenu'}{'buttons'}[3]= + $setbfr->Button(-text=>'Cancel', + -font=>$deffont,%butcol, + -command=>sub{destroy $setmenu; + undef $tlwins{"setmenu"}; + })->pack(-side=>'left', + -padx=>10); + $setmenu->bind(''=>sub{destroy $setmenu; + undef $tlwins{"setmenu"};}); +} + +# dialog toplevel for color settings +sub popcolor { + my ($parframe,@entryvar)=@_; +# see if toplevel window is already there + if (Exists($tlwins{'chngcol'}{'addr'})) { + $tlwins{'chngcol'}{'addr'}->deiconify(); + $tlwins{'chngcol'}{'addr'}->raise(); + return; + } + my $dlgwin=$parframe->Toplevel(-title=>'Change colours'); + $dlgwin->resizable(0,0); + $tlwins{'chngcol'}{'addr'}=$dlgwin; +# entry widgets for default/active back/foreground + $dlgwin->Label(-text=>'Enter colours as names or RGB #xxxxxx values', + -font=>$deffont)->pack(-side=>'top'); + my $dlgdef=$dlgwin->Frame()->pack(-side=>'top'); + my $dlgact=$dlgwin->Frame()->pack(-side=>'top'); + my $dlgdef1=$dlgdef->Frame()->pack(-side=>'left'); + my $dlgtfr0=$dlgdef1->Frame()->pack(-side=>'top'); + my $dlgtfr1=$dlgdef1->Frame()->pack(-side=>'top'); + my $dlgact1=$dlgact->Frame()->pack(-side=>'left'); + my $dlgtfr2=$dlgact1->Frame()->pack(-side=>'top'); + my $dlgtfr3=$dlgact1->Frame()->pack(-side=>'top'); + $dlgtfr0->Label(-text=>"Default background", + -anchor=>'w', + -width=>18, + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr0->Entry(-textvariable=>\$entryvar[0], + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr1->Label(-text=>"Default foreground", + -anchor=>'w', + -width=>18, + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr1->Entry(-textvariable=>\$entryvar[1], + -font=>$deffont)->pack(-side=>'left'); + my $deflabel=$dlgdef->Label(-text=>'Default', + -relief=>'ridge', + -width=>10, + -height=>2)->pack(-side=>'right', + -padx=>7); + $dlgtfr2->Label(-text=>"Active background", + -anchor=>'w', + -width=>18, + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr2->Entry(-textvariable=>\$entryvar[2], + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr3->Label(-text=>"Active foreground", + -anchor=>'w', + -width=>18, + -font=>$deffont)->pack(-side=>'left'); + $dlgtfr3->Entry(-textvariable=>\$entryvar[3], + -font=>$deffont)->pack(-side=>'left'); + my $actlabel=$dlgact->Label(-text=>'Active', + -background=>$entryvar[2], + -foreground=>$entryvar[3], + -relief=>'ridge', + -width=>10, + -height=>2)->pack(-side=>'right', + -padx=>7); +# buttons + my $setbfr=$dlgwin->Frame()->pack(-side=>'bottom'); + my $chngflag=0; + $tlwins{'chngcol'}{'buttons'}[0]= + $setbfr->Button(-text=>'OK', + -font=>$deffont,%butcol, + -command=>sub { + foreach (@entryvar) { # RGB form with leading # + $_="#$_" if (/^[A-Fa-f0-9]{6}$/); + } + $chngflag=1 if (&colcheck($dlgwin,@entryvar)); + }, + -width=>6)->pack(-side=>'left', + -padx=>5, + -pady=>10); + $tlwins{'chngcol'}{'buttons'}[1]= + $setbfr->Button(-text=>'Preview', + -font=>$deffont,%butcol, + -command=>sub { + foreach (@entryvar) { # RGB form with leading # + $_="#$_" if (/^[A-Fa-f0-9]{6}$/); + } + if (&colcheck($dlgwin,@entryvar)) { + $deflabel-> + configure(-background=>$entryvar[0], + -foreground=>$entryvar[1]); + $actlabel-> + configure(-background=>$entryvar[2], + -foreground=>$entryvar[3]); + } + }, + -width=>6)->pack(-side=>'left', + -padx=>5, + -pady=>10); + $tlwins{'chngcol'}{'buttons'}[2]= + $setbfr->Button(-text=>'Cancel', + -font=>$deffont,%butcol, + -command=>sub{destroy $dlgwin; + undef $tlwins{'chngcol'}; + })->pack(-side=>'right', + -padx=>5, + -pady=>10); + $dlgwin->bind(''=>sub{destroy $dlgwin; + undef $tlwins{'chngcol'}; }); + $dlgwin->waitVariable(\$chngflag); + destroy $dlgwin; + undef $tlwins{'chngcol'}; + return @entryvar; +} + +# check colours set in popcolor; relies on the existence of X11's showrgb +sub colcheck { + my ($dlgwin,@entryvar)=@_; + my $ecnt=0; + foreach (@entryvar) { # all colours defined? + last unless ($_); + ++$ecnt; + } + &popmsg(2,'Some colours undefined.',$dlgwin) if ($ecnt != 4); + my $defcol=0; + if (`which showrgb`) { # test for proper name + my @rgb=`showrgb`; + my @norgb; + foreach my $colour (@entryvar) { + if ($colour =~ /^#[A-Fa-f0-9]{6}$/ || grep /\b$colour\b/i,@rgb) { + ++$defcol; + } else { + push @norgb,$colour; + } + } + if ($defcol != 4) { + my $norgb=join("\n",@norgb); + &popmsg(2,"Some colours invalid:\n$norgb",$dlgwin); + } + } else { $defcol=4; } + return ($ecnt == 4 && $defcol == 4) ? 1 : 0; +} + +# write user's ~/.texdocrc +sub writerc { + use File::Copy qw/cp mv/; + my ($homedocpath_tmp,$quiet_tmp,$autoview_tmp,$xfmt_viewer_tmp, + $tdcolors_tmp, + $dvi_viewer_tmp,$dvips_conv_tmp, + $ps_viewer_tmp, + $pdf_viewer_tmp,$pdfps_conv_tmp, + $html_viewer_tmp, + $htmlps_conv_tmp,$htmlps_redir_tmp, + $txt_viewer_tmp,$txtps_conv_tmp, + $txtps_redir_tmp,$print_cmd_tmp,$parframe)=@_; + my $err=0; + mv $myrc,"$myrc.save" if (-e $myrc); + open(MYRC,">$myrc"); + print MYRC "# user's .texdocrc, generated by program\n +# root of user's doc directory (from \$HOMETEXMF) +# can be left empty if \$TEXMFHOME is undefined +HOMEDOCPATH=$homedocpath_tmp +# general viewer behaviour (y or yes to make active) +QUIET=$quiet_tmp +AUTOVIEW=$autoview_tmp +XFMT_VIEWER=$xfmt_viewer_tmp +# button colours: default and active back-/foreground +# names and RGB values are both allowed; use the form #xxxxxx for RGB +TDCOLORS=$tdcolors_tmp +# the following variables contain whole commands, i.e. options can be given +# DVI settings +DVI_VIEWER=$dvi_viewer_tmp +DVIPS_CONV=$dvips_conv_tmp +# PostScript handling +PS_VIEWER=$ps_viewer_tmp +# PDF handling +PDF_VIEWER=$pdf_viewer_tmp +PDFPS_CONV=$pdfps_conv_tmp +# HTML handling +HTML_VIEWER=$html_viewer_tmp +HTMLPS_CONV=$htmlps_conv_tmp +# HTMLPS_REDIR must be on, if the html->ps converter normally writes its output +# to stdout instead of a file (e.g. as html2ps) (y or yes to make active) +HTMLPS_REDIR=$htmlps_redir_tmp +# Plain text handling +# TDK_OWN is texdoctk's own text file viewer +TXT_VIEWER=$txt_viewer_tmp +TXTPS_CONV=$txtps_conv_tmp +# TXTPS_REDIR must be on, if the txt->ps converter normally writes its output +# to stdout instead of a file (e.g. as a2ps) (y or yes to make active) +TXTPS_REDIR=$txtps_redir_tmp +# printer +PRINT_CMD=$print_cmd_tmp +\n# end of config\n"; + close(MYRC); +} + +# help window (toplevel) +sub helptext { +# see if toplevel window is already there + if (Exists($tlwins{"helptext"}{'addr'})) { + $tlwins{"helptext"}{'addr'}->deiconify(); + $tlwins{"helptext"}{'addr'}->raise(); + return; + } + my $help=$main->Toplevel(-title=>'Help/About'); + $help->resizable(0,1); + $tlwins{'helptext'}{'addr'}=$help; + $help->Label(-text=>"texdoctk +TeX documentation browser +v$version ($date)", + -font=>$deffont)->pack(-side=>'top', + -ipady=>10, + -anchor=>'s'); + my $helpbody=$help->Scrolled("Text", + -relief=>'flat', + -font=>$deffont, + -height=>20, + -width=>60, + -scrollbars=>"e")->pack(-side=>'top', + -fill=>'y', + -expand=>1); + my $pos=tell DATA; + while () { + $_ =~ s/\$sysrc/$sysrc/; + last if (/^#/); + $helpbody->insert('end',$_); + } + seek(DATA,$pos,0); + $helpbody->configure(-state=>'disabled'); + $tlwins{'helptext'}{'buttons'}[0]= + $help->Button(-text=>'Close', + -font=>$deffont,%butcol, + -command=>sub{destroy $help; + undef $tlwins{"helptext"}; + })->pack(-side=>'bottom', + -fill=>'x'); + $help->bind(''=>sub{destroy $help; undef $tlwins{"helptext"};}); +} + +# read config file; personal settings override the default settings +sub readrc { + my($rcfile,$icall)=@_; + my ($var,$val); + my $pathflag=0; + my $pathflagl=0; + my $pathflagh=0; + my $tdcolors=''; +# for backward compatibility of converter/printer options + my ($dvips_opts,$pdfps_opts,$print_opts); +# read defaults resp. local/personal settings + CALL: { + ($icall == 1) && do { + open (RC,"$rcfile") || + &fatalmsg("Couldn't open system-wide default config file ${TeXDocRcDefaults}.\n"); + last CALL; + }; + ($icall == 2) && do { + open (RC,"$rcfile") || + &fatalmsg("Couldn't open personal config file ~/.texdocrc.\n"); + last CALL; + }; + }; + while ($line = ) { + next if ($line =~ /^($|#)/); + chomp $line; + ($var,$val)=split("=",$line,2); + RCVARS: { + ($var =~ /texdocpath/i) && do { # TEXDOCPATH + if (length $val > 0) { + $pathflag=1; + eval(join("",("\$",lc($var),"=\$val"))); + } + last RCVARS; + }; + ($var =~ /localdocpath/i) && do { # LOCALDOCPATH + if (length $val > 0) { + $pathflagl=1; + eval(join("",("\$",lc($var),"=\$val"))); + } + last RCVARS; + }; + ($var =~ /homedocpath/i) && do { # HOMEDOCPATH + if ($icall == 2 && length $val > 0) { # set only in ~/.texdocrc + $pathflagh=1; + eval(join("",("\$",lc($var),"=\$val"))); + } + last RCVARS; + }; + # other variables + eval(join("",("\$",lc($var),"=\$val"))); + }; + } + close(RC); +# find texmf/doc, and possibly other distribution texmf trees + if ($rcfile eq $sysrc || $pathflag == 1) { + $texmfmain=`kpsewhich --expand-path=${qq}\$TEXMFMAIN${qq}`; + chomp $texmfmain; + $texdocpath="$texmfmain/$texdocpath"; + $texmfdist=`kpsewhich --expand-path=${qq}\$TEXMFDIST${qq}`; + chomp $texmfdist; + $distdocpath=join('/',"$texmfdist",basename($texdocpath,"")) + if (length $texmfdist); + # TeXLive has this texmf-doc + $texmfdoc=join('/',"$texmfmain-doc",basename($texdocpath,"")); + if (-e $texmfdoc) { + chomp $texmfdoc; + $docdocpath="$texmfdoc/$docdocpath"; + } + } +# find texmf-local/doc, if there is one + if ($rcfile eq $sysrc || $pathflagl == 1) { + $texmflocal=`kpsewhich --expand-path=${qq}\$TEXMFLOCAL${qq}`; + chomp $texmflocal; + if (length $texmflocal) { + # if LOCALDOCPATH is not explicitly defined, it equals TEXDOCPATH + unless (defined $localdocpath) { + $localdocpath=basename($texdocpath,""); + } + $localdocpath="$texmflocal/$localdocpath"; + } + } +# find user's $HOMETEXMF/doc, if there is one + if ($icall == 2 || $pathflagh == 1) { + $texmfhome=`kpsewhich --expand-path=${qq}\$HOMETEXMF${qq}`; + chomp $texmfhome; + if (length $texmfhome) { + # if HOMEDOCPATH is not explicitly defined, it equals TEXDOCPATH + unless (defined $homedocpath) { + $homedocpath=basename($texdocpath,""); + } + $homedocpath="$texmfhome/$homedocpath"; + } + } +# colours: create array + @tdcolors=split(' ',$tdcolors); + if (scalar @tdcolors != 4) { # if old texdocrc file is used + if (!(-e $myrc) || (-e $myrc && $icall == 2)) { + print "NOTE: Button colours not set in $rcfile; using defaults.\n"; + @tdcolors=('#d9d9d9','Black','#ececec','red'); + } + } + %butcol=('-background'=>$tdcolors[0], + '-foreground'=>$tdcolors[1], + '-activebackground'=>$tdcolors[2], + '-activeforeground'=>$tdcolors[3]); +# viewer: suppress viewer warnings/use $PAGER if no $txt_viewer is defined + $quiet=($quiet =~ /y/i || $quiet eq "1") ? 1 : 0; + if (!(defined $txt_viewer) && defined $ENV{PAGER}) { + $txt_viewer=$ENV{PAGER}; + } +# viewer: autostart viewer if listbox of search results contains only 1 item + $autoview=($autoview =~ /y/i || $autoview eq "1") ? 1 : 0; +# viewer: use text viewer to open files with unrecognized format + $xfmt_viewer=($xfmt_viewer =~ /y/i || $xfmt_viewer eq "1") ? 1 : 0; +# converter: output redirection flags for HTML/Text->PS converters + $htmlps_redir=($htmlps_redir =~ /(y|1)/i) ? 1 : 0; + $txtps_redir=($txtps_redir =~ /(y|1)/i) ? 1 : 0; +# for backward compatibility of converter/printer options + $dvips_conv.=" $dvips_opts" if ($dvips_opts); + $pdfps_conv.=" $pdfps_opts" if ($pdfps_opts); + $print_cmd.=" $print_opts" if ($print_opts); +} + +# determine resolution if xwininfo is available +# slightly modified from a patch contributed by Reinhard Kotucha +sub x_resolution { + my $x_res; + if ($IsWin32) { + $x_res = &GetScreenWidth; + } + else { + open(XINF,"xwininfo -root|") or return 1200; + while () { + chop; + if (/Width:/) { ($x_res=$_)=/Width:\s+(\d+)/; last; } + } + close(XINF); + } + return $x_res; +} + +# generate a random name for temporary files +sub randname { + my $namestr; + my @chars=("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); + my $time=time; + my $maxcnt=3+substr($time,-1); + for (my $i=0; $i<=$maxcnt; $i++) { $namestr.=$chars[rand(51)] } + my @tmp=split(/./,$time/$$); + $namestr.=$tmp[1]; + until (length($namestr) > 16) { $namestr.=int(rand(1000000)) } + return $namestr; +} + +# find index of an array entry +sub arrindex { + my @array=@_; + my $item=pop @array; + my $i=0; + foreach (@array) { + last if ($_ eq $item); + ++$i; + } + return $i; +} + +# clean up and exit +sub clean_exit { + foreach (@tmpfiles) { if (-e $_) { unlink $_; } } + exit; +} + +# alternative main window, launched for fatal error messages on startup +sub fatalmsg { + my($msg)=@_; + print STDERR $msg; # also print to stderr +# create frame for main window + my $main=new MainWindow; + $main->resizable(0,0); + $main->title("TeX Documentation Browser"); + $main->bind(''=>sub { exit }); + $main->bind(''=>sub { exit }); + my $msgframe=$main->Frame(-background=>"#ffcc99"); + my $cmdframe=$main->Frame; + $msgframe->pack(-side=>'top'); + $cmdframe->pack(-side=>'bottom',-fill=>'x'); +# make buttons for command frame + my $Qbut=$cmdframe->Button(-text=>'Kill',%butcol, + -command=>sub { exit })->pack(-fill=>'x'); +# define common default font for labels and text explicitly + my @deffont=$Qbut->configure(-font); +# ensure readability on high-res screens (suggested by R.Kotucha) + $deffont='Helvetica -16 bold' if &x_resolution > 1200; + $Qbut->configure(-font=>$deffont); + $msgframe->Label(-text=>'FATAL ERROR', + -font=>$deffont)->pack(-side=>'top', -fill=>'x'); +# get size of message text + my @dummy=split("\n",$msg); + my $nline=scalar @dummy; + my $msgwidth=0; + my $lline; + foreach (@dummy) { + $lline=length $_; + if ($lline > $msgwidth) { $msgwidth=$lline; } + } + my $message=$msgframe->Text(-relief=>'flat', + -font=>$deffont, + -height=>$nline, + -width=>$msgwidth)->pack(-side=>'top'); + $message->insert('end',$msg); + $message->configure(-state=>'disabled'); + MainLoop; +} + +if ($IsWin32) { + sub GetScreenWidth { + my $GetDeviceCaps = new Win32::API('gdi32', 'GetDeviceCaps', 'NN', 'N'); + my $HORZRES = 8; # from WinGDI.h + if(not defined $GetDeviceCaps) { + die "Can't import API GetDeviceCaps: $!\n"; + } + return $GetDeviceCaps->Call(0, $HORZRES); + } + + sub GetTempPath { + my $GetTempPath = new Win32::API('kernel32', 'GetTempPath', 'NP', 'N'); + if(not defined $GetTempPath) { + die "Can't import API GetTempPath: $!\n"; + } + my $lpBuffer = " " x 260; + + $GetTempPath->Call(80, $lpBuffer); + } + + sub ShellExecute { + my ($command, $file) = @_; + my $ShellExecute = new Win32::API('shell32', 'ShellExecute', 'NPPPPN', 'N'); + if(not defined $ShellExecute) { + die "Can't import API ShellExecute: $!\n"; + } + $ShellExecute->Call(0, $command, $file, '', '', 0); + } + + sub GetHomeDir { + my $home = $ENV{'HOME'}; + # Should check for CSIDL_... + return $home; + } +} +__END__ +Many TeX programmers provide more or less detailed manuals for +their programs or packages. They are usually available as .dvi, +.ps, .pdf, .html or plain text files (sometimes included in the +.sty files instead of a separate documentation file) and can be +accessed with this browser, which is simply an interface to find a +documentation more easily. It starts the respective viewer for +reading the selected documentation making use of a database file +which contains the path entries according to the current teTeX +texmf/doc structure; additional usage of a system-wide local and +of individual user texmf trees with corresponding databases is also +possible. +The documentations are grouped in several categories shown in the +main window; pressing one of its buttons lists all documentations +belonging to this topic. +The topic window lets you select one documentation file, view or +send it to the default printer. By right-clicking on the selected +item you get the complete path of the file. +The search button of the main window allows you to search the +database for a string; it does not search file names. Enter the +string and hit to start the search or to +cancel. Just hitting without typing something in will +show the full list of files in the database. +Defaults for the documentation root directory, the viewers, the +converters, certain options and the printer are set in the global +configuration file $sysrc. +However, each user can put a copy of it as .texdocrc into his home +directory to modify them according to his needs; modification or +generation of ~/.texdocrc can also be done with the Settings menu. +Additionally, the settings can be changed temporarily with this +menu. + +The following key shortcuts are defined for use with the browser: + Quit browser + Raise the Main window to the foreground + Search a keyword in database (case insensitive) + Cancel/close subwindow or search entry widget + View selected document (topic windows) + Print selected document (topic windows) + Open settings menu + Kill fatal error message window (same as + ) + Open this help + Equivalent to button press; + OK in selection menu and search + Next/previous widget + +There are the following command line options: + -a autostart viewer if a listbox of search results + contains only one item; can also be set in a + configuration file + -v disable suppression of viewer messages sent to + stderr and of certain permanent message popup + windows, in case this was not set in a + configuration file; default: off + +Some more information is available in the manpage of texdoctk. + +Comments and suggestions to: +Thomas Ruedas +tr@dlc.ku.dk or tex-k@tug.org +# Local Variables: +# mode: perl +# auto-fill-hook: do-auto-fill +# End: +# vim: ts=8 sw=4 noexpandtab -- cgit v1.2.3