home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
cpp2tex.zip
/
C++2ltx.zip
/
C++2ltx
(
.txt
)
< prev
next >
Wrap
LaTeX Document
|
1999-11-22
|
12KB
|
291 lines
#!/bin/awk -f
# C++2ltx.awk: C/C++ to LaTeX konvertor (version 22. 11. 1999)
# c Petr Mikulik
# Laboratory of Thin Films and Nanostructures
# Masaryk University, Brno, Czech Republic
# mikulik@physics.muni.cz, http://www.sci.muni.cz/~mikulik/
# This program is free (open source), but copyrighted and it must
# be distributed with the whole accompanying stuff (see C++2ltx.zip)
# Brief documentation:
# --------------------
# Keywords in the file:
# "//C++2ltx+" on a single line: all "//" and "/*" comments are taken as TeX enhanced
# "//C++2ltx-" on a single line: all "//" and "/*" comments are taken as programmer's
# comments (the default setting)
# //+ and /*+ ... */ ... enhanced comments (supposed LaTeX code there)
# //- and /*- ... */ ... usual C/C++ comment. This is useful when the
# default setting are enhanced comments
# //! ... this line is completely ignored
# (in principle, equivalent to //- % blablabla)
### The program:
BEGIN {
END_quietly=0
cerr="/dev/stderr" # standard error output
if (ARGC!=2) {
print "\nScript C++2ltx.awk (c Petr Mikulik, Brno, August 1998)" >cerr
print "Syntax: (g)awk -f C++2ltx.awk _input_C_or_C++_file_ >output_file.tex\n" >cerr
print "This program is freeware distributed under GNU General Public License." >cerr
print "Homepage: http://www.sci.muni.cz/~mikulik" >cerr
END_quietly=1
exit
# Remarks:
# -- There can fit up to 65 characters "x" (in 10 pt) on line 250 mm width
# (see CharsPerLine below)
print "% Format: latex\n"
print "\\documentclass[a4paper]{article}"
print "\\special{landscape}"
print "\\textwidth=274mm"
print "\\oddsidemargin=-15.6mm"
print "\\evensidemargin=-15.6mm"
print "\\textheight=182.7mm"
print "\\topmargin=-15.7mm"
print "\n\\twocolumn \\columnsep=16mm \\columnseprule=1.0pt"
print "\\parindent=0pt \\parskip=0pt"
print "\\rightskip=0pt plus 0.3\\textwidth"
print "\\hfuzz=1em \\vfuzz=1em"
print "\n\\let\\Huge\\huge \\let\\huge\\LARGE \\let\\LARGE\\Large \\let\\Large\\large"
print "\\let\\large\\normalsize \\let\\normalsize\\small \\let\\small\\footnotesize"
print "\\let\\footnotesize\\scriptsize \\let\\scriptsize\\tiny"
print "\\let\\bigskip\\medskip \\let\\medskip\\smallskip\n"
print "\\usepackage{fancyhdr} \\pagestyle{fancy}"
print "\\def\\headrulewidth{0pt} \\def\\footrulewidth{0pt} \\headsep=12pt"
print "\\lhead{} \\rhead{} \\lfoot{} \\cfoot{} \\rfoot{}"
print "\\chead{\\fboxrule=1.0pt \\framebox[\\hsize]{"
"ls -l --full-time "ARGV[1] | getline # find the creation date of the file
S=$3" "$4" "$5" "$7" "$6; close("ls -l --full-time "ARGV[1])
i=ARGV[1]
gsub("_","\\_",i) # since \verb cannot be used in \chead, precede TeX's special
gsub("\\$","\\$",i) # characters here
if (index(i,"\\")) { # translation \ => $\backslash$ in the input filename
gsub("\\\\","C2LTX",i)
gsub("C2LTX","$\\backslash$",i)
print " \\quad \\textbf{"i"} \\quad ("S") \\hfill"
S=ENVIRON["LOGNAME"];
if (S=="") { S=ENVIRON["USER"]; if (S=="") S=root }
S=S" from "ENVIRON["HOSTNAME"]" ("strftime("%a %b %d %Y %H:%M:%S",systime())
print " printed by "S") \\hfill Page \\thepage \\quad}}"
print "\n\\usepackage{C++2ltx}"
print "\\def\\up{\\unskip\\penalty0}"
print "\\def\\CLTXVF{\\normalfont\\ttfamily\\slshape}"
print "\n\\begin{document}\n"
#### DEFAULT SETTINGS ####
CharsPerLine=80 # limit for cutting the line into words (i.e. into the \hboxes)
# depends on the default font and page size used---found manually
DefaultEnhancedComment=0 # default enhanced comments yes/no
#### END of the default setttings
### USUAL THINGS ###
# cerr ... see above
### GLOBAL VARIABLES ###
# separators for \verb command
Separators="
|!+=-@;:.0123456789[]()" # the array of choosable separators
Separator="" # separator chosen for the current line
# line parsing
Line ="" # contains the line read from input (should always equal $0)
iLine =0 # index from which start or continue parsing of the Line
isLongLine =0 # is this line long, i.e. are there more chars than CharsPerLine??
wasBlankLine=0 # flag for separating paragraphs by blank lines
# comment treatment
cPresent =0 # is there still a comment on the current line?
c2slashes =0 # is it // or //+ comment?
cEnhanced =0 # is it TeX-enhanced comment?
cLeft =0; cRight =0 # parsing this piece of Line. If cOpen then cRight is unused
cOpen =0 # set to 1 if the current line $0 is continuation of an open long /* comment
cOpenFirstLine =0 # first line of open command opening
cParIndentation =0 # string with \parindent and \hangindent to be employed at each beginning
# new paragraph of an open enhanced comment
#### END of global variables
##### ENDING THE PROGRAM #####
END {
if (END_quietly); # write nothing since there is no (useful) output
else print "\\end{document}"
####### PROCESS INPUT: Blank line and //C++2ltx + and - switches #######
NF==0 { # blank line
if (cOpen && cEnhanced) printf "\n\n\\medskip"
else print "\\medskip\n"
wasBlankLine=1
next
wasBlankLine!=0 {
if (cOpen && cEnhanced) if (cParIndentation) printf cParIndentation
wasBlankLine=0
$0=="//C++2ltx+" {
DefaultEnhancedComment=1
next
$0=="//C++2ltx-" {
DefaultEnhancedComment=0
next
$0 ~ "//!" { # line contains comment
if (index($1,"//!")==1) next # ignore this line with only ignorable comment
i=index($0,"//!")
$0=substr($0,1,i-1)
$0=StripTrailingSpaces($0)
################## MAIN PROGRAM PART ##################
Line=$0; ExpandTabulators()
iLine=1 # start parsing from the first column (of course)
OutHead=""; OutLine="" # make the output strings empty
if (!( cOpen && cEnhanced )) OutTail="" # keep still OutTail, i.e. \par}
# Find a suitable \verb separator
i=1; flag=1
while (flag) {
Separator=substr(Separators,i,1); i++
flag=index(Line,Separator)
if ( cOpen && cEnhanced ) isLongLine=0
else {
isLongLine = (length(Line)>CharsPerLine) ? 1 : 0
### RUDE OF HANGINDENT:
if (isLongLine) {
iLine=match(Line,"[^ ]")
ParIndent=iLine-1
OutHead="{\\par\\leavevmode\\parindent="ParIndent*1.22"ex\\indent\\hangindent="(ParIndent+2)*1.22"ex"
OutTail=OutTail "\\par}"
}
# Go over all pieces of code and comment until the whole line is processed
while (iLine<=length(Line)) {
FindNextComment() # find comment, and if it is there, then set its cXXXX staff
if (!cPresent) { # there is no comment
OutLine=OutLine VerbIt( substr(Line,iLine) )
iLine=length(Line)+1
else { # there is a COMMENT on the line
if (iLine>CharsPerLine-15) # parbox too narrow, thus shorten hangindent
OutLine=OutLine "\\advance\\hangindent-" 25*1.22 "ex"
if (cLeft>iLine) # typeset the code (if exist) preceding the comment
OutLine=OutLine VerbIt( substr(Line,iLine,cLeft-iLine) )
if (c2slashes || cOpen) { # It is // comment or long (open) /* comment. Format it now
#! if (longComment...)
if (cEnhanced) { # enhanced comment, no surrounding code needed
OutLine=OutLine "\n" StripRoundSpaces(substr(Line,cLeft))
# isn't it the first thing on the line?
if (cOpen && cLeft==match(Line,"[^ ]")-1) { # yes, it is, thus hangindent it
cParIndentation="\\parindent="(cLeft-1)*1.22"ex\\indent\\hangindent="(cLeft-1)*1.22"ex%"
OutHead="{" cParIndentation
if (!cOpenFirstLine) OutLine="" # clear that "\verb| |"
cOpenFirstLine=0
OutTail="\\par}"
}
else { # usual comment
OutLine=OutLine "%\n{\\makeatletter\\let\\verbatim@font\\CLTXVF\\makeatother%\n"
S=substr(Line,cLeft)
if (isLongLine) S=StripLeadingSpaces(S)
OutLine=OutLine VerbIt( S ) "\n}"
iLine=length(Line)+1
else { # It is /* */ comment. Format it now
if (cEnhanced) { # enhanced comment, no surrounding code needed
OutLine=OutLine "\n" StripRoundSpaces(substr(Line,cLeft,cRight-cLeft-4)) "%\n"
iLine=cRight-1
else { # usual comment
OutLine=OutLine "%\n{\\makeatletter\\let\\verbatim@font\\CLTXVF\\makeatother%\n"
OutLine=OutLine VerbIt( substr(Line,cLeft,cRight-cLeft+1) ) "}%\n"
iLine=cRight+1
}
} # the whole line has been processed
# flush the output
if (OutHead!="") printf "%s",OutHead
if (OutLine!="") printf "%s",OutLine
if (cOpen && cEnhanced) {} # printf "\n"
else
if (OutTail!="") {
if (substr(OutLine,length(OutLine))!="\n") printf "\n" # print tail on a new line
printf "%s",OutTail
print "\n"
} # end of the Main Program Part
####################### FUNCTIONS #######################
# This function expands tabulators in the global variable Line
function ExpandTabulators ( i,S,sp ) {
i=index(Line,"\t")
if (i>0) {
S=""
while (i!=0) {
S=S""substr(Line,1,i-1)
sp=" "
for (p=8-i%8; p>0; p--) sp=sp" "
S=S""sp
Line=substr(Line,i+1)
i=index(Line,"\t")
}
Line=S""Line
# Verboses a code passed from line. If the line is short, then put \verb in front of the line
# enclosed by separators, otherwise makes hboxes of \verbed all words
function VerbIt ( line, i,S ) {
if (!isLongLine) { # print \verb+<line>+
return "\\verb"Separator line Separator
# otherwise cut the line into \hbox{\verb+<word_of_line>+}
while (length(line)>0) {
i=match(line," [^ ]")
if (i!=0) { # ending space
S = S "\\hbox{\\verb" Separator substr(line,1,i) Separator "} \\up"
line=substr(line,i+1); }
else {
S = S"\\hbox{\\verb" Separator line Separator "} "
line = "" }
return S
# Is there comment?
function FindNextComment ( line,S ) {
if (cOpen) { # multiline comment /* ... */ continues
cPresent=1
cLeft=1
cRight=index( substr(Line,1), "*/" )
cOpen = (cRight==0) ? 1:0
if (cRight>0) cRight += cEnhanced ? 3:1
return
line=substr(Line,iLine)
cPresent=indexNotInQuotes(line,"//")
if (cPresent) { # there is // comment
c2slashes=1
cLeft=cPresent+iLine-1 # position of the comment in Line
# cRight is unused
else {
cPresent=indexNotInQuotes(line,"/*")
if (!cPresent) return # there is no (more) comment on the current line
c2slashes=0 # there is /* comment
cLeft=cPresent+iLine-1 # position of the comment in Line
cRight=index( substr(Line,cLeft+2), "*/" )
cOpen = (cRight==0) ? 1:0
if (cOpen) cOpenFirstLine=1
if (cRight>0) cRight+=cLeft+2
# find whether the comment is enhanced
S=substr(line,cPresent+2,1)
delSign=1
if (S=="-") cEnhanced=0; else # there was //-
if (S=="+") cEnhanced=1; else # there was //+
{ cEnhanced=DefaultEnhancedComment # use the default value
delSign=0 } # no delete of sign
# delete unnecessary parts of the comment: //+ and /*- (enhanced) or + and / for normal
if (cEnhanced)
Line=substr(Line,1,cLeft-1) substr(Line,cLeft+2+delSign) # delete also the // or /*
else if (delSign)
Line=substr(Line,1,cLeft+1) substr(Line,cLeft+3)
function StripTrailingSpaces ( S ,i ) {
i=match(S," +$")
return (i==0) ? S : substr(S,1,i-1)
function StripLeadingSpaces ( S ,i ) {
i=match(S,"[^ ]")
return (i==0) ? "" : substr(S,i)
function StripRoundSpaces ( S ,i ) {
i=match(S,"[^ ]")
if (i==0) return ""
S=substr(S,i)
i=match(S," +$")
return (i==0) ? S : substr(S,1,i-1)
# This function works like index(S,pattern) with the exception that
# the pattern cannot appear in quotes (inside C/C++ strings)
function indexNotInQuotes ( S, pattern ) {
offset=0
while (1) {
p=index(substr(S,offset+1),pattern)
if (p==0) return 0 # no pattern found
p+=offset
c=countQuotes(S,1,p-1)
if (c%2==0) return p # even number of quotes, thus return the found position
offset=p
# returns number of quotes in the specified region. Takes care of \"
function countQuotes ( S, from, to ) {
S=substr(S,from,to)
from=index(S,"\"")
while (from) { # there is (still) a quote
# increment counter of quotes if the quote is not backslashed:
if (!( from>0 && substr(S,from-1,1)=="\\" )) c++
S=substr(S,from+1)
from=index(S,"\"")
return c
# eof C++2ltx.awk