diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tiny_c2l/lx2l-src |
Initial commit
Diffstat (limited to 'support/tiny_c2l/lx2l-src')
-rw-r--r-- | support/tiny_c2l/lx2l-src/0readme.txt | 21 | ||||
-rw-r--r-- | support/tiny_c2l/lx2l-src/config.lx | 87 | ||||
-rw-r--r-- | support/tiny_c2l/lx2l-src/makefile.lxx | 280 | ||||
-rw-r--r-- | support/tiny_c2l/lx2l-src/position.lx | 1078 | ||||
-rw-r--r-- | support/tiny_c2l/lx2l-src/tiny_cvt2ltx.lx | 1477 |
5 files changed, 2943 insertions, 0 deletions
diff --git a/support/tiny_c2l/lx2l-src/0readme.txt b/support/tiny_c2l/lx2l-src/0readme.txt new file mode 100644 index 0000000000..6a078fd48b --- /dev/null +++ b/support/tiny_c2l/lx2l-src/0readme.txt @@ -0,0 +1,21 @@ +This directory contains the LX2l sources of tiny_c2l.l, tiny_t2l.l, +position.dtx, position.ins, position.html, makefile*, and descrip.mms. + +If you want to modify something, you should grab the lx2l preprocessor +(http://www.informatik.fh-mannheim.de/lx2l) to generate the files from the LX2l +source. + +To generate the makefile, use the command + + lx2l -x makefile.lxx + +and then one of the following commands to generate the makefile: + + lx2l d makefile.lx (DOS makefile with lx2l) + lx2l u makefile.lx (UNIX makefile with lx2l) + lx2l v makefile.lx (VMS makefile with lx2l) + lx2l d1 makefile.lx (DOS makefile without lx2l) + lx2l u1 makefile.lx (UNIX makefile without lx2l) + lx2l v1 makefile.lx (VMS makefile without lx2l) + +Then you can type just "make" to build everything else. diff --git a/support/tiny_c2l/lx2l-src/config.lx b/support/tiny_c2l/lx2l-src/config.lx new file mode 100644 index 0000000000..f5d3a1715e --- /dev/null +++ b/support/tiny_c2l/lx2l-src/config.lx @@ -0,0 +1,87 @@ +@@# DEBUG YES + +# If you use the afterpage package, the space for line numbers is +# justified every 100 lines. Unfortunately, the first line on the page +# after a change uses the old widt, the following lines use the new +# width. I don't know, how to fix this problem; so I prefer using a fix +# width for line numbers. +# The same problem occurs if one checks the \count0 register (current page +# number): it is incremented at the second line of each page. + +@@# USE_AFTERPAGE NO + +@# \datum +25.2.2000 + +@# \major_version +1 +@# \minor_version +4 +@# \patch_level +0 + +@# version_missing_blanks +{@calc "%s" " "*(42-strlen("\version from \date"))} + +@#-1 lhead +{@end@} + +@#-1 chead +Produced from %f on %D %t + +@#-1 rhead +{@end@} + +@#-1 lfoot +{@end@} + +@#-1 cfoot +Page %p + +@#-1 rfoot +{@end@} + +@# tab2spc +3 + +@# min_blank +0.25em + +@# max_blank +0.55em + +@# min_xblank +0.3em + +@# max_xblank +0.45em + +@# hyphen_kern +\kern0.05em + +@#-1 l2e_style + \documentclass[10pt]{article}{@@+} + \usepackage{a4,position,fancyhdr}{@@+} + \usepackage[latin1]{inputenc}{@@+} + \textwidth18cm\textheight25cm\hoffset-3cm\voffset-1cm + +@#-1 l209_style + \documentstyle[a4,position,fancyhdr]{article}{@@+} + \textwidth18cm\textheight25cm\hoffset-3cm\voffset-1cm + +@#-1 l2e_style_line + \documentclass[10pt]{article}{@@+} + \usepackage{a4,position,fancyhdr}{@@+} + \usepackage[latin1]{inputenc}{@@+} +{@if USE_AFTERPAGE} \usepackage{afterpage}{@@+} +{@endif} \textwidth18cm\textheight25cm\hoffset-3cm\voffset-1cm + +@#-1 l209_style_line + \documentstyle[a4,position,fancyhdr{@if USE_AFTERPAGE},afterpage{@endif}]{article}{@@+} + \textwidth18cm\textheight25cm\hoffset-3cm\voffset-1cm + +@# copyright +%%{@@+} +%% Copyright (C) 1997 - {@calc get_year("")} Michael Plugge <m.plugge@fh-mannheim.de>{@@+} +%% All rights reserved.{@@+} +%% diff --git a/support/tiny_c2l/lx2l-src/makefile.lxx b/support/tiny_c2l/lx2l-src/makefile.lxx new file mode 100644 index 0000000000..b3ea644faa --- /dev/null +++ b/support/tiny_c2l/lx2l-src/makefile.lxx @@ -0,0 +1,280 @@ +{@lxx_output_extension <.lx>} +{@lxx_mode <k>} +{@default_thread <v>} +{@@@du}{@output_name <makefile>} +{@@@v}{@output_name <descrip.mms>} + +{@@@adu} +{@convert_initial_blanks} +{@map}& {@end@} +{@map}! + +{@@v} +{@map}& {@end@} +{@@v1}{@map}&, +{@@@v} +{@map}!;* +{@map}: : +{@unmap}: + +{@set <dante1>} 1-7 +{@set <dante2>} 8-100 + +@#::dante_files1 multiple.tex multiple.dvi position.dtx position.ins position.sty {@@##} + cvt_rm.c tiny_c2l.l tiny_t2l.l testfile.l testfile.dvi asm_uebung.s asm_uebung.dvi +@#::makefiles makefile.dos makefile.unix makefile.vms +@#::dante_files2 config.lx makefile.lxx position.lx tiny_cvt2ltx.lx + +@# dante_dir1 +{@@@d}dante-neu\ +{@@@u}dante-neu/ +{@@@v}[.dante-neu] + +@# dante_dir2 +{@@@d}dante-neu\lx2l-src\ +{@@@u}dante-neu/lx2l-src/ +{@@@v}[.dante-neu.lx2l-src] + +@# dante_zipfiles +{@@@d}tiny_c2l\*.* +{@@@u}tiny_c2l/* +{@@@v}[.tiny_c2l]*.* + + +@# tiny_c2l +{@@@v}mc sys$disk:[]tiny_c2l$(EXE) +{@@@u}./tiny_c2l +{@@@d}tiny_c2l + +@# xdvi +{@@@d}yap +{@@@uv}xdvi + +@# run cmd +{@@@v}mc sys$disk:[]{@#.cmd}$(EXE) +{@@@u}./\cmd +{@@@d}\cmd + +@# copy +{@@@dv}copy +{@@@u}cp + +@# rename +{@@@dv}rename +{@@@u}mv + +@# lx2lxh +{@@@v}mc sys$disk:[]lx2lxh$(EXE) +{@@@u}./lx2lxh +{@@@d}lx2lxh + +@# obj +{@@@v}$(OBJ) +{@@@^v}.o + +@# exe +{@@@d}.exe +{@@@u}{@end@} +{@@@v}$(EXE) + +@# cvt_rm_dep +{@calc "%s" "\delete"=="cvt_rm" ? " cvt_rm\exe" : "";} + +@# delete +{@@@}cvt_rm +{@@d1v1}cvt_rm +{@@u1}- rm + +@# latex +latex + +@# latex_b +latex{@@v}/batch + +@#- ltx_delete base TEX +{@@@}\delete \base.aux!&\base.dvi!&\base.lis!&\base.log!{@@#.TEX+}&\base.tex!{@@#.TEX#}&\base.toc! +{@@d1v1}\delete \base.aux!&\base.dvi!&\base.lis!&\base.log!{@@#.TEX+}&\base.tex!{@@#.TEX#}&\base.toc! +{@@u1}\delete \base.aux!&\base.dvi!&\base.log!{@@#.TEX+}&\base.tex!{@@#.TEX#}&\base.toc! + +@#- make_ltx short base full src gen opt{@@+} +{@#.short}v: \base.dvi + \xdvi \base.dvi +{@#.short}t2: \base.dvi position.sty + - \latex_b \full +\base.dvi: \full position.sty + - \latex_b \full +{@if "\src" ne ""}{@#.short}t: \full +\full: \src \gen\exe + \run(\gen) \opt \src \full +{@endif} + +{@@#} + +@#- mf target thread +makefile.\target: makefile.lx{@@+} + lx2l {@#.thread}1 makefile.lx makefile.\target + +@#- dante_copy1 file +\dante_dir1\file: \file{@@+} + \copy \file \dante_dir1 + +@#- dante_copy2 file +\dante_dir2\file: \file{@@+} + \copy \file \dante_dir2 + +{@@@@}{@remap}: + +{@@-} +{@@@v} +{@unmap}: +.ifdef __AXP__ +OBJ = .obj_x +EXE = .exe_x +LIBS = ,sys$share:vaxcrtl/lib/exec=$(MMS$TARGET) +.else +OBJ = .obj +EXE = .exe +LIBS = ,c.opt/opt/exec=$(MMS$TARGET) +.endif +LEX = flex +{@remap}: + +.SUFFIXES: .l $(OBJ) $(EXE) +.c$(EXE): + $(CC) $</object=$(MMS$TARGET_NAME)$(OBJ) + link $(MMS$TARGET_NAME)$(OBJ)$(LIBS) + \delete $(MMS$TARGET_NAME)$(OBJ)! +.l$(EXE): + $(LEX) $< + $(CC) $(MMS$TARGET_NAME).c/object=$(MMS$TARGET_NAME)$(OBJ) + link $(MMS$TARGET_NAME)$(OBJ)$(LIBS) + \delete $(MMS$TARGET_NAME).c!&$(MMS$TARGET_NAME)$(OBJ)! +{@@@^v} +CFLAGS = -O2 -fomit-frame-pointer -Wchar-subscripts -Wformat +LEX = flex +LFLAGS = +LDFLAGS = +LIBS = +CC = gcc + +.PHONY: demo tf + +{@@@d} +.SUFFIXES: .l .exe +.c.exe: + $(CC) $< -o$* + djp $* + \delete $*.o $* +.l.exe: + $(LEX) $< + $(CC) $*.c -o$* + djp $* + \delete $*.c $*.o $* +{@@@@} + +all: tc pt2 demo +demo: tiny_c2l.dvi testfile.dvi asm_uebung.dvi multiple.dvi + +\make_ltx#p#position#position.dtx#### +py: position.sty +position.sty: position.dtx position.ins + \latex position.ins + +\make_ltx#tc#tiny_c2l#tiny_c2l.tex#tiny_c2l.l#tiny_c2l#-l# +\make_ltx#tf#testfile#testfile.tex#testfile.l#tiny_c2l#-+ -l1# +\make_ltx#a#asm_uebung#asm_uebung.tex#asm_uebung.s#tiny_t2l#-t8# +md: multiple.dvi +multiple.dvi: testfile.tex tiny_c2l.tex position.sty + - \latex_b multiple + +tc: tiny_c2l\exe +{@@@} +tiny_c2l.l: tiny_cvt2ltx.lx config.lx + lx2l c tiny_cvt2ltx.lx +{@@@dv} +tiny_c2l\exe: tiny_c2l.l +cvt_rm\exe: cvt_rm.c +{@@@@} + +tt: tiny_t2l\exe +{@@@v} +tiny_t2l\exe: tiny_t2l.l +{@@@} +\make_ltx#tf1#testfile1#testfile1.tex#testfile1.l#tiny_c2l#-+ -l1# +tiny_t2l.l: tiny_cvt2ltx.lx config.lx + lx2l t tiny_cvt2ltx.lx + +mf{@@v}: descrip.mms +descrip.mms{@@@}: makefile.lx + lx2l {@@d}d{@@u}u{@@v}v{@@@} makefile.lx +makefile.lx: makefile.lxx + lx2l -x makefile.lxx +\mf(dos)(d) +\mf(unix)(u) +\mf(vms)(v) +mfs: makefile.lx {@forall}\makefiles {@repeat} + lx2l d1 makefile.lx makefile1.dos + lx2l u1 makefile.lx makefile1.unix + lx2l v1 makefile.lx makefile1.vms + +position.dtx: position.lx config.lx + lx2l p position.lx + +position.ins: position.lx + lx2l i position.lx + +html: position.html position.idx +pxh: position.html + +position.lxh: position.lx lx2lxh\exe + \lx2lxh position.lx position.lxh +position.html: position.lxh config.lx + lx2l h position.lxh +position.idx: position.lxh config.lx + lx2l i1 position.lxh +{@@v} +lx2lxh\exe: lx2lxh.l +{@@@} + +dante: dante_zip clean +dante_zip: tiny_c2l.zip +tiny_c2l.zip: dante_files + \rename dante-neu{@@v}.dir{@@@} tiny_c2l + zip -9ur tiny_c2l \dante_zipfiles + \rename tiny_c2l{@@v}.dir{@@@} dante-neu +dante_files:{@forall} {@#dante_dir1}\dante_files1{@repeat}\ + {@forall} {@#dante_dir1}\makefiles{@repeat}\ + {@forall} {@#dante_dir2}\dante_files2{@repeat} + +{@forall}\dante_copy1(\dante_files1) +{@repeat} +{@forall}\dante_copy1(\makefiles) +{@repeat} +{@forall}\dante_copy2(\dante_files2) +{@repeat} + +{@@@@} +clean:\cvt_rm_dep + \ltx_delete(tiny_c2l)(1) + \ltx_delete(testfile)(1) + \ltx_delete(asm_uebung)(1) + \ltx_delete(multiple)(0) + \delete tiny_c2l.dbg!&tiny_t2l.dbg!{@@@}&lx2l.dbg!&position.html!&position.lxh!{@@@@} + \ltx_delete(position)(0){@@@}&position.dtx!{@@@@} +{@@@} + \delete makefile.lx!&makefile.dos!&makefile.unix!&makefile.vms!&makefile1.dos!&makefile1.unix!&makefile1.vms! + \ltx_delete(testfile1)(1) + \ltx_delete(tiny_t2l)(1) + \ltx_delete(linediagram)(1) + \ltx_delete(tf)(1) +{@@@@} +distclean: clean + \delete {@@@}tiny_c2l.l!&{@@@@}tiny_c2l.c!&tiny_c2l\obj!&tiny_c2l\exe! + \delete {@@@}tiny_t2l.l!&{@@@@}tiny_t2l.c!&tiny_t2l\obj!&tiny_t2l\exe! + \delete cvt_rm\obj!&cvt_rm\exe!&position.sty +{@@@} + \delete makefile!&descrip.mms!&position.sty!&position.ins! + \delete{@for [dante1]} {@#dante_dir1}\dante_files1!{@repeat} + \delete{@for [dante2]} {@#dante_dir1}\dante_files1!{@repeat} + \delete{@forall} {@#dante_dir1}\makefiles!{@repeat} + \delete{@forall} {@#dante_dir2}\dante_files2!{@repeat} diff --git a/support/tiny_c2l/lx2l-src/position.lx b/support/tiny_c2l/lx2l-src/position.lx new file mode 100644 index 0000000000..6df745a842 --- /dev/null +++ b/support/tiny_c2l/lx2l-src/position.lx @@ -0,0 +1,1078 @@ +{@default_thread <p>} +{@ext_default <>} +{@@i}{@output_name <position.ins>} +{@@p}{@output_name <position.dtx>} +{@@h}{@output_name <position.html>} +{@@i1}{@output_name <position.idx>} +{@@t1}{@output_name <position.toc>} + +{@@@}{@include <config.lx>} +{@@@1}{@use_map0} + +{@@ip} +{@map1} +{@@+} +% {@end@} + +{@map2} +{@@+} +%% {@end@} + +{@map4}<$<$ +{@map4}>$>$ +{@map4}§<p> + +{@@h} +{@map4}<< +{@map4}>> +{@map4}§<p> + +{@@hi1} +{@map3} _ +{@map3}\{@end@} +{@unmap} \ + +@#1 v arg +{@#.arg} + +@# \tex +{@@h}TeX +{@@^h}\TeX{} + +@# \latex +{@@h}LaTeX +{@@^h}\LaTeX{} + +@# \tc +{@@h}<code>tiny_c2l</code> +{@@^h}|tiny_c2l| + +@# \cvt +{@@h}<code>cvt2ltx</code> +{@@^h}|cvt2ltx| + +@# \mb \txt +{@@h}\txt +{@@^h}\mbox{\txt} + +@# \em \txt +{@@h}<em>\txt</em> +{@@^h}\emph{\txt} + +@#1 section txt +{@@h}<h1>{@#.txt}</h1> +{@@ip}\section{{@#.txt}} +{@@@1} + +@#1 subsection txt +{@@h}<h2>{@#.txt}</h2> +{@@ip}\subsection{{@#.txt}} +{@@@1} + +@#1 subsubsection txt +{@@h}<h3>{@#.txt}</h3> +{@@ip}\subsubsection{{@#.txt}} +{@@@1} + +@#1 dm macro +{@@ip}\DescribeMacro{{@#.macro}} +{@@h}<a name={@#.macro+3}></a> +{@@t1} +{@@i1}\index{{@#.macro+3}}{@@+} + +@#1 bm macro +{@@ip} \begin{macrocode}{@@+} +{@#.macro}{@@+} +% \end{macrocode} +{@@h}<pre>{@@+} +{@#.macro}{@@+} +</pre> +{@@@1} + +@#1 bm1 macro +{@@ip} \begin{macrocode}{@@+} +{@#.macro} +{@@h}<pre>{@@+} +{@#.macro} +{@@@1} + +@#1 bm2 macro +{@@ip}{@#.macro}{@@+} +% \end{macrocode} +{@@h}{@#.macro}{@@+} +{@@@1} +</pre> + +@#1+4 c x +{@@i@1} +{@@p}/$\ast$\bs{}{@#.x} +{@@h}/*\{@#.x} + +@#1+4 o x +{@@i@1} +{@@p}/$\ast$\bs{}o{@#.x}$\ast$/ +{@@h}/*\o{@#.x}*/ + +{@@-} +{@calc [\beta] "%s" \minor_version%2==1 ? " (beta release)" : "";} +{@calc [\version] "%s" "\major_version.\minor_version.\patch_level\beta"} +{@calc [\ltx_date] "%d/%02d/%02d" get_year("\datum");get_month("\datum");get_day("\datum");} +{@@}--- END OF PROLOG --- +{@@p@1}{@use_char} +% \iffalse +%% +%% File `position.dtx'. +{@#copyright} +%% Please send error reports and suggestions for improvements to: +%% +%% Michael Plugge +%% Neustadter Str. 132 +%% D-67360 Lingenfeld +%% Germany +%% Internet: <m.plugge@fh-mannheim.de> +%% +% \fi + +% \CheckSum{0}{@use_map2} +\CharacterTable + {Upper-case \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 + Lower-case \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 + Digits \0\1\2\3\4\5\6\7\8\9 + Exclamation \! Double quote \" Hash (number) \# + Dollar \$ Percent \% Ampersand \& + Acute accent \' Left paren \( Right paren \) + Asterisk \* Plus \+ Comma \, + Minus \- Point \. Solidus \/ + Colon \: Semicolon \; Less than \< + Equals \= Greater than \> Question mark \? + Commercial at \@ Left bracket \[ Backslash \\ + Right bracket \] Circumflex \^ Underscore \_ + Grave accent \` Left brace \{ Vertical bar \| + Right brace \} Tilde \~}{@use_char} +% +% \iffalse +%<*driver> +\documentclass{ltxdoc} +\usepackage{a4wide,fancyhdr} +\pagestyle{fancy} +\newenvironment{dsc}{\begin{list}{}{\leftmargin7em\labelwidth5em + \itemindent0em\itemsep0pt}}{\end{list}} +\newenvironment{dsca}{\begin{list}{}{\leftmargin7em\labelwidth5em + \itemindent0em\itemsep0pt\parsep0pt}}{\end{list}} +\newenvironment{dscb}{\begin{list}{}{\leftmargin4em\labelwidth3em + \itemindent0em\itemsep0pt\parsep0pt}}{\end{list}} +\gdef\itx#1{\item[\bs\tt #1\hfill]} +\gdef\itm#1{\item[\tt #1\hfill]} +\gdef\<#1>{$<$#1$>$} +\gdef\bs{$\backslash$} +\begin{document} + \DocInput{position.dtx} +\end{document} +%</driver>{@use_map1} +\fi +\pagenumbering{roman} +\tableofcontents +\pagenumbering{arabic} +\title{The position package and tiny\_c2l: \\[-.5ex]First Attempt in vertical + Alignment and ``smart'' Line Breaking} +\author{Michael Plugge} +\date{{@#ltx_date}} + +\maketitle + +{@@hp} +\begin{abstract} +This package provides a set of macros that can be used for vertical +alignment of code and ``smart'' (context-sensitive) linebreaking. It is an +first attempt to solve the problems concerning whitespace and linebreaking +in prettyprinting. A small \{C/C++/Java\}$\rightarrow$\latex converter +(\tc) is included as sample application to show how the macros can +be used. +\end{abstract} + +{@#section}{Introduction} +Position.sty and \tc --- Makros for vertical alignment and ``smart'' +line breaking. + +This is a set of experimental macros, which I hacked for use in the cvt2tx +package. The macros allow a vertical alignment using the roman(!) font. +The basic idea is to have a grid of ``should be'' positions on the paper, +for example .5em per (input) character. If two or more blanks or a tab +character are found in the input text, the corresponding position is used +for output; if there is only one blank, it is stretched (or shrinked) to +get near this ``ideal'' position. The actual value for one blank is +\mb{{@#min_blank} \dots{} {@#max_blank}}. + +Another macro (|\mpout|) can be used to generate ``leaders'' between +specific positions in the input text. You specify the (ASCII/grid) start +position, the end position and the fill character; then the corresponding +range in the .dvi fileis filled using this pattern. This macro is quite +useful for block comments or long horizontal structures. + +A small \mb{\{C/C++/Java\} $\rightarrow$ \latex} converter (\tc) +is also included as example how to use the macros. Only a few very basic +things are implemented: recognition of keywords, comments, strings etc. No +reformatting of text is done, lex/yacc files are not recognized (this may +lead to erors if a pattern contains a single \texttt{"} without prepended +backslash!)\dots{} The first version of \tc was just a quick \& dirty +hack to get some testfiles for the macros. Later I added some features in +order to build a tiny but usable converter. + +The macros are intended to be used later in another package (\cvt). The +converters of this family are much more powerful and and have less +restrictions. Unfortunately I didn't get the time to do some work on these, +too. The main reason for making public this test software is to get +opinions and critics as well as additions of personal needs. The more +feedback I will get, the faster \cvt and \tc will come to a more +useful state. + +The documentation is quite poor; if I get the time, it will be improved. +Comments, bug reports/fixes or extensions are welcome. + +Copyright \copyright{} 1997,1998 Michael Plugge \<m.plugge@fh-mannheim.de> + +{@#subsection}{The Problem} +When one starts writing a prettyprinter that uses \latex for formatting, +some tough nuts are to crack. Two of these are handling of white space and +linebreaking. AFAIK, these problems are currently not solved in a +satisfactory way. + +One common way to handle blanks and tabs is to convert tab characters to an +appropriate number of spaces and then convert each space to a fixed amount +of space (for example 0.5em). If a proportional font is used to document +the program source (this gives IMHO the fanciest result), vertical +structures as assignment blocks, block comments, vertical alignment of Lex +actions etc. are lost because the characters have different width. Some +converters try to handle this problem by using a non-proportional font +(typewriter); but this seems to be not a satisfactory way (it is not often +used, too). + +The other problem is that of overlong source lines. For this problem +currently three different approaches are used: + +\begin{itemize} +\item The first way is to do no linebreaking at all; the user has to be + aware that lines are not too long; if not, one simply gets overful \tex + boxes. + + This way is ok if one uses the prettyprinter mainly for own programs; + but it is bad if you have to print foreign programs with many overlong + lines. + +\item The second way uses \latex for linebreaking, without additional + environments etc. This is a simple solution, but the result does not + satisfy: the start of the continuation lines goes back to the line + begin. So all indentation is messes up. + +\item The third way is a little more elaborated: in this case linebreaking + does not go back to the begin of the line, but rather to the current + indentation level (with a little additional offset to denote the + continuation line). This method was used in \cvt; it gives generally + better results, but doesn't satisfy in all situations too. + + If this method is used for strings, the (inserted) blanks at line begin + are not part of the real string; but they would be included by a + compiler. + + Even far worse is the case of C++ comments (//): these end naturally at + the end of a line. The text from the continuation lines would be + interpreted by a compiler (from syntax point of view) as code, not as + comment. +\end{itemize} + +{@#subsection}{Line breaking in the tiny\_c2l/position package} +The \tc/position package has a very flexible system for line +breaking: it can output some text before the actual line break, change the +value of indentation and output some text at the begin of the new +(continuation) line. In \tc, these features are used to generate a +context-sensitive way of linebreaking: + +\begin{itemize} +\item For normal code the current indentation is used with a little + additional offset (.5 em) to mark continuation lines. + +\item For preprocessor lines, `{\tt \symbol{'040}}\bs' is appended to the + end of the line; the continuation lines are indented slightly more than + normal code lines (1.5 em). + +\item For strings, a backslash is appended at the end of the line; the + continuation lines get \emph{no} indentation (they go back to the start + of the new line). + +\item C comments (starting with /$\ast$) get a `$\ast$' at the start of + each continuation line. Indentation is done such that the `$\ast$' + characters are vertically aligned (even if the comment start is shifted + right due to wide characters as shown in testfile.l). + +\item C++ comments (starting with //) get `//' at line begin. The `//' + characters of the continuation lines are vertically aligned with the + first `//' (as in the case of C comments) +\end{itemize} + +Even though some problems remain, this way of line breaking gives much more +satisfactory results than the other three ways. + +{@#subsection}{Handling of white space in the tiny\_c2l/position package} +In the \tc/position package, white space is handled quite different +than in other converters. The goal is to get an output that is (concerning +vertical structures) mostly similar to the ASCII input. To approach this +goal the output sheed is divided into several (equidistant) positions which +are directly mapped to the ``ASCII positions'' of the source file In the +current version, the ``grid width'' is 0.5em; it is determined by the +macro |\ind|). All text must be output using one of three macros: +|\jmpo{position}{txt}|, |\njo{position}{text}|, |\xnjo{cnt}{position}{txt}| +or |mpout\{pos1\}\{pos2\}\{pattern\}|. + +\begin{dsc} + +\itx{jmpo\{pos\}\{txt\}:} jump to the position which is specified in the + first parameter, and then output the text from the second parameter. + This macro does the main work for vertical alignment; it is used if in + the source text multiple blanks or (at least one) tab character is + found. (Depending on the current output position, it may jump a long way + concerned to the ASCII file.) + +\itx{njo\{pos\}\{txt\}:} nojump, output: This macro is + used if a single blank is found in the source text. In this case, the + output does not jump to the ``grid'' position, but rather tries to reach + this position using some glue ({@#min_blank} to {@#max_blank}). If the + grid position is too far right, {@#max_blank} is used; if the current + position is already more right than the grid position, {@#min_blank} is + used. + +\itx{xnjo\{cnt\}\{pos\}\{txt\}:} This macro is similar to |\njo|, with a + little difference: the glue is {@#min_xblank} to {@#max_xblank}, and it + can be used for multiple blanks (the actual count is given in the first + parameter). This macro is used for ``fill comments'' in \tc to + avoid |\jmpo| in this context; it gives a relative constant blank width + in this case. + +\itx{mpout\{p1\}\{p2\}\{c\}\{k\}:} This macro is used to fill the space + between the positions |p1| and |p2| with the character(s) given in |c|. + The parameter |\{k\}| specifies an additional kern (positive or + negative) that is inserted after each pattern (this is used for example + for $<$ or $>$). + +\end{dsc} + +These macros keep track of the current position in the .dvi file. If the +current position is already larger than the requested grid position, only a +small space ({@#min_blank}) is inserted in all cases. If direct output +would be used (without these macros), the position macros cannot work +properly because the internal variables contain wrong position values. + +{@#section}{tiny\_c2l Mini Manual} +|tiny_c2l| is a little converter that converts C, C++ or Java source code +to \latex. The first version of |tiny_c2l| was just a quick hack to +generate some testfiles for the position macros. Now it is slightly +extended to work as a ``real'' converter, although it has many limitations. +It can be used either as a simple converter, as starting point for an own +converter project or just as example how to use the macros of the position +package. + +{@#subsection}{Invocation} +|tiny_c2l| accepts two arguments and a number of options. The first +argument is the input file name, the second argument is the output file +name. Both may be omitted: if no output name is given, stdout is used +instead; if no input name is given, stdin is used for input. If you want to +use stdin for input, you can also use the -o$<$name$>$ option to specify an +output file name. + +{@#subsection}{Options} +|tiny_c2l| has a number of options; these can be placed anywhere in the +command line (before, between or after the filenames). If multiple values +are given for a specific option, the only last value is used. + +All options accept only a short form. If an option accepts parameters, no +blank must be inserted between the option character and the option +parameter. If an option contains blanks (for example a header or footer +text) it must be quoted. + +Valid options are: + +\begin{dsca} +\itm{-h<position><txt>} +\itm{-f<position><txt>} These two options control the header (-h) and + footer (-f) text. |<position>| is a single character that specifies the + requested position: l~(left), c~(center) or r~(right). |<txt>| is the + text that will be output at this position. + + For the |<txt>| parameter, some escape sequences are defined for + inclusion of file name and date/time: + \begin{dscb} + \itm{\%f} input file name + \itm{\%p} page number + \itm{\%t} time (HH:MM) + \itm{\%D} date (DD-MMM-YYYY) + \itm{\%h} hour + \itm{\%M} minute + \itm{\%d} day of month + \itm{\%m} month (numeric value) + \itm{\%n} (english) name of month (full form) + \itm{\%s} (english) name of month (short form) + \itm{\%N} (local) name of month (full form) + \itm{\%S} (local) name of month (short form) + \itm{\%y} year + \itm{\%\%} the `\%' character itself + \end{dscb} + + Usually these texts will contain some blanks; in this case they must be + quoted. For example the standard center header would be written as + \par\hspace*{2em}\mb{\tt "-hcProduced from \%f on \%D \%t"} +\itm{-+} use C++ mode (with additional keywords and // comments) +\itm{-j} use Java mode (with additional keywords and // comments) +\itm{-t<cnt>} number of blanks per tab +\itm{-d} debug mode; the FLEX debug output is written to the file tiny\_c2l.dbg +\itm{-o<name>} specify output name (useful if stdin is used for input) +\itm{-?} show a short help screen +\end{dsca} + +{@#subsection}{Special Features} +{@#subsubsection}{Embedded \latex comments} +|tiny_c2l| provides two backdoors to include embedded \latex comments: +``append mode'' and ``verbatim mode''. + +\begin{itemize} \item The ``append mode'' embedded \latex is defined for + C or C++ style comments. It starts with {@#c}(a) (resp. //\bs{}a) and + ends with the comment end ($\ast$/ for C comments, line end for C++ + comments). The comment delimiters (in the standard form /$\ast$ or //) + are written to the output file. + + Everything within these comments is copied directly to the output file, + without any modifications. So you can include formulas (or even pictures + ;-))) in the comment. + +\item ``Verbatim mode'' embedded \latex is defined only for C style + comments. It is used to include global (\latex) options or section + commands as |\section|, |\subsection|, \dots{}, |\index| in the file; it + could be used also to generate a two-column listing of a part of the + file. + + This mode is started with {@#c}(v) and ends with the comment end (at the + first $\ast$/). The comment delimiters /$\ast$ and $\ast$/ are not + written to the output file. +\end{itemize} + +{@#subsubsection}{``Fill'' Comments} +Fill comments are a special mode for of normal (multiline) comments in +which linebreaks are rearranged to fill the lines in the generated .dvi +file. Fill comments are started with {@#c}(f) (resp. //\bs{}f). For C style +comments each new line must have a leading `$\ast$'. + +The linebreak, leading blanks, and (in C mode) the `$\ast$' and following +blanks are replacedby a single blank. So the whole comment appears in the +\latex file as a single long line; this is broken by the |\njo| and |\xnjo| +macros. Blanks in fill comments are not handled by the |\jmpo| macro, but +rather by |\xnjo|. This macro uses reduced glue (the current range is from +{@#min_xblank} to {@#max_xblank}); for multiple blanks no jump to the grid +position is done, it inserts just more space. This is done because in fill +comments positioning makes no sense. + +You can force a linebreak if you use a single @ character at the end of a +line. This character is not printed in the output file. + +{@#subsubsection}{Block comments} +Block comments start with {@#c}(b) and end with $\ast$/. They are used +mainly for procedure headers; they use some special formatting options: + +\begin{itemize} +\item The used font is |\blockfont| (default: roman). +\item The `:' character is moved to the grid position even after a single + blank. +\item If a single character is found at the end of the line, this is also + moved to the grid position. +\end{itemize} + +{@#subsubsection}{Omitting source lines in the Output} +To omit a number of lines in the output, the command {@#o}(<cnt>) can be +used. It must appear on an own line (leading or trailing blanks are +allowed). \<cnt> is the number of lines to omit: for example, {@#o}(20) +would omit the next 20 lines. + +To omit a larger piece of code, the command {@#o}(+) and {@#o}(-) can be +used. Everything between the lines containing these commands is omitted; +instead a line is inserted which tells how many lines were skipped. If you +want to omit lines without the skip message, use the command {@#o}(q) +(instead of {@#o}(+)) or {@#o}(<cnt>q) (instead of {@#o}(<cnt>)). These +commands suppress the skip message; they just skip the lines. + + +{@#subsubsection}{Support for multiple File Projects} +The generated file contains some code to detect if it is used as standalone +file or if it is included from another file. All you have to do for this +feature is to include a line containing |\usepackage{position,fancyhdr}| in +the preamble of the wrapper file; then you may include (or input) one or +more files generated by \tc. + +{@#subsubsection}{\LaTeX~2.09/\LaTeXe\ Support} +The generated file automagically detects if \latex~2.09 or \LaTeXe\ is used +by checking the |\documentclass| macro. Two preambles are provided; so you +can use the file with any \latex version without trouble and without +changing to the slow compatibility mode of \LaTeXe. + +{@#section}{Future Enhancements} +{@#subsection}{tiny\_c2l Converter:} +Many enhancements are possible for \tc. Some of these are: + +\begin{itemize} +\item Special support for Lex/Yacc files +\item Support for other programming languages +\item Integrated invocation of \latex, xdvi, dvips and print (using a + command-line option) +\item Special (direct) support for multiple-file projects +\item Native VMS-CLI interface +\item Autogeneration of |\section|, |\subsection| and |\index| entries for all + functions (and classes); autogenerate also a fileheader and (on + request) a table of contents and index +\item Refinement of the linebreaking and alignment code (will be discussed in + the next two sections) +\end{itemize} + +Many of these features are implemented already in the \cvt package. +If I get the time, I'll include them into |tiny_c2l| (or rewrite \cvt +to include the |tiny_c2l| code). + +{@#subsection}{Line Breaking:} +Currently line breaking is done in a brute force way: the only check that +is done by the macros is if the line is too long if the current box is +added. If yes, the line is broken, if not, the box is just shipped out. +This approach leads sometimes to bad linebreaks: for example, it is +possible that a linebreak occurs directly after a ", or in the mid of a +|for(;;)| command (between the two `;'). + +A much better solution would be to have not only \em{one} output box, but +rather 3 or~5, which are filled sequentially and are used as a \emph{fifo} +register. Each box should have an associated |\penalty| dependend on the +syntactical structure of the box and its position in the output. Each box +gets some additional |\penalty| if a new box is added to the list (and the +other boxes are shifted left by this). This reflects the decision that the +linebreak should appear at the rightmost position, if it is syntactically +ok. Linebreaking would be done at the position with the lowest |\penalty| +(which could be even the first box). + +The actual values of |\penalty| would need some thorough studies. This +approach would yield a much more fancy way of linebreaking: linebreaks +would be done at ``good'' positions, not simply at the first position that +leads to an overful line (which is also usually the last possible position +for the linebreak). + +{@#subsection}{Vertical Alignment:} +Also in this area some refinements could be done; but they seem to be not +very simple: + +In |tiny_c2l|, vertical alignment is done on a local point of view: only the +current environment is considered. It would be nice to extend the scope for +alignments to be consistent for a page (or even complete functions or the +whole file). + +One could look for the position of some special structures (for example +start position of comments, position of the `=' in assignments etc.) and to +keep a list of these positions in the last 100 lines (in the case of scope +of a page). The corresponding positions in the .dvi file should be +calculated too (either by \tex or by using approximate values in C). If in +the selected range (100 lines back, in the current function or in the file) +two patterns have the same ASCII position, they should get also the same +.dvi position (which means, these structures get a position that must not be +a grid position, but could be shifted right also. + +Implementing this feature would give a fine output without user +intervention, but it seems to be not trivial. It would require at least two +scanner passes; if the .dvi positions are calculated by \tex, it would be +still more expensive in terms of processing time. + +{@#section}{Implementation} +{@#subsection}{Annnouncement Message} +{@#dm}{announcement message} +First, we announce the macro package. +{@#bm1}§%<*package> +\ifx\documentclass\undefined %this package may be used also with LaTeX 2.09 ;-))) + \message{position.sty §{@use_char}{@#version}\space <{@#ltx_date}>} +\else + \NeedsTeXFormat{LaTeX2e} + \ProvidesPackage{position}[{@#ltx_date}\space {@#version}] + \typeout{Package: position {@#version}\space {@@##} + <{@#ltx_date}{@use_map1}{@#bm2}§>} +\fi§ +{@#subsection}{\latex Format and standalone/include file check} +{@#dm}{file prolog} +Now comes a tricky part: we want to check (without need of user input) +if this file is used with \LaTeXe or \LaTeX~2.09, and also if it is used +as standalone file or as an include file. This task is done by the macro +|\getformat| and the conditional |\ifmfiles| in the following way: + +The prolog of a generated file looks like this (explanation follows): + +\begin{verbatim} +\ifx\getformat\undefined + \newcount\getformat\getformat0 +\else + \mfilestrue\getformat3 +\fi +\ifx\documentclass\undefined\advance\getformat1\fi + +\ifcase\getformat + \documentclass[10pt]{article} + \usepackage{a4wide,position,fancyhdr} + \usepackage[latin1]{inputenc} +\or + \documentstyle[a4wide,position,fancyhdr]{article} +\else\fi % multiple file input: don't load format +\end{verbatim} + +The first line checks, if |\getformat| is already defined; if yes, we can +be sure that the file was included (in this case, |\getformat| was defined +in position.sty). The conditional |\ifmfiles| is set to true +(|\mfilestrue|) and |\getformat| is set to 3. If |\getformat| was not yet +defined, we are in single file mode: |\getformat| is declared and +initialized with~0. + +The next line checks the used format file: if |\documentclass| is +undefined, we are in \LaTeX~2.09, otherwise we use \LaTeXe. + +Now we have all informations available in the counter register +|\getformat|: + +\begin{itemize} +\item If |\getformat| is 0, we are in single file mode, using \LaTeX~2.09 +\item If |\getformat| is 1, we are in single file mode, using\LaTeXe +\item If |\getformat| is 3, we are in multiple file mode, using\LaTeX~2.09 +\item If |\getformat| is 4, we are in multiple file mode, using\LaTeXe +\end{itemize} + +In multiple file mode, the conditional |\ifmfiles| is also set to true +(this conditional is used at the end of the file). Now comes a +multiway-switch (|\ifcase\getformat|) with the |\documentclass| +(|\getformat|==0 for \LaTeXe) or |documentstyle| (|\getformat|==1 for +\LaTeX~2.09) command. If |\getformat| is larger than~1, nothing is done at +this point. In this case the file is included into another file, which +already loaded the position style file. + +{@#dm}{file epilog} +The epilog of a generated file has the following structure: + +\begin{verbatim} +\ifmfiles\def\END{\relax}\else\def\END{\end{document}}\fi +\END +\end{verbatim} + +If the conditional |\ifmfiles| is true (it is set at beginning of the +file), the macro |\END| is defined as |\relax|, otherwise it is defined as +|\end{document}|. If the file was used as standalone file, the final macro +|\END| is expanded to |\end{document}|; otherwise it is expanded to +|\relax|, and control goes back to the wrapper file. + +{@#dm}{\getformat} +Now we are again in the file |position.sty|. First we have to check if +|\getformat| was already defined (in case of a stand-alone file). If not, +it it declared at this point. + +{@#bm}§\ifx\getformat\undefined\newcount\getformat\getformat0\fi +\newif\ifmfiles\mfilesfalse§ + +{@#subsection}{Definitions} +{@#subsubsection}{Font definitions} +The following part contains some definitions for used fonts. +The switch |ifoldlatex| is used for compatibility with \LaTeX~2.09. If +this conditional is set to true, the low-level font declarations |\rm|, +|\bf|\dots{} are used instead of the \LaTeXe{} font declarations +|\normalfont|, |\bfseries|\dots{} + +The font |\blockfont| is used for block comments (that is for comments +starting with |/*\b| or |/*********...*****\b| in C. All other definitions +should be obviously. + +{@#dm}{special characters} +The hyphen character (`-') is too short for standard program code; so it +is replaced by a macro |\mm|. For text fonts, we use a dash with a little +kern around it for the ASCII character `-' +(|{@#hyphen_kern}{--}{@#hyphen_kern}|); for the tt font we have to switch +back to a single hyphen. + +Another problem are the braces |\{| and |\}|: in the tt fonts they are not +defined. In the generated file, `\{' is replaced by the macro |\brl| and +`\}' is replaced by the macro |\brr|. + +In a text font, the macros |\brl| and |\brr| are expanded to `\bs\{' +resp.\ `\bs\}'; for the tt font family these macros are replaced by +|\symbol{`\{}}| and |\symbol{`\}}}|. + +All these definitions are made by two macros: |\pstd| enables the +definitions for a standard font, while |\ptt| enables the tt font +definitions. + +Each font command contains the (\latex) font change command (e.g. +|\bfseries|) and either |\ptt| or |\pstd| to select the translation of the +special symbols. + +{@#bm1}§\newif\ifoldlatex\oldlatextrue +\gdef\pstd{\gdef\mm{§{@#hyphen_kern}{--}{@#hyphen_kern}{@#bm2}§{}}\gdef\brl{\{}\gdef\brr{\}}} +\gdef\ptt{\gdef\mm{-}\gdef\brl{\symbol{`\{}}\gdef\brr{\symbol{`\}}}} +\ifoldlatex + \gdef\basefont{\rm\pstd} + \gdef\blockfont{\rm\pstd} + \gdef\keywordfont{\bf\pstd} + \gdef\stringfont{\tt\ptt} + \gdef\commentfont{\it\pstd} + \gdef\headfont{\sl\pstd} + \gdef\footfont{\sl\pstd} +\else + \gdef\basefont{\normalfont\pstd} + \gdef\blockfont{\normalfont\pstd} + \gdef\keywordfont{\bfseries\pstd} + \gdef\stringfont{\ttfamily\ptt} + \gdef\commentfont{\itshape\pstd} + \gdef\headfont{\slshape\pstd} + \gdef\footfont{\slshape\pstd} +\fi +\basefont§ +{@#subsubsection}{Definition of special Characters} +Here are the definitions for some special characters and +some macros for output of multiple characters: + +\begin{dsca} +\itx{spy} symbol for blank in LEX/YACC pattern (printed as {\tt \symbol{'040}}) +\itx{sq} symbol used for single quote in program code +\itx{qql} opening double quote for strings (\latex or tt style; default is \latex style) +\itx{qqr} closing double quote for strings (same as above) +\itx{ul} alternate form for `\_' (with additional kern) +\itx{bs} multiple backslashes (with additional kern) +\itx{mlt} multiple $<$ characters (with additional kern) +\itx{mgt} multiple $>$ characters (with additional kern) +\itx{mast} multiple stars +\itx{mblank} multiple blanks +\itx{n} empty line/end of a line +\end{dsca} + +The alternate forms for |\qql|, |\qqr| and |\ul| are commented out; you may +use these if you like. + +{@#bm}§\gdef\spy{{\tt \symbol{'040}}} +\gdef\sq{{\tt\symbol{13}}} +\gdef\qql{``} +\gdef\qqr{''} +\gdef\ul{{\_\kern.1em}} + +%\gdef\qql{{\tt "}} +%\gdef\qqr{{\tt "}} +%\gdef\ul{\_} +\gdef\bs#1{$\count255=1\loop\ifnum\count255<#1\advance\count255 by 1 + \backslash\hspace*{-.2em}\repeat\backslash$} +\gdef\mlt#1{$\count255=1 \loop\ifnum\count255<#1\advance\count255 by 1 + <\hspace*{-.4em}\repeat<$} +\gdef\mgt#1{$\count255=1 \loop\ifnum\count255<#1\advance\count255 by 1 + >\hspace*{-.4em}\repeat>$} +\gdef\mast#1{$\count255=0 \loop\ifnum\count255<#1\advance\count255 by 1 + \ast\repeat$} +\gdef\mblank#1{\count255=0 \loop\ifnum\count255<#1\advance\count255 by 1 + ~\repeat} +\gdef\n{\mbox{}\\}§ +{@#subsection}{Internal Macros} +{@#subsubsection}{Register Allocations} +{@#dm}{Allocations} +Now we go into medias res. First some register allocations: + +\begin{dsca} +\itx{poutbox} box for output +\itx{pstartbox} box for line begin (inserted \emph{after} a line break) +\itx{pendbox} box for line end (inserted \emph{before} a line break) +\itx{pcur} current position +\itx{pcurbr} indentation value for line break in comments +\itx{pcmtstart} start position of a multi-line comment +\itx{plena} current line length, depending on indentation and continuation +\itx{pdecr} decrement value for too long lines +\itx{pstarta} value of indentation at line begin +\itx{pstart} current value of indentation +\itx{ind} indentation unit (width for 1 ASCII position difference; standard is .5em) +\itx{pst} macro for inserting a `$\ast$' in continuation lines of C comments +\itx{ifpend} test if |\pendbox| should be shipped out at end of line. +\itx{ifpbrk} enable/disable automatic linebreak (not yet used) +\end{dsca} + +{@#bm}§\newbox\poutbox +\newbox\pstartbox +\newbox\pendbox +\newif\ifpend +\newif\ifpbrk +\newlength\pcur +\newlength\pcurbr +\newlength\pcmtstart +\newlength\plena +\newlength\plinenowidth +\newlength\ind +\newcount\pdecr +\newcount\pstarta +\newcount\pstart +\gdef\pst{$\ast$} +\pbrktrue +\ind.5em +\setbox\pstartbox=\hbox{} +\setbox\pendbox=\hbox{}§ + +{@#dm}{\init} +This macro (or |\initc|) must be used at the beginning of each line; it +initializes the position environment. + +{@#bm}§\gdef\init#1#2{% + \par\noindent\hbox to \plinenowidth{\hss {\rm\scriptsize #2}\hspace{1em}}% + \plena\textwidth \advance\plena -\plinenowidth + \pdecr0 + \pcurbr0pt + \setbox\pstartbox=\hbox{}% + \pstart#1\advance\pstart 1 \pstarta\pstart + \skip0\ind\multiply\skip0 by #1 \pcur\skip0 + \ifnum #1>0 \hspace*{\skip0}\fi% + \ifpend\advance\plena -\wd\pendbox\fi% +}§ +{@#dm}{\initc} +This macro is used instead of |\init| for continuation lines of multi-line +strings/comments to preserve the current indentation and |\pstartbox|. +Supplied parameters are: + +\begin{dsca} +\itm{Parameter \tt \#1:\hfill} amount of space to move left or right (relative to the last line) +\itm{Parameter \tt \#2:\hfill} mode flag +\itm{Parameter \tt \#3:\hfill} number of blanks before text start +\end{dsca} + +the mode flag has the following values: +\begin{dsca} +\itm{mode=0:} used for strings +\itm{mode=1:} not in use +\itm{mode=2:} not in use +\itm{mode=3:} not in use +\itm{mode=4:} used for C++ comments +\itm{mode=5:} used for C comments (with $\ast$ at line begin) +\itm{mode=6:} used for C comments (without $\ast$ at line begin) +\itm{mode=7:} not in use +\end{dsca} + +NOTE: Not all modes are currently in use or fully implemented in the +|tiny_c2l| converter. They may be used/modified in a later version (or change +the values or actions). + +{@#bm}§\gdef\initc#1#2#3#4{% + \par\noindent\pdecr0% + \hbox to \plinenowidth{\hss {\rm\scriptsize #4}\hspace{1em}}% + \ifcase#2 + \pcurbr\ind\multiply\pcurbr #1 \pcur\pcurbr \gdef\pst{}% 0 + \or% + \pcurbr\ind\multiply\pcurbr #1 \gdef\pst{$\ast$}% 1 + \or% + \pcurbr\ind\multiply\pcurbr #1 + \advance\pcurbr\pcmtstart \gdef\pst{}% 2 + \or% + \pcurbr\ind\multiply\pcurbr #1 + \advance\pcurbr\pcmtstart \gdef\pst{$\ast$}% 3 + \or% + \pcurbr\pcmtstart \setbox\poutbox=\hbox{/}% + \advance\pcurbr\wd\poutbox \gdef\pst{}% 4 + \or% + \pcurbr\pcmtstart \setbox\poutbox=\hbox{/}% + \advance\pcurbr\wd\poutbox \gdef\pst{$\ast$}% 5 + \or% + \pcurbr\pcmtstart \setbox\poutbox=\hbox{/$\ast$}% + \advance\pcurbr\wd\poutbox \gdef\pst{}% 6 + \or% + \pcurbr\pcmtstart \setbox\poutbox=\hbox{/$\ast$}% + \advance\pcurbr\wd\poutbox \gdef\pst{$\ast$}% 7 + \or% + \pcurbr\ind\multiply\pcurbr #1 \gdef\pst{}% 8 + \else% + \pcurbr0pt \gdef\pst{}% + \fi% + \setbox\pstartbox=\hbox{\pst\mblank{#3}}% + \hspace*{\pcurbr}\copy\pstartbox% + \pcur\pcurbr \advance\pcur\wd\pstartbox + \ifpend\advance\plena -\wd\pendbox \fi% + \ifnum#2=8 \pcurbr0pt\fi% +}§ + +{@#dm}{\plcntmargin} +This macro is used to set the margin width for line numbers. It is +invoked after a page is shipped out; so you should use a width that is +enough for the next 100 lines or so. + +{@#bm}§\gdef\plcntmargin#1{% + \setbox\poutbox=\hbox{#1\hspace{1em}}\global\plinenowidth\wd\poutbox +}§ +{@#dm}{line end macros} +These two macros enable (|\pee|) and disable (|\ped|) the insertion +of |\pendbox| at the end of a source line. The actual value is set using +the macro |\pes|. All three macros modify the value of |\plena| (the +current page width) to ensure correct line breaking. +{@#bm}§\gdef\pee{\advance\plena -\wd\pendbox\pendtrue} +\gdef\ped{\advance\plena \wd\pendbox\pendfalse} +\gdef\pes#1#2{% + \setbox\pendbox=\hbox{#1}% + \advance\plena -\wd\pendbox + \ifnum#2 > -1 \pstart#2\fi% + \pendtrue% +}§ + +{@#dm}{\psinit} +This macro is used to initialize |\pstartbox| and |\pstart|. +{@#bm}§\gdef\psinit#1#2{% + \ifnum#1>-1 \pstart#1\fi% + \ifnum#1=-2 \pstart\pstarta\fi% + \setbox\pstartbox=\hbox{#2}% +}§ + +{@#dm}{\cmtinit} +This macro is used to save the current indentation at start of a comment. +{@#bm}§\gdef\cmtinit{\pcurbr\pcur \pcmtstart\pcur}§ + +{@#dm}{\eol} +This macro is used at end of a line (for breaking overlong lines). +If the condition |\ifpend| is true, copy |\pendbox| to the end of the line, +then a line break is inserted. +{@#bm}§\gdef\eol{\ifpend\copy\pendbox\else\mbox{}\fi\\\hspace*{\plinenowidth}}§ + +{@#dm}{\calcindent} +This macro is used to calculate the indentation after a linebreak +{@#bm}§\gdef\calcindent{% + \ifdim\pcurbr>0pt\skip0\pcurbr +\else% + \skip0\ind \multiply\skip0\pstart +\fi +}§ + +{@#dm}{\brkln} +This macro is used to break the current line. +{@#bm}§\gdef\brkln{% + \ifpbrk% + \eol %insert line break + \calcindent% calculate the indentation for the new line + \pdecr\count255 \advance\pdecr-\pstart + \pcur\wd\poutbox \advance\pcur\skip0 + \hspace*{\skip0}\copy\pstartbox% + \advance\pcur\wd\pstartbox + \else% + \hspace*{\skip0}% + \fi% +}§ + +{@#dm}{\jmpo} +This macro is used to jump to the position specified in |#1| and print the +text from |#2|. If this position is smaller than the current position, +insert a small space ({@#min_blank}) and then print the text. If the output +would exceed the line length, break the line, preserving the current +indentation (in this case the starting point is the current indentation+1|\ind|). +{@#bm1}§\gdef\jmpo#1#2{% + \ifnum#1>0 + \count255 #1\advance\count255 -\pdecr + \skip0\ind \multiply\skip0\count255 %calculate the output position + \advance\skip0-\pcur %calculate the width of the needed space + \count255 #1 %current start position (needed for line break) + \fi%§{@use_char} + \ifdim\skip0<{@#min_blank} %(current position > target position) + \skip0 {@#min_blank}{@use_map1}{@#bm2}§% insert a small space + \fi% + \ifnum #1<1 \skip0 0pt \count255 -#1\fi% + %copy #2 to \poutbox and add the width of the box to \pcur + \setbox\poutbox=\hbox{#2}% +%%%% probieren: \advance\pcur\wd\poutbox \advance\pcur\skip0 +%%%% dann ohne \relax + \advance\pcur\skip0 \advance\pcur\wd\poutbox %calculate the new position + \relax% TeX seems to be tired at this point; give it some rest ;-))) + \ifdim\pcur>\plena %requested position > right margin; break line + \brkln% + \else% + \hspace*{\skip0}% + \fi% + \box\poutbox% +}§ + +{@#dm}{\xnjo} +This macro is used to output the text in |#3| at ``wish position'' in |#2|, +using |#1| blanks. The used space per blank is from {@#min_xblank} to +{@#max_xblank} (according to the current position). This macro does nearly +the same as |\njo|, but is intended only for multiple blanks; the cases for +|#2|$<$1 are left out. + +The used space interval is smallter than that used for |\njo|; this macro +is intended to be used in comments etc. + +{@#bm1}§\gdef\xnjo#1#2#3{% + \count255 #2 \advance\count255 -\pdecr + \skip0\ind \multiply\skip0\count255 + \advance\skip0-\pcur \divide\skip0 #1 + \count255 #2 %current start position (for line break)§{@use_char} + \ifdim\skip0<{@#min_xblank} \skip0 {@#min_xblank} \multiply\skip0 #1\fi% + \ifdim\skip0>{@#max_xblank} \skip0 {@#max_xblank} \multiply\skip0 #1\fi% + %copy #3 to \poutbox and add the width of the box to \pcur + \setbox\poutbox=\hbox{#3}%{@use_map1}{@#bm2}§ + \advance\pcur\wd\poutbox \advance\pcur\skip0 + \ifdim\pcur>\plena %requested position > right margin + \brkln% insert a line break + \else% + \hspace*{\skip0}% + \fi% + \box\poutbox% +}§ + +{@#dm}{\njo} +This macro is used to output the text specified in parameter~2 at the grid +position specified in parameter~1, without jumping to the position (used +for a single blank). The actual used space is from {@#min_blank} to +{@#max_blank}, according to the current position. If |#1|$\leq 0$, output +|#2| directly (without blank). If the output would exceed the line length, +break the line as in |\jmpo|. + +{@#bm1}§\gdef\njo#1#2{% + \ifnum#1<0 \count255 -#1 \skip0 0pt\fi% + \ifnum#1=0 \count255 0 \skip0 0pt\fi% + \ifnum#1>0% + \count255 #1 \advance\count255 -\pdecr + \skip0\ind \multiply\skip0\count255 + \advance\skip0-\pcur + \count255 #1 %current start position (for line break) + \fi%§{@use_char} + \ifdim\skip0<{@#min_blank} \skip0 {@#min_blank}\fi% + \ifdim\skip0>{@#max_blank} \skip0 {@#max_blank}\fi% + \ifnum#1<1 \skip0 0pt\fi%{@use_map1}{@#bm2}§ + %copy #2 to \poutbox and add the width of the box to \pcur + \setbox\poutbox=\hbox{#2}% + \advance\pcur\wd\poutbox \advance\pcur\skip0 + \ifdim\pcur>\plena %requested position > right margin + \brkln% insert a line break + \else% + \hspace*{\skip0}% + \fi% + \box\poutbox% +}§ + +{@#dm}{\mpout} +This macro is related to the \tex |\leaders|. It outputs the character +(or text) specified in |#3| from grid position |#1| to grid position |#2|. +|#4| can is used to specify additional kern (this is used for example for +$<$ and $>$). + +{@#bm}§\gdef\mpout#1#2#3#4{% + \ifnum#1>0 \skip0\ind\multiply\skip0 by #1\advance\skip0-\pcur \fi% + \ifdim\skip0<0pt \skip0 0pt\fi% don't move back! + \ifnum#1>0 \hspace*{\skip0}\advance\pcur\skip0\fi% + \setbox\poutbox=\hbox{#3}\skip0\wd\poutbox %width of one output character (#3) + \skip1\ind\multiply\skip1 by #2 \skip2\skip1 \advance\skip1-\pcur + \pcur\skip2 \advance\pcur\skip0 \skip2\skip1 %total width of line + \advance\skip0 #4 %add kern + \divide\skip1\skip0 \count255\skip1 \advance\count255 by 1% number of characters + \skip1\wd\poutbox \multiply\skip1 by \count255 \advance\skip2 -\skip1 + \ifdim\skip2<0pt \advance\count255 -1 \advance\skip2 \wd\poutbox \fi% + \divide\skip2\count255 + \copy\poutbox% + \loop% + \ifnum\count255>0\advance\count255 by -1 \hspace*{\skip2}\copy\poutbox% + \repeat% +} +%</package>§ +% \Finale +\endinput {@use_char} + +{@@i}{@use_char} +{@#copyright} +\def\batchfile{position.ins} +\input docstrip.tex +\keepsilent +\preamble +\endpreamble +\generateFile{position.sty}{f}{\from{position.dtx}{package}} diff --git a/support/tiny_c2l/lx2l-src/tiny_cvt2ltx.lx b/support/tiny_c2l/lx2l-src/tiny_cvt2ltx.lx new file mode 100644 index 0000000000..52676f4da6 --- /dev/null +++ b/support/tiny_c2l/lx2l-src/tiny_cvt2ltx.lx @@ -0,0 +1,1477 @@ +{@default_thread <c>} +{@@c}{@output_name <tiny_c2l.l>} +{@@i}{@output_name <tiny_i2l.l>} +{@@t}{@output_name <tiny_t2l.l>} +{@include <config.lx>} + +@@# C_CMT_NEU 1 NO +@@# LEX_RULES NO + +############################################################# +noch probieren: Umbruch bei Präprozessor-Strings + mehrzeilige Präprozessor-Sachen +############################################################# + +{@@@} +{@map1} +\n\{@@+} + +{@map1}\\\ +{@map1}"\" +{@map1}§\n +{@use_char} + +@#1 string txt +{@#.txt+1} + +@# name +{@@c}tiny_c2l +{@@i}tiny_i2l +{@@t}tiny_t2l + +@# latex_name +{@@c}tiny\_c2l +{@@i}tiny\_i2l +{@@t}tiny\_t2l + +@# sc +{@@ci}sc +{@@t}INITIAL + +@# sc1 +{@@ci}sc1 +{@@t}INITIAL + +@#2 subst pos1 pos2 +fprintf(yyout,"\\{@#.pos1}{@#.pos2}{\\%s ",{@#.pos2}font);{@@+} + substitute_format({@#.pos1}{@#.pos2}); + +@# blank_sc +{@@c}<INITIAL,CPLUSPLUS,JAVA,PREPROCESSOR,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT> +{@@i}<INITIAL,CMT,FILL_CMT> +{@@t}{@end@} + +{@@-} +{@@}First we have to generate some composite macros. These are currently +not yet supported in the {@calc } command; but they are needed for some +calculations. So they are generated as simple macros using a {@calc } +command with output written to macros. + +{@@@}{@calc [\date] "%d-%s-%d" // convert the german date to dd-mmm-yyyy +get_day("\datum"); switch(get_month("\datum")){ + case 1: "jan"; + case 2: "feb"; + 3: "Mar"; + 4: "Apr"; + 5: "May"; + 6: "Jun"; + 7: "JUL"; + 8: "Aug"; + 9: "Sep"; + 10: "Oct"; + 11: "Nov"; + 12: "Dec"; + default: ""; +}; get_year("\datum");} +{@calc [\beta] "%s" \minor_version%2==1 ? " (beta release)" : "";;} +{@calc [\version] "%s" "\major_version.\minor_version.\patch_level\beta"} +/*\v + % write table of contents (only in single file mode): + \ifmfiles\else\pagenumbering{roman} + \tableofcontents\newpage\pagenumbering{arabic}\fi + \centerline{\huge\bf File {@#latex_name}.l} +*/ + +/*\b + <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + <<<<<<<<<<<<<<<<<<<<<<<<<<<<***********************>>>>>>>>>>>>>>>>>>>>>>>> + <* filename : {@#name}.l *> + <* purpose : this is a little lex file as an example for a simple *> + <* : converter using the position macros. Only a few *> + <* : basic conversions are implemented; all fonts etc. are *> + <* : hard-coded. You may use this file as example for use *> + <* : of the position macros or as starting point for an own *> + <* : converter project. *> + <* : *> + <* cvt2ltx : This file is the tiny version of c2ltx; keywords, *> + <* equiv. : strings and comments are recognized. A very simple *> + <* : version of embedded LaTeX is implemented (only append *> + <* : mode and verbatim mode; everything is copied verbatim *> + <* : to the output file in both cases. *> + <* : *> + <* version : \version from \date \version_missing_blanks *> + <* author : Michael Plugge <m.plugge@fh-mannheim.de> *> + <<<<<<<<<<<<<<<<<<<<<<<<<<<<***********************>>>>>>>>>>>>>>>>>>>>>>>> + <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +*/ + +%{ + /*\v \section{Declaration Part} */ +#define VERSION "{@#version}" +#define VERSION_DATE "\date" + +#define TAB2SPC {@#tab2spc} +{@@@} +#define BASE_FONT "basefont" +#define BLOCK_FONT "blockfont" +#define KEYWORD_FONT "keywordfont" +#define STRING_FONT "stringfont" +#define COMMENT_FONT "commentfont" +#define HEADFONT "headfont" +#define FOOTFONT "footfont" +#define LHEAD "{@#lhead}" +#define CHEAD "{@#chead}" +#define RHEAD "{@#rhead}" +#define LFOOT "{@#lfoot}" +#define CFOOT "{@#cfoot}" +#define RFOOT "{@#rfoot}" +#define L2E_STYLE "{@#l2e_style}" +#define L209_STYLE "{@#l209_style}" +#define L2E_STYLE_LINE "{@#l2e_style_line}" +#define L209_STYLE_LINE "{@#l209_style_line}" + +{@@ci} + /*\f The following definition controls the behavior of linebreaks + * for comments: after this ASCII position, continuation lines use + * the current indentation */ +#define ALIGN_CMT_LIMIT 50 + +{@@@} +#define LEN(val) if((leng+=val)>70){leng=0; fprintf(yyout,"%%\n ");} +#if VMS +#undef ECHO +#define ECHO yyleng==1 ? fputc(*yytext,yyout) : fprintf(yyout,"%s",yytext) +#endif + +#include <string.h> +#include <time.h> + +char *ptr,*ptr1,*kern,*inputname,buffer[256],init=1,cmt_mode; +int pos,old_pos,brace_open,tmp,leng,tab2spc=TAB2SPC{@@ci},sc,sc1, + pes_old= -1,cmt_blanks{@@@},skip_cnt,cmt_pos,line=1,show_lines,use_header=1; +long year; +time_t time_val; +struct tm *atime; + +char *lhead=LHEAD,*chead=CHEAD,*rhead=RHEAD,*headfont=HEADFONT, + *lfoot=LFOOT,*cfoot=CFOOT,*rfoot=RFOOT,*footfont=FOOTFONT, + *latex_prolog1= +"%%%% This file was generated by {@#name} (version %s, %s){@#string}^§ +\ifx\getformat\undefined + \newcount\getformat\getformat0 +\else + \mfilestrue\getformat3 +\fi +\ifx\documentclass\undefined\advance\getformat1\fi§ +\ifcase\getformat +%s +\or +%s +\else\fi %% multiple file input: don't load format§%s^", + + *latex_prolog2="{@#string}^{@@c}\gdef\cmt#1#2{\psinit{#1}{\hphantom{/}$\ast$\mblank{#2}}\%s} +\gdef\cmtpp#1#2{\psinit{#1}{//\mblank{#2}}\%s} +\gdef\ccmtend{\setbox\pstartbox=\hbox{\hphantom{/}}} +{@@i}\gdef\cmt#1#2{\psinit{#1}{;\mblank{#2}}\%s} +{@@@}\ifmfiles\else\begin{document}\fi\begin{flushleft}§§^", + +*month[]={ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +}, +*local_month[]={ + "Januar", + "Februar", + "März", + "April", + "Mai", + "Juni", + "Juli", + "August", + "September", + "Oktober", + "November", + "Dezember" +}, +*month1[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}, +*local_month1[]={"Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"}, +*usage_text1=" Usage: {@#name}{@#string}^ [options] [infile [outfile]] [options] + infile and/or outfile may be omitted; in this case stdin/stdout are used. + valid options are: + -hn don't generate header or footer text + -hl<txt> header text: left side (default "^{@#lhead}{@#string}^") + -hc<txt> header text: center (default "^{@#chead}{@#string}^") + -hr<txt> header text: right side (default "^{@#rhead}{@#string}^") + -fl<txt> footer text: left side (default "^{@#lfoot}{@#string}^") + -fc<txt> footer text: center (default "^{@#cfoot}{@#string}^") + -fr<txt> footer text: right side (default "^{@#rfoot}{@#string}^") + possible escape sequences for the -h. and -f. switches are: + %f: input file name %m: month (numeric value) + %p: page number %n: (english) name of month (full form) + %t: time (HH:MM) %s: (english) name of month (short form) + %D: date (DD-MMM-YYYY) %N: (local) name of month (full form) + %h: hour %S: (local) name of month (short form) + %M: minute %y: year + %d: day of month %: the `%' character itself{@@c} + -l[cnt] output line numbers + -+ C++ mode + -j java mode{@@@} + -o outputname (if stdin is used for input) + -t<cnt> number of spaces per tab character (default: ^", +*usage_text2="{@#string}^) + -d debug (debug output is written to ^{@#name}{@#string}^.dbg) + -? show this help screen§^"; + +void keyword(void); +void skip_msg(void); +{@@ci}void chk_cmt(void); +{@@@}void print_jmpo(int linebegin); +void init_out(int mode); +int die(char *cmd,int mode); +void substitute_format(char *format); +char *subst(int c); +void current_line(void); +%} + +{@@c} + /* preprocessor keywords (without the leading #) */ +PP_KEY (define[ \t])|(undef[ \t])|(ifn?(def)?[ \t(])|{@@##} + (elif[ \t(])|(else[ \t\n])|(endif[ \t\n])|(error[ \t])|{@@##} + (line[ \t])|(pragma[ \t])|(include[ \t<\"]) +{@@@} +SP [ \t]+ +SPO [ \t]* +WS [ \t\n] +WSO [ \t\n]* +WSSEMI [ \t\n;] +WSBRSEMI [ \t\n(;] +WSBR [ \t\n(] +WSBR2 [ \t\n)] +WSBC [ \t\n{] +WSS [ \t\n*] +WSSB [ \t\n*)] +WSC [ \t\n:] +OPER [ \t\n+\-*/%|&^~!=<>\[(,] +CA [ \t\n<] +WSB2 [ \t\n\[(] +NEW_DEL [ \t\n\[(<] + +%x LINE_BEGIN OMIT +{@@c} +%x STRING C_CMT CPP_CMT FILL_CMT FILL_CPP_CMT +%x EL_CMT1 EL_CMT2 EL_CMT3 PREPROCESSOR +%s JAVA CPLUSPLUS{@@#LEX_RULES+} PATTERN PATTERN_STRING REG_EXPR{@@#LEX_RULES#} +{@@i} +%x STRING STRING1 CMT FILL_CMT EL_CMT1 EL_CMT2 EL_CMT3 +{@@@} + +%option 8bit noyywrap outfile="{@#name}.c"{@@#DEBUG+} debug{@@#DEBUG#} + +%% + /*\v \section{Rules section}\subsection{\LaTeX Prolog} */ + if(show_lines) + fprintf(yyout,latex_prolog1,VERSION,VERSION_DATE,L2E_STYLE_LINE, + L209_STYLE_LINE,use_header?"\\pagestyle{fancy}\n":""); + else + fprintf(yyout,latex_prolog1,VERSION,VERSION_DATE,L2E_STYLE, + L209_STYLE,use_header?"\\pagestyle{fancy}\n":""); +{@@&-USE_AFTERPAGE} + fprintf(yyout,"\\plcntmargin{777}\n"); +{@@&#USE_AFTERPAGE} + if(use_header){ + {@#subst}(l)(head) + {@#subst}(c)(head) + {@#subst}(r)(head) + {@#subst}(l)(foot) + {@#subst}(c)(foot) + {@#subst}(r)(foot) + } + if(!show_lines) + fprintf(yyout,"\\plinenowidth0pt\n"); + else + fprintf(yyout,"\\plcntmargin{77}\n"); + fprintf(yyout,latex_prolog2{@@ci},COMMENT_FONT,COMMENT_FONT{@@@}); + BEGIN(LINE_BEGIN); + + /*\v \subsection{Rules for Line Begin} */ +<LINE_BEGIN>{ + /* special cases: blank lines, Blanks at end of line */ + ^{SPO}\n { + fprintf(yyout,"\\init0"); + current_line(); + fprintf(yyout,"\\n{@@ci}\\ped{@@@}\n"); + pos=brace_open=0; + line++; + } + {SP}$ /* ignore spaces at end of line */ + + /* general line begin (we need the \init macro here) */ + ^" " pos++; fprintf(yyout,"\\init1"); current_line(); fprintf(yyout,"\\njo{-1}{"); brace_open=1; leng=16; BEGIN({@#sc}); + ^{SP} print_jmpo(1); BEGIN({@#sc}); + ^[^ \t\n] { + fprintf(yyout,"\\init0"); current_line(); fprintf(yyout,"\\njo0{"); + yyless(0); +{@@ci} + pes_old= -1; +{@@@} + brace_open=1; + leng=14; + cmt_pos=1; + BEGIN({@#sc}); + } + . yyless(0); cmt_pos=pos+1; BEGIN({@#sc1}); +} + + /*\v \subsection{Rules for Blanks and Tabs} */ +{@#blank_sc}{ + " " { + pos++; + if(brace_open)fputc('}',yyout); +{@@ci} + chk_cmt(); +{@@@} + fprintf(yyout,"\\njo{%d}{",pos); + brace_open=1; + LEN(10); + } + {SP} print_jmpo(0); +} + +{@@c} +{@@#C_CMT_NEU+} +<C_CMT>{ + \n{SPO}"*/" { + if(brace_open)fputc('}',yyout); + line++; + pos=leng=brace_open=cmt_mode=0; + fprintf(yyout,"\\n\n\\initc{0}{5}{0}"); + current_line(); + fprintf(yyout,"\\ccmtend\\%s",BASE_FONT); + leng=30; + init_out(0); + fprintf(yyout,"/}"); + brace_open=cmt_mode=0; + LEN(17+strlen(BASE_FONT)); + BEGIN(sc1); + } + \n{SPO}\*{SPO} { + if(brace_open)fputc('}',yyout); + line++; + for(ptr=yytext+yyleng-1,cmt_blanks=0;*ptr==' ';ptr--)cmt_blanks++; + pos=cmt_pos+cmt_blanks; + fprintf(yyout,"\\n\n\\initc{0}{5}{%d}",cmt_blanks); + current_line(); + leng=brace_open=0; + LEN(25); + } + \n{SPO}\*+\/? { + if(brace_open)fputc('}',yyout); + line++; + LEN(15); + for(ptr=yytext+yyleng-1,cmt_blanks=0;*ptr==' ';ptr--)cmt_blanks++; + pos=cmt_pos; + for(ptr=yytext,tmp=0;*ptr;)if(*ptr++=='*')tmp++; + if(*(yytext+yyleng-1)=='/'){ + fprintf(yyout,"\\ccmtend\\%s",BASE_FONT); + BEGIN(sc1); + } + fprintf(yyout,"\\n\n\\initc{0}{5}{0}"); + current_line(); + if(tmp>4){ + LEN(31); + fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}",cmt_pos,cmt_pos+tmp-2,"$\\ast$","2pt"); + if(*(yytext+yyleng-1)=='/')fprintf(yyout,"\\njo0{/}"); + } + else{ + fprintf(yyout,"\\njo0{\\mast{%d}/}",tmp); + if(*(yytext+yyleng-1)=='/')fputc('/',yyout); + LEN(10+strlen(BASE_FONT)+yyleng); + } + brace_open=0; + } + \n{SPO} { + if(brace_open)fputc('}',yyout); + line++; + leng=brace_open=0; + for(pos=0,ptr=yytext+1;*ptr;ptr++){ + if(*ptr=='\t') + pos+=tab2spc-pos%tab2spc; + else + pos++; + } + LEN(20); + fprintf(yyout,"\\n\n\\initc{%d}{0}{0}",pos); + current_line(); + } +} + +{@@@} +{@@c}<INITIAL,CPLUSPLUS,JAVA,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{@@@}\n { +{@@#C_CMT_NEU-} +{@@c}<INITIAL,CPLUSPLUS,JAVA,PREPROCESSOR,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{@@@}\n { +{@@#C_CMT_NEU#} + if(brace_open)fputc('}',yyout); + line++; + pos=leng=brace_open=0; + fprintf(yyout,"\\n{@@c}\\ped{@@@}\n"); +{@@c} + pes_old= -1; + if(YY_START==CPP_CMT || YY_START==FILL_CPP_CMT){ + sc=sc1; + fprintf(yyout,"\\%s ",BASE_FONT); + LEN(2+strlen(BASE_FONT)); + } + else + sc=YY_START; +{@@@} + BEGIN(LINE_BEGIN); + } + +{@@c}<INITIAL,CPLUSPLUS,JAVA,STRING,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{@@@}{ + {SP}$ /* ignore spaces at end of line */ + + /*\v \subsection{Rules for special characters} */ + \<{2,9} init_out(0); fprintf(yyout,"\\mlt{%d}",yyleng); LEN(7); + \>{2,9} init_out(0); fprintf(yyout,"\\mgt{%d}",yyleng); LEN(7); + \\{2,} init_out(0); fprintf(yyout,"\\bs{%d}",yyleng); LEN(6); + \*{2,9} init_out(0); fprintf(yyout,"\\mast{%d}",yyleng); LEN(8); + + /*\v \subsection{``Leader'' rules} */ + \<{10,} | + \>{10,} | + \+{10,} | + \${10,} | + \#{10,} | + \%{10,} | + \~{10,} | + \*{10,} { + switch(*yytext){ + case '<': kern="-2pt"; ptr="$<$"; break; + case '>': kern="-2pt"; ptr="$>$"; break; + case '+': kern="0pt"; ptr="+"; break; + case '$': kern="0pt"; ptr="\\$"; break; + case '#': kern="0pt"; ptr="\\#"; break; + case '%': kern="0pt"; ptr="\\%"; break; + case '~': kern="0pt"; ptr="$\\sim$"; break; + case '*': kern="2pt"; ptr="$\\ast$"; break; + default: kern="0pt"; ptr=""; break; + } + if(brace_open)fputc('}',yyout); + fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}",pos,pos+yyleng-1,ptr,kern); + pos+=yyleng; + brace_open=0; + LEN(strlen(kern)+strlen(ptr)+19); + } +} + +{@@c} +{@@#LEX_RULES+} + /*\v \subsection{Rules for LEX mode} */ +<PATTERN>{ + \\*[["] { + init_out(0); + tmp= *(yytext+yyleng-1); + if(yyleng>1)fprintf(yyout,"\\bs{%d}",yyleng-1); + if(yyleng%2){ + brace_open=0; + if(tmp=='['){ + fprintf(yyout,"{]}}\\%s",PATTERN_FONT); + BEGIN(REG_EXPR); + } + else{ + fprintf(yyout,"``}\\%s",STRING_FONT); + BEGIN(PATTERN_STRING); + } + } + else{ + if(tmp=='[') + fprintf(yyout,"{]}"); + else + fprintf(yyout,"{\\tt \"}"); + } + } +} +<REG_EXPR,PATTERN_STRING>{ + " " fprintf(yyout,"{\\spy}"); +} + +<REG_EXPR>{ + +} +<PATTERN_STRING>{ + +} + +{@@#LEX_RULES#} + /*\v \subsection{Rules for Preprocessor Keywords} */ + /* (first handle just the leading #) */ +\#{SPO}{PP_KEY} { + yyless(1); + init_out(0); + fprintf(yyout,"{\\%s \\#}}\\pes{ \\bs{1}}{%d}",KEYWORD_FONT,pos+2); + pes_old=pos+2; + brace_open=0; + LEN(18+strlen(KEYWORD_FONT)); + BEGIN(PREPROCESSOR); + } + +<PREPROCESSOR>.|\n yyless(0); BEGIN({@#sc1}); /* this should not occur */ +<PREPROCESSOR>{PP_KEY} yyless(yyleng-1); keyword(); + + /*\v \subsection{Rules for common C/C++/Java Keywords} */ +break[ \t\n;] | +case[ \t\n(] | +char[ \t\n*)] | +continue[ \t\n;] | +default[ \t\n:] | +do[ \t\n{] | +double[ \t\n*)] | +else[ \t\n{] | +float[ \t\n*)] | +for[ \t\n(] | +goto{WS} | +if[ \t\n(] | +int[ \t\n*)] | +long[ \t\n*)] | +return[ \t\n(;] | +short[ \t\n*)] | +static[ \t\n*)] | +switch[ \t\n(] | +void[ \t\n)] | +volatile{WS} | +while[ \t\n(] yyless(yyleng-1); keyword(); + + /*\v \subsection{Rules for C/C++ only Keywords} */ +<INITIAL,CPLUSPLUS>{ + auto{WS} | + const{WS} | + defined[ \t\n(] | + enum{WS} | + extern{WS} | + register{WS} | + sizeof[ \t\n(] | + struct[ \t\n{] | + typedef{WS} | + union[ \t\n{] yyless(yyleng-1); keyword(); + + /*\v \subsection{Rules for special VMS Keywords} */ + _align[ \t\n(] | + globaldef[ \t\n{] | + globalref[ \t\n{] | + globalvalue[ \t\n{] | + main_program[ \t\n{] | + MAIN_PROGRAM[ \t\n{] | + noshare[ \t\n{] | + readonly[ \t\n{] | + variant_struct[ \t\n{] | + variant_union[ \t\n{] yyless(yyleng-1); keyword(); +} + + /*\v \subsection{Rules for C++ Keywords} */ +<CPLUSPLUS>{ + and[ \t\n(] | + and_eq[ \t\n(] | + asm[ \t\n{] | + bitand[ \t\n(] | + bitor[ \t\n(] | + bool{WS} | + compl{WS} | + const_cast[ \t\n<] | + dynamic_cast[ \t\n<] | + explicit{WS} | + export{WS} | + friend{WS} | + inline[ \t\n{] | + mutable[ \t\n*)] | + namespace[ \t\n{] | + not[ \t\n(] | + not_eq[ \t\n(] | + or[ \t\n(] | + or_eq[ \t\n(] | + reinterpret_cast[ \t\n<] | + static_cast[ \t\n<] | + template[ \t\n:] | + typeid[ \t\n(] | + typename[ \t\n(] | + using{WS} | + virtual{WS} | + wchar_t[ \t\n*)] | + xor[ \t\n(] | + xor_eq[ \t\n(] yyless(yyleng-1); keyword(); +} + + + /*\v \subsection{Rules for Java only Keywords} */ +<JAVA>{ + abstract{WS} | + boolean{WS} | + byte{WS} | + byvalue{WS} | + extends{WS} | + final{WS} | + finally[ \t\n{] | + implements{WS} | + import{WS} | + inner{WS} | + instanceof{WS} | + interface{WS} | + native{WS} | + null[ \t\n)] | + package{WS} | + super[ \t\n(] | + synchronized{WS} | + throws{WS} | + transient{WS} keyword(); +} + + /*\v \subsection{Rules for C++/Java Keywords} */ +<CPLUSPLUS,JAVA>{ + catch[ \t\n(] | + class{WS} | + const[ \t\n*] | + delete[ \t\n\[(<] | + false[ \t\n;] | + new[ \t\n\[(<] | + operator[ \t\n+\-*/%|&^~!=<>\[(,] | + private[ \t\n:] | + protected[ \t\n:] | + public[ \t\n:] | + this[ \t\n\-.*] | + throw[ \t\n(] | + true[ \t\n;] | + try[ \t\n{] yyless(yyleng-1); keyword(); +} + + /*\v \subsection{Rules for Strings} */ +\"\" init_out(0); fprintf(yyout,"{\\tt \"\"}"); LEN(8); +\\*\" { + if(yyleng%2){ /* even number of `\': begin string */ + init_out(0); + if(yyleng>1) + fprintf(yyout,"\\bs{%d}\\qql}\\%s\\pes{\\bs{1}}{0}",yyleng-1,STRING_FONT); + else + fprintf(yyout,"\\qql}\\%s\\pes{\\bs{1}}{0}",STRING_FONT); + LEN(21+strlen(STRING_FONT)); + brace_open=0; + BEGIN(STRING); + } + else{ /* odd number of `\': no string */ + init_out(0); + fprintf(yyout,"\\bs{%d}{\\tt \"}",yyleng-1); + LEN(14); + } + } + +<STRING>{ + \n { + if(brace_open)fputc('}',yyout); + line++; + pos=leng=brace_open=0; + fprintf(yyout,"\\n\n\\initc000"); + current_line(); + LEN(20); + } + + " "+ init_out(0); for(tmp=0;tmp<yyleng;tmp++)fputc('~',yyout); fputc('}',yyout); brace_open=0; LEN(yyleng+1); + \t print_jmpo(0); + \\+n init_out(0); fprintf(yyout,"\\bs{%d}n}",yyleng-1); LEN(9); brace_open=0; + \\*\" { + if(yyleng%2){ /* even number of `\': end string */ + init_out(0); + if(yyleng>1) + fprintf(yyout,"\\bs{%d}\\%s \\qqr}\\%s",yyleng-1,BASE_FONT,BASE_FONT); + else + fprintf(yyout,"\\%s \\qqr}\\%s",BASE_FONT,BASE_FONT); + if(pes_old>=0) + fprintf(yyout,"\\pes{ \\bs{1}}{%d}\\njo0{",pes_old); + else + fprintf(yyout,"\\ped\\pstart\\pstarta\\njo0{"); + LEN(36+strlen(BASE_FONT)); + BEGIN(sc1); + } + else{ /* odd number of `\': no string */ + init_out(0); + fprintf(yyout,"\\bs{%d}{\\tt \"}",yyleng-1); + LEN(14); + } + } +} + + /*\v \subsection{Rules for Comments} */ +"/*\\f"[ ]* { + if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2; + init_out(1); + cmt_mode=3; + old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng; + fprintf(yyout,"/$\\ast$\\%s",COMMENT_FONT); + cmt_blanks=0; + if(*(yytext+yyleng-1)==' ') + for(ptr=yytext;*ptr;)if(*ptr++==' '){ + fputc('~',yyout); + cmt_blanks++; + } + LEN(13+strlen(COMMENT_FONT)); + BEGIN(FILL_CMT); + } +"/*"(\\b)?[ ]* { + if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2; + init_out(1); + if(*(yytext+3)!='b'){ /* no block comment */ + cmt_mode=1; + old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng; + } + else + cmt_mode=2; + cmt_blanks=0; + fprintf(yyout,"/$\\ast$"); + if(*(yytext+yyleng-1)==' '){ + if(cmt_mode==1){ + fprintf(yyout,"\\%s",COMMENT_FONT); + LEN(13+strlen(COMMENT_FONT)); + } + else{ + fprintf(yyout,"\\%s",BLOCK_FONT); + LEN(13+strlen(BLOCK_FONT)); + } + for(ptr=yytext;*ptr;)if(*ptr++==' '){ + fputc('~',yyout); + cmt_blanks++; + } + } + BEGIN(C_CMT); + } +\/\*+\/ | +\/\*{2,}(\\b)? { + if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2; + init_out(1); + if(*(yytext+yyleng-1)!='b'){ /* no block comment */ + cmt_mode=1; + old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng; + } + else + cmt_mode=2; /* block comment */ + cmt_blanks=0; + if(yyleng==2 || yyleng==4 && *(yytext+3)=='b') + fprintf(yyout,"/$\\ast$"); + else if(*(yytext+2)=='*' && yyleng<11){ + for(ptr=yytext+1,tmp=0;*ptr++=='*';tmp++); + fprintf(yyout,"/\\mast{%d}}",tmp); + brace_open=0; + } + else{ + fprintf(yyout,"/}"); + brace_open=0; + if(cmt_mode==1) + tmp=pos; + else + tmp=pos-2; + fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}", + tmp-yyleng+1,tmp-1,"$\\ast$","2pt"); + } + LEN(15); + if(*(yytext+yyleng-1)=='/'){ + yyless(yyleng-1); + cmt_mode=0; + } + else + BEGIN(C_CMT); + } +<CPLUSPLUS,JAVA>{ + "//\\f"[ ]* | + \/{2,}[ ]* { + init_out(2); + if(*(yytext+3)=='f') + BEGIN(FILL_CPP_CMT); + else + BEGIN(CPP_CMT); + fprintf(yyout,"//"); + for(ptr=yytext,cmt_blanks=0;*ptr;)if(*ptr++==' '){ + fputc('~',yyout); + cmt_blanks++; + } + old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng; + fprintf(yyout,"}\\cmtpp{%d}{%d}",old_pos,cmt_blanks); + brace_open=0; + } +} + +<C_CMT>\*+\/ { + if(brace_open)fputc('}',yyout); + brace_open=cmt_mode=0; + fprintf(yyout,"\\ccmtend\\%s",BASE_FONT); + pos+=yyleng; + if(yyleng>5){ + LEN(31); + fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}\\njo0{/}", + pos-yyleng,pos-2,"$\\ast$","2pt"); + } + else{ + fprintf(yyout,"\\njo0{\\mast{%d}/}",yyleng-1); + LEN(10+strlen(BASE_FONT)+yyleng); + } + BEGIN(sc1); + } + +<C_CMT,FILL_CMT>{ + " :" { + yyless(1); + if(cmt_mode==2 || cmt_mode==5) + print_jmpo(0); + else{ + pos++; + if(brace_open)fputc('}',yyout); + chk_cmt(); + fprintf(yyout,"\\njo{%d}{",pos); + brace_open=1; + LEN(10); + } + } + [ ][^ \t\n]\n { + yyless(1); + if(brace_open)fputc('}',yyout); + chk_cmt(); + if(cmt_mode==2 || cmt_mode==5){ + fprintf(yyout,"\\jmpo{%d}{",++pos); + LEN(10); + } + else{ + fprintf(yyout,"\\njo{%d}{",++pos); + LEN(9); + } + brace_open=1; + } +} + +<FILL_CMT>{ /* special rules for / *\f (fill comments for C) */ + "*/" | + \n{SPO}\*\/ { + if(brace_open)fputc('}',yyout); + for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++; + chk_cmt(); + brace_open=cmt_mode=0; + fprintf(yyout,"\\ccmtend\\%s",BASE_FONT); + pos+=yyleng; + fprintf(yyout,"\\jmpo{%d}{$\\ast$/}",pos+=100); /* force line break */ + LEN(20); + BEGIN(sc1); + } + {SPO}\n{SPO} | + \n{SPO}\*{SPO} { + if(brace_open)fputc('}',yyout); + line++; + chk_cmt(); + fprintf(yyout,"\\njo{%d}{",++pos); /* replace pattern by a blank */ + LEN(9); + brace_open=1; + } + (\n{SPO}\*{SPO}){2,} { + if(brace_open)fputc('}',yyout); + for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++; + fprintf(yyout,"\\jmpo{%d}{}\\jmpo{%d}{",pos+100,pos+200); /* empty line with star */ + pos+=200; + LEN(23); + brace_open=1; + } + (\n{SPO}){2,}(\*{SPO})? | + \n{SPO}@\n{SPO} | + \n{SPO}\*{SPO}@\n{SPO}\*{SPO} { + if(brace_open)fputc('}',yyout); + for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++; + fprintf(yyout,"\\n\\jmpo{%d}{",pos+=100); /* empty line */ + LEN(12); + brace_open=1; + } + {SP}@\n{SPO} | + {SP}@\n{SPO}\*{SPO} { + if(brace_open)fputc('}',yyout); + line++; + chk_cmt(); + fprintf(yyout,"\\jmpo{%d}{",pos+=100); /* force linebreak */ + LEN(9); + brace_open=1; + } +} + +<FILL_CPP_CMT>{ /* special rules for //\f (fill comments for C++/Java ) */ + \n{SPO}"//"{SPO} { + if(brace_open)fputc('}',yyout); + line++; + chk_cmt(); + fprintf(yyout,"\\njo{%d}{",++pos); /* replace pattern by a blank */ + LEN(9); + brace_open=1; + } + \n{SPO}"//"{SPO}@?\n{SPO}"//"{SPO} { + if(brace_open)fputc('}',yyout); + for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++; + fprintf(yyout,"\\jmpo{%d}{}\\jmpo{%d}{",pos+100,pos+200); /* empty line */ + pos+=200; + LEN(23); + brace_open=1; + } + {SP}@\n{SPO}"//"{SPO} { + if(brace_open)fputc('}',yyout); + line++; + chk_cmt(); + fprintf(yyout,"\\jmpo{%d}{",pos+=100); /* force linebreak */ + LEN(9); + brace_open=1; + } +} + +<C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT,STRING>[`'] init_out(0); fprintf(yyout,"{%c}",*yytext); + + /*\v \subsection{Rules for line breaking without spaces} */ +\-{2,} { /* don't split ++ -- */ + init_out(0); + fputc('{',yyout); + for(tmp=0;tmp<yyleng;tmp++)fprintf(yyout,"\\mm"); + fputc('}',yyout); + LEN(yyleng*3+2); + } +\+{2,} init_out(0); ECHO; LEN(yyleng); + +"<<=" | +">>=" { + /* allow a linebreak before these patterns */ + if(brace_open)fputc('}',yyout); + fprintf(yyout,"\\njo0{"); + if(*ptr=='<') + fprintf(yyout,"\\mlt{2}="); + else + fprintf(yyout,"\\mgt{2}="); + brace_open=1; + LEN(8); + } + +"||" | +"&&" | +"+=" | +"-=" | +"*=" | +"/=" | +"&=" | +"|=" | +"%=" | +"<=" | +">=" | +"==" | +"!=" | +[+\-*/%={] { + /* allow a linebreak before these patterns */ + if(brace_open)fputc('}',yyout); + brace_open=0; + init_out(0); + for(ptr=yytext;*ptr;ptr++)fprintf(yyout,"%s",subst(*ptr)); + LEN(9); + } +[,;}] init_out(0); fprintf(yyout,"%s}",subst(*yytext)); brace_open=0; + [a-zA-Z0-9$_]+ { /* C identifier: print them out */ + init_out(0); + for(ptr=yytext;*ptr;ptr++)switch(*ptr){ + case '_': + case '$': fprintf(yyout,"%s",subst(*ptr)); break; + default: fputc(*ptr,yyout); break; + } + LEN(yyleng); + } +{@@@} + +{@@c}<INITIAL,CPLUSPLUS,JAVA>\'.\' { + init_out(0); + fprintf(yyout,"{\\sq}%s{\\sq}",subst(*(yytext+1))); + } + +<INITIAL,CPLUSPLUS,JAVA,STRING,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{@@@}{ + . { + init_out(0); + fprintf(yyout,"%s",subst(*yytext)); + } + \f\n? fprintf(yyout,"\\newpage\n"); if(*(yytext+yyleng-1)=='\n')line++; + [a-zA-Z0-9]+ init_out(0); fprintf(yyout,"%s",yytext); +} + + /*\v \subsection{Rules for omitting Code} */ +<LINE_BEGIN>{ + {SPO}"/*"\\o[q+]"*/"{SPO}\n { + for(ptr=yytext;*ptr++!='o';); + if(*ptr=='+') + skip_cnt=0; + else + skip_cnt= -1; + tmp= -1; +{@@c} + sc=YY_START; +{@@@} + BEGIN(OMIT); + line++; + } + {SPO}"/*"\\o[1-9]+q?"*/"{SPO}\n { + for(ptr=yytext;*ptr++!='o';); + tmp=atoi(ptr); + skip_cnt= -1; + for(;*ptr && *ptr!='q';ptr++)if(*ptr=='*')skip_cnt=0; + BEGIN(OMIT); + line++; + } +} + +<OMIT>{ + {SPO}"/*\\o-*/"{SPO}\n { +{@@c} + if(sc==C_CMT)chk_cmt(); + if(sc==STRING)fprintf(yyout,"\\%s",STRING_FONT); +{@@@} + skip_msg(); + brace_open=0; + BEGIN(LINE_BEGIN); + line++; + } +{@@c} + \/\*+(\\b)? sc=C_CMT; if(*(yytext+yyleng-1)=='b')cmt_mode=2; else cmt_mode=1; + \*+\/ sc=sc1; cmt_mode=0; + \\*\" { + if(yyleng%2 && sc!=C_CMT) + if(sc!=STRING) + sc=STRING; /* begin of string */ + else + sc=sc1; /* end of string */ + } +{@@@} + \*+ + \/+ + \\ + [^\\\"*\/\n]+ /* skip */ + \n { + if(skip_cnt>=0)skip_cnt++; + line++; + if(!--tmp){ +{@@c} + if(sc==C_CMT)chk_cmt(); +{@@@} + skip_msg(); + brace_open=0; + BEGIN(LINE_BEGIN); + } + } + <<EOF>> skip_msg(); yyterminate(); +} + +{@@c} + /*\v \subsection{Rules for Embedded \LaTeX} */ +<CPLUSPLUS>"//\\a " init_out(0); fprintf(yyout,"}// "); brace_open=0; BEGIN(EL_CMT3); +<EL_CMT3>\n yyless(0); BEGIN(CPLUSPLUS); +<INITIAL,CPLUSPLUS,LINE_BEGIN>{ + "/*\\a" init_out(0); fprintf(yyout,"}\\ped{}/$\\ast$"); brace_open=0; BEGIN(EL_CMT1); + {SPO}"/*\\v" | + {WSO}"/*\\v1" { + for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++; + if(brace_open)fputc('}',yyout); + brace_open=0; + fprintf(yyout,"\\ped{}\n"); + BEGIN(EL_CMT2); + } +} + +<EL_CMT1,EL_CMT2>{ + \n ECHO; line++; + "*/"{SPO}\n? { + if(YY_START==EL_CMT1)fprintf(yyout,"$\\ast$/"); + if(*(yytext+yyleng-1)=='\n'){ + pos=leng=brace_open=0; + sc=sc1; + line++; + fputc('\n',yyout); + BEGIN(LINE_BEGIN); + } + else{ + BEGIN(sc1); + LEN(7); + } + } +} +<EL_CMT1,EL_CMT2,EL_CMT3>[^ \t\n*]+ ECHO; +{@@@} +%% + +{@@c} + /*\v \section{C Code section}\subsection{Function chk\_cmt(void)} */ +void chk_cmt(void) +{ + /* values for cmt_mode: + * cmt_mode==1: normal comment mode (first line) + * cmt_mode==2: block comment mode + * cmt_mode==3: fill mode (Started with / *\f) + * cmt_mode==4: normal comment mode (not in the first line) + * cmt_mode==5: block comment mode (continuation) + */ + if(cmt_mode==1 || cmt_mode==3){ + fprintf(yyout,"\\cmt{%d}{%d}",old_pos,cmt_blanks); + cmt_mode=0; + } + else if(cmt_mode==2){ + fprintf(yyout,"\\%s ",BLOCK_FONT); + LEN(2+strlen(BLOCK_FONT)); + cmt_mode=5; + } +} + +{@@@} + /*\v \subsection{Function skip\_msg(void)} */ +void skip_msg(void) +{ + if(skip_cnt==1) + fprintf(yyout,"\\par\\centerline{/\\mast{20}{ \\commentfont SKIP A LINE }\\mast{20}/}\\par\n"); + else if(skip_cnt>1) + fprintf(yyout,"\\par\\centerline{/\\mast{20}{ \\commentfont SKIP %d LINES }\\mast{20}/}\\par\n",skip_cnt); +} + +{@@c} + /*\v \subsection{Function keyword(void)} */ +void keyword(void) +{ + init_out(0); + fprintf(yyout,"{\\%s ",KEYWORD_FONT); + for(ptr=yytext;*ptr;)fprintf(yyout,"%s",subst(*ptr++)); + fputc('}',yyout); + LEN(3+strlen(KEYWORD_FONT)+yyleng); + yy_set_bol(0); + if(YY_START==PREPROCESSOR)BEGIN(sc1); +} + +{@@@} + /*\v \subsection{Function init\_out(void)} */ +void init_out(int mode) +{ + /* mode==0: kein \cmtinit + * mode==1: \cmtinit für C-Kommentar + * mode==2: \cmtinit für C++-Kommentar + */ + pos+=yyleng; + if(mode==0){ + if(!brace_open){ +{@@c} + chk_cmt(); +{@@@} + fprintf(yyout,"\\njo0{"); + leng+=7; + } + } +{@@c} + else{ + if(brace_open)fputc('}',yyout); + if(pos-yyleng>ALIGN_CMT_LIMIT){ /* position is too far right; omit \cmtinit */ + fprintf(yyout,"\\njo0{"); + leng+=7; + } + else{ + fprintf(yyout,"\\cmtinit\\njo0{"); + leng+=15; + } + } +{@@@} + brace_open=1; +} + + /*\v \subsection{Function print\_jmpo(int linebegin)} */ +void print_jmpo(int linebegin) +{ + int old=pos; + for(ptr=yytext;*ptr==' ' || *ptr=='\t';ptr++){ + if(*ptr=='\t') + pos+=tab2spc-pos%tab2spc; + else + pos++; + } + if(linebegin){ + fprintf(yyout,"\\init{%d}",pos); + current_line(); + fprintf(yyout,"\\njo{%d}{",-pos); + leng=18; + } + else if(brace_open){ + fputc('}',yyout); +{@@c} + chk_cmt(); + if(YY_START==FILL_CMT || YY_START==FILL_CPP_CMT){ + fprintf(yyout,"\\xnjo{%d}{%d}{",pos-old,pos); + LEN(13); + } + else{ +{@@@} + fprintf(yyout,"\\jmpo{%d}{",pos); + LEN(10); +{@@c} + } +{@@@} + } + else{ +{@@c} + chk_cmt(); + if(YY_START==FILL_CMT || YY_START==FILL_CPP_CMT){ + fprintf(yyout,"\\xnjo{%d}{%d}{",pos-old,pos); + LEN(13); + } + else{ +{@@@} + fprintf(yyout,"\\jmpo{%d}{",pos); + LEN(10); +{@@c} + } +{@@@} + } + brace_open=1; +} + + /*\v \subsection{Function die(char *cmd,int mode)} */ +int die(char *cmd,int mode) +{ + switch(mode){ + case 1: + fprintf(stderr,"Can't open %s for read; exit\n",cmd); + exit(4); + case 2: + fprintf(stderr,"Can't open %s for write; exit\n",cmd); + exit(4); + case 3: + fprintf(stderr,"%s\n",cmd); + exit(4); + default: + return 0; + } +} + + /*\v \subsection{Function subst(int c)} */ +char *subst(int c) +{ + static char retbuffer[2]; + + if(c<0)c+=256; + switch(c){ + case '#': leng+=2; return "\\#"; + case '$': leng+=2; return "\\$"; + case '%': leng+=2; return "\\%"; + case '&': leng+=2; return "\\&"; + case '\'': leng+=3; return "\\sq{}"; + case '*': leng+=6; return "$\\ast$"; + case '-': leng+=5; return "{\\mm}"; + case '<': leng+=3; return "$<$"; + case '>': leng+=3; return "$>$"; + case '[': leng+=3; return "{[}"; + case '\\': leng+=4; return "\\bs{1}"; + case ']': leng+=3; return "{]}"; + case '^': leng+=9; return "$\\hat{~}$"; + case '_': leng+=5; return "{\\ul}"; + case '`': leng+=3; return "{`}"; + case '{': leng+=6; return "\\brl{}"; + case '|': leng+=6; return "$\\mid$"; + case '}': leng+=6; return "\\brr{}"; + case '~': leng+=6; return "$\\sim$"; + case '"': leng+=7; return "{\\tt \"}"; + default: leng++; *retbuffer=c; return retbuffer; + } +} + + /*\v \subsection{Function substitute\_format(char *format)} */ +void substitute_format(char *format) +{ + char c,*ptr1; + + for(ptr=format;*ptr;ptr++){ + if(*ptr=='%'){ /* escape sequences: */ + switch(*++ptr){ + case 'd': /* %d: day of month */ + fprintf(yyout,"%d",atime->tm_mday); + break; + case 'D': /* %D: date (format DD-MMM-YYYY) */ + fprintf(yyout,"%d{\\mm}%s{\\mm}%ld",atime->tm_mday,month1[atime->tm_mon],year); + break; + case 'f': /* %f: input file name */ + for(ptr1=inputname;*ptr1;)fprintf(yyout,"%s",subst(*ptr1++)); + break; + case 'h': + fprintf(yyout,"%02d",atime->tm_hour); + break; + case 'm': /* %m: month (numeric value) */ + fprintf(yyout,"%d",atime->tm_mon+1); + break; + case 'M': /* %M: minute */ + fprintf(yyout,"%02d",atime->tm_min); + break; + case 'n': /* %n: (english) name of month (full form) */ + fprintf(yyout,"%s",month[atime->tm_mon]); + break; + case 'N': /* %N: (local) name of month (full form) */ + fprintf(yyout,"%s",local_month[atime->tm_mon]); + break; + case 's': /* %s: (english) name of month (short form) */ + fprintf(yyout,"%s",month1[atime->tm_mon]); + break; + case 'S': /* %S: (local) name of month (short form) */ + fprintf(yyout,"%s",local_month1[atime->tm_mon]); + break; + case 'p': /* %p: page (in the LaTeX file) */ + fprintf(yyout,"\\thepage"); + break; + case 't': /* %t: time (format HH:MM) */ + fprintf(yyout,"%02d:%02d",atime->tm_hour,atime->tm_min); + break; + case 'y': /* %y: year */ + fprintf(yyout,"%ld",year); + break; + case '%': /* %%: the `%' character itself */ + fputc('\\',yyout); + fputc('%',yyout); + break; + default: /* unknown escape sequence: just print it out */ + fprintf(stderr,"Unknown escape sequence `%%%c' detected; print it out.\n",*ptr); + fprintf(stderr,"(format string was >%s<)\n",format); + fputc('%',yyout); + fprintf(yyout,"%s",subst(*ptr)); + break; + } + } + else + fprintf(yyout,"%s",subst(*ptr)); + } + fprintf(yyout,"}\n"); +} + + /*\v \subsection{Function current\_line(void)} */ +void current_line(void) +{ + if(show_lines>0 && line%show_lines==0){ + fprintf(yyout,"{%d}",line); +{@if USE_AFTERPAGE} + if((line+50)%100==0)fprintf(yyout,"\\afterpage{\\plcntmargin{%d}}\n",line+50); +{@endif} + } + else + fprintf(yyout,"{}"); + LEN(10); +} + + /*\v \subsection{Function main(int argc, char **argv)} */ +int main(int argc, char **argv) +{ + int i; + +#ifdef FLEX_DEBUG + yy_flex_debug=0; +#endif /* FLEX_DEBUG */ + time(&time_val); + atime=localtime(&time_val); + year=time_val/(365L*24L*60L*60L)+1970L; +{@@c} + sc=sc1=INITIAL; +{@@@} + for(i=1;i<argc;i++){ + if(*argv[i]=='-'){ + for(ptr=argv[i]+1;*ptr;)switch(*ptr++){ + case 'd': +#ifdef FLEX_DEBUG + yy_flex_debug=1; +#else + fprintf(stderr,"{@#name} was compiled without debug info; ignore switch -d\n"); +#endif + break; +{@@c} + case '+': + sc=sc1=CPLUSPLUS; + break; + case 'j': + sc=sc1=JAVA; + break; +{@@@} + case 'h': + switch(*ptr++){ + case 'n': use_header=0; break; /* no header */ + case 'l': lhead=ptr; break; /* left header text */ + case 'c': chead=ptr; break; /* center header text */ + case 'r': rhead=ptr; break; /* right header text */ + default: break; + } + while(*ptr)ptr++; /* forget the rest of the argument */ + break; + case 'l': + if(*ptr) + show_lines=atoi(ptr); + else + show_lines=5; + while(*ptr)ptr++; /* forget the rest of the argument */ + break; + case 'f': + switch(*ptr++){ + case 'l': lfoot=ptr; break; /* left footer text */ + case 'c': cfoot=ptr; break; /* center footer text */ + case 'r': rfoot=ptr; break; /* right footer text */ + default: break; + } + while(*ptr)ptr++; /* forget the rest of the argument */ + break; + case 'o': /* output name */ + if(!yyout)(yyout=fopen(ptr,"w")) || die(ptr,2); + break; + case 't': + tab2spc=atoi(ptr); + break; + case '?': + fprintf(stderr,"{@#name} Version %s (%s)\n%s%d%s", + VERSION,VERSION_DATE,usage_text1,TAB2SPC,usage_text2); +#if VMS + exit(1); +#else + exit(0); +#endif + default: + break; + } + } + else if(!yyin) /* argument without leading '-': input or output name */ + (yyin=fopen(inputname=argv[i],"r")) || die(inputname,1); + else if(!yyout) + (yyout=fopen(argv[i],"w")) || die(argv[i],2); + } + if(!yyin)yyin=stdin; /* no inputname specified */ + if(!yyout)yyout=stdout; /* no outputname specified */ + if(inputname){ + for(ptr=inputname,ptr1=buffer;*ptr;) + switch(*ptr){ + case '_': + case '$': *ptr1++='\\'; + default: + *ptr1++= *ptr++; + break; + } + *ptr1=0; + } + else + strcpy(buffer,inputname="(stdin)"); +#ifdef FLEX_DEBUG + if(yy_flex_debug){ + /* FLEX gives very much debug info; write the stuff to a file */ + fprintf(stderr,"redirect stderr to file {@#name}.dbg\n"); + (freopen("{@#name}.dbg","w",stderr)) + || die("error opening file {@#name}.dbg for stderr (freopen)",3); + } +#endif /* FLEX_DEBUG */ + yylex(); + + /* write the end of the LaTeX file */ + if(brace_open)fputc('}',yyout); + fprintf(yyout,"{@#string}^\end{flushleft} +\ifmfiles\def\END{\relax}\else\def\END{\end{document}}\fi +\END§^"); + fclose(yyin); + fclose(yyout); +} |