Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!ukc!tcdcs!swift.cs.tcd.ie!emcmanus From: emcmanus@cs.tcd.ie (Eamonn McManus) Newsgroups: comp.text.tex Subject: Re: Typesetting programming languages -- RESULTS Summary: TeX macros to typeset C Keywords: TeX, LaTeX, C Message-ID: <1704@tws8.cs.tcd.ie> Date: 2 Mar 90 19:49:59 GMT References: <4354@jhunix.HCF.JHU.EDU> Organization: Computer Science Department, Trinity College Dublin Lines: 168 barrett@jhunix.HCF.JHU.EDU (Dan Barrett) writes: ... >I'd really prefer a system that allowed me to do: > >\begin{c_code} >main() >{ > int foo; > ...etc... >} >\end{c_code} > >without all the muck that tgrind adds. ... Funny you should mention it, as I have just been working on macros to allow just that. They typeset C text as I like it: in a normal font, without bolding either keywords or identifiers. Comments are set slanted, strings in typewriter. The macros are very raw and somewhat untested, so I'd appreciate comments and suggestions. % cprog.tex (or cprog.sty) - formatting of C programs % By Eamonn McManus , February 1990. % This file is not copyrighted. % This allows C programs to be formatted directly by TeX. It can be % invoked by \cprogfile{filename} or (in LaTeX) \begin{cprog} ... % \end{cprog} or (in plain TeX) \cprog ... \end{cprog}. % The formatting is (necessarily) simple. C text is set in a normal Roman % font, comments in a slanted font, and strings in a typewriter font, with % spaces made visible as the `square u' symbol. Tabs are expanded to four % spaces (this does not look good when comments are aligned to the right of % program text). Some pairs of input characters appear as single output % characters: << <= >> >= != -> are respectively TeX's \ll \le \gg \ge \ne % \rightarrow. % The fonts below can be changed to alter the setting of the various parts % of the program. The \cprogbaselineskip parameter can be altered to % change the line spacing. LaTeX's \baselinestretch is taken into account % too. The indentation is \cprogindent, initially 0. % This package works by making a large number of characters active. Since % even spaces are active, it is possible to examine the next character by % making it a parameter, rather than using \futurelet as one would % normally do. This is more convenient, but the coding does mean that if % the next character itself wants to examine a character it may look at a % token from the macro rather than the input text. % The macros were thrown together rather quickly, and could do with some % work. For example, the big macro defined with @[] taking the place of % \{} could be recoded to use \{} and so be more legible. The grouping of % two-character pairs should be controllable, since not everyone will want % it. The internal macros etc should have @ in their names, and should be % checked against LaTeX macros for clashes. % Allow multiple inclusion to go faster. \ifx\undefined\cprogsetup % The whole file. % Define the fonts used for program text, comments, and strings. % Note that if \it is used for \commentfont, something will need to % be done about $ signs, which come out as pounds sterling. \let\ctextfont=\rm \let\commentfont=\sl \let\stringfont=\tt % Parameters. Unfortunately \newdimen is \outer (\outerness is a mistake) % so we need a subterfuge in case we are skipping the file. \csname newdimen\endcsname\cprogbaselineskip \cprogbaselineskip=\baselineskip \csname newdimen\endcsname\cprogindent \cprogindent=0pt \def\makeactive#1{\catcode`#1=\active} \def\makeother#1{\catcode`#1=12} {\obeyspaces\gdef\activespace{ } \obeylines\gdef\activecr{^^M}} \def\spacewidthof{\fontdimen2} % Width of a space in the following font. % The following group makes many characters active, so that their catcodes % in the \cprogchars macro are active, allowing them to be defined. We % could alternatively define more stuff like \activebackslash and use % \expandafter or (carefully) \edef to expand these in the macro. \begingroup \catcode`@=\catcode`\\ \catcode`[=\catcode`{ \catcode`]=\catcode`} \catcode9=\active \makeactive! \makeactive" \makeactive' \makeactive* \makeactive- \makeactive/ \makeactive< \makeactive> \makeactive\{ \makeactive\} \makeactive| \makeactive\\ @gdef@activebackslash[\]@gdef@activestar[*] @gdef@cprogchars[% Don't indent this macro with tabs! They are active. @makeother##@makeother$@makeother&@makeother@%@makeother^% @makeactive"@makeactive'@makeactive*@makeactive-@makeactive/% @makeactive<@makeactive>@makeactive{@makeactive}@makeactive|% @makeactive!@makeactive\@makeactive_% @def!##1[@ifx=##1$@ne$@else@string!##1@fi]% @def-##1[@ifx>##1$@rightarrow$@else$@string-$##1@fi]% @def"[@cquote"]@def'[@cquote']@def*[$@string*$]% % We use \aftergroup in < and > to deal with the fact that #1 might % itself examine the following character. @def<##1[[$@ifx<##1@ll$@else@ifx=##1@le$@else @string<$@aftergroup##1@fi@fi]]% @def>##1[[$@ifx>##1@gg$@else@ifx=##1@ge$@else @string>$@aftergroup##1@fi@fi]]% @def{[$@string{$]@def}[$@string}$]% @def|[$@string|$]@def\[$@backslash$]@def~[$@sim$]% @let/=@ccomment @obeyspaces @expandafter@def@activespace[@leavevmode@space]% @catcode9=@active @def^^I[@ @ @ @ ]% @obeylines @expandafter@def@activecr[@strut@par]] % This macro is illegible. @gdef@cprogarg#1\end{cprog}[#1@endcprogarg] @endgroup \begingroup \makeactive" \makeactive' \gdef\cquote#1{% #1 is the quote, " or '. \begingroup \tt\string#1\stringfont \makeactive\\% \expandafter\def\activebackslash##1{\char`\\\string##1}% \expandafter\def\activespace{\char`\ }% \expandafter\let\activecr=\unclosedstring \makeother*\makeother-\makeother/\makeother<\makeother>\makeother\{% \makeother\}\makeother_\makeother|% \ifx"#1\def'{\char13}\else\makeother"\fi \def#1{\tt\string#1\endgroup}} \endgroup \def\unclosedstring{% \errhelp{A string or character constant earlier in the line was unclosed.^^J So I'm closing it now.}% \errmessage{Unclosed string}% \endgroup} \newlinechar=`^^J % In a comment, we shrink the width of the opening / to that of a space so % that the stars in multiline comments will line up. We also shrink the % closing * for symmetry. \def\spacebox#1{\hbox to \spacewidthof\font{#1\hss}} \begingroup \makeactive* \gdef\ccomment#1{% \ifx#1*\begingroup \noindent \commentfont % We want the width of a space in \commentfont, not \ctextfont. \spacebox{\ctextfont\string/}*% \makeother-\makeother'\makeother"\makeother/% \makeactive*\let*=\commentstar \else \leavevmode\string/#1\kern-1pt % \fi} \makeother* \makeactive/ \gdef\commentstar#1{% \ifx #1/\endgroup \spacebox{$*$}\string/\let\next\relax% \else $*$\let\next#1% \fi\next} \endgroup \ifx\undefined\baselinestretch \def\baselinestretch{1}\fi \def\cprogsetup{\cprogchars \ctextfont \baselineskip=\baselinestretch\cprogbaselineskip \parindent=\cprogindent} \def\cprogfile#1{\begingroup \cprogsetup \input#1\endgroup} % The {cprog} environment or \cprog macro reads in all the argument text. % By making the C definition of \ much cleverer we could avoid this. \def\cprog{\begingroup \cprogsetup \cprogarg} % In LaTeX we need to call \end{cprog} properly to close the environment, % whereas in plain TeX this will end the job. The test for LaTeX is not % bulletproof, but most plain TeX documents don't refer to the LaTeX logo. \ifx\undefined\LaTeX \let\endcprogarg=\endgroup \else \def\endcprogarg{\endgroup\end{cprog}} \let\endcprog=\relax \fi \fi % \ifx\undefined\cprogsetup \endinput -- Eamonn McManus emcmanus@cs.tcd.ie ...!mcsun!cs.tcd.ie!emcmanus One of the 0% of Americans who are not Americans.