Home
Nuweb A Simple Literate Programming Tool
Contents
1. c2pstr char msg ParamText msg NULL NULL NULL CenterAlert kAlertID va_end args o Macro defined by scraps 12bc 13 14a Macro referenced in scrap 9e 2 2 3 File Names We expect at least one file name While a missing file name might be ignored without causing any problems we take the opportunity to report the usage convention Process the remaining arguments file names 14b t if arg gt argc 1 error stderr 4s expected a file name Usage is s cnotv file name n command_name command_name exit 1 y do Handle the file name in argv arg 15a arg while arg lt argc JO Macro referenced in scrap 9e 14 The code to handle a particular file name is rather more tedious than the actual processing of the file A file name may be an arbitrarily complicated path name with an optional extension If no extension is present we add w as a default The extended path name will be kept in a local variable source name The resulting tex file will be written in the current directory its name will be kept in the variable tex name Handle the file name in argv arg 15a char source_name 256 char tex name 256 char aux name 256 Build source name and tex name 15b Process a file 16a YO Macro referenced in scrap 14b I bump the pointer p through all the characters in argv arg copying all the characters into source name via the pointer a At
2. info 7b 16c 19a 30b 37c init_scraps 16c 36d 36e isgraph 6b 35a 52b 56 islower 6b 51a isspace 6b 22a 40a 52b 53 54 55c isupper 6b 51a LESS 48a 49a 50 macro_names 16c 18c 26a 42b 47b 47c 55b main 9e malloc 6b 65b Manager 38b 38cde 41c 42a 43b 62 63b max_depth 58d 59a 60 61 Move Node 58c 58e 60 61 Name 17c 18a 21ab 25b 26b 28b 30a 40ab 42a 45a 47a 47bcd 49a 50 51b 52ab 54 56 57b 58a 59b 62 63b name_add 40a 47d 51b 52b 68 Name Node 58a 58b 60 61 62 number flag lla 11b 12ac 46a op char 63a 63b output flag lla 11b 12ac 16a pass1 16ab 16c 24c pop 4lc 42ab 43b 44d 62 pop scrap name 42a 45a PREFIX 48a 49a 50 prefix_add 42b 47d 49a 55b print_scrap_numbers 18e 22bc 23a 23b 27ac push 38c 38d 39bc 41a pushs 38d 39c 41a putc 6b 19b 20 24abc 25b 26c 27abc 29a 37a 43b 44bcd reject_match 59a 62 63b remove 6b 30b 31 reverse 57b 57c reverse_lists 18c 47d 57b robs_strcmp 51a 51b root 49a 51b 52a 58d 59a 60 61 62 save_string 34b 39a 47d 48b 49a 52a SCRAP 36c 36e 39a ScrapEntry 36b 36ce 39a scraps 19b 2labc 22bc 23ab 36c 36e 38e 39abc 40a 41b 46ab 59a 62 scrap_array 36c 37a 39ab 43b 44a 46ab 62 Scrap_Node 18b 23b 25c 27abc 29a 40a 41b 43a 46c 47a 57bc 62 search 16c 58f
3. mbox verb break mbox verb FAN mbox verb 0 Diamond end list vspace 1ex footnotesize addtolength baselineskip 1ex begin list setlength itemsep parsep setlength itemindent leftmargin item Macro referenced in scrap 17b end list end minipage 4ex end flushleft The flushleft environment is used to avoid IATEX warnings about underful lines The minipage environment 20 is used to avoid page breaks in the middle of scraps The verb command allows arbitrary characters to be printed however note the special handling of the case in the switch statement Macro and file definitions are formatted nearly identically I ve factored the common parts out into separate scraps Write output file definition 21a Name name collect file name Begin the scrap environment 21c fprintf tex file verb s footnotesize name gt spelling write single scrap ref tex file scraps fputs equiv n tex file Fill in the middle of the scrap environment 21d Write file defs 22b Finish the scrap environment 22a FO Macro referenced in scrap 20 I don t format a macro name at all specially figuring the programmer might want to use italics or bold face in the midst of the name Write macro definition 21b Name name collect_macro_name Begin the scrap environment 21c fprintf tex_file langle s footnotesize name gt spelling
4. write_single_scrap_ref tex_file scraps fputs rangle equiv n tex file Fill in the middle of the scrap environment 21d Write macro defs 22c Write macro refs 23a Finish the scrap environment 22a FO Macro referenced in scrap 20 Begin the scrap environment 21c fputs begin flushleft small tex_file if big_definition fputs n begin minipage linewidth tex file fprintf tex file label scrap d n scraps jo Macro referenced in scraps 21ab The interesting things here are the inserted at the end of each scrap and the various spacing commands The diamond helps to clearly indicate the end of a scrap The spacing commands were derived empirically they may be adjusted to taste Fill in the middle of the scrap environment 21d fputs vspace 1ex n begin listH H item n tex file copy scrap tex file fputs Diamond n end list n tex file JO Macro referenced in scraps 21ab 21 We ve got one last spacing command controlling the amount of white space after a scrap Note also the whitespace eater I use it to remove any blank lines that appear after a scrap in the source file This way text following a scrap will not be indented Again this is a matter of personal taste Finish the scrap environment 22a if big_definition fputs end minipage 4ex n tex file fputs end flushleft n tex file do c source get 0 while
5. indent write scraps file name gt defs global indent indent indent chars debug flag tab flag indent flag indent global indent name gt mark FALSE else if tex_flag warning stderr 4s macro never defined lt s gt n command_name name gt spelling JO Macro referenced in scrap 44d 3 2 1 Collecting Page Numbers Function prototypes 45b extern void collect numbers o Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a 45 scraps c 46a void collect numbers aux name char x aux name if number_flag int i for i 1 i lt scraps i scrap_array i page i else FILE aux_file fopen aux name r already_warned FALSE if aux_file char aux_line 500 while fgets aux_line 500 aux_file int scrap number int page number char dummy 50 if 3 sscanf aux line newlabel scrap d 7 H dF 4scrap number dummy page number if scrap number scraps scrap_array scrap_number page page number else Warn only once about needing to rerun after Latex 37c fclose aux file Add letters to scraps with duplicate page numbers 46b y File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab Add letters to scraps with duplicate page numbers 46b int scrap for scrap 2 scrap lt scraps scrap if scrap_array scrap 1 page scr
6. 59a size_t 6b 64c 65b Slab 36a 36b 38bc 39a 41c SLAB_SIZE 36a 38c 41c 63b source file 19a 32d 33b 34ab 35abc source get 17ab 19b 20 22a 24ac 25ad 26a 28a 32a 33b 34b 35b 39bc 40ab 52b 53 54 55ac 56 57a source line 17b 32b 32c 33b 34ab 35abc 39ac 40a 49b 52b 53 54 55b 56 57a source name 13 15ab 16a 17b 32b 32c 34ab 35abc 39ac 40a 49b 52b 53 54 55abc 56 57a source open 16c 19a 32a 35c source peek 32d 33b 34ab 35bc stack 33a 34b 35b stderr 6b 12a 14b 16c 17b 19a 23a 25b 30b 34ab 35ac 37c 39bc 40a 42ab 43b 44cd 45a 49b 52b 53 54 55abc 56 57a strlen 6b 41a 48ab 63b sym_char 63a 63b tempnam 6b 30b tex flag lla 11b 12ac 16ac 45a toupper 6b 51a TRUE 7a llab 12a 20 23b 25d 27b 29a 34a 37bc 45a 50 52a 53 63ab user_names 16c 18c 28a 40a 47b 47c 59a verbose flag lla 11b 12ac 16c 19a 30b warning 7b 17b 23a 25b 44d 45a 49b 53 write_files 16a 29b 30a write_scraps 30b 36d 43a 45a write scrap ref 23b 27b 29a 36d 37a 37b write_single_scrap_ref 21ab 23a 25c 27ac 29a 36d 3Tb write_tex 16a 18d 19a 69 Bibliography o N o ct A co 9 Alfred V Aho and Margaret J Corasick Efficient string matching An aid to bibliographic search Communications of the ACM 18 6 333 340 June 1975 David R Hanson Fast allocation and d
7. Interpret command line arguments lle Process the remaining arguments file names 14b exit 0 y endif o File defined by scraps 7c 9e 2 2 1 Command Line Arguments There are five possible command line arguments t Suppresses generation of the tex file o Suppresses generation of the output files c Forces output files to overwrite old files of the same name without comparing for equality first v The verbose flag Forces output of progress reports n Forces sequential numbering of scraps instead of page numbers 10 Global flags are declared for each of the arguments Global variable declarations 11a extern int tex_flag if FALSE don t emit the tex file extern int output_flag if FALSE don t emit the output files extern int compare flag if FALSE overwrite without comparison extern int verbose_flag if TRUE write progress information extern int number flag if TRUE use a sequential numbering scheme o Macro defined by scraps llac 32b 37d 47b Macro referenced in scrap 6a The flags are all initialized for correct default behavior Global variable definitions 11b int tex flag TRUE int output flag TRUE int compare flag TRUE int verbose flag FALSE int number flag FALSE o Macro defined by scraps 11bd 32c 38a 47c Macro referenced in scrap 9d We save the invocation name of the command in a global variable command_name for use in erro
8. Macro referenced in scrap 59a 61 3 4 2 Searching the Scraps Search scraps 62 for i 1 i lt scraps i char c Manager reader Goto_Node state NULL reader prev NULL reader scrap scrap array i slab reader index 0 c pop amp reader while c 1 while state amp amp goto_lookup c state state state gt fail if state state goto_lookup c state else state root c c pop amp reader if state amp amp state gt output Name_Node p state gt output do Name name p gt name if reject_match name c amp reader amp amp name gt uses name gt uses gt scrap i 1 Scrap Node new use Scrap Node arena_getmem sizeof Scrap_Node new_use gt scrap i new_use gt next name gt uses name gt uses new use p p gt next while p JO Macro referenced in scrap 59a Rejecting Matches A problem with simple substring matching is that the string he would match longer strings like she and her Norman Ramsey suggested examining the characters occuring immediately before and after a match and rejecting the match if it appears to be part of a longer token Of course the concept of token is language dependent so we may be occasionally mistaken For the present we ll consider the mechanism an experiment 62 scraps c 63a define sym char c isalnum c c _ static int op char c
9. Type declarations 7ab 46c 47a Referenced in scrap 6a Warn only once about needing to rerun after Latex 37c Referenced in scraps 37a 46a Write abbreviated definition list 25c Referenced in scrap 25b Write defining scrap numbers 27b Referenced in scrap 26c Write file defs 22b Referenced in scrap 21a Write file s defining scrap numbers 27a Referenced in scrap 26c Write index of file names 25d Referenced in scrap 20 Write index of macro names 26a Referenced in scrap 20 Write index of user specified names 28a Referenced in scrap 20 Write macro definition 21b Referenced in scrap 20 Write macro defs 22c Referenced in scrap 21b Write macro refs 23a Referenced in scrap 21b Write out files gt spelling 30b Referenced in scrap 30a Write output file definition 21a Referenced in scrap 20 Write referencing scrap numbers 27c Referenced in scrap 26c 67 4 3 Identifiers Knuth prints his index of indentifiers in a two column format I could force this automatically by emitting the twocolumn command but this has the side effect of forcing a new page Therefore it seems better to leave it this up to the user already_warned 37c 37d 38a 46a arena 64b 64c 65abc arena free 16a 63c 65c arena_getmem 18b 36e 38c 39a 40a 41b 48b 52a 59
10. c Scan at sequence 17b c source get y JO Macro referenced in scrap 16c Only four of the at sequences are interesting during the first pass We skip past others immediately warning if unexpected sequences are discovered Scan at sequence 17b c source get switch c case U case o Build output file definition 17c break case D case d Build macro definition 18a break case Q case u case m case f ignore during this pass break default warning stderr Ss unexpected Q sequence ignored 4s line d n command_name source_name source_line break y po Macro referenced in scrap 17a 2 3 1 Accumulating Definitions There are three steps required to handle a definition 1 Build an entry for the name so we can look it up later 2 Collect the scrap and save it in the table of scraps 3 Attach the scrap to the name We go through the same steps for both file names and macro names Build output file definition 17c Name name collect_file_name returns a pointer to the name entry int scrap collect_scrap returns an index to the scrap Add scrap to name s definition list 18b JO Macro referenced in scrap 17b 17 Build macro definition 18a Name name collect_macro_name int scrap collect_scrap Add scrap to name s definition list 18b FO Macro referenced in scrap 1
11. enum LESS GREATER EQUAL PREFIX EXTENSION static int compare x y char x char y int len result int xl strlen x int yl strlen y int xp x xl 1 int yp ylyl 1 if xp xl if yp yl len xl lt yl xl yl result strncmp x y len if result lt 0 return GREATER else if result gt 0 return LESS else if xl lt yl 1 if xp return EXTENSION else return LESS else if xl gt yl 1 if yp return PREFIX else return GREATER else return EQUAL y o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc names c 48b char save_string s char s char new char arena_getmem strlen s 1 sizeof char strcpy new s return new File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc 48 names c 49a static int ambiguous_prefix Name prefix_add root spelling Name root char spelling Name node root while node switch compare node gt spelling spelling 1 case GREATER root amp node gt rlink break case LESS root amp node gt llink break case EQUAL return node case EXTENSION node gt spelling save_string spelling return node case PREFIX Check for ambiguous prefix 49b return node y node root Create new name entry 52a o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc Since a very short prefi
12. error stderr 4s empty scrap name 4s d n command_name source_name source_line exit 1 p NO return prefix_add amp macro_names name FO Macro referenced in scraps 55ac 57a Skip until scrap begins then return name 55c do c source_get while isspace c if c Q source_get error stderr 4s expected after macro name s d n command_name source_name start_line exit 1 Cleanup and install name 55b yo Macro referenced in scrap 54 Terminated by gt 55 names c 56 Name collect_scrap_name char name 256 char p name int ip 0 int c source_get while c c Mt c source_get while c EOF amp amp ip lt 256 switch c case Look for end of scrap name and return 57a break case Mt case ptt 7 iptt do c source get while c c MU break case 4A ptr iptt do c source get while c n do c source get 0 while c c MU break default if isgraph c error stderr AS unexpected character in macro name 4s 4d Nn command_name source_name source_line exit 1 ptt c ip c source_get break if ip 256 error stderr 4s array bounds exceeded fs d n command_name source_name source_line else error stderr 4s unexpected end of file fs d n command
13. o char c switch c 4 case case case case case case case amp case case case case case case case case lt case gt return TRUE default return FALSE File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 63b static int reject match name post reader o Name xname char post Manager reader int len strlen name gt spelling char first name gt spelling 0 char last name gt spelling len 1 char prev 0 len reader gt index len 2 if len gt 0 prev reader gt scrap gt chars len else if reader gt prev prev reader gt scrap gt chars SLAB_SIZE len if sym_char last amp amp sym_char post return TRUE if sym_char first amp amp sym_char prev return TRUE if op_char last amp amp op_char post return TRUE if op_char first amp amp op_char prev return TRUE return FALSE File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab 3 9 I manage memory using a simple scheme inspired by Hanson s idea of arenas 2 all the Memory Management Function prototypes 63c extern void arena_getmem extern void arena free o Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6
14. y remove temp name else remove files gt spelling rename temp_name files gt spelling else rename temp_name files gt spelling yo Macro referenced in scrap 30b 31 Chapter 3 The Support Routines 3 1 Source Files 3 1 1 Global Declarations We need two routines to handle reading the source files Function prototypes 32a extern void source_open pass in the name of the source file extern int source get no args returns the next char or EOF Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a There are also two global variables maintained for use in error messages and such Global variable declarations 32b extern char source_name name of the current file extern int source_line current line in the source file Macro defined by scraps llac 32b 37d 47b Macro referenced in scrap 6a Global variable definitions 32c char source_name NULL int source_line 0 Macro defined by scraps 11bd 32c 38a 47c Macro referenced in scrap 9d 3 1 2 Local Declarations input c 32d static FILE source_file the current input file static int source_peek static int double_at static int include_depth o File defined by scraps 8b 32d 33ab 35c 32 input c 33a struct 1 FILE file char name int line Y stack 10 o File defined by scraps 8b 32d 33ab 35c 3 1 3 Readi
15. 1 2 Writing Nuweb The bulk of a nuweb file will be ordinary IATEX In fact any IATEX file can serve as input to nuweb and will be simply copied through unchanged to the tex file unless a nuweb command is discovered All nuweb commands begin with an at sign 0 Therefore a file without at signs will be copied unchanged Nuweb commands are used to specify output files define macros and delimit scraps These are the basic features of interest to the nuweb tool all else is simply text to be copied to the tex file 1 2 1 The Major Commands Files and macros are defined with the following commands Qo file name flags scrap Output a file The file name is terminated by whitespace Cd macro name scrap Define a macro The macro name is terminated by a return or the beginning of a scrap A specific file may be specified several times with each definition being written out one after the other in the order they appear The definitions of macros may be similarly divided Scraps Scraps have specific begin markers and end markers to allow precise control over the contents and layout Note that any amount of whitespace including carriage returns may appear between a name and the beginning of a scrap anything where the scrap body includes every character in anything all the blanks all the tabs all the carriage returns Inside a scrap we may invoke a macro lt macro name gt Causes the macro macro name to be ex
16. 23b 24a 26b 28b 28 Format a user index entry 29a Scrap_Node uses name gt uses if uses int page Scrap_Node defs name gt defs fprintf tex file item verb s name gt spelling if uses gt scrap lt defs gt scrap write scrap ref tex file uses gt scrap TRUE amp page uses uses gt next y else if defs gt scrap uses gt scrap uses uses gt next fputs underline tex file write single scrap ref tex file defs gt scrap putc tex file page 2 defs defs gt next while uses defs 4 if uses amp amp defs uses gt scrap defs gt scrap 1 write scrap ref tex file uses gt scrap FALSE page uses uses gt next y else if uses amp amp defs gt scrap uses gt scrap uses uses gt next fputs underline tex file write single scrap ref tex file defs gt scrap putc tex file page 2 defs defs gt next fputs n tex file y YO Macro referenced in scrap 28b 2 5 Writing the Output Files Function prototypes 29b extern void write_files o Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a 29 output c 30a void write files files Name files while files write_files files gt llink Write out files gt spelling 30b files files gt rlink o File defined by scraps 8a 30a We call tempnam causi
17. Find a new chunk of memory 65a y o File defined by scraps 9c 64abc 65c Tf the current chunk doesn t have adequate space at least n bytes we examine the rest of the list of chunks starting at arena gt next looking for a chunk with adequate space If n is very large we may not find it right away or we may not find a suitable chunk at all 64 Find a new chunk of memory 65a Chunk ap arena Chunk np ap gt next while np char v sizeof Chunk char np if v n lt np gt limit np gt avail v n arena np return v ap mp np ap gt next Allocate a new chunk of memory 65b FO Macro referenced in scrap 64c If there isn t a suitable chunk of memory on the free list then we need to allocate a new one Allocate a new chunk of memory 65b size_t m n 10000 np Chunk malloc m np gt limit m char np np gt avail n sizeof Chunk char np np gt next NULL ap gt next np arena np return sizeof Chunk char np JO Macro referenced in scrap 65a 3 5 2 Freeing Memory To free all the memory in the arena we need only point arena back to the first empty chunk arena c 65c void arena_free arena amp first o File defined by scraps 9c 64abc 65c 65 Chapter 4 Indices Three sets of indices can be created automatically an index of file names an index of macro names and an index of user specified
18. break case Skip over index entries 25a case putc file return case lt Format macro name 25b break default ignore these since passi will have warned about them break y JO Macro referenced in scrap 24a There s no need to check for errors here since we will have already pointed out any during the first pass 24 Skip over index entries 25a do do c source_get while c c source_get while c FO Macro referenced in scrap 24c Format macro name 25b Name name collect scrap name fprintf file langle s footnotesize name gt spelling if name gt defs Write abbreviated definition list 25c else putc file warning stderr 4s scrap never defined lt s gt in command_name name gt spelling fputs rangle verb0 file FO Macro referenced in scrap 24c Write abbreviated definition list 25c Scrap_Node p name gt defs write single scrap ref file p gt scrap p p gt next if p fputs ldots file JO Macro referenced in scrap 25b 2 4 2 Generating the Indices Write index of file names 25d if file_names fputs n smal1 begin list setlength itemsep parsep tex_file fputs setlength itemindent leftmargin n tex file format entry file names tex file TRUE fputs NNend list tex file c sour
19. each slash I update trim to point just past the slash in source name The effect is that trim will point at the file name without any leading directory specifications The pointer dot is made to point at the file name extension if present If there is no extension we add w to the source name In any case we create the tex name from trim taking care to get the correct extension Build source name and tex name 15b char p argv arg char q source name char trim q char dot NULL char c p while c 1 qt C if c 4 trim q dot NULL else if c dot q 1 c prt q NO if dot 1 dot 0 sprintf tex name s tex trim sprintf aux name s aux trim dot y else sprintf tex_name s tex trim sprintf aux_name s aux trim gtr e q w kq NO FO Macro referenced in scrap 15a 15 Now that we re finally ready to process a file it s not really too complex We bundle most of the work into three routines pass1 see Section 2 3 write tex see Section 2 4 and write files see Section 2 5 After we re finished with a particular file we must remember to release its storage see Section 3 5 Process a file 16a passi source name if tex flag 1 collect numbers aux name write tex source name tex name if output_flag write_files file_names arena_free JO Macro referenc
20. in scrap 33b Handle an at character 34a Referenced in scrap 33b Handle at sign during scrap accumulation 39c Referenced in scrap 39b Handle macro invocation in scrap 40b Referenced in scrap 39c Handle optional per file flags 53 Referenced in scrap 52b Handle tab characters on output 44c Referenced in scrap 43b Handle the file name in argv arg 15a Referenced in scrap 14b Include files 6b Referenced in scrap 6a Insert appropriate indentation 44b Referenced in scraps 43b 44a Insert debugging information if required 44a Referenced in scraps 43b 44d Interpret at sequence 20 Referenced in scrap 19b Interpret command line arguments 11ef Referenced in scrap 9e Interpret the argument string s 12a Referenced in scrap 11f Look for end of scrap name and return 57a Referenced in scrap 56 Macintosh utility code 12bc 13 14a Referenced in scrap 9e Open an include file 34b Referenced in scrap 34a Process a file 16a Referenced in scraps 13 15a Process the remaining arguments file names 14b Referenced in scrap 9e Reverse cross reference lists 18c Referenced in scrap 16c Save macro name 4la Referenced in scrap 40b Scan at sequence 17b Referenced in scrap 17a Scan the source file looking for at sequences 17a Referenced in scrap 16c Search scraps 62 Referenced in scrap 59a Skip over index entries 25a Referenced in scrap 24c Skip until scrap begins then return name 55c Referenced in scrap 54
21. isspace c o Macro referenced in scraps 21ab Formatting Cross References Write file defs 22b if name gt defs gt next fputs vspace lex n tex file fputs footnotesize addtolength baselineskip lex n tex file fputs begin list setlength itemsep parsep tex file fputs setlength itemindent leftmargin n tex file fputs NNitem File defined by scraps tex file print scrap numbers tex file name gt defs fputs end list n tex file else fputs vspace 2ex n tex file JO Macro referenced in scrap 2la Write macro defs 22c fputs vspace 1ex n tex file fputs footnotesize addtolength baselineskip 1lex n tex file fputs begin list setlength itemsep parsep tex file fputs setlength itemindent leftmargin n tex file if name gt defs gt next fputs NNitem Macro defined by scraps tex file print scrap numbers tex file name gt defs y JO Macro referenced in scrap 21b 22 Write macro refs 23a t if name gt uses if name gt uses gt next 1 fputs item Macro referenced in scraps tex file print_scrap_numbers tex_file name gt uses else fputs item Macro referenced in scrap tex_file write single scrap ref tex file name gt uses gt scrap fputs n tex file else fputs item Macro never referenced n tex file warning stderr 4
22. language and typesetting language For example CWEB Knuth s current system of choice works with a combination of C or C and TEX 8 Another system FunnelWeb is independent of any programming language and only mildly dependent on TEX 10 Inspired by the versatility of Funnel Web and by the daunting size of its documentation I decided to write my own very simple tool for literate programming 1 1 Nuweb Nuweb works with any programming language and IATEX 7 I wanted to use TFX because it supports a multi level sectioning scheme and has facilities for drawing figures I wanted to be able to work with arbitrary programming languages because my friends and I write programs in many languages and sometimes combinations of several languages e g C Fortran C yacc lex Scheme assembly Postscript and so forth The need to support arbitrary programming languages has many consequences No pretty printing Both WEB and CWEB are able to pretty print the code sections of their documents because they understand the language well enough to parse it Since we want to use any language we ve got to abandon this feature 1 There is another system similar to mine written by Norman Ramsey called noweb 9 It perhaps suffers from being overly Unix dependent and requiring several programs to use On the other hand its command syntax is very nice In any case nuweb certainly owes its name and a number of features to his inspiration No inde
23. new Goto_Node arena_getmem sizeof Goto_Node new gt moves NULL new gt fail NULL new gt moves NULL new gt output NULL new_move gt state new new_move gt c c new_move gt next g gt moves g gt moves new move if depth max depth 1 int i Goto_Node new_depths Goto_Node arena_getmem 2 depth sizeof Goto_Node max_depth 2 depth for i 0 i lt depth i new_depths i depths i depths new depths for i depth i lt max_depth i depths i NULL new gt next depths depth depths depth new y q new depth y g gt output Name_Node arena_getmem sizeof Name_Node g gt output gt next NULL g gt output gt name tree FO Macro referenced in scrap 59b 60 Build failure functions 61 1 int depth for depth 1 depth max depth depth 4 Goto_Node r depths depth while r 1 Move Node m r gt moves while m 4 char a m gt c Goto_Node s m gt state Goto_Node state r gt fail while state amp amp goto_lookup a state state state gt fail if state s gt fail goto_lookup a state else s gt fail root a if s gt fail Name_Node p s gt fail gt output while p Name_Node q Name_Node arena_getmem sizeof Name_Node g gt name p gt name q gt next s gt output s gt output a p p gt next m m gt next r r gt next FO
24. new name int ip 0 do c source_get while isspace c if c 0 Name name do p c iptt c source_get while c amp amp isspace c amp amp ip lt 256 if ip 256 error stderr fs Array bounds exceeded in scrap As d n command_name source_name source_line exit 1 p NO name name_add amp user_names new name if name gt defs name gt defs gt scrap scraps Scrap_Node def Scrap_Node arena_getmem sizeof Scrap_Node def gt scrap scraps def gt next name gt defs name gt defs def while c 1 200 c source_get if c 1 error stderr 4s unexpected c in scrap fs d n command_name c source_name source_line exit 1 FO Macro referenced in scrap 39c Handle macro invocation in scrap 40b Name name collect scrap name Save macro name 4la Add current scrap to name s uses 41b c source_get FO Macro referenced in scrap 39c 40 Save macro name 4la char ks name gt spelling int len strlen s 1 pushs lt amp writer while len gt 0 push s amp writer len if kg pushs amp writer else push s amp writer pushs gt amp writer yO Macro referenced in scrap 40b Add current scrap to name s uses 41b if name gt uses name gt uses gt scrap scraps 1 Scrap_Node use S
25. nuweb foo bar quux will take as input the file foo bar quux w and will create the file quux tex in the current directory By default nuweb performs both tangling and weaving at the same time Normally this is not a bottleneck in the compilation process however it s possible to achieve slightly faster throughput by avoiding one or another of the default functions using command line flags There are currently three possible flags t Suppress generation of the tex file o Suppress generation of the output files c Avoid testing output files for change before updating them Thus the command nuweb to foo bar quux would simply scan the input and produce no output at all There are two additional command line flags v For verbose causes nuweb to write information about its progress to stderr n Forces scraps to be numbered seguentially from 1 instead of using page numbers This form is perhaps more desirable for small webs 1 4 Restrictions Because nuweb is intended to be a simple tool I ve established a few restrictions Over time some of these may be eliminated others seem fundamental e The handling of errors is not completely ideal In some cases I simply warn of a problem and continue in other cases I halt immediately This behavior should be regularized e I warn about references to macros that haven t been defined but don t halt This seems most convenient for development but may change in th
26. 2 5 Writing the Output Files s bracie e aoe eS a e di BRYN OR 3 The Support Routines del Source Biles a se ee ede ee eU A ADD GI ddydd dd Be 3 1 1 Global Declarations sw wi te uyn o WWW a Tw da r y y loan yn 3 12 Local Declarations 7 4 4 dok de te de apre ren A a aed de e IADAU da at ve mea r a 3 1 3 Readingea Fil amp gar kode ake Si ea dw aa Sy yol me Be oke kra kra ee ae a WAG A Ne ald Opening Bl Ge Yo thy li e de he A a r Ge wee rd enh en ah anal By Sa Sa IDAS A fa de A Oe kai pat pan ANI Be at len Fly Ge aa 3 2 1 Collecting Page Numbers venn 33 Names o eM Ad dd tee ae UU A 3 4 Searching for Index Entries ee di de W tee RE Ee den ta aa ee A 3 4 1 Building the Automata FFF I GR RR yg 3 42 Searching the Scraps s oss re v a f a Ge g RR YR ARAD AD Y AB ok BALA SE ja C amp G 3 5 Memory Management TII Allocating Memory ain f anu A E ae ls y dy ee A A Ea eg 39 2 J Freeing Memmorys beta il DR OM Ur EA GWCW GDG y A ae aa eS 4 Indices 66 Ala AOS A o de de Gi Ch Ch Ad A Cg AL Sp A Me No E 66 ADA MACOS A a ah BA o tt a NND 66 Ao dentihers tete te A te e A AA fo Cd GAGA AR AA a tan tenten fe fiy f y cr ADE de 68 Chapter 1 Introduction In 1984 Knuth introduced the idea of literate programming and described a pair of tools to support the practise 3 His approach was to combine Pascal code with TEX documentation to produce a new language WEB that offered program
27. 2a 43a 46a 58abcde 59ab 63ab 3 4 1 Building the Automata Function prototypes 58f extern void search o Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a 58 scraps c 59a static void build gotos static int reject match void search int i for i 0 i 128 i root i NULL max_depth 10 depths Goto_Node arena getmem max depth sizeof Goto Node for i 0 i lt max_depth i depths i NULL build gotos user names Build failure functions 61 Search scraps 62 File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 59b static void build gotos tree Name tree while tree Extend goto graph with tree gt spelling 60 build_gotos tree gt rlink tree tree gt llink File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab 59 Extend goto graph with tree gt spelling 60 int depth 2 char p tree gt spelling char c p Goto_Node kq root c if lg 1 q Goto_Node arena_getmem sizeof Goto_Node root c q q gt moves NULL q gt fail NULL q gt moves NULL g gt output NULL g gt next depths 1 depths 1 g y while c p Goto_Node new goto_lookup c q if new Move_Node new_move Move Node arena_getmem sizeof Move_Node
28. 7b Since a file or macro may be defined by many scraps we maintain them in a simple linked list The list is actually built in reverse order with each new definition being added to the head of the list Add scrap to name s definition list 18b Scrap_Node def Scrap_Node arena_getmem sizeof Scrap_Node def gt scrap scrap def gt next name gt defs name gt defs def Jo Macro referenced in scraps 17c 18a 2 3 2 Fixing the Cross References Since the definition and reference lists for each name are accumulated in reverse order we take the time at the end of pass1 to reverse them all so they ll be simpler to print out prettily The code for reverse_lists appears in Section 3 3 Reverse cross reference lists 18c reverse_lists file_names reverse lists macro names reverse lists user names JO Macro referenced in scrap 16c 2 4 Writing the Latex File The second pass invoked via a call to write_tex copies most of the text from the source file straight into a tex file Definitions are formatted slightly and cross reference information is printed out Note that all the formatting is handled in this section If you don t like the format of definitions or indices or whatever it ll be in this section somewhere Similarly if someone wanted to modify nuweb to work with a different typesetting system this would be the place to look Function prototypes 18d extern void write_tex o Mac
29. Code This routine frames dialog item 1 the OK button in the options dialog Macintosh utility code 12b pascal void MyItemProc WindowPtr theDlg short theltem Rect iRect Handle iHndl short iType GetDItem theDlg 1 amp iType Handle amp iHndl amp iRect item 1 PenSize 3 3 InsetRect amp iRect 4 4 FrameRoundRect amp iRect 16 16 Jo Macro defined by scraps 12bc 13 14a Macro referenced in scrap 9e If the option key is held down when the program is started we pop up a dialog box allowing the user to alter the program flags Macintosh utility code 12c void CenterDialog short thelD check_for_options EventRecord theEvent short itemHit 12 DialogPtr myDlg ControlHandle iHndl Rect iRect short iType GetNextEvent everyEvent amp theEvent if theEvent modifiers amp optionKey CenterDialog 128 myDlg GetNewDialog 128 0 WindowPtr 1 GetDItem myDlg 7 amp iType Handle amp iHndl amp iRect SetDItem myDlg 7 iType Handle MyItemProc amp iRect ShowWindow myD1g do ModalDialog 0 amp itemHit switch itemHit case 1 break case 2 GetDItem myDlg 2 kiType Handle amp iHndl amp iRect tex flag tex flag SetCtlValue iHndl tex flag break case 3 GetDItem myDlg 3 iType Handle amp iHndl amp iRect output flag output_flag SetCtlValue iHndl output_flag break case 4 GetDItem myDlg 4 iT
30. Nuweb A Simple Literate Programming Tool Version 0 87 Preston Briggs preston cs rice edu This work has been supported by ARPA through ONR grant N00014 91 J 1989 Contents 1 Introduction Ti INU A REAL cC Aes e d v d y eas oe Ee Br Lot du Se dy Y O Rd 1 27 Writing Nuweb 000 ket a dak w dou Sie Ge a Coe apn ae Ba Reena i aa aad a a 42 1 The Major Commands didnt Ge Uc a be EYE Biwi es GW Y ee OO 1 2 2 The Minor Commands ee 1 3 Running N uwebs swear made dad di bab ba 8S GO a a le ells Ek Gea id 154 OR estriction 8i IR AA A A PEER ART a O EE AU AU A 1 5 Acknowledgements a a len ee 2 The Overall Structure pe A A O O ROA 2 10 FheMain Files a e A ee het hc BU R eG di Me dlr e8 21 2 Support Files e ae hh ee E EA UE GG A WW EEE EM ESS 2 27 The Main Routine se eb sw 4 4 dede di D4 DR toe we eee SON Ee hae d d 2 2 1 Command Line Arguments ug 2 2 2 Macintosh Specific Code aaa 223 Fil6 Name aa eb aay ets A y A ye EI yey fo e n n Sd dy AU te SO S aw Zo Pass ONE Gee o A Once a du Be hae esha BIA ea a a a f see 2 3 1 Accumulating Definitions venn 2 3 2 Fixing the Cross References RG I Gu ug 2 4 Writing the Latex Elle ua e te e Ne Ne de a ML MD et Cyd yd Ty yd dal UA RR R A A on Ne Mo Me 2 4 Formatting DefnitiG6AS s a huu a ata di e Aaa he a a a A Md Ted ian fen ee Se A 2 4 2 Generating the ndices FEE ER ug
31. _name source_name source_line exit 1 yo Macro referenced in scrap 33b Open an include file 34b char name 256 if include depth gt 10 error stderr s include nesting too deep s d n command_name source_name source_line exit 1 Collect include file name 35a stack include_depth name source name stack include_depth file source_file stack include_depth line source_line 1 include_depth source_line 1 source_name save_string name source_file fopen source_name r if source_file error stderr 4s can t open include file s n command_name source name exit 1 source_peek getc source_file c source_get yo Macro referenced in scrap 34a 94 Collect include file name 35a char p name do c getc source_file while c c MU while isgraph c pi C c getc source_file p NO if c N 1 error stderr 4s unexpected characters after file name fs d n command name source name source line exit 1 Jo Macro referenced in scrap 34b If an EOF is discovered the current file must be closed and input from the next stacked file must be resumed If no more files are on the stack the EOF is returned Handle EOF 35b fclose source file if include depth include depth source file stack include_depth file source_line stack include_dept
32. a 63 Basically I allocate storage required when processing a source file primarily for names and scraps using calls to arena getmem n where n specifies the number of bytes to be allocated When the storage is no longer required the entire arena is freed with a single call to arena free Both operations are quite fast arena c 64a typedef struct chunk struct chunk next char limit char avail Chunk File defined by scraps 9c 64abc 65c We define an empty chunk called first The variable arena points at the current chunk of memory it s initially pointed at first As soon as some storage is required a real chunk of memory will be allocated and attached to first gt next storage will be allocated from the new chunk and later chunks if necessary arena c 64b static Chunk first NULL NULL NULL static Chunk arena amp first o File defined by scraps 9c 64abc 65c 3 5 1 Allocating Memory The routine arena_getmem n returns a pointer to at least n bytes of memory Note that n is rounded up to ensure that returned pointers are always aligned We align to the nearest 8 byte segment since that ll satisfy the more common 2 byte and 4 byte alignment restrictions too arena c 64c void arena_getmem n size t n char q char p arena gt avail n n 7 amp 77 ensuring alignment to 8 bytes q p n if q lt arena gt limit arena gt avail q return p
33. a 60 61 62 63c 64c build gotos 59a 59b Chunk 64a 64b 65ab collect_file_name 17c 21a 47d 52b collect_macro_name 18a 21b 47d 54 collect_numbers 16a 45b 46a collect_scrap 17c 18a 36d 38e collect_scrap_name 25b 40b 47d 56 command name llc 11de 12a 13 14b 17b 19a 23a 25b 30b 34ab 35ac 37c 39bc 40a 42ab 43b 44cd 45a 49b 52b 53 54 55abc 56 57a compare 48a 49a 50 compare_flag lla 11b 12ac 30b copy_scrap 18e 21d 24a depths 58d 59a 60 61 double_at 32d 34a 35c EQUAL 48a 49a 50 error 7b 12a 14ab 19a 30b 34ab 35ac 39bc 40a 42ab 43b 44cd 45a 52b 54 55abc 56 57a exit 6b 9e 14b 30b 34ab 35ac 39bc 40a 42ab 43b 44cd 45a 92b 54 55abc 56 57a EXTENSION 48a 49a 50 FALSE 7a llab 12a 20 23b 26a 27b 29a 34a 35c 45a 46a 50 52a 53 63ab fclose 6b 19a 30b 31 35b 46a FILE 6b 7b 14a 19a 23b 24a 26b 28b 30b 31 32d 33a 37ab 43a 46a file names 16ac 18c 25d 47b 47c 52b first 37a 63b 64b 65c fopen 6b 19a 30b 31 34b 35c 46a format_entry 18e 25d 26a 26b format_user_entry 18e 28a 28b fprintf 6b 7b 21abc 25b 26c 29a 37a 44a fputs 6b 21abcd 22abc 23ab 24ac 25bcd 26ac 27ac 28a 29a 37a getc 6b 31 33b 34ab 35abc goto_lookup 58e 60 61 62 Goto_Node 58b 58cde 59a 60 61 62 GREATER 48a 49a 50 include_depth 32d 34b 35bc
34. ap array scrap page 1 if scrap array scrap 1 letter scrap array scrap 1 letter a scrap_array scrap letter scrap array scrap 1 letter 1 JO Macro referenced in scrap 46a 3 3 Names Type declarations 46c typedef struct scrap node struct scrap_node next int scrap Scrap_Node o Macro defined by scraps 7ab 46c 47a Macro referenced in scrap 6a 46 Type declarations 47a typedef struct name char spelling struct name llink struct name rlink Scrap_Node defs Scrap_Node uses int mark char tab_flag char indent_flag char debug_flag Name o Macro defined by scraps 7ab 46c 47a Macro referenced in scrap 6a Global variable declarations 47b extern Name file_names extern Name macro_names extern Name user_names Macro defined by scraps llac 32b 37d 47b Macro referenced in scrap 6a Global variable definitions 47c Name file_names NULL Name macro_names NULL Name user_names NULL o Macro defined by scraps 11bd 32c 38a 47c Macro referenced in scrap 9d Function prototypes 47d extern Name collect file name extern Name collect macro name extern Name collect_scrap_name extern Name name_add extern Name prefix_add extern char save_string extern void reverse_lists Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a 47 names c 48a
35. ce get FO Macro referenced in scrap 20 25 Write index of macro names 26a if macro_names fputs n small begin list setlength itemsep parsep tex_file fputs setlength itemindent leftmargin n tex file format entry macro names tex file FALSE fputs end list tex file c source_get FO Macro referenced in scrap 20 latex c 26b static void format_entry name tex_file file_flag Name name FILE xtex file int file flag while name format_entry name gt llink tex file file flag Format an index entry 26c name name gt rlink File defined by scraps 7e 18e 19a 23b 24a 26b 28b Format an index entry 26c fputs item tex file if file_flag fprintf tex_file verb Z s name gt spelling Write file s defining scrap numbers 27a ag else fprintf tex_file langle s footnotesize name gt spelling Write defining scrap numbers 27b fputs rangle tex file Write referencing scrap numbers 27c putc n tex file Jo Macro referenced in scrap 26b 26 Write file s defining scrap numbers 27a Scrap_Node p name gt defs fputs footnotesize Defined by scrap tex_file if p gt next fputs s tex_file print scrap numbers tex file p else putc tex file write single scrap ref tex file p gt scrap putc tex fil
36. crap_Node arena_getmem sizeof Scrap_Node use gt scrap scraps use gt next name gt uses name gt uses use FO Macro referenced in scrap 40b scraps c 41c static char pop manager Manager manager Slab scrap manager gt scrap int index manager gt index char c scrap gt chars index if index SLAB_SIZE manager gt prev scrap manager gt scrap scrap gt next index O manager gt index index return c o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab 41 scraps c 42a static Name pop scrap name manager Manager manager char name 256 char p name int ip 0 int c pop manager while ip lt 256 if c Check for end of scrap name and return 42b else ptr c iptt c pop manager error stderr 4s array bounds exceeded n command name exit 1 o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab Check for end of scrap name and return 42b c pop manager if c 0 ptt c iptt c pop manager else if c 4 if p name gt 3 amp amp p 1 amp pl 2 amp p 3 pl 3 gt p 2 p 0 return prefix_add amp macro_names name else error stderr 4s found an internal problem 1 n command_name exit 1 FO Macro reference
37. d in scrap 42a 42 scraps c 43a int write scraps file defs global indent indent chars o debug_flag tab_flag indent_flag FILE file Scrap_Node defs int global_indent char indent_chars char debug flag char tab flag char indent flag int indent 0 while defs Copy defs gt scrap to file 43b defs defs gt next y return indent global indent File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab Copy defs gt scrap to file 43b char c Manager reader int line number scrap_array defs gt scrap file_line Insert debugging information if required 44a reader scrap scrap_array defs gt scrap slab reader index 0 c pop amp reader while c 1 switch c case Check for macro invocation in scrap 44d break case n putc c file line_number Insert appropriate indentation 44b break case t Handle tab characters on output 44c break default putc c file if global_indent indent gt 500 1 error stderr s indent_chars array overflow n command_name exit 1 indent chars global indent indent indent break c pop amp reader JO Macro referenced in scrap 43a 43 Insert debugging information if required 44a if debug flag fprintf file n line d s n line number scrap array defs scrap file name Insert appropria
38. e putc tex file YO Macro referenced in scrap 26c Write defining scrap numbers 27b Scrap_Node p name gt defs if pt int page write_scrap_ref tex_file p gt scrap TRUE amp page p p gt next while p write scrap ref tex file p gt scrap FALSE amp page p p gt next y y else putc tex file yo Macro referenced in scrap 26c Write referencing scrap numbers 27c Scrap_Node p name gt uses fputs footnotesize tex_file if p fputs Referenced in scrap tex_file if p gt next fputs s tex_file print_scrap_numbers tex_file p else putc tex_file write single scrap ref tex file p gt scrap putc tex file else fputs Not referenced tex file putc tex file yO Macro referenced in scrap 26c 27 Write index of user specified names 28a if user_names fputs n smal1 begin list setlength itemsep parsep tex_file fputs setlength itemindent leftmargin n tex file format user entry user names tex file fputs NNend list tex file c source_get FO Macro referenced in scrap 20 latex c 28b static void format_user_entry name tex_file Name name FILE tex_file while name format_user_entry name gt llink tex file Format a user index entry 29a name name gt rlink y o File defined by scraps 7e 18e 19a
39. e future e File names and index entries should not contain any signs e Macro names may be almost any well formed T X string It makes sense to change fonts or use math mode however care should be taken to ensure matching braces brackets and dollar signs e Anything is allowed in the body of a scrap however very long scraps horizontally or vertically may not typeset well e Temporary files created for comparison to the eventual output files are placed in the current directory Since they may be renamed to an output file name all the output files should be on the same file system as the current directory e Because page numbers cannot be determined until the document has been typeset we have to rerun nuweb after IATEX to obtain a clean version of the document very similar to the way we sometimes have to rerun MTEX to obtain an up to date table of contents after significant edits Nuweb will warn in most cases when this needs to be done in the remaining cases ITEX will warn that labels may have changed Very long scraps may be allowed to break across a page if declared with 0 or CD instead of 6o and Cd This doesn t work very well as a default since far too many short scraps will be broken across pages however as a user controlled option it seems very useful 1 5 Acknowledgements Several people have contributed their times ideas and debugging skills In particular I d like to acknowledge the contributions of O
40. e_get while c EOF amp amp ip lt 256 switch c case Check for terminating at sequence and return name 55a break case XML case ptt iptt do c source get 0 while c c MU break case pt iptt do c source get while c n do c source get while c c MU break case n Skip until scrap begins then return name 55c default ptr c iptt c source get break if ip 256 error stderr 4s array bounds exceeded 4s d n command_name source_name start_line else error stderr 4s expected macro name fs d n command_name source_name start_line exit 1 return NULL unreachable return to avoid warnings on some compilers o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc 54 Check for terminating at sequence and return name 55a c source_get switch c 4 case 0 prr c iptt break case Cleanup and install name 55b default error stderr ZS unexpected c in macro name fs d n command name c source_name start line exit 1 JO Macro referenced in scrap 54 Cleanup and install name 55b if p gt name amp amp p 1 pro if p name gt 3 amp amp pl 1 gt amp amp pl 2 gt amp amp pl 3 gt 1 pl 3 p 2 if p name name 0
41. eallocation of memory based on object lifetimes Software Practice and Experience 20 1 5 12 January 1990 Donald E Knuth Literate programming The Computer Journal 27 2 97 111 May 1984 Donald E Knuth METAFONT The Program Computers amp Typesetting Addison Wesley 1986 Donald E Knuth TEX The Program Computers amp Typesetting Addison Wesley 1986 Donald E Knuth The TEXbook Computers amp Typesetting Addison Wesley 1986 Leslie Lamport ATRX A Document Preparation System Addison Wesley 1986 Silvio Levy and Donald E Knuth CWEB user manual The CWEB system of structured documentation Technical Report STAN CS 83 977 Stanford University October 1990 Available for anonymous ftp from labrea stanford edu in directory pub cweb Norman Ramsey Literate programming tools need not be complex Submitted to IEEE Software August 1992 10 Ross N Williams FunnelWeb user s manual May 1992 Available for anonymous ftp from sirius itd adelaide edu au in directory pub funnelweb 70
42. ed in scrap 42a Check for macro invocation in scrap 44d Referenced in scrap 43b Check for terminating at sequence and return name 55a Referenced in scrap 54 Cleanup and install name 55b Referenced in scraps 55ac 57a Collect include file name 35a Referenced in scrap 34b Collect user specified index entries 40a Referenced in scrap 39c Compare the temp file and the old file 31 Referenced in scrap 30b Copy defs gt scrap to file 43b Referenced in scrap 43a Copy source_file into tex_file 19b Referenced in scrap 19a 66 Copy macro into file 45a Referenced in scrap 44d Create new name entry 52a Referenced in scraps 49a 51b Create new scrap managed by writer 39a Referenced in scrap 38e Expand tab into spaces 24b Referenced in scraps 24a 44c Extend goto graph with tree gt spelling 60 Referenced in scrap 59b Fill in the middle of the scrap environment 21d Referenced in scraps 21ab Find a new chunk of memory 65a Referenced in scrap 64c Finish the scrap environment 22a Referenced in scraps 21ab Format a user index entry 29a Referenced in scrap 28b Format an index entry 26c Referenced in scrap 26b Format macro name 25b Referenced in scrap 24c Function prototypes 16b 18d 29b 32a 36d 45b 47d 58f 63c Referenced in scrap 6a Global variable declarations 11ac 32b 37d 47b Referenced in scrap 6a Global variable definitions 11bd 32c 38a 47c Referenced in scrap 9d Handle EOF 35b Referenced
43. ed in scraps 13 15a 2 3 Pass One During the first pass we scan the file recording the definitions of each macro and file and accumulating all the scraps Function prototypes 16b extern void pass1 o Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a The routine pass1 takes a single argument the name of the source file It opens the file then initializes the scrap structures see Section 3 2 and the roots of the file name tree the macro name tree and the tree of user specified index entries see Section 3 3 After completing all the necessary preparation we make a pass over the file filling in all our data structures Next we seach all the scraps for references to the user specified index entries Finally we must reverse all the cross reference lists accumulated while scanning the scraps passi c 16c void pass1 file_name char file_name if verbose_flag info stderr reading s n file name source open file name init scraps macro names NULL file names NULL user_names NULL Scan the source file looking for at sequences 17a if tex_flag search Reverse cross reference lists 18c File defined by scraps 7d 16c 16 The only thing we look for in the first pass are the command sequences All ordinary text is skipped entirely Scan the source file looking for at sequences 17a int c source_get while c EOF if
44. ers I usually put these in their own section in the ATEX document for example see Chapter 4 Identifiers must be explicitely specified for inclusion in the Cu index By convention each identifier is marked at the point of its definition all references to each identifier inside scraps will be discovered automatically To mark an identifier for inclusion in the index we must mention it at the end of a scrap For example d a scrap QA Let s pretend we re declaring the variables FOO and BAR inside this scrap FOO BAR I ve used alphabetic identifiers in this example but any string of characters not including whitespace or characters will do Therefore it s possible to add index entries for things like lt lt if desired An identifier may be declared in more than one scrap In the generated index each identifier appears with a list of all the scraps using and defining it where the defining scraps are distinguished by underlining Note that the identifier doesn t actually have to appear in the defining scrap it just has to be in the list of definitions at the end of a scrap 1 3 Running Nuweb Nuweb is invoked using the following command nuweb flags file name One or more files may be processed at a time If a file name has no extension w will be appended While a file name may specify a file in another directory the resulting tex file will always be created in the current directory For example
45. h line source_name stack include_depth name source_peek getc source file c source get Jo Macro referenced in scrap 33b 3 1 4 Opening a File The routine source_open takes a file name and tries to open the file If unsuccessful it complains and halts Otherwise it sets source_name source_line and double_at input c 35c void source_open name char name source_file fopen name r if source file error stderr s couldn t open s n command name name exit 1 source_name name source_line 1 source_peek getc source_file double_at FALSE include_depth 0 File defined by scraps 8b 32d 33ab 35c 35 3 2 Scraps scraps c 36a define SLAB SIZE 500 typedef struct slab struct slab next char chars SLAB SIZE Slab o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 36b typedef struct char file_name int file_line int page char letter Slab slab ScrapEntry o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 36c static ScrapEntry SCRAP 256 define scrap array i SCRAP i gt gt 8 i 255 static int scraps o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab Function prototypes 36d extern void init_scraps extern int collect_scrap extern int write_scrap
46. identifiers An index entry includes the name of the entry where it was defined and where it was referenced 4 1 Files arena c Defined by scraps 9c 64abc 65c global c Defined by scrap 9d global h Defined by scrap 6a input c Defined by scraps 8b 32d 33ab 35c latex c Defined by scraps 7e 18e 19a 23b 24a 26b 28b names c Defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc nuweb c Defined by scraps 7c 9e output c Defined by scraps 8a 30a passi c Defined by scraps 7d 16c scraps c Defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab 4 2 Macros Accumulate scrap and return scraps 39b Referenced in scrap 38e Add scrap to name s definition list 18b Referenced in scraps 17c 18a Add current scrap to name s uses 41b Referenced in scrap 40b Add letters to scraps with duplicate page numbers 46b Referenced in scrap 46a Allocate a new chunk of memory 65b Referenced in scrap 65a Begin the scrap environment 21c Referenced in scraps 21ab Build source_name and tex_name 15b Referenced in scrap 15a Build failure functions 61 Referenced in scrap 59a Build macro definition 18a Referenced in scrap 17b Build output file definition 17c Referenced in scrap 17b Check at sequence for end of scrap 24c Referenced in scrap 24a Check for ambiguous prefix 49b Referenced in scrap 49a Check for end of scrap name and return 42b Referenc
47. ll the scraps for occurences of each entry The obvious approach to this problem would be quite expensive for large documents however there 97 is an interesting paper describing an efficient solution 1 scraps c 58a typedef struct name node struct name node next Name name Name Node o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 58b typedef struct goto node Name Node output list of words ending in this state struct move node moves list of possible moves struct goto node fail and where to go when no move fits struct goto node next next goto node with same depth Goto Node o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 58c typedef struct move node struct move node next Goto Node state char c Move Node o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 58d static Goto_Node root 128 static int max_depth static Goto_Node depths File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 58e static Goto Node goto_lookup c g char c Goto_Node g Move_Node m g gt moves while m amp amp m gt c c m m gt next if m return m gt state else return NULL o File defined by scraps 9a 36abce 37ab 38bcde 41c 4
48. m y while xc yc amp amp xc 4 x y XC x ye y if isupper xc amp amp islower yc return xc 2 toupper yc 2 1 if islower xc amp amp isupper yc return toupper xc 2 1 yc 2 return xc yc F o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc names c 51b Name name_add root spelling Name root char spelling Name node root while node int result robs_strcmp node gt spelling spelling if result gt 0 root amp node gt llink else if result lt 0 root amp node gt rlink else return node node root Create new name entry 52a o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc 51 Create new name entry 52a node Name arena_getmem sizeof Name node gt spelling save_string spelling node gt mark FALSE node gt llink NULL node gt rlink NULL node gt uses NULL node gt defs NULL node gt tab_flag TRUE node gt indent_flag TRUE node gt debug_flag FALSE root node return node yo Macro referenced in scraps 49a 51b Name terminated by whitespace Also check for per file flags Keep skipping white space until we reach scrap names c 52b Name collect_file_name Name new_name char name 256 char p name int ip 0 int start_line source_line int c source_get while isspace c c source_get while isgra
49. mers a superior approach to programming He wrote several programs in WEB including weave and tangle the programs used to support literate programming The idea was that a programmer wrote one document the web file that combined documentation written in TEX 6 with code written in Pascal Running tangle on the web file would produce a complete Pascal program ready for compilation by an ordinary Pascal compiler The primary function of tangle is to allow the programmer to present elements of the program in any desired order regardless of the restrictions imposed by the programming language Thus the programmer is free to present his program in a top down fashion bottom up fashion or whatever seems best in terms of promoting understanding and maintenance Running weave on the web file would produce a T X file ready to be processed by TEX The resulting document included a variety of automatically generated indices and cross references that made it much easier to navigate the code Additionally all of the code sections were automatically pretty printed resulting in a quite impressive document Knuth also wrote the programs for TEX and METAFONT entirely in WEB eventually publishing them in book form 5 4 These are probably the largest programs ever published in a readable form Inspired by Knuth s example many people have experimented with WEB Some people have even built web like tools for their own favorite combinations of programming
50. name source name source line exit 1 return NULL unreachable return to avoid warnings on some compilers F File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc 56 Look for end of scrap name and return 57a c source_get switch c 4 case 0 prr c iptt c source get 0 break case gt Cleanup and install name 55b default error stderr As unexpected c in macro name s d n command name c source_name source line exit 1 JO Macro referenced in scrap 56 names c 57b static Scrap_Node reverse a forward declaration void reverse_lists names Name names while names reverse_lists names gt llink names gt defs reverse names gt defs names gt uses reverse names gt uses names names gt rlink File defined by scraps 9b 48ab 49a 50 5lab 52b 54 56 57bc Just for fun here s a non recursive version of the traditional list reversal code Note that it reverses the list in place that is it does no new allocations names c 57c static Scrap_Node reverse a Scrap_Node a if a Scrap_Node b a gt next a gt next NULL while b Scrap_Node c b gt next b gt next a a n b c return a o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc 3 4 Searching for Index Entries Given the array of scraps and a set of index entries we need to search a
51. ned TRUE y yo Macro referenced in scraps 37a 46a Global variable declarations 37d extern int already_warned o Macro defined by scraps llac 32b 37d 47b Macro referenced in scrap 6a 37 Global variable definitions 38a int already warned 0 o Macro defined by scraps 11bd 32c 38a 47c Macro referenced in scrap 9d scraps c 38b typedef struct Slab scrap Slab prev int index Manager o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 38c static void push c manager char c Manager manager Slab scrap manager gt scrap int index manager gt index scrap gt chars indext c if index SLAB_SIZE Slab new Slab arena getmem sizeof Slab scrap gt next new manager gt scrap new index 0 manager gt index index o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 38d static void pushs s manager char s Manager manager while s push s manager File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 38e int collect_scrap Manager writer Create new scrap managed by writer 39a Accumulate scrap and return scraps 39b File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab 38 Create new scrap managed by write
52. ng a File The routine source get returns the next character from the current source file It notices newlines and keeps the line counter source line up to date It also catches EOF and watches for characters All other characters are immediately returned input c 33b int source_get int c source_peek switch c case EOF Handle EOF 35b return c case Handle an at character 34a return c case n source line default source_peek getc source_file return c File defined by scraps 8b 32d 33ab 35c This whole character handling mess is pretty annoying I want to recognize i so I can handle include files correctly At the same time it makes sense to recognize illegal sequences and complain this avoids ever having to check anywhere else Unfortunately I need to avoid tripping over the sequence hence this whole unsatisfactory double_at business 33 Handle an at character 34a c getc source_file if double_at source_peek c double_at FALSE c 0 y else switch c 4 case i Open an include file 34b break case f case m case u case d case o case D case Q case case case lt case gt case source peek c c 0 break case source peek c double_at TRUE break default error stderr fs bad 0 sequence 4s line 4d n command
53. ng it to create a file name in the current directory This could cause a problem for rename if the eventual output file will reside on a different file system Perhaps it would be better to examine files gt spelling to find any directory information Note the superfluous call to remove before rename We re using it get around a bug in some implemen tations of rename Write out files gt spelling 30b char indent_chars 500 FILE temp_file ifdef __MWERKS__ char temp_name tmpnam 0 else char temp_name tempnam 0 endif __MWERKS__ temp_file fopen temp_name w if temp_file error stderr fs can t create s for a temporary file n command_name temp_name exit 1 if verbose_flag info stderr writing 4sAn files gt spelling write_scraps temp file files gt defs 0 indent_chars files gt debug flag files gt tab_flag files gt indent flag fclose temp file if compare_flag Compare the temp file and the old file 31 else remove files gt spelling rename temp_name files gt spelling FO Macro referenced in scrap 30a Again we use a call to remove before rename 30 Compare the temp file and the old file 31 FILE old_file fopen files gt spelling r if old_file int x y temp_file fopen temp_name r do x getc old file y getc temp file while x y amp amp x EOF fclose old file fclose temp file if x
54. nguages that are sensitive to layout but it is also important in many practical situations e g debugging Speed Since nuweb doesn t do to much the nuweb tool runs quickly I combine the functions of tangle and weave into a single program that performs both functions at once Page numbers Inspired by the example of noweb nuweb refers to all scraps by page number to simplify navigation If there are multiple scraps on a page say page 17 they are distinguished by lower case letters e g 17a 17b and so forth Multiple file output The programmer may specify more than one output file in a single nuweb file This is required when constructing programs in a combination of languages say Fortran and C It s also an advantage when constructing very large programs that would require a lot of compile time This last point is very important By allowing the creation of multiple output files we avoid the need for monolithic programs Thus we support the creation of very large programs by groups of people A further reduction in compilation time is achieved by first writing each output file to a temporary location then comparing the temporary file with the old version of the file If there is no difference the temporary file can be deleted If the files differ the old version is deleted and the temporary file renamed This approach works well in combination with make or similar tools since make will avoid recompiling untouched output files
55. panded inline as the code is written out to a file It is an error to specify recursive macro invocations Note that macro names may be abbreviated either during invocation or definition For example it would be very tedious to have to repeatedly type the macro name d Check for terminating at sequence and return name if found Therefore we provide a mechanism stolen from Knuth of indicating abbreviated names d Check for terminating Basically the programmer need only type enough characters to uniquely identify the macro name followed by three periods An abbreviation may even occur before the full version nuweb simply preserves the longest version of a macro name Note also that blanks and tabs are insignificant in a macro name any string of them are replaced by a single blank When scraps are written to an output or tex file tabs are expanded into spaces by default Currently I assume tab stops are set every eight characters Furthermore when a macro is expanded in a scrap the body of the macro is indented to match the indentation of the macro invocation Therefore care must be taken with languages e g Fortran that are sensitive to indentation These default behaviors may be changed for each output file see below Flags When defining an output file the programmer has the option of using flags to control output of a particular file The flags are intended to make life a little easier for programmers using certain language
56. ph c amp amp ip lt 256 1 p c iptt c source_get if ip 256 error stderr 4s array bounds exceeded fs d n command_name source_name start_line exit 1 if p name error stderr 4s expected file name fs d n command_name source_name start_line exit 1 p NO new name name add 4file names name Handle optional per file flags 53 if c Q source get 4 1 error stderr 4s expected after file name s 7 d n command_name source_name start_line exit 1 return new name File defined by scraps 9b 48ab 49a 50 5lab 52b 54 56 57bc 52 Handle optional per file flags 53 while 1 1 while isspace c c source get if c gt c source get do switch c case t case d case i default new_name gt tab_flag FALSE break new_name gt debug_flag TRUE break new_name gt indent_flag FALSE break warning stderr 4s unexpected per file flag 4s d in command name source name source line break c source get while isspace c y else break YO Macro referenced in scrap 52b Name terminated by Nn or Cf but keep skipping until 64 53 names c 54 Name collect_macro_name char name 256 char p name int ip 0 int start_line source_line int c source_get while isspace c c sourc
57. r 39a Slab scrap Slab arena_getmem sizeof Slab if scraps amp 255 0 SCRAP scraps gt gt 8 ScrapEntry arena_getmem 256 sizeof ScrapEntry scrap_array scraps slab scrap scrap_array scraps file_name save_string source_name scrap_array scraps file_line source_line scrap_array scraps page 1 scrap array scraps letter 0 writer scrap scrap writer index 0 yo Macro referenced in scrap 38e Accumulate scrap and return scraps 39b int c source_get while 1 switch c case EOF error stderr fs unexpect EOF in scrap 4s 4d Nn command_name scrap_array scraps file_name scrap_array scraps file_line exit 1 case Handle at sign during scrap accumulation 39c break default push c amp writer c source_get break FO Macro referenced in scrap 38e Handle at sign during scrap accumulation 39c c source_get switch c case pushs 0 amp writer c source_get break case Collect user specified index entries 40a case push 0 amp writer return scraps case Handle macro invocation in scrap 40b break default error stderr 4s unexpected 04c in scrap 4s d n command_name c source_name source line exit 1 FO Macro referenced in scrap 39b 39 Collect user specified index entries 40a do char new name 256 char p
58. r messages Global variable declarations 11c extern char command_name Macro defined by scraps llac 32b 37d 47b Macro referenced in scrap 6a Global variable definitions 11d char command_name NULL Macro defined by scraps 11bd 32c 38a 47c Macro referenced in scrap 9d The invocation name is conventionally passed in argv 0 Interpret command line arguments 11e command_name argv 0 o Macro defined by scraps 11ef Macro referenced in scrap 9e We need to examine the remaining entries in argv looking for command line arguments Interpret command line arguments 11f while arg argc 1 char s argv arg if kst 2 Interpret the argument string s 12a arg y else break o Macro defined by scraps llef Macro referenced in scrap 9e 11 Several flags can be stacked behind a single minus sign therefore we ve got to loop through the string handling them all Interpret the argument string s 12a char c ks while c 1 switch c 4 case c compare flag FALSE break case n number flag TRUE break case o output flag FALSE break case t tex flag FALSE break case v verbose flag TRUE break default error stderr 4s unexpected argument ignored Usage is s cnotv file n command_name command_name break c stt JO Macro referenced in scrap 11f 2 2 2 Macintosh Specific
59. renced in scrap 19a 19 Interpret at sequence 20 int big_definition FALSE c source_get switch c 1 case 0 big definition TRUE case o Write output file definition 21a break case D big_definition TRUE case d Write macro definition 21b break case f Write index of file names 25d break case m Write index of macro names 26a break case u Write index of user specified names 28a break case putc c tex file default c source get 0 break y o Macro referenced in scrap 19b 2 4 1 Formatting Definitions We go through a fair amount of effort to format a file definition I ve derived most of the IATEX commands experimentally it s quite likely that an expert could do a better job The TEX for the previous macro definition should look like this perhaps modulo the scrap references Nbegin flushleft small begin minipage linewidth label scrap37 langle Interpret at sequence footnotesize 18 rangle equiv vspace 1ex begin list item mbox verb mbox verb int big definition FALSE mbox verb c source get O WN mbox verb switch c mbox verb case 0 big definition TRUE mbox verb case o langle Write output file definition footnotesize 19a rangle verb0e mbox verb case tt verb putc c tex_file mbox verb default c source_get
60. ro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a We need a few local function declarations before we get into the body of write_tex latex c 18e static void copy scrap formats the body of a scrap static void print scrap numbers formats a list of scrap numbers static void format entry formats an index entry static void format user entry o File defined by scraps 7e 18e 19a 23b 24a 26b 28b 18 The routine write tex takes two file names as parameters the name of the web source file and the name of the tex output file latex c 19a void write tex file name tex name char file name char tex name FILE tex file fopen tex name w if tex file if verbose flag info stderr writing s n tex name source open file name Copy source file into tex file 19b fclose tex file else error stderr 4s can t open 4sAn command_name tex name File defined by scraps 7e 18e 19a 23b 24a 26b 28b We make our second and final pass through the source web this time copying characters straight into the tex file However we keep an eye peeled for characters which signal a command sequence Copy source_file into tex_file 19b int scraps 1 int c source_get while c EOF 1 if c Interpret at sequence 20 else putc c tex_file c source_get y yO Macro refe
61. s extern void write_scrap_ref extern void write_single_scrap_ref Macro defined by scraps 16b 18d 29b 32a 36d 45b 47d 58f 63c Macro referenced in scrap 6a scraps c 36e void init_scraps scraps 1 SCRAP 0 o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab ScrapEntry arena_getmem 256 sizeof ScrapEntry 36 scraps c 37a void write scrap ref file num first page FILE file int num int first int page t if scrap_array num page gt 0 1 if first fprintf file 4d scrap array num page else if scrap array num page page fprintf file kd scrap_array num page if scrap_array num letter gt 0 fputc scrap_array num letter file de else if first putc file else fputs file Warn only once about needing to rerun after Latex 37c page scrap_array num page o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab scraps c 37b void write single scrap ref file num FILE file int num int page write scrap ref file num TRUE amp page File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab Warn only once about needing to rerun after Latex 37c if already_warned info stderr 4s you ll need to rerun nuweb after running latex n command_name already_war
62. s lt s gt never referenced n command_name name gt spelling fputs end list n tex file Jo Macro referenced in scrap 21b latex c 23b static void print scrap numbers tex file scraps FILE xtex file Scrap Node scraps int page write scrap ref tex file scraps gt scrap TRUE amp page scraps scraps gt next while scraps 1 write scrap ref tex file scraps gt scrap FALSE amp page scraps scraps gt next y fputs Na tex file y o File defined by scraps 7e 18e 19a 23b 24a 26b 28b Formatting a Scrap We add a mbox at the beginning of each line to avoid problems with older versions of TEX 23 latex c 24a static void copy_scrap file FILE file int indent 0 int c source_get fputs mbox verb file while 1 switch c case Check at sequence for end of scrap 24c break case n fputs n mbox verbe file indent 0 break case t Expand tab into spaces 24b break default putc c file indent break c source get o File defined by scraps 7e 18e 19a 23b 24a 26b 28b Expand tab into spaces 24b int delta 8 indent 8 indent delta while delta gt 0 1 putc file delta Jo Macro referenced in scraps 24a 44c Check at seguence for end of scrap 24c c source get switch c 1 case Q fputs tt verbO file
63. s They introduce little language dependences however they do so only for a particular file Thus it is still easy to mix languages within a single document There are three per file flags d Forces the creation of line directives in the output file These are useful with C and sometimes C and Fortran on many Unix systems since they cause the compiler s error messages to refer to the web file rather than the output file Similarly they allow source debugging in terms of the web file i Suppresses the indentation of macros That is when a macro is expanded in a scrap it will not be indented to match the indentation of the macro invocation This flag would seem most useful for Fortran programmers t Suppresses expansion of tabs in the output file This feature seems important when generating make files 1 2 2 The Minor Commands We have two very low level utility commands that may appear anywhere in the web file Causes a single at sign to be copied into the output Qi file name Includes a file Includes may be nested though there is currently a limit of 10 levels The file name should be complete no extension will be appended and should be terminated by a carriage return Finally there are three commands used to create indices to the macro names file definitions and user specified identifiers f Create an index of file names Cm Create an index of macro name Cu Create an index of user specified identifi
64. s to work on all the local systems Type declarations 7a ifndef FALSE define FALSE 0 endif ifndef TRUE define TRUE 0 endif o Macro defined by scraps 7ab 46c 47a Macro referenced in scrap 6a Type declarations 7b ifdef __MWERKS__ include DSUtils h include stdarg h extern int error FILE stream const char format define warning error define info error else define error fprintf define warning fprintf define info fprintf endif Macro defined by scraps Tab 46c 47a Macro referenced in scrap 6a 2 1 1 The Main Files The code is divided into four main files introduced here and five support files introduced in the next section The file nuweb c will contain the driver for the whole program see Section 2 2 nuweb c 7c include global h o File defined by scraps 7c 9e The first pass over the source file is contained in pass1 c It handles collection of all the file names macros names and scraps see Section 2 3 pass1 c 7d include global h o File defined by scraps 7d 16c The tex file is created during a second pass over the source file The file latex c contains the code controlling the construction of the tex file see Section 2 4 latex c 7e include global h o File defined by scraps 7e 18e 19a 23b 24a 26b 28b The code controlling the creation of the output files is in output c see Section 2 5 output c 8a incl
65. sman Buyukisik Manuel Carriba Adrian Clarke Tim Harvey Michael Lewis Walter Ravenek Rob Shillingsburg Kayvan Sylvan Dominique de Waleffe and Scott Warren Of course most of these people would never have heard or nuweb or many other tools without the efforts of George Greenwade Chapter 2 The Overall Structure Processing a web requires three major steps 1 Read the source accumulating file names macro names scraps and lists of cross references 2 Reread the source copying out to the tex file with protection and cross reference information for all the scraps 3 Traverse the list of files names For each file name a Dump all the defining scraps into a temporary file b If the file already exists and is unchanged delete the temporary file otherwise rename the temporary file 2 1 Files I have divided the program into several files for quicker recompilation during development global h 6a Include files 6b Type declarations 7a Global variable declarations 11a Function prototypes 16b y o We ll need at least three of the standard system include files Include files 6b include lt stdlib h gt include lt stdio h gt include string h include ctype h o Macro referenced in scrap 6a I also like to use TRUE and FALSE in my code I d use an enum here except that some systems seem to provide definitions of TRUE and FALSE be default The following code seem
66. te indentation 44b yo Macro referenced in scraps 43b 44d Insert appropriate indentation 44b 1 if indent flag if tab flag for indent 0 indent global indent indent putc file else for indent 0 indent global indent indent putc indent chars indent file y indent O Jo Macro referenced in scraps 43b 44a Handle tab characters on output 44c if tab_flag Expand tab into spaces 24b else putc t file if global_indent indent gt 500 error stderr 4s indent_chars array overflow n command_name exit 1 indent_chars global_indent indent t indent Jo Macro referenced in scrap 43b Check for macro invocation in scrap 44d c pop amp reader switch c case putc c file if global_indent indent gt 500 error stderr 4s indent_chars array overflow n command_name exit 1 indent_chars global_indent indent indent break case lt Copy macro into file 45a Insert debugging information if required 44a break default ignore since we should already have a warning break y JO Macro referenced in scrap 43b 44 Copy macro into file 45a Name name pop scrap name kreader if name gt mark error stderr 4s recursive macro discovered involving lt s gt n command_name name gt spelling exit 1 y if name gt defs name gt mark TRUE
67. ude global h o File defined by scraps 8a 30a 2 1 2 Support Files The support files contain a variety of support routines used to define and manipulate the major data ab stractions The file input c holds all the routines used for referring to source files see Section 3 1 input c 8b include global h o File defined by scraps 8b 32d 33ab 35c Creation and lookup of scraps is handled by routines in scraps c see Section 3 2 scraps c 9a include global h o File defined by scraps 9a 36abce 37ab 38bcde 41c 42a 43a 46a 58abcde 59ab 63ab The handling of file names and macro names is detailed in names c see Section 3 3 names c 9b include global h o File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc Memory allocation and deallocation is handled by routines in arena c see Section 3 5 arena c 9c include global h o File defined by scraps 9c 64abc 65c Finally for best portability I seem to need a file containing useless definitions of all the global variables global c 9d include global h Global variable definitions 11b 2 2 The Main Routine The main routine is quite simple in structure It wades through the optional command line arguments then handles any files listed on the command line nuweb c 9e ifdef __MWERKS__ Macintosh utility code 12b else void main argc argv int argc char argv int arg 1
68. x might match more than one macro name I need to check for other matches to avoid mistakes Basically I simply continue the search down both branches of the tree Check for ambiguous prefix 49b if ambiguous_prefix node gt llink spelling ambiguous_prefix node gt rlink spelling warning stderr Zs ambiguous prefix 0 lt 4s 0 gt 4s line d n command_name spelling source_name source_line JO Macro referenced in scrap 49a 49 names c 50 static int ambiguous prefix node spelling Name xnode char spelling while node switch compare node gt spelling spelling 1 case GREATER node node gt rlink break case LESS node node gt llink break case EQUAL case EXTENSION case PREFIX return TRUE y y return FALSE y Q File defined by scraps 9b 48ab 49a 50 51ab 52b 54 56 57bc Rob Shillingsburg suggested that I organize the index of user specified identifiers more traditionally that is not relying on strict ASCII comparisons via strcmp Ideally we d like to see the index ordered like this aardvark Adam atom Atomic atoms The function robs_strcmp implements the desired predicate 50 names c 51a static int robs_strcmp x y char x char y char xx X char yy y int xc toupper xx int yc toupper yy while xc yc amp amp xc XX ye xc toupper xx yc toupper yy y if xc yc return xc yc xc x y
69. x of identifiers Because WEB knows about Pascal it is able to construct an index of all the iden tifiers occurring in the code sections filtering out keywords and the standard type identifiers Unfor tunately this isn t as easy in our case We don t know what an identifiers looks like in each language and we certainly don t know all the keywords On the other hand see the end of Section 1 3 Of course we ve got to have some compensation for our losses or the whole idea would be a waste Here are the advantages I can see Simplicity The majority of the commands in WEB are concerned with control of the automatic pretty printing Since we don t pretty print many commands are eliminated A further set of commands is subsumed by IATEX and may also be eliminated As a result our set of commands is reduced to only four members explained in the next section This simplicity is also reflected in the size of this tool which is quite a bit smaller than the tools used with other approaches No pretty printing Everyone disagrees about how their code should look so automatic formatting annoys many people One approach is to provide ways to control the formatting Our approach is simpler we perform no automatic formatting and therefore allow the programmer complete control of code layout Control We also offer the programmer complete control of the layout of his output files the files generated during tangling Of course this is essential for la
70. ype Handle amp iHndl amp iRect compare_flag compare_flag SetCtlValue iHnd1 compare_flag break case 5 GetDItem myDlg 5 iType Handle amp iHndl amp iRect verbose_flag verbose flag SetCtlValue iHndl verbose flag break case 6 GetDItem myDlg 6 kiType Handle amp iHndl amp iRect number flag number flag SetCtlValue iHndl number flag break while itemHit ok DisposDialog myDlg Jo Macro defined by scraps 12bc 13 14a Macro referenced in scrap 9e Macintosh utility code 13 void process_file char filename char source_name 256 char tex_name 256 char aux name 256 char p filename char q char trim q char dot NULL source name char c command name nuweb c ptt while c 1 qt C if c dot q 1 13 c pt q O if dot dot 0 sprintf tex name s tex trim sprintf aux_name s aux trim dot else sprintf tex name s tex trim sprintf aux name s aux trim qtt 7 7 kqgt wu q NO Process a file 16a o Macro defined by scraps 12bc 13 14a Macro referenced in scrap 9e Macintosh utility code 14a int error FILE stream const char format Str255 msg int i 0 va_list args va_start args format vsprintf char msg format args while msg i if msgli n msg i r i
Download Pdf Manuals
Related Search
Related Contents
HERBALIFELINE, SUPLEMENTO DE OMEGA 3 THERMO JACK - Digitales Einstichthermometer THERMO JACK Maytag MAV-39 User's Manual Samsung 2233RZ Uporabniški priročnik Epson Projector Lamp Livescribe+ Benutzerhandbuch "取扱説明書" Archos FM Remote Control User's Manual Behringer X32 PRODUCER-TP Quick Start Guide Copyright © All rights reserved.
Failed to retrieve file