%D \module
%D   [       file=buff-ver, % was core-ver
%D        version=2000.05.09,
%D          title=\CONTEXT\ Buffer Macros,
%D       subtitle=Verbatim,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Buffer Macros / Verbatim}

\unprotect

\ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
\ifx\stoplinenumbering \undefined \let\stoplinenumbering\relax \fi
\ifx\setuplinenumbering\undefined \def\setuplinenumbering[#1]{} \fi

% \type{ <crlf> char} geeft bagger

%D We are going to embed the general verbatim support macros in
%D a proper environment. First we show the common setup
%D macro, so we know what features are supported. The options
%D are hooked into the support macros via the \type{\obey}
%D macros.

\newif\ifslantedtypeactivated
\newif\ifslantedtypepermitted

\def\switchslantedtype
  {\ifslantedtypepermitted
     \ifslantedtypeactivated
       \slantedtypeactivatedfalse\tttf
     \else
       \slantedtypeactivatedtrue\ttsl
     \fi
   \fi}

\newprettytrue % movet to here from cont-sys.tex

\def\prettyidentifier {TEX}
\def\prettypalet      {}

\def\installprettytype
  {\dodoubleargument\doinstallprettytype}

\def\doinstallprettytype[#1][#2]% map #1 onto #2
  {\uppercasestring#1\to\asciia
   \uppercasestring#2\to\asciib
   \setevalue{\??ty\??ty\asciia}{\asciib}}

\def\setupprettiesintype#1%
  {\uppercasestring#1\to\ascii
   \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}%
   \doifundefined{setuppretty\prettyidentifier type}%
     {\startnointerference
        \restorecatcodes % also needed when loading during \newpretty
        \startreadingfile % restore < and > if needed
        \lowercasestring verb-\prettyidentifier\to\filename
        \readsysfile{\filename.mkii}\donothing\donothing
        \stopreadingfile
      \stopnointerference}%
   \doifdefinedelse{setuppretty\prettyidentifier type}%
     {\let\uncatcodecharacters\uncatcodeallcharacters % ugly, should be switch / todo
      \def\dosetupprettytype{\getvalue{setuppretty\prettyidentifier type}}}
     {\let\dosetupprettytype\relax}}

\def\setupprettytype{\dosetupprettytype}

% \def\setupcommonverbatim
%   {\recatcodeuppercharactersfalse % obey regime / encoding
%    %
%    \let\prettyidentifier\s!default
%    %
%    \doifelse{\typingparameter\c!text}\v!yes
%      \naturaltextexttrue
%      \naturaltextextfalse
%    \def\prettyidentifierfont{\typingparameter\c!icommand}%
%    \def\prettyvariablefont  {\typingparameter\c!vcommand}%
%    \def\prettynaturalfont   {\typingparameter\c!ccommand}%
%    %
%    \doif{\typingparameter\c!space}\v!on
%      {\def\obeyspaces{\setcontrolspaces}}%
%    \doif{\typingparameter\c!page }\v!no
%      {\def\obeypages {\ignorepages}}%
%    %
%    \doifelse{\typingparameter\c!tab}\v!yes
%      {\def\obeytabs{\settabskips}}%
%      {\doif{\typingparameter\c!tab}\s!ascii
%         {\chardef\tabskipmode\plustwo % quit on >127
%          \def\obeytabs{\settabskips}}}%
%    %
%    \ignorehyphens % default
%    \ExpandFirstAfter\processaction
%      [\typingparameter\c!lines]
%      [        \v!yes=>\obeybreakpoints,
%        \v!hyphenated=>\obeyhyphens]%
%    \processaction
%      [\typingparameter\c!empty]
%      [\v!yes=>\obeyemptylines,
%       \v!all=>\obeyallemptylines]%
%    %
%    \ExpandFirstAfter\processaction
%      [\typingparameter\c!option]
%      [     \v!none=>\let\obeycharacters\relax,
%           \v!color=>\setupprettiesintype{TEX}%
%                     \let\obeycharacters\setupprettytype
%                     \let\obeytabs\ignoretabs,
%          \v!normal=>\let\obeycharacters\setupgroupedtype,
%        \v!commands=>\def\obeycharacters{\setupcommandsintype}% \let
%                     \let\obeytabs\ignoretabs,
%         \v!slanted=>\let\obeycharacters\setupslantedtype
%                     \let\obeytabs\ignoretabs,
%         \s!unknown=>\setupprettiesintype{\typingparameter\c!option}%
%                     \let\obeycharacters\setupprettytype
%                     \let\obeytabs\ignoretabs]%
%    \doifnumberelse{\typingparameter\c!tab}
%      {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
%      \donothing
%   %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
%   % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
%    \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
%    \setupverbatimcolor}

\setvalue{\??tp:\c!lines:\v!yes       }{\obeybreakpoints}
\setvalue{\??tp:\c!lines:\v!hyphenated}{\obeyhyphens}

\setvalue{\??tp:\c!empty:\v!yes       }{\obeyemptylines}
\setvalue{\??tp:\c!empty:\v!all       }{\obeyallemptylines}

\setvalue{\??tp:\c!option:\v!none     }{\let\obeycharacters\relax}
\setvalue{\??tp:\c!option:\v!color    }{\setupprettiesintype{TEX}%
                                        \let\obeycharacters\setupprettytype
                                        \let\obeytabs\ignoretabs}
\setvalue{\??tp:\c!option:\v!normal   }{\let\obeycharacters\setupgroupedtype}
\setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}%
                                        \let\obeytabs\ignoretabs}
\setvalue{\??tp:\c!option:\v!slanted  }{\let\obeycharacters\setupslantedtype
                                        \let\obeytabs\ignoretabs}
\setvalue{\??tp:\c!option:\s!unknown  }{\setupprettiesintype{\typingparameter\c!option}%
                                        \let\obeycharacters\setupprettytype
                                        \let\obeytabs\ignoretabs}

\def\setupcommonverbatim
  {\recatcodeuppercharactersfalse % obey regime / encoding
   %
   \let\prettyidentifier\s!default
   %
   \doifelse{\typingparameter\c!text}\v!yes
     \naturaltextexttrue
     \naturaltextextfalse
   \def\prettyidentifierfont{\typingparameter\c!icommand}%
   \def\prettyvariablefont  {\typingparameter\c!vcommand}%
   \def\prettynaturalfont   {\typingparameter\c!ccommand}%
   %
   \doif{\typingparameter\c!space}\v!on
     {\def\obeyspaces{\setcontrolspaces}}%
   \doif{\typingparameter\c!page }\v!no
     {\def\obeypages {\ignorepages}}%
   %
   \doifelse{\typingparameter\c!tab}\v!yes
     {\def\obeytabs{\settabskips}}%
     {\doif{\typingparameter\c!tab}\s!ascii % not needed in mkiv
        {\chardef\tabskipmode\plustwo % quit on >127
         \def\obeytabs{\settabskips}}}%
   %
   \ignorehyphens % default
   \getvalue{\??tp:\c!lines:\typingparameter\c!lines}%
   \getvalue{\??tp:\c!empty:\typingparameter\c!empty}%
   \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}%
   \doifnumberelse{\typingparameter\c!tab}
     {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
     \donothing
  %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
  % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
   \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
   \setupverbatimcolor}

% BEWARE: the noligatures will globally change the verbatim font's behaviour

% test case:
%
% \definetype[typeTEX][option=tex]
%
% \typeTEX|\example---oeps|. this---ligates---again.
% \typeTEX{\example---oeps}. this---ligates---again.
% \type   {\example---oeps}. this---ligates---again.

\def\setupcommandsintype % can also be \string\
  {\setupgroupedtype
   \edef\\{\typingparameter\c!escape}%
   \letvalue{\\}=\\% for instance \/=/
   \@EA\catcode\@EA`\\=\@@escape
   \def\BTEX##1\ETEX##2% ##2 gobbles active space
     {\naturaltextext##1\unskip\relax}}

\def\setupslantedtype
  {\slantedtypepermittedtrue\setupgroupedtype}

\ifx\setupprettytype  \undefined \let\setupprettytype  \relax             \fi
\ifx\setupslantedtype \undefined \let\setupslantedtype \relax             \fi
\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax             \fi
\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi

%D The verbatim commands have a rather long and turbulent
%D history. Most users of \CONTEXT\ probably will never use
%D some of the features, but I've kept in mind that when one is
%D writing a users manual, about everything can and undoubtly
%D will be subject to a verbatim treatment.
%D
%D Verbatim command are very sensitive to argument processing,
%D which is a direct result of the \CATCODES\ being fixed at
%D reading time. With our growing understanding of \TEX,
%D especially of the mechanism that can be used for looking
%D ahead and manipulating \CATCODES, the verbatim support
%D became more and more advanced and natural.
%D
%D Typesetting inline verbatim can be accomplished by
%D \type{\type}, which in this sentence was typeset by saying
%D just \type{\type{\type}}, which in turn was typeset by
%D \unknown. Using the normal grouping characters \type{{}} is
%D the most natural way of using this command.
%D
%D A second, more or less redundant, alternative is delimiting
%D the argument with an own character. This method was
%D implemented in the context of a publication in the \MAPS,
%D where this way of delimiting is recognized by \LATEX\ users.
%D
%D The third, more original alternative, is the one using
%D \type{<<} and \type{>>} as delimiters. This alternative can
%D be used in situations where slanted typeseting is needed.

% todo: we can use \letter... here:

\def\lesscharacter {<}
\def\morecharacter {>}

\chardef\texescape     = `\\
\chardef\leftargument  = `\{
\chardef\rightargument = `\}

%D \macros
%D   {type}
%D
%D We define \type{\type} as a protected command. This command
%D has several invocations: grouped, wirt boundary characters,
%D and with font switches.

% \starttyping
% normal: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
% normal: \par \type{xx<..xx..<xx <slanted> >..>xx} \par \type{<....>} \par \type{<..<xx>..>}
% \setuptype[option=slanted]
% slanted: \par \type{xx<<..sl..<<xx <<sl>> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<<sl>>..>> \par
% slanted: \par \type{xx<<..sl..<xx <sl> xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<sl>..>> \par
% \setuptype[option=none]
% none: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
% \stoptyping

%D When writing the manual to \CONTEXT\ and documenting this
%D source we needed to typeset \type{<<} and \type{>>}. Because
%D we wanted to do this in the natural way, we've adapted the
%D original definition a bit. This implementation went through
%D several live cycles. The final implementation looks a bit
%D further and treats the lone \type{<<} and \type{>>} a bit
%D different. The \type {\null} prevents ligatures, which
%D unfortunately turn up in Lucida fonts.

%D The following lines show what happens when we set
%D \type {option=commands}.
%D
%D \startbuffer
%D \starttyping
%D test//test test/BTEX \footnote{test test test}/ETEX test
%D test//test test/BTEX \footnote{test test test}/ETEX  test
%D test test test/BTEX \bf(nota bene)/ETEX test
%D test test test /BTEX \bf(nota bene)/ETEX  test
%D \stoptyping
%D \stopbuffer
%D
%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup
%D
%D this was keyed in as:
%D
%D \typebuffer

\unexpanded\def\type{\dotype\empty}

% not that fast but catches \type{\command} % nothing more after \command
%
% \setupcolors[state=start]
% \setuptype[option=TEX]
% \setupcolors[textcolor=red]
%
% The options \type{before=\startsolutionbackground } and
% \type{after=\stopsolutionbackground} take care of putting a frame,
% which can
%
% {\blue The options \type{before=\startsolutionbackground } and
% \type{after=\stopsolutionbackground} take care of putting a frame,
% which} can

\def\resumecoloraftergroup
  {\localstartcolor[\s!black]%
   \localstartcolor[\maintextcolor]%
   \aftergroup\localstopcolor
   \aftergroup\localstopcolor}

% the rather messy \type command

\def\dotype#1% was \dotype
  {\bgroup
   \resumecoloraftergroup % a problem is that we can still be in color mode, tricky hack
   \begstrut % new, enables leading space in \type { abc } at par start / begstrut else no hyphenation
   \let\currenttypingclass\??ty
   \edef\currenttyping{#1}%
   \catcode`\<=\@@other
   \catcode`\>=\@@other
   \futurelet\next\dodotype}

\def\dodotypeA
  {\initializetype
   \initializetypegrouping
   \verbatimfont
   \verbatimcolor
   \afterassignment\protectfirsttype\let\next=}

\def\dodotypeB
  {\initializetype
   \setupnotypegrouping
   \verbatimfont
   \verbatimcolor
   \let\next=}

\def\dodotypeC<#1%
  {\initializetype
   \verbatimfont
   \verbatimcolor
   \if#1<%
     \@EA\setupalternativetypegrouping
   \else
     \@EA#1%
   \fi}

\def\dodotypeD#1%
  {\initializetype
   \verbatimfont
   \verbatimcolor
   \catcode`#1=\@@endgroup}

\def\dodotype
  {\ifx\next\bgroup
     \@EA\dodotypeA
   \else\if\next<%
     \doifelse{\typingparameter\c!option}\v!none
       {\@EAEAEA\dodotypeB}{\@EAEAEA\dodotypeC}%
   \else
     \@EAEAEA\dodotypeD
   \fi\fi}

% The next one is safe for: \def\xx#1{\type{#1}} \xx{\ifx}

\let\protectedfirsttype\string % \relax for special cases

\bgroup
\catcode`\<=\active
\catcode`\>=\active
\gdef\doprotectfirsttype
  {\normalifx\next<%
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\bgroup
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\egroup % takes care of \type{}
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\activeleftargument
     \endrobusttest \let\next\relax
   \normalelse
     \endrobusttest \let\next\protectedfirsttype
   \normalfi\normalfi\normalfi\normalfi
   \next}
\egroup

\def\protectfirsttype
  {\beginrobusttest
   \futurelet\next\doprotectfirsttype}

% Verbatim does not work when passed as an argument, so here is a
% workaround. Beware, spaces are introduced after a \type {\csname}.

\chardef\recodeverbatimmode\zerocount % 0=nothing 1=rescan 2=autorescan

% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytabulate
% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytable

\def\dodotypeA
  {\initializetype
   \initializetypegrouping
   \verbatimfont
   \verbatimcolor
   \ifcase\recodeverbatimmode
     \@EA\dodotypeAA
   \or
     \@EA\dodotypeAB
   \or
     \ifnum\catcode`\{=\@@active
       \@EAEAEA\dodotypeAB
     \else
       \@EAEAEA\dodotypeAA
     \fi
   \else
     \@EA\dodotypeAA
   \fi}

\def\dodotypeAA
  {\afterassignment\protectfirsttype\let\next=}

\def\dodotypeAB
  {\bgroup
   \catcode`\}=\@@endgroup
   \catcode`\{=\@@begingroup
   \afterassignment\redotypeAB\global\globalscratchtoks}

\def\redotypeAB
  {\egroup
   \expandafter\defconvertedargument\expandafter\ascii\expandafter{\the\globalscratchtoks}% == \edefconvertedargument\ascii{\the\globalscratchtoks}%
   \ifx\scantokens\undefined\ascii\else\everyeof{\hskip-\spaceskip}\scantokens\expandafter{\ascii}\fi
   \egroup}

\bgroup
\catcode`\[=\@@begingroup
\catcode`\]=\@@endgroup
\catcode`\{=\@@active
\catcode`\}=\@@active
\gdef\initializetypegrouping
  [\ifnum\catcode`\{=\@@active
     \let\normalactivebgroup{%
     \let\normalactiveegroup}%
   \else
     \catcode`\{=\@@active
     \catcode`\}=\@@active
     \let\normalactivebgroup\leftargument
     \let\normalactiveegroup\rightargument
   \fi
   \def\activeleftargument
     [\bgroup
      \catcode`\}=\@@active
      \let}\activerightargument
      \normalactivebgroup]%
   \def\activerightargument
     [\normalactiveegroup
      \egroup]%
   \let{=\activeleftargument
   % not \let}=\egroup, otherwise things go wrong in alignments (???)
   \catcode`\}=\@@endgroup]
\egroup

\bgroup
\catcode`\<=\@@active
\catcode`\>=\@@active
\gdef\setupalternativetypegrouping
  {\catcode`\<=\@@active
   \catcode`\>=\@@active
   \def\doless
     {\ifx<\next
        \def\next
          {\bgroup\switchslantedtype
           \let\next=}%
      \else
        \let\next\lesscharacter
      \fi
      \next}%
   \def\domore
     {\ifx>\next
        \def\next
          {\egroup
           \let\next=}%
      \else
        \let\next\morecharacter
      \fi
      \next}%
   \def<{\futurelet\next\doless}%
   \def>{\futurelet\next\domore}}
\egroup

\def\setupnotypegrouping
  {\catcode`\<=\@@begingroup
   \catcode`\>=\@@endgroup}

\def\doenterdoublelesstype
  {\ifx\next\egroup
      \lesscharacter\null\lesscharacter
   \else
     \bgroup\switchslantedtype
     \let\doenterdoublemoretype\egroup
   \fi}

\def\doenterdoublemoretype
  {\def\doenterdoubletype
     {\ifx\next\egroup
        \morecharacter\null\morecharacter
      \fi}}

\bgroup
\catcode`\<=\@@active
\catcode`\>=\@@active
\gdef\setupgroupedtype
  {\catcode`\<=\@@active
   \catcode`\>=\@@active
   \def\doless
     {\ifx<\next
        \def\next
          {\def\enterdoubletype{\futurelet\next\doenterdoublelesstype}%
           \afterassignment\enterdoubletype
           \let\next=}%
      \else
        \let\next\lesscharacter
      \fi
      \next}%
   \def\domore
     {\ifx>\next
        \def\next
          {\def\enterdoubletype{\futurelet\next\doenterdoublemoretype}%
           \afterassignment\enterdoubletype
           \let\next=}%
      \else
        \let\next\morecharacter
      \fi
      \next}%
   \def<{\futurelet\next\doless}%
   \def>{\futurelet\next\domore}}
\egroup

%D The neccessary initializations are done by calling
%D \type{\initializetype} which in return calls for the support
%D macro \type{\setupinlineverbatim}.

\def\initializetype
  {\let\obeylines\ignorelines
   \setupcommonverbatim
   \setupinlineverbatim}

%D \macros
%D   {setuptype}
%D
%D Some characteristics of \type{\type} can be set up by:

\def\setuptype
  {\dodoubleempty\dosetuptype}

\def\dosetuptype[#1][#2]%
  {\ifsecondargument
     \getparameters[\??ty#1][#2]%
   \else
     \getparameters[\??ty][#1]%
   \fi}

%D \macros
%D   {typ,obeyhyphens,obeybreakpoints}
%D
%D Although it's not clear from the macros, one character
%D trait of this macros, which are build on top of the support
%D module, is that they don't hyphenate. We therefore offer
%D the alternative \type{\typ}. The current implementation
%D works all right, but a decent hyphenation support of
%D \type{\tt} text will be implemented soon.

\def\obeyhyphens
  {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
   \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
   \spaceskip.25em\relax} % hm a bit of stretch !

\def\obeybreakpoints
  {\ignorehyphens
   \veryraggedright}

\def\ignorehyphens
  {% \nohyphens % forgotten when no \par
   \normallanguage\minusone % fails as the font redoes the language
   \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
   \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
   \spaceskip.5em\relax}


\unexpanded\def\typ
  {\bgroup
   \let\@@tylines\v!hyphenated
   \futurelet\next\dodotype}

%D \macros
%D   {tex,arg,mat,dis}
%D
%D Sometimes, for instance when we pass verbatim text as an
%D argument, the fixed \CATCODES\ interfere with our wishes. An
%D experimental implementation of character by character
%D processing of verbatim text did overcome this limitation,
%D but we've decided not to use that slow and sometimes
%D troublesome solution. Instead we stick to some 'old'
%D \CONTEXT\ macros for typesetting typical \TEX\ characters.
%D
%D The next implementation is more clear but less versatile,
%D so we treated it for a beter one.
%D
%D \starttyping
%D \def\dospecialtype#1#2%
%D   {\bgroup
%D    \initializetype
%D    \catcode`\{=\@@begingroup
%D    \catcode`\}=\@@endgroup
%D    \def\dospecialtype%
%D      {\def\dospecialtype{#2\egroup}%
%D       \bgroup
%D       \aftergroup\dospecialtype
%D       #1}%
%D    \afterassignment\dospecialtype
%D    \let\next=}
%D
%D \unexpanded\def\tex{\dospecialtype\texescape\relax}
%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument}
%D \unexpanded\def\mat{\dospecialtype\$\$}
%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}}
%D \stoptyping

\def\setgroupedtype
  {\let\currenttypingclass\??ty
   \initializetype
   \verbatimcolor
   \catcode`\{=\@@begingroup
   \catcode`\}=\@@endgroup}

\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}}
\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}}
\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}}
\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}}

\let\normaltexttex\tex
\let\normaltextarg\arg
\let\normaltextmat\mat
\let\normaltextdis\dis

%D \macros
%D   {starttyping}
%D
%D Display verbatim is realized far more easy, which is mostly
%D due to the fact that we use \type{\stop...} as delimiter.
%D The implementation inherits  some features, for instance the
%D support of linenumbering, which can best be studied in the
%D documented support module.

\let\currenttyping     \empty
\let\currenttypingclass\??ty  % saveguard

% \def\typingparameter#1%
%   {\executeifdefined
%      {\currenttypingclass\currenttyping#1}%
%      {\executeifdefined{\currenttypingclass#1}\empty}}

\def\typingparameter#1%
  {\ifcsname\currenttypingclass\currenttyping#1\endcsname
     \csname\currenttypingclass\currenttyping#1\endcsname
   \else\ifcsname\currenttypingclass#1\endcsname
     \csname\currenttypingclass#1\endcsname
   \fi\fi}

\def\settypingparameter#1#2%
  {\setvalue{\currenttypingclass\currenttyping#1}{#2}}

\def\setxtypingparameter#1#2%
  {\setxvalue{\currenttypingclass\currenttyping#1}{#2}}

% \def\initializetyping
%   {%\donefalse
%    \switchtobodyfont[\typingparameter\c!bodyfont]%
%    \donefalse
%    \scratchskip\typingparameter\c!oddmargin\relax
%    \ifzeropt\scratchskip\else\donetrue\fi
%    \scratchskip\typingparameter\c!evenmargin\relax
%    \ifzeropt\scratchskip\else\donetrue\fi
%    \ifdone
%      \def\doopenupverbatimline
%        {\getpagestatus
%         \ifrightpage
%           \hskip\typingparameter\c!oddmargin\relax
%         \else
%           \hskip\typingparameter\c!evenmargin\relax
%         \fi}%
%    \else
%      \doadaptleftskip{\typingparameter\c!margin}%
%    \fi
%    \doifdefinedelse{\??bo\typingparameter\c!blank}
%      {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}}
%      {\edef\!!stringa{\typingparameter\c!blank}}%
%    \processaction
%      [\!!stringa]
%      [ \v!standard=>\scratchskip\ctxparskip,
%           \v!small=>\scratchskip\blankokleinmaat,
%          \v!medium=>\scratchskip\blankomiddelmaat,
%             \v!big=>\scratchskip\blankogrootmaat,
%        \v!halfline=>\scratchskip.5\baselineskip,
%            \v!line=>\scratchskip\baselineskip,
%            \v!none=>\scratchskip\zeropoint,
%         \s!unknown=>\scratchskip\commalistelement]%
%    \ifgridsnapping
%      \ifdim\scratchskip=.5\baselineskip\relax
%        \edef\verbatimbaselineskip{\the\scratchskip}% new
%      \else
%        \edef\verbatimbaselineskip{\the\baselineskip}%
%      \fi
%    \else
%      \edef\verbatimbaselineskip{\the\scratchskip}%
%    \fi
%    \setupcommonverbatim}

\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip}
\setvalue{\??tp:\c!blank:\v!small   }{\blankokleinmaat}
\setvalue{\??tp:\c!blank:\v!medium  }{\blankomiddelmaat}
\setvalue{\??tp:\c!blank:\v!big     }{\blankogrootmaat}
\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip}
\setvalue{\??tp:\c!blank:\v!line    }{\baselineskip}
\setvalue{\??tp:\c!blank:\v!none    }{\zeropoint}

\def\initializetyping
  {%\donefalse
   \switchtobodyfont[\typingparameter\c!bodyfont]%
   \donefalse
   \scratchskip\typingparameter\c!oddmargin\relax
   \ifzeropt\scratchskip\else\donetrue\fi
   \scratchskip\typingparameter\c!evenmargin\relax
   \ifzeropt\scratchskip\else\donetrue\fi
   \ifdone
     \def\doopenupverbatimline
       {\getpagestatus
        \ifrightpage
          \hskip\typingparameter\c!oddmargin\relax
        \else
          \hskip\typingparameter\c!evenmargin\relax
        \fi}%
   \else
     \doadaptleftskip{\typingparameter\c!margin}%
   \fi
   \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}%
   \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax
   \ifgridsnapping
     \ifdim\scratchskip=.5\baselineskip\relax
       \edef\verbatimbaselineskip{\the\scratchskip}% new
     \else
       \edef\verbatimbaselineskip{\the\baselineskip}%
     \fi
   \else
     \edef\verbatimbaselineskip{\the\scratchskip}%
   \fi
   \setupcommonverbatim}

%D The basic display verbatim commands are defined in an
%D indirect way. As we will see, they are a specific case of a
%D more general mechanism.

% we need this hack because otherwise verbatim skips
% the first line (everything after the initial command)

\def\dostarttyping#1% tricky non standard lookahead
  {\bgroup
   \let\currenttypingclass\??tp
   \edef\currenttyping{#1}%
   \obeylines
   \futurelet\nexttoken\dodostarttyping}

\def\dodostarttyping
  {\ifx\nexttoken[%
     \expandafter\dododostarttyping
   \else
     \expandafter\nododostarttyping
   \fi}

\def\nododostarttyping
  {\dododostarttyping[]}

\def\dododostarttyping[#1]%
  {\typingparameter\c!before
   \startpacked % includes \bgroup
   \dosetuptypelinenumbering{#1}%
   \initializetyping
   \startverbatimcolor
   \expanded{\processdisplayverbatim{\s!stop\currenttyping}}}

\def\dostoptyping#1% hm, currenttyping
  {\stopverbatimcolor
   \stoppacked  % includes \egroup
   \typingparameter\c!after
   \egroup
   \dochecknextindentation{\??tp#1}%
   \dorechecknextindentation}

%D Line numbering for files is combined with filtering, while
%D display verbatim has the ability to continue.
%D
%D \starttyping
%D \typefile[numbering=file,start=10,stop=12]{test.tex}
%D
%D \definetyping[code][numbering=line]
%D
%D \starttext
%D \startcode
%D ...
%D ...
%D \stopcode
%D
%D \startcode[continue]
%D ...
%D ...
%D \stopcode
%D
%D \startcode[start=10]
%D ...
%D \stopcode
%D \stoptyping

%D \macros
%D   {setuptyping}
%D
%D The setup of typing accepts two arguments. The optional
%D first one identifies the user defined ones. If only one
%D argument is given, the values apply to both the standard
%D command \type{\starttyping} and \type{\typefile}.

\def\dosetuptyping[#1][#2]%
  {\ifsecondargument
     \getparameters[\??tp#1][#2]%
   \else
     \getparameters[\??tp][#1]%
   \fi}

\def\setuptyping
  {\dodoubleempty\dosetuptyping}

%D \macros
%D   {definetype}
%D
%D Specific inline verbatim commands can be defined with the
%D following command.

\def\definetype
  {\dodoubleempty\dodefinetype}

\def\dodefinetype[#1][#2]%
  {\unexpanded\setvalue{#1}{\dotype{#1}}%
   \getparameters[\??ty#1][#2]}

%D \macros
%D   {definetyping}
%D
%D For most users the standard \type{\start}||\type{\stop}||pair
%D will suffice, but for documentation purposes the next
%D definition command can be of use:
%D
%D \starttyping
%D \definetyping[extratyping][margin=3em]
%D
%D \startextratyping
%D these extra ones are indented by 1 em
%D \stopextratyping
%D \stoptyping
%D
%D The definitions default to the standard typing values.

\def\presettyping[#1][#2]%
  {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]%
   \getparameters [\??tp#1][#2]}

\def\dodefinetyping[#1][#2]%
  {\setvalue{\e!start#1}{\dostarttyping{#1}}%
   \setvalue{\e!stop #1}{\dostoptyping {#1}}%
   \presettyping[#1][#2]}

\def\definetyping
  {\dodoubleempty\dodefinetyping}

%D We can use some core color commands. These are faster than
%D the standard color switching ones and work ok on a line by
%D line basis.
%D
%D \starttyping
%D \def\setupverbatimcolor%
%D   {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}%
%D    \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
%D    \def\endofpretty       {\stopcolormode}}
%D \stoptyping
%D
%D Since we support a global color too, the folowing
%D definition is better:

% \def\setupverbatimcolor% fast and local versus slow and global
%   {\doifelsenothing{\typingparameter\c!color}
%      {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
%       \let\endofpretty        \restorecolormode % \stopcolormode
%       \let\startverbatimcolor \relax
%       \let\stopverbatimcolor  \relax
%       \let\verbatimcolor      \relax}
%      {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
%       \let\endofpretty        \stopcolor
%       \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
%       \let\stopverbatimcolor  \stopcolor
%       \def\verbatimcolor     {\getvalue{\typingparameter\c!color}}}% command !
%    \doifelsenothing{\typingparameter\c!palet}
%      {\let\prettypalet\empty
%       \let\endofpretty\relax
%       \def\beginofpretty[##1]{}}
%      {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
%
% let's forget about this optimization not that we have mkiv

\def\setupverbatimcolor
  {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
   \let\endofpretty        \stopcolor
   \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
   \let\stopverbatimcolor  \stopcolor
   \def\verbatimcolor     {\getvalue{\typingparameter\c!color}}% command !
   \doifelsenothing{\typingparameter\c!palet}
     {\let\prettypalet\empty
      \let\endofpretty\relax
      \def\beginofpretty[##1]{}}
     {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}

\let\prettypalet       \empty
\let\startverbatimcolor\relax
\let\stopverbatimcolor \relax
\let\verbatimcolor     \relax

%D In the verbatim module, there are some examples given of
%D the more obscure features of the verbatim environments.
%D
%D \startbuffer
%D \startTEX
%D \def\mathematics#1%         % usage: \type {\mathematics{x^2}}
%D   {\ifmmode#1\else$#1$\fi}  % becomes: \mathematics{x^2}
%D \stopTEX
%D \stopbuffer
%D
%D \typebuffer
%D
%D This gives, as can be expected:
%D
%D \getbuffer
%D
%D When we want to see some typeset \TEX\ too, we can say:
%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 \typebuffer
%D
%D or:
%D
%D \getbuffer
%D
%D In a similar way:
%D
%D \startbuffer
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D \stopbuffer
%D
%D \typebuffer
%D
%D gives:
%D
%D \getbuffer
%D
%D The next examples sow how we can directly call for natural
%D \TEX\ comments:
%D
%D \startbuffer
%D \setuptyping
%D   [TEX]
%D   [text=yes]
%D
%D \startTEX
%D \def\mathematics#1%         % usage: \type {\mathematics{x^2}}
%D   {\ifmmode#1\else$#1$\fi}  % becomes: \mathematics{x^2}
%D \stopTEX
%D
%D \setuptyping
%D   [SQL]
%D   [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it]
%D
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D
%D \setuptyping
%D   [SQL]
%D   [ccommand=\tf\underbar]
%D
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D \stopbuffer
%D
%D \typebuffer
%D
%D Now watch:
%D
%D \getbuffer
%D
%D The natural \TEX\ typesetting was introduced when Tobias
%D and Berend started using verbatim \JAVASCRIPT\ and \SQL.

%D \macros
%D   {EveryPar, EveryLine, iflinepar}
%D
%D One of the features of these commands is the support of
%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}.
%D In the documentation of the verbatim support module we give
%D some examples of line- and paragraph numbering using these
%D macros.

%D \macros
%D   {typefile}
%D
%D Typesetting files verbatim (for the moment) only supports
%D colorization of \TEX\ sources as valid option. The other
%D setup values are inherited from display verbatim.
%D The implementation of \type{\typefile} is straightforward:

% new feature (not yet 100\% ok)
%
% \setuptyping[file][numbering=file]
%
% \typefile[start=2,nlines=3]{zapf}
% \typefile[start=continue,nlines=13]{zapf}
% \typefile{zapf}
%
% \setuptyping[file][numbering=line]
%
% \typefile[start=4,step=3]{zapf}
% \typefile{zapf}

\def\typefile
  {\dodoubleempty\dotypefile}

\def\dotypefile[#1][#2]#3%
  {\ifsecondargument
     \dodotypefile[#1][#2]{#3}%
   \else\iffirstargument
     \doifassignmentelse{#1}
       {\dodotypefile[\v!file][#1]{#3}}
       {\dodotypefile[#1][]{#3}}%
   \else
     \dodotypefile[\v!file][]{#3}%
   \fi\fi}

\def\dosetuptypelinenumbering#1% fuzzy
  {\doifundefined{\currenttypingclass\currenttyping\c!start}
     {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}%
   \setuptyping[\currenttyping][#1]%
   \doifelse{\typingparameter\c!numbering}\v!file
     {% kind of special: filters lines !
      \setuplinenumbering[\c!method=\v!file]%
      \donetrue}
     {\doifelse{\typingparameter\c!numbering}\v!line
        {% \setuplinenumbering defaults start/step to 1/1, so we need
         \doifinsetelse\v!continue{#1,\typingparameter\c!start}
           {\scratchcounter0\typingparameter\c!n
            \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}%
           {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}%
         \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}%
         \setuplinenumbering
           [\c!method=\v!type,
            \c!start=\typingparameter\c!start,
            \c!stop=\typingparameter\c!stop,
            \c!step=\typingparameter\c!step]%
         \donetrue}
        {\donefalse}}%
   \ifdone
     \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
     \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
     \def\beginofverbatimlines{\startlinenumbering}%
     \def\endofverbatimlines  {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}%
   \fi}

\def\reporttypingerror#1% temp hack
  {\blank
   \dontleavehmode\hbox\bgroup
     \expanded{\defconvertedargument\noexpand\ascii{#1}}%
     \tttf[\makemessage\m!verbatims1\ascii]%
     \showmessage\m!verbatims1\ascii
   \egroup
   \blank}

\def\dosometyping#1#2#3#4#5%
  {\bgroup
   \let\currenttypingclass\??tp
   \edef\currenttyping{#1}%
   \typingparameter\c!before
   \startpacked % includes \bgroup
   \dosetuptypelinenumbering{#2}%
   \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal}
     {\setuptyping[#1][\c!option=\v!none]}%
   \doif{\typingparameter\c!option}\v!color
     {\expandafter\aftersplitstring#3\at.\to\prettyidentifier
      \settypingparameter\c!option{\prettyidentifier}}%
   \initializetyping
   \startverbatimcolor
   \doifundefinedelse{\currenttypingclass#3\v!global\c!start}
     {\scratchcounter\zerocount}
     {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}%
   \advance\scratchcounter\plusone
   \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}%
   \doifelsenothing{\typingparameter\c!start}
     {#4}
     {\doif{\typingparameter\c!start}\v!continue
        {\setevalue{\currenttypingclass#1\c!start}%
           {\getvalue{\currenttypingclass#3\v!global\c!start}}}%
      \doifelsenothing{\typingparameter\c!stop}
        {\doifelsenothing{\typingparameter\c!nlines}
           {#4}
           {\setxvalue{\currenttypingclass#3\v!global\c!start}%
              {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}%
            #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}%
        {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}%
   \stopverbatimcolor
   \stoppacked
   \typingparameter\c!after
   \egroup}

\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy)
  {\doiflocfileelse{#1}
     {\firstoftwoarguments}
     {\doifinputfileelse{#1}
        {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too
        {\secondoftwoarguments}}}

\def\dodotypefile[#1][#2]#3%
  {\doifelsetypingfile{#3}
     {\dosometyping{#1}{#2}{#3}{\processfileverbatim\readfilename}{\processfilelinesverbatim\readfilename}}
     {\reporttypingerror{#3}}}

%D \macros
%D   {filename}
%D
%D Typesetting filenames in monospaced fonts is possible with
%D
%D \starttyping
%D \filename{here/there/filename.suffix}
%D \stoptyping
%D
%D The definition is not that spectacular.

\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}}

%D This leaves some settings:

\permitshiftedendofverbatim
\optimizeverbatimtrue

%D And a bonus macro:

\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii}

%D The setups for display verbatim and file verbatim are
%D shared. One can adapt the extra defined typing environments,
%D but they also default to the values below. Watch the
%D alternative escape character.

\setuptyping
  [       \c!before=\blank,
           \c!after=\blank,
        \c!bodyfont=,
           \c!color=,
           \c!space=\v!off,
            \c!page=\v!no,
             \c!tab=\s!ascii,
          \c!option=\v!none,
           \c!palet=colorpretty,
            \c!text=\v!no,
           \c!style=\tttf,
        \c!icommand=\ttsl,
        \c!vcommand=,
        \c!ccommand=\tttf,
      \c!indentnext=\v!yes,
          \c!margin=\!!zeropoint,
      \c!evenmargin=\!!zeropoint,
       \c!oddmargin=\!!zeropoint,
           \c!blank=\v!line,
          \c!escape=/, % beware \string\ , should also be accepted
       \c!numbering=\v!no,
           \c!lines=,
           \c!empty=,
           \c!start=1,
            \c!stop=,
            \c!step=1,
        \c!continue=,
          \c!nlines=]

\definetyping[\v!typing]

\presettyping[\v!file][]

% \setuptyping % not needed
%   [\v!file]
%   [\c!start=1,
%    \c!stop=,
%    \c!step=1,
%    \c!continue=,
%    \c!nlines=]

%D The setups for inline verbatim default to:

\setuptype
  [ \c!space=\v!off,
    \c!color=,
    \c!style=\tt\tf, % \tttf gives problems with {\tx \type...}
     \c!page=\v!no,
      \c!tab=\v!yes,
    \c!palet=colorpretty,
   \c!option=\v!normal]

\definetyping[RAW]   [\c!option=RAW]
\definetyping[MP]    [\c!option=MP]
\definetyping[PL]    [\c!option=PL]
\definetyping[PM]    [\c!option=PL]
\definetyping[JS]    [\c!option=JS]
\definetyping[JV]    [\c!option=JV]
\definetyping[SQL]   [\c!option=SQL]
\definetyping[TEX]   [\c!option=TEX]
\definetyping[PAS]   [\c!option=PAS]
\definetyping[PASCAL][\c!option=PAS]
\definetyping[MOD]   [\c!option=PAS]
\definetyping[MODULA][\c!option=PAS]
\definetyping[DELPHI][\c!option=PAS]
\definetyping[EIFFEL][\c!option=EIF]
\definetyping[XML]   [\c!option=XML]
\definetyping[LUA]   [\c!option=LUA]

\installprettytype [RAW]        [RAW]

\installprettytype [TEX]        [TEX]

\installprettytype [PERL]       [PL]
\installprettytype [PL]         [PL]
\installprettytype [PM]         [PL]

\installprettytype [METAPOST]   [MP]
\installprettytype [METAFONT]   [MP]
\installprettytype [MP]         [MP]
\installprettytype [MF]         [MP]

\installprettytype [JAVASCRIPT] [JS]
\installprettytype [JAVA]       [JV]
\installprettytype [JS]         [JS]
\installprettytype [JV]         [JV]

\installprettytype [SQL]        [SQL]

\installprettytype [PASCAL]     [PAS]
\installprettytype [PAS]        [PAS]
\installprettytype [MODULA]     [PAS]
\installprettytype [MOD]        [PAS]

\installprettytype [EIFFEL]     [EIF]
\installprettytype [EIF]        [EIF]
\installprettytype [E]          [EIF]

\installprettytype [XML]        [XML]

\installprettytype [LUA]        [LUA]

\installnewpretty M {\setupprettiesintype {MP}\setupprettytype}
\installnewpretty P {\setupprettiesintype {PL}\setupprettytype}
\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype}
\installnewpretty J {\setupprettiesintype {JV}\setupprettytype}
\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype}
\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth
\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken
\installnewpretty X {\setupprettiesintype{XML}\setupprettytype}

%D We use the \CONTEXT\ color system for switching to and from
%D color mode. We can always redefine these colors afterwards.

\definecolor [colorprettyone]   [r=.9, g=.0, b=.0] % red
\definecolor [colorprettytwo]   [r=.0, g=.8, b=.0] % green
\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue
\definecolor [colorprettyfour]  [r=.8, g=.8, b=.6] % yellow

\definecolor [grayprettyone]    [s=.30]
\definecolor [grayprettytwo]    [s=.45]
\definecolor [grayprettythree]  [s=.60]
\definecolor [grayprettyfour]   [s=.75]

\definepalet
  [colorpretty]
  [  prettyone=colorprettyone,
     prettytwo=colorprettytwo,
   prettythree=colorprettythree,
    prettyfour=colorprettyfour]

\definepalet
  [graypretty]
  [  prettyone=grayprettyone,
     prettytwo=grayprettytwo,
   prettythree=grayprettythree,
    prettyfour=grayprettyfour]

\definepalet [TEXcolorpretty] [colorpretty]
\definepalet [TEXgraypretty]  [graypretty]
\definepalet [PLcolorpretty]  [colorpretty]
\definepalet [PLgraypretty]   [graypretty]
\definepalet [PMcolorpretty]  [colorpretty]
\definepalet [PMgraypretty]   [graypretty]
\definepalet [MPcolorpretty]  [colorpretty]
\definepalet [MPgraypretty]   [graypretty]
\definepalet [JVcolorpretty]  [colorpretty]
\definepalet [JVgraypretty]   [graypretty]
\definepalet [JScolorpretty]  [colorpretty]
\definepalet [JSgraypretty]   [graypretty]
\definepalet [SQLcolorpretty] [colorpretty]
\definepalet [SQLgraypretty]  [graypretty]
\definepalet [PAScolorpretty] [colorpretty]
\definepalet [PASgraypretty]  [graypretty]
\definepalet [EIFcolorpretty] [colorpretty]
\definepalet [EIFgraypretty]  [graypretty]
\definepalet [XMLcolorpretty] [colorpretty]
\definepalet [XMLgraypretty]  [graypretty]
\definepalet [LUAcolorpretty] [colorpretty]
\definepalet [LUAgraypretty]  [graypretty]

\protect \endinput
