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 >
LaTeX Document  |  1999-11-22  |  12KB  |  291 lines

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