%D \module %D [ file=supp-ver, %D version=1995.10.10, %D title=\CONTEXT\ Support Macros, %D subtitle=Verbatim, %D author=J. Hagen, %D date=\huidigedatum, %D copyright=J. Hagen] % % This module is part of \CONTEXT, a general purpose, % parameter driven, macro package programmed in \TEX. This % module may only be distributed as part of \CONTEXT. %D Because this module is quite independant of system macros, %D it can be used as a stand||alone verbatim environment. \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 Support Macros / Verbatim} %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 \starttypen %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 \stoptypen %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 \starttypen %D We can say \type<> or \type{something}. The first one is a bit %D longer but also supports slanted typing, which accomplished by typing %D \type<> word>>. We can also use commands to enhance the text %D \type<> 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 \stoptypen %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 %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 \undefined \verbatimfont \def\verbatimfont {\tt} \fi %D \macros %D {obeyedspace, obeyedtab, obeyedline, obeyedpage} %D {} %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 \macros %D {controlspace,setcontrolspaces} %D {} %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}} \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 %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} \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=\@@active\def^^L{\obeyedline}} \egroup %D \macros %D {obeycharacters} %D {} %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 %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} \egroup %D \macros %D {processinlineverbatim} %D {} %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 \starttypen %D \processinlineverbatim{\closingcommand} %D \stoptypen %D %D One can define his own verbatim commands, which can be very %D simple: %D %D \starttypen %D \def\Verbatim {\processinlineverbatim\relax} %D \stoptypen %D %D or a bit more more complex: %D %D \starttypen %D \def\GroupedVerbatim% %D {\bgroup %D \dosomeusefullthings %D \processinlineverbatim\egroup} %D \stoptypen %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\setupinlineverbatim% {\verbatimfont \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 \def\endofverbatimcommand{#1\egroup}% \bgroup \aftergroup\endofverbatimcommand \futurelet\next\doprocessinlineverbatim} %D \macros %D {processdisplayverbatim} %D {} %D %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 %D We can define a display verbatim environment with the %D command \type{\processdisplayverbatim} in the following way: %D %D \starttypen %D \processdisplayverbatim{\closingcommand} %D \stoptypen %D %D \noindent For instance, we can define a simple command like: %D %D \starttypen %D \def\BeginVerbatim {\processdisplayverbatim{EndVerbatim}} %D \stoptypen %D %D \noindent But we can also do more advance things like: %D %D \starttypen %D \def\BeginVerbatim {\bigskip \processdisplayverbatim{\EndVerbatim}} %D \def\EndVerbatim {\bigskip} %D \stoptypen %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 \linepartrue \expandafter\let\csname\verbatimname\endcsname=\relax \edef\endofverbatimcommand{\csname\verbatimname\endcsname}% \edef\endofverbatimcommand{\meaning\endofverbatimcommand}% \verbatimfont \setupcopyverbatim \let\doverbatimline=\relax \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. \def\setupcopyverbatim% {\uncatcodecharacters \frenchspacing \obeyspaces \obeytabs \obeylines \obeycharacters} %D \macros %D {ifeightbitcharacters} %D {} %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. \def\uncatcodecharacters% {\ifeightbitcharacters \scratchcounter=255 \else \scratchcounter=127 \fi \loop \catcode\scratchcounter=\@@letter \advance\scratchcounter by -1 \ifnum\scratchcounter>-1 \repeat} %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% \gdef\copyverbatimline#1 {\ifx\doverbatimline\relax% gobble rest of the first line \let\doverbatimline=\dodoverbatimline% \def\next{\copyverbatimline}% \else% \def\next{#1 }% \ifx\next\emptyspace% \def\next% {\doemptyverbatimline{#1}% \copyverbatimline}% \else% \edef\next{\meaning\next}% \ifx\next\endofverbatimcommand% \def\next% {\egroup\endofdisplayverbatim}% \else% \def\next% {\doverbatimline{#1}% \copyverbatimline}% \fi% \fi% \fi% \next}} %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 %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. \newif\iflinepar \def\dodoverbatimline#1% {\leavevmode\the\everyline\strut\processverbatimline{#1}% \EveryPar{}% \lineparfalse \obeyedline\par} %D \macros %D {obeyemptylines} %D {} %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 \starttypen %D \obeyemptylines %D \stoptypen %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. \bgroup \catcode`\^^L=\@@active \gdef\emptypage {^^L} \catcode`\^^M=\@@active \gdef\emptyline {^^M} \gdef\emptyspace { } \egroup \def\doemptyverbatimline% {\vskip\ht\strutbox \vskip\dp\strutbox {\setbox0=\hbox{\the\everyline}}% \linepartrue} \def\obeyemptylines% {\def\doemptyverbatimline{\doverbatimline}} %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 %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. \def\doprocesstabskip% {\obeyedspace % \hskip.5em or \hbox to .5em{} \ifdone \advance\scratchcounter by 1 \let\next=\doprocesstabskip \donefalse \else\ifnum\scratchcounter>7\relax \let\next=\relax \else \advance\scratchcounter 1\relax \let\next=\doprocesstabskip \fi\fi \next} \def\dodoprocesstabskipline#1#2\endoftabskipping% {\ifnum\scratchcounter>7\relax \scratchcounter=1\relax \donetrue \else \advance\scratchcounter 1\relax \donefalse \fi \ifx#1\relax \let\next=\relax \else \def\next{#1\dodoprocesstabskipline#2\endoftabskipping}% \fi \next} \let\endoftabskipping = \relax \let\processverbatimline = \relax \def\doprocesstabskipline#1% {\bgroup \scratchcounter=1\relax \dodoprocesstabskipline#1\relax\endoftabskipping \egroup} %D \macros %D {processfileverbatim} %D {} %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 \starttypen %D \processfileverbatim{filename} %D \stoptypen %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 %D \type{\ifprocessingverbatim}, so the output routine can %D adapt its behavior. \newif\ifprocessingverbatim \def\processfileverbatim#1% {\par \bgroup \parindent\!!zeropoint \ifdim\lastskip<\parskip \removelastskip \vskip\parskip \fi \parskip\!!zeropoint \processingverbatimtrue \linepartrue \uncatcodecharacters \verbatimfont \frenchspacing \obeyspaces \obeytabs \obeylines \obeypages \obeycharacters \openin\scratchread=#1% \def\doreadline% {\read\scratchread to \next \ifeof\scratchread % we don't want to be treated as \else\ifx\next\emptyline \expandafter\doemptyverbatimline\expandafter{\next}% \else\ifx\next\emptypage \expandafter\doemptyverbatimline\expandafter{\next}% \else \expandafter\dodoverbatimline\expandafter{\next}% \fi\fi\fi \readline}% \def\readline% {\ifeof\scratchread \let\next=\relax \else \let\next=\doreadline \fi \next}% \readline \closein\scratchread \egroup \ignorespaces} %D These 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 \starttypen %D \type{text} %D %D \starttyping %D ... verbatim text ... %D \stoptyping %D %D \typefile{filename} %D \stoptypen %D %D We can turn on the options by: %D %D \starttypen %D \controlspacetrue %D \verbatimtabstrue %D \prettyverbatimtrue %D \stoptypen %D %D Here is the implementation: \newif\ifcontrolspace \newif\ifverbatimtabs \newif\ifprettyverbatim \def\presettyping% {\ifcontrolspace \let\obeyspace=\setcontrolspace \fi \ifverbatimtabs \let\obeytabs=\settabskips \fi \ifprettyverbatim \let\obeycharacters=\setupprettytextype \fi} \def\type% {\bgroup \presettyping \processinlineverbatim{\egroup}} \def\starttyping% {\bgroup \presettyping \processdisplayverbatim{\stoptyping}} \def\stoptyping% {\egroup} \def\typefile#1% {\bgroup \presettyping \processfileverbatim{#1}% \egroup} %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 %D We'll spend the remainder of this article on coloring the %D verbatim text. At \PRAGMA\ we use the integrated environment %D \TEXEDIT\ for editing and processing \TEX\ %D documents.\voetnoot{\TEXEDIT\ has been operative since %D 1991.} This program also supports real time spell checking %D and \TEX\ based file management. Although definitely not %D exclusive, the programs cooperate nicely with \CONTEXT. %D Because \TEX\ can be considered a tool for experts, we've %D tried to put as less a burden on non||technical users as %D possible. This is accomplished in the following ways: %D %D \startopsomming %D %D \som We've added some trivial symmetry checking to %D \TEXEDIT. Sources are checked for the use of brackets, %D braces, begin||end and start||stop like constructions, %D with or without arguments. %D %D \som Although \TEX\ is very tolerant to unformatted input, %D we stimulate users to make the \ASCII\ source as clean %D as possible. Many sources I've seen in distribution %D sets look so awful, that I sometimes wonder how people %D get them working. In our opinion, a good||looking %D source leads to less errors. %D %D \som We use parameter driven setups and make the commands %D as tolerant as possible. We don't accept commands that %D don't look nice in \ASCII. %D %D \som Finally ---I could have added some more--- we use %D color. %D %D \stopopsomming %D %D When in spell||checking||mode, the words spelled correctly %D are shown in {\em green}, the unknown or wrongly spelled %D words are in {\em red} and upto four categories of words, %D for instance passive verbs and nouns, become {\em blue} %D (or cyan) or {\em yellow}. Short and nearly always correct %D words are in white (on a black screen). This makes %D checking||on||the||fly very easy and convenient, especially %D because we place the accents automatically. %D %D In \TEX||mode we show \TEX||specific tokens and sequences of %D tokens in appropriate colors and again we use four colors. %D We use those colors in a way that supports parameter driven %D setups, table typesetting and easy visual checking of %D symmetry. Furthermore the text becomes more readable. %D %D \bgroup %D \chardef\ampersand =`\& %D \chardef\comment =`\% %D \chardef\leftbrace =`\{ %D \chardef\rightbrace=`\} %D %D \plaatstabel{geen} %D \starttabel[|l|l|] %D \HL %D \FC\bf color \MC\bf characters that are influenced \LC\SR %D \HL %D \FC red \MC\tt \leftbrace\ \rightbrace\ %D \string$ \LC\FR %D \FC green \MC\tt \string\this\ \string\!!that\ %D \string\??these\ \string\@@those\ \LC\MR %D \FC yellow \MC\tt \string` \string' \string~ %D \string^ \string_ \ampersand\ %D \string/ \string+ \string- %D \string| \comment\ \LC\MR %D \FC blue \MC\tt \string( \string) \string# %D \string[ \string] \string" %D \string< \string> \string= \LC\LR %D \HL %D \stoptabel %D \egroup %D %D Macro||definition and style files often look quite green, %D because they contain many calls to macros. Pure text files %D on the other hand are mostly white (on the screen) and color %D clearly shows their structure. %D %D When I prepared the interactive \PDF\ manuals of \CONTEXT, %D \TEXEDIT\ and \PPCHTEX\ (1995), I decided to include the %D original source text of the manuals as an appendix. At every %D chapter or (sub)section the reader can go to the %D corresponding line in the source, just to see how things %D were done in \TEX. Of course, the reader can jump from the %D to corresponding typeset text too. %D %D Confronted with those long (boring) sources, I decided that %D a colored output, in accordance with \TEXEDIT\ would be %D nice. It would not only visually add some quality to the %D manual, but also make the sources more readable. %D %D Apart from a lot of \CATCODE||magic, programming the color %D macros was surprisingly easy. Although the macro's are %D hooked into the standard \CONTEXT\ verbatim mechanism, they %D are set up in a way that embedding them in another verbatim %D environment is possible. %D %D We can turn on coloring by reassigning %D \type{\obeycharacters}: %D %D \starttypen %D \let\obeycharacters=\setupprettytextype %D \stoptypen %D %D During pretty typesetting we can be in two states: {\em %D command} and {\em parameter}. The first condition becomes %D true if we encounter a backslash, the second state is %D entered when we meet a~\type{#}. \newif\ifintexcommand \newif\ifintexparameter %D \macros %D {splittexparameters} %D {} %D %D The mechanism described here, is meant to be used with %D color. It is nevertheless possible to use different fonts %D instead of distinctive colors. When using color, it's better %D to end parameter mode after the \type{#}. When on the %D other hand we use a slanted typeface for the hashmark, then %D a slanted number looks better. \newif\ifsplittexparameters \splittexparameterstrue %D \macros %D {splittexcontrols} %D {} %D %D With \type{\splittexcontrols} we can influence the way %D control characters are processed in macro names. By default, %D the \type{^^} part is uncolored. When this boolean is set to %D false, they get the same color as the other characters. \newif\ifsplittexcontrols \splittexcontrolstrue %D The next boolean is used for internal purposes only and %D keeps track of the length of the name. Because two||character %D sequences starting with a backslash are always seen as a %D command. \newif\iffirstintexcommand %D We use a maximum of four colors because more colors will %D distract too much. In the following table we show the %D logical names of the colors, their color and $rgb$ values. %D %D \plaatstabel{geen} %D \starttabel[|l|l|c|c|c|c|] %D \HL %D \FC\bf identifier \MC\bf color \MC\bf r \MC\bf g \MC\bf b \MC\bf bw \LC\SR %D \HL %D \FC texprettyone \MC red \MC 0.9 \MC 0.0 \MC 0.0 \MC 0.30 \LC\FR %D \FC texprettytwo \MC green \MC 0.0 \MC 0.8 \MC 0.0 \MC 0.45 \LC\MR %D \FC texprettythree \MC yellow \MC 0.0 \MC 0.0 \MC 0.9 \MC 0.60 \LC\MR %D \FC texprettyfour \MC blue \MC 0.8 \MC 0.8 \MC 0.6 \MC 0.75 \LC\LR %D \HL %D \stoptabel %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. \def\setcolorverbatim% {\splittexparameterstrue \def\texprettyone {.9 .0 .0 } % red \def\texprettytwo {.0 .8 .0 } % green \def\texprettythree {.0 .0 .9 } % blue \def\texprettyfour {.8 .8 .6 } % yellow \def\texbeginofpretty[##1]% {\special{ps:: \csname##1\endcsname setrgbcolor}} \def\texendofpretty% {\special{ps:: 0 0 0 setrgbcolor}}} % black \def\setgrayverbatim% {\splittexparameterstrue \def\texprettyone {.30 } % gray \def\texprettytwo {.45 } % gray \def\texprettythree {.60 } % gray \def\texprettyfour {.75 } % gray \def\texbeginofpretty[##1]% {\special{ps:: \csname##1\endcsname setgray}} \def\texendofpretty% {\special{ps:: 0 setgray}}} % black %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. \setcolorverbatim %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. \def\texbeginofcommand% {\texendofparameter \ifintexcommand \else \global\intexcommandtrue \global\firstintexcommandtrue \texbeginofpretty[texprettytwo]% \fi} \def\texendofcommand% {\ifintexcommand \texendofpretty \global\intexcommandfalse \global\firstintexcommandfalse \fi} \def\texbeginofparameter% {\texendofcommand \ifintexparameter \else \global\intexparametertrue \texbeginofpretty[texprettythree]% \fi} \def\texendofparameter% {\ifintexparameter \texendofpretty \global\intexparameterfalse \fi} %D We've got nine types of characters. The first type concerns %D the grouping characters that become red and type seven takes %D care of the backslash. Type eight is the most recently added %D one and handles the control characters starting with %D \type{^^}. In the definition part at the end of this module %D we can see how characters are organized by type. \def\ifnotfirstintexcommand#1% {\iffirstintexcommand \string#1% \texendofcommand \else} \def\textypeone#1% {\ifnotfirstintexcommand#1% \texendofcommand \texendofparameter \texbeginofpretty[texprettyone]\string#1\texendofpretty \fi} \def\textypetwo#1% {\ifnotfirstintexcommand#1% \texendofcommand \texendofparameter \texbeginofpretty[texprettythree]\string#1\texendofpretty \fi} \def\textypethree#1% {\ifnotfirstintexcommand#1% \texendofcommand \texendofparameter \texbeginofpretty[texprettyfour]\string#1\texendofpretty \fi} \def\textypefour#1% {\ifnotfirstintexcommand#1% \texendofcommand \texendofparameter \string#1% \fi} \def\textypefive#1% {\ifnotfirstintexcommand#1% \texbeginofparameter \string#1% \fi} \def\textypesix#1% {\ifnotfirstintexcommand#1% \ifintexparameter \ifsplittexparameters \texendofparameter \string#1% \else \string#1% \texendofparameter \fi \else \texendofcommand \string#1% \fi \fi} \def\textypeseven#1% {\ifnotfirstintexcommand#1% \texbeginofcommand \string#1% \fi} \def\dodotextypeeight#1% {\texendofparameter \ifx\next#1% \ifsplittexcontrols \ifintexcommand \texendofcommand \string#1\string#1% \texbeginofcommand \else \string#1\string#1% \fi \else \string#1\string#1% \fi \let\next=\relax \else \textypethree#1% \fi \next} \def\textypeeight#1% {\def\dotextypeeight{\dodotextypeeight#1}% \afterassignment\dotextypeeight\let\next=} \def\textypenine#1% {\texendofparameter \global\firstintexcommandfalse \string#1} %D We have to take care of the control characters we mentioned %D before. We obey their old values but only after ending our %D two states. \def\texsetcontrols% {\global\let\oldobeyedspace = \obeyedspace \global\let\oldobeyedline = \obeyedline \global\let\oldobeyedpage = \obeyedpage \def\obeyedspace% {\texendofcommand \texendofparameter \oldobeyedspace}% \def\obeyedline% {\texendofcommand \texendofparameter \oldobeyedline}% \def\obeyedpage% {\texendofcommand \texendofparameter \oldobeyedpage}} %D Next comes the tough part. We have to change the \CATCODE\ %D of each character. These macro's are tuned for speed and %D simplicity. When viewed in color they look quite simple. \def\setupprettytextype% {\texsetcontrols \texsetspecialpretty \texsetalphabetpretty \texsetextrapretty} %D When handling the lowercase characters, we cannot use %D lowercased macro names. This means that we have to redefine %D some well known macros, like \type{\bgroup}. \def\texpresetcatcode% {\def\\##1% {\expandafter\catcode\expandafter`\csname##1\endcsname\@@active}} \def\texsettypenine% {\def\\##1% {\def##1{\textypenine##1}}} \bgroup \bgroup \gdef\texpresetalphapretty% {\texpresetcatcode \\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} \texpresetalphapretty \gdef\texsetalphapretty% {\texpresetalphapretty \texsettypenine \\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} \egroup \global\let\TEXPRESETCATCODE = \texpresetcatcode \global\let\TEXSETTYPENINE = \texsettypenine \global\let\BGROUP = \bgroup \global\let\EGROUP = \egroup \global\let\GDEF = \gdef \BGROUP \GDEF\TEXPRESETALPHAPRETTY% {\TEXPRESETCATCODE \\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} \TEXPRESETALPHAPRETTY \GDEF\TEXSETALPHAPRETTY% {\TEXPRESETALPHAPRETTY \TEXSETTYPENINE \\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} \EGROUP \gdef\texsetalphabetpretty% {\texsetalphapretty \TEXSETALPHAPRETTY} \egroup %D Macro names normally only may contain characters, but in %D unprotected state we can also use the characters~\type{@}, %D \type{!} and~\type{?}. Of course they are only colored %D (green) when they are part of a name. \bgroup \gdef\texpresetextrapretty% {\texpresetcatcode \\?\\!\\@} \texpresetextrapretty \gdef\texsetextrapretty% {\texpresetextrapretty \texsettypenine \\?\\!\\@} \egroup %D Here comes the main specification routine. In this macro we %D also have to change the escape character to \type{!} and use %D \type{X}, \type{Y} and \type{Z} for grouping and ignoring, %D which makes the result a bit less readable. Plain \TEX\ %D defines \type{\+} as an outer macro, so we have to redefine %D this one too. \def\+{\tabalign} \bgroup \gdef\texpresetspecialpretty% {\def\\##1{\catcode`##1\@@active}% \\\[\\\]\\\=\\\<\\\>\\\#\\\(\\\)\\\"% \\\$\\\{\\\}% \\\-\\\+\\\|\\\%\\\/\\\_\\\^\\\&\\\~\\\'\\\`% \\\.\\\,\\\:\\\;% \\\*% \\\1\\\2\\\3\\\4\\\5\\\6\\\7\\\8\\\9% \\\\} \catcode`\X=\the\catcode`\{ \catcode`\Y=\the\catcode`\} \catcode`\Z=\the\catcode`\% \gdef\texsetsometypes% {\def\!##1##2{\def##1{##2{##1}}}}% XZ \catcode`\!=\@@escape !texpresetspecialpretty !gdef!texsetspecialpretty XZ !texpresetspecialpretty !texsetsometypes !! $ !textypeone !! { !textypeone !! } !textypeone !! [ !textypetwo !! ] !textypetwo !! ( !textypetwo !! ) !textypetwo !! = !textypetwo !! < !textypetwo !! > !textypetwo !! " !textypetwo !! - !textypethree !! + !textypethree !! / !textypethree !! | !textypethree !! % !textypethree !! ' !textypethree !! ` !textypethree !! _ !textypethree !! ^ !textypethree !! & !textypethree !! ~ !textypethree !! . !textypefour !! , !textypefour !! : !textypefour !! ; !textypefour !! * !textypefour !! # !textypefive !! 1 !textypesix !! 2 !textypesix !! 3 !textypesix !! 4 !textypesix !! 5 !textypesix !! 6 !textypesix !! 7 !textypesix !! 8 !textypesix !! 9 !textypesix !! \ !textypeseven !! ^ !textypeeight YZ YZ \egroup %D This text was published in the \MAPS\ of the dutch \TEX\ %D users group \NTG. In that article, the verbatim part of the %D text was set with the following commands for the examples: %D %D \starttypen %D \def\starttypen% We simplify the \ConTeXt\ macro. %D {\bgroup %D \everypar{} % We disable some troublesome mechanisms. %D \advance\leftskip by 1em %D \processdisplayverbatim{\stoptypen}} %D %D \def\stoptypen% %D {\egroup} %D \stoptypen %D %D The implementation itself was typeset with: %D %D \starttypen %D \def\startdefinition% %D {\bgroup %D \everypar{} % Again we disable some troublesome mechanisms. %D \let\obeycharacters=\setupprettytextype %D \EveryPar{\showparagraphcounter}% %D \EveryLine{\showlinecounter}% %D \verbatimcorps %D \processdisplayverbatim{\stopdefinition}} %D %D \def\stopdefinition% %D {\egroup} %D \stoptypen %D %D And because we have both \type{\EveryPar} and %D \type{\EveryLine} available, we can implement a dual %D numbering mechanism: %D %D \starttypen %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 \stoptypen %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 \starttypen %D \EveryLine %D {\iflinepar %D \showparagraphcounter %D \fi %D \showlinecounter} %D \stoptypen %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 \starttypen %D \processinlineverbatim{\closingcommand} %D \processdisplayverbatim{\closingcommand} %D \processfileverbatim{filename} %D \stoptypen %D %D We can satisfy our own specific needs with the following %D interfacing macro's: %D %D \starttypen %D \obeyspaces \obeytabs \obeylines \obeypages \obeycharacters %D \stoptypen %D %D Some needs are fulfilled already with: %D %D \starttypen %D \setcontrolspace \settabskips \setupprettytextype %D \stoptypen %D %D lines can be enhanced with ornaments using: %D %D \starttypen %D \everypar \everyline \iflinepar %D \stoptypen %D %D and color support is implemented by: %D %D \starttypen %D \texbeginofpretty[#1] ... \texendofpretty %D \stoptypen %D %D We can influence the verbatim environment with the following %D macro and booleans: %D %D \starttypen %D \obeyemptylines \splittexparameters... \splittexcontrols... %D \stoptypen %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 texprettyone}, {\em texprettytwo}, {\em %D texprettythree} and {\em texprettyfour}. 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 \starttypen %D \setgrayverbatim \setcolorverbatim %D \stoptypen %D \macros %D {permitshiftedendofverbatim} %D {} %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. \ifx \undefined \convertargument \else \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 \@EA\convertargument\csname\verbatimname\endcsname\to\endofverbatimcommand \verbatimfont \setupcopyverbatim \let\doverbatimline=\relax \copyverbatimline} \let\doifendofverbatim=\doifinstringelse \def\permitshiftedendofverbatim% {\let\doifendofverbatim=\doifelse} {\obeylines% \gdef\copyverbatimline#1 {\ifx\doverbatimline\relax% gobble rest of the first line \let\doverbatimline=\dodoverbatimline% \def\next{\copyverbatimline}% \else% \convertargument#1 \to\next% \ifx\next\emptyspace% \def\next% {\doemptyverbatimline{#1}% \copyverbatimline}% \else% \doifendofverbatim{\endofverbatimcommand}{\next}% {\def\next% {\egroup\endofdisplayverbatim}}% {\def\next% {\doverbatimline{#1}% \copyverbatimline}}% \fi% \fi% \next}} \fi \protect