From 0cc1077c47e6954e29692736bb136caa6935206b Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sat, 23 Apr 2022 23:41:01 +0100 Subject: [PATCH] Using new-style readme scripts --- Chapter 1/Basics.w | 4 - Chapter 1/Program Control.w | 6 +- Chapter 6/Git Support.w | 2 +- Chapter 6/Makefiles.w | 3 +- Chapter 6/Readme Writeme.w | 255 +----- Manual/Webs, Tangling and Weaving.w | 93 +- README.md | 2 +- Tangled/inweb.c | 839 +++++++------------ docs/foundation-module/4-chr.html | 2 +- docs/foundation-module/4-pm.html | 6 +- docs/foundation-module/4-prp.html | 29 +- docs/foundation-module/4-sm.html | 2 +- docs/goldbach/goldbach.pdf | Bin 251998 -> 251998 bytes docs/inweb/1-apacs.html | 2 +- docs/inweb/1-bsc.html | 4 - docs/inweb/1-pc.html | 6 +- docs/inweb/3-tc.html | 4 +- docs/inweb/5-df.html | 2 +- docs/inweb/5-hf.html | 2 +- docs/inweb/5-ptf.html | 2 +- docs/inweb/5-tf.html | 2 +- docs/inweb/5-tu.html | 216 ++--- docs/inweb/5-wt.html | 2 +- docs/inweb/6-gs.html | 2 +- docs/inweb/6-mkf.html | 3 +- docs/inweb/6-rw.html | 347 ++------ docs/inweb/M-wtaw.html | 113 +-- foundation-module/Chapter 4/Preprocessor.w | 26 +- inweb.mk | 4 +- scripts/inweb.mkscript | 4 +- scripts/{READMEscript.txt => inweb.rmscript} | 6 +- 31 files changed, 619 insertions(+), 1371 deletions(-) rename scripts/{READMEscript.txt => inweb.rmscript} (93%) diff --git a/Chapter 1/Basics.w b/Chapter 1/Basics.w index 3c7c799..9a6ad7c 100755 --- a/Chapter 1/Basics.w +++ b/Chapter 1/Basics.w @@ -25,8 +25,6 @@ see //foundation: A Brief Guide to Foundation//. @e hash_table_entry_usage_CLASS @e language_function_CLASS @e language_type_CLASS -@e macro_CLASS -@e macro_tokens_CLASS @e macro_usage_CLASS @e makefile_specifics_CLASS @e nonterminal_variable_CLASS @@ -116,9 +114,7 @@ DECLARE_CLASS(hash_table_entry_usage) DECLARE_CLASS(hash_table_entry) DECLARE_CLASS(language_function) DECLARE_CLASS(language_type) -DECLARE_CLASS(macro_tokens) DECLARE_CLASS(macro_usage) -DECLARE_CLASS(macro) DECLARE_CLASS(makefile_specifics) DECLARE_CLASS(nonterminal_variable) DECLARE_CLASS(para_macro) diff --git a/Chapter 1/Program Control.w b/Chapter 1/Program Control.w index 0469b32..671e5f9 100644 --- a/Chapter 1/Program Control.w +++ b/Chapter 1/Program Control.w @@ -113,11 +113,11 @@ void Main::follow_instructions(inweb_instructions *ins) { @ = if ((ins->makefile_setting) && (ins->prototype_setting == NULL)) - ins->prototype_setting = Filenames::from_text(I"makescript.txt"); + ins->prototype_setting = Filenames::from_text(I"script.mkscript"); if ((ins->gitignore_setting) && (ins->prototype_setting == NULL)) - ins->prototype_setting = Filenames::from_text(I"gitignorescript.txt"); + ins->prototype_setting = Filenames::from_text(I"script.giscript"); if ((ins->writeme_setting) && (ins->prototype_setting == NULL)) - ins->prototype_setting = Filenames::from_text(I"READMEscript.txt"); + ins->prototype_setting = Filenames::from_text(I"script.rmscript"); if (ins->makefile_setting) Makefiles::write(W, ins->prototype_setting, ins->makefile_setting, WebModules::make_search_path(ins->import_setting)); diff --git a/Chapter 6/Git Support.w b/Chapter 6/Git Support.w index 469a701..76f7de1 100644 --- a/Chapter 6/Git Support.w +++ b/Chapter 6/Git Support.w @@ -12,7 +12,7 @@ void Git::write_gitignore(web *W, filename *prototype, filename *F) { WRITE_TO(header, "# This gitignore was automatically written by inweb -gitignore\n"); WRITE_TO(header, "# and is not intended for human editing\n\n"); WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); - Preprocessor::preprocess(prototype, F, header, L, NULL_GENERAL_POINTER); + Preprocessor::preprocess(prototype, F, header, L, NULL_GENERAL_POINTER, '#'); } @ Our one non-standard macro simply includes a file of standing material which diff --git a/Chapter 6/Makefiles.w b/Chapter 6/Makefiles.w index 11bdd61..181ab32 100644 --- a/Chapter 6/Makefiles.w +++ b/Chapter 6/Makefiles.w @@ -35,7 +35,8 @@ void Makefiles::write(web *W, filename *prototype, filename *F, module_search *I WRITE_TO(header, "# and is not intended for human editing\n\n"); WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); - Preprocessor::preprocess(prototype, F, header, L, STORE_POINTER_makefile_specifics(specifics)); + Preprocessor::preprocess(prototype, F, header, L, + STORE_POINTER_makefile_specifics(specifics), '#'); } @ We will allow a makescript to declare "components" (webs, really), so we need diff --git a/Chapter 6/Readme Writeme.w b/Chapter 6/Readme Writeme.w index 7aeed84..bfc8423 100644 --- a/Chapter 6/Readme Writeme.w +++ b/Chapter 6/Readme Writeme.w @@ -2,248 +2,35 @@ To construct Readme and similar files. -@ This is a very simple generator for |README.md| files, written in Markdown -syntax, but with a few macro expansions of our own. The prototype file, which -uses these extra macros, is expanded to the final file, which does not. - -As we scan through the prototype file, we keep track of this: +@ This is a simple use of //foundation: Preprocessor//. Note that we use a +non-standard comment syntax (i.e., |/| at start of line, not |#|) to avoid +colliding with Markdown's heading syntax. = -typedef struct write_state { - struct text_stream *OUT; - struct linked_list *known_macros; /* of |macro| */ - struct macro *current_definition; - struct macro_tokens *stack_frame; -} write_state; - -void Readme::write(filename *from, filename *to) { - WRITE_TO(STDOUT, "write-me: %f --> %f\n", from, to); - write_state ws; - ws.current_definition = NULL; - ws.known_macros = NEW_LINKED_LIST(macro); - macro *V = Readme::new_macro(I"version", NULL, NULL); - ADD_TO_LINKED_LIST(V, macro, ws.known_macros); - macro *P = Readme::new_macro(I"purpose", NULL, NULL); - ADD_TO_LINKED_LIST(P, macro, ws.known_macros); - macro *A = Readme::new_macro(I"var", NULL, NULL); - ADD_TO_LINKED_LIST(A, macro, ws.known_macros); - ws.stack_frame = NULL; - text_stream file_to; - if (Streams::open_to_file(&file_to, to, UTF8_ENC) == FALSE) - Errors::fatal_with_file("can't write readme file", to); - ws.OUT = &file_to; - TextFiles::read(from, FALSE, "unable to read template file", TRUE, - &Readme::write_helper, NULL, (void *) &ws); - Streams::close(&file_to); +void Readme::write(filename *prototype, filename *F) { + linked_list *L = NEW_LINKED_LIST(preprocessor_macro); + preprocessor_macro *mm = Preprocessor::new_macro(L, + I"bibliographic", I"datum: DATUM of: ASSET", + Readme::bibliographic_expander, NULL); + Preprocessor::do_not_suppress_whitespace(mm); + WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); + Preprocessor::preprocess(prototype, F, NULL, L, NULL_GENERAL_POINTER, '/'); } -@ The file consists of definitions of macros, made one at a time, and -starting with |@define| and finishing with |@end|, and actual material. +@ And this is the one domain-specific macro: = -void Readme::write_helper(text_stream *text, text_file_position *tfp, void *state) { - write_state *ws = (write_state *) state; - text_stream *OUT = ws->OUT; - - match_results mr = Regexp::create_mr(); - if (Regexp::match(&mr, text, L" *@end *")) { - if (ws->current_definition == NULL) - Errors::in_text_file("@end without @define", tfp); - else ws->current_definition = NULL; - } else if (ws->current_definition) { - if (Str::len(ws->current_definition->content) > 0) - WRITE_TO(ws->current_definition->content, "\n"); - WRITE_TO(ws->current_definition->content, "%S", text); - } else if (Regexp::match(&mr, text, L" *@define (%i+)(%c*)")) { - if (ws->current_definition) - Errors::in_text_file("@define without @end", tfp); - else { - macro *M = Readme::new_macro(mr.exp[0], mr.exp[1], tfp); - ws->current_definition = M; - ADD_TO_LINKED_LIST(M, macro, ws->known_macros); - } - } else { - Readme::expand_material(ws, OUT, text, tfp); - Readme::expand_material(ws, OUT, I"\n", tfp); - } - Regexp::dispose_of(&mr); +void Readme::bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS, + text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { + text_stream *datum = parameter_values[0]; + text_stream *asset_name = parameter_values[1]; + text_stream *OUT = PPS->dest; + writeme_asset *A = Readme::find_asset(asset_name); + if (A->if_web) WRITE("%S", Bibliographic::get_datum(A->if_web, datum)); + else if (Str::eq(datum, I"Build Date")) WRITE("%S", A->date); + else if (Str::eq(datum, I"Version Number")) WRITE("%S", A->version); } -@ The "content" of a macro is its definition, and the tokens are named -parameters. - -= -typedef struct macro { - struct text_stream *name; - struct text_stream *content; - struct macro_tokens tokens; - CLASS_DEFINITION -} macro; - -macro *Readme::new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) { - macro *M = CREATE(macro); - M->name = Str::duplicate(name); - M->tokens = Readme::parse_token_list(tokens, tfp); - M->content = Str::new(); - return M; -} - -typedef struct macro_tokens { - struct macro *bound_to; - struct text_stream *pars[8]; - int no_pars; - struct macro_tokens *down; - CLASS_DEFINITION -} macro_tokens; - -@ = -macro_tokens Readme::parse_token_list(text_stream *chunk, text_file_position *tfp) { - macro_tokens mt; - mt.no_pars = 0; - mt.down = NULL; - mt.bound_to = NULL; - if (Str::get_first_char(chunk) == '(') { - int x = 1, bl = 1, from = 1, quoted = FALSE; - while ((bl > 0) && (Str::get_at(chunk, x) != 0)) { - wchar_t c = Str::get_at(chunk, x); - if (c == '\'') { - quoted = quoted?FALSE:TRUE; - } else if (quoted == FALSE) { - if (c == '(') bl++; - else if (c == ')') { - bl--; - if (bl == 0) @; - } else if ((c == ',') && (bl == 1)) @; - } - x++; - } - Str::delete_n_characters(chunk, x); - } - return mt; -} - -@ Quotes can be used in token lists so that literal commas and brackets can -be used without breaking the flow. - -@ = - int n = mt.no_pars; - if (n >= 8) Errors::in_text_file("too many parameters", tfp); - else { - mt.pars[n] = Str::new(); - for (int j=from; jstack_frame; - ws->stack_frame = &mt; - Readme::expand_at(ws, OUT, mr.exp[1], tfp); - ws->stack_frame = mt.down; - Readme::expand_material(ws, OUT, mr.exp[2], tfp); - } else { - WRITE("%S", text); - } - Regexp::dispose_of(&mr); -} - -@ If we run into the notation |@something|, it's possible that |something| is -the name of a parameter somewhere in the current stack, either on the top -frame or on frames lower down. The first match wins... and if there are no -matches, then it must be a macro name. - -= -void Readme::expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, - text_file_position *tfp) { - macro_tokens *stack = ws->stack_frame; - while (stack) { - macro *in = stack->bound_to; - if (in) - for (int n = 0; n < in->tokens.no_pars; n++) - if (Str::eq(in->tokens.pars[n], macro_name)) { - if (n < stack->no_pars) { - Readme::expand_material(ws, OUT, stack->pars[n], tfp); - return; - } - } - stack = stack->down; - } - - macro *M; - LOOP_OVER_LINKED_LIST(M, macro, ws->known_macros) - if (Str::eq(M->name, macro_name)) { - ws->stack_frame->bound_to = M; - Readme::expand_macro(ws, OUT, M, tfp); - return; - } - Errors::in_text_file("no such @-command", tfp); - WRITE_TO(STDERR, "(command is '%S')\n", macro_name); -} - -@ So, then: suppose we have to expand |@example(5, gold rings)|. Then the -|macro_name| below is set to |example|, and the current stack frame contains the -values |5| and |gold rings|. - -= -void Readme::expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) { - if (Str::eq(M->name, I"version")) @ - else if (Str::eq(M->name, I"purpose")) @ - else if (Str::eq(M->name, I"var")) @ - else { - ws->stack_frame->bound_to = M; - Readme::expand_material(ws, OUT, M->content, tfp); - } -} - -@ = - if (ws->stack_frame->no_pars != 1) - Errors::in_text_file("@version takes 1 parameter", tfp); - else { - TEMPORARY_TEXT(program) - Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme::write_var(OUT, program, I"Version Number"); - DISCARD_TEXT(program) - } - -@ = - if (ws->stack_frame->no_pars != 1) - Errors::in_text_file("@purpose takes 1 parameter", tfp); - else { - TEMPORARY_TEXT(program) - Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme::write_var(OUT, program, I"Purpose"); - DISCARD_TEXT(program) - } - -@ = - if (ws->stack_frame->no_pars != 2) - Errors::in_text_file("@var takes 2 parameters", tfp); - else { - TEMPORARY_TEXT(program) - TEMPORARY_TEXT(bibv) - Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme::expand_material(ws, bibv, ws->stack_frame->pars[1], tfp); - Readme::write_var(OUT, program, bibv); - DISCARD_TEXT(program) - DISCARD_TEXT(bibv) - } - @ An "asset" here is something for which we might want to write the version number of, or some similar metadata for. Assets are usually webs, but can also be a few other rather Inform-specific things; those have a more limited diff --git a/Manual/Webs, Tangling and Weaving.w b/Manual/Webs, Tangling and Weaving.w index d954d7f..0567fee 100644 --- a/Manual/Webs, Tangling and Weaving.w +++ b/Manual/Webs, Tangling and Weaving.w @@ -655,24 +655,6 @@ not |.mkscript|, and: if the web provided no script of its own; the idea is that you can then list some additional things to ignore. -@h Ctags. -Each time a web is tangled, Inweb writes a |tags| file to the web's home -directory, containing a list of //Universal ctags -> https://ctags.io// -for any structures, functions or constant definitions found in the web. You -need do nothing to make this happen, and can ignore the file if it's of no -use. If you are editing a web in certain text editors, though, such as -//BBEdit -> https://www.barebones.com/products/bbedit// for MacOS, then this -should make code completion and definition lookup features work. - -You can however write the file elsewhere: -= (text as ConsoleText) - $ inweb/Tangled/inweb W -tangle -ctags-to secret_lair/my_nifty.ctags -= -or not at all: -= (text as ConsoleText) - $ inweb/Tangled/inweb W -tangle -no-ctags -= - @h README files. Repositories at Github customarily have |README.mk| files, in Markdown syntax, explaining what they are. These of course should probably include @@ -680,55 +662,20 @@ current version numbers, and it's a pain keeping that up to date. For really complicated repositories, containing multiple webs, some automation is essential, and once again Inweb can oblige. = (text as ConsoleText) - $ inweb/Tangled/inweb W -write-me W/README.mk + $ inweb/Tangled/inweb W -prototype W/W.rmscript -write-me W/README.mk = -expands a script called |READMEscript.txt| into |README.mk|. Alternatively, -the script can be specified explicitly: -= (text as ConsoleText) - $ inweb/Tangled/inweb W -prototype MySpecialThang.txt -write-me W/README.mk -= -@ Everything in the script is copied over verbatim except where the |@| character -is used, which was chosen because it isn't significant in Github's form of -Markdown. |@name(args)| is like a function call (or, in more traditional -language, a macro): it expands out to something depending on the arguments. -|args| is a comma-separated list of fragments of text, which can themselves -contain further uses of |@|. (If these fragments of text need to contain -commas or brackets, they can be put into single quotes: |@thus(4,',')| has -two arguments, |4| and |,|.) Three functions are built in: +The same conventions and notations are used here as for makefiles and gitignores +(see above), except that the comment character is no longer |#|, since a |#| +at the start of a line means a heading in Markdown. Instead, a line is a comment +if its first non-whitespace character is a forward-slash |/|. -(a) |@version(A)| expands to the version number of |A|, which is normally the -path to a web; it then produces the value of the |[[Version Number]]| for -that web. But |A| can also be the filename of an Inform extension, provided -that it ends in |.i7x|, or a few other Inform-specific things for which -Inweb is able to deduce a version number. +(*) The special makefile macros are not available, though |set| and |repeat| are; -(b) |@purpose(A)| is the same, but for the |[[Purpose]]| of a web. It's -blank for everything else. - -(c) |@var(A,D)| is more general, and reads the bibliographic datum |D| from -the web indicated by |A|. In fact, |@version(A)| is an abbreviation for -|@var(A,Version Number)| and |@purpose(A)| for |@var(A,Purpose)|, so this -is really the only one needed. - -@ It is also possible to define new functions. For example: -= (text) - @define book(title, path, topic) - * @title - @topic. Ebook in Indoc format, stored at path @path. - @end -= -The definition lies between |@define| and |@end| commands. This one takes -three parameters, and inside the definition, their values can be referred -to as |@title|, |@path| and |@topic|. Functions are free to use other -functions: -= (text) - @define primary(program, language) - * @program - @purpose(@program) - __@version(@program)__ - @end -= -However, each function needs to have been defined before any line on which -it is actually expanded. A definition of one function |A| can refer to another -function |B| not yet defined; but any actual use of |A| must be made after -both |A| and |B| have been defined. So, basically, declare before use. +(*) The special macro |{bibliographic datum: ... of: ...}| expands to the value +of the named bibliographic datum for the program named. |Version Number| is +especially useful, and is available even for some Inform assets which are not +webs and do not therefore have bibliographic data of their own -- interpreter +templates and Inform 7 extensions, for example. @h Semantic version numbering and build metadata. When Inweb reads in a web, it also looks for a file called |build.txt| in @@ -763,3 +710,21 @@ is advanced by one. Running |-advance-build-file B| does this for a stand-alone build file |B|, without need of a web. + +@h Ctags. +Each time a web is tangled, Inweb writes a |tags| file to the web's home +directory, containing a list of //Universal ctags -> https://ctags.io// +for any structures, functions or constant definitions found in the web. You +need do nothing to make this happen, and can ignore the file if it's of no +use. If you are editing a web in certain text editors, though, such as +//BBEdit -> https://www.barebones.com/products/bbedit// for MacOS, then this +should make code completion and definition lookup features work. + +You can however write the file elsewhere: += (text as ConsoleText) + $ inweb/Tangled/inweb W -tangle -ctags-to secret_lair/my_nifty.ctags += +or not at all: += (text as ConsoleText) + $ inweb/Tangled/inweb W -tangle -no-ctags += diff --git a/README.md b/README.md index e64c7bf..0ef1687 100644 --- a/README.md +++ b/README.md @@ -85,5 +85,5 @@ If you have also built Intest as "work/intest", then you can try these: ### Colophon This README.mk file was generated automatically by Inweb, and should not -be edited. To make changes, edit scripts/READMEscript.txt and re-generate. +be edited. To make changes, edit inweb.rmscript and re-generate. diff --git a/Tangled/inweb.c b/Tangled/inweb.c index a0fb12c..ae102c2 100644 --- a/Tangled/inweb.c +++ b/Tangled/inweb.c @@ -809,76 +809,74 @@ struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; }; #define hash_table_entry_usage_CLASS 54 #define language_function_CLASS 55 #define language_type_CLASS 56 -#define macro_CLASS 57 -#define macro_tokens_CLASS 58 -#define macro_usage_CLASS 59 -#define makefile_specifics_CLASS 60 -#define nonterminal_variable_CLASS 61 -#define para_macro_CLASS 62 -#define paragraph_CLASS 63 -#define paragraph_tagging_CLASS 64 -#define preform_nonterminal_CLASS 65 -#define programming_language_CLASS 66 -#define reserved_word_CLASS 67 -#define section_CLASS 68 -#define source_line_CLASS 69 -#define structure_element_CLASS 70 -#define tangle_target_CLASS 71 -#define tex_results_CLASS 72 -#define text_literal_CLASS 73 -#define theme_tag_CLASS 74 -#define weave_format_CLASS 75 -#define weave_pattern_CLASS 76 -#define weave_plugin_CLASS 77 -#define weave_order_CLASS 78 -#define web_CLASS 79 -#define writeme_asset_CLASS 80 -#define weave_document_node_CLASS 81 -#define weave_head_node_CLASS 82 -#define weave_body_node_CLASS 83 -#define weave_tail_node_CLASS 84 -#define weave_section_header_node_CLASS 85 -#define weave_section_footer_node_CLASS 86 -#define weave_chapter_header_node_CLASS 87 -#define weave_chapter_footer_node_CLASS 88 -#define weave_verbatim_node_CLASS 89 -#define weave_section_purpose_node_CLASS 90 -#define weave_subheading_node_CLASS 91 -#define weave_bar_node_CLASS 92 -#define weave_linebreak_node_CLASS 93 -#define weave_pagebreak_node_CLASS 94 -#define weave_paragraph_heading_node_CLASS 95 -#define weave_endnote_node_CLASS 96 -#define weave_material_node_CLASS 97 -#define weave_figure_node_CLASS 98 -#define weave_extract_node_CLASS 99 -#define weave_audio_node_CLASS 100 -#define weave_download_node_CLASS 101 -#define weave_video_node_CLASS 102 -#define weave_embed_node_CLASS 103 -#define weave_pmac_node_CLASS 104 -#define weave_vskip_node_CLASS 105 -#define weave_chapter_node_CLASS 106 -#define weave_section_node_CLASS 107 -#define weave_code_line_node_CLASS 108 -#define weave_function_usage_node_CLASS 109 -#define weave_commentary_node_CLASS 110 -#define weave_carousel_slide_node_CLASS 111 -#define weave_toc_node_CLASS 112 -#define weave_toc_line_node_CLASS 113 -#define weave_chapter_title_page_node_CLASS 114 -#define weave_defn_node_CLASS 115 -#define weave_source_code_node_CLASS 116 -#define weave_url_node_CLASS 117 -#define weave_footnote_cue_node_CLASS 118 -#define weave_begin_footnote_text_node_CLASS 119 -#define weave_display_line_node_CLASS 120 -#define weave_function_defn_node_CLASS 121 -#define weave_item_node_CLASS 122 -#define weave_grammar_index_node_CLASS 123 -#define weave_inline_node_CLASS 124 -#define weave_locale_node_CLASS 125 -#define weave_maths_node_CLASS 126 +#define macro_usage_CLASS 57 +#define makefile_specifics_CLASS 58 +#define nonterminal_variable_CLASS 59 +#define para_macro_CLASS 60 +#define paragraph_CLASS 61 +#define paragraph_tagging_CLASS 62 +#define preform_nonterminal_CLASS 63 +#define programming_language_CLASS 64 +#define reserved_word_CLASS 65 +#define section_CLASS 66 +#define source_line_CLASS 67 +#define structure_element_CLASS 68 +#define tangle_target_CLASS 69 +#define tex_results_CLASS 70 +#define text_literal_CLASS 71 +#define theme_tag_CLASS 72 +#define weave_format_CLASS 73 +#define weave_pattern_CLASS 74 +#define weave_plugin_CLASS 75 +#define weave_order_CLASS 76 +#define web_CLASS 77 +#define writeme_asset_CLASS 78 +#define weave_document_node_CLASS 79 +#define weave_head_node_CLASS 80 +#define weave_body_node_CLASS 81 +#define weave_tail_node_CLASS 82 +#define weave_section_header_node_CLASS 83 +#define weave_section_footer_node_CLASS 84 +#define weave_chapter_header_node_CLASS 85 +#define weave_chapter_footer_node_CLASS 86 +#define weave_verbatim_node_CLASS 87 +#define weave_section_purpose_node_CLASS 88 +#define weave_subheading_node_CLASS 89 +#define weave_bar_node_CLASS 90 +#define weave_linebreak_node_CLASS 91 +#define weave_pagebreak_node_CLASS 92 +#define weave_paragraph_heading_node_CLASS 93 +#define weave_endnote_node_CLASS 94 +#define weave_material_node_CLASS 95 +#define weave_figure_node_CLASS 96 +#define weave_extract_node_CLASS 97 +#define weave_audio_node_CLASS 98 +#define weave_download_node_CLASS 99 +#define weave_video_node_CLASS 100 +#define weave_embed_node_CLASS 101 +#define weave_pmac_node_CLASS 102 +#define weave_vskip_node_CLASS 103 +#define weave_chapter_node_CLASS 104 +#define weave_section_node_CLASS 105 +#define weave_code_line_node_CLASS 106 +#define weave_function_usage_node_CLASS 107 +#define weave_commentary_node_CLASS 108 +#define weave_carousel_slide_node_CLASS 109 +#define weave_toc_node_CLASS 110 +#define weave_toc_line_node_CLASS 111 +#define weave_chapter_title_page_node_CLASS 112 +#define weave_defn_node_CLASS 113 +#define weave_source_code_node_CLASS 114 +#define weave_url_node_CLASS 115 +#define weave_footnote_cue_node_CLASS 116 +#define weave_begin_footnote_text_node_CLASS 117 +#define weave_display_line_node_CLASS 118 +#define weave_function_defn_node_CLASS 119 +#define weave_item_node_CLASS 120 +#define weave_grammar_index_node_CLASS 121 +#define weave_inline_node_CLASS 122 +#define weave_locale_node_CLASS 123 +#define weave_maths_node_CLASS 124 #define NO_MODE 0 #define ANALYSE_MODE 1 #define TANGLE_MODE 2 @@ -1095,7 +1093,7 @@ struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; }; #define PDFTEX_TEX_FORM 1 #define NO_DEFINED_CLSW_VALUES 38 #define NO_DEFINED_DA_VALUES 4 -#define NO_DEFINED_CLASS_VALUES 127 +#define NO_DEFINED_CLASS_VALUES 125 #define NO_DEFINED_MREASON_VALUES 5 #define NO_DEFINED_LOCALE_VALUES 2 #define NO_DEFINED_MTID_VALUES 42 @@ -1311,7 +1309,7 @@ typedef struct text_file_position { int skip_terminator; int actively_scanning; /* whether we are still interested in the rest of the file */ } text_file_position; -#line 58 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 59 "inweb/foundation-module/Chapter 4/Preprocessor.w" typedef struct preprocessor_loop { struct text_stream *loop_var_name; struct linked_list *iterations; /* of |text_stream| */ @@ -1331,20 +1329,21 @@ typedef struct preprocessor_state { struct preprocessor_variable_set *stack_frame; struct linked_list *known_macros; /* of |preprocessor_macro| */ struct general_pointer specifics; + wchar_t comment_character; } preprocessor_state; -#line 413 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 422 "inweb/foundation-module/Chapter 4/Preprocessor.w" typedef struct preprocessor_variable { struct text_stream *name; struct text_stream *value; CLASS_DEFINITION } preprocessor_variable; -#line 433 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 442 "inweb/foundation-module/Chapter 4/Preprocessor.w" typedef struct preprocessor_variable_set { struct linked_list *variables; /* of |preprocessor_variable| */ struct preprocessor_variable_set *outer; CLASS_DEFINITION } preprocessor_variable_set; -#line 506 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 515 "inweb/foundation-module/Chapter 4/Preprocessor.w" typedef struct preprocessor_macro { /* syntax */ struct text_stream *identifier; @@ -1368,7 +1367,7 @@ typedef struct preprocessor_macro { CLASS_DEFINITION } preprocessor_macro; -#line 530 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 539 "inweb/foundation-module/Chapter 4/Preprocessor.w" typedef struct preprocessor_macro_parameter { struct text_stream *name; struct text_stream *definition_token; @@ -2407,7 +2406,7 @@ typedef struct tex_results { struct filename *PDF_filename; CLASS_DEFINITION } tex_results; -#line 45 "inweb/Chapter 6/Makefiles.w" +#line 46 "inweb/Chapter 6/Makefiles.w" typedef struct makefile_specifics { struct web *for_web; /* if one has been set at the command line */ struct dictionary *tools_dictionary; /* components with |type: tool| */ @@ -2422,29 +2421,7 @@ typedef struct defined_constant { struct source_line *at; CLASS_DEFINITION } defined_constant; -#line 12 "inweb/Chapter 6/Readme Writeme.w" -typedef struct write_state { - struct text_stream *OUT; - struct linked_list *known_macros; /* of |macro| */ - struct macro *current_definition; - struct macro_tokens *stack_frame; -} write_state; -#line 91 "inweb/Chapter 6/Readme Writeme.w" -typedef struct macro_tokens { - struct macro *bound_to; - struct text_stream *pars[8]; - int no_pars; - struct macro_tokens *down; - CLASS_DEFINITION -} macro_tokens; -#line 76 "inweb/Chapter 6/Readme Writeme.w" -typedef struct macro { - struct text_stream *name; - struct text_stream *content; - struct macro_tokens tokens; - CLASS_DEFINITION -} macro; -#line 254 "inweb/Chapter 6/Readme Writeme.w" +#line 41 "inweb/Chapter 6/Readme Writeme.w" typedef struct writeme_asset { struct text_stream *name; struct web_md *if_web; @@ -3439,46 +3416,48 @@ unicode_file_buffer TextFiles__create_ufb(void) ; #line 226 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, unicode_file_buffer *ufb) ; #line 23 "inweb/foundation-module/Chapter 4/Preprocessor.w" -void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header, linked_list *special_macros, general_pointer specifics) ; -#line 81 "inweb/foundation-module/Chapter 4/Preprocessor.w" +void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header, linked_list *special_macros, general_pointer specifics, wchar_t comment_char) ; +#line 83 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__set_loop_var_name(preprocessor_loop *loop, text_stream *name) ; -#line 84 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 86 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__add_loop_iteration(preprocessor_loop *loop, text_stream *value) ; -#line 96 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 98 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X) ; -#line 160 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 169 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocessor_state *PPS) ; -#line 399 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 408 "inweb/foundation-module/Chapter 4/Preprocessor.w" int Preprocessor__acceptable_variable_name(text_stream *name) ; -#line 419 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 428 "inweb/foundation-module/Chapter 4/Preprocessor.w" text_stream * Preprocessor__read_variable(preprocessor_variable *var) ; -#line 423 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 432 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__write_variable(preprocessor_variable *var, text_stream *val) ; -#line 439 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 448 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable_set * Preprocessor__new_variable_set(preprocessor_variable_set *outer) ; -#line 446 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 455 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable * Preprocessor__find_variable_in_one(text_stream *name, preprocessor_variable_set *set) ; -#line 456 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 465 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable * Preprocessor__find_variable(text_stream *name, preprocessor_variable_set *set) ; -#line 470 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 479 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable * Preprocessor__ensure_variable(text_stream *name, preprocessor_variable_set *in_set) ; -#line 547 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 556 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro * Preprocessor__new_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), text_file_position *tfp) ; -#line 607 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 616 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__add_line_to_macro(preprocessor_macro *mm, text_stream *line, text_file_position *tfp) ; -#line 625 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 634 "inweb/foundation-module/Chapter 4/Preprocessor.w" linked_list * Preprocessor__list_of_reserved_macros(linked_list *special_macros) ; -#line 638 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 647 "inweb/foundation-module/Chapter 4/Preprocessor.w" +void Preprocessor__do_not_suppress_whitespace(preprocessor_macro *mm) ; +#line 652 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__new_loop_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), text_file_position *tfp) ; -#line 679 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 691 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro * Preprocessor__find_macro(linked_list *L, text_stream *name) ; -#line 694 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 706 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__default_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 711 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 723 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__set_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 726 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 738 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 755 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 767 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; #line 77 "inweb/foundation-module/Chapter 4/Tries and Avinues.w" wchar_t * Tries__search(match_trie *T, text_stream *p, wchar_t *add_outcome) ; @@ -4578,21 +4557,21 @@ void TeXUtilities__remove_math_mode(OUTPUT_STREAM, text_stream *text) ; void TeXUtilities__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) ; #line 12 "inweb/Chapter 6/Makefiles.w" void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I) ; -#line 64 "inweb/Chapter 6/Makefiles.w" +#line 65 "inweb/Chapter 6/Makefiles.w" void Makefiles__identity_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 86 "inweb/Chapter 6/Makefiles.w" +#line 87 "inweb/Chapter 6/Makefiles.w" void Makefiles__platform_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 108 "inweb/Chapter 6/Makefiles.w" +#line 109 "inweb/Chapter 6/Makefiles.w" void Makefiles__seek_INWEBPLATFORM(text_stream *line, text_file_position *tfp, void *X) ; -#line 118 "inweb/Chapter 6/Makefiles.w" +#line 119 "inweb/Chapter 6/Makefiles.w" void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 168 "inweb/Chapter 6/Makefiles.w" +#line 169 "inweb/Chapter 6/Makefiles.w" void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 201 "inweb/Chapter 6/Makefiles.w" +#line 202 "inweb/Chapter 6/Makefiles.w" void Makefiles__dependent_files_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; -#line 257 "inweb/Chapter 6/Makefiles.w" +#line 258 "inweb/Chapter 6/Makefiles.w" void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) ; -#line 298 "inweb/Chapter 6/Makefiles.w" +#line 299 "inweb/Chapter 6/Makefiles.w" void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) ; #line 8 "inweb/Chapter 6/Git Support.w" void Git__write_gitignore(web *W, filename *prototype, filename *F) ; @@ -4604,31 +4583,21 @@ void Ctags__write(web *W, filename *F) ; void Ctags__write_line_ref(OUTPUT_STREAM, source_line *L, pathname *P) ; #line 182 "inweb/Chapter 6/Ctags Support.w" void Ctags__note_defined_constant(source_line *L, text_stream *name) ; -#line 19 "inweb/Chapter 6/Readme Writeme.w" -void Readme__write(filename *from, filename *to) ; -#line 44 "inweb/Chapter 6/Readme Writeme.w" -void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) ; -#line 83 "inweb/Chapter 6/Readme Writeme.w" -macro * Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) ; -#line 100 "inweb/Chapter 6/Readme Writeme.w" -macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) ; -#line 149 "inweb/Chapter 6/Readme Writeme.w" -void Readme__expand_material(write_state *ws, text_stream *OUT, text_stream *text, text_file_position *tfp) ; -#line 172 "inweb/Chapter 6/Readme Writeme.w" -void Readme__expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, text_file_position *tfp) ; -#line 204 "inweb/Chapter 6/Readme Writeme.w" -void Readme__expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) ; -#line 263 "inweb/Chapter 6/Readme Writeme.w" +#line 10 "inweb/Chapter 6/Readme Writeme.w" +void Readme__write(filename *prototype, filename *F) ; +#line 23 "inweb/Chapter 6/Readme Writeme.w" +void Readme__bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ; +#line 50 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) ; -#line 273 "inweb/Chapter 6/Readme Writeme.w" +#line 60 "inweb/Chapter 6/Readme Writeme.w" writeme_asset * Readme__find_asset(text_stream *program) ; -#line 324 "inweb/Chapter 6/Readme Writeme.w" +#line 111 "inweb/Chapter 6/Readme Writeme.w" void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) ; -#line 336 "inweb/Chapter 6/Readme Writeme.w" +#line 123 "inweb/Chapter 6/Readme Writeme.w" void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) ; -#line 350 "inweb/Chapter 6/Readme Writeme.w" +#line 137 "inweb/Chapter 6/Readme Writeme.w" void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) ; -#line 366 "inweb/Chapter 6/Readme Writeme.w" +#line 153 "inweb/Chapter 6/Readme Writeme.w" void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) ; #line 66 "inweb/Chapter 6/Colonies.w" void Colonies__load(filename *F) ; @@ -5346,11 +5315,6 @@ text_stream *TL_IS_675 = NULL; text_stream *TL_IS_676 = NULL; text_stream *TL_IS_677 = NULL; text_stream *TL_IS_678 = NULL; -text_stream *TL_IS_679 = NULL; -text_stream *TL_IS_680 = NULL; -text_stream *TL_IS_681 = NULL; -text_stream *TL_IS_682 = NULL; -text_stream *TL_IS_683 = NULL; void register_tangled_text_literals(void); #line 57 "inweb/foundation-module/Chapter 2/Streams.w" #define WRITE(args...) Writers__printf(OUT, args) @@ -11215,7 +11179,7 @@ int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, #line 23 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header, - linked_list *special_macros, general_pointer specifics) { + linked_list *special_macros, general_pointer specifics, wchar_t comment_char) { struct text_stream processed_file; if (STREAM_OPEN_TO_FILE(&processed_file, F, ISO_ENC) == FALSE) Errors__fatal_with_file("unable to write tangled file", F); @@ -11225,7 +11189,7 @@ void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *hea preprocessor_state PPS; { -#line 66 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 67 "inweb/foundation-module/Chapter 4/Preprocessor.w" PPS.dest = OUT; PPS.suppress_newline = FALSE; PPS.last_line_was_blank = TRUE; @@ -11236,6 +11200,7 @@ void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *hea PPS.stack_frame = PPS.global_variables; PPS.known_macros = Preprocessor__list_of_reserved_macros(special_macros); PPS.specifics = specifics; + PPS.comment_character = comment_char; } #line 32 "inweb/foundation-module/Chapter 4/Preprocessor.w" @@ -11245,11 +11210,11 @@ void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *hea STREAM_CLOSE(OUT); } -#line 57 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 58 "inweb/foundation-module/Chapter 4/Preprocessor.w" -#line 64 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 65 "inweb/foundation-module/Chapter 4/Preprocessor.w" -#line 81 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 83 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__set_loop_var_name(preprocessor_loop *loop, text_stream *name) { loop->loop_var_name = Str__duplicate(name); } @@ -11257,24 +11222,28 @@ void Preprocessor__add_loop_iteration(preprocessor_loop *loop, text_stream *valu ADD_TO_LINKED_LIST(Str__duplicate(value), text_stream, loop->iterations); } -#line 96 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 98 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X) { preprocessor_state *PPS = (preprocessor_state *) X; - match_results mr = Regexp__create_mr(); { -#line 106 "inweb/foundation-module/Chapter 4/Preprocessor.w" - if (Regexp__match(&mr, line, L" *#%c*")) { Regexp__dispose_of(&mr); return; } +#line 110 "inweb/foundation-module/Chapter 4/Preprocessor.w" + LOOP_THROUGH_TEXT(pos, line) { + wchar_t c = Str__get(pos); + if (c == PPS->comment_character) return; + if (Characters__is_whitespace(c) == FALSE) break; + } } -#line 99 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 100 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; { -#line 109 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 117 "inweb/foundation-module/Chapter 4/Preprocessor.w" + match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L" *{define: *(%C+) (%c*)} *")) { -#line 115 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 124 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (PPS->defining) Errors__in_text_file("nested definitions are not allowed", tfp); text_stream *name = mr.exp[0]; @@ -11285,11 +11254,11 @@ void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X return; } -#line 109 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 118 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; if (Regexp__match(&mr, line, L" *{end-define} *")) { -#line 130 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 139 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (PPS->defining == NULL) Errors__in_text_file("{end-define} without {define: ...}", tfp); PPS->defining = NULL; @@ -11297,27 +11266,27 @@ void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X return; } -#line 110 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 119 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; if (PPS->defining) { -#line 125 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 134 "inweb/foundation-module/Chapter 4/Preprocessor.w" Preprocessor__add_line_to_macro(PPS->defining, line, tfp); Regexp__dispose_of(&mr); return; } -#line 111 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 120 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; Regexp__dispose_of(&mr); } -#line 100 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 101 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; Preprocessor__expand(line, tfp, PPS); { -#line 137 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 146 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (PPS->suppress_newline == FALSE) { text_stream *OUT = PPS->dest; if (Str__len(line) == 0) { @@ -11331,11 +11300,11 @@ void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X PPS->suppress_newline = FALSE; } -#line 102 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 103 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } -#line 160 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 169 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocessor_state *PPS) { TEMPORARY_TEXT(before_matter) TEMPORARY_TEXT(braced_matter) @@ -11361,18 +11330,18 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess if (after_times) { { -#line 197 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 206 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (Preprocessor__acceptable_variable_name(braced_matter)) { { -#line 258 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 267 "inweb/foundation-module/Chapter 4/Preprocessor.w" Preprocessor__expand(before_matter, tfp, PPS); if (PPS->repeat_sp > 0) { WRITE_TO(PPS->dest, "{%S}", braced_matter); } else { { -#line 303 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 312 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable *var = Preprocessor__find_variable(braced_matter, PPS->stack_frame); if (var) { @@ -11385,13 +11354,13 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } } -#line 262 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 271 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } Preprocessor__expand(after_matter, tfp, PPS); } -#line 198 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 207 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } else { text_stream *identifier = braced_matter; @@ -11403,7 +11372,7 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } { -#line 225 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 234 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro *loop_mm; LOOP_OVER_LINKED_LIST(loop_mm, preprocessor_macro, PPS->known_macros) if (Str__len(loop_mm->loop_name) > 0) { @@ -11432,7 +11401,7 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } } -#line 207 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 216 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; preprocessor_macro *mm = Preprocessor__find_macro(PPS->known_macros, identifier); @@ -11444,7 +11413,7 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } else { { -#line 274 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 283 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (mm->suppress_whitespace_when_expanding) { while (Characters__is_whitespace(Str__get_last_char(before_matter))) Str__delete_last_character(before_matter); @@ -11466,12 +11435,12 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } else { { -#line 318 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 327 "inweb/foundation-module/Chapter 4/Preprocessor.w" text_stream *parameter_values[MAX_PP_MACRO_PARAMETERS]; for (int i=0; ino_parameters; i++) if (parameter_values[i] == NULL) if (mm->parameters[i]->optional == FALSE) { @@ -11522,13 +11491,13 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } } -#line 321 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 330 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; preprocessor_loop *loop = NULL; if (mm->begins_loop) { -#line 382 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 391 "inweb/foundation-module/Chapter 4/Preprocessor.w" if (PPS->repeat_sp >= MAX_PREPROCESSOR_LOOP_DEPTH) { Errors__in_text_file("repetition too deep", tfp); } else { @@ -11543,27 +11512,27 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess } } -#line 324 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 333 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; (*(mm->expander))(mm, PPS, parameter_values, loop, tfp); } -#line 293 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 302 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; if (mm->suppress_newline_after_expanding) PPS->suppress_newline = TRUE; } Preprocessor__expand(after_matter, tfp, PPS); } -#line 216 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 225 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } Regexp__dispose_of(&mr); } } -#line 183 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 192 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } else { WRITE_TO(PPS->dest, "%S", text); @@ -11573,7 +11542,7 @@ void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocess DISCARD_TEXT(after_matter) } -#line 399 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 408 "inweb/foundation-module/Chapter 4/Preprocessor.w" int Preprocessor__acceptable_variable_name(text_stream *name) { LOOP_THROUGH_TEXT(pos, name) { wchar_t c = Str__get(pos); @@ -11585,7 +11554,7 @@ int Preprocessor__acceptable_variable_name(text_stream *name) { return TRUE; } -#line 418 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 427 "inweb/foundation-module/Chapter 4/Preprocessor.w" text_stream *Preprocessor__read_variable(preprocessor_variable *var) { if (var == NULL) internal_error("no such pp variable"); @@ -11596,7 +11565,7 @@ void Preprocessor__write_variable(preprocessor_variable *var, text_stream *val) var->value = Str__duplicate(val); } -#line 438 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 447 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable_set *Preprocessor__new_variable_set(preprocessor_variable_set *outer) { preprocessor_variable_set *set = CREATE(preprocessor_variable_set); @@ -11625,7 +11594,7 @@ preprocessor_variable *Preprocessor__find_variable(text_stream *name, return NULL; } -#line 470 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 479 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_variable *Preprocessor__ensure_variable(text_stream *name, preprocessor_variable_set *in_set) { if (in_set == NULL) internal_error("variable without set"); @@ -11639,11 +11608,11 @@ preprocessor_variable *Preprocessor__ensure_variable(text_stream *name, return var; } -#line 529 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 538 "inweb/foundation-module/Chapter 4/Preprocessor.w" -#line 536 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 545 "inweb/foundation-module/Chapter 4/Preprocessor.w" -#line 547 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 556 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), @@ -11653,7 +11622,7 @@ preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, preprocessor_macro *new_macro = CREATE(preprocessor_macro); { -#line 561 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 570 "inweb/foundation-module/Chapter 4/Preprocessor.w" new_macro->identifier = Str__duplicate(name); new_macro->no_parameters = 0; @@ -11668,11 +11637,11 @@ preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, new_macro->suppress_whitespace_when_expanding = TRUE; } -#line 554 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 563 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; { -#line 575 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 584 "inweb/foundation-module/Chapter 4/Preprocessor.w" text_stream *spec = Str__duplicate(parameter_specification); match_results mr = Regexp__create_mr(); while (Regexp__match(&mr, spec, L" *(%C+): *(%C+) *(%c*)")) { @@ -11685,7 +11654,7 @@ preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, } else { { -#line 593 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 602 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro_parameter *new_parameter = CREATE(preprocessor_macro_parameter); new_parameter->name = Str__duplicate(par_name); new_parameter->definition_token = Str__duplicate(token_name); @@ -11697,7 +11666,7 @@ preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, new_macro->parameters[new_macro->no_parameters++] = new_parameter; } -#line 585 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 594 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; } } @@ -11706,13 +11675,13 @@ preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name, Errors__in_text_file("parameter list for this definition is malformed", tfp); } -#line 555 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 564 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; ADD_TO_LINKED_LIST(new_macro, preprocessor_macro, L); return new_macro; } -#line 607 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 616 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__add_line_to_macro(preprocessor_macro *mm, text_stream *line, text_file_position *tfp) { if (mm->no_lines >= MAX_PP_MACRO_LINES) { @@ -11722,7 +11691,7 @@ void Preprocessor__add_line_to_macro(preprocessor_macro *mm, text_stream *line, } } -#line 625 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 634 "inweb/foundation-module/Chapter 4/Preprocessor.w" linked_list *Preprocessor__list_of_reserved_macros(linked_list *special_macros) { linked_list *L = NEW_LINKED_LIST(preprocessor_macro); Preprocessor__new_loop_macro(L, TL_IS_5, TL_IS_6, @@ -11736,6 +11705,11 @@ linked_list *Preprocessor__list_of_reserved_macros(linked_list *special_macros) return L; } +void Preprocessor__do_not_suppress_whitespace(preprocessor_macro *mm) { + mm->suppress_newline_after_expanding = FALSE; + mm->suppress_whitespace_when_expanding = FALSE; +} + void Preprocessor__new_loop_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), @@ -11758,23 +11732,21 @@ void Preprocessor__new_loop_macro(linked_list *L, text_stream *name, mm = Preprocessor__new_macro(L, subname, parameter_specification, expander, tfp); mm->begins_loop = TRUE; mm->loop_name = Str__duplicate(name); - mm->suppress_newline_after_expanding = FALSE; - mm->suppress_whitespace_when_expanding = FALSE; mm->span = TRUE; + Preprocessor__do_not_suppress_whitespace(mm); Str__clear(subname); WRITE_TO(subname, "end-%S-span", name); mm = Preprocessor__new_macro(L, subname, NULL, Preprocessor__end_loop_expander, tfp); mm->ends_loop = TRUE; mm->loop_name = Str__duplicate(name); - mm->suppress_newline_after_expanding = FALSE; - mm->suppress_whitespace_when_expanding = FALSE; mm->span = TRUE; + Preprocessor__do_not_suppress_whitespace(mm); DISCARD_TEXT(subname) } -#line 679 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 691 "inweb/foundation-module/Chapter 4/Preprocessor.w" preprocessor_macro *Preprocessor__find_macro(linked_list *L, text_stream *name) { preprocessor_macro *mm; LOOP_OVER_LINKED_LIST(mm, preprocessor_macro, L) @@ -11783,7 +11755,7 @@ preprocessor_macro *Preprocessor__find_macro(linked_list *L, text_stream *name) return NULL; } -#line 694 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 706 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__default_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { PPS->stack_frame = Preprocessor__new_variable_set(PPS->stack_frame); @@ -11797,7 +11769,7 @@ void Preprocessor__default_expander(preprocessor_macro *mm, preprocessor_state * PPS->stack_frame = PPS->stack_frame->outer; } -#line 711 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 723 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__set_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { text_stream *name = parameter_values[0]; @@ -11810,7 +11782,7 @@ void Preprocessor__set_expander(preprocessor_macro *mm, preprocessor_state *PPS, Preprocessor__write_variable(var, value); } -#line 726 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 738 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { text_stream *with = parameter_values[0]; @@ -11830,7 +11802,7 @@ void Preprocessor__repeat_expander(preprocessor_macro *mm, preprocessor_state *P Preprocessor__add_loop_iteration(loop, value); } -#line 755 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 767 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { PPS->shadow_sp = 0; @@ -11846,7 +11818,7 @@ void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state LOOP_OVER_LINKED_LIST(value, text_stream, loop->iterations) { -#line 774 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 786 "inweb/foundation-module/Chapter 4/Preprocessor.w" Preprocessor__write_variable(loop_var, value); if (mm->span) { Preprocessor__expand(matter, tfp, PPS); @@ -11864,7 +11836,7 @@ void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state } } -#line 768 "inweb/foundation-module/Chapter 4/Preprocessor.w" +#line 780 "inweb/foundation-module/Chapter 4/Preprocessor.w" ; PPS->stack_frame = PPS->stack_frame->outer; } @@ -17233,7 +17205,7 @@ void SimpleTangler__tangle_L3(OUTPUT_STREAM, text_stream *text, if (Input_File) fclose(Input_File); } -#line 103 "inweb/Chapter 1/Basics.w" +#line 101 "inweb/Chapter 1/Basics.w" DECLARE_CLASS_ALLOCATED_IN_ARRAYS(source_line, 1000) DECLARE_CLASS(asset_rule) DECLARE_CLASS(breadcrumb_request) @@ -17250,9 +17222,7 @@ DECLARE_CLASS(hash_table_entry_usage) DECLARE_CLASS(hash_table_entry) DECLARE_CLASS(language_function) DECLARE_CLASS(language_type) -DECLARE_CLASS(macro_tokens) DECLARE_CLASS(macro_usage) -DECLARE_CLASS(macro) DECLARE_CLASS(makefile_specifics) DECLARE_CLASS(nonterminal_variable) DECLARE_CLASS(para_macro) @@ -31236,7 +31206,7 @@ void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I makefile_specifics *specifics = CREATE(makefile_specifics); { -#line 55 "inweb/Chapter 6/Makefiles.w" +#line 56 "inweb/Chapter 6/Makefiles.w" specifics->for_web = W; specifics->tools_dictionary = Dictionaries__new(16, FALSE); specifics->webs_dictionary = Dictionaries__new(16, FALSE); @@ -31252,12 +31222,13 @@ void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I WRITE_TO(header, "# and is not intended for human editing\n\n"); WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); - Preprocessor__preprocess(prototype, F, header, L, STORE_POINTER_makefile_specifics(specifics)); + Preprocessor__preprocess(prototype, F, header, L, + STORE_POINTER_makefile_specifics(specifics), '#'); } -#line 53 "inweb/Chapter 6/Makefiles.w" +#line 54 "inweb/Chapter 6/Makefiles.w" -#line 64 "inweb/Chapter 6/Makefiles.w" +#line 65 "inweb/Chapter 6/Makefiles.w" void Makefiles__identity_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics); @@ -31273,7 +31244,7 @@ void Makefiles__identity_settings_expander(preprocessor_macro *mm, preprocessor_ } } -#line 86 "inweb/Chapter 6/Makefiles.w" +#line 87 "inweb/Chapter 6/Makefiles.w" void Makefiles__platform_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { filename *prototype = Filenames__in(path_to_inweb, TL_IS_645); @@ -31303,7 +31274,7 @@ void Makefiles__seek_INWEBPLATFORM(text_stream *line, text_file_position *tfp, v Regexp__dispose_of(&mr); } -#line 118 "inweb/Chapter 6/Makefiles.w" +#line 119 "inweb/Chapter 6/Makefiles.w" void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics); @@ -31320,7 +31291,7 @@ void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *P dictionary *D = specifics->tools_dictionary; { -#line 151 "inweb/Chapter 6/Makefiles.w" +#line 152 "inweb/Chapter 6/Makefiles.w" web_md *Wm = Reader__load_web_md(Pathnames__from_text(path), NULL, specifics->search_path, TRUE); Wm->as_module->module_name = Str__duplicate(symbol); @@ -31330,25 +31301,25 @@ void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *P Dictionaries__write_value(D, symbol, Wm); } -#line 132 "inweb/Chapter 6/Makefiles.w" +#line 133 "inweb/Chapter 6/Makefiles.w" ; { -#line 160 "inweb/Chapter 6/Makefiles.w" +#line 161 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", symbol, webname); WRITE("%SWEB = %S\n", symbol, path); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", symbol, symbol, webname); WRITE("%SX = $(%SWEB)/Tangled/%S\n", symbol, symbol, webname); } -#line 133 "inweb/Chapter 6/Makefiles.w" +#line 134 "inweb/Chapter 6/Makefiles.w" ; } else if (Str__eq(category, TL_IS_649)) { int marker = MAKEFILE_WEB_MOM; dictionary *D = specifics->webs_dictionary; { -#line 151 "inweb/Chapter 6/Makefiles.w" +#line 152 "inweb/Chapter 6/Makefiles.w" web_md *Wm = Reader__load_web_md(Pathnames__from_text(path), NULL, specifics->search_path, TRUE); Wm->as_module->module_name = Str__duplicate(symbol); @@ -31358,25 +31329,25 @@ void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *P Dictionaries__write_value(D, symbol, Wm); } -#line 137 "inweb/Chapter 6/Makefiles.w" +#line 138 "inweb/Chapter 6/Makefiles.w" ; { -#line 160 "inweb/Chapter 6/Makefiles.w" +#line 161 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", symbol, webname); WRITE("%SWEB = %S\n", symbol, path); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", symbol, symbol, webname); WRITE("%SX = $(%SWEB)/Tangled/%S\n", symbol, symbol, webname); } -#line 138 "inweb/Chapter 6/Makefiles.w" +#line 139 "inweb/Chapter 6/Makefiles.w" ; } else if (Str__eq(category, TL_IS_650)) { int marker = MAKEFILE_MODULE_MOM; dictionary *D = specifics->modules_dictionary; { -#line 151 "inweb/Chapter 6/Makefiles.w" +#line 152 "inweb/Chapter 6/Makefiles.w" web_md *Wm = Reader__load_web_md(Pathnames__from_text(path), NULL, specifics->search_path, TRUE); Wm->as_module->module_name = Str__duplicate(symbol); @@ -31386,18 +31357,18 @@ void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *P Dictionaries__write_value(D, symbol, Wm); } -#line 142 "inweb/Chapter 6/Makefiles.w" +#line 143 "inweb/Chapter 6/Makefiles.w" ; { -#line 160 "inweb/Chapter 6/Makefiles.w" +#line 161 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", symbol, webname); WRITE("%SWEB = %S\n", symbol, path); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", symbol, symbol, webname); WRITE("%SX = $(%SWEB)/Tangled/%S\n", symbol, symbol, webname); } -#line 143 "inweb/Chapter 6/Makefiles.w" +#line 144 "inweb/Chapter 6/Makefiles.w" ; } else { Errors__in_text_file("category should be 'tool', 'module' or 'web'", tfp); @@ -31405,7 +31376,7 @@ void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *P PPS->last_line_was_blank = FALSE; } -#line 168 "inweb/Chapter 6/Makefiles.w" +#line 169 "inweb/Chapter 6/Makefiles.w" void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { Preprocessor__set_loop_var_name(loop, TL_IS_651); @@ -31416,7 +31387,7 @@ void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state * int marker = MAKEFILE_TOOL_MOM; { -#line 189 "inweb/Chapter 6/Makefiles.w" +#line 190 "inweb/Chapter 6/Makefiles.w" module *M; LOOP_OVER(M, module) { if ((M->origin_marker == marker) && @@ -31427,13 +31398,13 @@ void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state * } } -#line 176 "inweb/Chapter 6/Makefiles.w" +#line 177 "inweb/Chapter 6/Makefiles.w" ; } else if (Str__eq(category, TL_IS_654)) { int marker = MAKEFILE_WEB_MOM; { -#line 189 "inweb/Chapter 6/Makefiles.w" +#line 190 "inweb/Chapter 6/Makefiles.w" module *M; LOOP_OVER(M, module) { if ((M->origin_marker == marker) && @@ -31444,13 +31415,13 @@ void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state * } } -#line 179 "inweb/Chapter 6/Makefiles.w" +#line 180 "inweb/Chapter 6/Makefiles.w" ; } else if (Str__eq(category, TL_IS_655)) { int marker = MAKEFILE_MODULE_MOM; { -#line 189 "inweb/Chapter 6/Makefiles.w" +#line 190 "inweb/Chapter 6/Makefiles.w" module *M; LOOP_OVER(M, module) { if ((M->origin_marker == marker) && @@ -31461,14 +31432,14 @@ void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state * } } -#line 182 "inweb/Chapter 6/Makefiles.w" +#line 183 "inweb/Chapter 6/Makefiles.w" ; } else { Errors__in_text_file("category should be 'tool', 'module' or 'web'", tfp); } } -#line 201 "inweb/Chapter 6/Makefiles.w" +#line 202 "inweb/Chapter 6/Makefiles.w" void Makefiles__dependent_files_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics); @@ -31521,12 +31492,12 @@ void Makefiles__dependent_files_expander(preprocessor_macro *mm, preprocessor_st PPS->last_line_was_blank = FALSE; } -#line 257 "inweb/Chapter 6/Makefiles.w" +#line 258 "inweb/Chapter 6/Makefiles.w" void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) { dictionary *patterns_done = Dictionaries__new(16, TRUE); if (F) { -#line 268 "inweb/Chapter 6/Makefiles.w" +#line 269 "inweb/Chapter 6/Makefiles.w" pathname *P = Filenames__up(F); TEMPORARY_TEXT(leaf_pattern) WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P)); @@ -31553,14 +31524,14 @@ void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) { DISCARD_TEXT(tester) } -#line 259 "inweb/Chapter 6/Makefiles.w" +#line 260 "inweb/Chapter 6/Makefiles.w" ; section_md *Sm; LOOP_OVER_LINKED_LIST(Sm, section_md, L) { filename *F = Sm->source_file_for_section; { -#line 268 "inweb/Chapter 6/Makefiles.w" +#line 269 "inweb/Chapter 6/Makefiles.w" pathname *P = Filenames__up(F); TEMPORARY_TEXT(leaf_pattern) WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P)); @@ -31587,12 +31558,12 @@ void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) { DISCARD_TEXT(tester) } -#line 263 "inweb/Chapter 6/Makefiles.w" +#line 264 "inweb/Chapter 6/Makefiles.w" ; } } -#line 298 "inweb/Chapter 6/Makefiles.w" +#line 299 "inweb/Chapter 6/Makefiles.w" void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) { TEMPORARY_TEXT(PT) WRITE_TO(PT, "%p", P); @@ -31612,7 +31583,7 @@ void Git__write_gitignore(web *W, filename *prototype, filename *F) { WRITE_TO(header, "# This gitignore was automatically written by inweb -gitignore\n"); WRITE_TO(header, "# and is not intended for human editing\n\n"); WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); - Preprocessor__preprocess(prototype, F, header, L, NULL_GENERAL_POINTER); + Preprocessor__preprocess(prototype, F, header, L, NULL_GENERAL_POINTER, '#'); } #line 22 "inweb/Chapter 6/Git Support.w" @@ -31733,248 +31704,39 @@ void Ctags__note_defined_constant(source_line *L, text_stream *name) { dc->at = L; } -#line 18 "inweb/Chapter 6/Readme Writeme.w" - -void Readme__write(filename *from, filename *to) { - WRITE_TO(STDOUT, "write-me: %f --> %f\n", from, to); - write_state ws; - ws.current_definition = NULL; - ws.known_macros = NEW_LINKED_LIST(macro); - macro *V = Readme__new_macro(TL_IS_660, NULL, NULL); - ADD_TO_LINKED_LIST(V, macro, ws.known_macros); - macro *P = Readme__new_macro(TL_IS_661, NULL, NULL); - ADD_TO_LINKED_LIST(P, macro, ws.known_macros); - macro *A = Readme__new_macro(TL_IS_662, NULL, NULL); - ADD_TO_LINKED_LIST(A, macro, ws.known_macros); - ws.stack_frame = NULL; - text_stream file_to; - if (Streams__open_to_file(&file_to, to, UTF8_ENC) == FALSE) - Errors__fatal_with_file("can't write readme file", to); - ws.OUT = &file_to; - TextFiles__read(from, FALSE, "unable to read template file", TRUE, - &Readme__write_helper, NULL, (void *) &ws); - Streams__close(&file_to); +#line 10 "inweb/Chapter 6/Readme Writeme.w" +void Readme__write(filename *prototype, filename *F) { + linked_list *L = NEW_LINKED_LIST(preprocessor_macro); + preprocessor_macro *mm = Preprocessor__new_macro(L, + TL_IS_660, TL_IS_661, + Readme__bibliographic_expander, NULL); + Preprocessor__do_not_suppress_whitespace(mm); + WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); + Preprocessor__preprocess(prototype, F, NULL, L, NULL_GENERAL_POINTER, '/'); } -#line 44 "inweb/Chapter 6/Readme Writeme.w" -void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) { - write_state *ws = (write_state *) state; - text_stream *OUT = ws->OUT; - - match_results mr = Regexp__create_mr(); - if (Regexp__match(&mr, text, L" *@end *")) { - if (ws->current_definition == NULL) - Errors__in_text_file("@end without @define", tfp); - else ws->current_definition = NULL; - } else if (ws->current_definition) { - if (Str__len(ws->current_definition->content) > 0) - WRITE_TO(ws->current_definition->content, "\n"); - WRITE_TO(ws->current_definition->content, "%S", text); - } else if (Regexp__match(&mr, text, L" *@define (%i+)(%c*)")) { - if (ws->current_definition) - Errors__in_text_file("@define without @end", tfp); - else { - macro *M = Readme__new_macro(mr.exp[0], mr.exp[1], tfp); - ws->current_definition = M; - ADD_TO_LINKED_LIST(M, macro, ws->known_macros); - } - } else { - Readme__expand_material(ws, OUT, text, tfp); - Readme__expand_material(ws, OUT, TL_IS_663, tfp); - } - Regexp__dispose_of(&mr); +#line 23 "inweb/Chapter 6/Readme Writeme.w" +void Readme__bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS, + text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) { + text_stream *datum = parameter_values[0]; + text_stream *asset_name = parameter_values[1]; + text_stream *OUT = PPS->dest; + writeme_asset *A = Readme__find_asset(asset_name); + if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum)); + else if (Str__eq(datum, TL_IS_662)) WRITE("%S", A->date); + else if (Str__eq(datum, TL_IS_663)) WRITE("%S", A->version); } -#line 82 "inweb/Chapter 6/Readme Writeme.w" - -macro *Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) { - macro *M = CREATE(macro); - M->name = Str__duplicate(name); - M->tokens = Readme__parse_token_list(tokens, tfp); - M->content = Str__new(); - return M; -} - -#line 98 "inweb/Chapter 6/Readme Writeme.w" - -#line 100 "inweb/Chapter 6/Readme Writeme.w" -macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) { - macro_tokens mt; - mt.no_pars = 0; - mt.down = NULL; - mt.bound_to = NULL; - if (Str__get_first_char(chunk) == '(') { - int x = 1, bl = 1, from = 1, quoted = FALSE; - while ((bl > 0) && (Str__get_at(chunk, x) != 0)) { - wchar_t c = Str__get_at(chunk, x); - if (c == '\'') { - quoted = quoted?FALSE:TRUE; - } else if (quoted == FALSE) { - if (c == '(') bl++; - else if (c == ')') { - bl--; - if (bl == 0) -{ -#line 129 "inweb/Chapter 6/Readme Writeme.w" - int n = mt.no_pars; - if (n >= 8) Errors__in_text_file("too many parameters", tfp); - else { - mt.pars[n] = Str__new(); - for (int j=from; j= 8) Errors__in_text_file("too many parameters", tfp); - else { - mt.pars[n] = Str__new(); - for (int j=from; jstack_frame; - ws->stack_frame = &mt; - Readme__expand_at(ws, OUT, mr.exp[1], tfp); - ws->stack_frame = mt.down; - Readme__expand_material(ws, OUT, mr.exp[2], tfp); - } else { - WRITE("%S", text); - } - Regexp__dispose_of(&mr); -} - -#line 172 "inweb/Chapter 6/Readme Writeme.w" -void Readme__expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, - text_file_position *tfp) { - macro_tokens *stack = ws->stack_frame; - while (stack) { - macro *in = stack->bound_to; - if (in) - for (int n = 0; n < in->tokens.no_pars; n++) - if (Str__eq(in->tokens.pars[n], macro_name)) { - if (n < stack->no_pars) { - Readme__expand_material(ws, OUT, stack->pars[n], tfp); - return; - } - } - stack = stack->down; - } - - macro *M; - LOOP_OVER_LINKED_LIST(M, macro, ws->known_macros) - if (Str__eq(M->name, macro_name)) { - ws->stack_frame->bound_to = M; - Readme__expand_macro(ws, OUT, M, tfp); - return; - } - Errors__in_text_file("no such @-command", tfp); - WRITE_TO(STDERR, "(command is '%S')\n", macro_name); -} - -#line 204 "inweb/Chapter 6/Readme Writeme.w" -void Readme__expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) { - if (Str__eq(M->name, TL_IS_664)) -{ -#line 215 "inweb/Chapter 6/Readme Writeme.w" - if (ws->stack_frame->no_pars != 1) - Errors__in_text_file("@version takes 1 parameter", tfp); - else { - TEMPORARY_TEXT(program) - Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme__write_var(OUT, program, TL_IS_667); - DISCARD_TEXT(program) - } - -} -#line 205 "inweb/Chapter 6/Readme Writeme.w" - - else if (Str__eq(M->name, TL_IS_665)) -{ -#line 225 "inweb/Chapter 6/Readme Writeme.w" - if (ws->stack_frame->no_pars != 1) - Errors__in_text_file("@purpose takes 1 parameter", tfp); - else { - TEMPORARY_TEXT(program) - Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme__write_var(OUT, program, TL_IS_668); - DISCARD_TEXT(program) - } - -} -#line 206 "inweb/Chapter 6/Readme Writeme.w" - - else if (Str__eq(M->name, TL_IS_666)) -{ -#line 235 "inweb/Chapter 6/Readme Writeme.w" - if (ws->stack_frame->no_pars != 2) - Errors__in_text_file("@var takes 2 parameters", tfp); - else { - TEMPORARY_TEXT(program) - TEMPORARY_TEXT(bibv) - Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); - Readme__expand_material(ws, bibv, ws->stack_frame->pars[1], tfp); - Readme__write_var(OUT, program, bibv); - DISCARD_TEXT(program) - DISCARD_TEXT(bibv) - } - -} -#line 207 "inweb/Chapter 6/Readme Writeme.w" - - else { - ws->stack_frame->bound_to = M; - Readme__expand_material(ws, OUT, M->content, tfp); - } -} - -#line 262 "inweb/Chapter 6/Readme Writeme.w" +#line 49 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) { writeme_asset *A = Readme__find_asset(program); if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum)); - else if (Str__eq(datum, TL_IS_669)) WRITE("%S", A->date); - else if (Str__eq(datum, TL_IS_670)) WRITE("%S", A->version); + else if (Str__eq(datum, TL_IS_664)) WRITE("%S", A->date); + else if (Str__eq(datum, TL_IS_665)) WRITE("%S", A->version); } -#line 273 "inweb/Chapter 6/Readme Writeme.w" +#line 60 "inweb/Chapter 6/Readme Writeme.w" writeme_asset *Readme__find_asset(text_stream *program) { writeme_asset *A; LOOP_OVER(A, writeme_asset) if (Str__eq(program, A->name)) return A; @@ -31986,72 +31748,72 @@ writeme_asset *Readme__find_asset(text_stream *program) { A->next_is_version = FALSE; { -#line 287 "inweb/Chapter 6/Readme Writeme.w" +#line 74 "inweb/Chapter 6/Readme Writeme.w" if (Str__ends_with_wide_string(program, L".i7x")) { { -#line 306 "inweb/Chapter 6/Readme Writeme.w" +#line 93 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(Filenames__from_text(program), FALSE, "unable to read extension", TRUE, &Readme__extension_harvester, NULL, A); } -#line 288 "inweb/Chapter 6/Readme Writeme.w" +#line 75 "inweb/Chapter 6/Readme Writeme.w" ; } else { if (WebMetadata__directory_looks_like_a_web(Pathnames__from_text(program))) { A->if_web = WebMetadata__get_without_modules(Pathnames__from_text(program), NULL); } else { filename *I6_vn = Filenames__in( - Pathnames__down(Pathnames__from_text(program), TL_IS_671), TL_IS_672); + Pathnames__down(Pathnames__from_text(program), TL_IS_666), TL_IS_667); if (TextFiles__exists(I6_vn)) { -#line 310 "inweb/Chapter 6/Readme Writeme.w" +#line 97 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(I6_vn, FALSE, "unable to read header file from I6 source", TRUE, &Readme__header_harvester, NULL, A); } -#line 295 "inweb/Chapter 6/Readme Writeme.w" +#line 82 "inweb/Chapter 6/Readme Writeme.w" ; - filename *template_vn = Filenames__in(Pathnames__from_text(program), TL_IS_673); + filename *template_vn = Filenames__in(Pathnames__from_text(program), TL_IS_668); if (TextFiles__exists(template_vn)) { -#line 314 "inweb/Chapter 6/Readme Writeme.w" +#line 101 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(template_vn, FALSE, "unable to read manifest file from website template", TRUE, &Readme__template_harvester, NULL, A); } -#line 297 "inweb/Chapter 6/Readme Writeme.w" +#line 84 "inweb/Chapter 6/Readme Writeme.w" ; - filename *rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_674); + filename *rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_669); if (TextFiles__exists(rmt_vn)) { -#line 318 "inweb/Chapter 6/Readme Writeme.w" +#line 105 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE, &Readme__readme_harvester, NULL, A); } -#line 299 "inweb/Chapter 6/Readme Writeme.w" +#line 86 "inweb/Chapter 6/Readme Writeme.w" ; - rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_675); + rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_670); if (TextFiles__exists(rmt_vn)) { -#line 318 "inweb/Chapter 6/Readme Writeme.w" +#line 105 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE, &Readme__readme_harvester, NULL, A); } -#line 301 "inweb/Chapter 6/Readme Writeme.w" +#line 88 "inweb/Chapter 6/Readme Writeme.w" ; } } } -#line 282 "inweb/Chapter 6/Readme Writeme.w" +#line 69 "inweb/Chapter 6/Readme Writeme.w" ; return A; } -#line 324 "inweb/Chapter 6/Readme Writeme.w" +#line 111 "inweb/Chapter 6/Readme Writeme.w" void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); @@ -32061,7 +31823,7 @@ void Readme__extension_harvester(text_stream *text, text_file_position *tfp, voi Regexp__dispose_of(&mr); } -#line 336 "inweb/Chapter 6/Readme Writeme.w" +#line 123 "inweb/Chapter 6/Readme Writeme.w" void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); @@ -32073,7 +31835,7 @@ void Readme__header_harvester(text_stream *text, text_file_position *tfp, void * Regexp__dispose_of(&mr); } -#line 350 "inweb/Chapter 6/Readme Writeme.w" +#line 137 "inweb/Chapter 6/Readme Writeme.w" void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); @@ -32087,7 +31849,7 @@ void Readme__template_harvester(text_stream *text, text_file_position *tfp, void Regexp__dispose_of(&mr); } -#line 366 "inweb/Chapter 6/Readme Writeme.w" +#line 153 "inweb/Chapter 6/Readme Writeme.w" void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); @@ -32107,7 +31869,7 @@ void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void * void Colonies__load(filename *F) { colony *C = CREATE(colony); C->members = NEW_LINKED_LIST(colony_member); - C->home = TL_IS_676; + C->home = TL_IS_671; C->assets_path = NULL; C->patterns_path = NULL; colony_reader_state crs; @@ -32131,8 +31893,8 @@ void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L"(%c*?): \"*(%C+)\" at \"(%c*)\" in \"(%c*)\"")) { colony_member *CM = CREATE(colony_member); - if (Str__eq(mr.exp[0], TL_IS_677)) CM->web_rather_than_module = TRUE; - else if (Str__eq(mr.exp[0], TL_IS_678)) CM->web_rather_than_module = FALSE; + if (Str__eq(mr.exp[0], TL_IS_672)) CM->web_rather_than_module = TRUE; + else if (Str__eq(mr.exp[0], TL_IS_673)) CM->web_rather_than_module = FALSE; else { CM->web_rather_than_module = FALSE; Errors__in_text_file("text before ':' must be 'web' or 'module'", tfp); @@ -32140,7 +31902,7 @@ void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs CM->name = Str__duplicate(mr.exp[1]); CM->path = Str__duplicate(mr.exp[2]); CM->home_leaf = Str__new(); - if (Str__suffix_eq(CM->path, TL_IS_679, 6)) { + if (Str__suffix_eq(CM->path, TL_IS_674, 6)) { filename *F = Filenames__from_text(CM->path); Filenames__write_unextended_leafname(CM->home_leaf, F); WRITE_TO(CM->home_leaf, ".html"); @@ -32280,7 +32042,7 @@ module *Colonies__as_module(colony_member *CM, source_line *L, web_md *Wm) { #line 254 "inweb/Chapter 6/Colonies.w" filename *F = NULL; pathname *P = NULL; - if (Str__suffix_eq(CM->path, TL_IS_680, 6)) + if (Str__suffix_eq(CM->path, TL_IS_675, 6)) F = Filenames__from_text(CM->path); else P = Pathnames__from_text(CM->path); @@ -32307,7 +32069,7 @@ text_stream *Colonies__home(void) { colony *C; LOOP_OVER(C, colony) return C->home; - return TL_IS_681; + return TL_IS_676; } pathname *Colonies__assets_path(void) { @@ -32499,7 +32261,7 @@ int Colonies__resolve_reference_in_weave_inner(text_stream *url, text_stream *ti return FALSE; } if (N > 1) { - Main__error_in_web(TL_IS_682, L); + Main__error_in_web(TL_IS_677, L); WebModules__named_reference(&found_M, &found_Sm, &bare_module_name, title, search_M, text, TRUE, FALSE); return FALSE; @@ -32581,7 +32343,7 @@ void Colonies__paragraph_URL(OUTPUT_STREAM, paragraph *P, filename *from) { if (P == NULL) internal_error("no para"); section *to_S = P->under_section; module *to_M = to_S->md->owning_module; - if (Str__ne(to_M->module_name, TL_IS_683)) { + if (Str__ne(to_M->module_name, TL_IS_678)) { colony_member *to_C = Colonies__find(to_M->module_name); if (to_C) { pathname *from_path = Filenames__up(from); @@ -32707,9 +32469,9 @@ void register_tangled_text_literals(void) { TL_IS_94 = Str__literal(L"inweb"); TL_IS_95 = Str__literal(L"Patterns"); TL_IS_96 = Str__literal(L"Materials"); - TL_IS_97 = Str__literal(L"makescript.txt"); - TL_IS_98 = Str__literal(L"gitignorescript.txt"); - TL_IS_99 = Str__literal(L"READMEscript.txt"); + TL_IS_97 = Str__literal(L"script.mkscript"); + TL_IS_98 = Str__literal(L"script.giscript"); + TL_IS_99 = Str__literal(L"script.rmscript"); TL_IS_100 = Str__literal(L"Short Title"); TL_IS_101 = Str__literal(L"Short Title"); TL_IS_102 = Str__literal(L"Title"); @@ -33270,28 +33032,23 @@ void register_tangled_text_literals(void) { TL_IS_657 = Str__literal(L"basics"); TL_IS_658 = Str__literal(L"default.giscript"); TL_IS_659 = Str__literal(L"tags"); - TL_IS_660 = Str__literal(L"version"); - TL_IS_661 = Str__literal(L"purpose"); - TL_IS_662 = Str__literal(L"var"); - TL_IS_663 = Str__literal(L"\n"); - TL_IS_664 = Str__literal(L"version"); - TL_IS_665 = Str__literal(L"purpose"); - TL_IS_666 = Str__literal(L"var"); - TL_IS_667 = Str__literal(L"Version Number"); - TL_IS_668 = Str__literal(L"Purpose"); - TL_IS_669 = Str__literal(L"Build Date"); - TL_IS_670 = Str__literal(L"Version Number"); - TL_IS_671 = Str__literal(L"inform6"); - TL_IS_672 = Str__literal(L"header.h"); - TL_IS_673 = Str__literal(L"(manifest).txt"); - TL_IS_674 = Str__literal(L"README.txt"); - TL_IS_675 = Str__literal(L"README.md"); + TL_IS_660 = Str__literal(L"bibliographic"); + TL_IS_661 = Str__literal(L"datum: DATUM of: ASSET"); + TL_IS_662 = Str__literal(L"Build Date"); + TL_IS_663 = Str__literal(L"Version Number"); + TL_IS_664 = Str__literal(L"Build Date"); + TL_IS_665 = Str__literal(L"Version Number"); + TL_IS_666 = Str__literal(L"inform6"); + TL_IS_667 = Str__literal(L"header.h"); + TL_IS_668 = Str__literal(L"(manifest).txt"); + TL_IS_669 = Str__literal(L"README.txt"); + TL_IS_670 = Str__literal(L"README.md"); + TL_IS_671 = Str__literal(L"docs"); + TL_IS_672 = Str__literal(L"web"); + TL_IS_673 = Str__literal(L"module"); + TL_IS_674 = Str__literal(L".inweb"); + TL_IS_675 = Str__literal(L".inweb"); TL_IS_676 = Str__literal(L"docs"); - TL_IS_677 = Str__literal(L"web"); - TL_IS_678 = Str__literal(L"module"); - TL_IS_679 = Str__literal(L".inweb"); - TL_IS_680 = Str__literal(L".inweb"); - TL_IS_681 = Str__literal(L"docs"); - TL_IS_682 = Str__literal(L"Multiple cross-references might be meant here"); - TL_IS_683 = Str__literal(L"(main)"); + TL_IS_677 = Str__literal(L"Multiple cross-references might be meant here"); + TL_IS_678 = Str__literal(L"(main)"); } diff --git a/docs/foundation-module/4-chr.html b/docs/foundation-module/4-chr.html index fdb2feb..009cb65 100644 --- a/docs/foundation-module/4-chr.html +++ b/docs/foundation-module/4-chr.html @@ -89,7 +89,7 @@ function togglePopup(material_id) { if ((c == ' ') || (c == '\t')) return TRUE; return FALSE; } -int Characters::is_whitespace(int c) { +int Characters::is_whitespace(int c) { if ((c == ' ') || (c == '\t') || (c == '\n')) return TRUE; return FALSE; } diff --git a/docs/foundation-module/4-pm.html b/docs/foundation-module/4-pm.html index e994c35..f94403b 100644 --- a/docs/foundation-module/4-pm.html +++ b/docs/foundation-module/4-pm.html @@ -204,7 +204,7 @@ deallocate.

-match_results Regexp::create_mr(void) {
+match_results Regexp::create_mr(void) {
     match_results mr;
     mr.no_matched_texts = 0;
     for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
@@ -214,7 +214,7 @@ deallocate.
     return mr;
 }
 
-void Regexp::dispose_of(match_results *mr) {
+void Regexp::dispose_of(match_results *mr) {
     if (mr) {
         for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
             if (mr->exp[i]) {
@@ -229,7 +229,7 @@ deallocate.
 

-int Regexp::match(match_results *mr, text_stream *text, wchar_t *pattern) {
+int Regexp::match(match_results *mr, text_stream *text, wchar_t *pattern) {
     if (mr) Regexp::prepare(mr);
     int rv = (Regexp::match_r(mr, text, pattern, NULL, FALSE) >= 0)?TRUE:FALSE;
     if ((mr) && (rv == FALSE)) Regexp::dispose_of(mr);
diff --git a/docs/foundation-module/4-prp.html b/docs/foundation-module/4-prp.html
index f8c339a..b545520 100644
--- a/docs/foundation-module/4-prp.html
+++ b/docs/foundation-module/4-prp.html
@@ -74,7 +74,7 @@ pointer to any data those special meanings need to use.
 
 
 void Preprocessor::preprocess(filename *prototype, filename *F, text_stream *header,
-    linked_list *special_macros, general_pointer specifics) {
+    linked_list *special_macros, general_pointer specifics, wchar_t comment_char) {
     struct text_stream processed_file;
     if (STREAM_OPEN_TO_FILE(&processed_file, F, ISO_ENC) == FALSE)
         Errors::fatal_with_file("unable to write tangled file", F);
@@ -107,6 +107,7 @@ the prototype file line-by-line:
     struct preprocessor_variable_set *stack_frame;
     struct linked_list *known_macros;  of preprocessor_macro
     struct general_pointer specifics;
+    wchar_t comment_character;
 } preprocessor_state;
 
 typedef struct preprocessor_loop {
@@ -131,6 +132,7 @@ the prototype file line-by-line:
     PPS.stack_frame = PPS.global_variables;
     PPS.known_macros = Preprocessor::list_of_reserved_macros(special_macros);
     PPS.specifics = specifics;
+    PPS.comment_character = comment_char;
 
  • This code is used in §1.

§2. Conceptually, each loop runs a variable with a given name through a series @@ -157,24 +159,32 @@ parametrised names: but then, nor should you.

 void Preprocessor::scan_line(text_stream *line, text_file_position *tfp, void *X) {
     preprocessor_state *PPS = (preprocessor_state *) X;
-    match_results mr = Regexp::create_mr();
     Skip comments3.1;
     Deal with textual definitions of new macros3.2;
     Preprocessor::expand(line, tfp, PPS);
     Sometimes, but only sometimes, output a newline3.3;
 }
 
-

§3.1. Skip comments3.1 = +

§3.1. A line is a comment to the preprocessor if its first non-whitespace character +is the special comment character: often #, but not necessarily. +

+ +

Skip comments3.1 =

-    if (Regexp::match(&mr, line, L" *#%c*")) { Regexp::dispose_of(&mr); return; }
+    LOOP_THROUGH_TEXT(pos, line) {
+        wchar_t c = Str::get(pos);
+        if (c == PPS->comment_character) return;
+        if (Characters::is_whitespace(c) == FALSE) break;
+    }
 
  • This code is used in §3.

§3.2. Deal with textual definitions of new macros3.2 =

+    match_results mr = Regexp::create_mr();
     if (Regexp::match(&mr, line, L" *{define: *(%C+) (%c*)} *")) Begin a definition3.2.1;
     if (Regexp::match(&mr, line, L" *{end-define} *")) End a definition3.2.3;
     if (PPS->defining) Continue a definition3.2.2;
@@ -790,6 +800,11 @@ built in here and therefore work in every domain:
     return L;
 }
 
+void Preprocessor::do_not_suppress_whitespace(preprocessor_macro *mm) {
+    mm->suppress_newline_after_expanding = FALSE;
+    mm->suppress_whitespace_when_expanding = FALSE;
+}
+
 void Preprocessor::new_loop_macro(linked_list *L, text_stream *name,
     text_stream *parameter_specification,
     void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *),
@@ -812,18 +827,16 @@ built in here and therefore work in every domain:
     mm = Preprocessor::new_macro(L, subname, parameter_specification, expander, tfp);
     mm->begins_loop = TRUE;
     mm->loop_name = Str::duplicate(name);
-    mm->suppress_newline_after_expanding = FALSE;
-    mm->suppress_whitespace_when_expanding = FALSE;
     mm->span = TRUE;
+    Preprocessor::do_not_suppress_whitespace(mm);
 
     Str::clear(subname);
     WRITE_TO(subname, "end-%S-span", name);
     mm = Preprocessor::new_macro(L, subname, NULL, Preprocessor::end_loop_expander, tfp);
     mm->ends_loop = TRUE;
     mm->loop_name = Str::duplicate(name);
-    mm->suppress_newline_after_expanding = FALSE;
-    mm->suppress_whitespace_when_expanding = FALSE;
     mm->span = TRUE;
+    Preprocessor::do_not_suppress_whitespace(mm);
 
     DISCARD_TEXT(subname)
 }
diff --git a/docs/foundation-module/4-sm.html b/docs/foundation-module/4-sm.html
index 223947b..d4b479f 100644
--- a/docs/foundation-module/4-sm.html
+++ b/docs/foundation-module/4-sm.html
@@ -277,7 +277,7 @@ at those positions may well not be, of course.)
 

-wchar_t Str::get(string_position P) {
+wchar_t Str::get(string_position P) {
     if ((P.S == NULL) || (P.index < 0)) return 0;
     return Streams::get_char_at_index(P.S, P.index);
 }
diff --git a/docs/goldbach/goldbach.pdf b/docs/goldbach/goldbach.pdf
index 2d094179019e83e380412a32f44b6faa98215bb9..6e3427e12ee71b0fc207d26fbde67a516af77458 100644
GIT binary patch
delta 137
zcmcb&f&bnH{)QID7N#xC0w*<%jEyZ#&9n^+)eQ{PHM#VC^HW?BOHvgyT&#=?jEoFS
zjEo^lwp*TLUdQWfVCv>#WbAD0>TGQ2WNvBZ=;CT*>}u-lSF3>r(i=!$#$*l
H%qENgCuk$Q

delta 137
zcmcb&f&bnH{)QID7N#xC0w*;M%?yo=4Ydsn)eQ{PHM#VC^HW?BOHvgyT&#=?jEoFS
zjEo^lwp*TLUdQWf>g4F;W@_kYY+zzx=<4cZWa{eVVrJ@WU~K4SYHn_Br(i=!$#$*l
H%qENg6W=2~

diff --git a/docs/inweb/1-apacs.html b/docs/inweb/1-apacs.html
index 2cffe1d..e53c3d1 100644
--- a/docs/inweb/1-apacs.html
+++ b/docs/inweb/1-apacs.html
@@ -472,7 +472,7 @@ the style names for colouring, say, COBOL source code from, e.g.,
     Regexp::dispose_of(&mr);
 }
 
-
  • The structure css_file_transformation is accessed in 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
+
  • The structure css_file_transformation is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
diff --git a/docs/inweb/1-bsc.html b/docs/inweb/1-bsc.html index 4baae45..c8674d0 100644 --- a/docs/inweb/1-bsc.html +++ b/docs/inweb/1-bsc.html @@ -66,8 +66,6 @@ see A Brief Guide t enum hash_table_entry_usage_CLASS enum language_function_CLASS enum language_type_CLASS -enum macro_CLASS -enum macro_tokens_CLASS enum macro_usage_CLASS enum makefile_specifics_CLASS enum nonterminal_variable_CLASS @@ -157,9 +155,7 @@ see A Brief Guide t DECLARE_CLASS(hash_table_entry) DECLARE_CLASS(language_function) DECLARE_CLASS(language_type) -DECLARE_CLASS(macro_tokens) DECLARE_CLASS(macro_usage) -DECLARE_CLASS(macro) DECLARE_CLASS(makefile_specifics) DECLARE_CLASS(nonterminal_variable) DECLARE_CLASS(para_macro) diff --git a/docs/inweb/1-pc.html b/docs/inweb/1-pc.html index e4efaf7..ea5afc2 100644 --- a/docs/inweb/1-pc.html +++ b/docs/inweb/1-pc.html @@ -180,11 +180,11 @@ program: some input, some thinking, a choice of three forms of output.
     if ((ins->makefile_setting) && (ins->prototype_setting == NULL))
-        ins->prototype_setting = Filenames::from_text(I"makescript.txt");
+        ins->prototype_setting = Filenames::from_text(I"script.mkscript");
     if ((ins->gitignore_setting) && (ins->prototype_setting == NULL))
-        ins->prototype_setting = Filenames::from_text(I"gitignorescript.txt");
+        ins->prototype_setting = Filenames::from_text(I"script.giscript");
     if ((ins->writeme_setting) && (ins->prototype_setting == NULL))
-        ins->prototype_setting = Filenames::from_text(I"READMEscript.txt");
+        ins->prototype_setting = Filenames::from_text(I"script.rmscript");
     if (ins->makefile_setting)
         Makefiles::write(W, ins->prototype_setting, ins->makefile_setting,
             WebModules::make_search_path(ins->import_setting));
diff --git a/docs/inweb/3-tc.html b/docs/inweb/3-tc.html
index ab42c72..19a73c9 100644
--- a/docs/inweb/3-tc.html
+++ b/docs/inweb/3-tc.html
@@ -313,7 +313,7 @@ chapter as its value during the sole iteration.
                 TEMPORARY_TEXT(url)
                 TEMPORARY_TEXT(purpose)
                 WRITE_TO(url, "%p", M->module_location);
-                Readme::write_var(purpose, url, I"Purpose");
+                Readme::write_var(purpose, url, I"Purpose");
                 if (Str::len(purpose) > 0) level = IF_TRUE_LEVEL;
                 DISCARD_TEXT(url)
                 DISCARD_TEXT(purpose)
@@ -766,7 +766,7 @@ this will recursively call The Collater, in fact.
     } else if (Str::eq_wide_string(detail, L"Purpose")) {
         TEMPORARY_TEXT(url)
         WRITE_TO(url, "%p", M->module_location);
-        Readme::write_var(substituted, url, I"Purpose");
+        Readme::write_var(substituted, url, I"Purpose");
         DISCARD_TEXT(url)
     } else {
         WRITE_TO(substituted, "%S for %S", varname, M->module_name);
diff --git a/docs/inweb/5-df.html b/docs/inweb/5-df.html
index 4180559..b30f30f 100644
--- a/docs/inweb/5-df.html
+++ b/docs/inweb/5-df.html
@@ -132,7 +132,7 @@ function togglePopup(material_id) {
     return TRUE;
 }
 
-
  • The structure debugging_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/hf, 6/rw and here.
+
  • The structure debugging_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/hf and here.

§2.1. Render document2.1 =

diff --git a/docs/inweb/5-hf.html b/docs/inweb/5-hf.html index 35eb18f..ca8c56a 100644 --- a/docs/inweb/5-hf.html +++ b/docs/inweb/5-hf.html @@ -97,7 +97,7 @@ instance of this: struct asset_rule *copy_rule; } HTML_render_state;
-
  • The structure HTML_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/df, 6/rw and here.
+
  • The structure HTML_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/df and here.

§3. The initial state is as follows:

diff --git a/docs/inweb/5-ptf.html b/docs/inweb/5-ptf.html index ccb6b37..cd29411 100644 --- a/docs/inweb/5-ptf.html +++ b/docs/inweb/5-ptf.html @@ -131,7 +131,7 @@ function togglePopup(material_id) { return TRUE; }
-
  • The structure PlainText_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/tf, 5/hf, 5/df, 6/rw and here.
+
  • The structure PlainText_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/tf, 5/hf, 5/df and here.

§2.1. Render chapter header2.1 =

diff --git a/docs/inweb/5-tf.html b/docs/inweb/5-tf.html index f42bcdc..d9012db 100644 --- a/docs/inweb/5-tf.html +++ b/docs/inweb/5-tf.html @@ -95,7 +95,7 @@ generic as possible, but with special features depending on Trees::traverse_from(tree->root, &TeX::render_visit, (void *) &trs, 0); }
-
  • The structure TeX_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/hf, 5/df, 6/rw and here.
+
  • The structure TeX_render_state is accessed in 1/apacs, 3/tc, 3/twot, 5/wt, 5/fm, 5/ptf, 5/hf, 5/df and here.

§4. For the reason why footnotes are omitted, see below: they aren't really.

diff --git a/docs/inweb/5-tu.html b/docs/inweb/5-tu.html index bf569c3..6d6f013 100644 --- a/docs/inweb/5-tu.html +++ b/docs/inweb/5-tu.html @@ -315,13 +315,13 @@ we also look out for {}^3\sqr

-    TEMPORARY_TEXT(macro)
+    TEMPORARY_TEXT(macro)
     i++;
     while ((i < Str::len(text)) && (Characters::isalpha(Str::get_at(text, i))))
-        PUT_TO(macro, Str::get_at(text, i++));
-    if (Str::eq(macro, I"not")) Remove the not prefix7.4.2
+        PUT_TO(macro, Str::get_at(text, i++));
+    if (Str::eq(macro, I"not")) Remove the not prefix7.4.2
     else Remove a general macro7.4.1;
-    DISCARD_TEXT(macro)
+    DISCARD_TEXT(macro)
     i--;
 
  • This code is used in §7.
@@ -329,114 +329,114 @@ we also look out for {}^3\sqr

-    if (Str::eq(macro, I"leq")) WRITE("<=");
-    else if (Str::eq(macro, I"geq")) WRITE(">=");
-    else if (Str::eq(macro, I"sim")) WRITE("~");
-    else if (Str::eq(macro, I"hbox")) WRITE("");
-    else if (Str::eq(macro, I"left")) WRITE("");
-    else if (Str::eq(macro, I"right")) WRITE("");
-    else if (Str::eq(macro, I"Rightarrow")) WRITE("=>");
-    else if (Str::eq(macro, I"Leftrightarrow")) WRITE("<=>");
-    else if (Str::eq(macro, I"to")) WRITE("-->");
-    else if (Str::eq(macro, I"rightarrow")) WRITE("-->");
-    else if (Str::eq(macro, I"longrightarrow")) WRITE("-->");
-    else if (Str::eq(macro, I"leftarrow")) WRITE("<--");
-    else if (Str::eq(macro, I"longleftarrow")) WRITE("<--");
-    else if (Str::eq(macro, I"lbrace")) WRITE("{");
-    else if (Str::eq(macro, I"mid")) WRITE("|");
-    else if (Str::eq(macro, I"rbrace")) WRITE("}");
-    else if (Str::eq(macro, I"cdot")) WRITE(".");
-    else if (Str::eq(macro, I"cdots")) WRITE("...");
-    else if (Str::eq(macro, I"dots")) WRITE("...");
-    else if (Str::eq(macro, I"times")) WRITE("*");
-    else if (Str::eq(macro, I"quad")) WRITE("  ");
-    else if (Str::eq(macro, I"qquad")) WRITE("    ");
-    else if (Str::eq(macro, I"TeX")) WRITE("TeX");
-    else if (Str::eq(macro, I"neq")) WRITE("!=");
-    else if (Str::eq(macro, I"noteq")) WRITE("!=");
-    else if (Str::eq(macro, I"ell")) WRITE("l");
-    else if (Str::eq(macro, I"log")) WRITE("log");
-    else if (Str::eq(macro, I"exp")) WRITE("exp");
-    else if (Str::eq(macro, I"sin")) WRITE("sin");
-    else if (Str::eq(macro, I"cos")) WRITE("cos");
-    else if (Str::eq(macro, I"tan")) WRITE("tan");
-    else if (Str::eq(macro, I"top")) WRITE("T");
-    else if (Str::eq(macro, I"Alpha")) PUT((wchar_t) 0x0391);
-    else if (Str::eq(macro, I"Beta")) PUT((wchar_t) 0x0392);
-    else if (Str::eq(macro, I"Gamma")) PUT((wchar_t) 0x0393);
-    else if (Str::eq(macro, I"Delta")) PUT((wchar_t) 0x0394);
-    else if (Str::eq(macro, I"Epsilon")) PUT((wchar_t) 0x0395);
-    else if (Str::eq(macro, I"Zeta")) PUT((wchar_t) 0x0396);
-    else if (Str::eq(macro, I"Eta")) PUT((wchar_t) 0x0397);
-    else if (Str::eq(macro, I"Theta")) PUT((wchar_t) 0x0398);
-    else if (Str::eq(macro, I"Iota")) PUT((wchar_t) 0x0399);
-    else if (Str::eq(macro, I"Kappa")) PUT((wchar_t) 0x039A);
-    else if (Str::eq(macro, I"Lambda")) PUT((wchar_t) 0x039B);
-    else if (Str::eq(macro, I"Mu")) PUT((wchar_t) 0x039C);
-    else if (Str::eq(macro, I"Nu")) PUT((wchar_t) 0x039D);
-    else if (Str::eq(macro, I"Xi")) PUT((wchar_t) 0x039E);
-    else if (Str::eq(macro, I"Omicron")) PUT((wchar_t) 0x039F);
-    else if (Str::eq(macro, I"Pi")) PUT((wchar_t) 0x03A0);
-    else if (Str::eq(macro, I"Rho")) PUT((wchar_t) 0x03A1);
-    else if (Str::eq(macro, I"Varsigma")) PUT((wchar_t) 0x03A2);
-    else if (Str::eq(macro, I"Sigma")) PUT((wchar_t) 0x03A3);
-    else if (Str::eq(macro, I"Tau")) PUT((wchar_t) 0x03A4);
-    else if (Str::eq(macro, I"Upsilon")) PUT((wchar_t) 0x03A5);
-    else if (Str::eq(macro, I"Phi")) PUT((wchar_t) 0x03A6);
-    else if (Str::eq(macro, I"Chi")) PUT((wchar_t) 0x03A7);
-    else if (Str::eq(macro, I"Psi")) PUT((wchar_t) 0x03A8);
-    else if (Str::eq(macro, I"Omega")) PUT((wchar_t) 0x03A9);
-    else if (Str::eq(macro, I"alpha")) PUT((wchar_t) 0x03B1);
-    else if (Str::eq(macro, I"beta")) PUT((wchar_t) 0x03B2);
-    else if (Str::eq(macro, I"gamma")) PUT((wchar_t) 0x03B3);
-    else if (Str::eq(macro, I"delta")) PUT((wchar_t) 0x03B4);
-    else if (Str::eq(macro, I"epsilon")) PUT((wchar_t) 0x03B5);
-    else if (Str::eq(macro, I"zeta")) PUT((wchar_t) 0x03B6);
-    else if (Str::eq(macro, I"eta")) PUT((wchar_t) 0x03B7);
-    else if (Str::eq(macro, I"theta")) PUT((wchar_t) 0x03B8);
-    else if (Str::eq(macro, I"iota")) PUT((wchar_t) 0x03B9);
-    else if (Str::eq(macro, I"kappa")) PUT((wchar_t) 0x03BA);
-    else if (Str::eq(macro, I"lambda")) PUT((wchar_t) 0x03BB);
-    else if (Str::eq(macro, I"mu")) PUT((wchar_t) 0x03BC);
-    else if (Str::eq(macro, I"nu")) PUT((wchar_t) 0x03BD);
-    else if (Str::eq(macro, I"xi")) PUT((wchar_t) 0x03BE);
-    else if (Str::eq(macro, I"omicron")) PUT((wchar_t) 0x03BF);
-    else if (Str::eq(macro, I"pi")) PUT((wchar_t) 0x03C0);
-    else if (Str::eq(macro, I"rho")) PUT((wchar_t) 0x03C1);
-    else if (Str::eq(macro, I"varsigma")) PUT((wchar_t) 0x03C2);
-    else if (Str::eq(macro, I"sigma")) PUT((wchar_t) 0x03C3);
-    else if (Str::eq(macro, I"tau")) PUT((wchar_t) 0x03C4);
-    else if (Str::eq(macro, I"upsilon")) PUT((wchar_t) 0x03C5);
-    else if (Str::eq(macro, I"phi")) PUT((wchar_t) 0x03C6);
-    else if (Str::eq(macro, I"chi")) PUT((wchar_t) 0x03C7);
-    else if (Str::eq(macro, I"psi")) PUT((wchar_t) 0x03C8);
-    else if (Str::eq(macro, I"omega")) PUT((wchar_t) 0x03C9);
-    else if (Str::eq(macro, I"exists")) PUT((wchar_t) 0x2203);
-    else if (Str::eq(macro, I"in")) PUT((wchar_t) 0x2208);
-    else if (Str::eq(macro, I"forall")) PUT((wchar_t) 0x2200);
-    else if (Str::eq(macro, I"cap")) PUT((wchar_t) 0x2229);
-    else if (Str::eq(macro, I"emptyset")) PUT((wchar_t) 0x2205);
-    else if (Str::eq(macro, I"subseteq")) PUT((wchar_t) 0x2286);
-    else if (Str::eq(macro, I"land")) PUT((wchar_t) 0x2227);
-    else if (Str::eq(macro, I"lor")) PUT((wchar_t) 0x2228);
-    else if (Str::eq(macro, I"lnot")) PUT((wchar_t) 0x00AC);
-    else if (Str::eq(macro, I"sum")) PUT((wchar_t) 0x03A3);
-    else if (Str::eq(macro, I"prod")) PUT((wchar_t) 0x03A0);
+    if (Str::eq(macro, I"leq")) WRITE("<=");
+    else if (Str::eq(macro, I"geq")) WRITE(">=");
+    else if (Str::eq(macro, I"sim")) WRITE("~");
+    else if (Str::eq(macro, I"hbox")) WRITE("");
+    else if (Str::eq(macro, I"left")) WRITE("");
+    else if (Str::eq(macro, I"right")) WRITE("");
+    else if (Str::eq(macro, I"Rightarrow")) WRITE("=>");
+    else if (Str::eq(macro, I"Leftrightarrow")) WRITE("<=>");
+    else if (Str::eq(macro, I"to")) WRITE("-->");
+    else if (Str::eq(macro, I"rightarrow")) WRITE("-->");
+    else if (Str::eq(macro, I"longrightarrow")) WRITE("-->");
+    else if (Str::eq(macro, I"leftarrow")) WRITE("<--");
+    else if (Str::eq(macro, I"longleftarrow")) WRITE("<--");
+    else if (Str::eq(macro, I"lbrace")) WRITE("{");
+    else if (Str::eq(macro, I"mid")) WRITE("|");
+    else if (Str::eq(macro, I"rbrace")) WRITE("}");
+    else if (Str::eq(macro, I"cdot")) WRITE(".");
+    else if (Str::eq(macro, I"cdots")) WRITE("...");
+    else if (Str::eq(macro, I"dots")) WRITE("...");
+    else if (Str::eq(macro, I"times")) WRITE("*");
+    else if (Str::eq(macro, I"quad")) WRITE("  ");
+    else if (Str::eq(macro, I"qquad")) WRITE("    ");
+    else if (Str::eq(macro, I"TeX")) WRITE("TeX");
+    else if (Str::eq(macro, I"neq")) WRITE("!=");
+    else if (Str::eq(macro, I"noteq")) WRITE("!=");
+    else if (Str::eq(macro, I"ell")) WRITE("l");
+    else if (Str::eq(macro, I"log")) WRITE("log");
+    else if (Str::eq(macro, I"exp")) WRITE("exp");
+    else if (Str::eq(macro, I"sin")) WRITE("sin");
+    else if (Str::eq(macro, I"cos")) WRITE("cos");
+    else if (Str::eq(macro, I"tan")) WRITE("tan");
+    else if (Str::eq(macro, I"top")) WRITE("T");
+    else if (Str::eq(macro, I"Alpha")) PUT((wchar_t) 0x0391);
+    else if (Str::eq(macro, I"Beta")) PUT((wchar_t) 0x0392);
+    else if (Str::eq(macro, I"Gamma")) PUT((wchar_t) 0x0393);
+    else if (Str::eq(macro, I"Delta")) PUT((wchar_t) 0x0394);
+    else if (Str::eq(macro, I"Epsilon")) PUT((wchar_t) 0x0395);
+    else if (Str::eq(macro, I"Zeta")) PUT((wchar_t) 0x0396);
+    else if (Str::eq(macro, I"Eta")) PUT((wchar_t) 0x0397);
+    else if (Str::eq(macro, I"Theta")) PUT((wchar_t) 0x0398);
+    else if (Str::eq(macro, I"Iota")) PUT((wchar_t) 0x0399);
+    else if (Str::eq(macro, I"Kappa")) PUT((wchar_t) 0x039A);
+    else if (Str::eq(macro, I"Lambda")) PUT((wchar_t) 0x039B);
+    else if (Str::eq(macro, I"Mu")) PUT((wchar_t) 0x039C);
+    else if (Str::eq(macro, I"Nu")) PUT((wchar_t) 0x039D);
+    else if (Str::eq(macro, I"Xi")) PUT((wchar_t) 0x039E);
+    else if (Str::eq(macro, I"Omicron")) PUT((wchar_t) 0x039F);
+    else if (Str::eq(macro, I"Pi")) PUT((wchar_t) 0x03A0);
+    else if (Str::eq(macro, I"Rho")) PUT((wchar_t) 0x03A1);
+    else if (Str::eq(macro, I"Varsigma")) PUT((wchar_t) 0x03A2);
+    else if (Str::eq(macro, I"Sigma")) PUT((wchar_t) 0x03A3);
+    else if (Str::eq(macro, I"Tau")) PUT((wchar_t) 0x03A4);
+    else if (Str::eq(macro, I"Upsilon")) PUT((wchar_t) 0x03A5);
+    else if (Str::eq(macro, I"Phi")) PUT((wchar_t) 0x03A6);
+    else if (Str::eq(macro, I"Chi")) PUT((wchar_t) 0x03A7);
+    else if (Str::eq(macro, I"Psi")) PUT((wchar_t) 0x03A8);
+    else if (Str::eq(macro, I"Omega")) PUT((wchar_t) 0x03A9);
+    else if (Str::eq(macro, I"alpha")) PUT((wchar_t) 0x03B1);
+    else if (Str::eq(macro, I"beta")) PUT((wchar_t) 0x03B2);
+    else if (Str::eq(macro, I"gamma")) PUT((wchar_t) 0x03B3);
+    else if (Str::eq(macro, I"delta")) PUT((wchar_t) 0x03B4);
+    else if (Str::eq(macro, I"epsilon")) PUT((wchar_t) 0x03B5);
+    else if (Str::eq(macro, I"zeta")) PUT((wchar_t) 0x03B6);
+    else if (Str::eq(macro, I"eta")) PUT((wchar_t) 0x03B7);
+    else if (Str::eq(macro, I"theta")) PUT((wchar_t) 0x03B8);
+    else if (Str::eq(macro, I"iota")) PUT((wchar_t) 0x03B9);
+    else if (Str::eq(macro, I"kappa")) PUT((wchar_t) 0x03BA);
+    else if (Str::eq(macro, I"lambda")) PUT((wchar_t) 0x03BB);
+    else if (Str::eq(macro, I"mu")) PUT((wchar_t) 0x03BC);
+    else if (Str::eq(macro, I"nu")) PUT((wchar_t) 0x03BD);
+    else if (Str::eq(macro, I"xi")) PUT((wchar_t) 0x03BE);
+    else if (Str::eq(macro, I"omicron")) PUT((wchar_t) 0x03BF);
+    else if (Str::eq(macro, I"pi")) PUT((wchar_t) 0x03C0);
+    else if (Str::eq(macro, I"rho")) PUT((wchar_t) 0x03C1);
+    else if (Str::eq(macro, I"varsigma")) PUT((wchar_t) 0x03C2);
+    else if (Str::eq(macro, I"sigma")) PUT((wchar_t) 0x03C3);
+    else if (Str::eq(macro, I"tau")) PUT((wchar_t) 0x03C4);
+    else if (Str::eq(macro, I"upsilon")) PUT((wchar_t) 0x03C5);
+    else if (Str::eq(macro, I"phi")) PUT((wchar_t) 0x03C6);
+    else if (Str::eq(macro, I"chi")) PUT((wchar_t) 0x03C7);
+    else if (Str::eq(macro, I"psi")) PUT((wchar_t) 0x03C8);
+    else if (Str::eq(macro, I"omega")) PUT((wchar_t) 0x03C9);
+    else if (Str::eq(macro, I"exists")) PUT((wchar_t) 0x2203);
+    else if (Str::eq(macro, I"in")) PUT((wchar_t) 0x2208);
+    else if (Str::eq(macro, I"forall")) PUT((wchar_t) 0x2200);
+    else if (Str::eq(macro, I"cap")) PUT((wchar_t) 0x2229);
+    else if (Str::eq(macro, I"emptyset")) PUT((wchar_t) 0x2205);
+    else if (Str::eq(macro, I"subseteq")) PUT((wchar_t) 0x2286);
+    else if (Str::eq(macro, I"land")) PUT((wchar_t) 0x2227);
+    else if (Str::eq(macro, I"lor")) PUT((wchar_t) 0x2228);
+    else if (Str::eq(macro, I"lnot")) PUT((wchar_t) 0x00AC);
+    else if (Str::eq(macro, I"sum")) PUT((wchar_t) 0x03A3);
+    else if (Str::eq(macro, I"prod")) PUT((wchar_t) 0x03A0);
     else {
-        if (Str::len(macro) > 0) {
+        if (Str::len(macro) > 0) {
             int suspect = TRUE;
-            LOOP_THROUGH_TEXT(pos, macro) {
+            LOOP_THROUGH_TEXT(pos, macro) {
                 wchar_t c = Str::get(pos);
                 if ((c >= 'A') && (c <= 'Z')) continue;
                 if ((c >= 'a') && (c <= 'z')) continue;
                 suspect = FALSE;
             }
-            if (Str::eq(macro, I"n")) suspect = FALSE;
-            if (Str::eq(macro, I"t")) suspect = FALSE;
+            if (Str::eq(macro, I"n")) suspect = FALSE;
+            if (Str::eq(macro, I"t")) suspect = FALSE;
             if (suspect)
-                PRINT("[Passing through unknown TeX macro \\%S:\n  %S\n", macro, text);
+                PRINT("[Passing through unknown TeX macro \\%S:\n  %S\n", macro, text);
         }
-        WRITE("\\%S", macro);
+        WRITE("\\%S", macro);
     }
 
  • This code is used in §7.4.
@@ -448,14 +448,14 @@ we also look out for {}^3\sqr
     if (Str::get_at(text, i) == '\\') {
-        Str::clear(macro);
+        Str::clear(macro);
         i++;
         while ((i < Str::len(text)) && (Characters::isalpha(Str::get_at(text, i))))
-            PUT_TO(macro, Str::get_at(text, i++));
-        if (Str::eq(macro, I"exists")) PUT((wchar_t) 0x2204);
-        else if (Str::eq(macro, I"forall")) { PUT((wchar_t) 0x00AC); PUT((wchar_t) 0x2200); }
+            PUT_TO(macro, Str::get_at(text, i++));
+        if (Str::eq(macro, I"exists")) PUT((wchar_t) 0x2204);
+        else if (Str::eq(macro, I"forall")) { PUT((wchar_t) 0x00AC); PUT((wchar_t) 0x2200); }
         else {
-            PRINT("Don't know how to apply '\\not' to '\\%S'\n", macro);
+            PRINT("Don't know how to apply '\\not' to '\\%S'\n", macro);
         }
     } else {
         PRINT("Don't know how to apply '\\not' here\n");
diff --git a/docs/inweb/5-wt.html b/docs/inweb/5-wt.html
index 0e8897c..fa74d8f 100644
--- a/docs/inweb/5-wt.html
+++ b/docs/inweb/5-wt.html
@@ -299,7 +299,7 @@ function togglePopup(material_id) {
     CLASS_DEFINITION
 } weave_verbatim_node;
 
-
  • The structure weave_document_node is accessed in 3/tc, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_head_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_body_node is private to this section.
  • The structure weave_tail_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_chapter_header_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_chapter_footer_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_section_header_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_section_footer_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_section_purpose_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_subheading_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_bar_node is private to this section.
  • The structure weave_pagebreak_node is private to this section.
  • The structure weave_linebreak_node is private to this section.
  • The structure weave_paragraph_heading_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_endnote_node is private to this section.
  • The structure weave_figure_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_extract_node is accessed in 5/hf and here.
  • The structure weave_audio_node is accessed in 8/ws, 5/tf, 5/hf, 5/df and here.
  • The structure weave_video_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_download_node is accessed in 5/hf, 5/df and here.
  • The structure weave_material_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_embed_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_pmac_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_vskip_node is accessed in 5/tf, 5/df and here.
  • The structure weave_chapter_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_section_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_code_line_node is private to this section.
  • The structure weave_function_usage_node is accessed in 1/wp, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_commentary_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_carousel_slide_node is accessed in 2/tgs, 5/hf, 5/df and here.
  • The structure weave_toc_node is accessed in 5/tf, 5/df and here.
  • The structure weave_toc_line_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_chapter_title_page_node is private to this section.
  • The structure weave_defn_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_inline_node is private to this section.
  • The structure weave_locale_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_source_code_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_url_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_footnote_cue_node is accessed in 2/tp, 3/tw, 3/twot, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_begin_footnote_text_node is accessed in 2/tp, 3/tw, 3/twot, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_display_line_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_function_defn_node is accessed in 1/wp, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_item_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_grammar_index_node is private to this section.
  • The structure weave_maths_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_verbatim_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
+
  • The structure weave_document_node is accessed in 3/tc, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_head_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_body_node is private to this section.
  • The structure weave_tail_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_chapter_header_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_chapter_footer_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_section_header_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_section_footer_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_section_purpose_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_subheading_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_bar_node is private to this section.
  • The structure weave_pagebreak_node is private to this section.
  • The structure weave_linebreak_node is private to this section.
  • The structure weave_paragraph_heading_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_endnote_node is private to this section.
  • The structure weave_figure_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_extract_node is accessed in 5/hf and here.
  • The structure weave_audio_node is accessed in 8/ws, 5/tf, 5/hf, 5/df and here.
  • The structure weave_video_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_download_node is accessed in 5/hf, 5/df and here.
  • The structure weave_material_node is accessed in 5/tf, 5/hf, 5/df and here.
  • The structure weave_embed_node is accessed in 1/fm, 1/pp, 1/wp, 8/ws, 4/cl, 5/ptf, 5/tf, 5/hf, 5/df, 6/rw and here.
  • The structure weave_pmac_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_vskip_node is accessed in 5/tf, 5/df and here.
  • The structure weave_chapter_node is accessed in 5/ptf, 5/tf, 5/df and here.
  • The structure weave_section_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_code_line_node is private to this section.
  • The structure weave_function_usage_node is accessed in 1/wp, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_commentary_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_carousel_slide_node is accessed in 2/tgs, 5/hf, 5/df and here.
  • The structure weave_toc_node is accessed in 5/tf, 5/df and here.
  • The structure weave_toc_line_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_chapter_title_page_node is private to this section.
  • The structure weave_defn_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_inline_node is private to this section.
  • The structure weave_locale_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_source_code_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_url_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_footnote_cue_node is accessed in 2/tp, 3/tw, 3/twot, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_begin_footnote_text_node is accessed in 2/tp, 3/tw, 3/twot, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_display_line_node is accessed in 1/pc, 2/lc, 2/tp, 2/pn, 3/ta, 3/tw, 3/tt, 4/as, 4/cl, 4/is, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs and here.
  • The structure weave_function_defn_node is accessed in 1/wp, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_item_node is accessed in 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_grammar_index_node is private to this section.
  • The structure weave_maths_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df and here.
  • The structure weave_verbatim_node is accessed in 2/trs, 3/twot, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df and here.

§2.

diff --git a/docs/inweb/6-gs.html b/docs/inweb/6-gs.html
index 1a7e3dc..2c6acf9 100644
--- a/docs/inweb/6-gs.html
+++ b/docs/inweb/6-gs.html
@@ -61,7 +61,7 @@ function togglePopup(material_id) {
     WRITE_TO(header, "# This gitignore was automatically written by inweb -gitignore\n");
     WRITE_TO(header, "# and is not intended for human editing\n\n");
     WRITE_TO(STDOUT, "(Read script from %f)\n", prototype);
-    Preprocessor::preprocess(prototype, F, header, L, NULL_GENERAL_POINTER);
+    Preprocessor::preprocess(prototype, F, header, L, NULL_GENERAL_POINTER, '#');
 }
 

§2. Our one non-standard macro simply includes a file of standing material which diff --git a/docs/inweb/6-mkf.html b/docs/inweb/6-mkf.html index 547a784..bf56953 100644 --- a/docs/inweb/6-mkf.html +++ b/docs/inweb/6-mkf.html @@ -86,7 +86,8 @@ special loop construct. WRITE_TO(header, "# and is not intended for human editing\n\n"); WRITE_TO(STDOUT, "(Read script from %f)\n", prototype); - Preprocessor::preprocess(prototype, F, header, L, STORE_POINTER_makefile_specifics(specifics)); + Preprocessor::preprocess(prototype, F, header, L, + STORE_POINTER_makefile_specifics(specifics), '#'); }

§1.1. We will allow a makescript to declare "components" (webs, really), so we need diff --git a/docs/inweb/6-rw.html b/docs/inweb/6-rw.html index 5a09eaf..9eee223 100644 --- a/docs/inweb/6-rw.html +++ b/docs/inweb/6-rw.html @@ -50,277 +50,38 @@ function togglePopup(material_id) {

To construct Readme and similar files.

-

§1. This is a very simple generator for README.md files, written in Markdown -syntax, but with a few macro expansions of our own. The prototype file, which -uses these extra macros, is expanded to the final file, which does not. -

- -

As we scan through the prototype file, we keep track of this: +

§1. This is a simple use of Preprocessor (in foundation). Note that we use a +non-standard comment syntax (i.e., / at start of line, not #) to avoid +colliding with Markdown's heading syntax.

-typedef struct write_state {
-    struct text_stream *OUT;
-    struct linked_list *known_macros;  of macro
-    struct macro *current_definition;
-    struct macro_tokens *stack_frame;
-} write_state;
-
-void Readme::write(filename *from, filename *to) {
-    WRITE_TO(STDOUT, "write-me: %f --> %f\n", from, to);
-    write_state ws;
-    ws.current_definition = NULL;
-    ws.known_macros = NEW_LINKED_LIST(macro);
-    macro *V = Readme::new_macro(I"version", NULL, NULL);
-    ADD_TO_LINKED_LIST(V, macro, ws.known_macros);
-    macro *P = Readme::new_macro(I"purpose", NULL, NULL);
-    ADD_TO_LINKED_LIST(P, macro, ws.known_macros);
-    macro *A = Readme::new_macro(I"var", NULL, NULL);
-    ADD_TO_LINKED_LIST(A, macro, ws.known_macros);
-    ws.stack_frame = NULL;
-    text_stream file_to;
-    if (Streams::open_to_file(&file_to, to, UTF8_ENC) == FALSE)
-        Errors::fatal_with_file("can't write readme file", to);
-    ws.OUT = &file_to;
-    TextFiles::read(from, FALSE, "unable to read template file", TRUE,
-        &Readme::write_helper, NULL, (void *) &ws);
-    Streams::close(&file_to);
+void Readme::write(filename *prototype, filename *F) {
+    linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
+    preprocessor_macro *mm = Preprocessor::new_macro(L,
+        I"bibliographic", I"datum: DATUM of: ASSET",
+        Readme::bibliographic_expander, NULL);
+    Preprocessor::do_not_suppress_whitespace(mm);
+    WRITE_TO(STDOUT, "(Read script from %f)\n", prototype);
+    Preprocessor::preprocess(prototype, F, NULL, L, NULL_GENERAL_POINTER, '/');
 }
 
-
  • The structure write_state is accessed in 4/prp, 1/apacs, 5/ptf, 5/tf, 5/hf, 5/df and here.
-

§2. The file consists of definitions of macros, made one at a time, and -starting with @define and finishing with @end, and actual material. +

§2. And this is the one domain-specific macro:

-void Readme::write_helper(text_stream *text, text_file_position *tfp, void *state) {
-    write_state *ws = (write_state *) state;
-    text_stream *OUT = ws->OUT;
-
-    match_results mr = Regexp::create_mr();
-    if (Regexp::match(&mr, text, L" *@end *")) {
-        if (ws->current_definition == NULL)
-            Errors::in_text_file("@end without @define", tfp);
-        else ws->current_definition = NULL;
-    } else if (ws->current_definition) {
-        if (Str::len(ws->current_definition->content) > 0)
-            WRITE_TO(ws->current_definition->content, "\n");
-        WRITE_TO(ws->current_definition->content, "%S", text);
-    } else if (Regexp::match(&mr, text, L" *@define (%i+)(%c*)")) {
-        if (ws->current_definition)
-            Errors::in_text_file("@define without @end", tfp);
-        else {
-            macro *M = Readme::new_macro(mr.exp[0], mr.exp[1], tfp);
-            ws->current_definition = M;
-            ADD_TO_LINKED_LIST(M, macro, ws->known_macros);
-        }
-    } else {
-        Readme::expand_material(ws, OUT, text, tfp);
-        Readme::expand_material(ws, OUT, I"\n", tfp);
-    }
-    Regexp::dispose_of(&mr);
+void Readme::bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+    text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+    text_stream *datum = parameter_values[0];
+    text_stream *asset_name = parameter_values[1];
+    text_stream *OUT = PPS->dest;
+    writeme_asset *A = Readme::find_asset(asset_name);
+    if (A->if_web) WRITE("%S", Bibliographic::get_datum(A->if_web, datum));
+    else if (Str::eq(datum, I"Build Date")) WRITE("%S", A->date);
+    else if (Str::eq(datum, I"Version Number")) WRITE("%S", A->version);
 }
 
-

§3. The "content" of a macro is its definition, and the tokens are named -parameters. -

- -
-typedef struct macro {
-    struct text_stream *name;
-    struct text_stream *content;
-    struct macro_tokens tokens;
-    CLASS_DEFINITION
-} macro;
-
-macro *Readme::new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) {
-    macro *M = CREATE(macro);
-    M->name = Str::duplicate(name);
-    M->tokens = Readme::parse_token_list(tokens, tfp);
-    M->content = Str::new();
-    return M;
-}
-
-typedef struct macro_tokens {
-    struct macro *bound_to;
-    struct text_stream *pars[8];
-    int no_pars;
-    struct macro_tokens *down;
-    CLASS_DEFINITION
-} macro_tokens;
-
-
  • The structure macro is accessed in 2/trs, 4/prp, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs, 6/cln and here.
  • The structure macro_tokens is private to this section.
-

§4.

- -
-macro_tokens Readme::parse_token_list(text_stream *chunk, text_file_position *tfp) {
-    macro_tokens mt;
-    mt.no_pars = 0;
-    mt.down = NULL;
-    mt.bound_to = NULL;
-    if (Str::get_first_char(chunk) == '(') {
-        int x = 1, bl = 1, from = 1, quoted = FALSE;
-        while ((bl > 0) && (Str::get_at(chunk, x) != 0)) {
-            wchar_t c = Str::get_at(chunk, x);
-            if (c == '\'') {
-                quoted = quoted?FALSE:TRUE;
-            } else if (quoted == FALSE) {
-                if (c == '(') bl++;
-                else if (c == ')') {
-                    bl--;
-                    if (bl == 0) Recognise token4.1;
-                } else if ((c == ',') && (bl == 1)) Recognise token4.1;
-            }
-            x++;
-        }
-        Str::delete_n_characters(chunk, x);
-    }
-    return mt;
-}
-
-

§4.1. Quotes can be used in token lists so that literal commas and brackets can -be used without breaking the flow. -

- -

Recognise token4.1 = -

- -
-    int n = mt.no_pars;
-    if (n >= 8) Errors::in_text_file("too many parameters", tfp);
-    else {
-        mt.pars[n] = Str::new();
-        for (int j=from; j<x; j++) PUT_TO(mt.pars[n], Str::get_at(chunk, j));
-        Str::trim_white_space(mt.pars[n]);
-        if ((Str::get_first_char(mt.pars[n]) == '\'') &&
-            (Str::get_last_char(mt.pars[n]) == '\'')) {
-            Str::delete_first_character(mt.pars[n]);
-            Str::delete_last_character(mt.pars[n]);
-        }
-        mt.no_pars++;
-    }
-    from = x+1;
-
-
  • This code is used in §4 (twice).
-

§5. So much for creating macros. Now we can write the actual expander. As can -be seen, it passes material straight through, except for instances of the -notation @name, possibly followed by a bracketed list of parameters. -

- -
-void Readme::expand_material(write_state *ws, text_stream *OUT, text_stream *text,
-    text_file_position *tfp) {
-    match_results mr = Regexp::create_mr();
-    if (Regexp::match(&mr, text, L"(%c*?)@(%i+)(%c*)")) {
-        Readme::expand_material(ws, OUT, mr.exp[0], tfp);
-        macro_tokens mt = Readme::parse_token_list(mr.exp[2], tfp);
-        mt.down = ws->stack_frame;
-        ws->stack_frame = &mt;
-        Readme::expand_at(ws, OUT, mr.exp[1], tfp);
-        ws->stack_frame = mt.down;
-        Readme::expand_material(ws, OUT, mr.exp[2], tfp);
-    } else {
-        WRITE("%S", text);
-    }
-    Regexp::dispose_of(&mr);
-}
-
-

§6. If we run into the notation @something, it's possible that something is -the name of a parameter somewhere in the current stack, either on the top -frame or on frames lower down. The first match wins... and if there are no -matches, then it must be a macro name. -

- -
-void Readme::expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name,
-    text_file_position *tfp) {
-    macro_tokens *stack = ws->stack_frame;
-    while (stack) {
-        macro *in = stack->bound_to;
-        if (in)
-            for (int n = 0; n < in->tokens.no_pars; n++)
-                if (Str::eq(in->tokens.pars[n], macro_name)) {
-                    if (n < stack->no_pars) {
-                        Readme::expand_material(ws, OUT, stack->pars[n], tfp);
-                        return;
-                    }
-                }
-        stack = stack->down;
-    }
-
-    macro *M;
-    LOOP_OVER_LINKED_LIST(M, macro, ws->known_macros)
-        if (Str::eq(M->name, macro_name)) {
-            ws->stack_frame->bound_to = M;
-            Readme::expand_macro(ws, OUT, M, tfp);
-            return;
-        }
-    Errors::in_text_file("no such @-command", tfp);
-    WRITE_TO(STDERR, "(command is '%S')\n", macro_name);
-}
-
-

§7. So, then: suppose we have to expand @example(5, gold rings). Then the -macro_name below is set to example, and the current stack frame contains the -values 5 and gold rings. -

- -
-void Readme::expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) {
-    if (Str::eq(M->name, I"version")) Perform built-in expansion of version macro7.1
-    else if (Str::eq(M->name, I"purpose")) Perform built-in expansion of purpose macro7.2
-    else if (Str::eq(M->name, I"var")) Perform built-in expansion of var macro7.3
-    else {
-        ws->stack_frame->bound_to = M;
-        Readme::expand_material(ws, OUT, M->content, tfp);
-    }
-}
-
-

§7.1. Perform built-in expansion of version macro7.1 = -

- -
-    if (ws->stack_frame->no_pars != 1)
-        Errors::in_text_file("@version takes 1 parameter", tfp);
-    else {
-        TEMPORARY_TEXT(program)
-        Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp);
-        Readme::write_var(OUT, program, I"Version Number");
-        DISCARD_TEXT(program)
-    }
-
-
  • This code is used in §7.
-

§7.2. Perform built-in expansion of purpose macro7.2 = -

- -
-    if (ws->stack_frame->no_pars != 1)
-        Errors::in_text_file("@purpose takes 1 parameter", tfp);
-    else {
-        TEMPORARY_TEXT(program)
-        Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp);
-        Readme::write_var(OUT, program, I"Purpose");
-        DISCARD_TEXT(program)
-    }
-
-
  • This code is used in §7.
-

§7.3. Perform built-in expansion of var macro7.3 = -

- -
-    if (ws->stack_frame->no_pars != 2)
-        Errors::in_text_file("@var takes 2 parameters", tfp);
-    else {
-        TEMPORARY_TEXT(program)
-        TEMPORARY_TEXT(bibv)
-        Readme::expand_material(ws, program, ws->stack_frame->pars[0], tfp);
-        Readme::expand_material(ws, bibv, ws->stack_frame->pars[1], tfp);
-        Readme::write_var(OUT, program, bibv);
-        DISCARD_TEXT(program)
-        DISCARD_TEXT(bibv)
-    }
-
-
  • This code is used in §7.
-

§8. An "asset" here is something for which we might want to write the version +

§3. An "asset" here is something for which we might want to write the version number of, or some similar metadata for. Assets are usually webs, but can also be a few other rather Inform-specific things; those have a more limited range of bibliographic data, just the version and date (and we will not @@ -337,19 +98,19 @@ assume that the version complies with any format). CLASS_DEFINITION } writeme_asset; -void Readme::write_var(text_stream *OUT, text_stream *program, text_stream *datum) { - writeme_asset *A = Readme::find_asset(program); +void Readme::write_var(text_stream *OUT, text_stream *program, text_stream *datum) { + writeme_asset *A = Readme::find_asset(program); if (A->if_web) WRITE("%S", Bibliographic::get_datum(A->if_web, datum)); else if (Str::eq(datum, I"Build Date")) WRITE("%S", A->date); else if (Str::eq(datum, I"Version Number")) WRITE("%S", A->version); }

  • The structure writeme_asset is accessed in 2/trs, 4/prp, 5/wt, 6/cs, 6/cln and here.
-

§9. That just leaves the business of inspecting assets to obtain their metadata. +

§4. That just leaves the business of inspecting assets to obtain their metadata.

-writeme_asset *Readme::find_asset(text_stream *program) {
+writeme_asset *Readme::find_asset(text_stream *program) {
     writeme_asset *A;
     LOOP_OVER(A, writeme_asset) if (Str::eq(program, A->name)) return A;
     A = CREATE(writeme_asset);
@@ -358,70 +119,70 @@ assume that the version complies with any format).
     A->date = Str::new();
     A->version = Str::new();
     A->next_is_version = FALSE;
-    Read in the asset9.1;
+    Read in the asset4.1;
     return A;
 }
 
-

§9.1. Read in the asset9.1 = +

§4.1. Read in the asset4.1 =

     if (Str::ends_with_wide_string(program, L".i7x")) {
-        Read in the extension file9.1.1;
+        Read in the extension file4.1.1;
     } else {
         if (WebMetadata::directory_looks_like_a_web(Pathnames::from_text(program))) {
             A->if_web = WebMetadata::get_without_modules(Pathnames::from_text(program), NULL);
         } else {
             filename *I6_vn = Filenames::in(
                 Pathnames::down(Pathnames::from_text(program), I"inform6"), I"header.h");
-            if (TextFiles::exists(I6_vn)) Read in I6 source header file9.1.2;
+            if (TextFiles::exists(I6_vn)) Read in I6 source header file4.1.2;
             filename *template_vn = Filenames::in(Pathnames::from_text(program), I"(manifest).txt");
-            if (TextFiles::exists(template_vn)) Read in template manifest file9.1.3;
+            if (TextFiles::exists(template_vn)) Read in template manifest file4.1.3;
             filename *rmt_vn = Filenames::in(Pathnames::from_text(program), I"README.txt");
-            if (TextFiles::exists(rmt_vn)) Read in README file9.1.4;
+            if (TextFiles::exists(rmt_vn)) Read in README file4.1.4;
             rmt_vn = Filenames::in(Pathnames::from_text(program), I"README.md");
-            if (TextFiles::exists(rmt_vn)) Read in README file9.1.4;
+            if (TextFiles::exists(rmt_vn)) Read in README file4.1.4;
         }
     }
 
-
  • This code is used in §9.
-

§9.1.1. Read in the extension file9.1.1 = +

  • This code is used in §4.
+

§4.1.1. Read in the extension file4.1.1 =

     TextFiles::read(Filenames::from_text(program), FALSE, "unable to read extension", TRUE,
-        &Readme::extension_harvester, NULL, A);
+        &Readme::extension_harvester, NULL, A);
 
-
  • This code is used in §9.1.
-

§9.1.2. Read in I6 source header file9.1.2 = +

  • This code is used in §4.1.
+

§4.1.2. Read in I6 source header file4.1.2 =

     TextFiles::read(I6_vn, FALSE, "unable to read header file from I6 source", TRUE,
-        &Readme::header_harvester, NULL, A);
+        &Readme::header_harvester, NULL, A);
 
-
  • This code is used in §9.1.
-

§9.1.3. Read in template manifest file9.1.3 = +

  • This code is used in §4.1.
+

§4.1.3. Read in template manifest file4.1.3 =

     TextFiles::read(template_vn, FALSE, "unable to read manifest file from website template", TRUE,
-        &Readme::template_harvester, NULL, A);
+        &Readme::template_harvester, NULL, A);
 
-
  • This code is used in §9.1.
-

§9.1.4. Read in README file9.1.4 = +

  • This code is used in §4.1.
+

§4.1.4. Read in README file4.1.4 =

     TextFiles::read(rmt_vn, FALSE, "unable to read README file from website template", TRUE,
-        &Readme::readme_harvester, NULL, A);
+        &Readme::readme_harvester, NULL, A);
 
-
  • This code is used in §9.1 (twice).
-

§10. The format for the contents section of a web is documented in Inweb. +

  • This code is used in §4.1 (twice).
+

§5. The format for the contents section of a web is documented in Inweb.

-void Readme::extension_harvester(text_stream *text, text_file_position *tfp, void *state) {
+void Readme::extension_harvester(text_stream *text, text_file_position *tfp, void *state) {
     writeme_asset *A = (writeme_asset *) state;
     match_results mr = Regexp::create_mr();
     if (Str::len(text) == 0) return;
@@ -430,11 +191,11 @@ assume that the version complies with any format).
     Regexp::dispose_of(&mr);
 }
 
-

§11. Explicit code to read from header.h in the Inform 6 repository. +

§6. Explicit code to read from header.h in the Inform 6 repository.

-void Readme::header_harvester(text_stream *text, text_file_position *tfp, void *state) {
+void Readme::header_harvester(text_stream *text, text_file_position *tfp, void *state) {
     writeme_asset *A = (writeme_asset *) state;
     match_results mr = Regexp::create_mr();
     if (Str::len(text) == 0) return;
@@ -445,11 +206,11 @@ assume that the version complies with any format).
     Regexp::dispose_of(&mr);
 }
 
-

§12. Explicit code to read from the manifest file of a website template. +

§7. Explicit code to read from the manifest file of a website template.

-void Readme::template_harvester(text_stream *text, text_file_position *tfp, void *state) {
+void Readme::template_harvester(text_stream *text, text_file_position *tfp, void *state) {
     writeme_asset *A = (writeme_asset *) state;
     match_results mr = Regexp::create_mr();
     if (Str::len(text) == 0) return;
@@ -462,11 +223,11 @@ assume that the version complies with any format).
     Regexp::dispose_of(&mr);
 }
 
-

§13. And this is needed for cheapglk and glulxe in the Inform repository. +

§8. And this is needed for cheapglk and glulxe in the Inform repository.

-void Readme::readme_harvester(text_stream *text, text_file_position *tfp, void *state) {
+void Readme::readme_harvester(text_stream *text, text_file_position *tfp, void *state) {
     writeme_asset *A = (writeme_asset *) state;
     match_results mr = Regexp::create_mr();
     if (Str::len(text) == 0) return;
diff --git a/docs/inweb/M-wtaw.html b/docs/inweb/M-wtaw.html
index 0f50b75..69e0cea 100644
--- a/docs/inweb/M-wtaw.html
+++ b/docs/inweb/M-wtaw.html
@@ -48,7 +48,7 @@
     
 

How to use Inweb to weave or tangle a web already written.

-
+

§1. All-in-one webs. A program written for use with Inweb is called a "web". Inweb was primarily designed for large, multisection webs, but it can also be used in a much @@ -811,28 +811,7 @@ not .mkscript -

§26. Ctags. Each time a web is tangled, Inweb writes a tags file to the web's home -directory, containing a list of Universal ctags -for any structures, functions or constant definitions found in the web. You -need do nothing to make this happen, and can ignore the file if it's of no -use. If you are editing a web in certain text editors, though, such as -BBEdit for MacOS, then this -should make code completion and definition lookup features work. -

- -

You can however write the file elsewhere: -

- -
-    $ inweb/Tangled/inweb W -tangle -ctags-to secret_lair/my_nifty.ctags
-
-

or not at all: -

- -
-    $ inweb/Tangled/inweb W -tangle -no-ctags
-
-

§27. README files. Repositories at Github customarily have README.mk files, in Markdown +

§26. README files. Repositories at Github customarily have README.mk files, in Markdown syntax, explaining what they are. These of course should probably include current version numbers, and it's a pain keeping that up to date. For really complicated repositories, containing multiple webs, some automation @@ -840,63 +819,22 @@ is essential, and once again Inweb can oblige.

-    $ inweb/Tangled/inweb W -write-me W/README.mk
+    $ inweb/Tangled/inweb W -prototype W/W.rmscript -write-me W/README.mk
 
-

expands a script called READMEscript.txt into README.mk. Alternatively, -the script can be specified explicitly: +

The same conventions and notations are used here as for makefiles and gitignores +(see above), except that the comment character is no longer #, since a # +at the start of a line means a heading in Markdown. Instead, a line is a comment +if its first non-whitespace character is a forward-slash /.

-
-    $ inweb/Tangled/inweb W -prototype MySpecialThang.txt -write-me W/README.mk
-
-

§28. Everything in the script is copied over verbatim except where the @ character -is used, which was chosen because it isn't significant in Github's form of -Markdown. @name(args) is like a function call (or, in more traditional -language, a macro): it expands out to something depending on the arguments. -args is a comma-separated list of fragments of text, which can themselves -contain further uses of @. (If these fragments of text need to contain -commas or brackets, they can be put into single quotes: @thus(4,',') has -two arguments, 4 and ,.) Three functions are built in: -

- -
  • (a) @version(A) expands to the version number of A, which is normally the -path to a web; it then produces the value of the [[Version Number]] for -that web. But A can also be the filename of an Inform extension, provided -that it ends in .i7x, or a few other Inform-specific things for which -Inweb is able to deduce a version number. -
  • (b) @purpose(A) is the same, but for the [[Purpose]] of a web. It's -blank for everything else. -
  • (c) @var(A,D) is more general, and reads the bibliographic datum D from -the web indicated by A. In fact, @version(A) is an abbreviation for -@var(A,Version Number) and @purpose(A) for @var(A,Purpose), so this -is really the only one needed. +
    • ● The special makefile macros are not available, though set and repeat are; +
    • ● The special macro {bibliographic datum: ... of: ...} expands to the value +of the named bibliographic datum for the program named. Version Number is +especially useful, and is available even for some Inform assets which are not +webs and do not therefore have bibliographic data of their own — interpreter +templates and Inform 7 extensions, for example.
    -

    §29. It is also possible to define new functions. For example: -

    - -
    -    @define book(title, path, topic)
    -    * @title - @topic. Ebook in Indoc format, stored at path @path.
    -    @end
    -
    -

    The definition lies between @define and @end commands. This one takes -three parameters, and inside the definition, their values can be referred -to as @title, @path and @topic. Functions are free to use other -functions: -

    - -
    -    @define primary(program, language)
    -    * @program - @purpose(@program) - __@version(@program)__
    -    @end
    -
    -

    However, each function needs to have been defined before any line on which -it is actually expanded. A definition of one function A can refer to another -function B not yet defined; but any actual use of A must be made after -both A and B have been defined. So, basically, declare before use. -

    - -

    §30. Semantic version numbering and build metadata. When Inweb reads in a web, it also looks for a file called build.txt in +

    §27. Semantic version numbering and build metadata. When Inweb reads in a web, it also looks for a file called build.txt in the web's directory; if that isn't there, it looks for the same file in the current working directory; if that's not there either, never mind.

    @@ -929,7 +867,7 @@ the web as the variable Seman

    For more on semvers, see: https://semver.org

    -

    §31. A special advancing mechanism exists to update build numbers and dates. +

    §28. A special advancing mechanism exists to update build numbers and dates. Running Inweb with -advance-build W checks the build date for web W: if it differs from today, then it is changed to today, and the build code is advanced by one. @@ -939,6 +877,27 @@ is advanced by one. without need of a web.

    +

    §29. Ctags. Each time a web is tangled, Inweb writes a tags file to the web's home +directory, containing a list of Universal ctags +for any structures, functions or constant definitions found in the web. You +need do nothing to make this happen, and can ignore the file if it's of no +use. If you are editing a web in certain text editors, though, such as +BBEdit for MacOS, then this +should make code completion and definition lookup features work. +

    + +

    You can however write the file elsewhere: +

    + +
    +    $ inweb/Tangled/inweb W -tangle -ctags-to secret_lair/my_nifty.ctags
    +
    +

    or not at all: +

    + +
    +    $ inweb/Tangled/inweb W -tangle -no-ctags
    +
    diff --git a/foundation-module/Chapter 4/Preprocessor.w b/foundation-module/Chapter 4/Preprocessor.w index 8ada442..a493179 100644 --- a/foundation-module/Chapter 4/Preprocessor.w +++ b/foundation-module/Chapter 4/Preprocessor.w @@ -21,7 +21,7 @@ pointer to any data those special meanings need to use. = void Preprocessor::preprocess(filename *prototype, filename *F, text_stream *header, - linked_list *special_macros, general_pointer specifics) { + linked_list *special_macros, general_pointer specifics, wchar_t comment_char) { struct text_stream processed_file; if (STREAM_OPEN_TO_FILE(&processed_file, F, ISO_ENC) == FALSE) Errors::fatal_with_file("unable to write tangled file", F); @@ -53,6 +53,7 @@ typedef struct preprocessor_state { struct preprocessor_variable_set *stack_frame; struct linked_list *known_macros; /* of |preprocessor_macro| */ struct general_pointer specifics; + wchar_t comment_character; } preprocessor_state; typedef struct preprocessor_loop { @@ -73,6 +74,7 @@ typedef struct preprocessor_loop { PPS.stack_frame = PPS.global_variables; PPS.known_macros = Preprocessor::list_of_reserved_macros(special_macros); PPS.specifics = specifics; + PPS.comment_character = comment_char; @ Conceptually, each loop runs a variable with a given name through a series of textual values in sequence, and we store that data here: @@ -95,17 +97,24 @@ parametrised names: but then, nor should you. = void Preprocessor::scan_line(text_stream *line, text_file_position *tfp, void *X) { preprocessor_state *PPS = (preprocessor_state *) X; - match_results mr = Regexp::create_mr(); @; @; Preprocessor::expand(line, tfp, PPS); @; } +@ A line is a comment to the preprocessor if its first non-whitespace character +is the special comment character: often |#|, but not necessarily. + @ = - if (Regexp::match(&mr, line, L" *#%c*")) { Regexp::dispose_of(&mr); return; } + LOOP_THROUGH_TEXT(pos, line) { + wchar_t c = Str::get(pos); + if (c == PPS->comment_character) return; + if (Characters::is_whitespace(c) == FALSE) break; + } @ = + match_results mr = Regexp::create_mr(); if (Regexp::match(&mr, line, L" *{define: *(%C+) (%c*)} *")) @; if (Regexp::match(&mr, line, L" *{end-define} *")) @; if (PPS->defining) @; @@ -635,6 +644,11 @@ linked_list *Preprocessor::list_of_reserved_macros(linked_list *special_macros) return L; } +void Preprocessor::do_not_suppress_whitespace(preprocessor_macro *mm) { + mm->suppress_newline_after_expanding = FALSE; + mm->suppress_whitespace_when_expanding = FALSE; +} + void Preprocessor::new_loop_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), @@ -657,18 +671,16 @@ void Preprocessor::new_loop_macro(linked_list *L, text_stream *name, mm = Preprocessor::new_macro(L, subname, parameter_specification, expander, tfp); mm->begins_loop = TRUE; mm->loop_name = Str::duplicate(name); - mm->suppress_newline_after_expanding = FALSE; - mm->suppress_whitespace_when_expanding = FALSE; mm->span = TRUE; + Preprocessor::do_not_suppress_whitespace(mm); Str::clear(subname); WRITE_TO(subname, "end-%S-span", name); mm = Preprocessor::new_macro(L, subname, NULL, Preprocessor::end_loop_expander, tfp); mm->ends_loop = TRUE; mm->loop_name = Str::duplicate(name); - mm->suppress_newline_after_expanding = FALSE; - mm->suppress_whitespace_when_expanding = FALSE; mm->span = TRUE; + Preprocessor::do_not_suppress_whitespace(mm); DISCARD_TEXT(subname) } diff --git a/inweb.mk b/inweb.mk index 80401f6..d153271 100644 --- a/inweb.mk +++ b/inweb.mk @@ -111,7 +111,7 @@ test: .PHONY: commit commit: $(INWEB) -advance-build-file $(ME)/build.txt - $(INWEB) -prototype inweb/scripts/READMEscript.txt -write-me inweb/README.md + $(INWEB) -prototype inweb/scripts/inweb.rmscript -write-me inweb/README.md cd $(ME); git commit -a .PHONY: pages @@ -130,7 +130,7 @@ pages: rm -f $(ME)/docs/docs-assets/*.png rm -f $(ME)/docs/docs-assets/*.gif cp -f $(ME)/docs-src/Octagram.png $(ME)/docs/docs-assets/Octagram.png - $(INWEB) -prototype inweb/scripts/READMEscript.txt -write-me inweb/README.md + $(INWEB) -prototype inweb/scripts/inweb.rmscript -write-me inweb/README.md mkdir -p $(ME)/docs/inweb rm -f $(ME)/docs/inweb/*.html mkdir -p $(ME)/docs/goldbach diff --git a/scripts/inweb.mkscript b/scripts/inweb.mkscript index 720f1e3..3926b3d 100644 --- a/scripts/inweb.mkscript +++ b/scripts/inweb.mkscript @@ -131,7 +131,7 @@ test: .PHONY: commit commit: $(INWEB) -advance-build-file $(ME)/build.txt - $(INWEB) -prototype inweb/scripts/READMEscript.txt -write-me inweb/README.md + $(INWEB) -prototype inweb/scripts/inweb.rmscript -write-me inweb/README.md cd $(ME); git commit -a # Weaving the web for GitHub Pages: @@ -152,7 +152,7 @@ pages: rm -f $(ME)/docs/docs-assets/*.png rm -f $(ME)/docs/docs-assets/*.gif cp -f $(ME)/docs-src/Octagram.png $(ME)/docs/docs-assets/Octagram.png - $(INWEB) -prototype inweb/scripts/READMEscript.txt -write-me inweb/README.md + $(INWEB) -prototype inweb/scripts/inweb.rmscript -write-me inweb/README.md mkdir -p $(ME)/docs/inweb rm -f $(ME)/docs/inweb/*.html mkdir -p $(ME)/docs/goldbach diff --git a/scripts/READMEscript.txt b/scripts/inweb.rmscript similarity index 93% rename from scripts/READMEscript.txt rename to scripts/inweb.rmscript index 7cfb57b..98b3e0f 100644 --- a/scripts/READMEscript.txt +++ b/scripts/inweb.rmscript @@ -1,6 +1,6 @@ -# Inweb @var(inweb,Version Number) +# Inweb {bibliographic datum: Version Number of: inweb} -v@var(inweb,Semantic Version Number) '@var(inweb,Version Name)' (@var(inweb,Build Date)) +v{bibliographic datum: Semantic Version Number of: inweb} '{bibliographic datum: Version Name of: inweb}' ({bibliographic datum: Build Date of: inweb}) ## About Inweb @@ -85,4 +85,4 @@ If you have also built Intest as "work/intest", then you can try these: ### Colophon This README.mk file was generated automatically by Inweb, and should not -be edited. To make changes, edit scripts/READMEscript.txt and re-generate. +be edited. To make changes, edit inweb.rmscript and re-generate.