diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-12 23:45:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-12 23:45:13 +0000 |
commit | 92a15e15b276458e10aa05016bf472e8c6dd3eb0 (patch) | |
tree | af0343097e5f497167cefa16ed45c03475b98c37 /Master/texmf-dist/tex/context/base/verb-ini.tex | |
parent | df014cf02a62504f6b3e7a4398fb1e093b84f114 (diff) |
context
git-svn-id: svn://tug.org/texlive/trunk@608 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/verb-ini.tex')
-rw-r--r-- | Master/texmf-dist/tex/context/base/verb-ini.tex | 2089 |
1 files changed, 2089 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/verb-ini.tex b/Master/texmf-dist/tex/context/base/verb-ini.tex new file mode 100644 index 00000000000..c38c3f6f4cc --- /dev/null +++ b/Master/texmf-dist/tex/context/base/verb-ini.tex @@ -0,0 +1,2089 @@ +%D \module +%D [ file=verb-ini, +%D version=1997.12.22, +%D title=\CONTEXT\ Verbatim Macros, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Today I would implement the pretty handler slightly +%D different, using stack and intermediate flushing. Maybe +%D even without active chars. So, someday \unknown + +%D Because this module is quite independant of system macros, +%D it can be used as a stand||alone verbatim environment. +%D +%D This is a sort of second release of \type{supp-ver} and +%D therefore differs in some aspects from the implementation +%D published in the \MAPS. The first change concern +%D optimization of breaks, that is, the first and last two +%D lines of verbatim blocks are kept together. The second +%D adaption is due to the fact that I wanted to support pretty +%D printing not only for \TEX\ sources, but also for \PERL, +%D \METAPOST\ and probably more. The \JAVASCRIPT\ module is +%D closely related to \PERL, so we will not mention that one +%D again. + +\ifx \undefined \writestatus \input supp-mis.tex \fi + +%D Verbatim typesetting, especially of \TEX\ sources, is a +%D non||trivial task. This is a direct results of the fact that +%D characters can have \CATCODES\ other than~11 and such +%D characters needs a special treatment. What for instance is +%D \TEX\ supposed to do when it encounters a \type{$} or an +%D \type{#}? This module deals with these matters. + +\writestatus{loading}{Context Verbatim Macros / Initialization} + +%D The verbatim environment has some features, like coloring +%D \TEX\ text, seldom found in other environments. Especially +%D when the output of \TEX\ is viewed on an electronic medium, +%D coloring has a positive influence on the readability of +%D \TEX\ sources, so we found it very acceptable to dedicate +%D half of this module to typesetting \TEX\ specific character +%D sequences in color. In this module we'll also present some +%D macro's for typesetting inline, display and file verbatim. +%D The macro's are capable of handling \TAB\ too. +%D +%D This module shows a few tricks that are often overseen by +%D novice, like the use of the \TEX\ primitive \type{\meaning}. +%D First I'll show in what way the users are confronted with +%D verbatim typesetting. Because we want to be able to test for +%D symmetry and because we hate the method of closing down the +%D verbatim mode with some strange active character, we will +%D use the following construction for display verbatim: +%D +%D \starttyping +%D \starttyping +%D The Dutch word 'typen' stands for 'typing', therefore in the Dutch version +%D one will not find the word 'verbatim'. +%D \stoptyping +%D \stoptyping +%D +%D In \CONTEXT\ files can be typed with \type{\typefile} and +%D inline verbatim can be accomplished with \type{\type}. This +%D last command comes in many flavors: +%D +%D \starttyping +%D We can say \type<<something>> or \type{something}. The first one is a bit +%D longer but also supports slanted typing, which accomplished by typing +%D \type<<a <<slanted>> word>>. We can also use commands to enhance the text +%D \type<<with <</bf boldfaced>> text>>. Just to be complete, we decided +%D to accept also \LaTeX\ alike verbatim, which means that \type+something+ +%D and \type|something| are valid commands too. Of course we want the grouped +%D alternatives to process \type{hello {\bf big} world} with braces. +%D \stoptyping +%D +%D In the core modules, we will build this support on top of +%D this module. There these commands can be tuned with +%D accompanying setup commands. There we can enable commands, +%D slanted typing, control spaces, \TAB||handling and (here we +%D are:) coloring. We can also setup surrounding white space +%D and indenting. Here we'll only show some examples. + +\unprotect + +%D \macros +%D {verbatimfont} +%D +%D When we are typesetting verbatim we use a non||proportional +%D (mono spaced) font. Normally this font is available by +%D calling \type{\tt}. In \CONTEXT\ this command does a +%D complete font||style switch. There we could have stuck with +%D \type{\tttf}. + +\ifx\verbatimfont\undefined \def\verbatimfont{\tt\normalnoligatures\font} \fi + +\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi + +%D \macros +%D {obeyedspace, obeyedtab, obeyedline, obeyedpage} +%D +%D We have followed Knuth in naming macros that make \SPACE, +%D \NEWLINE\ and \NEWPAGE\ active and assigning them +%D \type{\obeysomething}, but first we set some default values. + +\def\obeyedspace {\hbox{ }} +\def\obeyedtab {\obeyedspace} +\def\obeyedline {\par} +\def\obeyedpage {\vfill\eject} + +%D Because we will introduce a status variable, we can define +%D a better \type {\obeyedspace}. + +\def\obeyedspace {\ifprocessingverbatim\hbox{ }\else\space\fi} + +%D \macros +%D {controlspace,setcontrolspaces} +%D +%D First we define \type{\obeyspaces}. When we want visible +%D spaces (control spaces) we only have to adapt the definition +%D of \type{\obeyedspace} to: + +\def\controlspace{\hbox{\char32}} +\def\normalspace { } +\def\normalspaces{\catcode`\ =\@@space} + +\bgroup +\catcode`\ =\@@active +\gdef\obeyspaces{\catcode`\ =\@@active\def {\obeyedspace}} +\gdef\setcontrolspaces{\catcode`\ =\@@active\def {\controlspace}} +\egroup + +%D \macros +%D {obeytabs, obeylines, obeypages, +%D ignoretabs, ignorelines, ignorepages} +%D +%D Next we take care of \NEWLINE\ and \NEWPAGE\ and because we +%D want to be able to typeset listings that contain \TAB, we +%D have to handle those too. Because we have to redefine the +%D \NEWPAGE\ character locally, we redefine the meaning of +%D this (often already) active character. + +\catcode`\^^L=\@@active \def^^L{\par} + +%D The following indirect definitions enable us to implement +%D all kind of \type{\obeyed} handlers. + +\bgroup + +\catcode`\^^I=\@@active +\catcode`\^^M=\@@active +\catcode`\^^L=\@@active + +\gdef\obeytabs {\catcode`\^^I=\@@active\def^^I{\obeyedtab}} +\gdef\obeylines {\catcode`\^^M=\@@active\def^^M{\obeyedline}} +\gdef\obeypages {\catcode`\^^L=\@@active\def^^L{\obeyedpage}} + +\gdef\ignoretabs {\catcode`\^^I=\@@active\def^^I{\obeyedspace}} +\gdef\ignorelines {\catcode`\^^M=\@@active\def^^M{\obeyedspace}} +\gdef\ignorepages {\catcode`\^^L=\@@ignore} % \@@active\def^^L{\obeyedline}} +\gdef\ignoreeofs {\catcode`\^^Z=\@@ignore} + +%D For testing (see digit parser) we need an indirect macro +%D in order to compare the next (\type {\next}) token +%D (possibly \type {^^M}) being \type {\obeyedline}. + +\gdef\nextobeyedline{\obeyedline} + +\egroup + +%D \macros +%D {obeycharacters} +%D +%D We also predefine \type{\obeycharacters}, which will +%D enable us to implement character||specific behavior, like +%D colored verbatim. + +\let\obeycharacters=\relax + +%D \macros +%D {settabskips} +%D +%D The macro \type{\settabskip} can be used to enable tab +%D handling. Processing tabs is sometimes needed when one +%D processes a plain \ASCII\ listing. Tab handling slows down +%D verbatim typesetting considerably. + +\bgroup + +\catcode`\^^I=\@@active + +\gdef\settabskips + {\let\processverbatimline\doprocesstabskipline + \catcode`\^^I\@@active + \let^^I\doprocesstabskip} + +\gdef\setfixedtabskips#1% + {\catcode`\^^I\@@active + \def^^I{\kern#1\spaceskip}} + +\egroup + +%D \macros +%D {processingverbatim} +%D +%D Typesetting a file in most cases results in more than one +%D page. Because we don't want problems with files that are +%D read in during the construction of the page, we set \type +%D {\ifprocessingverbatim}, so the output routine can adapt +%D its behavior. Originally we used \type {\scratchread}, but +%D because we want to support nesting, we decided to use a +%D separate input file. + +\newif\ifprocessingverbatim + +%D \macros +%D {processinlineverbatim} +%D +%D Although the inline verbatim commands presented here will be +%D extended and embedded in the core modules of \CONTEXT, +%D they can be used separately. Both grouped and character +%D alternatives are provided but \type{<<} and nested +%D braces are implemented in the core module. This commands +%D takes one argument: the closing command. +%D +%D \starttyping +%D \processinlineverbatim{\closingcommand} +%D \stoptyping +%D +%D One can define his own verbatim commands, which can be very +%D simple: +%D +%D \starttyping +%D \def\Verbatim {\processinlineverbatim\relax} +%D \stoptyping +%D +%D or a bit more more complex: +%D +%D \starttyping +%D \def\GroupedVerbatim% +%D {\bgroup +%D \dosomeusefullthings +%D \processinlineverbatim\egroup} +%D \stoptyping +%D +%D Before entering inline verbatim mode, we take care of the +%D unwanted \TAB, \NEWLINE\ and \NEWPAGE\ characters and +%D turn them into \SPACE. We need the double \type{\bgroup} +%D construction to keep the closing command local. + +\def\setverbatimspaceskip + {\setbox\scratchbox\hbox{x}% + \spaceskip\wd\scratchbox + \xspaceskip\spaceskip} + +\def\setupinlineverbatim + {\verbatimfont + \setverbatimspaceskip + \let\obeytabs\ignoretabs + \let\obeylines\ignorelines + \let\obeypages\ignorepages + \setupcopyverbatim} + +\def\doprocessinlineverbatim + {\ifx\next\bgroup + \setupinlineverbatim + \catcode`\{\@@begingroup + \catcode`\}\@@endgroup + \def\next{\let\next=}% + \else + \setupinlineverbatim + \def\next##1{\catcode`##1=\@@endgroup}% + \fi + \next} + +\def\processinlineverbatim#1% + {\bgroup + \processingverbatimtrue + \localcatcodestrue % TeX processes paragraph's + \def\endofverbatimcommand{#1\egroup}% + \bgroup + \aftergroup\endofverbatimcommand + \futurelet\next\doprocessinlineverbatim} + +%D The closing command is executed afterwards as an internal +%D command and therefore should not be given explicitly when +%D typesetting inline verbatim. + +%D \macros +%D {optimizeverbatim} +%D +%D One day, a collegue asked me why I didn't prevent breaking +%D after a first or before a last verbatim line. At first sight +%D I thought of using the two pass mechanism, but because we're +%D already keeping track of individual lines, a more direct +%D solution is possible: we just keep track of in what line +%D we are. One can turn this feature off. + +\newif\ifoptimizeverbatim \optimizeverbatimtrue + +%D Before we implement display and file verbatim, we define +%D some macros that deal with typesetting the individual lines. +%D We keep track of the status by means of a character +%D specification. This status variable tells us if we're +%D skipping a first line or placing a first or last line. +%D The next few examples show us where breaks are inserted. +%D +%D \bgroup +%D +%D \def\doverbatimnobreak +%D {\nobreak\hrule width 10cm\par\penalty500} % == \nobreak +%D +%D \def\doverbatimgoodbreak +%D {\nobreak\hrule width 3cm \par\penalty\linepenalty} +%D +%D \starttyping +%D test +%D test +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D test +%D test +%D test +%D test +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D test +%D +%D test +%D test +%D test +%D \stoptyping +%D +%D \egroup +%D +%D The long ones are \type{\nobreaks} and the short ones +%D \type{\goodbreaks}. And this is how it's done: + +\def\doverbatimnobreak + {\ifoptimizeverbatim\penalty500\fi} + +\def\doverbatimgoodbreak + {\ifoptimizeverbatim\penalty\linepenalty\fi} + +\def\doflushverbatimline + {\expandafter\dodoverbatimline\expandafter{\savedverbatimline}} + +\let\handleverbatimline=\relax + +% \def\initializeverbatimline% +% {\global\let\savedverbatimline=\empty +% \ifskipfirstverbatimline +% \global\chardef\verbatimstatus=0 +% \else +% \global\chardef\verbatimstatus=1 +% \fi} +% +% more efficient + +\global\chardef\verbatimstatus0 + +\def\initializeverbatimline + {\global\let\savedverbatimline\empty + \global\chardef\verbatimstatus\ifskipfirstverbatimline0 \else1 \fi} + +\let\donextemptyverbatimline\relax + +\def\presetemptyverbatimline + {\ifcase\verbatimstatus + \global\chardef\verbatimstatus\plusone + \or + \or + \donextemptyverbatimline + \or + \doflushverbatimline + \global\let\savedverbatimline\empty + \doemptyverbatimline + \global\chardef\verbatimstatus\plustwo + \else + \kern\zeropoint + \doverbatimnobreak + \doflushverbatimline + \global\let\savedverbatimline\empty + \doemptyverbatimline + \global\chardef\verbatimstatus\plustwo + \fi} + +\def\presetnormalverbatimline + {\ifcase\verbatimstatus + \global\chardef\verbatimstatus\plustwo + \or + \global\chardef\verbatimstatus\plusthree + \or + \global\chardef\verbatimstatus\plusthree + \or + \doflushverbatimline + \global\chardef\verbatimstatus\plusfour + \or + \kern\zeropoint + \doverbatimnobreak + \doflushverbatimline + \global\chardef\verbatimstatus\plusfive + \or + \doverbatimgoodbreak + \doflushverbatimline + \fi + \global\let\savedverbatimline\verbatimline} + +\def\presetlastverbatimline + {\ifcase\verbatimstatus \or \or \or + \doflushverbatimline + \else + \kern\zeropoint + \doverbatimnobreak + \doflushverbatimline + \fi} + +%D \macros +%D {skipfirstverbatimline} +%D +%D By default the rest of the first line is ignored. We can +%D turn this feature off by saying: +%D +%D \starttyping +%D \skipfirstverbatimlinefalse +%D \stoptyping + +\newif\ifskipfirstverbatimline \skipfirstverbatimlinetrue + +%D \macros +%D {processdisplayverbatim} +%D +%D We can define a display verbatim environment with the +%D command \type{\processdisplayverbatim} in the following way: +%D +%D \starttyping +%D \processdisplayverbatim{\closingcommand} +%D \stoptyping +%D +%D \noindent For instance, we can define a simple command like: +%D +%D \starttyping +%D \def\BeginVerbatim {\processdisplayverbatim{EndVerbatim}} +%D \stoptyping +%D +%D \noindent But we can also do more advance things like: +%D +%D \starttyping +%D \def\BeginVerbatim {\bigskip \processdisplayverbatim{\EndVerbatim}} +%D \def\EndVerbatim {\bigskip} +%D \stoptyping +%D +%D When we compare these examples, we see that the backslash in +%D the closing command is optional. One is free in actually +%D defining a closing command. If one is defined, the command +%D is executed after ending verbatim mode. + +\def\processdisplayverbatim#1% + {\par + \bgroup + \escapechar=-1 + \xdef\verbatimname{\string#1}% + \egroup + \def\endofdisplayverbatim{\csname\verbatimname\endcsname}% + \bgroup + \parindent\zeropoint + \ifdim\lastskip<\parskip + \removelastskip + \vskip\parskip + \fi + \parskip\zeropoint + \processingverbatimtrue + \global\linepartrue + \expandafter\let\csname\verbatimname\endcsname\relax + \edef\endofverbatimcommand{\csname\verbatimname\endcsname}% + \edef\endofverbatimcommand{\meaning\endofverbatimcommand}% + \verbatimfont + \setverbatimspaceskip + \global\linepartrue % needed for paragraph numbering + \setupcopyverbatim + \initializeverbatimline + \copyverbatimline} + +%D We save the closing sequence in \type{\endofverbatimcommand} +%D in such a way that it can be compared on a line by line +%D basis. For the conversion we use \type{\meaning}, which +%D converts the line to non||expandable tokens. We reset +%D \type{\parskip}, because we don't want inter||paragraph +%D skips to creep into the verbatim source. Furthermore we +%D \type{\relax} the line||processing macro while getting the +%D rest of the first line. The initialization command +%D \type{\setupcopyverbatim} does just what we expect it to do: +%D it assigns all characters \CATCODE~11. Next we switch to +%D french spacing and call for obeyance. + +\newevery \everysetupverbatim \relax + +\def\setupcopyverbatim + {\uncatcodecharacters + \frenchspacing + \obeyspaces + \obeytabs + \obeylines + \obeypages + \obeycharacters + \the\everysetupverbatim} + +%D \macros +%D {eightbitcharacters, +%D setcatcodes,uncatcodespecials, +%D uncatcodecharacters,uncatcodespacetokens, +%D setnaturalcatcodes} +%D +%D As its name says, \type{\uncatcodecharacters} resets the +%D \CATCODE\ of characters. When we use an upper bound of +%D 127 or 255, depending in \type{\ifeightbitcharacters}. By +%D counting down, we only have to use one counter. The +%D macro \type{\setcatcodes} can be uses to set alternative +%D values. The macro \type{\resetspecialcharacters} resets +%D characters with special meanings. This macro is not used +%D in the verbatim macros, but is best defined in this module. + +\def\doprocesscatcodes#1% using a toks does not speed this up + {\scratchcounter\ifeightbitcharacters 255\else 127\fi\relax + \loop + \savecatcode + #1\relax + \advance\scratchcounter \minusone + \ifnum\scratchcounter>\minusone + \repeat + \let\savecatcode\relax + \let\restorecatcodes\dorestorecatcodes} + +\def\uncatcodespecials + {\doprocesscatcodes + {\ifnum\catcode\scratchcounter=\@@letter\relax\else + \catcode\scratchcounter=\@@other + \fi}% + \uncatcodespacetokens} + +\def\uncatcodespacetokens + {\catcode`\ =\@@space + \catcode`\^^L=\@@ignore + \catcode`\^^M=\@@endofline + \catcode`\^^?=\@@ignore} + +\def\setcatcodes#1% + {\doprocesscatcodes{\catcode\scratchcounter=#1}} + +\def\uncatcodeallcharacters % slow one, with restore + {\setcatcodes\@@letter} + +\def\uncatcodecharacters % quick one + {\setnaturalcatcodes} + +\newtoks\everycommoncatcodes +\newtoks\everynaturalcatcodes +\newtoks\everynormalcatcodes + +\def\setcommoncatcodes + {\catcode`\!\@@other \catcode`\?\@@other \catcode`\@\@@other + \catcode`\=\@@other \catcode`\<\@@other \catcode`\>\@@other + \catcode`\*\@@other \catcode`\/\@@other + \catcode`\-\@@other \catcode`\+\@@other + \catcode`\:\@@other \catcode`\;\@@other + \catcode`\.\@@other \catcode`\,\@@other + \catcode`\'\@@other \catcode`\"\@@other \catcode`\`\@@other + \catcode`\(\@@other \catcode`\)\@@other + \the\everycommoncatcodes} + +\def\setnaturalcatcodes % see elsewhere, merge 'm + {\setcommoncatcodes + \uncatcodespacetokens + \catcode`\#\@@other + \catcode`\$\@@other + \catcode`\%\@@other + \catcode`\&\@@other + \catcode`\\\@@other + \catcode`\^\@@other + \catcode`\_\@@other + \catcode`\{\@@other + \catcode`\|\@@other + \catcode`\}\@@other + \catcode`\~\@@other + \the\everynaturalcatcodes} + +\def\setnormalcatcodes + {\setcommoncatcodes + \uncatcodespacetokens + \catcode`\#\@@parameter + \catcode`\$\@@mathshift + \catcode`\%\@@comment + \catcode`\&\@@alignment + \catcode`\\\@@escape + \catcode`\^\@@superscript + \catcode`\_\@@subscript + \catcode`\{\@@begingroup + \catcode`\|\@@active + \catcode`\}\@@endgroup + \catcode`\~\@@active + \the\everynormalcatcodes} + +%D \macros +%D {localcatcodes, +%D restorecatcodes, +%D beginrestorecatcodes,endrestorecatcodes} +%D +%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we +%D use only one auxiliary file, which deals with tables of +%D contents, registers, two pass tracking, references etc. This +%D file, as well as files concerning graphics, is processed when +%D needed, which can be in the mid of typesetting verbatim. +%D However, when reading in data in verbatim mode, we should +%D temporary restore the normal \CATCODES, and that's exactly +%D what the next macros do. Saving the catcodes can be +%D disabled by saying \type{\localcatcodestrue}. + +%D The previous macros call for \type{\savecatcode}, which is +%D implemented as: + +\def\@@aa@@{@@aa@@} +\def\@@cc@@{@@cc@@} + +\newif\iflocalcatcodes + +\def\savecatcode + {\iflocalcatcodes \else + \saverestoreactivecatcode + {\@EA\let\csname\@@aa@@\the\scratchcounter\endcsname~}% + \@EA\chardef\csname\@@cc@@\the\scratchcounter\endcsname + \catcode\scratchcounter + \fi} + +%D It's counterpart is: + +\def\restorecatcode + {\@EA\catcode\@EA\scratchcounter + \csname\@@cc@@\the\scratchcounter\endcsname + \saverestoreactivecatcode + {\@EA\let\@EA~\csname\@@aa@@\the\scratchcounter\endcsname}} + +%D Especially when we enable pretty printing, we need to +%D restore the meaning of active characters too. Just think of +%D using \type{||} in headers and footers. + +\def\saverestoreactivecatcode#1% + {\edef\saveduccode{\the\uccode`~}% + \uccode`~=\scratchcounter + \uppercase{#1}% + \uccode`~=\saveduccode} + +%D When we want to restore \CATCODES\ we call for +%D \type{\restorecatcodes}, which default to \type{\relax} + +\let\restorecatcodes=\relax + +%D or when we've saved things calls for: + +\def\dorestorecatcodes + {\iflocalcatcodes \else + \doprocesscatcodes\restorecatcode + \fi} + +%D We also provide an alternative, that forces grouping +%D when needed. An application of this macros can be found in +%D buffering data. + +\def\beginrestorecatcodes + {\ifx\restorecatcodes\relax + \let\endrestorecatcodes\relax + \else + \bgroup + \restorecatcodes + \let\beginrestorecatcodes\bgroup + \let\endrestorecatcodes \egroup + \fi} + +%D \macros +%D {makeallother} +%D +%D With \type {\makeallother} each character ($>0$) gets the +%D category code 12. +%D +%D The next alternative was okay when memory was still low. +%D +%D \starttyping +%D \def\makeallother +%D {\dorecurse{255}{\catcode\recurselevel=\@@other}} +%D \stoptyping +%D +%D Today we prebuild a token list: + +\ifx\makeallother\undefined + + \newtoks\makeallothertoks + + \dorecurse{255} + {\@EA\appendtoks\@EA\catcode\recurselevel=\@@other\to\makeallothertoks} + + \def\makeallother{\the\makeallothertoks} + +\fi + +%D The main copying routine of display verbatim does an +%D ordinary string||compare on the saved closing command and +%D the current line. The space after \type{#1} in the +%D definition of \type{\next} is essential! As a result of +%D using \type{\obeylines}, we have to use \type{%}'s after +%D each line but none after the first \type{#1}. + +{\obeylines% + \long\gdef\copyverbatimline#1 + {\def\next{#1 }% + \gdef\verbatimline{#1}% + \ifx\next\emptyspace% + \presetemptyverbatimline% + \else% + \edef\next{\meaning\next}% + \ifx\next\endofverbatimcommand% + \presetlastverbatimline% + \def\copyverbatimline{\egroup\endofdisplayverbatim}% + \else% + \presetnormalverbatimline% + \fi% + \fi% + \handleverbatimline% + \copyverbatimline}} + +%D The actual typesetting of a line is done by a separate +%D macro, which enables us to implement \TAB\ handling. The +%D \type{\do} and \type{\dodo} macros take care of the +%D preceding \type{\parskip}, while skipping the rest of the +%D first line. The \type{\relax} is used as an signal. + +%D \macros +%D {iflinepar} +%D +%D A careful reader will see that \type{\linepar} is reset. +%D This boolean can be used to determine if the current line is +%D the first line in a pseudo paragraph and this boolean is set +%D after each empty line. The \type{\relax} can be used to +%D determine the end of the line when one implements a scanner +%D routine. + +\newif\iflinepar + +\let\doopenupverbatimline=\empty + +% \long\def\dodoverbatimline#1% +% {\leavevmode +% \doopenupverbatimline +% \the\everyline\strut\processverbatimline{#1\relax}% +% \EveryPar{}% +% \global\lineparfalse +% \obeyedline\par} + +\let\beginverbatimline\relax +\let\endverbatimline \relax + +\long\def\dodoverbatimline#1% we don't want to group + {\bgroup % due to pretty status + \iflinepar\else\EveryPar{}\fi + \leavevmode + \xdef\dokeepverbatimlinedata + {\parindent \the\parindent + \hangindent\the\hangindent + \hangafter \the\hangafter + \leftskip \the\leftskip + \rightskip \the\rightskip}% + \egroup + \dokeepverbatimlinedata + \doopenupverbatimline + \the\everyline\strut + \beginverbatimline + \processverbatimline{#1\relax\flushrestofverbatimline}% + \endverbatimline + \global\lineparfalse + \obeyedline\par} + +%D \macros +%D {flushrestofverbatimline} +%D +%D Some pretty drivers will collect tokens for the sake of +%D testing on keywords. This collected string needs to be +%D flushed. The \type {\relax} can serve as signal that there +%D is nothing more to be interpreted. + +\let\flushrestofverbatimline\empty + +%D \macros +%D {obeyemptylines,verbatimbaselineskip} +%D +%D Empty lines in verbatim can lead to white space on top of +%D a new page. Because this is not what we want, we turn +%D them into vertical skips. This default behavior can be +%D overruled by: +%D +%D \starttyping +%D \obeyemptylines +%D \stoptyping +%D +%D Although it would cost us only a few lines of code, we +%D decided not to take care of multiple empty lines. When a +%D (display) verbatim text contains more successive empty +%D lines, this probably suits some purpose. When applicable, +%D one can set the verbatim baselineskip. + +\bgroup +\catcode`\^^L=\@@active \gdef\emptypage {^^L} +\catcode`\^^M=\@@active \gdef\emptyline {^^M} + \gdef\emptyspace { } +\egroup + +\def\verbatimbaselineskip% We don't use \let here! + {\baselineskip} + +\def\doemptyverbatimline + {\vskip\verbatimbaselineskip + {\setbox0\hbox{\the\everyline}}% + \global\linepartrue} + +\def\obeyemptylines + {\let\donextemptyverbatimline\doemptyverbatimline} + +%D \TEX\ does not offer \type{\everyline}, which is a direct +%D result of its advanced multi||pass paragraph typesetting +%D mechanism. Because in verbatim mode paragraphs and lines are +%D more or less equal, we can easily implement our own simple +%D \type{\everyline} support. + +%D \macros +%D {EveryPar, EveryLine} +%D +%D In this module we've reserved \type{\everypar} for the +%D things to be done with paragraphs and \type{\everyline} for +%D line specific actions. In \CONTEXT\ however, we use +%D \type{\everypar} for placing side- and columnfloats, +%D inhibiting indentation and some other purposes. In verbatim +%D mode, every line becomes a paragraph, which means that +%D \type{\everypar} is executed frequently. To be sure, the +%D user specific use of both \type{\everyline} and +%D \type{\everypar} is implemented by means of +%D \type{\EveryLine} and \type{\EveryPar}. +%D +%D We still have to take care of the \TAB. A \TAB\ takes eight +%D spaces and a \SPACE\ normally has a width of 0.5~em. Because +%D we can be halfway a tabulation, we must keep track of the +%D position. This takes time, especially when we print complete +%D files, therefore we \type{\relax} this mechanism by default. + +\chardef\spacespertab=7 + +%\def\doprocesstabskip% +% {\obeyedspace % \hskip.5em or \hbox to .5em{} +% \ifdone +% \advance\scratchcounter 1 +% \let\next\doprocesstabskip +% \donefalse +% \else\ifnum\scratchcounter>\spacespertab +% \let\next\relax +% \else +% \advance\scratchcounter 1 +% \let\next\doprocesstabskip +% \fi\fi +% \next} + +\def\doprocesstabskip + {\obeyedspace % \hskip.5em or \hbox to .5em{} + \ifdone + \donefalse + \advance\scratchcounter \plusone + \@EA\doprocesstabskip + \else\ifnum\scratchcounter>\spacespertab + % nothing + \else + \advance\scratchcounter \plusone + \@EAEAEA\doprocesstabskip + \fi\fi} + +\let\endoftabskipping=\relax % will become obsolete + +% \def\doprocesstabskipline#1% +% {\bgroup +% \scratchcounter1 +% \dodoprocesstabskipline#1\relax\endoftabskipping +% \egroup} +% +% \def\dodoprocesstabskipline#1#2\endoftabskipping +% {\ifnum\scratchcounter>\spacespertab +% \scratchcounter\plusone +% \donetrue +% \else +% \advance\scratchcounter \plusone +% \donefalse +% \fi +% \ifx#1\relax +% \let\next\relax +% \else +% \def\next{#1\dodoprocesstabskipline#2\endoftabskipping}% +% \fi +% \next} + +\def\doprocesstabskipline#1% + {\bgroup + \scratchcounter\plusone + \dodoprocesstabskipline#1\relax + \egroup} + +\def\dodoprocesstabskipline#1% + {\ifnum\scratchcounter>\spacespertab\relax + \donetrue \else \donefalse \advance + \fi \scratchcounter \plusone + \ifx#1\relax \else + \ifcase\tabskipmode + % can't happen + \or + % go on + \else\ifnum`#1<128 + % ok, no special character + \else\ifnum\catcode`#1=\active + % quits parsing, else utf lookahead problems + \chardef\tabskipmode\zerocount + \fi\fi\fi + \ifcase\tabskipmode + \@EAEAEA#1% + \else + \@EAEAEA#1\@EAEAEA\dodoprocesstabskipline + \fi + \fi} + +% ^ will be replaced + +\chardef\tabskipmode=1 % 0=quit 1=no test 2=test on active>128 + +% + +\def\processverbatimline#1{#1} % remove the fake grouping + +%D \macros +%D {processfileverbatim} +%D +%D The verbatim typesetting of files is done on a bit different +%D basis. This time we don't check for a closing command, but +%D look for \EOF\ and when we've met, we make sure it does not +%D turn into an empty line. +%D +%D \starttyping +%D \processfileverbatim{filename} +%D \stoptyping +%D +%D We reserve a dedicated file handle. + +\newread\verbatiminput + +\newcount\verbatimlinenumber + +\let \beginofverbatimlines \relax +\let \endofverbatimlines \relax + +\def\processfileverbatim#1% + {\par + \bgroup + \processingverbatimtrue + \global\verbatimlinenumber0 + \global\linepartrue + \beginofverbatimlines + \bgroup + \parindent\zeropoint + \ifdim\lastskip<\parskip + \removelastskip + \vskip\parskip + \fi + \parskip\zeropoint + \uncatcodecharacters + \verbatimfont + \setverbatimspaceskip + \frenchspacing + \obeyspaces + \obeytabs + \obeylines + \obeypages + \obeycharacters + \ignoreeofs + \catcode`\^^M=\@@ignore % \par is already taken care of + \openin\verbatiminput=#1\relax + \skipfirstverbatimlinefalse + \initializeverbatimline + \def\readline% + {\ifeof\verbatiminput \else + \ifx\firstverbatimfileline\empty + \global\advance\verbatimlinenumber\plusone + \read\verbatiminput to \verbatimline + \else + \let\verbatimline\firstverbatimfileline + \let\firstverbatimfileline\empty + \fi + \fi + \ifeof\verbatiminput + \ifx\lastverbatimfileline\empty + \presetlastverbatimline + \let\readline\relax + \else % we will re-enter the \ifeof branch twice + \presetnormalverbatimline + \def\readline% + {\let\verbatimline\lastverbatimfileline + \let\lastverbatimfileline\empty}% + \fi + \else\ifx\verbatimline\empty + \presetemptyverbatimline + \else\ifx\verbatimline\emptyline + \presetemptyverbatimline + \else\ifx\verbatimline\emptypage + \presetemptyverbatimline + \else + \presetnormalverbatimline + \fi\fi\fi\fi + \handleverbatimline + \readline}% + \ifeof\verbatiminput \else + \expandafter\readline + \fi + \closein\verbatiminput + \egroup + \endofverbatimlines + \egroup + \ignorespaces} + +%D Something new: + +\def\processfilelinesverbatim#1#2#3% + {\bgroup + \let\saveddoflushverbatimline\doflushverbatimline + \let\saveddoemptyverbatimline\doemptyverbatimline + \def\checkverbatimfileline##1% + {\ifnum\verbatimlinenumber<#2\else + \ifnum\verbatimlinenumber>#3\else + ##1% + \fi\fi}% + \def\doflushverbatimline + {\checkverbatimfileline\saveddoflushverbatimline}% + \def\doemptyverbatimline + {\checkverbatimfileline\saveddoemptyverbatimline}% + \processfileverbatim{#1}% + \egroup} + +%D \macros +%D {firstverbatimfileline, lastverbatimfileline} +%D +%D The following two macros can be set to achieve special +%D effects, like: +%D +%D \starttyping +%D \convertargument\StartFake{something}\to\firstverbatimfileline +%D \convertargument\StopFake\to\firstverbatimfileline +%D \stoptyping +%D +%D These hooks were needed for typesetting flowchart +%D definitions verbatim, since the temporary files does not +%D have the start and stop commands embedded. + +\let\firstverbatimfileline\empty +\let\lastverbatimfileline \empty + +%D One can use the different \type{\obeysomething} commands to +%D influence the behavior of these macro's. We use for instance +%D \type{\obeycharacters} for making \type{/} an active +%D character when we want to include typesetting commands. + +%D The next part of this module deals with pretty printing. The +%D best way to understand how pretty verbatim typeseting works +%D is to take a look at the output produced by the \TEX, \PERL\ +%D and \METAPOST\ modules first. Each of these modules has a +%D few setup macros that tag the individual characters with a +%D number that itself is associated to a interpretation macro. +%D A previous implementation linked characters (after making +%D them active) directly to such interpreters, but the more +%D indirect way makes it possible to inspect the next +%D character(s) without much expansion problems and/or +%D increasing run time. + +%D By the way, \TEX\ defines \type{\+} as an outer macro, so we +%D have to redefine this one to keep ourselves out of complaints. + +\def\+{\tabalign} + +%D Just to keep things consistant and to speed up some macros a +%D but, we define a few private constants. + +\def\!!PRETTY {PRETTY} + +\def\!!prettyone {prettyone} +\def\!!prettytwo {prettytwo} +\def\!!prettythree {prettythree} +\def\!!prettyfour {prettyfour} + +%D The first step in defining a pretty interpreter is to assign +%D each character that needs special attention a number, like: +%D +%D \starttyping +%D \setpretty \`A 21 +%D \stoptyping +%D +%D Here the macro \type{\setpretty} makes the character +%D \type{A} active, and sets it meaning to the auxiliary macro +%D \type{\handleprettytoken}. This auxiliary macro takes the +%D character code (a number) and the interpretation number. The +%D three step implementation uses the \TEX book \type{~} trick. + +\def\dodosetpretty + {\!!countb=\uccode`~\relax + \catcode\!!countb=\@@active + \uppercase{\edef~{\noexpand\handleprettytoken{\the\!!counta}{\the\!!countb}}}} + +\def\dosetpretty + {\afterassignment\dodosetpretty\!!counta} + +\def\setpretty + {\afterassignment\dosetpretty\uccode`~=} + +%D The macro \type{\handleprettytoken} is rather trivial and +%D calls for an interpreter macro. + +\def\handleprettytoken#1% + {\csname\!!PRETTY#1\endcsname} % \getvalue{\!!PRETTY#1}} + +%D This interpreter is installed by saying +%D +%D \starttyping +%D \installprettyhandler 21 \SOMEprettyone +%D \stoptyping + +\def\installprettyhandler#1 #2% + {\letvalue{\!!PRETTY#1}#2} + +%D Such an interpreter gets the character number: +%D +%D \starttyping +%D \def\SOMEprettyone#1{...\getpretty{#1}...} +%D \stoptyping +%D +%D where \type{\getpretty} equals \type{\char}. We can't +%D use \type{\let} here because we have to get rid of the +%D braces. + +\def\getpretty#1% + {\char#1} + +%D Sometimes the action depends on the next token. This token +%D can be passed to the macro \type{\getprettydata}, that sets +%D \type{\prettytype} to the interpreter code. The character +%D code is saved in \type{\prettychar}. + +\def\setprettydata#1#2% + {\global\chardef\prettytype#1% + \global\chardef\prettychar#2\relax} + +\def\getprettydata#1% + {\global\chardef\prettytype\zerocount + \global\chardef\prettychar\zerocount + \bgroup + \let\handleprettytoken\setprettydata + \setbox0\hbox{#1}% expands #1 and ignores space + \egroup} + +%D If needed the current and next token can be handled alongside: + +\def\getpretties#1#2% + {\char#1\bgroup\let\handleprettytoken\getsecondpretty#2\egroup} + +\def\getsecondpretty#1#2% + {\char#2} + +%D When needed, one can reassign an interpreter by using +%D \type{\newpretty} and its associates. +%D +%D \bgroup +%D \setuptyping[file][optionoptie=tex,paletpalet=colorpretty] +%D +%D \startbuffer +%D \bgroup +%D \catcode`\|=\@@escape %%\|\ +%D \catcode`\\=\@@active %%\\+ +%D |gdef|dohandlenewpretty#1% +%D {|def|dodohandlenewpretty##1% +%D {|def|oldprettychar{#1}% +%D |getprettydata{##1}% +%D |ifnum|oldprettychar=|prettychar +%D |def|dododohandlenewpretty####1% +%D {|getprettydata{\}% +%D |let|oldprettytype=|prettytype +%D |getprettydata{####1}% +%D |ifnum|prettytype=|oldprettytype +%D |let|next=|newpretty +%D |else +%D |def|next{|newprettycommand{#1}##1####1}% +%D |fi +%D |next}% +%D |let|next=|dododohandlenewpretty +%D |else +%D |def|next{|newprettycommand{#1}##1}% +%D |fi +%D |next}% +%D |def|donohandlenewpretty##1% +%D {|newprettycommand{#1}##1}% +%D |handlenextnextpretty|dodohandlenewpretty|donohandlenewpretty} +%D |egroup +%D \stopbuffer +%D +%D {\newprettytrue\typebuffer} +%D +%D In this example we see that the colors differ from what we +%D expect, but conform the definitions in the macro. This kind +%D of recoloring can be achieved by saying: +%D +%D \typebuffer +%D +%D We'll show some more examples: +%D +%D \startbuffer[pretty] +%D \installnewpretty r \red +%D \installnewpretty g \green +%D \installnewpretty b \blue +%D \stopbuffer +%D +%D \getbuffer[pretty] +%D +%D \startbuffer +%D %%\ r{Red +%D %%\ g\Green +%D %%\ b[Blue +%D \stopbuffer +%D +%D {\newprettytrue\typebuffer} +%D +%D Watch the green \type{\Green}! This lines are specified as: +%D +%D \typebuffer +%D +%D along with: +%D +%D \typebuffer[pretty] +%D +%D When needed, one can use grouping. +%D +%D \startbuffer +%D {yes} %%\ B %%\{[ %%\}] +%D {no} +%D {no} %%\ E +%D {yes} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we tell the visualizer that the \type +{+ should be +%D treated like a \type +[+ so we get: +%D +%D {\newprettytrue\typebuffer} +%D +%D I won't explain the details of this mechanism. Those who +%D want to build their own pretty interpreters have to close +%D read the source anyway. +%D +%D Last we show an example of mixed pretty typesetting: +%D +%D \startbuffer +%D \ziezo{test} %%\ P ##\ B##\ T % enter PERL mode %%\ E +%D if $test eq "test" ##\ B ##\ B##\ T % begin group (\bgroup) %%\ E +%D if $test eq "test"; ##\ T %%\ B%%\ T % enter TEX mode %%\ E +%D \ziezo{test} %%\ M %%\ B%%\ T % enter METAPOST mode %%\ E +%D draw (0,0)--(10,10); %%\ E ##\ B##\ T % end group (\egroup) %%\ E +%D if $test eq "test"; +%D \stopbuffer +%D +%D \typebuffer +%D +%D Here we use \type{%%\ T}, \type{%%\ P} and \type{%%\ M} for +%D switching between \TEX, \PERL\ and \METAPOST\ mode. +%D +%D {\newprettytrue\typebuffer} +%D +%D \egroup +%D +%D Don't forget to set: + +\newif\ifnewpretty + +\def\installnewpretty + {\def\doinstallnewpretty##1% + {\setvalue{NP::\the\scratchcounter}{##1}}% + \afterassignment\doinstallnewpretty\scratchcounter=`} + +%D Let's define the options we used here: + +\newevery\everyprettyend\relax + +\let\prettyend=\relax + +\def\prettybegin + {\bgroup\def\prettyend{\the\everyprettyend\egroup}} + +\installnewpretty B \prettybegin +\installnewpretty E \prettyend + +\installnewpretty J \setupprettyJVtype +\installnewpretty M \setupprettyMPtype +\installnewpretty P \setupprettyPLtype +\installnewpretty T \setupprettyTEXtype + +%D \macros +%D {ifnaturaltextext} +%D +%D When one uses \ETEX, switching to normal \TEX\ is possible +%D too. We also introduce a switch that can be used in the +%D drivers and set in higher level shell macros. + +\newif\ifnaturaltextext + +% \starttyping +% test /naturaltextext\hpos{word}{test}/relax test +% \stoptyping +% +% \MPxy{word} + +\beginETEX \scantokens + +%\def\naturaltextext#1#2\relax +% {\bgroup\prettynaturalfont{\restorecatcodes\scantokens{\ignorespaces#2}}\egroup} + +\def\naturaltextext#1\relax + {\bgroup + \prettynaturalfont{\restorecatcodes\scantokens{\ignorespaces#1}}% + \egroup} + +\def\naturaltextext#1\relax + {\bgroup + \def\ascii{#1}% + \setnormalcatcodes + \restorecatcodes + \prettynaturalfont{\scantokens\expandafter{\ascii}\ifhmode\unskip\fi}% + \egroup} + +\endETEX + +\beginTEX + +\def\naturaltextext + {\disableprettynow} + +\endTEX + +\installnewpretty N \naturaltextext + +%D When seen in action this gives: +%D +%D \startbuffer +%D \startTEX +%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}} +%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{X^2} +%D \stopTEX +%D \stopbuffer +%D +%D \getbuffer +%D +%D This is keyed in as: +%D +%D \typebuffer + +%D This means that when the interpreter modules support this +%D mechanism, by default we have some keys already available. + +\def\newpretty#1% + {\getprettydata{#1}% + \ifcase\prettytype + \expandafter\nonewpretty + \else + \expandafter\donewpretty + \fi + #1} + +\def\nonewpretty#1#2% + {\getprettydata{#2}% + \getvalue{NP::\the\prettychar}} + +\def\donewpretty#1% + {\bgroup + \def\handleprettytoken##1##2##3% + {\getprettydata{##3}% + \egroup + \ifcase\prettytype\else + \setpretty##2=\prettytype\relax + \fi}% + #1} + +%D When implementing new pretty macros, one only needs to +%D define something like: +%D +%D \starttyping +%D \def\TEXtypezero% +%D {\handlenewpretty\TEXtypethree} +%D \stoptyping +%D +%D Here the number states the category (in our examples the +%D backslash). The second argument takes care of normal +%D situations. + +\def\handlenewpretty#1% + {\let\newprettycommand=#1% + \handlenextnextpretty\dohandlenewpretty\newprettycommand} + +%D The previous shown implementation only interprets single +%D comments, but the final one also accepts double ones. The +%D main reason for this is that in \JAVA\ we have to deal with +%D \type{//}. Personally I prefer the double \type{%%} because +%D is stands out and is more symmetrical with the double +%D slash. + +\bgroup +\catcode`\|=\@@escape +\catcode`\\=\@@active +|gdef|dohandlenewpretty#1% + {|def|dodohandlenewpretty##1% + {|def|oldprettychar{#1}% + |getprettydata{##1}% + |ifnum|oldprettychar=|prettychar + |def|dododohandlenewpretty####1% + {|getprettydata{\}% + |let|oldprettytype=|prettytype + |getprettydata{####1}% + |ifnum|prettytype=|oldprettytype + |let|next|newpretty + |else + |def|next{|newprettycommand{#1}##1####1}% + |fi + |next}% + |let|next|dododohandlenewpretty + |else + |def|next{|newprettycommand{#1}##1}% + |fi + |next}% + |def|donohandlenewpretty##1% + {|newprettycommand{#1}##1}% + |handlenextnextpretty|dodohandlenewpretty|donohandlenewpretty} +|egroup + +%D The `nextnext' macro we used in the previous definition +%D looks ahead. This is needed because individual lines are +%D handles by macro's and the next character can be something +%D that ends the line and/or does not belong to the verbatim +%D data. + +% \def\handlenextnextpretty#1#2#3% +% {\def\dohandlenextnextpretty% +% {\ifx\next\bgroup % something {} +% \let\next=#2% +% \else\ifx\next\relax % end of line / signal +% \let\next=#2% +% %\else\ifx\next\egroup % end of line / no signal +% % \let\next=#2% +% %\else\ifx\next\par % end of line / \par +% % \let\next=#2% +% \else +% \let\next=#1% +% \fi\fi%\fi\fi +% \next{#3}}% +% \futurelet\next\dohandlenextnextpretty} + +\def\handlenextnextpretty#1#2#3% + {\def\dohandlenextnextpretty% + {\ifx\next\bgroup % something {} + \@EA#2% + \else\ifx\next\relax % end of line / signal + \@EAEAEA#2% + \else + \@EAEAEA#1% + \fi\fi + {#3}}% + \futurelet\next\dohandlenextnextpretty} + +%D The pretty interpreters can (and will) change the meaning of +%D some controls. To enable them calling the originals we save +%D their meanings and to enable nesting we permit this only +%D once. + +\def\saveprettycontrols + {\global\let\oldobeyedspace \obeyedspace + \global\let\oldobeyedline \obeyedline + \global\let\oldobeyedpage \obeyedpage + \let\saveprettycontrols \relax} + +%D The \PERL\ and \METAPOST\ interpreters will also handle +%D reserved words. Sets of identifiers are defined like: +%D +%D \starttyping +%D \useprettyidentifiers \MODULAidentifiers \MODULAsetspecials +%D if then else elsif case while do repeat until ... +%D \stoptyping +%D +%D New entries can be added to existing sets by repeatedly +%D using this command. + +\def\useprettyidentifiers#1#2% \variable \presetcatcodes + {\bgroup + \ifx#1\undefined + \global\let#1=\empty + \fi + \def\handleprettytoken##1##2{\char##2}% + #2\relax + \def\douseprettyidentifiers##1\par% + {\xdef#1{\space#1\space##1}% + \egroup}% + \douseprettyidentifiers} + +%D We can test om identifiers with: + +\def\doifprettyidentifierelse#1% + {\doifincsnameelse{\space#1\space}} + +%D \macros +%D {prettyidentifierfont,prettyvariablefont,prettynaturalfont} +%D +%D When one want to typeset identifiers and system variables +%D in a different typeface, one has to set the next two +%D variables. + +\let\prettyidentifierfont=\relax +\let\prettyvariablefont =\relax +\let\prettynaturalfont =\relax + +%D The interpreter macros are loaded at run time. The main +%D reason lays in the fact that we don't want to have the +%D identifier lists hard coded in the format file. To prevent +%D repetitive loading, one should load the modules before the +%D first call to the macros. +%D +%D \starttyping +%D \input verb-tex.tex +%D \input verb-pl.tex +%D \input verb-mp.tex +%D \input verb-jv.tex +%D \stoptyping +%D +%D In \CONTEXT\ we follow a different thread, and therefore all +%D macros in the additional modules use \type {\gdef}'s and +%D \type {\doglobal}'s. Manipulating \type {\globaldef} is +%D possible but leads to fuzzy situations. + +%D \macros +%D {ifdisablepretty,disableprettynow,disableprettyafterwards} +%D +%D Although for pretty printing \PERL\ and \JAVASCRIPT\ code +%D one has to implement a bit more clever mechanism, the next +%D switches can be used to turn off pretty printing. The +%D boolean turns on this feature. + +\newif\ifdisablepretty \disableprettyfalse +\newif\ifprettydisabled \prettydisabledfalse + +\def\disableprettynow + {\ifdisablepretty\ifprettydisabled\else + \let\prettyidentifierfont\relax + \let\prettyvariablefont\relax + \let\prettycomment\relax + \def\beginofpretty[##1]{}% + \let\endofpretty\relax + \prettydisabledtrue + \fi\fi} + +\def\disableprettyafterwards + {\ifdisablepretty\ifprettydisabled\else + \def\endofpretty{\normalendofpretty\disableprettynow}% + \fi\fi} + +\def\enableprettynow + {\prettydisabledfalse + \let\prettyidentifierfont\normalprettyidentifierfont + \let\prettyvariablefont \normalprettyvariablefont + \let\prettynaturalfont \normalprettynaturalfont + \let\beginofpretty \normalbeginofpretty + \let\endofpretty \normalendofpretty} + +%D This feature is hooked into the verbatim line handling +%D routine with: + +\def\beginverbatimline + {\prettydisabledfalse + \ifnewpretty\else\let\handlenewpretty\empty\fi % moved + \let\normalprettyidentifierfont\prettyidentifierfont + \let\normalprettyvariablefont \prettyvariablefont + \let\normalprettynaturalfont \prettynaturalfont + \let\normalbeginofpretty \beginofpretty + \let\normalendofpretty \endofpretty} + +\def\endverbatimline + {\enableprettynow} + +%D The rest of this module is dedicated to non \CONTEXT\ users +%D and shows an example of an verbatim environment based on the +%D previous macros. +%D +%D The macro's can be used to construct the commands we +%D mentioned in the beginning of this documentation. We leave +%D this to the fantasy of the reader and only show some \PLAIN\ +%D \TEX\ alternatives for display verbatim and listings. We +%D define three commands for typesetting inline text, display +%D text and files verbatim. The inline alternative also accepts +%D user supplied delimiters. +%D +%D \starttyping +%D \type{text} +%D +%D \starttyping +%D ... verbatim text ... +%D \stoptyping +%D +%D \typefile{filename} +%D \stoptyping +%D +%D We can turn on the options by: +%D +%D \starttyping +%D \controlspacetrue +%D \verbatimtabstrue +%D \prettyverbatimtrue +%D \stoptyping +%D +%D Here is the implementation: + +\newif\ifcontrolspace +\newif\ifverbatimtabs +\newif\ifprettyverbatim + +\ifCONTEXT \else + + \def\presettyping + {\ifcontrolspace \let\obeyspace \setcontrolspace \fi + \ifverbatimtabs \let\obeytabs \settabskips \fi + \ifprettyverbatim \let\obeycharacters\setupprettytype \fi} + + \def\type + {\bgroup + \def\_{\string_}% + \def\^{\string^}% + \presettyping + \processinlineverbatim\egroup} + + \def\starttyping + {\bgroup + \presettyping + \processdisplayverbatim\stoptyping} + + \def\stoptyping + {\egroup} + + \def\typefile#1% + {\bgroup + \presettyping + \processfileverbatim{#1}% + \egroup} + +\fi + +%D In \CONTEXT\ users say things like: +%D +%D \starttyping +%D \definetyping [TEX] [option=TEX] +%D \definetyping [MP] [option=MP] +%D \definetyping [PL] [option=PL] +%D \definetyping [JV] [option=JV] +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D \setuptyping[file][option=color] +%D \stoptyping +%D +%D That way \CONTEXT\ selects the appropriate interpreter +%D itself, but more on that in another module. In other +%D packages one can define: + +\ifCONTEXT \else + + \input verb-tex + \input verb-mp + \input verb-pl + \input verb-jv + \input verb-sql + + \def\startTEX + {\bgroup \everypar{}% + \let\obeycharacters\setupprettyTEXtype + \processdisplayverbatim{\stopTEX}} + + \def\startMP + {\bgroup \everypar{}% + \let\obeycharacters\setupprettyMPtype + \processdisplayverbatim{\stopMP}} + + \def\startPL + {\bgroup \everypar{}% + \let\obeycharacters\setupprettyPLtype + \processdisplayverbatim{\stopPL}} + + \def\startJV + {\bgroup \everypar{}% + \let\obeycharacters\setupprettyJVtype + \processdisplayverbatim{\stopJV}} + + \def\startSQL + {\bgroup \everypar{}% + \let\obeycharacters\setupprettySQLtype + \processdisplayverbatim{\stopSQL}} + + \let\stopTEX=\egroup + \let\stopMP =\egroup + \let\stopPL =\egroup + \let\stopJV =\egroup + \let\stopSQL=\egroup + +\fi + +%D This following poor mans implementation of color is based on +%D PostScript. One can of course use grayscales too. In the +%D core modules these macros are redefined to using the color +%D mechanism present in \CONTEXT. + +\ifCONTEXT \else + + \def\setcolorverbatim + {\def\prettyone {.9 .0 .0 } % red + \def\prettytwo {.0 .8 .0 } % green + \def\prettythree {.0 .0 .9 } % blue + \def\prettyfour {.8 .8 .6 } % yellow + \def\beginofpretty[##1]% + {\special{ps:: \csname##1\endcsname setrgbcolor}} + \def\endofpretty% + {\special{ps:: 0 0 0 setrgbcolor}}} % black + + \def\setgrayverbatim + {\def\prettyone {.30 } % gray + \def\prettytwo {.45 } % gray + \def\prettythree {.60 } % gray + \def\prettyfour {.75 } % gray + \def\beginofpretty[##1]% + {\special{ps:: \csname##1\endcsname setgray}} + \def\endofpretty% + {\special{ps:: 0 setgray}}} % black + +\fi + +%D One can redefine these two commands after loading this +%D module. When available, one can also use appropriate +%D font||switch macro's. We default to color. + +\ifCONTEXT \else \setcolorverbatim \fi + +%D Here come the commands that are responsible for entering and +%D leaving the two states. As we can see, they've got much in +%D common. + +%D The previous version of this module was published in the +%D \MAPS\ of the dutch \TEX\ users group \NTG. In that article, +%D the verbatim part of the text was typeset with the following +%D commands for the examples: +%D +%D \starttyping +%D \def\starttyping% We simplify the \ConTeXt\ macro. +%D {\bgroup +%D \everypar{} % We disable some troublesome mechanisms. +%D \advance\leftskip by 1em +%D \processdisplayverbatim{\stoptyping}} +%D +%D \let\stoptyping=\egroup +%D \stoptyping +%D +%D We also used: +%D +%D \starttyping +%D \def\startdefinition% +%D {\bgroup +%D \everypar{} % Again we disable some troublesome mechanisms. +%D \let\obeycharacters=\setupprettyTEXtype % See verb-tex.tex! +%D \EveryPar{\showparagraphcounter}% +%D \EveryLine{\showlinecounter}% +%D \verbatimbodyfont +%D \processdisplayverbatim{\stopdefinition}} +%D +%D \def\stopdefinition% +%D {\egroup} +%D \stoptyping +%D +%D And because we have both \type{\EveryPar} and +%D \type{\EveryLine} available, we can implement a dual +%D numbering mechanism: +%D +%D \starttyping +%D \newcount\paragraphcounter +%D \newcount\linecounter +%D +%D \def\showparagraphcounter% +%D {\llap +%D {\bgroup +%D \counterfont +%D \hbox to 4em +%D {\global\advance\paragraphcounter by 1 +%D \hss \the\paragraphcounter \hskip2em}% +%D \egroup +%D \hskip1em}} +%D +%D \def\showlinecounter% +%D {\llap +%D {\bgroup +%D \counterfont +%D \hbox to 2em +%D {\global\advance\linecounter by 1 +%D \hss \the\linecounter}% +%D \egroup +%D \hskip1em}} +%D \stoptyping +%D +%D One may have noticed that the \type{\EveryPar} is only +%D executed once, because we consider each piece of verbatim +%D as one paragraph. When one wants to take the empty lines +%D into account, the following assignments are appropriate: +%D +%D \starttyping +%D \EveryLine +%D {\iflinepar +%D \showparagraphcounter +%D \fi +%D \showlinecounter} +%D \stoptyping +%D +%D In this case, nothing has to be assigned to \type{\EveryPar}, +%D maybe except of just another extra numbering scheme. The +%D macros used to typeset this documentation are a bit more +%D complicated, because we have to take take 'long' margin +%D lists into account. When such a list exceeds the previous +%D pargraph we postpone placement of the paragraph number till +%D there's room. This way so it does not clash with the margin +%D words. + +%D Normally such commands have to be embedded in a decent setup +%D structure, where options can be set at will. +%D +%D Now let's summarize the most important commands. +%D +%D \starttyping +%D \processinlineverbatim{\closingcommand} +%D \processdisplayverbatim{\closingcommand} +%D \processfileverbatim{filename} +%D \stoptyping +%D +%D We can satisfy our own specific needs with the following +%D interfacing macro's: +%D +%D \starttyping +%D \obeyspaces \obeytabs \obeylines \obeypages \obeycharacters +%D \stoptyping +%D +%D We can influence the verbatim environment with the following +%D macro: +%D +%D \starttyping +%D \obeyemptylines +%D \stoptyping +%D +%D Some needs are fulfilled already with: +%D +%D \starttyping +%D \setcontrolspace \settabskips +%D \stoptyping +%D +%D lines can be enhanced with ornaments using: +%D +%D \starttyping +%D \everypar \everyline \iflinepar +%D \stoptyping +%D +%D and pretty verbatim support is implemented by: +%D +%D \starttyping +%D \beginofpretty[#1] ... \endofpretty +%D \stoptyping +%D +%D and some setup macro, like: +%D +%D \starttyping +%D \setupprettyIDENTIFIERtype +%D \stoptyping +%D +%D The color support macro can be redefined by the user. The +%D parameter \type{#1} can be one of the four 'fixed' +%D identifiers {\em prettyone}, {\em prettytwo}, {\em +%D prettythree} and {\em prettyfour}. We have implemented a +%D more or less general PostScript color support mechanism, +%D using \type{specials}. One can toggle between color and +%D grayscale with: +%D +%D \starttyping +%D \setgrayverbatim \setcolorverbatim +%D \stoptyping + +%D \macros +%D {permitshiftedendofverbatim} +%D +%D We did not mention one drawback of the mechanism described +%D here. The closing command must start at the first position +%D of the line. In \CONTEXT\ we will not have this drawback, +%D because we can test if the end command is a substring of the +%D current line. The testing is done by two of the support +%D macros, which of course are not available in a stand alone +%D application of this module. + +\ifCONTEXT + + \let\doifendofverbatim=\doifelse + + \def\permitshiftedendofverbatim + {\let\doifendofverbatim\doifinstringelse} + +% \def\processdisplayverbatim#1% +% {\par +% \bgroup +% \escapechar=-1 +% \xdef\verbatimname{\string#1}% +% \egroup +% \def\endofdisplayverbatim{\csname\verbatimname\endcsname}% +% \bgroup +% \parindent\zeropoint +% \ifdim\lastskip<\parskip +% \removelastskip +% \vskip\parskip +% \fi +% \parskip\zeropoint +% \processingverbatimtrue +% \expandafter\let\csname\verbatimname\endcsname=\relax +% \expandafter\convertargument\csname\verbatimname\endcsname +% \to\endofverbatimcommand +% \verbatimfont +% \setverbatimspaceskip +% \global\linepartrue % needed for paragraph numbering +% \setupcopyverbatim +% \initializeverbatimline +% \copyverbatimline} + + {\obeylines% + \long\gdef\copyverbatimline#1 + {\convertargument#1 \to\next% + \gdef\verbatimline{#1}% + \ifx\next\emptyspace% + \presetemptyverbatimline% + \else% + \doifendofverbatim{\endofverbatimcommand}{\next}% + {\presetlastverbatimline% + \def\copyverbatimline{\egroup\endofdisplayverbatim}}% + {\presetnormalverbatimline}% + \fi% + \handleverbatimline% + \copyverbatimline}} + +%D As a bonus, we provide the next alternative, which takes +%D end tags like \type {Hello World!}. + +% \def\processtaggeddisplayverbatim#1% +% {\par +% \let\endofdisplayverbatim\relax +% \convertargument#1\to\endofverbatimcommand +% \bgroup +% \parindent\zeropoint +% \ifdim\lastskip<\parskip +% \removelastskip +% \vskip\parskip +% \fi +% \parskip\zeropoint +% \processingverbatimtrue +% \verbatimfont +% \setverbatimspaceskip +% \global\linepartrue % needed for paragraph numbering +% \setupcopyverbatim +% \initializeverbatimline +% \copyverbatimline} + + \def\doprocessdisplayverbatim#1#2% + {\par + \bgroup + \escapechar-1 + \xdef\verbatimname{\string#2}% + \egroup + \ifcase#1% + \let\endofdisplayverbatim\relax + \else + \def\endofdisplayverbatim{\csname\verbatimname\endcsname}% + \fi + \bgroup + \parindent\zeropoint + \ifdim\lastskip<\parskip + \removelastskip + \vskip\parskip + \fi + \parskip\zeropoint + \processingverbatimtrue + \ifcase#1% + \convertargument#2\to\endofverbatimcommand + \else + \expandafter\let\csname\verbatimname\endcsname=\relax + \expandafter\convertargument\csname\verbatimname\endcsname + \to\endofverbatimcommand + \fi + \verbatimfont + \setverbatimspaceskip + \global\linepartrue % needed for paragraph numbering + \setupcopyverbatim + \initializeverbatimline + \copyverbatimline} + + \def\processdisplayverbatim {\doprocessdisplayverbatim1} + \def\processtaggeddisplayverbatim{\doprocessdisplayverbatim0} + +\fi + +%D \macros +%D {installprettyescape} +%D +%D The next feature is dedicated to Fabrice Popineau who +%D wanted math inside verbatim. + +\def\prettyescapecnt{255} + +\def\installprettyescape + {\dodoubleempty\doinstallprettyescape} + +\def\doinstallprettyescape[#1][#2]#3 #4% + {\bgroup + \doglobal\decrement\prettyescapecnt + \def\docommando##1% + {\def\next{\dodoinstallprettyescape{##1}{#3}{#4}}% + \catcode`#3=\@@active + \@EA\scantokens\@EA{\next}}% + \iffirstargument + \processcommalist[#1]\docommando + \else + \docommando\empty + \fi} + +\def\dodoinstallprettyescape#1#2#3% + {\unexpanded\setgvalue{PRETTY@#1@\prettyescapecnt}##1##2#2{#3{##2}}% + \expanded % we need to freeze the counter + {\doglobal\noexpand\appendtoks + \noexpand\doif{#1}\noexpand\prettyidentifier + {\noexpand\setpretty`\string#2=\prettyescapecnt + \noexpand\installprettyhandler \prettyescapecnt\space\getvalue{PRETTY@#1@\prettyescapecnt}}% + }\to \everysetupverbatim + \egroup} + +%D An example of its usage is: +%D +%D \startbuffer +%D \def\xverbatimmath#1#2{\naturaltextext\mathematics{#1}\relax} +%D \def\yverbatimmath#1#2{\naturaltextext\mathematics{[[#1]]}\relax} +%D \def\zverbatimmath#1#2{\naturaltextext\mathematics{(#1)}\relax} +%D +%D \installprettyescape [MP] $ \xverbatimmath +%D \installprettyescape [MP] ~ \yverbatimmath +%D \installprettyescape [MP] * \zverbatimmath +%D +%D \startMP +%D if $x>10$ : +%D $x := 20$ +%D ~x := 20~ +%D *x := 20* +%D end +%D \stopMP +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\protect \endinput |