home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / cpp2tex.zip / C++2ltx.zip / C++2ltx.cmd < prev    next >
OS/2 REXX Batch file  |  1999-11-22  |  12KB  |  385 lines

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