summaryrefslogtreecommitdiff
path: root/support/tiny_c2l/lx2l-src
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tiny_c2l/lx2l-src
Initial commit
Diffstat (limited to 'support/tiny_c2l/lx2l-src')
-rw-r--r--support/tiny_c2l/lx2l-src/0readme.txt21
-rw-r--r--support/tiny_c2l/lx2l-src/config.lx87
-rw-r--r--support/tiny_c2l/lx2l-src/makefile.lxx280
-rw-r--r--support/tiny_c2l/lx2l-src/position.lx1078
-rw-r--r--support/tiny_c2l/lx2l-src/tiny_cvt2ltx.lx1477
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}<&lt;
+{@map4}>&gt;
+{@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);
+}