% \iffalse % $Id: vcode.dtx,v 1.7 2003/05/05 14:12:00 tom Exp $ % % $Log: vcode.dtx,v $ % Revision 1.7 2003/05/05 14:12:00 tom % fixed a bug involving short lines and wide left margins % % Revision 1.6 2000/10/30 20:10:19 tom % Fixed to allow URL arguments to contain square brackets. % % Revision 1.5 2000/10/23 20:32:14 tom % 'yank' is apparently not the done thing in these functions. % replaced with (insert (car kill-ring)) % % Revision 1.4 2000/10/23 17:05:27 tom % added optional URL argument for Hyperlatex. % % Revision 1.3 1999/03/22 21:59:03 tom % updated DODS doc tools % % Revision 1.2 1999/02/16 14:47:51 tom % minor rework % % Revision 1.1 1999/02/03 22:37:56 tom % LaTeX template creation and book design revamp. % % \fi % % \MakeShortVerb\| % % \DoNotIndex{\@minipagetrue,\@tempswatrue,\\,\ ,\addtolength} % \DoNotIndex{\begin,\bgroup,\box,\def,\DisableCrossrefs} % \DoNotIndex{\do,\DocInput,\documentclass,\egroup,\EnableCrossrefs} % \DoNotIndex{\end,\endinput,\endverbatim,\fbox,\fi} % \DoNotIndex{\gdef,\global,\hbadness,\hbox,\hsize} % \DoNotIndex{\hskip,\lastbox,\let,\mbox,\newcommand} % \DoNotIndex{\newlength,\OldMakeindex,\OnlyDescription,\par,\parindent} % \DoNotIndex{\parsep,\RecordChanges,\setbox,\setcounter,\setlength} % \DoNotIndex{\stepcounter,\textit,\textrm,\the,\theCodeLineNo} % \DoNotIndex{\tt,\unhbox,\unskip,\vskip,\wd} % % \iffalse % \begin{macrocode} %<*driver> \newcommand{\vc}{{\tt vcode}} \documentclass{ltxdoc} \EnableCrossrefs %\DisableCrossrefs % Say \DisableCrossrefs if index is ready \CodelineIndex \RecordChanges % Gather update information %\OnlyDescription % comment out for implementation details %\OldMakeindex % use if your MakeIndex is pre-v2.9 \setlength\hfuzz{15pt} % dont make so many \hbadness=7000 % over and under full box warnings \begin{document} \DocInput{vcode.dtx} \end{document} % % \end{macrocode} % \fi % % \GetFileInfo{vcode.sty} % \title{Controlling {\tt verbatim} Text} % \author{Tom Sgouros} % \maketitle % % \begin{abstract} % This package creates a semblance of control over aspects of the % |verbatim| environment, using some of the hooks of the alternate % |verbatim.sty| package. % \end{abstract} % % \changes{1.0}{99/01/31}{Created} % %\catcode`\<=14 %<+sty>\typeout{Style-option: `vcode' (George Ferguson & Tom Sgouros)} %<+sty>\NeedsTeXFormat{LaTeX2e} %<+sty>\ProvidesPackage{vcode} %<+sty> [1999/01/31 v1.0 %<+sty> LaTeX2e package for source code% %<+sty> ] %<+sty>\@ifundefined{verbatim@processline}{\RequirePackage{verbatim}}{} %\catcode`\<=12 % % % {\parskip 0pt \tableofcontents } % % \newcommand{\hlx}{Hyperlatex} % \newcommand{\latex}{\LaTeX} % % \section{Introduction} % Using the simplest form of {\tt verbatim.sty} presents some % problems in formatting example text. There is little control over % the placement of the examples (both horizontally and vertically), % and often one wants control of the size of the text, to prevent % lines from running over the right margin. Line numbers are also % nice. % % None of these present a real problem, until you try to use % whatever solution you find with one of the latex-to-html % converters around. Both latex2html and Hyperlatex choke on the % simple solutions. Here, then, is a package {\tt vcode.sty} % designed for use with Hyperlatex that provides substantial control % over the placement of the example text, and other features % (including line numbering and controlled indentation). There is a % companion {\tt vcode.hlx} that works with Hyperlatex to create % html versions of the LaTeX original. % % Since HTML does not provide the same kind of formatting control % as \latex , the \hlx\ version of this package ignores the formatting % instructions used by \latex . You can use a stylesheet to % control the look of the {\tt vcode} examples, and the formatting % argument is used as a class identifier in the
 declaration.
%
%    The \hlx\ version of this class provides an optional argument to
%    create a hyperlink from the displayed text.  This is ignored by
%    the \latex\ version.
%
%    Note that since the package works by putting all the verbatim
%    lines into a box, and then outputting the box all at once, it is
%    not well-suited for long examples (more than one page). 
%
%    This package was originally {\tt code.sty}, written by George
%    Ferguson in 1991, ``based on a suggestion by Bernd Raichle
%    (raichle@azu.informatik.uni-stuttgart.de).''  It was debugged a
%    little, and modified to add features and to work with the
%    Hyperlatex package by Tom Sgouros in 1998 and 1999.
%
%    This package assumes the use of Rainer Sch\"opf's
%    (SCHOEPF@SC.ZIB-Berlin.DE) verbatim style option. 
%
% \section{\tt vcode.sty}
%
%    The \vc\ environment formats the text between its beginning
%    and end in verbatim mode. The box containing the code is only as
%    wide as its longest line.
%

%    The \vc\ environments provides the following
%    options\footnote{We use the LaTeX iteration macro |@tfor| to process
%    arguments to the \vc\ environment.}:
%
%    \begin{description}
%    \item[c] Center the block of code.
%    \item[l] Make the block of code flush to the left margin.
%    \item[r] Make the block of code flush to the right margin.
%    \item[i] Indent the block of code (by |\vcodeindent|) from the left.
%    \item[f] Draw a frame around the block of code.
%    \item[t] Make the resulting box have its baseline at the top.
%    \item[b] Make the resulting box have its baseline at the bottom.
%    \item[s] Make the text a little smaller (|\small|).
%    \item[x] Make the text even smaller (|\footnotesize|).
%    \item[z] Make the text smaller still (not normally useful:
%    |\scriptsize|). 
%    \item[n] Add line numbers.
%    \end{description}
%
%    Any combination and order of options is acceptable, but only the last
%    of any conflicting options will have any effect.
%    The default is to produce a flush-left, bottom-aligned block of
%    code. (normal size, no indent)
%
%    The |\vcodeindent| length can be used to control the length of
%    indentation: 
%    \begin{macrocode}
%<*sty>
\newlength{\vcodeindent}
\setlength{\vcodeindent}{\parindent}
%
%    \end{macrocode}
%
%    The |CodeLineNo| counter is used to generate the line numbers.
%    The counter is zeroed when the environment is exited, so if it is
%    reset between environments, the next line numbers will begin after
%    incrementing the given line number.
%
%    \begin{macrocode}
%<*sty>
\newcounter{CodeLineNo}
\newcount\vc@CodeLineFlag
%
%    \end{macrocode}
%
%    These are convenient lengths, and definitions of default
%    positions.
%
%    \begin{macrocode}
%<*sty>
\newlength{\vc@indent}
\newlength{\vc@testwidth}
\newlength{\vc@adjustmargin}
\def\vc@flushleft#1{\hskip 0pt minus\parindent \hbox{#1}\hfill}
\def\vc@flushright#1{\hfill\hbox{#1}}
\def\vc@centered#1{\ \hfill\hbox{#1}\hfill\ }
\def\vc@indented#1{\hskip\vc@indent\hbox{#1}}
\def\vc@noop#1{#1}
%
%    \end{macrocode}
%
%    This is the environment definition.  It redefines
%    |\verbatim@processline| in accord with the |\verbatim| package
%    instructions.  The optional argument is ignored completely in
%    \latex .
%
%    \begin{macrocode}
%<*sty>
\newenvironment{vcode}[2][]{%
%
%    \end{macrocode}
%
%    Here we redefine the verbatim font.  Note that we elide a bit of
%    trickery in the verbatim.sty file that allows you to print ?` and
%    !` .  In this package, those combinations appear to print
%    upside-down ? and ! .  For most purposes, this is an unlikely
%    combination, so we suffer. 
%
%    \begin{macrocode}
%<*sty>
\gdef\verbatim@font{\tt}%
\newcommand{\CodeFont}[1]{\textrm{\textit{\footnotesize ##1}}}%
%
%    \end{macrocode}
%
%    Now redefine `processline' to produce only a line as wide
%    as the natural width of the line.  Notice that if the line is smaller
%    than |\@totalleftmargin|, the line length is artifically increased to
%    that length.  This is, it appears, something you have to do if you're 
%    going to use |\par| to indicate the separation between lines.
%
%    \begin{macrocode}
%<*sty>
\def\verbatim@processline{%
  \stepcounter{CodeLineNo}%
  {\setbox1=\hbox{\ifnum\vc@CodeLineFlag=1 \CodeFont{%
      \theCodeLineNo}\ \fi\the\verbatim@line}%
   \hsize=\ifdim\wd1>\@totalleftmargin\wd1\else\@totalleftmargin\fi%
   \hskip-\@totalleftmargin\unhbox1\par}}%
%
%    \end{macrocode}
%
%    These are the defaults: flush left, unboxed, no line numbers,
%    bottom-aligned. 
%    \begin{macrocode}
%<*sty>
  \global\let\vc@hadjust\vc@flushleft%
  \global\let\vc@frame\mbox%
  \global\let\vc@vadjust\vbox%
%
%    \end{macrocode}
%
%    If the typeset box is wider than the line width, some peculiar
%    things happen to the vertical spacing.  We save that width here,
%    to check it later and cheat a little.
%
%    \begin{macrocode}
%<*sty>
  \setlength{\vc@testwidth}{\linewidth}%
%
%    \end{macrocode}
%
%    Here we process the arguments to the environment.  Note that
%    arguments can easily override one another.  The rightmost of any
%    conflicting arguments wins.
%
%    \begin{macrocode}
%<*sty>
  \@tfor \vc@char :=#2\do%
    {\if\vc@char c\global\let\vc@hadjust\vc@centered\fi%
     \if\vc@char l\global\let\vc@hadjust\vc@flushleft\fi%
     \if\vc@char r\global\let\vc@hadjust\vc@flushright\fi%
     \if\vc@char i\global\let\vc@hadjust\vc@indented\fi%
     \if\vc@char t\global\let\vc@vadjust\vtop\fi%
     \if\vc@char b\global\let\vc@vadjust\vbox\fi%
     \if\vc@char f\global\let\vc@frame\fbox\fi%
     \if\vc@char s\gdef\verbatim@font{\small\tt}\fi%
     \if\vc@char x\gdef\verbatim@font{\footnotesize\tt}\fi%
     \if\vc@char z\gdef\verbatim@font{\scriptsize\tt}\fi%
     \if\vc@char n\global\vc@CodeLineFlag=1\setcounter{CodeLineNo}{0}\fi%
    }%
%
%    \end{macrocode}
%
%    Now save the verbatim code in a box.
%
%    \begin{macrocode}
%<*sty>
  \bgroup \setlength{\vc@indent}{\vcodeindent}%
  \@minipagetrue \@tempswatrue%
  \setbox0=\vc@vadjust \bgroup \verbatim}%
%
%    \end{macrocode}
%
%    Here's where the environment is wrapped up.  The cheating is done,
%    and the box in which the verbatim text is saved is dumped.
%
%    \begin{macrocode}
%<*sty>
{%
  \endverbatim%
  \unskip\setbox0=\lastbox% get rid of the last (empty) box.
  \egroup % close the box.
%
%    \end{macrocode}
%
%    If the box is too wide, we cheat and move up (|-2\parsep|) a tad.
%    We also zero the line number counter here.
%
%    \begin{macrocode}
%<*sty>
  \ifx\vc@hadjust\vc@indented\addtolength{\vc@testwidth}{-\vc@indent}\fi%
  \ifnum\wd0>\vc@testwidth\vskip-2\parsep\fi%
  \vc@hadjust{\vc@frame{\box0}}%
  \global\vc@CodeLineFlag=0%
  \egroup%
}
%
%    \end{macrocode}
%
% \section{\tt vcode.hlx}
%
%    This package is especially designed to work with Otfried Cheong's
%    Hyperlatex package.  For generating html, it is only essential
%    that the \vc\ text be put in between |
| tags.  The \vc\
%    arguments may be discarded.
%
%    The \vc\ arguments are placed in a ``class'' declaration in the
%    |
| tag declaration.  So some semblance of control can be
%    exerted through cascading stylesheets.  The optional argument may
%    contain a URL to link the \vc\ text to.  If the optional argument
%    is a single period (|.|), the text of the \vc\ is used as the
%    hyperlink.  Obviously, this is intended for displaying URLs.
%    Note that \ltx\ chokes when you use brackets in an optional argument.  
%    So don't do that.
%
%    Future enhancements might include parsing the line-number
%    argument, and putting that into the html.  For now, however, this
%    will do. 
%
%    The default case (with no optional argument) simply searches
%    forward for the |\end{vcode}| declaration, and envelops the whole
%    in the |
| tags.  The optional argument makes things a little
%    more complex.  If the argument is specified, it is simply
%    inserted into an || tag surrounding the text.  If the `.'
%    option is used, the \vc\ text must be scanned and killed, and
%    yanked into the || declaration, and then into the gulf between
%    the |
| tags.
%
%    If the URL uses brackets, they may be escaped with a backslash.  
%    Note that this relies on the argument not printing in \ltx .
%
%    \begin{macrocode}
%<*hlx>
\HlxEval{
(put 'vcode         'hyperlatex 'hyperlatex-format-vcode)
(put 'endvcode      'hyperlatex 'hyperlatex-end-vcode)

(defun hyperlatex-format-vcode ()
  (let* ((url  (hyperlatex-parse-optional-argument-brackets))
	 (args (hyperlatex-parse-required-argument))
	 (begin (point)))
    (hyperlatex-blk)
    (search-forward "\\end{vcode}")
    (replace-match "")
    (kill-region begin (point))
    (if url
	(hyperlatex-gen
	 (format "a href=\"%s\" class=\"url\""
		 (if (string= url ".")
		     (substring (car kill-ring) 1 -1)
		   (hyperlatex-format-vcode-brackets url)))))
    (if args
	(hyperlatex-gen (format "pre class=\"%s\"" args))
      (hyperlatex-gen "pre"))
    (insert (car kill-ring))
    (hyperlatex-gen "/pre")
    (if url (hyperlatex-gen "/a"))
    (hyperlatex-pop-stacks)))

(defun hyperlatex-format-vcode-brackets (url)
  "LaTeX cannot use brackets smoothly in optional arguments (which are 
  delimited with brackets).  Use `\[' and `\]' for brackets in the vcode
  URL argument.  This only works because the vcode optional argument is 
  discarded in LaTeX."
  (cond ((string-match "\\\\\\[" url)
	 (progn
	   (hyperlatex-message url)
	   (hyperlatex-format-vcode-brackets (replace-match "[" t t url))))
	((string-match "\\\\\\]" url)
	 (progn
	   (hyperlatex-message url)
	   (hyperlatex-format-vcode-brackets (replace-match "]" t t url))))
	(t url)))

(defun hyperlatex-parse-optional-argument-brackets ()
  "Parses the argument enclosed in brackets after the commands.
Deletes command and returns argument (nil if none)."
  (goto-char hyperlatex-command-start)
  (hyperlatex-delete-|)
  (hyperlatex-delete-comment)
  (if (= (following-char) ?\[ )
      (progn
	(goto-char (1+ (point)))
	(while (not (and (= (following-char) ?\])
			 (/= (preceding-char) ?\\))) 
	  (if (= (following-char) ?\{)
	      (forward-sexp 1)
	    (goto-char (1+ (point)))))
	(prog1
	    (buffer-substring (1+ hyperlatex-command-start) (point))
	  (delete-region hyperlatex-command-start (1+ (point)))))))

(defun hyperlatex-end-vcode ()
  (error "Nested vcode environments!"))

}
%
%    \end{macrocode}
%
%    There is a problem with using \hlx\ and docstrip, and that's the
%    |\endinput| that goes at the end of the file...
%
%    \begin{macrocode}
%<*hlx>
\newcommand{\endinput}{}
%
%    \end{macrocode}


% \Finale \PrintIndex