home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / cpp2tex.zip / C++2ltx.zip / C++2ltx.awk (.txt) < prev    next >
LaTeX Document  |  1999-11-22  |  12KB  |  290 lines

  1. # C++2ltx.awk: C/C++ to LaTeX konvertor (version 22. 11. 1999)
  2. # c Petr Mikulik
  3. # Laboratory of Thin Films and Nanostructures
  4. # Masaryk University, Brno, Czech Republic
  5. # mikulik@physics.muni.cz, http://www.sci.muni.cz/~mikulik/
  6. # This program is free (open source), but copyrighted and it must 
  7. # be distributed with the whole accompanying stuff (see C++2ltx.zip)
  8. # Brief documentation:
  9. # --------------------
  10. # Keywords in the file: 
  11. #   "//C++2ltx+"   on a single line: all "//" and "/*" comments are taken as TeX enhanced
  12. #   "//C++2ltx-"   on a single line: all "//" and "/*" comments are taken as programmer's 
  13. #            comments (the default setting)
  14. # //+ and /*+ ... */  ... enhanced comments (supposed LaTeX code there)
  15. # //- and /*- ... */  ... usual C/C++ comment. This is useful when the 
  16. #              default setting are enhanced comments
  17. # //!              ... this line is completely ignored
  18. #              (in principle, equivalent to  //- % blablabla)
  19. ### The program:
  20. BEGIN {
  21. END_quietly=0
  22. cerr="/dev/stderr" # standard error output
  23. if (ARGC!=2) { 
  24.   print "\nScript C++2ltx.awk (c Petr Mikulik, Brno, August 1998)"  >cerr
  25.   print "Syntax:  (g)awk -f C++2ltx.awk _input_C_or_C++_file_ >output_file.tex\n" >cerr
  26.   print "This program is freeware distributed under GNU General Public License." >cerr
  27.   print "Homepage: http://www.sci.muni.cz/~mikulik" >cerr
  28.   END_quietly=1
  29.   exit
  30. # Remarks:
  31. #   -- There can fit up to 65 characters "x" (in 10 pt) on line 250 mm width
  32. #    (see CharsPerLine below)
  33. print "% Format: latex\n"
  34. print "\\documentclass[a4paper]{article}"
  35. print "\\special{landscape}"
  36. print "\\textwidth=274mm"
  37. print "\\oddsidemargin=-15.6mm"
  38. print "\\evensidemargin=-15.6mm"
  39. print "\\textheight=182.7mm"
  40. print "\\topmargin=-15.7mm"
  41. print "\n\\twocolumn \\columnsep=16mm \\columnseprule=1.0pt"
  42. print "\\parindent=0pt \\parskip=0pt"
  43. print "\\rightskip=0pt plus 0.3\\textwidth"
  44. print "\\hfuzz=1em \\vfuzz=1em"
  45. print "\n\\let\\Huge\\huge \\let\\huge\\LARGE \\let\\LARGE\\Large \\let\\Large\\large"
  46. print "\\let\\large\\normalsize \\let\\normalsize\\small \\let\\small\\footnotesize"
  47. print "\\let\\footnotesize\\scriptsize \\let\\scriptsize\\tiny"
  48. print "\\let\\bigskip\\medskip \\let\\medskip\\smallskip\n"
  49. print "\\usepackage{fancyhdr} \\pagestyle{fancy}"
  50. print "\\def\\headrulewidth{0pt} \\def\\footrulewidth{0pt} \\headsep=12pt"
  51. print "\\lhead{} \\rhead{} \\lfoot{} \\cfoot{} \\rfoot{}"
  52. print "\\chead{\\fboxrule=1.0pt \\framebox[\\hsize]{"
  53.   "ls -l --full-time "ARGV[1] | getline # find the creation date of the file
  54.   S=$3" "$4" "$5" "$7" "$6; close("ls -l --full-time "ARGV[1])
  55. i=ARGV[1]
  56. gsub("_","\\_",i)    # since \verb cannot be used in \chead, precede TeX's special
  57. gsub("\\$","\\$",i)    # characters here
  58. if (index(i,"\\")) { # translation \ => $\backslash$ in the input filename
  59.   gsub("\\\\","C2LTX",i)
  60.   gsub("C2LTX","$\\backslash$",i)
  61. print "  \\quad \\textbf{"i"} \\quad ("S") \\hfill"
  62.   S=ENVIRON["LOGNAME"]; 
  63.   if (S=="") { S=ENVIRON["USER"]; if (S=="") S=root }
  64.   S=S" from "ENVIRON["HOSTNAME"]" ("strftime("%a %b %d %Y %H:%M:%S",systime())
  65. print "  printed by "S") \\hfill Page \\thepage \\quad}}"
  66. print "\n\\usepackage{C++2ltx}"
  67. print "\\def\\up{\\unskip\\penalty0}"
  68. print "\\def\\CLTXVF{\\normalfont\\ttfamily\\slshape}"
  69. print "\n\\begin{document}\n"
  70. #### DEFAULT SETTINGS ####
  71. CharsPerLine=80 # limit for cutting the line into words (i.e. into the \hboxes)
  72.            # depends on the default font and page size used---found manually
  73. DefaultEnhancedComment=0 # default enhanced comments yes/no
  74. #### END of the default setttings
  75. ### USUAL THINGS ###
  76. # cerr ... see above
  77. ### GLOBAL VARIABLES ###
  78. # separators for \verb command
  79. Separators="
  80. |!+=-@;:.0123456789[]()" # the array of choosable separators
  81. Separator=""                  # separator chosen for the current line
  82. # line parsing
  83. Line =""    # contains the line read from input (should always equal $0)
  84. iLine =0    # index from which start or continue parsing of the Line
  85. isLongLine =0    # is this line long, i.e. are there more chars than CharsPerLine??
  86. wasBlankLine=0 # flag for separating paragraphs by blank lines
  87. # comment treatment
  88. cPresent =0    # is there still a comment on the current line?
  89. c2slashes =0    # is it // or //+ comment?
  90. cEnhanced =0    # is it TeX-enhanced comment?
  91. cLeft =0; cRight =0    # parsing this piece of Line. If cOpen then cRight is unused
  92. cOpen =0    # set to 1 if the current line $0 is continuation of an open long /* comment
  93. cOpenFirstLine =0    # first line of open command opening
  94. cParIndentation =0    # string with \parindent and \hangindent to be employed at each beginning
  95.             # new paragraph of an open enhanced comment
  96. #### END of global variables
  97. ##### ENDING THE PROGRAM #####
  98. END {
  99. if (END_quietly);  # write nothing since there is no (useful) output
  100.   else print "\\end{document}"
  101. ####### PROCESS INPUT: Blank line and //C++2ltx + and - switches #######
  102. NF==0 { # blank line
  103.   if (cOpen && cEnhanced) printf "\n\n\\medskip"
  104.     else print "\\medskip\n"
  105.   wasBlankLine=1
  106.   next
  107. wasBlankLine!=0 {
  108.   if (cOpen && cEnhanced) if (cParIndentation) printf cParIndentation
  109.   wasBlankLine=0
  110. $0=="//C++2ltx+" {
  111.   DefaultEnhancedComment=1
  112.   next
  113. $0=="//C++2ltx-" {
  114.   DefaultEnhancedComment=0
  115.   next
  116. $0 ~ "//!" { # line contains comment
  117.   if (index($1,"//!")==1) next # ignore this line with only ignorable comment
  118.   i=index($0,"//!")
  119.   $0=substr($0,1,i-1)
  120.   $0=StripTrailingSpaces($0)
  121. ################## MAIN PROGRAM PART ##################
  122. Line=$0; ExpandTabulators()
  123. iLine=1 # start parsing from the first column (of course)
  124. OutHead=""; OutLine=""  # make the output strings empty
  125. if (!( cOpen && cEnhanced )) OutTail="" # keep still OutTail, i.e. \par}
  126. # Find a suitable \verb separator
  127. i=1; flag=1
  128. while (flag) {
  129.   Separator=substr(Separators,i,1); i++
  130.   flag=index(Line,Separator)
  131. if ( cOpen && cEnhanced ) isLongLine=0
  132.   else    {
  133.     isLongLine = (length(Line)>CharsPerLine) ? 1 : 0
  134.     ### RUDE OF HANGINDENT:
  135.     if (isLongLine) {
  136.     iLine=match(Line,"[^ ]")
  137.     ParIndent=iLine-1
  138.     OutHead="{\\par\\leavevmode\\parindent="ParIndent*1.22"ex\\indent\\hangindent="(ParIndent+2)*1.22"ex"
  139.     OutTail=OutTail "\\par}"
  140.     }
  141. # Go over all pieces of code and comment until the whole line is processed
  142. while (iLine<=length(Line)) {
  143.   FindNextComment()  # find comment, and if it is there, then set its cXXXX staff
  144.   if (!cPresent) { # there is no comment
  145.     OutLine=OutLine VerbIt( substr(Line,iLine) )
  146.     iLine=length(Line)+1
  147.     else { # there is a COMMENT on the line
  148.       if (iLine>CharsPerLine-15) # parbox too narrow, thus shorten hangindent
  149.      OutLine=OutLine "\\advance\\hangindent-" 25*1.22 "ex"
  150.       if (cLeft>iLine) # typeset the code (if exist) preceding the comment
  151.     OutLine=OutLine VerbIt( substr(Line,iLine,cLeft-iLine) )
  152.       if (c2slashes || cOpen) { # It is // comment or long (open) /* comment. Format it now
  153.       #! if (longComment...)
  154.       if (cEnhanced) { # enhanced comment, no surrounding code needed
  155.         OutLine=OutLine "\n" StripRoundSpaces(substr(Line,cLeft))
  156.         # isn't it the first thing on the line?
  157.         if (cOpen && cLeft==match(Line,"[^ ]")-1) { # yes, it is, thus hangindent it
  158.           cParIndentation="\\parindent="(cLeft-1)*1.22"ex\\indent\\hangindent="(cLeft-1)*1.22"ex%"
  159.           OutHead="{" cParIndentation
  160.           if (!cOpenFirstLine) OutLine="" # clear that "\verb|    |"
  161.           cOpenFirstLine=0
  162.           OutTail="\\par}"
  163.           }
  164.         else { # usual comment
  165.         OutLine=OutLine "%\n{\\makeatletter\\let\\verbatim@font\\CLTXVF\\makeatother%\n"
  166.         S=substr(Line,cLeft)
  167.         if (isLongLine) S=StripLeadingSpaces(S)
  168.         OutLine=OutLine VerbIt( S ) "\n}"
  169.       iLine=length(Line)+1
  170.     else { # It is /* */ comment. Format it now
  171.       if (cEnhanced) { # enhanced comment, no surrounding code needed
  172.         OutLine=OutLine "\n" StripRoundSpaces(substr(Line,cLeft,cRight-cLeft-4)) "%\n"
  173.         iLine=cRight-1
  174.         else { # usual comment
  175.         OutLine=OutLine "%\n{\\makeatletter\\let\\verbatim@font\\CLTXVF\\makeatother%\n"
  176.         OutLine=OutLine VerbIt( substr(Line,cLeft,cRight-cLeft+1) ) "}%\n"
  177.         iLine=cRight+1
  178.       }
  179.   } # the whole line has been processed
  180. # flush the output
  181. if (OutHead!="") printf "%s",OutHead
  182. if (OutLine!="") printf "%s",OutLine
  183. if (cOpen && cEnhanced) {} # printf "\n"
  184.   else
  185. if (OutTail!="") {
  186.     if (substr(OutLine,length(OutLine))!="\n") printf "\n" # print tail on a new line
  187.     printf "%s",OutTail
  188. print "\n"
  189. } # end of the Main Program Part
  190. ####################### FUNCTIONS #######################
  191. # This function expands tabulators in the global variable Line
  192. function ExpandTabulators (  i,S,sp ) {
  193. i=index(Line,"\t")
  194. if (i>0) {
  195.   S=""
  196.   while (i!=0) {
  197.     S=S""substr(Line,1,i-1)
  198.     sp=" "
  199.     for (p=8-i%8; p>0; p--) sp=sp" "
  200.     S=S""sp
  201.     Line=substr(Line,i+1)
  202.     i=index(Line,"\t")
  203.     }
  204.   Line=S""Line
  205. # Verboses a code passed from line. If the line is short, then put \verb in front of the line
  206. # enclosed by separators, otherwise makes hboxes of \verbed all words
  207. function VerbIt ( line,   i,S ) {
  208. if (!isLongLine) { # print \verb+<line>+
  209.     return "\\verb"Separator line Separator
  210. # otherwise cut the line into \hbox{\verb+<word_of_line>+}
  211. while (length(line)>0) {
  212.   i=match(line," [^ ]")
  213.   if (i!=0) { # ending space
  214.       S = S "\\hbox{\\verb" Separator substr(line,1,i) Separator "} \\up"
  215.       line=substr(line,i+1); }
  216.     else { 
  217.       S = S"\\hbox{\\verb" Separator line Separator "} "
  218.       line = "" }
  219. return S
  220. # Is there comment?
  221. function FindNextComment (     line,S ) {
  222. if (cOpen) { # multiline comment /* ... */ continues
  223.   cPresent=1
  224.   cLeft=1
  225.   cRight=index( substr(Line,1), "*/" )
  226.   cOpen = (cRight==0) ? 1:0
  227.   if (cRight>0) cRight += cEnhanced ? 3:1
  228.   return
  229. line=substr(Line,iLine)
  230. cPresent=indexNotInQuotes(line,"//")
  231. if (cPresent) { # there is // comment
  232.     c2slashes=1
  233.     cLeft=cPresent+iLine-1 # position of the comment in Line
  234.     # cRight is unused
  235.   else {
  236.     cPresent=indexNotInQuotes(line,"/*")
  237.     if (!cPresent) return # there is no (more) comment on the current line
  238.     c2slashes=0    # there is /* comment
  239.     cLeft=cPresent+iLine-1 # position of the comment in Line
  240.     cRight=index( substr(Line,cLeft+2), "*/" )
  241.     cOpen = (cRight==0) ? 1:0
  242.     if (cOpen) cOpenFirstLine=1
  243.     if (cRight>0) cRight+=cLeft+2
  244. # find whether the comment is enhanced
  245. S=substr(line,cPresent+2,1)
  246. delSign=1
  247. if (S=="-") cEnhanced=0; else    # there was //-
  248.   if (S=="+") cEnhanced=1; else    # there was //+
  249.     { cEnhanced=DefaultEnhancedComment # use the default value
  250.       delSign=0 } # no delete of sign
  251. # delete unnecessary parts of the comment: //+ and /*- (enhanced) or + and / for normal
  252. if (cEnhanced)
  253.     Line=substr(Line,1,cLeft-1) substr(Line,cLeft+2+delSign) # delete also the // or /* 
  254.   else if (delSign)
  255.     Line=substr(Line,1,cLeft+1) substr(Line,cLeft+3)
  256. function StripTrailingSpaces ( S   ,i ) {
  257. i=match(S," +$")
  258. return (i==0) ? S : substr(S,1,i-1)
  259. function StripLeadingSpaces ( S   ,i ) {
  260. i=match(S,"[^ ]")
  261. return (i==0) ? "" : substr(S,i)
  262. function StripRoundSpaces ( S   ,i ) {
  263. i=match(S,"[^ ]")
  264. if (i==0) return ""
  265. S=substr(S,i)
  266. i=match(S," +$")
  267. return (i==0) ? S : substr(S,1,i-1)
  268. # This function works like index(S,pattern) with the exception that
  269. # the pattern cannot appear in quotes (inside C/C++ strings)
  270. function indexNotInQuotes ( S, pattern ) {
  271. offset=0
  272. while (1) {
  273.   p=index(substr(S,offset+1),pattern)
  274.   if (p==0) return 0 # no pattern found
  275.   p+=offset
  276.   c=countQuotes(S,1,p-1)
  277.   if (c%2==0) return p # even number of quotes, thus return the found position
  278.   offset=p
  279. # returns number of quotes in the specified region. Takes care of \"
  280. function countQuotes ( S, from, to ) {
  281. S=substr(S,from,to)
  282. from=index(S,"\"")
  283. while (from) { # there is (still) a quote
  284.   # increment counter of quotes if the quote is not backslashed:
  285.   if (!( from>0 && substr(S,from-1,1)=="\\" )) c++
  286.   S=substr(S,from+1) 
  287.   from=index(S,"\"")
  288. return c
  289. # eof C++2ltx.awk
  290.