1 |
#! /usr/bin/env perl |
2 |
# |
3 |
# $Id: protex,v 1.1 2004/02/04 04:49:19 edhill Exp $ |
4 |
# |
5 |
#BOP |
6 |
# |
7 |
# !ROUTINE: ProTeX v. 2.00 - Translates DAO Prologues to LaTeX |
8 |
# |
9 |
# !INTERFACE: |
10 |
# protex [-hbACFS7] ] [+-nlsxf] [src_file(s)] |
11 |
# |
12 |
# !DESCRIPTION: |
13 |
# Perl filter to produce a \LaTeX compatible document |
14 |
# from a DAO Fortran source code with standard Pro\TeX |
15 |
# prologues. If source files are not specified it |
16 |
# reads from stdin; output is always to stdout. |
17 |
# |
18 |
# \noindent |
19 |
# {\bf Command Line Switches:} \vspace{0.2cm} |
20 |
# |
21 |
# \begin{center} |
22 |
# \begin{tabular}{|c|l|} \hline \hline |
23 |
# -h & Help mode: list command line options \\ \hline |
24 |
# -b & Bare mode, meaning no preamble, etc. \\ \hline |
25 |
# -i & internal mode: omit prologues marked !BOPI \\ \hline |
26 |
# +/-n & New Page for each subsection (wastes paper) \\ \hline |
27 |
# +/-l & Listing mode, default is prologues only \\ \hline |
28 |
# +/-s & Shut-up mode, i.e., ignore any code from BOC to EOC \\ \hline |
29 |
# +/-x & No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode \\ \hline |
30 |
# +/-f & No source file info \\ \hline |
31 |
# -A & Ada code \\ \hline |
32 |
# -C & C++ code \\ \hline |
33 |
# -F & F90 code (default) \\ \hline |
34 |
# -7 & F77 code \\ \hline |
35 |
# -S & Shell script \\ \hline \hline |
36 |
# \end{tabular} |
37 |
# \end{center} |
38 |
# |
39 |
# The options can appear in any order. The options, -h and -b, affect |
40 |
# the input from all files listed on command-line input. Each of the |
41 |
# remaining options effects only the input from the files listed after |
42 |
# the option and prior to any overriding option. The plus sign |
43 |
# turns off the option. For example, the command-line input, |
44 |
# \bv |
45 |
# protex -bnS File1 -F File2.f +n File3.f |
46 |
# \ev |
47 |
# will cause the option, {\tt -n} to affect the input from the files, |
48 |
# {\tt File} and {\tt File2.f}, but not from {\tt File3.f}. The |
49 |
# {\tt -S} option is implemented for {\tt File1} but is overridden by |
50 |
# the {\tt -F} for files {\tt File2.f} and {\tt File3.f}. |
51 |
# |
52 |
# |
53 |
# !SEE ALSO: |
54 |
# For a more detailed description of ProTeX functionality, |
55 |
# DAO Prologue and other conventions, consult: |
56 |
# |
57 |
# Sawyer, W., and A. da Silva, 1997: ProTeX: A Sample |
58 |
# Fortran 90 Source Code Documentation System. |
59 |
# DAO Office Note 97-11 |
60 |
# |
61 |
# |
62 |
# !REVISION HISTORY: |
63 |
# |
64 |
# 20Dec1995 da Silva First experimental version |
65 |
# 10Nov1996 da Silva First internal release (v1.01) |
66 |
# 28Jun1997 da Silva Modified so that !DESCRIPTION can appear after |
67 |
# !INTERFACE, and !INPUT PARAMETERS etc. changed to italics. |
68 |
# 02Jul1997 Sawyer Added shut-up mode |
69 |
# 20Oct1997 Sawyer Added support for shell scripts |
70 |
# 11Mar1998 Sawyer Added: file name, date in header, C, script support |
71 |
# 05Aug1998 Sawyer Fixed LPChang-bug-support-for-files-with-underscores |
72 |
# 10Oct1998 da Silva Introduced -f option for removing source file info |
73 |
# from subsection, etc. Added help (WS). |
74 |
# 06Dec1999 C. Redder Added LaTeX command "\label{sec:prologues}" just |
75 |
# after the beginning of the proglogue section. |
76 |
# 13Dec1999 C. Redder Increased flexbility in command-line |
77 |
# interface. The options can appear in any |
78 |
# order which will allow the user to implement |
79 |
# options for select files. |
80 |
# 01Feb1999 C. Redder Added \usepackage commands to preamble of latex |
81 |
# document to include the packages amsmath, epsfig |
82 |
# and hangcaption. |
83 |
# 10May2000 C. Redder Revised LaTeX command "\label{sec:prologues}" |
84 |
# to "\label{app:ProLogues}" |
85 |
# 10/10/2002 da Silva Introduced ARGUMENTS keyword, touch ups. |
86 |
# |
87 |
# 15Jan2003 R. Staufer Modified table of contents to print only section headers - no descriptions |
88 |
# |
89 |
# 25Feb2003 R. Staufer Added BOPI/EOPI and -i (internal) switch to provide the option of omitting prologue information from output files. |
90 |
# |
91 |
#EOP |
92 |
#---------------------------------------------------------------------------- |
93 |
|
94 |
# Keep this if you don't know what it does... |
95 |
# ------------------------------------------- |
96 |
$[ = 1; # set array base to 1 |
97 |
$, = ' '; # set output field separator |
98 |
$\ = "\n"; # set output record separator |
99 |
|
100 |
# Set valid options lists |
101 |
# ----------------------- |
102 |
$GlobOptions = 'hb'; # Global options (i.e for all files) |
103 |
$LangOptions = 'ACFS7'; # Options for setting programming languages |
104 |
$SwOptions = 'flinsx'; # Options that can change for each input |
105 |
# file |
106 |
$RegOptions = "$GlobOptions$LangOptions"; |
107 |
# Scan for global options until first first |
108 |
# file is processed. |
109 |
|
110 |
# Scan for global options |
111 |
# ----------------------- |
112 |
$NFiles = 0; |
113 |
Arg: |
114 |
foreach $arg (@ARGV) { |
115 |
$option = &CheckOpts ( $arg, $RegOptions, $SwOptions ) + 1; |
116 |
if ( $option ) { |
117 |
$rc = &GetOpts ( $arg, $GlobOptions ); |
118 |
next Arg; } |
119 |
|
120 |
else { $NFiles++; |
121 |
}# end if |
122 |
}# end foreach |
123 |
|
124 |
# If all input arguments are options, then assume the |
125 |
# filename, "-", for the standard input |
126 |
# -------------------------------------------------- |
127 |
if ( $NFiles == 0 ) { push (@ARGV, "-"); } |
128 |
|
129 |
# Implement help option |
130 |
# --------------------- |
131 |
if ( $opt_h ) { |
132 |
&print_help(); |
133 |
exit(); |
134 |
}#end if |
135 |
|
136 |
# Optional Prologue Keywords |
137 |
# -------------------------- |
138 |
@keys = ( "!INTERFACE:", |
139 |
"!USES:", |
140 |
"!PUBLIC TYPES:", |
141 |
"!PRIVATE TYPES:", |
142 |
"!PUBLIC MEMBER FUNCTIONS:", |
143 |
"!PRIVATE MEMBER FUNCTIONS:", |
144 |
"!PUBLIC DATA MEMBERS:", |
145 |
"!PARAMETERS:", |
146 |
"!ARGUMENTS:", |
147 |
"!DEFINED PARAMETERS:", |
148 |
"!INPUT PARAMETERS:", |
149 |
"!INPUT/OUTPUT PARAMETERS:", |
150 |
"!OUTPUT PARAMETERS:", |
151 |
"!RETURN VALUE:", |
152 |
"!REVISION HISTORY:", |
153 |
"!BUGS:", |
154 |
"!SEE ALSO:", |
155 |
"!SYSTEM ROUTINES:", |
156 |
"!FILES USED:", |
157 |
"!REMARKS:", |
158 |
"!TO DO:", |
159 |
"!CALLING SEQUENCE:", |
160 |
"!AUTHOR:", |
161 |
"!CALLED FROM:", |
162 |
"!LOCAL VARIABLES:" ); |
163 |
|
164 |
# Initialize these for clarity |
165 |
# ---------------------------- |
166 |
$intro = 0; # doing introduction? |
167 |
$prologue = 0; # doing prologue? |
168 |
$first = 1; # first prologue? |
169 |
$source = 0; # source code mode? |
170 |
$verb = 0; # verbatim mode? |
171 |
$tpage = 0; # title page? |
172 |
$begdoc = 0; # has \begin{document} been written? |
173 |
|
174 |
# Initial LaTeX stuff |
175 |
# ------------------- |
176 |
&print_notice(); |
177 |
&print_preamble(); # \documentclass, text dimensions, etc. |
178 |
&print_macros(); # short-hand LaTeX macros |
179 |
|
180 |
# Main loop -- for each command-line argument |
181 |
# ------------------------------------------- |
182 |
ARG: |
183 |
foreach $arg (@ARGV) { |
184 |
|
185 |
# Scan for non-global command-line options |
186 |
# ---------------------------------------- |
187 |
$option = &CheckOpts ( $arg, $RegOptions, $SwOptions, "quiet" ) + 1; |
188 |
if ( $option ) { |
189 |
&GetOpts ( $arg, $SwOptions ); |
190 |
&SetOpt ( $arg, $LangOptions ); |
191 |
next ARG; |
192 |
|
193 |
}# end if |
194 |
|
195 |
# Determine the type of code, set corresponding search strings |
196 |
# ------------------------------------------------------------ |
197 |
# if ( $opt_F ) { # FORTRAN |
198 |
$comment_string = '!'; # ------- |
199 |
$boi_string = '!BOI'; |
200 |
$eoi_string = '!EOI'; |
201 |
$bop_string = '!BOP'; |
202 |
$eop_string = '!EOP'; |
203 |
$bopi_string = '!BOPI'; |
204 |
$eopi_string = '!EOPI'; |
205 |
$boc_string = '!BOC'; |
206 |
$eoc_string = '!EOC'; |
207 |
#}# end if |
208 |
|
209 |
if ( $opt_7 ) { # f77 |
210 |
$comment_string = 'C'; # --- |
211 |
$boi_string = 'CBOI'; |
212 |
$eoi_string = 'CEOI'; |
213 |
$bop_string = 'CBOP'; |
214 |
$eop_string = 'CEOP'; |
215 |
$bopi_string = 'CBOPI'; |
216 |
$eopi_string = 'CEOPI'; |
217 |
$boc_string = 'CBOC'; |
218 |
$eoc_string = 'CEOC'; |
219 |
}# end if |
220 |
|
221 |
if ( $opt_A ) { # ADA |
222 |
$comment_string = '--'; # --- |
223 |
$boi_string = '--BOI'; |
224 |
$eoi_string = '--EOI'; |
225 |
$bop_string = '--BOP'; |
226 |
$eop_string = '--EOP'; |
227 |
$bopi_string = '--BOPI'; |
228 |
$eopi_string = '--EOPI'; |
229 |
$boc_string = '--BOC'; |
230 |
$eoc_string = '--EOC'; |
231 |
}# end if |
232 |
|
233 |
if ( $opt_C ) { |
234 |
$comment_string = '//'; # C |
235 |
$boi_string = '//BOI'; # - |
236 |
$eoi_string = '//EOI'; |
237 |
$bop_string = '//BOP'; |
238 |
$eop_string = '//EOP'; |
239 |
$bopi_string = '//BOPI'; |
240 |
$eopi_string = '//EOPI'; |
241 |
$boc_string = '//BOC'; |
242 |
$eoc_string = '//EOC'; |
243 |
}# end if |
244 |
|
245 |
if ( $opt_S ) { # Script |
246 |
$comment_string = '#'; # ------ |
247 |
$boi_string = '#BOI'; |
248 |
$eoi_string = '#EOI'; |
249 |
$bop_string = '#BOP'; |
250 |
$eop_string = '#EOP'; |
251 |
$bopi_string = '#BOPI'; |
252 |
$eopi_string = '#EOPI'; |
253 |
$boc_string = '#BOC'; |
254 |
$eoc_string = '#EOC'; |
255 |
}# end if |
256 |
|
257 |
# Set file name parameters |
258 |
# ------------------------ |
259 |
$InputFile = $arg; |
260 |
@all_path_components = split( /\//, $InputFile ); |
261 |
$FileBaseName = pop ( @all_path_components ); |
262 |
$FileBaseName =~ s/_/\\_/g; |
263 |
if ( $InputFile eq "-" ) {$FileBaseName = "Standard Input";} |
264 |
|
265 |
# Set date |
266 |
# -------- |
267 |
$Date = `date`; |
268 |
|
269 |
# Open current file |
270 |
# ----------------- |
271 |
open ( InputFile, "$InputFile" ) |
272 |
or print STDERR "Unable to open $InputFile: $!"; |
273 |
|
274 |
# Print page header |
275 |
# ----------------- |
276 |
printf "\n\\markboth{Left}{Source File: %s, Date: %s}\n\n", |
277 |
$FileBaseName, $Date; |
278 |
|
279 |
LINE: |
280 |
# Inner loop --- for processing each line of the input file |
281 |
# --------------------------------------------------------- |
282 |
while ( <InputFile> ) { |
283 |
chop; # strip record separator |
284 |
|
285 |
# !PARAMETERS: really mean !ARGUMENTS: |
286 |
# ------------------------------------ |
287 |
# s/!PARAMETERS:/!ARGUMENTS:/g; |
288 |
|
289 |
@Fld = split(' ', $_, 9999); |
290 |
|
291 |
# Straight quote |
292 |
# -------------- |
293 |
if ($Fld[1] eq '!QUOTE:') { |
294 |
for ($i = 2; $i <= $#Fld; $i++) { |
295 |
printf '%s ', $Fld[$i]; |
296 |
}# end for |
297 |
print " "; |
298 |
next LINE; |
299 |
}# end if |
300 |
|
301 |
# Handle optional Title Page and Introduction |
302 |
# ------------------------------------------- |
303 |
if ($Fld[1] eq $boi_string) { |
304 |
print ' '; |
305 |
$intro = 1; |
306 |
next LINE; |
307 |
}# end if |
308 |
|
309 |
if ($Fld[2] eq '!TITLE:') { |
310 |
if ( $intro ) { |
311 |
shift @Fld; |
312 |
shift @Fld; |
313 |
@title = @Fld; |
314 |
$tpage = 1; |
315 |
next LINE; |
316 |
}# end if |
317 |
}# end if |
318 |
|
319 |
if ($Fld[2] eq '!AUTHORS:') { |
320 |
if ( $intro ) { |
321 |
shift @Fld; |
322 |
shift @Fld; |
323 |
@author = @Fld; |
324 |
$tpage = 1; |
325 |
next LINE; |
326 |
}# end if |
327 |
}# end if |
328 |
|
329 |
if ($Fld[2] eq '!AFFILIATION:') { |
330 |
if ( $intro ) { |
331 |
shift @Fld; |
332 |
shift @Fld; |
333 |
@affiliation = @Fld; |
334 |
$tpage = 1; |
335 |
next LINE; |
336 |
}# end if |
337 |
}# end if |
338 |
|
339 |
if ($Fld[2] eq '!DATE:') { |
340 |
if ( $intro ) { |
341 |
shift @Fld; |
342 |
shift @Fld; |
343 |
@date = @Fld; |
344 |
$tpage = 1; |
345 |
next LINE; |
346 |
}# end if |
347 |
}# end if |
348 |
|
349 |
if ($Fld[2] eq '!INTRODUCTION:') { |
350 |
if ( $intro ) { |
351 |
&do_beg(); |
352 |
print ' '; |
353 |
print '%..............................................'; |
354 |
shift @Fld; |
355 |
shift @Fld; |
356 |
print "\\section{@Fld}"; |
357 |
next LINE; |
358 |
}# end if |
359 |
}# end if |
360 |
|
361 |
|
362 |
# End of introduction |
363 |
# ------------------- |
364 |
if ($Fld[1] eq $eoi_string) { |
365 |
print ' '; |
366 |
print '%/////////////////////////////////////////////////////////////'; |
367 |
print "\\newpage"; |
368 |
$intro = 0; |
369 |
next LINE; |
370 |
}# end if |
371 |
|
372 |
# Beginning of prologue |
373 |
# --------------------- |
374 |
if ($Fld[1] eq $bop_string) { |
375 |
if ( $source ) { &do_eoc(); } |
376 |
print ' '; |
377 |
print '%/////////////////////////////////////////////////////////////'; |
378 |
&do_beg(); |
379 |
if ($first == 0) { |
380 |
### print "\\newpage"; |
381 |
print " "; |
382 |
print "\\mbox{}\\hrulefill\\ "; |
383 |
print " ";} |
384 |
else { |
385 |
unless($opt_b){print "\\section{Routine/Function Prologues} \\label{app:ProLogues}";} |
386 |
}# end if |
387 |
|
388 |
$first = 0; |
389 |
$prologue = 1; |
390 |
$verb = 0; |
391 |
$source = 0; |
392 |
&set_missing(); # no required keyword yet |
393 |
next LINE; |
394 |
}# end if |
395 |
|
396 |
# Beginning of internal prologue |
397 |
# ------------------------------ |
398 |
if ($Fld[1] eq $bopi_string) { |
399 |
if ($opt_i) {$prologue = 0;} |
400 |
else { |
401 |
if ($source) { &do_eoc(); } |
402 |
print ' '; |
403 |
print '%/////////////////////////////////////////////////////////////'; |
404 |
&do_beg(); |
405 |
if ($first ==0) { |
406 |
### print "\\newpage"; |
407 |
print " "; |
408 |
print "\\mbox{}\\hrulefill\\"; |
409 |
print " ";} |
410 |
else { |
411 |
unless($opt_b){print "\\section{Routine/Function Prologues} \\label{app:ProLogues}";} |
412 |
}# endif |
413 |
$first = 0; |
414 |
$prologue = 1; |
415 |
$verb = 0; |
416 |
$source = 0; |
417 |
&set_missing(); # no required keyword yet |
418 |
next LINE; |
419 |
}# endelse |
420 |
}# endif |
421 |
|
422 |
# A new subroutine/function |
423 |
# ------------------------- |
424 |
if ($Fld[2] eq '!ROUTINE:' ) { |
425 |
if ($prologue) { |
426 |
shift @Fld; |
427 |
shift @Fld; |
428 |
$_ = join(' ', @Fld); |
429 |
$name_is = $_; |
430 |
s/_/\\_/g; # Replace "_" with "\_" |
431 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
432 |
unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} |
433 |
else {printf "\\subsubsection{%s }\n\n", $_;} |
434 |
$have_name = 1; |
435 |
$not_first = 1; |
436 |
next LINE; |
437 |
}# end if |
438 |
}# end if |
439 |
|
440 |
# A new Module |
441 |
# ------------ |
442 |
if ($Fld[2] eq '!MODULE:' ) { |
443 |
if ($prologue) { |
444 |
shift @Fld; |
445 |
shift @Fld; |
446 |
$_ = join(' ', @Fld); |
447 |
$name_is = $_; |
448 |
s/_/\\_/g; # Replace "_" with "\_" |
449 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
450 |
unless($opt_f) {printf "\\subsection{Fortran: Module Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;} |
451 |
else {printf "\\subsection{Fortran: Module Interface %s }\n\n", $_;} |
452 |
$have_name = 1; |
453 |
$have_intf = 1; # fake it, it does not need one. |
454 |
$not_first = 1; |
455 |
next LINE; |
456 |
}# end if |
457 |
}# end if |
458 |
|
459 |
# A new include file |
460 |
# ------------------ |
461 |
if ($Fld[2] eq '!INCLUDE:' ) { |
462 |
if ($prologue) { |
463 |
shift @Fld; |
464 |
shift @Fld; |
465 |
$_ = join(' ', @Fld); |
466 |
$name_is = $_; |
467 |
s/_/\\_/g; # Replace "_" with "\_" |
468 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
469 |
unless($opt_f) {printf "\\subsubsection{Include File %s (Source File: %s)}\n\n", $_, $FileBaseName;} |
470 |
else {printf "\\subsubsection{Include File %s }\n\n", $_;} |
471 |
$have_name = 1; |
472 |
$have_intf = 1; # fake it, it does not need one. |
473 |
$not_first = 1; |
474 |
next LINE; |
475 |
}# end if |
476 |
}# end if |
477 |
|
478 |
# A new INTERNAL subroutine/function |
479 |
# ---------------------------------- |
480 |
if ($Fld[2] eq '!IROUTINE:') { # Internal routine |
481 |
if ($prologue) { |
482 |
shift @Fld; |
483 |
shift @Fld; |
484 |
$_ = join(' ', @Fld); |
485 |
$name_is = $_; |
486 |
s/_/\\_/g; # Replace "_" with "\_" |
487 |
@words = split " ", $_; |
488 |
printf "\\subsubsection [$words[1]] {$_}\n\n"; |
489 |
$have_name = 1; |
490 |
next LINE; |
491 |
}# end if |
492 |
}# end if |
493 |
|
494 |
# A new CLASS |
495 |
# ------------ |
496 |
if ($Fld[2] eq '!CLASS:' ) { |
497 |
if ($prologue) { |
498 |
shift @Fld; |
499 |
shift @Fld; |
500 |
$_ = join(' ', @Fld); |
501 |
$name_is = $_; |
502 |
s/_/\\_/g; # Replace "_" with "\_" |
503 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
504 |
unless($opt_f) {printf "\\subsection{C++: Class Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;} |
505 |
else {printf "\\subsection{C++: Class Interface %s }\n\n", $_;} |
506 |
$have_name = 1; |
507 |
$have_intf = 1; # fake it, it does not need one. |
508 |
$not_first = 1; |
509 |
next LINE; |
510 |
}# end if |
511 |
}# end if |
512 |
|
513 |
# A new Method |
514 |
# ------------------------- |
515 |
if ($Fld[2] eq '!METHOD:' ) { |
516 |
if ($prologue) { |
517 |
shift @Fld; |
518 |
shift @Fld; |
519 |
$_ = join(' ', @Fld); |
520 |
$name_is = $_; |
521 |
s/_/\\_/g; # Replace "_" with "\_" |
522 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
523 |
unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} |
524 |
else {printf "\\subsubsection{%s }\n\n", $_;} |
525 |
$have_name = 1; |
526 |
$not_first = 1; |
527 |
next LINE; |
528 |
}# end if |
529 |
}# end if |
530 |
|
531 |
# A new function |
532 |
# ------------------------- |
533 |
if ($Fld[2] eq '!FUNCTION:' ) { |
534 |
if ($prologue) { |
535 |
shift @Fld; |
536 |
shift @Fld; |
537 |
$_ = join(' ', @Fld); |
538 |
$name_is = $_; |
539 |
s/_/\\_/g; # Replace "_" with "\_" |
540 |
if ( $opt_n && $not_first ) { printf "\\newpage\n"; } |
541 |
unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} |
542 |
else {printf "\\subsubsection{%s }\n\n", $_;} |
543 |
$have_name = 1; |
544 |
$not_first = 1; |
545 |
next LINE; |
546 |
}# end if |
547 |
}# end if |
548 |
|
549 |
# Description: what follows will be regular LaTeX (no verbatim) |
550 |
# ------------------------------------------------------------- |
551 |
if (/!DESCRIPTION:/) { |
552 |
if ($prologue) { |
553 |
if ($verb) { |
554 |
printf "\\end{verbatim}"; |
555 |
printf "\n{\\sf DESCRIPTION:\\\\ }\n\n"; |
556 |
$verb = 0; } |
557 |
else { # probably never occurs |
558 |
}# end if |
559 |
if ($opt_x) { |
560 |
printf "\\begin{verbatim} "; |
561 |
$verb = 1; |
562 |
$first_verb = 1; } |
563 |
else { |
564 |
for ($i = 3; $i <= $#Fld; $i++) { |
565 |
printf '%s ', $Fld[$i]; |
566 |
}# end for |
567 |
}# end if |
568 |
### print " "; |
569 |
$have_desc = 1; |
570 |
next LINE; |
571 |
}# end if |
572 |
}# end if |
573 |
|
574 |
# Handle optional keywords (these will appear as verbatim) |
575 |
# -------------------------------------------------------- |
576 |
if ($prologue) { |
577 |
KEY: foreach $key ( @keys ) { |
578 |
if ( /$key/ ) { |
579 |
if ($verb) { |
580 |
printf "\\end{verbatim}"; |
581 |
$verb = 0; } |
582 |
else { |
583 |
printf "\n\\bigskip"; |
584 |
}# end if |
585 |
$k = sprintf('%s', $key); |
586 |
$ln = length($k); |
587 |
###printf "\\subsubsection*{%s}\n", substr($k, 2, $ln - 1); |
588 |
###printf "{\\Large \\em %s}\n", ucfirst lc substr($k, 2, $ln - 1); |
589 |
$_ = $key; |
590 |
if( /USES/ || /INPUT/ || /OUTPUT/ || /PARAMETERS/ || |
591 |
/VALUE/ || /ARGUMENTS/ ) { |
592 |
printf "{\\em %s}\n", substr($k, 2, $ln - 1); } # italics |
593 |
else { |
594 |
printf "{\\sf %s}\n", substr($k, 2, $ln - 1); # san serif |
595 |
}# end if |
596 |
|
597 |
printf "\\begin{verbatim} "; |
598 |
$verb = 1; |
599 |
$first_verb = 1; |
600 |
if ( $key eq "!INTERFACE:" ) { $have_intf = 1; } |
601 |
if ( $key eq "!CALLING SEQUENCE:" ) { $have_intf = 1; } |
602 |
if ( $key eq "!REVISION HISTORY:" ) { $have_hist = 1; } |
603 |
next LINE; |
604 |
}# end if |
605 |
}# end foreach |
606 |
}# end if |
607 |
|
608 |
# End of prologue |
609 |
# --------------- |
610 |
if ($Fld[1] eq $eop_string) { |
611 |
if ($verb) { |
612 |
print "\\end{verbatim}"; |
613 |
$verb = 0; |
614 |
}# end if |
615 |
$prologue = 0; |
616 |
# &check_if_all_there(); # check if all required keywords are there. |
617 |
if ( $opt_l ) { |
618 |
$Fld[1] = $boc_string;} |
619 |
else { next LINE; } |
620 |
}# end if |
621 |
|
622 |
unless ( $opt_s ) { |
623 |
|
624 |
# End of Internal Prologue |
625 |
# ------------------------ |
626 |
|
627 |
if ($Fld[1] eq $eopi_string) { |
628 |
if ($verb) { |
629 |
print "\\end{verbatim}"; |
630 |
$verb = 0; |
631 |
}# endif |
632 |
$prologue = 0; |
633 |
# &check_if_all_there(); # check if all required keywords are there. |
634 |
if ($opt_l) { |
635 |
$Fld[1] = $boc_string;} |
636 |
else { next LINE; } |
637 |
}# endif |
638 |
|
639 |
# |
640 |
# Beginning of source code section |
641 |
# -------------------------------- |
642 |
if ($Fld[1] eq $boc_string) { |
643 |
print ' '; |
644 |
print '%/////////////////////////////////////////////////////////////'; |
645 |
$first = 0; |
646 |
$prologue = 0; |
647 |
$source = 1; |
648 |
### printf "\\subsubsection*{CONTENTS:}\n\n", $Fld[3]; |
649 |
printf "{\\sf CONTENTS:}"; |
650 |
printf "\n \\begin{verbatim}\n"; |
651 |
$verb = 1; |
652 |
next LINE; |
653 |
}# end if |
654 |
|
655 |
# End of source code |
656 |
# ------------------ |
657 |
if ($Fld[1] eq $eoc_string) { |
658 |
&do_eoc(); |
659 |
$prologue = 0; |
660 |
next LINE; |
661 |
}# end if |
662 |
}# end unless |
663 |
|
664 |
# Prologue or Introduction, print regular line (except for !) |
665 |
# ----------------------------------------------------------- |
666 |
if ($prologue||$intro) { |
667 |
if ( $verb && $#Fld == 1 && ( $Fld[1] eq $comment_string ) ) { |
668 |
next LINE; # to eliminate excessive blanks |
669 |
}# end if |
670 |
if ( $Fld[2] eq "\\ev" ) { # special handling |
671 |
$_ = $comment_string . " \\end{verbatim}"; |
672 |
}# end if |
673 |
s/^$comment_string/ /; # replace comment string with blank |
674 |
# $line = sprintf('%s', $_); # not necessary -- comment str is absent |
675 |
# $ln = length($line); # not necessary -- comment str is absent |
676 |
unless ( $first_verb ) { printf "\n "; } |
677 |
printf '%s', $_; |
678 |
# printf '%s', substr($line, 1, $ln - 1); # comment str is absent |
679 |
$first_verb = 0; |
680 |
next LINE; |
681 |
}# end if |
682 |
|
683 |
# Source code: print the full line |
684 |
# -------------------------------- |
685 |
if ($source) { |
686 |
print $_; |
687 |
next LINE; |
688 |
}# end if |
689 |
|
690 |
}# end inner loop for processing each line of the input file |
691 |
# --------------------------------------------------------- |
692 |
|
693 |
}# end main loop for each command-line argument |
694 |
# -------------------------------------------- |
695 |
print $_; |
696 |
if ( $source ) { &do_eoc(); } |
697 |
print '%...............................................................'; |
698 |
|
699 |
# see comment above where these are originally set. |
700 |
#print "\\setlength{\\parskip}{\\oldparskip}"; |
701 |
#print "\\setlength{\\parindent}{\\oldparindent}"; |
702 |
#print "\\setlength{\\baselineskip}{\\oldbaselineskip}"; |
703 |
|
704 |
unless ( $opt_b ) { |
705 |
print "\\end{document}"; |
706 |
}#end unless |
707 |
|
708 |
|
709 |
#---------------------------------------------------------------------- |
710 |
|
711 |
sub CheckOpts |
712 |
# Checks options against a given list. Outputs error message |
713 |
# for any invalid option. |
714 |
# |
715 |
# Usage: |
716 |
# $rc = &CheckOpts ( options, valid_reg_options, |
717 |
# valid_sw_options, |
718 |
# quiet_mode ) |
719 |
# |
720 |
# character: options - options to be checked. (e.g. -df+x) The |
721 |
# list must begin with a positive or |
722 |
# negative sign. If no sign appears at the |
723 |
# beginning or by itself, then the argument |
724 |
# is not recognized as a list of options. |
725 |
# character: valid_reg_options - list of valid regular options. |
726 |
# (i.e. options that are associated only |
727 |
# eith negative sign.) |
728 |
# character: valid_sw_options - list of valid switch options. |
729 |
# (i.e. options that can be associated with |
730 |
# either a positive or negative sign. |
731 |
# logical: quiet mode (optional) If true then print no error |
732 |
# messages. |
733 |
# integer: rc - return code |
734 |
# = -1 if the arguement, options, is |
735 |
# not recognized as a list of options |
736 |
# = 0 if all options are valid. |
737 |
# > 0 for the number of invalid options. |
738 |
# |
739 |
{ local($options, |
740 |
$valid_reg_options, |
741 |
$valid_sw_options, |
742 |
$quiet_mode ) = @_; |
743 |
|
744 |
if ( $options eq "+" || |
745 |
$options eq "-" ) {return -1} |
746 |
|
747 |
local(@Options) = split( / */, $options ); |
748 |
if ( $Options[ $[ ] ne "-" && |
749 |
$Options[ $[ ] ne "+" ) {return -1;} |
750 |
|
751 |
local($option, $option_sign, $valid_list, $pos); |
752 |
local($errs) = 0; |
753 |
foreach $option ( @Options ) { |
754 |
if ( $option eq "-" || |
755 |
$option eq "+" ) {$option_sign = $option;} |
756 |
else { |
757 |
if ( $option_sign eq "-" ) |
758 |
{ $valid_list = $valid_reg_options |
759 |
. $valid_sw_options; } |
760 |
else |
761 |
{ $valid_list = $valid_sw_options; } |
762 |
$pos = index ($valid_list,$option); |
763 |
if ( $pos < $[ && |
764 |
$quiet_mode ) { |
765 |
$errs++; |
766 |
print STDERR "Invalid option: $option_sign$option \n"; |
767 |
|
768 |
}# end if |
769 |
}# end if |
770 |
}# end foreach |
771 |
return $errs; |
772 |
|
773 |
}#end sub GetOpts |
774 |
|
775 |
sub GetOpts |
776 |
# Gets options. If an option is valid, then opt_[option] is |
777 |
# set to 0 or 1 as a side effect if the option is preceeded by |
778 |
# a positive or negative sign. |
779 |
# |
780 |
# Usage: |
781 |
# $rc = &GetOpts ( options, valid_options ) |
782 |
# |
783 |
# character: options - options to be checked. (e.g. -df+x) The |
784 |
# list must begin with a positive or |
785 |
# negative sign. If no sign appears at the |
786 |
# beginning or by itself, then the argument |
787 |
# is not recognized as a list of options. |
788 |
# character: valid_options - list of valid options (e.g. dfhx) |
789 |
# integer: rc - return code |
790 |
# = -1 if the arguement, options, is |
791 |
# not recognized as a list of options. |
792 |
# = 0 otherwise |
793 |
# |
794 |
{ local($options,$valid_options) = @_; |
795 |
|
796 |
if ( $options eq "+" || |
797 |
$options eq "-" ) {return -1} |
798 |
|
799 |
local(@Options) = split( / */, $options ); |
800 |
if ( $Options[ $[ ] ne "-" && |
801 |
$Options[ $[ ] ne "+" ) {return -1;} |
802 |
|
803 |
local($option, $option_sign); |
804 |
|
805 |
foreach $option ( @Options ) { |
806 |
|
807 |
if ( $option eq "-" || |
808 |
$option eq "+" ) { |
809 |
$option_sign = $option; } |
810 |
|
811 |
else { |
812 |
|
813 |
if ( index ($valid_options,$option) >= $[ ) { |
814 |
if ( $option_sign eq "-" ) {${"opt_$option"} = 1;} |
815 |
if ( $option_sign eq "+" ) {${"opt_$option"} = 0;}; |
816 |
|
817 |
}# end if |
818 |
}# end if |
819 |
}# end foreach |
820 |
|
821 |
return 0; |
822 |
}#end sub GetOpts |
823 |
|
824 |
sub SetOpt |
825 |
# Sets option flags. For the last input option that is in a |
826 |
# list, the flag opt_[option] is set to 1 as a side effect. |
827 |
# For all other options in the list, opt_[option] is set to 0. |
828 |
# |
829 |
# Usage: |
830 |
# $rc = &SetOpt ( options, valid_options ) |
831 |
# |
832 |
# character: options - options to be checked. (e.g. -df+x) The |
833 |
# list must begin with a positive or |
834 |
# negative sign. If no sign appears at the |
835 |
# beginning or by itself, then the argument |
836 |
# is not recognized as a list of options. |
837 |
# character: valid_options - list of valid options (e.g. def ) |
838 |
# integer: rc - return code |
839 |
# = -1 if the arguement, options, is |
840 |
# not recognized as a list of options. |
841 |
# = 0 otherwise |
842 |
# Note: For the examples provided for the input arguments, |
843 |
# $opt_d = 0, $opt_e = 0, and $opt_f = 1, since the |
844 |
# input option, -f, was the last in the argument, |
845 |
# option. |
846 |
# |
847 |
{ local($options,$valid_options) = @_; |
848 |
|
849 |
if ( $options eq "+" || |
850 |
$options eq "-" ) {return -1} |
851 |
|
852 |
local(@Options) = split( / */, $options ); |
853 |
local(@ValidOptions) = split( / */, $valid_options ); |
854 |
if ( $Options[ $[ ] ne "-" && |
855 |
$Options[ $[ ] ne "+" ) {return -1;} |
856 |
|
857 |
local($option, $option_sign); |
858 |
|
859 |
foreach $option ( @Options ) { |
860 |
if ( $option ne "-" && |
861 |
$option ne "+" ) { |
862 |
|
863 |
if ( index ($valid_options,$option) >= $[ ) { |
864 |
foreach $valid_option (@ValidOptions ) { |
865 |
${"opt_$valid_option"} = 0; |
866 |
|
867 |
}# end foreach |
868 |
${"opt_$option"} = 1; |
869 |
}# end if |
870 |
}# end if |
871 |
}# end foreach |
872 |
|
873 |
return 0; |
874 |
}#end sub SetOpt |
875 |
|
876 |
sub print_help { |
877 |
|
878 |
print "Usage: protex [-hbACFS] [+-nlsxf] [src_file(s)]"; |
879 |
print " "; |
880 |
print " Options:"; |
881 |
print " -h Help mode: list command line options"; |
882 |
print " -b Bare mode, meaning no preamble, etc."; |
883 |
print " +-n New Page for each subsection (wastes paper)"; |
884 |
print " +-l Listing mode, default is prologues only"; |
885 |
print " +-s Shut-up mode, i.e., ignore any code from BOC to EOC"; |
886 |
print " +-x No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode"; |
887 |
print " +-f No source file info"; |
888 |
print " -A Ada code"; |
889 |
print " -C C++ code"; |
890 |
print " -F F90 code"; |
891 |
print " -S Shell script"; |
892 |
print " "; |
893 |
print " The options can appear in any order. The options, -h and -b,"; |
894 |
print " affect the input from all files listed on command-line input."; |
895 |
print " Each of the remaining options effects only the input from the"; |
896 |
print " files listed after the option and prior to any overriding"; |
897 |
print " option. The plus sign turns off the option."; |
898 |
}# end sub print_help |
899 |
|
900 |
sub print_notice { |
901 |
|
902 |
print "% **** IMPORTANT NOTICE *****" ; |
903 |
print "% This LaTeX file has been automatically produced by ProTeX v. 1.1"; |
904 |
print "% Any changes made to this file will likely be lost next time"; |
905 |
print "% this file is regenerated from its source. Send questions "; |
906 |
print "% to Arlindo da Silva, dasilva\@gsfc.nasa.gov"; |
907 |
print " "; |
908 |
|
909 |
}# sub print_notice |
910 |
|
911 |
sub print_preamble { |
912 |
|
913 |
unless ( $opt_b ) { |
914 |
print "%------------------------ PREAMBLE --------------------------"; |
915 |
print "\\documentclass[11pt]{article}"; |
916 |
print "\\usepackage{amsmath}"; |
917 |
print "\\usepackage{epsfig}"; |
918 |
print "\\usepackage{hangcaption}"; |
919 |
print "\\textheight 9in"; |
920 |
print "\\topmargin 0pt"; |
921 |
print "\\headsep 1cm"; |
922 |
print "\\headheight 0pt"; |
923 |
print "\\textwidth 6in"; |
924 |
print "\\oddsidemargin 0in"; |
925 |
print "\\evensidemargin 0in"; |
926 |
print "\\marginparpush 0pt"; |
927 |
print "\\pagestyle{myheadings}"; |
928 |
print "\\markboth{}{}"; |
929 |
print "%-------------------------------------------------------------"; |
930 |
}# end unless |
931 |
|
932 |
# in your main document before you include any protex-generated files |
933 |
# for the first time, if you define these three variables as length |
934 |
# settings (like this:) |
935 |
# \newlength{\oldparskip} |
936 |
# \newlength{\oldparindent} |
937 |
# \newlength{\oldbaselineskip} |
938 |
# then 1) comment in all the lines below, and 2) find the 3 reset lines |
939 |
# further down and comment in them as well. |
940 |
# then protex will override the paragraph and skip settings during |
941 |
# the source sections, but will restore the original document settings |
942 |
# at the end. if someone can figure out how to check to see if a |
943 |
# latex variable exists, and do a conditional section, we could make |
944 |
# this fully self-contained. |
945 |
# nsc feb 2003 |
946 |
|
947 |
#print "\\setlength{\\oldparskip}{\\parskip}"; |
948 |
print "\\setlength{\\parskip}{0pt}"; |
949 |
#print "\\setlength{\\oldparindent}{\\parindent}"; |
950 |
print "\\setlength{\\parindent}{0pt}"; |
951 |
#print "\\setlength{\\oldbaselineskip}{\\baselineskip}"; |
952 |
print "\\setlength{\\baselineskip}{11pt}"; |
953 |
|
954 |
}# end sub print_preamble |
955 |
|
956 |
sub print_macros { |
957 |
|
958 |
print " "; |
959 |
print "%--------------------- SHORT-HAND MACROS ----------------------"; |
960 |
print "\\def\\bv{\\begin{verbatim}}"; |
961 |
print "\\def\\ev\{\\end\{verbatim}}"; |
962 |
print "\\def\\be{\\begin{equation}}"; |
963 |
print "\\def\\ee{\\end{equation}}"; |
964 |
print "\\def\\bea{\\begin{eqnarray}}"; |
965 |
print "\\def\\eea{\\end{eqnarray}}"; |
966 |
print "\\def\\bi{\\begin{itemize}}"; |
967 |
print "\\def\\ei{\\end{itemize}}"; |
968 |
print "\\def\\bn{\\begin{enumerate}}"; |
969 |
print "\\def\\en{\\end{enumerate}}"; |
970 |
print "\\def\\bd{\\begin{description}}"; |
971 |
print "\\def\\ed{\\end{description}}"; |
972 |
print "\\def\\({\\left (}"; |
973 |
print "\\def\\){\\right )}"; |
974 |
print "\\def\\[{\\left [}"; |
975 |
print "\\def\\]{\\right ]}"; |
976 |
print "\\def\\<{\\left \\langle}"; |
977 |
print "\\def\\>{\\right \\rangle}"; |
978 |
print "\\def\\cI{{\\cal I}}"; |
979 |
print "\\def\\diag{\\mathop{\\rm diag}}"; |
980 |
print "\\def\\tr{\\mathop{\\rm tr}}"; |
981 |
print "%-------------------------------------------------------------"; |
982 |
|
983 |
}# end sub print_macros |
984 |
|
985 |
sub do_beg { |
986 |
unless ( $opt_b ) { |
987 |
if ( $begdoc == 0 ) { |
988 |
if ( $tpage ) { |
989 |
print "\\title{@title}"; |
990 |
print "\\author{{\\sc @author}\\\\ {\\em @affiliation}}"; |
991 |
print "\\date{@date}"; |
992 |
} |
993 |
print "\\begin{document}"; |
994 |
if ( $tpage ) { |
995 |
print "\\maketitle"; |
996 |
} |
997 |
print "\\tableofcontents"; |
998 |
print "\\newpage"; |
999 |
$begdoc = 1; |
1000 |
} |
1001 |
} |
1002 |
}# end sub do_beg |
1003 |
|
1004 |
sub do_eoc { |
1005 |
print ' '; |
1006 |
if ($verb) { |
1007 |
print "\\end{verbatim}"; |
1008 |
$verb = 0; |
1009 |
} |
1010 |
$source = 0; |
1011 |
}# end sub do_eoc |
1012 |
|
1013 |
sub set_missing { |
1014 |
|
1015 |
$have_name = 0; # have routine name? |
1016 |
$have_desc = 0; # have description? |
1017 |
$have_intf = 0; # have interface? |
1018 |
$have_hist = 0; # have revision history? |
1019 |
$name_is = "UNKNOWN"; |
1020 |
|
1021 |
}# end sub set_missing |
1022 |
|
1023 |
|
1024 |
sub check_if_all_there { |
1025 |
|
1026 |
$have_name || |
1027 |
die "ProTeX: invalid prologue, missing !ROUTINE: or !IROUTINE: in <$name_is>"; |
1028 |
|
1029 |
$have_desc || |
1030 |
die "ProTeX: invalid prologue, missing !DESCRIPTION: in <$name_is>"; |
1031 |
|
1032 |
$have_intf || |
1033 |
die "ProTeX: invalid prologue, missing !INTERFACE: in <$name_is>"; |
1034 |
|
1035 |
$have_hist || |
1036 |
die "ProTeX: invalid prologue, missing !REVISION HISTORY: in <$name_is>"; |
1037 |
|
1038 |
}# end sub check_if_all_there |