8

Assume we have a source code in C++ like so:

void dfs(int p){
    if(o[p]) return;
    o[p]=1;
    c[p] = t++;
    for(int i=0; i<s[p].size(); ++i){
        dfs(s[p][i]);
    }
}

How do we properly display this source code in plain TeX?

The solution should keep all spaces, have all symbols, and use fixed width font.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • You probably want to just use eplain. It has support for a bunch of things you might want, including a \verbatim. – TH. Jun 29 '17 at 20:25
  • @TH. This is unfortunately not possible since I cannot change neither environment nor the command which compiles the document. However if I had a choice, the OPmac (as pointed by wipet's answer) version seems as a good one. – Václav Blažej Jun 30 '17 at 19:31

4 Answers4

9

A version that breaks ligatures and obeys blank lines:

\def\verbatim{%
  \begingroup
  \def\do##1{\catcode`##1=12 }%
  \dospecials
  \otherspecial\ {\ }%
  \otherspecial\-{-\kern0pt }%
  \otherspecial\`{\lq\kern0pt }%
  \otherspecial\'{\rq\kern0pt }%
  \otherspecial\^^M{\endgraf\ifblankline\vskip\baselineskip\fi\blanklinetrue}%
  \parindent0pt\medskip
  \everypar{\blanklinefalse}
  \tt\verbatimaux
}
\newif\ifblankline
\begingroup\endlinechar=-1
\catcode`\|=0 %
\catcode`\\=12 %
|gdef|verbatimaux#1\endverbatim#2{#1|endgroup|par|medskip}%
|endgroup%
\def\otherspecial#1#2{%
  \begingroup\lccode`~=`#1\relax
  \lowercase{\endgroup\def~}{#2}%
  \catcode`#1=\active
}

Some text some text some text some text some text some text.
Some text some text some text some text some text some text.
Some text some text some text some text some text some text.

\verbatim
void dfs(int p){
    if(o[p]) return;
    o[p]=1;
    c[p] = t++;
    for(int i=0; i<s[p].size(); ++i){
        dfs(s[p][i]);
    }
}

-- --- `` '' `? `!
\endverbatim

Some text some text some text some text some text some text.
Some text some text some text some text some text some text.
Some text some text some text some text some text some text.

\bye

enter image description here

egreg
  • 1,121,712
7

Something like

\def\verbatim{%
  \begingroup
    \def\do##1{\catcode`##1=12 }%
    \dospecials
    \obeylines
    \obeyspaces
    \tt
    \verbatimaux
}
\begingroup
\catcode`\|=0 %
\catcode`\\=12 %
|gdef|verbatimaux#1\endverbatim{#1|endverbatim}%
|endgroup
\def\endverbatim{\endgroup}
{\obeyspaces\gdef {\ }}% Omit this for 'explicit' spaces

\verbatim
void dfs(int p){
    if(o[p]) return;
    o[p]=1;
    c[p] = t++;
    for(int i=0; i<s[p].size(); ++i){
        dfs(s[p][i]);
    }
}
\endverbatim

\bye

should do you: a simplified version of LaTeX's verbatim environment. Also see Appendix E of The TeXbook (page 421), which described how Knuth did this for the book itself. (He requires every line is marked up using | ... |.)

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
5

When opmac is used then \begtt...\endtt environment is ready to use:

\input opmac

aha

\begtt
void dfs(int p){
    if(o[p]) return;
    o[p]=1;
    c[p] = t++;
    for(int i=0; i<s[p].size(); ++i){
        dfs(s[p][i]);
    }
}

// -- --- `` '' `? `!
\endtt

\bye

Moreover, you can copy the code from this Opmac trick and you can add \hisyntax{C} before \begtt and you get the following result:

ccode hisyntax

wipet
  • 74,238
  • In opmac you define \setverb with \def\do##1{\catcode`##1=12} inside; wouldn't it be safer to add a space after the 12 as is usual? – Manuel Jun 29 '17 at 19:12
  • 1
    @Manuel The \setverb macro includes definition of the \do followed by its usage: \dospecials followed by \catcode.... So, the last \do expands to \catcode~=12\catcode.... The missing space is irrelevant in this case, because\catcode` is primitive processed at main processor level. – wipet Jun 29 '17 at 19:26
1

In OpTeX, the \hisyntax macro is integrated to the format, so you can write

\fontfam[lm]

\begtt \hisyntax{C} void dfs(int p){ if(o[p]) return; o[p]=1; c[p] = t++; for(int i=0; i<s[p].size(); ++i){ dfs(s[p][i]); } }

// -- --- `` '' ?! \endtt

\bye

and you get the same "colorized" result as in the previous answer.

wipet
  • 74,238