% \iffalse meta-comment % % Copyright (C) 2007 by Scott Pakin % ------------------------------------------------------ % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3c or later is part of all distributions of LaTeX % version 2006/05/20 or later. % % \fi % % \iffalse %<*driver> \ProvidesFile{savetrees.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{savetrees} %<*package> [2007/12/23 v1.2a Pack as much text as possible onto each page] % % %<*driver> \documentclass{ltxdoc} \usepackage{array} \usepackage{dcolumn} \usepackage{tabularx} \EnableCrossrefs \CodelineIndex \setcounter{IndexColumns}{2} \RecordChanges \begin{document} \DocInput{savetrees.dtx} \end{document} % % \fi % % \CheckSum{294} % % \CharacterTable % {Upper-case \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 % Lower-case \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 % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v1.0}{2002/07/06}{Initial version} % % \GetFileInfo{savetrees.dtx} % % \DoNotIndex{\.,\@arabic,\@author,\@biblabel,\@clubpenalty,\@date,\@empty} % \DoNotIndex{\@enumctr,\@enumdepth,\@gobble,\@itemdepth,\@itemitem} % \DoNotIndex{\@latex@warning,\@m,\@mkboth,\@ne,\@noitemerr,\@openbib@code} % \DoNotIndex{\@title,\@toodeep,\@undefined,\addtolength,\advance} % \DoNotIndex{\baselineskip,\begin,\bibname,\c@enumiv,\chapter,\clubpenalty} % \DoNotIndex{\csname,\DeclareOption,\def,\descriptionlabel,\edef,\else,\end} % \DoNotIndex{\endcsname,\endlist,\expandafter,\fi,\footnote,\hss,\ifnum,\ifx} % \DoNotIndex{\itemindent,\labelwidth,\large,\let,\list,\llap,\MakeUppercase} % \DoNotIndex{\newcommand,\newenvironment,\newif,\newlength,\newpage,\null} % \DoNotIndex{\p@enumiv,\par,\ProcessOptions,\refname,\relax,\renewcommand} % \DoNotIndex{\renewenvironment,\romannumeral,\section,\setcounter} % \DoNotIndex{\setlength,\settowidth,\sfcode,\sloppy,\small} % \DoNotIndex{\textbf,\thanks,\the,\theenumiv,\thr@@,\usecounter,\vskip} % \DoNotIndex{\widowpenalty,\z@} % % ^^A ---------------------------------------------------------------------- % % \title{The \textsf{savetrees} package\thanks{This document % corresponds to \textsf{savetrees}~\fileversion, dated \filedate.}} % \author{Scott Pakin \\ \texttt{scott+st@pakin.org}} % % ^^A Define macros for typesetting/indexing package and program names. % \DeclareRobustCommand{\pkgname}[1]{^^A % \textsf{#1}^^A % \index{#1 (package)\actualchar\string\textsf{#1} (package)\encapchar usage}^^A % \index{packages:\levelchar#1\actualchar^^A % \string\textsf{#1}\encapchar usage}^^A % } % \DeclareRobustCommand{\progname}[1]{^^A % \texttt{#1}^^A % \index{#1 (program)\actualchar\string\texttt{#1} (program)\encapchar usage}^^A % \index{programs:\levelchar#1\actualchar^^A % \string\texttt{#1}\encapchar usage}^^A % } % % \sloppy % \maketitle % % \section{Introduction} % % The goal of the \pkgname{savetrees} package is to pack as much text as % possible onto each page of a \LaTeX{} document. Admittedly, this % makes the document far less attractive. Nevertheless, % \pkgname{savetrees} is a simple way to save paper when printing draft % copies of a document. It can also be useful when trying to meet a % tight page-length requirement for a conference or journal submission. % % Table~\ref{tbl:st-techniques} lists the various ways that % \pkgname{savetrees} compresses documents. Each of these techniques % can be selectively disabled through the use of package options. As % may be apparent from the table, only a few techniques are % beyond the capabilities of a \LaTeX{} novice. \pkgname{savetrees}'s % ``value added'' is the way that it aggregates a variety of % space-saving mechanisms into a single package and makes it easy to % manage the tradeoff between lower page count and higher readability. % % \begin{table} % \renewcommand{\arraystretch}{2} % \begin{tabularx}{\linewidth}{@{}Xl@{}} % \hline % Space-saving technique & % Implementation \\ % \hline % % Typeset section titles smaller and with less surrounding whitespace & % Use the \pkgname{titlesec} package \\ % % Reduce page margins & % Use the \pkgname{geometry} package \\ % % Reduce indentation and remove inter-item spacing from the various % list environments & % Redefine list environments \\ % % Relax float placement (more floats per page, increased ability to % share pages with text, etc.) & % Reassign \LaTeXe{} variables \\ % % Decrease paragraph indentation & % Reassign \texttt{\string\parindent} \\ % % Typeset document title with smaller fonts and with less surrounding % whitespace & % Redefine \texttt{\string\maketitle} \\ % % Reduce interline spacing & % Reassign \texttt{\string\baselinestretch} \\ % % Discourage \TeX\ from allowing the last line of a paragraph to % contain only a single word & % Reassign \texttt{\string\looseness} \\ % % Typeset bibliographies smaller and with no inter-item spacing & % Redefine \texttt{thebibliography} \\ % \hline % \end{tabularx} % \caption{\pkgname{savetrees}'s space-saving techniques} % \label{tbl:st-techniques} % \end{table} % % In addition to providing a \LaTeXe{} style file, the % \pkgname{savetrees} package also provides a \BibTeX{} style file. % |savetrees.bst| exhibits the following salient differences from % |plain.bst|: % % \begin{itemize} % \item Abbreviations are used wherever possible: % % \begin{center} % \begin{tabular}{l@{\quad$\Longrightarrow$\quad}l} % chapter & chap. \\ % edition & ed. \\ % editor \emph{or} editors & ed.\ \emph{or} eds. \\ % January, February,~\dots & Jan., Feb.,~\dots \\ % page \emph{or} pages & p.\ \emph{or} pp. \\ % Technical Report & Tech. Rep. \\ % \end{tabular} % \end{center} % % \item At most two authors are listed. The remainder are replaced by % ``et al.'' % % \item Authors' names are abbreviated to their initials plus surname % (e.g.,~``S.~D.~Pakin''). % \end{itemize} % % \noindent % In addition, |savetrees.bst| does not normally typeset |NOTE| fields, % although it can be instructed to via a \pkgname{savetrees} package % option. % % Finally, the \pkgname{savetrees} package includes a % Perl\index{Perl|usage} script called ``|makethin|'', which % automatically generates narrower versions of \TeX{} fonts plus % configuration files for Dvips and pdf\LaTeX. % % \section{\texttt{savetrees.sty}---reduce document whitespace} % % To use |savetrees.sty|, merely load it into a document by putting % ``|\usepackage{savetrees}|'' in the document's preamble. By default, % all of \pkgname{savetrees}'s space-saving techniques are enabled. % However, package options can disable any features that violate given % formatting requirements, that conflict with other \LaTeXe{} packages, % or that you simply consider excessively ugly. \pkgname{savetrees} % supports the following options: % % ^^A Display and index a package option. % \newcommand{\pkgoption}[1]{^^A % \textsf{#1}^^A % \index{#1 (package option)\actualchar^^A % \string\textsf{#1} (package option)\encapchar usage}^^A % \index{package options:\levelchar#1\actualchar^^A % \string\textsf{#1}\encapchar usage}^^A % } % % \begin{description} % \item[\pkgoption{normalsections}] Don't modify section headers. % % \item[\pkgoption{normalmargins}] Don't modify page margins. % % \item[\pkgoption{normallists}] Don't modify the |itemize|, % |enumerate|, or |description| environments. % % \item[\pkgoption{normalfloats}] Don't modify \LaTeXe's float % parameters. % % \item[\pkgoption{normalindent}] Don't modify paragraph indentation. % % \item[\pkgoption{normaltitle}] Don't modify the formatting of the % document title. % % \item[\pkgoption{normalleading}] Don't modify interline spacing. % % \item[\pkgoption{normallooseness}] Don't modify paragraph looseness. % % \item[\pkgoption{normalbib}] Don't modify bibliography formatting. % % \item[\pkgoption{normalbibnotes}] Don't omit |NOTE| fields from the % bibliography (only meaningful with the \pkgname{savetrees} % bibliography style). % \end{description} % % For example, to keep page margins and interline spacing as they are % but save space everyplace else, you should put the following % |\usepackage| line in your document's preamble: % % \begin{verbatim} % \usepackage[normalmargins,normalleading]{savetrees} % \end{verbatim} % % % \section{\texttt{savetrees.bst}---abbreviate bibliographic information} % % One of the advantages of a tool like \BibTeX{} is that the % bibliographic database can---and should---contain complete % bibliographic information for each reference, while style files % determine the subset of that information that is actually typeset. % |savetrees.bst| saves space by truncating |AUTHOR| fields to two % authors plus ``et al.'', listing authors by initials and surname only, % abbreviating the |MONTH| field to three letters, and (by default) % omitting the |NOTE| field altogether. % % To use the |savetrees.bst|, simply add % ``|\bibliographystyle{savetrees}|'' to your document (or replace an % existing |\bibliographystyle|). Then, to give |savetrees.bst|---or % \emph{any} \BibTeX{} style file---maximum flexibility, you should obey % the following rules when writing your |.bib| file: % % \begin{enumerate} % \item Use the three-letter month macros defined by virtually all % \BibTeX{} style files instead of spelling out month names % explicitly: % % \begin{tabularx}{\linewidth}{@{}lX@{}} % \hline % Good: & \texttt{MONTH = sep,} \\ % & Can be typeset as ``September'', ``Sept.'', ``SEP'', % ``Septiembre'', etc. \\ % % Bad: & \texttt{MONTH = \{September\},} \\ % & Can be typeset only as ``September''. \\ % \hline % \end{tabularx} % % \item Include authors' full names (or as much of each name as is % available); let \BibTeX{} abbreviate as necessary: % % \begin{tabularx}{\linewidth}{@{}lX@{}} % \hline % Better: & \texttt{AUTHOR = \{Rufus Xavier Sarsaparilla\}}, \\ % & Can be either typeset in full or abbreviated to % ``Rufus~X. Sarsaparilla'', ``R.~X. Sarsaparilla'', etc. \\ % % Worse: & \texttt{AUTHOR = \{R.~X. Sarsaparilla\}}, \\ % & Can be typeset as ``R.~X. Sarsaparilla''---or even a more % abbreviated form---but can't be expanded to the full name. \\ % \hline % \end{tabularx} % % \item Include the names of \emph{all} authors; let \BibTeX{} decide % where to truncate the list: % % \begin{tabularx}{\linewidth}{@{}lX@{}} % \hline % % Good: & \texttt{AUTHOR = \{Rufus Xavier Sarsaparilla and % Rafaella Gabriela Sarsaparilla and Albert Andreas % Armadillo\},} \\ % & All authors can be named, or the list can be truncated at any % point with ``et al.'', ``and others'', or whatever. \\ % % Bad: & \texttt{AUTHOR = \{Rufus Xavier Sarsaparilla and others\},} \\ % & At most one author can be named, but ``and others'' can still % be replaced by ``et al.''\ or a different phrase, the font % can be varied, and the author's name can be abbreviated, as in % the previous rule. \\ % Worse: & \texttt{AUTHOR = \{\{Rufus Xavier Sarsaparilla, et al.\}\},} \\ % & Can be typeset only precisely as ``Rufus Xavier % Sarsaparilla, et al.'' \\ % \hline % \end{tabularx} % \end{enumerate} % % The \pkgname{savetrees} \BibTeX{} style utilizes the same fields as % the standard \BibTeX{} styles (|plain|, |alpha|, |abbrv|, |unsrt|, % etc.), with the exception that the |NOTE| field is normally % suppressed. To include |NOTE| fields in your Bibliography/References % sections, pass the \pkgoption{normalbibnotes} option to the % \pkgname{savetrees} \LaTeX{} style file. % % |savetrees.bst| can't normally be used independently of % |savetrees.sty|, because the former typesets |NOTE| fields within a % |\savetreesbibnote{|\dots|}| call, which is defined by the latter. % If you desperately want to use |savetrees.bst| without having to load % |savetrees.sty|, then you should examine the definition of the % |\savetreesbibnote| macro % \makeatletter % \@ifundefined{r@code:stbn-begin}{^^A % in \texttt{savetrees.sty}. % }{^^A % on page~\pageref{code:stbn-begin} of this document^^A % \ifcodeline@index % ~(code lines~\ref{code:stbn-begin}--\ref{code:stbn-end})^^A % \fi. % } % \makeatother % % % \section{\texttt{makethin}---make thinner versions of \TeX{} fonts} % % \paragraph{Question:} % What's the narrowest font? % % \paragraph{Answer:} % It depends upon how you measure. Table~\ref{tbl:font-widths} % shows, for various fonts, the width in points of 1000 lowercase % letters with relative frequencies chosen to match ``typical'' % English text. There are 130~e's, 93~t's, 78~n's, 77~r's, and so forth % down the frequency distribution. According to the table, Times Roman % is statistically likely to be the best typeface for maximizing the % amount of text on the page. However, Times Roman may not be the % narrowest for \emph{your} document; you'll have to experiment and see. % % \newcommand{\thousandletters}{^^A % aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^^A % bbbbbbbbb^^A % cccccccccccccccccccccccccccccc^^A % dddddddddddddddddddddddddddddddddddddddddddd^^A % eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee^^A % ffffffffffffffffffffffffffff^^A % gggggggggggggggg^^A % hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh^^A % iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii^^A % jj^^A % kkk^^A % lllllllllllllllllllllllllllllllllll^^A % mmmmmmmmmmmmmmmmmmmmmmmmm^^A % nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn^^A % oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo^^A % ppppppppppppppppppppppppppp^^A % qqq^^A % rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr^^A % sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss^^A % ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt^^A % uuuuuuuuuuuuuuuuuuuuuuuuuuu^^A % vvvvvvvvvvvvv^^A % wwwwwwwwwwwwwwww^^A % xxxxx^^A % yyyyyyyyyyyyyyyyyyy^^A % z^^A % } % % \newlength{\thousandwidth} % \makeatletter % \newcommand{\fontwidth}[1]{^^A % \settowidth{\thousandwidth}{\fontfamily{#1}\selectfont\thousandletters}^^A % \divide\thousandwidth by 1000\relax % \strip@pt\thousandwidth % } % \makeatother % % \begin{table}[htbp] % \centering % \begin{tabular}{@{}l>{\sffamily\selectfont}l@{\qquad}D{.}{.}{-1}@{}} % \hline % Typeface & % \multicolumn{1}{l}{Package} & % \multicolumn{1}{l@{}}{Avg. width (pt.)} \\ % \hline % % Times Roman & times & \fontwidth{ptm} \\ % Computer Modern & \multicolumn{1}{l}{(default)} & \fontwidth{cmr} \\ % Charter & charter & \fontwidth{bch} \\ % Helvetica & helvetic & \fontwidth{phv} \\ % Palatino & palatino & \fontwidth{ppl} \\ % Utopia & utopia & \fontwidth{put} \\ % New Century Schoolbook & newcent & \fontwidth{pnc} \\ % Avant Garde & avantgar & \fontwidth{pag} \\ % Bookman & bookman & \fontwidth{pbk} \\ % Courier & courier & \fontwidth{pcr} \\ % \hline % \end{tabular} % \caption{Common fonts sorted by increasing width} % \label{tbl:font-widths} % \end{table} % % We can do better than merely \emph{selecting} a narrow font, though. % We can \emph{generate} a narrower version of an existing font. The % idea is to present \TeX{} with font metrics that indicate thinner % characters and to tell Dvips to use the PostScript % ``\texttt{ExtendFont}'' operator to compress all of the glyphs. The % \pkgname{savetrees} package comes with a Perl\index{Perl|usage} script, % \progname{makethin}, which automates the task of generating narrow % font variants. From a typography viewpoint, the results are % deplorable, as the glyphs are simply squeezed rather than % optically scaled to a new width. But from the perspective of trying % to pack more text onto a page with minimal effort, \progname{makethin} % can be quite efficacious. % % \DeleteShortVerb{\|} % \begin{center} % \begin{tabular}{|p{0.66\linewidth}|} % \multicolumn{1}{c}{\textbf{Warning}} \\ % \hline % To avoid confusion with the original font-metric files, do not % distribute the \texttt{.tfm} or \texttt{.vf} files generated by % \progname{makethin} unless you rename them first. \\ % \hline % \end{tabular} % \end{center} % \MakeShortVerb{\|} % % In addition to requiring Perl\index{Perl|usage}, \progname{makethin} % depends upon two helper programs: \progname{kpsewhich} and % \progname{dvitype}. \progname{kpsewhich} searches the \TeX{} % installation directory for a given file or file type. While % \progname{kpsewhich} is a standard part of Kpathsea-based \TeX{} % distributions, such as te\kern-.1em\TeX{}, it does not normally function on % non-Kpathsea based distributions, such as MiK\TeX{}.\footnote{I have % no current plans to port \progname{makethin} to non-Kpathsea based % \TeX{} distributions, but volunteers to do the work are certainly welcome.} % \progname{dvitype} outputs a DVI file in a textual format that's easy % for \progname{makethin} to process. \progname{makethin} extracts font % names from lines like the following: % % \begin{verbatim} % Font 44: cmtt10---loaded at size 655360 DVI units % Font 43: cmtt12 scaled 1200---loaded at size 943718 DVI units % Font 33: cmss10---loaded at size 655360 DVI units % \end{verbatim} % % The \progname{makethin} script contains documentation in POD\index{POD % (Plain Old Documentation)|usage} (Plain Old Documentation) format. % This can be extracted using \progname{makethin}'s |--man| or % |--man-ps| options, as described below, or any of % Perl's\index{Perl|usage} ``\texttt{pod2}\meta{something}'' converters, % such as \progname{pod2text} or \progname{pod2html}. Beginning on the % following page is the \progname{makethin} documentation, as extracted % by \progname{pod2latex} (with some minor formatting modifications). % % ^^A Adjust some lengths to be more amenable to formatting man pages. % \clearpage % \let\origparindent=\parindent % \setlength{\parindent}{0pt} % \let\origparskip=\parskip % \setlength{\parskip}{0.5\baselineskip} % % ^^A Define commands to index short and long makethin options. % \newcommand{\thinoptidxS}[1]{^^A % \index{#1\actualchar\texttt{-{}#1} (\texttt{makethin} option)\encapchar usage}^^A % \index{makethin options\actualchar\texttt{makethin} options:\levelchar % #1\actualchar\texttt{-{}#1}\encapchar usage}} % \newcommand{\thinoptidxL}[1]{^^A % \index{#1\actualchar\texttt{-{}-{}#1} (\texttt{makethin} option)\encapchar usage}^^A % \index{makethin options\actualchar\texttt{makethin} options:\levelchar % #1\actualchar\texttt{-{}-{}#1}\encapchar usage}} % \newcommand{\thinoptidx}[2]{\thinoptidxS{#1}\thinoptidxL{#2}} % % ^^A Define commands for displaying and indexing file names. % \newcommand{\thinextidx}[1]{^^A % \textit{.#1}\index{#1 files=\string\texttt{.#1} files\encapchar usage}} % \newcommand{\thinfileidx}[1]{^^A % \textit{#1}\index{#1=\string\texttt{#1}\encapchar usage}} % % ^^A Define a command for displaying and indexing program names. % \newcommand{\thinprogidx}[1]{^^A % \textbf{#1}^^A % \index{#1 (program)\actualchar\string\texttt{#1} (program)\encapchar usage}^^A % \index{programs:\levelchar#1\actualchar^^A % \string\texttt{#1}\encapchar usage}^^A % } % % \subsection*{NAME} % makethin---make thinner versions of PostScript fonts for \TeX{} % % \subsection*{SYNOPSIS} % makethin % \thinoptidx{v}{verbose}^^A % \thinoptidx{h}{help}^^A % \thinoptidx{x}{xscale}^^A % \thinoptidx{C}{cleanfirst}^^A % \thinoptidx{c}{clean}^^A % \thinoptidx{P}{config}^^A % \thinoptidx{p}{pdftex}^^A % \thinoptidx{m}{extramaps}^^A % \thinoptidx{k}{skipfonts}^^A % \thinoptidx{b}{basename}^^A % \thinoptidx{e}{extrafonts}^^A % \thinoptidxL{man}^^A % \thinoptidxL{man-ps}^^A % {\tt [}{\bf {\tt --}verbose}{\tt ]} % {\tt [}{\bf {\tt --}xscale}={\em factor\/}{\tt ]} % {\tt [}{\bf {\tt --}cleanfirst}{\tt ]} % {\tt [}{\bf {\tt --}clean}{\tt ]} % {\tt [}{\bf {\tt --}config}={\em extension\/}{\tt ]} % {\tt [}{\bf {\tt --}pdftex}{\tt ]} % {\tt [}{\bf {\tt --}extramaps}={\em file\/}{\tt [},{\em file\/}{\tt ]}...{\tt ]} % {\tt [}{\bf {\tt --}skipfonts}={\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]} % {\tt [}{\bf {\tt --}basename}={\em string\/}{\tt ]} % {\tt [}{\bf {\tt --}extrafonts}={\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]} % \thinextidx{dvi}{\em file\/} % % makethin % {\tt [}{\bf {\tt --}verbose}{\tt ]} % {\bf {\tt --}help} % % makethin % {\bf {\tt --}man}={\em man page\/} \verb+|+ {\bf {\tt --}man-ps}={\em PostScript file\/} % % \subsection*{DESCRIPTION} % \thinprogidx{makethin} produces thinner versions of PostScript fonts for use % with \TeX{}/\LaTeX{} and Dvips. More precisely, it finds all of % the \thinextidx{tfm} and \thinextidx{vf} fonts referred to by a % \thinextidx{dvi} file, scales the character-width metrics by a given % amount, and writes new \thinextidx{tfm} and \thinextidx{vf} files to % the current directory. \thinprogidx{makethin} then generates a customized % \thinextidx{map} and {\em config\/}^^A % \index{config files=\texttt{config} files|usage} % file for Dvips and, optionally, a customized % \thinfileidx{pdftex.cfg} file for pdf\LaTeX{}. % % The general procedure for using \thinprogidx{makethin} is as follows: % % \begin{enumerate} % % \item % Run \thinprogidx{latex} on your \thinextidx{tex} source file to produce a % \thinextidx{dvi} file. % % \item % Run \thinprogidx{makethin} on the \thinextidx{dvi} file to create new % \thinextidx{tfm}, \thinextidx{vf}, \thinextidx{map}, and % {\em config\/}\index{config files=\texttt{config} files|usage} files. % % \item % Re-run \thinprogidx{latex} on your \thinextidx{tex} source file to typeset it % with the new fonts. % % \item % Run \thinprogidx{dvips} on the \thinextidx{dvi} file, specifying the newly % generated \thinextidx{map} and % {\em config\/}\index{config files=\texttt{config} files|usage} files, % to produce a \thinextidx{ps} file. % % \end{enumerate} % % \subsection*{OPTIONS}^^A % % The following are the command-line options that \thinprogidx{makethin} accepts: % % \begin{description} % % \item[{\bf -v}, {\bf {\tt --}verbose}]^^A % \thinoptidx{v}{verbose}^^A % \hfil\\ % Increase the verbosity of the status output. {\bf {\tt --}verbose} can be % specified multiple times on the same command line, with each % {\bf {\tt --}verbose} futher increasing the verbosity. (Currently, two % {\bf {\tt --}verbose}s have maximal impact.) % % \item[{\bf -h}, {\bf {\tt --}help}]^^A % \thinoptidx{h}{help}^^A % \hfil\\ % Display basic usage information. When combined with {\bf {\tt --}verbose}, % additionally describes each of the command-line options. When % combined with a second {\bf {\tt --}verbose}, {\bf {\tt --}help} outputs the complete % \thinprogidx{makethin} manual page. % % \item[{\bf -x} {\em factor\/}, {\bf {\tt --}xscale}={\em factor\/}]^^A % \thinoptidx{x}{xscale}^^A % \hfil\\ % Scale fonts horizontally by a factor of {\em factor\/}. The default, % {\tt 0.5}, produces nearly illegible fonts but is useful for verifying % that \thinprogidx{makethin} actually worked. Factors of {\tt 0.90}--{\tt 0.99} % are more reasonable. % % \item[{\bf -C}, {\bf {\tt --}cleanfirst}]^^A % \thinoptidx{C}{cleanfirst}^^A % \hfil\\ % Delete all files generated by a previous run of \thinprogidx{makethin} before % generating new ones. % % \item[{\bf -c}, {\bf {\tt --}clean}]^^A % \thinoptidx{c}{clean}^^A % \hfil\\ % Delete all files generated by a previous run of \thinprogidx{makethin} and then % exit. % % \item[{\bf -P} {\em extension\/}, {\bf {\tt --}config}={\em extension\/}]^^A % \thinoptidx{P}{config}^^A % \hfil\\ % Process all of the \thinextidx{map} files named in % {\em config.\/}{\em extension\/}^^A % \index{config files=\texttt{config} files|usage} % (found in Dvips's configuration directory). {\bf {\tt --}config} % can be specified multiple times on the same command line. % \thinfileidx{config.ps} is processed implicitly. The same {\bf -P} % arguments that you would normally pass to \thinprogidx{dvips} to utilize % entirely PostScript fonts (e.g., {\bf -Pcmz} and {\bf -Pamz}) should % also be passed to \thinprogidx{makethin}. % % \item[{\bf -p}, {\bf {\tt --}pdftex}]^^A % \thinoptidx{p}{pdftex}^^A % \hfil\\ % In addition to producing the files needed by Dvips, also produce a % \thinfileidx{pdftex.cfg} file that is usable by pdf\LaTeX{}. % % \item[{\bf -m} {\em file\/}{\tt [},{\em file\/}{\tt ]}...{\tt ]}, {\bf {\tt --}extramaps}={\em file\/}{\tt [},{\em file\/}{\tt ]}...{\tt ]}]^^A % \thinoptidx{m}{extramaps}^^A % \hfil\\ % Additionally process the named Dvips \thinextidx{map} files even if they're % not referred to by any of the {\em config.\/}{\em extension\/} files^^A % \index{config files=\texttt{config} files|usage} % specified with {\bf {\tt --}config}. {\bf {\tt --}extramaps} can be % specified multiple times on the same command line. % % \item[{\bf -k} {\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]}, {\bf {\tt --}skipfonts}={\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]}]^^A % \thinoptidx{k}{skipfonts}^^A % \hfil\\ % Don't make thin versions of the named fonts, even if they're listed in % the \thinextidx{dvi} file. Fonts are named using the Berry scheme (i.e., % ``{\tt pcrr8a}'' as opposed to ``{\tt COURB}'' or ``{\tt Courier-Bold}''). % {\bf {\tt --}skipfonts} can be specified multiple times on the same command % line. % % \item[{\bf -b} {\em string\/}, {\bf {\tt --}basename}={\em string\/}]^^A % \thinoptidx{b}{basename}^^A % \hfil\\ % Tell \thinprogidx{makethin} to use {\em string\/} as the base name for the Dvips % configuration files it generates. The default is ``{\tt thin}'', so % \thinprogidx{makethin} normally produces files named \thinfileidx{config.thin} and % \thinfileidx{thin.map}, but {\bf {\tt --}basename} enables alternate % filenames to be used. % % \item[{\bf -e} {\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]}, {\bf {\tt --}extrafonts}={\em font\/}{\tt [},{\em font\/}{\tt ]}...{\tt ]}]^^A % \thinoptidx{e}{extrafonts}^^A % \hfil\\ % Make thin versions of the named fonts, even if they're not listed in % the \thinextidx{dvi} file. Fonts are named using the Berry scheme (i.e., % ``{\tt pcrr8a}'' as opposed to ``{\tt COURB}'' or ``{\tt Courier-Bold}''). % {\bf {\tt --}extrafonts} can be specified multiple times on the same command % line. % % \item[{\bf {\tt --}man}={\em man page\/}]^^A % \thinoptidxL{man}^^A % \hfil\\ % Create a Unix manual page for \thinprogidx{makethin} in the standard, $\ast$roff % format. Typical usage is: % \begin{verbatim} % makethin --man=/usr/man/man1/makethin.1 % \end{verbatim} % % \item[{\bf {\tt --}man-ps}={\em PostScript file\/}]^^A % \thinoptidxL{man-ps}^^A % \hfil\\ % Create a Unix manual page for \thinprogidx{makethin} in PostScript format instead % of $\ast$roff format. % % \end{description} % % In addition to the options listed above, \thinprogidx{makethin} has a required % argument, which is the name of a \thinextidx{dvi} file from which to read font % information. % % \subsection*{EXAMPLES} % The following are some examples of how to use \thinprogidx{makethin}. % % \subsubsection*{A typical case}^^A % % First, we need to produce {\em myfile.dvi\/}, because that contains the % font information that \thinprogidx{makethin} will read: % \begin{verbatim} % latex myfile.tex % \end{verbatim} % % Next, we invoke \thinprogidx{makethin}, telling it to process % \thinfileidx{config.cmz} (which, in turn, causes % \thinfileidx{psfonts.cmz} to be processed), This tells \thinprogidx{makethin} % to use PostScript versions of the Computer Modern fonts instead of % bitmapped versions. (\thinprogidx{makethin} can scale only PostScript fonts.) % We also specify maximal verbosity: % \begin{verbatim} % makethin -Pcmz --verbose --verbose myfile.dvi % \end{verbatim} % % The preceding line reads \thinfileidx{config.ps}, % \thinfileidx{config.cmz}, various map files, such as % \thinfileidx{psfonts.map} and \thinfileidx{psfonts.cmz}, and all of % the \thinextidx{tfm} and \thinextidx{vf} files mentioned in {\em % myfile.dvi\/}. It then writes \thinfileidx{config.thin}, % \thinfileidx{thin.map}, and modified versions of all of the % \thinextidx{tfm} and \thinextidx{vf} files to the current directory. % % We now need to re-run \thinprogidx{latex}, so it can produce a new {\em myfile.dvi\/} % using the thinner metrics listed in the current directory's \thinextidx{tfm} % and \thinextidx{vf} files: % \begin{verbatim} % latex myfile.tex % \end{verbatim} % % Finally, we produce a PostScript file using the newly generated using % \thinfileidx{config.thin} and \thinfileidx{thin.map} files: % \begin{verbatim} % dvips -Pthin myfile.dvi -o myfile.ps % \end{verbatim} % % If all worked according to plan, {\em myfile.ps\/} should be typeset using % extremely thin (half-width) versions of its original fonts. % % \subsubsection*{Producing thin fonts for use in pdf\LaTeX{}}^^A % \index{pdfLaTeX=pdf\LaTeX{}|(usage} % % Because \thinprogidx{makethin} can read only \thinextidx{dvi} files, not % \thinextidx{pdf} files, we first need to produce a \thinextidx{dvi} % file: % \begin{verbatim} % latex too-long.tex % \end{verbatim} % % {\em too-long.dvi\/} is typeset entirely using the Times family of % fonts. Therefore, we don't need to specify {\bf -Pcmz}. However, % {\bf pdflatex} normally embeds Times, thereby precluding {\bf % makethin}'s ability to scale it. (\thinprogidx{makethin} requires a {\em % .pfb\/} font file in order to scale the corresponding font.) % Fortunately, {\em /usr/share/texmf/dvips/config/ar-std-urw-kb.map\/}^^A % \index{ar-std-urw-kb.map=\texttt{ar-std-urw-kb.map}|usage} % already contains the proper mapping of \TeX{} names to \thinextidx{pfb} % files for Times, Courier, and Helvetica. We can tell \thinprogidx{makethin} % to use that file: % \begin{verbatim} % makethin --cleanfirst -v -v too-long.dvi --pdftex --xscale=0.9 % --extramaps=/usr/share/texmf/dvips/config/ar-std-urw-kb.map % \end{verbatim} % % In the preceding line, we changed the scaling factor from the default % of 0.5 to a more reasonable 0.9. Because we had some 0.5-scaled % \thinextidx{tfm} and \thinextidx{vf} files left over from the previous % example, we specified {\bf {\tt --}cleanfirst} to delete those old % font files. We specified {\bf {\tt --}pdftex} to make \thinprogidx{makethin} % produce a local \thinfileidx{pdftex.cfg} file. And we told {\bf % makethin} where to find the extra map file needed to force the usage % of \thinextidx{pfb} files. % % All that's left is to run {\bf pdflatex} to produce a \thinextidx{pdf} % file: % \begin{verbatim} % pdflatex too-long.tex % \end{verbatim} % % {\bf pdflatex} will read the font metric files (\thinextidx{tfm} and % \thinextidx{vf}) and \thinfileidx{pdftex.cfg} from the current % directory. This will tell it to load \thinfileidx{thin.map}, which % specifies the scaling factor. The result should be a document with % each character squeezed to 90\% of its original width. % % \index{pdfLaTeX=pdf\LaTeX{}|)} % % \subsection*{FILES} % \begin{description} % % \item[\thinprogidx{perl}]^^A % \index{Perl|usage}^^A % \hfil\\ % interpreter/compiler needed to run the \thinprogidx{makethin} script % % \item[\thinprogidx{kpsewhich}]^^A % \hfil\\ % finds files within the \TeX{} directory tree % % \item[\thinprogidx{dvitype}]^^A % \hfil\\ % outputs the typesetting commands contained within a \thinextidx{dvi} file % % \item[{\em $\ast$.tfm\/} and {\em $\ast$.vf\/}]^^A % \index{tfm files=\texttt{.tfm} files|usage}^^A % \index{vf files=\texttt{.vf} files|usage}^^A % \hfil\\ % \TeX{} font metrics and virtual fonts--metrics specifying the width of % each character in a font % % \item[{\em config.$\ast$\/}]^^A % \index{config files=\texttt{config} files|usage}^^A % \hfil\\ % Dvips configuration files, each containing (among other % information) a list of font-map files % % \item[{\em psfonts.$\ast$\/}, {\em $\ast$.map\/}]^^A % \index{psfonts.*=\texttt{psfonts.*}|usage}^^A % \index{map files|usage}^^A % \hfil\\ % Dvips font-map files, which map \TeX{} font names to PostScript % font names and \thinextidx{pfb} files % % \item[\thinfileidx{pdftex.cfg}]^^A % \hfil\\ % pdf\TeX{} and pdf\LaTeX{} configuration files, each containing (among % other information) a list of font-map files % % \item[\thinprogidx{groff}]^^A % \hfil\\ % used by {\bf {\tt --}man-ps} to produce a PostScript version of the % Unix manual page for \thinprogidx{makethin} % % \end{description} % % \subsection*{RESTRICTIONS}^^A % % The most serious restriction is that \thinprogidx{makethin} doesn't % work on Computer Modern Roman 10pt. (\thinfileidx{cmr10})---the % default \TeX{}/\LaTeX{} font. The reason, I believe, is that \TeX{} % and \LaTeX{} preload that font's metrics ({\em cmr10.tfm\/}) and % therefore ignore the scaled \thinfileidx{cmr10.tfm} on disk. It may % be possible to work around this limitation by copying % \thinfileidx{cmr10.tfm} to a new name and convincing \LaTeX{} to use that % name where it would otherwise have used \thinfileidx{cmr10.tfm}. % However, it's much easier merely to use a different font family (e.g., % with ``{\tt \char`\\usepackage\{times\}}'') for typesetting your % document when you know you want to run \thinprogidx{makethin}. % % \subsection*{SEE ALSO} % {\em dvips\/}(1), % {\em latex\/}(1), % {\em pdflatex\/}(1), % the \LaTeX{} {\tt savetrees} package % % \subsection*{AUTHOR} % Scott Pakin, {\em scott+st@pakin.org\/} % % \clearpage % \setlength{\parskip}{\origparskip} % \setlength{\parindent}{\origparindent} % % \StopEventually{\PrintChanges\PrintIndex} % % ^^A Define macros for labeling lines of code. % \makeatletter % \newcommand{\labelprevcodeline}[1]{^^A % \begingroup % \edef\@currentlabel{\the\c@CodelineNo}^^A % \label{#1}^^A % \endgroup % } % \newcounter{nextCodelineNo} % \newcommand{\labelnextcodeline}[1]{^^A % \begingroup % \setcounter{nextCodelineNo}{\c@CodelineNo}^^A % \addtocounter{nextCodelineNo}{1}^^A % \edef\@currentlabel{\thenextCodelineNo}^^A % \label{#1}^^A % \endgroup % } % \makeatother % % \section{Implementation of \texttt{savetrees.sty}} % % This section lists the complete, commented source code for the % \pkgname{savetrees} package. Although reading this section---and the % subsequent implementation sections---is not necessary for understanding % how to use \pkgname{savetrees}, it may be a useful teaching tool % for \LaTeX{} newcomers. For instance, if you want narrow page % margins, but find \pkgname{savetrees}'s defaults to be \emph{too} % narrow, then seeing how \pkgname{savetrees} alters margins may be % instructive for learning how to select your own page margins. % % \bigskip % We start by telling \pkgname{DocStrip} that this is where |savetrees.sty| % begins: % \begin{macrocode} %<*package> % \end{macrocode} % % \subsection{Option processing} % % By default, \pkgname{savetrees} tries to make documents extremely % dense. However, this also makes them rather ugly. The package % options defined in this section let the author specify which % space-saving routines are unacceptably grotesque and should not be % utilized. % % We now define one new |\if| statement for each package option and define % each package option to set the corresponding ``|\@st@normal@|\dots'' % flag to~\emph{true}. % % ^^A Define a macro to index an option declaration that appeared on the % ^^A previous code line. % \makeatletter % \newcommand{\pkgoptiondecl}[1]{^^A % \special@index{#1 (package option)\actualchar^^A % \string\textsf{#1} (package option)\encapchar main}^^A % \special@index{package options:\levelchar#1\actualchar^^A % \string\textsf{#1}\encapchar main}^^A % } % \makeatother % % \begin{macro}{\if@st@normal@sections} % \begin{macro}{\@st@normal@sectionstrue} % \begin{macro}{\@st@normal@sectionsfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to section titles. % \begin{macrocode} \newif\if@st@normal@sections \DeclareOption{normalsections}{\@st@normal@sectionstrue} % \end{macrocode} % \pkgoptiondecl{normalsections} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@margins} % \begin{macro}{\@st@normal@marginstrue} % \begin{macro}{\@st@normal@marginsfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to page margins. % \begin{macrocode} \newif\if@st@normal@margins \DeclareOption{normalmargins}{\@st@normal@marginstrue} % \end{macrocode} % \pkgoptiondecl{normalmargins} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@lists} % \begin{macro}{\@st@normal@liststrue} % \begin{macro}{\@st@normal@listsfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to the various list environments. % \begin{macrocode} \newif\if@st@normal@lists \DeclareOption{normallists}{\@st@normal@liststrue} % \end{macrocode} % \pkgoptiondecl{normallists} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@floats} % \begin{macro}{\@st@normal@floatstrue} % \begin{macro}{\@st@normal@floatsfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to \LaTeX's float-placement parameters. % \begin{macrocode} \newif\if@st@normal@floats \DeclareOption{normalfloats}{\@st@normal@floatstrue} % \end{macrocode} % \pkgoptiondecl{normalfloats} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@indent} % \begin{macro}{\@st@normal@indenttrue} % \begin{macro}{\@st@normal@indentfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to paragraph indentation. % \begin{macrocode} \newif\if@st@normal@indent \DeclareOption{normalindent}{\@st@normal@indenttrue} % \end{macrocode} % \pkgoptiondecl{normalindent} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@title} % \begin{macro}{\@st@normal@titletrue} % \begin{macro}{\@st@normal@titlefalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to title formatting. % \begin{macrocode} \newif\if@st@normal@title \DeclareOption{normaltitle}{\@st@normal@titletrue} % \end{macrocode} % \pkgoptiondecl{normaltitle} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@leading} % \begin{macro}{\@st@normal@leadingtrue} % \begin{macro}{\@st@normal@leadingfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to interline spacing. This spacing is known as % ``leading'' because of the additional strips of lead placed between % lines in the days of metal type. % \begin{macrocode} \newif\if@st@normal@leading \DeclareOption{normalleading}{\@st@normal@leadingtrue} % \end{macrocode} % \pkgoptiondecl{normalleading} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@looseness} % \begin{macro}{\@st@normal@loosenesstrue} % \begin{macro}{\@st@normal@loosenessfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to \TeX's paragraph looseness (i.e.,~the number of lines % by which \TeX\ is instructed to shrink each paragraph). % \begin{macrocode} \newif\if@st@normal@looseness \DeclareOption{normallooseness}{\@st@normal@loosenesstrue} % \end{macrocode} % \pkgoptiondecl{normallooseness} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@bib} % \begin{macro}{\@st@normal@bibtrue} % \begin{macro}{\@st@normal@bibfalse} % These are used to conditionally disable \pkgname{savetrees}'s % modifications to bibliography formatting. % \begin{macrocode} \newif\if@st@normal@bib \DeclareOption{normalbib}{\@st@normal@bibtrue} % \end{macrocode} % \pkgoptiondecl{normalbib} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\if@st@normal@bibnotes} % \begin{macro}{\@st@normal@bibnotestrue} % \begin{macro}{\@st@normal@bibnotesfalse} % These are used to conditionally include |NOTE| fields when using % |savetrees.bst|. % \begin{macrocode} \newif\if@st@normal@bibnotes \DeclareOption{normalbibnotes}{\@st@normal@bibnotestrue} % \end{macrocode} % \pkgoptiondecl{normalbibnotes} % \end{macro} % \end{macro} % \end{macro} % % \noindent % We need to process our options immediately, because they'll be needed % in the following code to determine which packages to load and what % macros to define. % \begin{macrocode} \ProcessOptions\relax % \end{macrocode} % % % \subsection{Section titles} % % The \LaTeX{} default is to typeset section titles in a large font and % with significant surrounding whitespace. We use the % \pkgname{titlesec} package to typeset section titles in the same font % size as the body text and to leave only a single blank line above and % below them. % % \begin{macrocode} \if@st@normal@sections \else \RequirePackage[tiny,compact]{titlesec} \fi % \end{macrocode} % % \subsection{Page margins} % % The typesetting wisdom of the ages says that the human eye is most % comfortable reading approximately 60~characters per line of text, and % this is what \LaTeX's default margins aim to achieve. Of course, % narrower margins mean fewer pages, and that's what \pkgname{savetrees} % is striving for. % % \begin{macro}{\@st@marginsize} % 1.5\,cm might not be the best margin size, so this value is stored in % the |\@st@marginsize| register, where it can easily be changed. % \begin{macrocode} \newlength{\@st@marginsize} \setlength{\@st@marginsize}{1.5cm} % \end{macrocode} % \end{macro} % % \noindent % Use the \pkgname{geometry} package to narrow our page margins, unless % the author wants to keep \LaTeX's original ones. Note that we accept % \pkgname{geometry}'s default of zero space allocated to marginal notes. % \changes{v1.2}{2006/11/20}{Made the top margin consistent with the other % margins and allocated space for the footer} % \begin{macrocode} \if@st@normal@margins \else \RequirePackage[lmargin=\@st@marginsize, rmargin=\@st@marginsize, tmargin=\@st@marginsize, bmargin=\@st@marginsize, includefoot, footskip=2ex]{geometry} \fi % \end{macrocode} % % % \subsection{List spacing} % % We try to save space in itemized lists, enumerated lists, and % description lists by reducing indentation slightly and by eliminating % inter-item spacing altogether. % % We make no modifications if the author prohibits us from doing so. % \begin{macrocode} \if@st@normal@lists \else % \end{macrocode} % The \pkgname{calc} package helps simplify our list redefinitions. % \begin{macrocode} \RequirePackage{calc} % \end{macrocode} % % \begin{environment}{itemize} % Except where indicated, the following code was taken directly from % \LaTeXe's definition of the |itemize| environment, in |ltlists.dtx|: % \begin{macrocode} \def\itemize{% \ifnum \@itemdepth >\thr@@\@toodeep\else \advance\@itemdepth\@ne \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% \expandafter \list \csname\@itemitem\endcsname {\def\makelabel##1{\hss\llap{##1}}% % \end{macrocode} % The following lines have been modified from the original. % \begin{macrocode} \settowidth{\leftmargin}{\csname\@itemitem\endcsname}% \addtolength{\leftmargin}{\labelsep * \@itemdepth}% \setlength{\topsep}{4pt plus 1pt minus 2pt}% \setlength{\itemsep}{0pt}% \setlength{\parsep}{0pt}% % \end{macrocode} % That's it for the modifications. We can now finish up the redefinition % of |itemize|. % \begin{macrocode} }% \fi} % \end{macrocode} % \end{environment} % % \begin{environment}{enumerate} % Except where indicated, the following code was taken directly from % \LaTeXe's definition of the |enumerate| environment, in |ltlists.dtx|: % \begin{macrocode} \def\enumerate{% \ifnum \@enumdepth >\thr@@\@toodeep\else \advance\@enumdepth\@ne \edef\@enumctr{enum\romannumeral\the\@enumdepth}% \expandafter \list \csname label\@enumctr\endcsname {\usecounter\@enumctr\def\makelabel##1{\hss\llap{##1}}% % \end{macrocode} % The following lines have been modified from the original. % \begin{macrocode} \settowidth{\leftmargin}{\csname label\@enumctr\endcsname}% \addtolength{\leftmargin}{\labelsep * \@enumdepth}% \setlength{\topsep}{4pt plus 1pt minus 2pt}% \setlength{\itemsep}{0pt}% \setlength{\parsep}{0pt}% % \end{macrocode} % That's it for the modifications. We can now finish up the % redefinition of |enumerate|. % \begin{macrocode} } \fi} % \end{macrocode} % \end{environment} % % \begin{environment}{description} % The |description| environment is a bit simpler than the |itemize| and % |enumerate| environments; it's a direct application of |list|. All we % need to do is reduce the left margin from the |list| default of 2\,em % to a slightly denser~1\,em. % \begin{macrocode} \renewenvironment{description}{% \begin{list}{}{\setlength{\leftmargin}{1em}% \labelwidth\z@ \itemindent-\leftmargin \let\makelabel\descriptionlabel}% }{% \end{list} } \fi % \end{macrocode} % \end{environment} % % % \subsection{Float placement} % % \begin{macro}{\topfraction} % \begin{macro}{\bottomfraction} % \begin{macro}{\textfraction} % \begin{macro}{\floatpagefraction} % \begin{macro}{\dbltopfraction} % \begin{macro}{\dblfloatpagefraction} % \LaTeX{} normally doesn't try very hard to pack floats onto a page. % The following parameter changes attempt to reduce the number of float % pages (and hence, total pages). As always, the author can require % that the original float-placement parameters be used instead. % \begin{macrocode} \if@st@normal@floats \else \renewcommand{\topfraction}{0.85} \renewcommand{\bottomfraction}{0.85} \renewcommand{\textfraction}{0.1} \renewcommand{\floatpagefraction}{0.85} \renewcommand{\dbltopfraction}{0.85} \renewcommand{\dblfloatpagefraction}{.85} \setcounter{topnumber}{25} \setcounter{bottomnumber}{25} \setcounter{totalnumber}{25} \setcounter{dbltopnumber}{25} \fi % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \subsection{Paragraph indentation} % % \LaTeX{} normally provides 2\,em of indentation at the start of each % paragraph. We can save a little space by reducing that to~1\,em. % % \begin{macrocode} \if@st@normal@indent \else \setlength{\parindent}{1em} \fi % \end{macrocode} % % % \subsection{Document title formatting} % % By default, the document title is typeset in the |\LARGE| font size, % and the author list and date are typeset |\large|. We redefine % |\@maketitle| to typeset the title |\large| and everything else in the % body font. In addition, we remove the extra whitespace above the % title and lessen the whitespace below the title. % % We proceed only with the author's permission. % \begin{macrocode} \if@st@normal@title \else % \end{macrocode} % \begin{macro}{\@maketitle} % The following was taken largely from |classes.dtx|, but modified as % specified above. % \begin{macrocode} \def\@maketitle{% \newpage \null \begin{center}% \let \footnote \thanks {\large \textbf{\@title}\par} \vskip 0.5\baselineskip \begin{tabular}[t]{c}% \@author \end{tabular}\par \vskip 0.5\baselineskip \@date \end{center}% \par \vskip \baselineskip } \fi % \end{macrocode} % \end{macro} % % % \subsection{Interline spacing} % % A document's page count can be reduced quite significantly by reducing % the amount of whitespace between successive lines of text, so that's % exactly what we do below. % % \begin{macro}{\baselinestretch} % 90\% of normal leading gives very good compression but still prevents % descenders from running into successive ascenders. 95\% would look % more subtle but, of course, would fit less text per page. % \begin{macrocode} \if@st@normal@leading \else \renewcommand{\baselinestretch}{0.9} \fi % \end{macrocode} % \end{macro} % % % \subsection{Paragraph looseness} % \changes{v1.2}{2006/11/20}{Added support for reducing paragraph looseness} % % Some paragraphs end with a lone word on the last line. If we can % discourage such typesetting we can gain an extra line. The underlying % mechanism we use is \TeX's |\looseness| primitive, which encourages % \TeX\ to expand the current paragraph by a given number of lines. % However, |\looseness| can be set to a negative number, which % encourages \TeX\ to shrink the current paragraph by a given number of % lines. For this technique to work, the paragraph must be relatively % long to \TeX\ has enough shrinkable whitespace to work with. % % Unfortunately, |\looseness| applies only to the current paragraph. We % therefore use |\everypar| to inject |\looseness=-1| into every % paragraph. However, the approach is not quite so simple as the % |\looseness=-1| is not injected into list environments. We therefore % use some tricky code due to Donald Arseneau to make the effect of % |\looseness=-1| as global as possible: % \changes{v1.2a}{2007/12/23}{Appended \texttt{\string\string\relax} to % \texttt{\string\string\looseness!=-1} to avoid discarding any % leading digits appearing in a paragraph} % \begin{macrocode} \if@st@normal@looseness \else \let\markeverypar\everypar \newtoks\everypar \everypar\markeverypar \markeverypar{\the\everypar\looseness=-1\relax} \fi % \end{macrocode} % % Even when |\everypar| is used in the ordinary fashion it is likely to % conflict with various \LaTeX\ packages. Because the preceding code is % a particularly tricky redefinition of |\everypar| it's likely that % many documents will need to disable paragraph looseness by specifying % the \pkgoption{normallooseness} option to \pkgname{savetrees}. % % % \subsection{Bibliography formatting} % % There are two ways we save space when typesetting bibliographies. % First, we omit blank linkes between entries. And second, we typeset % the entire bibliography---excluding the section title---with |\small|. % % We start, as always, by giving the author a chance to override our % changes. % \begin{macrocode} \if@st@normal@bib \else % \end{macrocode} % \begin{environment}{thebibliography} % The following was taken largely from |classes.dtx|; see that file for % additional documentation. \pkgname{savetrees}'s modifications are % indicated below. % \begin{macrocode} \renewenvironment{thebibliography}[1]{% % \end{macrocode} % In the |article| document class, a bibliography is a \emph{section} % called ``|\refname|''. In the |report| and |book| document classes, a % bibliography is a \emph{chapter} called ``|\bibname|''. In % |classes.dtx|, the correct code is extracted by \pkgname{DocStrip}. % Here, we have to use an |\ifx| primitive to select the appropriate % title and formatting. % \changes{v1.1}{2004/07/17}{Modified to test for % \texttt{\string\string\string\chapter}, not % \texttt{\string\string\string\bibname}.} % \changes{v1.2}{2006/11/19}{Modified to use the more robust % \texttt{\string\string\string\@ifundefined} macro to test for the existence % of \texttt{\string\string\string\chapter}} % \begin{macrocode} \@ifundefined{chapter}{% \section*{\refname \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}% }{% \chapter*{\bibname \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}}% }% % \end{macrocode} % Back to the original code\dots % \begin{macrocode} \list{\@biblabel{\@arabic\c@enumiv}}% {\settowidth\labelwidth{\@biblabel{#1}}% \leftmargin\labelwidth \advance\leftmargin\labelsep % \end{macrocode} % We eliminate the space between paragraphs, and we set the space % between items to only~1\,pt. We could have set this to~0\,pt., but % the extra space helps keep the citation numbers' brackets from getting % too close to each other, vertically. % \begin{macrocode} \setlength{\parsep}{0pt}% \setlength{\itemsep}{1pt}% % \end{macrocode} % Back to the original code\dots % \begin{macrocode} \@openbib@code \usecounter{enumiv}% \let\p@enumiv\@empty \renewcommand\theenumiv{\@arabic\c@enumiv}}% % \end{macrocode} % Although we kept the section title in its original size, we typeset % the rest of the bibliography a little bit smaller. % \begin{macrocode} \small % \end{macrocode} % We finish up using the original code\dots % \begin{macrocode} \sloppy \clubpenalty4000 \@clubpenalty \clubpenalty \widowpenalty4000% \sfcode`\.\@m }{% \def\@noitemerr {\@latex@warning{Empty `thebibliography' environment}}% \endlist } \fi % \end{macrocode} % \end{environment} % % % \subsection{Bibliographic notes} % \label{sec:bibliographic-notes} % % \begin{macro}{\savetreesbibnote} % The bibliographies output by the |savetrees.bst| \BibTeX{} style % (to be presented in Section~\ref{sec:savetrees.bst}) surround all |NOTE| % fields with a call to the |\savetreesbibnote| macro. As a result, this % must be defined for |savetrees.bst| to work. By default, % |\savetreesbibnote| is defined to do nothing. Howevever, the author % can specify that |\savetreesbibnote| should instead output its argument % with no additional processing. % \labelnextcodeline{code:stbn-begin} % \begin{macrocode} \if@st@normal@bibnotes \newcommand{\savetreesbibnote}[1]{#1} \else % \end{macrocode} % To supppress a |NOTE| field, we also have to gobble the period % following the note. Otherwise, the bibliography will show two periods % surrounding an empty note. % \begin{macrocode} \newcommand{\savetreesbibnote}[1]{\@gobble} \fi % \end{macrocode} % \labelprevcodeline{code:stbn-end} % \end{macro} % % \bigskip\noindent % This is the conclusion of |savetrees.sty|. % \begin{macrocode} % % \end{macrocode} % % % \section{Implementation of \texttt{savetrees.bst}} % \label{sec:savetrees.bst} % % In addition to a \LaTeXe{} style, the \pkgname{savetrees} package also % includes a \BibTeX{} style, |savetrees.bst|. |savetrees.bst| was % generated with the help of Patrick W. Daly's \pkgname{custom-bib} % package. The following options were provided to |merlin.mbs|: % % \begin{center} % \begin{minipage}{0.75\textwidth} % \ttfamily\selectfont % lang, nm-init, ed-au, nmdash, nmlm, x2, m2, isbn, issn, pp, ed, abr, % ednx, xedn, jabr, nfss % \end{minipage} % \end{center} % % Because |savetrees.bst| is a generated file---and can be regenerated using % the options listed above---it is unnecessary to list the complete % source code in this document. Rather, only the hand-modified parts are % presented below. % % \begin{macrocode} %<*bibstyle> % \end{macrocode} % % \begin{center} % $\vdots$ \\ % (460 lines of code omitted) \\ % $\vdots$ % \end{center} % % ^^A We surround all but our modified format.note function % ^^A within \iffalse...\fi. % \iffalse % \begin{macrocode} % =============================================================== % IMPORTANT NOTICE: % This bibliographic style (bst) file has been generated from one or % more master bibliographic style (mbs) files, listed above. % % This generated file can be redistributed and/or modified under the terms % of the LaTeX Project Public License Distributed from CTAN % archives in directory macros/latex/base/lppl.txt; either % version 1 of the License, or any later version. % =============================================================== % Name and version information of the main mbs file: % \ProvidesFile{merlin.mbs}[1999/05/28 3.89 (PWD)] % For use with BibTeX version 0.99a or later %------------------------------------------------------------------- % This bibliography style file is intended for texts in ENGLISH % This is a numerical citation style, and as such is standard LaTeX. % It requires no extra package to interface to the main text. % The form of the \bibitem entries is % \bibitem{key}... % Usage of \cite is as follows: % \cite{key} ==>> [#] % \cite[chap. 2]{key} ==>> [#, chap. 2] % where # is a number determined by the ordering in the reference list. % The order in the reference list is alphabetical by authors. %--------------------------------------------------------------------- ENTRY { address author booktitle chapter edition editor howpublished institution isbn issn journal key language month note number organization pages publisher school series title type volume year } {} { label } INTEGERS { output.state before.all mid.sentence after.sentence after.block } FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := #2 'after.sentence := #3 'after.block := } STRINGS { s t } FUNCTION {output.nonnull} { 's := output.state mid.sentence = { ", " * write$ } { output.state after.block = { add.period$ write$ newline$ "\newblock " write$ } { output.state before.all = 'write$ { add.period$ " " * write$ } if$ } if$ mid.sentence 'output.state := } if$ s } FUNCTION {output} { duplicate$ empty$ 'pop$ 'output.nonnull if$ } FUNCTION {output.check} { 't := duplicate$ empty$ { pop$ "empty " t * " in " * cite$ * warning$ } 'output.nonnull if$ } FUNCTION {fin.entry} { add.period$ write$ newline$ } FUNCTION {new.block} { output.state before.all = 'skip$ { after.block 'output.state := } if$ } FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = 'skip$ { after.sentence 'output.state := } if$ } if$ } FUNCTION {add.blank} { " " * before.all 'output.state := } FUNCTION {date.block} { new.block } FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } FUNCTION {new.block.checka} { empty$ 'skip$ 'new.block if$ } FUNCTION {new.block.checkb} { empty$ swap$ empty$ and 'skip$ 'new.block if$ } FUNCTION {new.sentence.checka} { empty$ 'skip$ 'new.sentence if$ } FUNCTION {new.sentence.checkb} { empty$ swap$ empty$ and 'skip$ 'new.sentence if$ } FUNCTION {field.or.null} { duplicate$ empty$ { pop$ "" } 'skip$ if$ } FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } { "\emph{" swap$ * "}" * } if$ } FUNCTION {capitalize} { "u" change.case$ "t" change.case$ } FUNCTION {space.word} { " " swap$ * " " * } % Here are the language-specific definitions for explicit words. % Each function has a name bbl.xxx where xxx is the English word. % The language selected here is ENGLISH FUNCTION {bbl.and} { "and"} FUNCTION {bbl.etal} { "et~al." } FUNCTION {bbl.editors} { "eds." } FUNCTION {bbl.editor} { "ed." } FUNCTION {bbl.edby} { "edited by" } FUNCTION {bbl.edition} { "ed." } FUNCTION {bbl.volume} { "vol." } FUNCTION {bbl.of} { "of" } FUNCTION {bbl.number} { "no." } FUNCTION {bbl.nr} { "no." } FUNCTION {bbl.in} { "in" } FUNCTION {bbl.pages} { "pp." } FUNCTION {bbl.page} { "p." } FUNCTION {bbl.chapter} { "chap." } FUNCTION {bbl.techrep} { "Tech. Rep." } FUNCTION {bbl.mthesis} { "Master's thesis" } FUNCTION {bbl.phdthesis} { "Ph.D. thesis" } MACRO {jan} {"Jan."} MACRO {feb} {"Feb."} MACRO {mar} {"Mar."} MACRO {apr} {"Apr."} MACRO {may} {"May"} MACRO {jun} {"Jun."} MACRO {jul} {"Jul."} MACRO {aug} {"Aug."} MACRO {sep} {"Sep."} MACRO {oct} {"Oct."} MACRO {nov} {"Nov."} MACRO {dec} {"Dec."} MACRO {acmcs} {"ACM Comput. Surv."} MACRO {acta} {"Acta Inf."} MACRO {cacm} {"Commun. ACM"} MACRO {ibmjrd} {"IBM J. Res. Dev."} MACRO {ibmsj} {"IBM Syst.~J."} MACRO {ieeese} {"IEEE Trans. Softw. Eng."} MACRO {ieeetc} {"IEEE Trans. Comput."} MACRO {ieeetcad} {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} MACRO {ipl} {"Inf. Process. Lett."} MACRO {jacm} {"J.~ACM"} MACRO {jcss} {"J.~Comput. Syst. Sci."} MACRO {scp} {"Sci. Comput. Programming"} MACRO {sicomp} {"SIAM J. Comput."} MACRO {tocs} {"ACM Trans. Comput. Syst."} MACRO {tods} {"ACM Trans. Database Syst."} MACRO {tog} {"ACM Trans. Gr."} MACRO {toms} {"ACM Trans. Math. Softw."} MACRO {toois} {"ACM Trans. Office Inf. Syst."} MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} MACRO {tcs} {"Theoretical Comput. Sci."} INTEGERS { nameptr namesleft numnames } FUNCTION {format.names} { 's := "" 't := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := nameptr #1 > { nameptr #2 #1 + = numnames #2 > and { "others" 't := #1 'namesleft := } 'skip$ if$ namesleft #1 > { ", " * t * } { numnames #2 > { "," * } 'skip$ if$ s nameptr "{ll}" format.name$ duplicate$ "others" = { 't := } { pop$ } if$ t "others" = { " " * bbl.etal * } { bbl.and space.word * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {format.names.ed} { format.names } FUNCTION {format.authors} { author empty$ { "" } { author format.names } if$ } FUNCTION {format.editors} { editor empty$ { "" } { editor format.names ", " * editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ * } if$ } FUNCTION {format.in.editors} { editor empty$ { "" } { editor format.names.ed editor num.names$ #1 > { ", " * bbl.editors * } { ", " * bbl.editor * } if$ } if$ } FUNCTION {format.isbn} { isbn empty$ { "" } { new.block "ISBN " isbn * } if$ } FUNCTION {format.issn} { issn empty$ { "" } { new.block "ISSN " issn * } if$ } FUNCTION {select.language} { duplicate$ empty$ 'pop$ { language empty$ 'skip$ { "{\selectlanguage{" language * "}" * swap$ * "}" * } if$ } if$ } % \end{macrocode} % \fi % % The following function is the only one modified by Scott Pakin. The % modification involves placing the entire note field within % |\savetreesbibnote{|\dots|}|. This enables |savetrees.sty| to % selectively define |\savetreesbibnote| to either output its argument as % is or discard it (and the subsequent period). See % Section~\ref{sec:bibliographic-notes} for |savetrees.sty|'s definition % of~|\savetreesbibnote|. % \begin{macrocode} FUNCTION {format.note} { note empty$ { "" } { "\savetreesbibnote{" note #1 #1 substring$ duplicate$ "{" = 'skip$ { output.state mid.sentence = { "l" } { "u" } if$ change.case$ } if$ note #2 global.max$ substring$ * "}" * * } if$ } % \end{macrocode} % % \iffalse % \begin{macrocode} FUNCTION {format.title} { title empty$ { "" } { title "t" change.case$ select.language } if$ } FUNCTION {output.bibitem} { newline$ "\bibitem{" write$ cite$ write$ "}" write$ newline$ "" before.all 'output.state := } FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = { t #1 #2 substring$ "--" = not { "--" * t #2 global.max$ substring$ 't := } { { t #1 #1 substring$ "-" = } { "-" * t #2 global.max$ substring$ 't := } while$ } if$ } { t #1 #1 substring$ * t #2 global.max$ substring$ 't := } if$ } while$ } FUNCTION {word.in} { bbl.in capitalize " " * } FUNCTION {format.date} { year empty$ { month empty$ { "" } { "there's a month but no year in " cite$ * warning$ month } if$ } { month empty$ 'year { month " " * year * } if$ } if$ } FUNCTION {format.btitle} { title emphasize select.language } FUNCTION {tie.or.space.connect} { duplicate$ text.length$ #3 < { "~" } { " " } if$ swap$ * * } FUNCTION {either.or.check} { empty$ 'pop$ { "can't use both " swap$ * " fields in " * cite$ * warning$ } if$ } FUNCTION {format.bvolume} { volume empty$ { "" } { bbl.volume volume tie.or.space.connect series empty$ 'skip$ { bbl.of space.word * series emphasize * } if$ "volume and number" number either.or.check } if$ } FUNCTION {format.number.series} { volume empty$ { number empty$ { series field.or.null } { output.state mid.sentence = { bbl.number } { bbl.number capitalize } if$ number tie.or.space.connect series empty$ { "there's a number but no series in " cite$ * warning$ } { bbl.in space.word * series * } if$ } if$ } { "" } if$ } FUNCTION {format.edition} { edition empty$ { "" } { output.state mid.sentence = { edition "l" change.case$ " " * bbl.edition * } { edition "t" change.case$ " " * bbl.edition * } if$ } if$ } INTEGERS { multiresult } FUNCTION {multi.page.check} { 't := #0 'multiresult := { multiresult not t empty$ not and } { t #1 #1 substring$ duplicate$ "-" = swap$ duplicate$ "," = swap$ "+" = or or { #1 'multiresult := } { t #2 global.max$ substring$ 't := } if$ } while$ multiresult } FUNCTION {format.pages} { pages empty$ { "" } { pages multi.page.check { bbl.pages pages n.dashify tie.or.space.connect } { bbl.page pages tie.or.space.connect } if$ } if$ } FUNCTION {format.journal.pages} { pages empty$ 'skip$ { duplicate$ empty$ { pop$ format.pages } { ":" * pages n.dashify * } if$ } if$ } FUNCTION {format.vol.num.pages} { volume field.or.null number empty$ 'skip$ { "(" number * ")" * * volume empty$ { "there's a number but no volume in " cite$ * warning$ } 'skip$ if$ } if$ format.journal.pages } FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ { bbl.chapter } { type "l" change.case$ } if$ chapter tie.or.space.connect pages empty$ 'skip$ { ", " * format.pages * } if$ } if$ } FUNCTION {format.in.ed.booktitle} { booktitle empty$ { "" } { editor empty$ { word.in booktitle emphasize * } { word.in format.in.editors * ", " * booktitle emphasize * } if$ } if$ } FUNCTION {empty.misc.check} { author empty$ title empty$ howpublished empty$ month empty$ year empty$ note empty$ and and and and and key empty$ not and { "all relevant fields are empty in " cite$ * warning$ } 'skip$ if$ } FUNCTION {format.thesis.type} { type empty$ 'skip$ { pop$ type "t" change.case$ } if$ } FUNCTION {format.tr.number} { type empty$ { bbl.techrep } 'type if$ number empty$ { "t" change.case$ } { number tie.or.space.connect } if$ } FUNCTION {format.article.crossref} { key empty$ { journal empty$ { "need key or journal for " cite$ * " to crossref " * crossref * warning$ "" } { word.in journal emphasize * } if$ } { word.in key * " " *} if$ " \cite{" * crossref * "}" * } FUNCTION {format.crossref.editor} { editor #1 "{vv~}{ll}" format.name$ editor num.names$ duplicate$ #2 > { pop$ " " * bbl.etal * } { #2 < 'skip$ { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = { " " * bbl.etal * } { bbl.and space.word * editor #2 "{vv~}{ll}" format.name$ * } if$ } if$ } if$ } FUNCTION {format.book.crossref} { volume empty$ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ word.in } { bbl.volume capitalize volume tie.or.space.connect bbl.of space.word * } if$ editor empty$ editor field.or.null author field.or.null = or { key empty$ { series empty$ { "need editor, key, or series for " cite$ * " to crossref " * crossref * warning$ "" * } { series emphasize * } if$ } { key * } if$ } { format.crossref.editor * } if$ " \cite{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { editor empty$ editor field.or.null author field.or.null = or { key empty$ { booktitle empty$ { "need editor, key, or booktitle for " cite$ * " to crossref " * crossref * warning$ "" } { word.in booktitle emphasize * } if$ } { word.in key * " " *} if$ } { word.in format.crossref.editor * " " *} if$ " \cite{" * crossref * "}" * } FUNCTION {format.org.or.pub} { 't := "" address empty$ t empty$ and 'skip$ { t empty$ { address empty$ 'skip$ { address * } if$ } { t * address empty$ 'skip$ { ", " * address * } if$ } if$ } if$ } FUNCTION {format.publisher.address} { publisher empty$ { "empty publisher in " cite$ * warning$ "" } { publisher } if$ format.org.or.pub } FUNCTION {format.organization.address} { organization empty$ { "" } { organization } if$ format.org.or.pub } STRINGS {oldname} FUNCTION {name.or.dash} { 's := oldname empty$ { s 'oldname := s } { s oldname = { "---" } { s 'oldname := s } if$ } if$ } FUNCTION {article} { output.bibitem format.authors "author" output.check name.or.dash new.block format.title "title" output.check new.block crossref missing$ { journal emphasize "journal" output.check format.vol.num.pages output format.date "year" output.check } { format.article.crossref output.nonnull format.pages output } if$ format.issn output new.block format.note output fin.entry } FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check name.or.dash } { format.authors output.nonnull name.or.dash crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output new.block format.number.series output new.sentence format.publisher.address output } { new.block format.book.crossref output.nonnull } if$ format.edition output format.date "year" output.check format.isbn output new.block format.note output fin.entry } FUNCTION {booklet} { output.bibitem format.authors output name.or.dash new.block format.title "title" output.check new.block howpublished output address output format.date output format.isbn output new.block format.note output fin.entry } FUNCTION {inbook} { output.bibitem author empty$ { format.editors "author and editor" output.check name.or.dash } { format.authors output.nonnull name.or.dash crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output format.chapter.pages "chapter and pages" output.check new.block format.number.series output new.sentence format.publisher.address output } { format.chapter.pages "chapter and pages" output.check new.block format.book.crossref output.nonnull } if$ format.edition output format.date "year" output.check crossref missing$ { format.isbn output } 'skip$ if$ new.block format.note output fin.entry } FUNCTION {incollection} { output.bibitem format.authors "author" output.check name.or.dash new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.chapter.pages output new.sentence format.publisher.address output format.edition output format.date "year" output.check format.isbn output } { format.incoll.inproc.crossref output.nonnull format.chapter.pages output } if$ new.block format.note output fin.entry } FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check name.or.dash new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.pages output new.sentence publisher empty$ { format.organization.address output } { organization output format.publisher.address output } if$ format.date "year" output.check format.isbn output format.issn output } { format.incoll.inproc.crossref output.nonnull format.pages output } if$ new.block format.note output fin.entry } FUNCTION {conference} { inproceedings } FUNCTION {manual} { output.bibitem author empty$ { organization empty$ 'skip$ { organization output.nonnull address output } if$ } { format.authors output.nonnull } if$ name.or.dash new.block format.btitle "title" output.check author empty$ { organization empty$ { address new.block.checka address output } 'skip$ if$ } { organization address new.block.checkb organization output address output } if$ format.edition output format.date output new.block format.note output fin.entry } FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check name.or.dash new.block format.btitle "title" output.check new.block bbl.mthesis format.thesis.type output.nonnull school "school" output.check address output format.date "year" output.check new.block format.note output fin.entry } FUNCTION {misc} { output.bibitem format.authors output name.or.dash title howpublished new.block.checkb format.title output howpublished new.block.checka howpublished output format.date output new.block format.note output fin.entry empty.misc.check } FUNCTION {phdthesis} { output.bibitem format.authors "author" output.check name.or.dash new.block format.btitle "title" output.check new.block bbl.phdthesis format.thesis.type output.nonnull school "school" output.check address output format.date "year" output.check new.block format.note output fin.entry } FUNCTION {proceedings} { output.bibitem editor empty$ { organization output } { format.editors output.nonnull } if$ name.or.dash new.block format.btitle "title" output.check format.bvolume output format.number.series output editor empty$ { publisher empty$ 'skip$ { new.sentence format.publisher.address output } if$ } { publisher empty$ { new.sentence format.organization.address output } { new.sentence organization output format.publisher.address output } if$ } if$ format.date "year" output.check format.isbn output format.issn output new.block format.note output fin.entry } FUNCTION {techreport} { output.bibitem format.authors "author" output.check name.or.dash new.block format.title "title" output.check new.block format.tr.number output.nonnull institution "institution" output.check address output format.date "year" output.check new.block format.note output fin.entry } FUNCTION {unpublished} { output.bibitem format.authors "author" output.check name.or.dash new.block format.title "title" output.check format.date output new.block format.note "note" output.check fin.entry } FUNCTION {default.type} { misc } READ FUNCTION {sortify} { purify$ "l" change.case$ } INTEGERS { len } FUNCTION {chop.word} { 's := 'len := s #1 len substring$ = { s len #1 + global.max$ substring$ } 's if$ } FUNCTION {sort.format.names} { 's := #1 'nameptr := "" s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := nameptr #1 > { nameptr #2 #1 + = numnames #2 > and { "others" 't := #1 'namesleft := } 'skip$ if$ " " * namesleft #1 = t "others" = and { "zzzzz" * } { t sortify * } if$ } { t sortify * } if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {sort.format.title} { 't := "A " #2 "An " #3 "The " #4 t chop.word chop.word chop.word sortify #1 global.max$ substring$ } FUNCTION {author.sort} { author empty$ { key empty$ { "to sort, need author or key in " cite$ * warning$ "" } { key sortify } if$ } { author sort.format.names } if$ } FUNCTION {author.editor.sort} { author empty$ { editor empty$ { key empty$ { "to sort, need author, editor, or key in " cite$ * warning$ "" } { key sortify } if$ } { editor sort.format.names } if$ } { author sort.format.names } if$ } FUNCTION {author.organization.sort} { author empty$ { organization empty$ { key empty$ { "to sort, need author, organization, or key in " cite$ * warning$ "" } { key sortify } if$ } { "The " #4 organization chop.word sortify } if$ } { author sort.format.names } if$ } FUNCTION {editor.organization.sort} { editor empty$ { organization empty$ { key empty$ { "to sort, need editor, organization, or key in " cite$ * warning$ "" } { key sortify } if$ } { "The " #4 organization chop.word sortify } if$ } { editor sort.format.names } if$ } FUNCTION {presort} { type$ "book" = type$ "inbook" = or 'author.editor.sort { type$ "proceedings" = 'editor.organization.sort { type$ "manual" = 'author.organization.sort 'author.sort if$ } if$ } if$ " " * year field.or.null sortify * " " * title field.or.null sort.format.title * #1 entry.max$ substring$ 'sort.key$ := } ITERATE {presort} SORT STRINGS { longest.label } INTEGERS { number.label longest.label.width } FUNCTION {initialize.longest.label} { "" 'longest.label := #1 'number.label := #0 'longest.label.width := } FUNCTION {longest.label.pass} { number.label int.to.str$ 'label := number.label #1 + 'number.label := label width$ longest.label.width > { label 'longest.label := label width$ 'longest.label.width := } 'skip$ if$ } EXECUTE {initialize.longest.label} ITERATE {longest.label.pass} FUNCTION {begin.bib} { preamble$ empty$ 'skip$ { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ "\expandafter\ifx\csname selectlanguage\endcsname\relax" write$ newline$ " \def\selectlanguage#1{\relax}\fi" write$ newline$ } EXECUTE {begin.bib} EXECUTE {init.state.consts} ITERATE {call.type$} FUNCTION {end.bib} { newline$ "\end{thebibliography}" write$ newline$ } EXECUTE {end.bib} % \end{macrocode} % \fi % % \begin{center} % $\vdots$ \\ % (941 lines of code omitted) \\ % $\vdots$ % \end{center} % % \begin{macrocode} % % \end{macrocode} % % % \section{Implementation of \texttt{makethin}} % % \progname{makethin} is a Perl\index{Perl|usage} script that produces % narrow variants of all of the fonts used in a document. The script is % about five~pages long and is not listed here. However, the following % is an outline of \progname{makethin}'s behavior: % % \begin{macrocode} %<*makethin> % \end{macrocode} % % \begin{enumerate} % \item Read all of the TFM and VF fonts named in the given DVI file. % % \item For each font, perform the following operations: % % \begin{enumerate} % \item If the font is a virtual font (|.vf|), then add all of the % VF and TFM fonts it names to the end of the font ``to-do'' list. % % \item If the font contains \TeX{} font metrics (|.tfm|), then % convert the font to an ASCII property list (|.pl|), replace each % ``|(CHARWD|~|R|~\meta{width}|)|'' expression with % ``|(CHARWD|~|R|~\meta{width}$\times$\meta{x-scale}|)|'', and % convert the result back to a |.tfm| file in the current directory. % \end{enumerate} % % \item Acquire a list of font-map files from |config.ps| and any other % Dvips configuration specified on the command line. % % \item Create a new font-map file, containing one line for each font % named in the given DVI file, but modified to specify % ``|"|\meta{x-scale} |ExtendFont"|'' on each line. % % \item Create a new Dvips configuration file that points to the new % font-map file. % \end{enumerate} % % \iffalse % \begin{macrocode} %< use File::Basename; use Getopt::Long; use Pod::Usage; use Pod::Man; use warnings; use strict; # Define some global variables. my $progname = basename $0; # Name of this program my @fontlist; # List of fonts to make thinner my @skipfonts; # Fonts specified by the user to ignore my @extrafonts; # Additional fonts specified by the user my @extramaps; # Additional .map files specified by the user my @configexts; # List of config.* files to process my @mapfiles; # List of .map files to copy and modify my @megamap; # Entire contents of all .map files my $cleanfirst; # Delete *.{tfm,vf} before creating new ones my $cleanonly; # Same as $cleanfirst, but exit after deleting my $dvifile; # Name of input .dvi file my $xscale = 0.5; # New font width as a fraction of the original my $verbose = 0; # 1=output task info; >1=output file info my $base = "thin"; # Name to use for config.* and *.map my $also_pdftex = 0; # 1=also produce a pdftex.map ########################################################################### # Set or change a filename's extension. sub set_ext ($$) { my ($name, $path, $suffix) = fileparse ($_[0], '\.[^.]*'); $path="" if $path eq "./"; return $path . $name . $_[1]; } # Try to find a file on disk using kpsewhich. Extra arguments to # kpsewhich can be included, too. sub find_file (@) { chomp (my $result = `kpsewhich @_`); return $? ? undef : $result; } # Make a font thinner. sub thin_font ($$$$) { my ($fname, $fpath, $fsuffix, $only_fontnames) = @_; my $virtualfont = $fsuffix eq ".vf"; my $converter = $virtualfont ? "vftovp" : "tftopl"; open (ASCII_TEXT, "$converter $fpath$fname$fsuffix|") || die "open(): $!\n"; # If we already converted the font, then merely look for additional fonts. if ($only_fontnames) { while () { /\(FONTNAME ([^\)]+)\)/i && push @fontlist, $1; } close ASCII_TEXT; return; } # Modify character widths. Also, store the name of any additional font # we encounter in a virtual font file. my $ascii_file = $virtualfont ? "$fname.vpl" : "$fname.pl"; open (ASCII_FILE, ">$ascii_file") || die "open(\"$ascii_file\"): $!\n"; while () { /\(FONTNAME ([^\)]+)\)/i && push @fontlist, $1; s|^(\s*)\(CHARWD (\S+) ([^\)]+)\)|sprintf "%s(CHARWD %s %.7f)", $1, $2, $3*$xscale|gie; print ASCII_FILE $_; } close ASCII_FILE; close ASCII_TEXT; # Convert the result from ASCII to binary. if ($virtualfont) { system "vptovf $fname.vpl"; die "system: $!\n" if $?; unlink "$fname.vpl"; } else { system "pltotf $fname.pl"; die "system: $!\n" if $?; unlink "$fname.pl"; } } # Re-map a font to a thinner variant. sub remap_font ($) { # See if any map file maps the given font. my $fontname = $_[0]; my @matches = grep {/^$fontname\s/} @megamap; return undef if $#matches==-1; # One does -- scale the font as specified. my $quoted = ""; while ($matches[0] =~ s/\"([^\"]+)\"//) { $quoted .= $1 . " "; } $matches[0] =~ s/\s+/ /g; $quoted =~ s/\S+\s+ExtendFont//g; $quoted .= "$xscale ExtendFont"; return $matches[0] . " \"$quoted\""; } # Output the embedded POD documentation in either *roff or PostScript format. sub pod2man ($$) { my ($manfile, $extraformatting) = @_; # Create an ordinary man page. my $parser = Pod::Man->new (center => "", date => "17 July 2004", release => ""); $parser->parse_from_file ($0, $manfile); # If requested, perform some extra formatting to make the # documentation print nicer. return if !$extraformatting; my @formattedman; open (MANPAGE, "<$manfile") || die "open(\"$manfile\"): $!\n"; while () { s/LaTeX/L\\h'-0.36m'\\v'-0.15'\\s-2A\\s+2\\v'0.15'\\h'-0.15m'TeX/g; s/TeX/T\\h'-0.1667m'\\v'0.20'E\\v'-0.20'\\h'-0.125m'X/g; s/\\\*\(--/--/g; push @formattedman, $_; } close MANPAGE; open (MANPAGE, "| groff -man > $manfile") || die "open(\"$manfile\"): $!\n"; print MANPAGE @formattedman; close MANPAGE; } ########################################################################### # Parse the command line. my $wanthelp = 0; Getopt::Long::Configure ("bundling"); GetOptions ("h|help" => \$wanthelp, "x|xscale=f" => \$xscale, "b|basename=s" => \$base, "k|skipfonts=s" => \@skipfonts, "e|extrafonts=s" => \@extrafonts, "m|extramaps=s" => \@extramaps, "P|config=s" => \@configexts, "c|clean" => \$cleanonly, "C|cleanfirst" => \$cleanfirst, "p|pdftex" => \$also_pdftex, "man=s" => sub {pod2man ($_[1], 0); exit 0}, "man-ps=s" => sub {pod2man ($_[1], 1); exit 0}, "v|verbose+" => \$verbose) || pod2usage (-verbose => 0, -exitval => 1); pod2usage (-verbose => $verbose, -exitval => 0) if $wanthelp; pod2usage (-verbose => 0, -exitval => 1) if $#ARGV==-1; $dvifile = $ARGV[0]; # Get a list of fonts from the DVI file and from the command line. print "Acquiring font names from $dvifile\n" if $verbose; open (DVI, "dvitype $dvifile|") || die "open(): $!\n"; my %uniquefonts; while () { /Font \d+: (\w+)/ && do {$uniquefonts{$1}=1}; } close DVI; foreach (map {split /,/, $_} @extrafonts) { $uniquefonts{$_} = 1; } @fontlist = sort {$a cmp $b} keys %uniquefonts; my %skipfonts = map {($_ => 1)} map {split /,/, $_} @skipfonts; # If told to, delete generated files from previous runs. if ($cleanfirst || $cleanonly) { print "Deleting generated font files, configuration files, and font maps\n" if $verbose; my @old_fontlist = @fontlist; while (@fontlist) { my $fontname = shift @fontlist; if ($skipfonts{$fontname}) { print " Ignoring $fontname (as directed by the command line)\n" if $verbose>1; next; } thin_font ($fontname, "", ".vf", 1) if -e "$fontname.vf"; foreach my $fsuffix (".vf", ".tfm") { if (-e "$fontname$fsuffix") { print " Removing $fontname$fsuffix\n" if $verbose>1; unlink "$fontname$fsuffix"; } } } my @extra_deletes = ("config.$base", "$base.map"); push (@extra_deletes, "pdftex.cfg") if $also_pdftex; foreach (@extra_deletes) { if (-e $_) { print " Removing $_\n" if $verbose>1; unlink $_; } } exit 0 if $cleanonly; @fontlist = @old_fontlist; } # Convert each font in turn. print "Creating *.tfm and *.vf files with ${xscale}X horizontal scaling\n" if $verbose; my %allfonts; while (@fontlist) { my $fontname = shift @fontlist; if ($skipfonts{$fontname}) { print " Ignoring $fontname (as directed by the command line)\n" if $verbose>1; next; } $allfonts{$fontname} = 1; if (-e (set_ext $fontname, ".vf") || -e (set_ext $fontname, ".tfm")) { print " Skipping $fontname (already converted)\n" if $verbose>1; if (-e set_ext $fontname, ".vf") { $fontname .= ".vf"; } else { $fontname .= ".tfm"; } my ($fname, $fpath, $fsuffix) = fileparse $fontname, "\.[^.]*"; thin_font ($fname, $fpath, $fsuffix, 1); # Only search for new fonts. } else { # Use a .vf file if available. If not, then use the .tfm file. print " Processing $fontname\n" if $verbose>1; my ($fname, $fpath, $fsuffix); if (find_file "$fontname.vf") { ($fname, $fpath, $fsuffix) = fileparse find_file ("$fontname.vf"), ".vf"; } elsif (find_file "$fontname.tfm") { ($fname, $fpath, $fsuffix) = fileparse find_file ("$fontname.tfm"), ".tfm"; } else { die "${progname}: I don't know anything about $fontname\n"; } # Convert the font. thin_font ($fname, $fpath, $fsuffix, 0); } } # Acquire a list of .map files to process. print "Reading dvips configuration files (config.*)\n" if $verbose; foreach my $ext ("ps", @configexts) { my $configfile = find_file '--format="dvips config"', "config.$ext"; die "${progname}: unable to find config.$ext\n" if !$configfile; print " Searching for map files in $configfile\n" if $verbose>1; open (CONFIGFILE, "<$configfile") || die "open(\"$configfile\"): $!\n"; while () { # Search for a PostScript font alias filename. chomp; s/\%.*//; next if !/^\s*p\s+(\+?)(\S+)/; # We found it -- adjust the list of .map files accordingly. @mapfiles=() if $1 eq ""; my $map = find_file '--format="dvips config"', $2; die "${progname}: unable to find $2\n" if !$map; push @mapfiles, $map; } close CONFIGFILE; } # Merge the contents of all map files into @megamap. print "Reading font maps (*.map)\n" if $verbose; foreach my $mapfile ((map {split /,/, $_} @extramaps), @mapfiles) { print " Reading font mappings from $mapfile\n" if $verbose>1; open (MAPFILE, "<$mapfile") || die "open(\"$mapfile\"): $!\n"; chomp (my @mappings = ); close MAPFILE; push @megamap, @mappings; } # Create a dvips configuration file. print "Generating config.$base\n" if $verbose; open (CONFIG, ">config.$base") || die "open(\"config.$base\"): $!\n"; print CONFIG <<"CONFIG_EOF"; % This file can be freely modified. It can also be % redistributed, provided that it is not called "config.thin". p +$base.map CONFIG_EOF close CONFIG; # Create a dvips map file. print "Generating $base.map\n" if $verbose; open (FONTMAP, ">$base.map") || die "open(\"$base.map\"): $!\n"; print FONTMAP <<'FONTMAP_EOF'; % This file can be freely modified. It can also be % redistributed, provided that it is not called "thin.map". FONTMAP_EOF my $num_maps = 0; foreach my $fontname (sort {$a cmp $b} keys %allfonts) { my $remapping = remap_font $fontname; if ($remapping) { print FONTMAP $remapping, "\n"; print " Wrote mapping for $fontname\n" if $verbose>1; $num_maps++; } elsif (! -e "$fontname.vf") { warn "${progname}: warning: no mapping was found for $fontname\n"; } } close FONTMAP; warn "${progname}: warning: no fonts were written to $base.map\n" if !$num_maps; # Create a pdfTeX config file. if ($also_pdftex) { print "Generating pdftex.cfg\n" if $verbose; unlink "pdftex.cfg"; my $pdfcfg = find_file "--progname=pdftex", "pdftex.cfg"; die "${progname}: unable to find pdftex.cfg\n" if !$pdfcfg; open (INCONFIG, "<$pdfcfg") || die "open(\"$pdfcfg\"): $!\n"; open (OUTCONFIG, ">pdftex.cfg") || die "open(\"pdftex.cfg\"): $!\n"; while () { next if /^\s*map\s/; # Discard all map lines. print OUTCONFIG $_; } print OUTCONFIG "\n% The next line was added by $progname.\n"; print OUTCONFIG "map $base.map\n"; close OUTCONFIG; close INCONFIG; } ########################################################################### __END__ =head1 NAME makethin - make thinner versions of PostScript fonts for TeX =head1 SYNOPSIS makethin [B<--verbose>] [B<--xscale>=I] [B<--cleanfirst>] [B<--clean>] [B<--config>=I] [B<--pdftex>] [B<--extramaps>=I[,I]...] [B<--skipfonts>=I[,I]...] [B<--basename>=I] [B<--extrafonts>=I[,I]...] I<.dvi file> makethin [B<--verbose>] B<--help> makethin B<--man>=I | B<--man-ps>=I =head1 DESCRIPTION B produces thinner versions of PostScript fonts for use with TeX/LaTeX and Dvips. More precisely, it finds all of the F<.tfm> and F<.vf> fonts referred to by a F<.dvi> file, scales the character-width metrics by a given amount, and writes new F<.tfm> and F<.vf> files to the current directory. B then generates a customized F<.map> and F file for Dvips and, optionally, a customized F file for pdfLaTeX. The general procedure for using B is as follows: =over 4 =item 1. Run B on your F<.tex> source file to produce a F<.dvi> file. =item 2. Run B on the F<.dvi> file to create new F<.tfm>, F<.vf>, F<.map>, and F files. =item 3. Re-run B on your F<.tex> source file to typeset it with the new fonts. =item 4. Run B on the F<.dvi> file, specifying the newly generated F<.map> and F files, to produce a F<.ps> file. =back =head1 OPTIONS The following are the command-line options that B accepts: =over 4 =item B<-v>, B<--verbose> Increase the verbosity of the status output. B<--verbose> can be specified multiple times on the same command line, with each B<--verbose> futher increasing the verbosity. (Currently, two B<--verbose>s have maximal impact.) =item B<-h>, B<--help> Display basic usage information. When combined with B<--verbose>, additionally describes each of the command-line options. When combined with a second B<--verbose>, B<--help> outputs the complete B manual page. =item B<-x> I, B<--xscale>=I Scale fonts horizontally by a factor of I. The default, C<0.5>, produces nearly illegible fonts but is useful for verifying that B actually worked. Factors of C<0.90>-C<0.99> are more reasonable. =item B<-C>, B<--cleanfirst> Delete all files generated by a previous run of B before generating new ones. =item B<-c>, B<--clean> Delete all files generated by a previous run of B and then exit. =item B<-P> I, B<--config>=I Process all of the F<.map> files named in FI (found in Dvips's configuration directory). B<--config> can be specified multiple times on the same command line. F is processed implicitly. The same B<-P> arguments that you would normally pass to B to utilize entirely PostScript fonts (e.g., B<-Pcmz> and B<-Pamz>) should also be passed to B. =item B<-p>, B<--pdftex> In addition to producing the files needed by Dvips, also produce a F file that is usable by pdfLaTeX. =item B<-m> I[,I]...], B<--extramaps>=I[,I]...] Additionally process the named Dvips F<.map> files even if they're not referred to by any of the FI files specified with B<--config>. B<--extramaps> can be specified multiple times on the same command line. =item B<-k> I[,I]...], B<--skipfonts>=I[,I]...] Don't make thin versions of the named fonts, even if they're listed in the F<.dvi> file. Fonts are named using the Berry scheme (i.e., ``C'' as opposed to ``C'' or ``C''). B<--skipfonts> can be specified multiple times on the same command line. =item B<-b> I, B<--basename>=I Tell B to use I as the base name for the Dvips configuration files it generates. The default is ``C'', so B normally produces files named F and F, but B<--basename> enables alternate filenames to be used. =item B<-e> I[,I]...], B<--extrafonts>=I[,I]...] Make thin versions of the named fonts, even if they're not listed in the F<.dvi> file. Fonts are named using the Berry scheme (i.e., ``C'' as opposed to ``C'' or ``C''). B<--extrafonts> can be specified multiple times on the same command line. =item B<--man>=I Create a Unix manual page for B in the standard, *roff format. Typical usage is: makethin --man=/usr/man/man1/makethin.1 =item B<--man-ps>=I Create a Unix manual page for B in PostScript format instead of *roff format. =back In addition to the options listed above, B has a required argument, which is the name of a F<.dvi> file from which to read font information. =head1 EXAMPLES The following are some examples of how to use B. =head2 A typical case First, we need to produce F, because that contains the font information that B will read: latex myfile.tex Next, we invoke B, telling it to process F (which, in turn, causes F to be processed), This tells B to use PostScript versions of the Computer Modern fonts instead of bitmapped versions. (B can scale only PostScript fonts.) We also specify maximal verbosity: makethin -Pcmz --verbose --verbose myfile.dvi The preceding line reads F, F, various map files, such as F and F, and all of the F<.tfm> and F<.vf> files mentioned in F. It then writes F, F, and modified versions of all of the F<.tfm> and F<.vf> files to the current directory. We now need to re-run B, so it can produce a new F using the thinner metrics listed in the current directory's F<.tfm> and F<.vf> files: latex myfile.tex Finally, we produce a PostScript file using the newly generated using F and F files: dvips -Pthin myfile.dvi -o myfile.ps If all worked according to plan, F should be typeset using extremely thin (half-width) versions of its original fonts. =head2 Producing thin fonts for use in pdfLaTeX Because B can read only F<.dvi> files, not F<.pdf> files, we first need to produce a F<.dvi> file: latex too-long.tex F is typeset entirely using the Times family of fonts. Therefore, we don't need to specify B<-Pcmz>. However, B normally embeds Times, thereby precluding B's ability to scale it. (B requires a F<.pfb> font file in order to scale the corresponding font.) Fortunately, F already contains the proper mapping of TeX names to F<.pfb> files for Times, Courier, and Helvetica. We can tell B to use that file: makethin --cleanfirst -v -v too-long.dvi --pdftex --xscale=0.9 --extramaps=/usr/share/texmf/dvips/config/ar-std-urw-kb.map In the preceding line, we changed the scaling factor from the default of 0.5 to a more reasonable 0.9. Because we had some 0.5-scaled F<.tfm> and F<.vf> files left over from the previous example, we specified B<--cleanfirst> to delete those old font files. We specified B<--pdftex> to make B produce a local F file. And we told B where to find the extra map file needed to force the usage of F<.pfb> files. All that's left is to run B to produce a F<.pdf> file: pdflatex too-long.tex B will read the font metric files (F<.tfm> and F<.vf>) and F from the current directory. This will tell it to load F, which specifies the scaling factor. The result should be a document with each character squeezed to 90% of its original width. =head1 FILES =over 4 =item B interpreter/compiler needed to run the B script =item B finds files within the TeX directory tree =item B outputs the typesetting commands contained within a F<.dvi> file =item F<*.tfm> and F<*.vf> TeX font metrics and virtual fonts--metrics specifying the width of each character in a font =item F Dvips configuration files, each containing (among other information) a list of font-map files =item F, F<*.map> Dvips font-map files, which map TeX font names to PostScript font names and F<.pfb> files =item F pdfTeX and pdfLaTeX configuration files, each containing (among other information) a list of font-map files =item B used by B<--man-ps> to produce a PostScript version of the Unix manual page for B =back =head1 RESTRICTIONS The most serious restriction is that B doesn't work on Computer Modern Roman 10pt. (F)--the default TeX/LaTeX font. The reason, I believe, is that TeX and LaTeX preload that font's metrics (F) and therefore ignore the scaled F on disk. It may be possible to work around this limitation by copying F to a new name and convincing LaTeX to use that name where it would otherwise have used F. However, it's much easier merely to use a different font family (e.g., with ``C<\usepackage{times}>'') for typesetting your document when you know you want to run B. =head1 SEE ALSO dvips(1), latex(1), pdflatex(1), the LaTeX C package =head1 AUTHOR Scott Pakin, I %VERBATIM_PERL % \end{macrocode} % \fi % % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput