diff --git a/Chapter_1/Assets, Plugins and Colour Schemes.w b/Chapter_1/Assets_Plugins_and_Colour_Schemes.nw similarity index 85% rename from Chapter_1/Assets, Plugins and Colour Schemes.w rename to Chapter_1/Assets_Plugins_and_Colour_Schemes.nw index 60298fe..019c6c4 100644 --- a/Chapter_1/Assets, Plugins and Colour Schemes.w +++ b/Chapter_1/Assets_Plugins_and_Colour_Schemes.nw @@ -3,19 +3,19 @@ Mainly for HTML, to add the necessary JavaScript for unusual requirements such as equations or footnotes. -@h Creation. +@ \section{Creation.} At present, plugins are simply their names: Inweb knows as little as possible about what they do. The model is just that a file being woven either does or does not need a plugin of a given name. -= +<<*>>= typedef struct weave_plugin { struct text_stream *plugin_name; int last_included_in_round; CLASS_DEFINITION } weave_plugin; -@ = +<<*>>= weave_plugin *Assets::new(text_stream *name) { weave_plugin *wp; LOOP_OVER(wp, weave_plugin) @@ -30,7 +30,7 @@ weave_plugin *Assets::new(text_stream *name) { @ And almost the same can be said about colour schemes, except that these we actually look for: they will be available to some patterns and not others. -= +<<*>>= typedef struct colour_scheme { struct text_stream *scheme_name; struct text_stream *prefix; @@ -39,7 +39,7 @@ typedef struct colour_scheme { CLASS_DEFINITION } colour_scheme; -@ = +<<*>>= colour_scheme *Assets::find_colour_scheme(weave_pattern *pattern, text_stream *name, text_stream *pre) { colour_scheme *cs; @@ -61,12 +61,12 @@ colour_scheme *Assets::find_colour_scheme(weave_pattern *pattern, return cs; } -@h Plugin inclusion. +@ \section{Plugin inclusion.} Plugins are included both by the pattern, if they are needed for anything woven to that pattern, and by the individual weave order, if a particular need has arisen on a particular file. -= +<<*>>= int current_inclusion_round = 0; void Assets::include_relevant_plugins(text_stream *OUT, weave_pattern *pattern, web *W, weave_order *wv, filename *from) { @@ -86,11 +86,11 @@ no matter how many times this is called. To include a plugin is by definition to include its assets. These may be held either in the current pattern, or in the one it is based on, or the one that in turn is based on, and so forth. The first-discovered asset wins: -i.e., if the current pattern's copy of the asset contains |MyAsset.png| then -this prevails over any |MyAsset.png| held by patterns further down. To do +i.e., if the current pattern's copy of the asset contains [[MyAsset.png]] then +this prevails over any [[MyAsset.png]] held by patterns further down. To do this, we store the leafnames in a dictionary. -= +<<*>>= void Assets::include_plugin(OUTPUT_STREAM, web *W, weave_plugin *wp, weave_pattern *pattern, filename *from) { if (wp->last_included_in_round == current_inclusion_round) return; @@ -125,13 +125,13 @@ void Assets::include_plugin(OUTPUT_STREAM, web *W, weave_plugin *wp, } } -@ Colour schemes are CSS files held slightly differently, in the |Colouring| +@ Colour schemes are CSS files held slightly differently, in the [[Colouring]] subdirectory of (presumably) an HTML-based pattern. A colour scheme can only be included once in each round, i.e., for each woven file, no matter how many times this is called. -= +<<*>>= void Assets::include_colour_scheme(OUTPUT_STREAM, web *W, colour_scheme *cs, weave_pattern *pattern, filename *from) { if (cs->last_included_in_round == current_inclusion_round) return; @@ -153,21 +153,22 @@ void Assets::include_colour_scheme(OUTPUT_STREAM, web *W, colour_scheme *cs, DISCARD_TEXT(css) } -@h Asset rules lists. +@ \section{Asset rules lists.} The practical effect of the two function above, then, is to call //Assets::include_asset// on each asset needed. What that function does is highly configurable by the pattern, so we now have to show how. Each -different filename extension, such as |.jpg|, has its own rule for what to do: +different filename extension, such as [[.jpg]], has its own rule for what to do: -@e EMBED_ASSET_METHOD from 1 -@e COPY_ASSET_METHOD -@e PRIVATE_COPY_ASSET_METHOD -@e COLLATE_ASSET_METHOD +<<*>>= +enum EMBED_ASSET_METHOD from 1 +enum COPY_ASSET_METHOD +enum PRIVATE_COPY_ASSET_METHOD +enum COLLATE_ASSET_METHOD -= +<<*>>= typedef struct asset_rule { struct text_stream *applies_to; - int method; /* one of the |*_ASSET_METHOD| values above */ + int method; /* one of the [[*_ASSET_METHOD]] values above */ struct text_stream *pre; struct text_stream *post; int transform_names; @@ -175,22 +176,22 @@ typedef struct asset_rule { } asset_rule; @ A pattern has a list of such rules, as follows. In each list, exactly one -rule has the empty text as its |applies_to|: that one is the default, for any +rule has the empty text as its [[applies_to]]: that one is the default, for any file whose extension does not appear in the rules list. (The default rule is to copy the file as a binary object, doing nothing fancy.) -= +<<*>>= linked_list *Assets::new_asset_rules_list(void) { linked_list *L = NEW_LINKED_LIST(asset_rule); Assets::add_asset_rule(L, I"", I"copy", NULL); return L; } -@ This is called by //Patterns// in response to |assets: EXT CMD| commands. The -|CMD| part is in |line|. +@ This is called by //Patterns// in response to [[assets: EXT CMD]] commands. The +[[CMD]] part is in [[line]]. -= +<<*>>= void Assets::add_asset_rule(linked_list *L, text_stream *ext, text_stream *line, text_file_position *tfp) { asset_rule *R = Assets::new_rule(L, ext, line, tfp); @@ -203,23 +204,23 @@ asset_rule *Assets::new_rule(linked_list *L, text_stream *ext, text_stream *line if (L) LOOP_OVER_LINKED_LIST(R, asset_rule, L) if (Str::eq_insensitive(R->applies_to, ext)) { - @; + <>; return R; } R = CREATE(asset_rule); R->applies_to = Str::duplicate(ext); - @; - @; + <>; + <>; return R; } -@ = +<>= R->method = COPY_ASSET_METHOD; R->pre = Str::new(); R->post = Str::new(); R->transform_names = FALSE; -@ = +<>= text_stream *cmd = line; text_stream *detail = NULL; match_results mr = Regexp::create_mr(); @@ -228,13 +229,13 @@ asset_rule *Assets::new_rule(linked_list *L, text_stream *ext, text_stream *line detail = mr.exp[1]; } if (Str::eq(cmd, I"copy")) { - @; R->method = COPY_ASSET_METHOD; + <>; R->method = COPY_ASSET_METHOD; } else if (Str::eq(cmd, I"private copy")) { - @; R->method = PRIVATE_COPY_ASSET_METHOD; + <>; R->method = PRIVATE_COPY_ASSET_METHOD; } else if (Str::eq(cmd, I"embed")) { - @; R->method = EMBED_ASSET_METHOD; + <>; R->method = EMBED_ASSET_METHOD; } else if (Str::eq(cmd, I"collate")) { - @; R->method = COLLATE_ASSET_METHOD; + <>; R->method = COLLATE_ASSET_METHOD; } else if (Str::eq(cmd, I"prefix")) { R->pre = Str::duplicate(detail); } else if (Str::eq(cmd, I"suffix")) { @@ -244,11 +245,11 @@ asset_rule *Assets::new_rule(linked_list *L, text_stream *ext, text_stream *line } else Errors::in_text_file("no such asset command", tfp); Regexp::dispose_of(&mr); -@ Given a filename |F| for some asset, which rule applies to it? The answer +@ Given a filename [[F]] for some asset, which rule applies to it? The answer is that if the current pattern, or any pattern it is based on, defines a rule, then the topmost one applies; and otherwise the default rule applies. -= +<<*>>= asset_rule *Assets::applicable_rule(weave_pattern *pattern, filename *F) { TEMPORARY_TEXT(ext) Filenames::write_extension(ext, F); @@ -266,11 +267,11 @@ asset_rule *Assets::applicable_rule(weave_pattern *pattern, filename *F) { return NULL; } -@h Inclusion of assets. +@ \section{Inclusion of assets.} Finally, then, we can include a single asset. This has already been located, -at filename |F|, and we now know how to find the applicable rule. +at filename [[F]], and we now know how to find the applicable rule. -= +<<*>>= pathname *Assets::include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename *F, text_stream *trans, weave_pattern *pattern, filename *from) { if (R == NULL) R = Assets::applicable_rule(pattern, F); @@ -280,19 +281,19 @@ pathname *Assets::include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename * WRITE_TO(url, "%S", Filenames::get_leafname(F)); if (R->transform_names == FALSE) trans = NULL; pathname *result = NULL; - if (Str::len(R->pre) > 0) @; + if (Str::len(R->pre) > 0) <>; switch (R->method) { - case EMBED_ASSET_METHOD: @; break; - case COPY_ASSET_METHOD: @; break; - case PRIVATE_COPY_ASSET_METHOD: @; break; - case COLLATE_ASSET_METHOD: @; break; + case EMBED_ASSET_METHOD: <>; break; + case COPY_ASSET_METHOD: <>; break; + case PRIVATE_COPY_ASSET_METHOD: <>; break; + case COLLATE_ASSET_METHOD: <>; break; } - if (Str::len(R->post) > 0) @; + if (Str::len(R->post) > 0) <>; DISCARD_TEXT(url) return result; } -@ = +<>= for (int i=0; ipre); i++) { if (Str::includes_at(R->pre, i, I"URL")) { WRITE("%S", url); @@ -301,11 +302,11 @@ pathname *Assets::include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename * } WRITE("\n"); -@ = +<>= if (verbose_mode) PRINT("Embed asset %f\n", F); Assets::transform(OUT, F, trans); -@ = +<>= pathname *H = W->redirect_weaves_to; if (H == NULL) H = Reader::woven_folder(W); if ((AP) && (R->method != PRIVATE_COPY_ASSET_METHOD)) H = AP; @@ -326,11 +327,11 @@ pathname *Assets::include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename * Epub::note_image(W->as_ebook, rel); } -@ = +<>= if (verbose_mode) PRINT("Collate asset %f\n", F); Collater::for_web_and_pattern(OUT, W, pattern, F, from); -@ = +<>= for (int i=0; ipost); i++) { if (Str::includes_at(R->post, i, I"URL")) { WRITE("%S", url); @@ -340,11 +341,11 @@ pathname *Assets::include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename * WRITE("\n"); @ "Transforming" is what happens to a CSS file to change the class names of -its |span| and |pre| styling rules, to add a prefix text. This is what changes +its [[span]] and [[pre]] styling rules, to add a prefix text. This is what changes the style names for colouring, say, COBOL source code from, e.g., -|span.identifier-syntax| to |span.ConsoleText-identifier-syntax|. +[[span.identifier-syntax]] to [[span.ConsoleText-identifier-syntax]]. -= +<<*>>= typedef struct css_file_transformation { struct text_stream *OUT; struct text_stream *trans; diff --git a/Chapter_1/Basics.w b/Chapter_1/Basics.nw similarity index 56% rename from Chapter_1/Basics.w rename to Chapter_1/Basics.nw index 9a6ad7c..9407a76 100755 --- a/Chapter_1/Basics.w +++ b/Chapter_1/Basics.nw @@ -5,99 +5,101 @@ module. @ Every program using //foundation// must define this: -@d PROGRAM_NAME "inweb" +<<*>>= +#define PROGRAM_NAME "inweb" @ We need to itemise the structures we'll want to allocate. For explanations, see //foundation: A Brief Guide to Foundation//. -@e asset_rule_CLASS -@e breadcrumb_request_CLASS -@e chapter_CLASS -@e colony_CLASS -@e colony_member_CLASS -@e colour_scheme_CLASS -@e colouring_language_block_CLASS -@e colouring_rule_CLASS -@e defined_constant_CLASS -@e enumeration_set_CLASS -@e footnote_CLASS -@e hash_table_entry_CLASS -@e hash_table_entry_usage_CLASS -@e language_function_CLASS -@e language_type_CLASS -@e macro_usage_CLASS -@e makefile_specifics_CLASS -@e nonterminal_variable_CLASS -@e para_macro_CLASS -@e paragraph_CLASS -@e paragraph_tagging_CLASS -@e preform_nonterminal_CLASS -@e programming_language_CLASS -@e reserved_word_CLASS -@e section_CLASS -@e source_line_CLASS -@e structure_element_CLASS -@e tangle_target_CLASS -@e tex_results_CLASS -@e text_literal_CLASS -@e theme_tag_CLASS -@e weave_format_CLASS -@e weave_pattern_CLASS -@e weave_plugin_CLASS -@e weave_order_CLASS -@e web_CLASS -@e writeme_asset_CLASS +<<*>>= +enum asset_rule_CLASS +enum breadcrumb_request_CLASS +enum chapter_CLASS +enum colony_CLASS +enum colony_member_CLASS +enum colour_scheme_CLASS +enum colouring_language_block_CLASS +enum colouring_rule_CLASS +enum defined_constant_CLASS +enum enumeration_set_CLASS +enum footnote_CLASS +enum hash_table_entry_CLASS +enum hash_table_entry_usage_CLASS +enum language_function_CLASS +enum language_type_CLASS +enum macro_usage_CLASS +enum makefile_specifics_CLASS +enum nonterminal_variable_CLASS +enum para_macro_CLASS +enum paragraph_CLASS +enum paragraph_tagging_CLASS +enum preform_nonterminal_CLASS +enum programming_language_CLASS +enum reserved_word_CLASS +enum section_CLASS +enum source_line_CLASS +enum structure_element_CLASS +enum tangle_target_CLASS +enum tex_results_CLASS +enum text_literal_CLASS +enum theme_tag_CLASS +enum weave_format_CLASS +enum weave_pattern_CLASS +enum weave_plugin_CLASS +enum weave_order_CLASS +enum web_CLASS +enum writeme_asset_CLASS -@e weave_document_node_CLASS -@e weave_head_node_CLASS -@e weave_body_node_CLASS -@e weave_tail_node_CLASS -@e weave_section_header_node_CLASS -@e weave_section_footer_node_CLASS -@e weave_chapter_header_node_CLASS -@e weave_chapter_footer_node_CLASS -@e weave_verbatim_node_CLASS -@e weave_section_purpose_node_CLASS -@e weave_subheading_node_CLASS -@e weave_bar_node_CLASS -@e weave_linebreak_node_CLASS -@e weave_pagebreak_node_CLASS -@e weave_paragraph_heading_node_CLASS -@e weave_endnote_node_CLASS -@e weave_material_node_CLASS -@e weave_figure_node_CLASS -@e weave_extract_node_CLASS -@e weave_audio_node_CLASS -@e weave_download_node_CLASS -@e weave_video_node_CLASS -@e weave_embed_node_CLASS -@e weave_pmac_node_CLASS -@e weave_vskip_node_CLASS -@e weave_chapter_node_CLASS -@e weave_section_node_CLASS -@e weave_code_line_node_CLASS -@e weave_function_usage_node_CLASS -@e weave_commentary_node_CLASS -@e weave_carousel_slide_node_CLASS -@e weave_toc_node_CLASS -@e weave_toc_line_node_CLASS -@e weave_chapter_title_page_node_CLASS -@e weave_defn_node_CLASS -@e weave_source_code_node_CLASS -@e weave_url_node_CLASS -@e weave_footnote_cue_node_CLASS -@e weave_begin_footnote_text_node_CLASS -@e weave_display_line_node_CLASS -@e weave_function_defn_node_CLASS -@e weave_item_node_CLASS -@e weave_grammar_index_node_CLASS -@e weave_inline_node_CLASS -@e weave_locale_node_CLASS -@e weave_maths_node_CLASS +enum weave_document_node_CLASS +enum weave_head_node_CLASS +enum weave_body_node_CLASS +enum weave_tail_node_CLASS +enum weave_section_header_node_CLASS +enum weave_section_footer_node_CLASS +enum weave_chapter_header_node_CLASS +enum weave_chapter_footer_node_CLASS +enum weave_verbatim_node_CLASS +enum weave_section_purpose_node_CLASS +enum weave_subheading_node_CLASS +enum weave_bar_node_CLASS +enum weave_linebreak_node_CLASS +enum weave_pagebreak_node_CLASS +enum weave_paragraph_heading_node_CLASS +enum weave_endnote_node_CLASS +enum weave_material_node_CLASS +enum weave_figure_node_CLASS +enum weave_extract_node_CLASS +enum weave_audio_node_CLASS +enum weave_download_node_CLASS +enum weave_video_node_CLASS +enum weave_embed_node_CLASS +enum weave_pmac_node_CLASS +enum weave_vskip_node_CLASS +enum weave_chapter_node_CLASS +enum weave_section_node_CLASS +enum weave_code_line_node_CLASS +enum weave_function_usage_node_CLASS +enum weave_commentary_node_CLASS +enum weave_carousel_slide_node_CLASS +enum weave_toc_node_CLASS +enum weave_toc_line_node_CLASS +enum weave_chapter_title_page_node_CLASS +enum weave_defn_node_CLASS +enum weave_source_code_node_CLASS +enum weave_url_node_CLASS +enum weave_footnote_cue_node_CLASS +enum weave_begin_footnote_text_node_CLASS +enum weave_display_line_node_CLASS +enum weave_function_defn_node_CLASS +enum weave_item_node_CLASS +enum weave_grammar_index_node_CLASS +enum weave_inline_node_CLASS +enum weave_locale_node_CLASS +enum weave_maths_node_CLASS @ And then expand the following macros, all defined in //Memory//. -= +<<*>>= DECLARE_CLASS_ALLOCATED_IN_ARRAYS(source_line, 1000) DECLARE_CLASS(asset_rule) DECLARE_CLASS(breadcrumb_request) diff --git a/Chapter_1/Configuration.w b/Chapter_1/Configuration.nw similarity index 79% rename from Chapter_1/Configuration.w rename to Chapter_1/Configuration.nw index d43a31a..ff4ee82 100644 --- a/Chapter_1/Configuration.w +++ b/Chapter_1/Configuration.nw @@ -3,63 +3,63 @@ To parse the command line arguments with which inweb was called, and to handle any errors it needs to issue. -@h Instructions. +@ \section{Instructions.} The following structure exists just to hold what the user specified on the command line: there will only ever be one of these. -= +<<*>>= typedef struct inweb_instructions { - int inweb_mode; /* our main mode of operation: one of the |*_MODE| constants */ + int inweb_mode; /* our main mode of operation: one of the [[*_MODE]] constants */ struct pathname *chosen_web; /* project folder relative to cwd */ struct filename *chosen_file; /* or, single file relative to cwd */ struct text_stream *chosen_range; /* which subset of this web we apply to (often, all of it) */ int chosen_range_actually_chosen; /* rather than being a default choice */ - int swarm_mode; /* relevant to weaving only: one of the |*_SWARM| constants */ - struct text_stream *tag_setting; /* |-weave-tag X|: weave, but only the material tagged X */ - struct text_stream *weave_pattern; /* |-weave-as X|: for example, |-weave-to HTML| */ + int swarm_mode; /* relevant to weaving only: one of the [[*_SWARM]] constants */ + struct text_stream *tag_setting; /* [[-weave-tag X]]: weave, but only the material tagged X */ + struct text_stream *weave_pattern; /* [[-weave-as X|: for example, |-weave-to HTML]] */ - int show_languages_switch; /* |-show-languages|: print list of available PLs */ - int catalogue_switch; /* |-catalogue|: print catalogue of sections */ - int functions_switch; /* |-functions|: print catalogue of functions within sections */ - int structures_switch; /* |-structures|: print catalogue of structures within sections */ - int advance_switch; /* |-advance-build|: advance build file for web */ - int scan_switch; /* |-scan|: simply show the syntactic scan of the source */ - int ctags_switch; /* |-ctags|: generate a set of Universal Ctags on each tangle */ - struct filename *weave_to_setting; /* |-weave-to X|: the pathname X, if supplied */ - struct pathname *weave_into_setting; /* |-weave-into X|: the pathname X, if supplied */ + int show_languages_switch; /* [[-show-languages]]: print list of available PLs */ + int catalogue_switch; /* [[-catalogue]]: print catalogue of sections */ + int functions_switch; /* [[-functions]]: print catalogue of functions within sections */ + int structures_switch; /* [[-structures]]: print catalogue of structures within sections */ + int advance_switch; /* [[-advance-build]]: advance build file for web */ + int scan_switch; /* [[-scan]]: simply show the syntactic scan of the source */ + int ctags_switch; /* [[-ctags]]: generate a set of Universal Ctags on each tangle */ + struct filename *weave_to_setting; /* [[-weave-to X]]: the pathname X, if supplied */ + struct pathname *weave_into_setting; /* [[-weave-into X]]: the pathname X, if supplied */ int sequential; /* give the sections sequential sigils */ - struct filename *tangle_setting; /* |-tangle-to X|: the pathname X, if supplied */ - struct filename *ctags_setting; /* |-ctags-to X|: the pathname X, if supplied */ - struct filename *makefile_setting; /* |-makefile X|: the filename X, if supplied */ - struct filename *gitignore_setting; /* |-gitignore X|: the filename X, if supplied */ - struct filename *advance_setting; /* |-advance-build-file X|: advance build file X */ - struct filename *writeme_setting; /* |-write-me X|: advance build file X */ - struct filename *prototype_setting; /* |-prototype X|: the pathname X, if supplied */ - struct filename *navigation_setting; /* |-navigation X|: the filename X, if supplied */ - struct filename *colony_setting; /* |-colony X|: the filename X, if supplied */ - struct text_stream *member_setting; /* |-member X|: sets web to member X of colony */ - struct linked_list *breadcrumb_setting; /* of |breadcrumb_request| */ - struct text_stream *platform_setting; /* |-platform X|: sets prevailing platform to X */ - int verbose_switch; /* |-verbose|: print names of files read to stdout */ + struct filename *tangle_setting; /* [[-tangle-to X]]: the pathname X, if supplied */ + struct filename *ctags_setting; /* [[-ctags-to X]]: the pathname X, if supplied */ + struct filename *makefile_setting; /* [[-makefile X]]: the filename X, if supplied */ + struct filename *gitignore_setting; /* [[-gitignore X]]: the filename X, if supplied */ + struct filename *advance_setting; /* [[-advance-build-file X]]: advance build file X */ + struct filename *writeme_setting; /* [[-write-me X]]: advance build file X */ + struct filename *prototype_setting; /* [[-prototype X]]: the pathname X, if supplied */ + struct filename *navigation_setting; /* [[-navigation X]]: the filename X, if supplied */ + struct filename *colony_setting; /* [[-colony X]]: the filename X, if supplied */ + struct text_stream *member_setting; /* [[-member X]]: sets web to member X of colony */ + struct linked_list *breadcrumb_setting; /* of [[breadcrumb_request]] */ + struct text_stream *platform_setting; /* [[-platform X]]: sets prevailing platform to X */ + int verbose_switch; /* [[-verbose]]: print names of files read to stdout */ int targets; /* used only for parsing */ - struct programming_language *test_language_setting; /* |-test-language X| */ - struct filename *test_language_on_setting; /* |-test-language-on X| */ + struct programming_language *test_language_setting; /* [[-test-language X]] */ + struct filename *test_language_on_setting; /* [[-test-language-on X]] */ - struct pathname *import_setting; /* |-import X|: where to find imported webs */ + struct pathname *import_setting; /* [[-import X]]: where to find imported webs */ } inweb_instructions; -@h Reading the command line. +@ \section{Reading the command line.} The dull work of this is done by the Foundation module: all we need to do is to enumerate constants for the Inweb-specific command line switches, and then declare them. -= +<<*>>= inweb_instructions Configuration::read(int argc, char **argv) { inweb_instructions args; - @; - @; + <>; + <>; CommandLine::read(argc, argv, &args, &Configuration::switch, &Configuration::bareword); Configuration::member_and_colony(&args); if (Str::len(args.weave_pattern) == 0) WRITE_TO(args.weave_pattern, "HTML"); @@ -75,7 +75,7 @@ inweb_instructions Configuration::read(int argc, char **argv) { return args; } -@ = +<>= args.inweb_mode = NO_MODE; args.swarm_mode = SWARM_OFF_SWM; args.show_languages_switch = FALSE; @@ -112,58 +112,59 @@ inweb_instructions Configuration::read(int argc, char **argv) { args.test_language_on_setting = NULL; @ The CommandLine section of Foundation needs to be told what command-line -switches we want, other than the standard set (such as |-help|) which it +switches we want, other than the standard set (such as [[-help]]) which it provides automatically. -@e VERBOSE_CLSW -@e IMPORT_FROM_CLSW +<<*>>= +enum VERBOSE_CLSW +enum IMPORT_FROM_CLSW -@e LANGUAGES_CLSG +enum LANGUAGES_CLSG -@e LANGUAGE_CLSW -@e LANGUAGES_CLSW -@e SHOW_LANGUAGES_CLSW -@e TEST_LANGUAGE_CLSW -@e TEST_LANGUAGE_ON_CLSW +enum LANGUAGE_CLSW +enum LANGUAGES_CLSW +enum SHOW_LANGUAGES_CLSW +enum TEST_LANGUAGE_CLSW +enum TEST_LANGUAGE_ON_CLSW -@e ANALYSIS_CLSG +enum ANALYSIS_CLSG -@e CATALOGUE_CLSW -@e FUNCTIONS_CLSW -@e STRUCTURES_CLSW -@e ADVANCE_CLSW -@e GITIGNORE_CLSW -@e MAKEFILE_CLSW -@e WRITEME_CLSW -@e PLATFORM_CLSW -@e ADVANCE_FILE_CLSW -@e PROTOTYPE_CLSW -@e SCAN_CLSW +enum CATALOGUE_CLSW +enum FUNCTIONS_CLSW +enum STRUCTURES_CLSW +enum ADVANCE_CLSW +enum GITIGNORE_CLSW +enum MAKEFILE_CLSW +enum WRITEME_CLSW +enum PLATFORM_CLSW +enum ADVANCE_FILE_CLSW +enum PROTOTYPE_CLSW +enum SCAN_CLSW -@e WEAVING_CLSG +enum WEAVING_CLSG -@e WEAVE_CLSW -@e WEAVE_INTO_CLSW -@e WEAVE_TO_CLSW -@e OPEN_CLSW -@e WEAVE_AS_CLSW -@e WEAVE_TAG_CLSW -@e BREADCRUMB_CLSW -@e NAVIGATION_CLSW +enum WEAVE_CLSW +enum WEAVE_INTO_CLSW +enum WEAVE_TO_CLSW +enum OPEN_CLSW +enum WEAVE_AS_CLSW +enum WEAVE_TAG_CLSW +enum BREADCRUMB_CLSW +enum NAVIGATION_CLSW -@e TANGLING_CLSG +enum TANGLING_CLSG -@e TANGLE_CLSW -@e TANGLE_TO_CLSW -@e CTAGS_TO_CLSW -@e CTAGS_CLSW +enum TANGLE_CLSW +enum TANGLE_TO_CLSW +enum CTAGS_TO_CLSW +enum CTAGS_CLSW -@e COLONIAL_CLSG +enum COLONIAL_CLSG -@e COLONY_CLSW -@e MEMBER_CLSW +enum COLONY_CLSW +enum MEMBER_CLSW -@ = +<>= CommandLine::declare_heading(L"inweb: a tool for literate programming\n\n" L"Usage: inweb WEB OPTIONS RANGE\n\n" L"WEB must be a directory holding a literate program (a 'web')\n\n" @@ -265,9 +266,9 @@ provides automatically. CommandLine::declare_switch(IMPORT_FROM_CLSW, L"import-from", 2, L"specify that imported modules are at pathname X"); -@ Foundation calls this on any |-switch| argument read: +@ Foundation calls this on any [[-switch]] argument read: -= +<<*>>= void Configuration::switch(int id, int val, text_stream *arg, void *state) { inweb_instructions *args = (inweb_instructions *) state; switch (id) { @@ -379,7 +380,7 @@ void Configuration::switch(int id, int val, text_stream *arg, void *state) { @ The colony file is, in one sense, a collection of presets for the web location and its navigational aids. -= +<<*>>= void Configuration::member_and_colony(inweb_instructions *args) { if (args->colony_setting) Colonies::load(args->colony_setting); if (Str::len(args->member_setting) > 0) { @@ -402,10 +403,10 @@ void Configuration::member_and_colony(inweb_instructions *args) { } @ Foundation calls this routine on any command-line argument which is -neither a switch (like |-weave|), nor an argument for a switch (like -the |X| in |-weave-as X|). +neither a switch (like [[-weave]]), nor an argument for a switch (like +the [[X]] in [[-weave-as X]]). -= +<<*>>= void Configuration::bareword(int id, text_stream *opt, void *state) { inweb_instructions *args = (inweb_instructions *) state; if ((args->chosen_web == NULL) && (args->chosen_file == NULL)) { @@ -416,11 +417,11 @@ void Configuration::bareword(int id, text_stream *opt, void *state) { } else Configuration::set_range(args, opt); } -@ Here we read a range. The special ranges |index|, |chapters| and |sections| -are converted into swarm settings instead. |all| is simply an alias for |0|. +@ Here we read a range. The special ranges [[index]], [[chapters]] and [[sections]] +are converted into swarm settings instead. [[all]] is simply an alias for [[0]]. Otherwise, a range is a chapter number/letter, or a section range. -= +<<*>>= void Configuration::set_range(inweb_instructions *args, text_stream *opt) { match_results mr = Regexp::create_mr(); if (Str::eq_wide_string(opt, L"index")) { @@ -452,7 +453,7 @@ void Configuration::set_range(inweb_instructions *args, text_stream *opt) { @ We can only be in a single mode at a time: -= +<<*>>= void Configuration::set_fundamental_mode(inweb_instructions *args, int new_material) { if ((args->inweb_mode != NO_MODE) && (args->inweb_mode != new_material)) Errors::fatal("can only do one at a time - weaving, tangling or analysing"); diff --git a/Chapter_1/Patterns.w b/Chapter_1/Patterns.nw similarity index 87% rename from Chapter_1/Patterns.w rename to Chapter_1/Patterns.nw index 16a9264..d00da6b 100644 --- a/Chapter_1/Patterns.w +++ b/Chapter_1/Patterns.nw @@ -2,32 +2,32 @@ Managing weave patterns, which are bundled configuration settings for weaving. -@h Reading in. +@ \section{Reading in.} Patterns are stored as directories in the file system, and are identified by -names such as |HTML|. On request, we need to find the directory corresponding +names such as [[HTML]]. On request, we need to find the directory corresponding to such a name, and to read it in. This structure holds the result: -= +<<*>>= typedef struct weave_pattern { - struct text_stream *pattern_name; /* such as |HTML| */ + struct text_stream *pattern_name; /* such as [[HTML]] */ struct pathname *pattern_location; /* the directory */ struct weave_pattern *based_on; /* inherit from which other pattern? */ - struct weave_format *pattern_format; /* such as |DVI|: the desired final format */ - struct linked_list *plugins; /* of |weave_plugin|: any extras needed */ - struct linked_list *colour_schemes; /* of |colour_scheme|: any extras needed */ + struct weave_format *pattern_format; /* such as [[DVI]]: the desired final format */ + struct linked_list *plugins; /* of [[weave_plugin]]: any extras needed */ + struct linked_list *colour_schemes; /* of [[colour_scheme]]: any extras needed */ - struct text_stream *mathematics_plugin; /* name only, not a |weave_pattern *| */ - struct text_stream *footnotes_plugin; /* name only, not a |weave_pattern *| */ + struct text_stream *mathematics_plugin; /* name only, not a [[weave_pattern *]] */ + struct text_stream *footnotes_plugin; /* name only, not a [[weave_pattern *]] */ struct text_stream *initial_extension; /* filename extension, that is */ - struct linked_list *post_commands; /* of |text_stream| */ - struct linked_list *blocked_templates; /* of |text_stream| */ + struct linked_list *post_commands; /* of [[text_stream]] */ + struct linked_list *blocked_templates; /* of [[text_stream]] */ - struct linked_list *asset_rules; /* of |asset_rule| */ + struct linked_list *asset_rules; /* of [[asset_rule]] */ int show_abbrevs; /* show section range abbreviations in the weave? */ int number_sections; /* insert section numbers into the weave? */ - struct text_stream *default_range; /* for example, |sections| */ + struct text_stream *default_range; /* for example, [[sections]] */ struct web *patterned_for; /* the web which caused this to be read in */ @@ -38,17 +38,17 @@ typedef struct weave_pattern { @ When a given web needs a pattern with a given name, this is where it comes. -= +<<*>>= weave_pattern *Patterns::find(web *W, text_stream *name) { filename *pattern_file = NULL; weave_pattern *wp = CREATE(weave_pattern); - @; - @; - @; + <>; + <>; + <>; return wp; } -@ = +<>= wp->pattern_name = Str::duplicate(name); wp->pattern_location = NULL; wp->plugins = NEW_LINKED_LIST(weave_plugin); @@ -66,7 +66,7 @@ weave_pattern *Patterns::find(web *W, text_stream *name) { wp->commands = 0; wp->name_command_given = FALSE; -@ = +<>= wp->pattern_location = NULL; pathname *CP = Colonies::patterns_path(); if (CP) { @@ -89,7 +89,7 @@ weave_pattern *Patterns::find(web *W, text_stream *name) { if (wp->pattern_location == NULL) Errors::fatal_with_text("no such weave pattern as '%S'", name); -@ = +<>= if (pattern_file) TextFiles::read(pattern_file, FALSE, "can't open pattern.txt file", TRUE, Patterns::scan_pattern_line, NULL, wp); @@ -99,16 +99,16 @@ weave_pattern *Patterns::find(web *W, text_stream *name) { Errors::fatal_with_text("pattern did not name itself at the top", name); @ The Foundation module provides a standard way to scan text files line by -line, and this is used to send each line in the |pattern.txt| file to the +line, and this is used to send each line in the [[pattern.txt]] file to the following routine: -= +<<*>>= void Patterns::scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) { weave_pattern *wp = (weave_pattern *) X; Str::trim_white_space(line); /* ignore trailing space */ if (Str::len(line) == 0) return; /* ignore blank lines */ - if (Str::get_first_char(line) == '#') return; /* lines opening with |#| are comments */ + if (Str::get_first_char(line) == '#') return; /* lines opening with [[#]] are comments */ wp->commands++; match_results mr = Regexp::create_mr(); @@ -180,7 +180,7 @@ void Patterns::scan_pattern_line(text_stream *line, text_file_position *tfp, voi Regexp::dispose_of(&mr); } -@ = +<<*>>= int Patterns::yes_or_no(text_stream *arg, text_file_position *tfp) { if (Str::eq(arg, I"yes")) return TRUE; if (Str::eq(arg, I"no")) return FALSE; @@ -200,11 +200,11 @@ text_stream *Patterns::plugin_name(text_stream *arg, text_file_position *tfp) { return Str::duplicate(arg); } -@h Post-processing. +@ \section{Post-processing.} In effect, a pattern can hold a shell script to run after each weave (subset) completes. -= +<<*>>= void Patterns::post_process(weave_pattern *pattern, weave_order *wv) { text_stream *T; LOOP_OVER_LINKED_LIST(T, text_stream, pattern->post_commands) { @@ -241,14 +241,14 @@ void Patterns::post_process(weave_pattern *pattern, weave_order *wv) { } } -@h Obtaining files. -Patterns provide place template files, such as |template-body.html|, in +@ \section{Obtaining files.} +Patterns provide place template files, such as [[template-body.html]], in their root directories. Note that if you're rash enough to set up a cycle of patterns inheriting from each other then this routine will lock up into an infinite loop. -= +<<*>>= filename *Patterns::find_template(weave_pattern *pattern, text_stream *leafname) { for (weave_pattern *wp = pattern; wp; wp = wp->based_on) { text_stream *T; @@ -263,7 +263,7 @@ filename *Patterns::find_template(weave_pattern *pattern, text_stream *leafname) @ Similarly, but looking in an intermediate directory: -= +<<*>>= filename *Patterns::find_file_in_subdirectory(weave_pattern *pattern, text_stream *dirname, text_stream *leafname) { for (weave_pattern *wp = pattern; wp; wp = wp->based_on) { @@ -274,7 +274,7 @@ filename *Patterns::find_file_in_subdirectory(weave_pattern *pattern, return NULL; } -@ = +<<*>>= void Patterns::include_plugins(OUTPUT_STREAM, web *W, weave_pattern *pattern, filename *from) { for (weave_pattern *p = pattern; p; p = p->based_on) { weave_plugin *wp; diff --git a/Chapter_1/Program Control.w b/Chapter_1/Program_Control.nw similarity index 80% rename from Chapter_1/Program Control.w rename to Chapter_1/Program_Control.nw index 8a0353d..6d9eae6 100644 --- a/Chapter_1/Program Control.w +++ b/Chapter_1/Program_Control.nw @@ -6,7 +6,7 @@ this plan out. @ Inweb syntax has gradually shifted over the years, but there are two main versions: the second was cleaned up and simplified from the first in 2019. -= +<<*>>= int default_inweb_syntax = V2_SYNTAX; @ Inweb has a single fundamental mode of operation: on any given run, it @@ -14,21 +14,22 @@ is either tangling, weaving or analysing. These processes use the same input and parsing code, but then do very different things to produce their output, so the fork in the road is not met until halfway through Inweb's execution. -@e NO_MODE from 0 /* a special mode for doing nothing except printing command-line syntax */ -@e ANALYSE_MODE /* for -scan, -catalogue, -functions and so on */ -@e TANGLE_MODE /* for any form of -tangle */ -@e WEAVE_MODE /* for any form of -weave */ -@e TRANSLATE_MODE /* a special mode for translating a multi-web makefile */ +<<*>>= +enum NO_MODE from 0 /* a special mode for doing nothing except printing command-line syntax */ +enum ANALYSE_MODE /* for -scan, -catalogue, -functions and so on */ +enum TANGLE_MODE /* for any form of -tangle */ +enum WEAVE_MODE /* for any form of -weave */ +enum TRANSLATE_MODE /* a special mode for translating a multi-web makefile */ -= +<<*>>= int fundamental_mode = NO_MODE; @ This operation will be applied to a single web, and will apply to the whole of that web unless we specify otherwise. Subsets of the web are represented by short pieces of text called "ranges". This can be a section range like -|2/pine|, a chapter number like |12|, an appendix letter |A| or the -preliminaries block |P|, the special chapter |S| for the "Sections" chapter -of an unchaptered web, or the special value |0| to mean the entire web (which +[[2/pine]], a chapter number like [[12]], an appendix letter [[A]] or the +preliminaries block [[P]], the special chapter [[S]] for the "Sections" chapter +of an unchaptered web, or the special value [[0]] to mean the entire web (which is the default). When weaving in "swarm mode", however, the user chooses a multiplicity of @@ -36,33 +37,34 @@ operations rather than just one. Now it's no longer a matter of weaving a particular section or chapter: we can weave all of the sections or chapters, one after another. -@e SWARM_OFF_SWM from 0 -@e SWARM_INDEX_SWM /* make index(es) as if swarming, but don't actually swarm */ -@e SWARM_CHAPTERS_SWM /* swarm the chapters */ -@e SWARM_SECTIONS_SWM /* swarm the individual sections */ +<<*>>= +enum SWARM_OFF_SWM from 0 +enum SWARM_INDEX_SWM /* make index(es) as if swarming, but don't actually swarm */ +enum SWARM_CHAPTERS_SWM /* swarm the chapters */ +enum SWARM_SECTIONS_SWM /* swarm the individual sections */ @ In order to run, Inweb needs to know where it is installed -- this enables it to find its configuration file, the macros file, and so on. Unless told otherwise on the command line, we'll assume Inweb is present in the current working directory. The "materials" will then be in a further -subfolder called |Materials|. +subfolder called [[Materials]]. -= +<<*>>= pathname *path_to_inweb = NULL; /* where we are installed */ pathname *path_to_inweb_materials = NULL; /* the materials pathname */ pathname *path_to_inweb_patterns = NULL; /* where built-in patterns are stored */ @ We count the errors in order to be able to exit with a suitable exit code. -= +<<*>>= int no_inweb_errors = 0; int verbose_mode = FALSE; -@h Main routine. +@ \section{Main routine.} -= +<<*>>= int main(int argc, char **argv) { - @; + <>; inweb_instructions args = Configuration::read(argc, argv); verbose_mode = args.verbose_switch; fundamental_mode = args.inweb_mode; @@ -76,22 +78,22 @@ int main(int argc, char **argv) { Main::follow_instructions(&args); - @; + <>; } -@ = +<>= Foundation::start(argc, argv); Formats::create_weave_formats(); -@ = +<>= Foundation::end(); return (no_inweb_errors == 0)?0:1; -@h Following instructions. +@ \section{Following instructions.} This is the whole program in a nutshell, and it's a pretty old-school program: some input, some thinking, a choice of three forms of output. -= +<<*>>= void Main::follow_instructions(inweb_instructions *ins) { web *W = NULL; if ((ins->chosen_web) || (ins->chosen_file)) { @@ -102,16 +104,16 @@ void Main::follow_instructions(inweb_instructions *ins) { Parser::parse_web(W, ins->inweb_mode); } if (no_inweb_errors == 0) { - if (ins->inweb_mode == TRANSLATE_MODE) @ - else if (ins->show_languages_switch) @ - else if ((ins->test_language_setting) || (ins->test_language_on_setting)) @ - else if (ins->inweb_mode != NO_MODE) @; + if (ins->inweb_mode == TRANSLATE_MODE) <> + else if (ins->show_languages_switch) <> + else if ((ins->test_language_setting) || (ins->test_language_on_setting)) <> + else if (ins->inweb_mode != NO_MODE) <>; } } @ This is a one-off featurette: -@ = +<>= if ((ins->makefile_setting) && (ins->prototype_setting == NULL)) ins->prototype_setting = Filenames::from_text(I"script.mkscript"); if ((ins->gitignore_setting) && (ins->prototype_setting == NULL)) @@ -130,13 +132,13 @@ void Main::follow_instructions(inweb_instructions *ins) { @ As is this: -@ = +<>= Languages::read_definitions(NULL); Languages::show(STDOUT); @ And this: -@ = +<>= if ((ins->test_language_setting) && (ins->test_language_on_setting)) { TEMPORARY_TEXT(matter) TEMPORARY_TEXT(coloured) @@ -152,15 +154,15 @@ void Main::follow_instructions(inweb_instructions *ins) { @ But otherwise we do something with the given web: -@ = +<>= if (ins->inweb_mode != ANALYSE_MODE) Reader::print_web_statistics(W); - if (ins->inweb_mode == ANALYSE_MODE) @; - if (ins->inweb_mode == TANGLE_MODE) @; - if (ins->inweb_mode == WEAVE_MODE) @; + if (ins->inweb_mode == ANALYSE_MODE) <>; + if (ins->inweb_mode == TANGLE_MODE) <>; + if (ins->inweb_mode == WEAVE_MODE) <>; @ "Analysis" invokes any combination of the following diagnostic tools: -@ = +<>= if (ins->swarm_mode != SWARM_OFF_SWM) Errors::fatal("only specific parts of the web can be analysed"); if (ins->catalogue_switch) @@ -189,17 +191,17 @@ quite different language from the rest of the web, and tangles to a different output, but needs to be part of the web since it's essential to an understanding of the whole system. -In this section we determine |tn|, the target number wanted, and |tangle_to|, +In this section we determine [[tn]], the target number wanted, and [[tangle_to]], the filename of the tangled code to write. This may have been set at the command line , but otherwise we impose a sensible choice based on the target. -@ = +<>= TEMPORARY_TEXT(tangle_leaf) tangle_target *tn = NULL; if (Str::eq_wide_string(ins->chosen_range, L"0")) { - @; + <>; } else if (Reader::get_section_for_range(W, ins->chosen_range)) { - @; + <>; } if (Str::len(tangle_leaf) == 0) { Errors::fatal("no tangle destination known"); } @@ -217,7 +219,7 @@ line , but otherwise we impose a sensible choice based on the target. @ Here the target number is 0, and the tangle is of the main part of the web, which for many small webs will be the entire thing. -@ = +<>= tn = NULL; if (Bibliographic::data_exists(W->md, I"Short Title")) Str::copy(tangle_leaf, Bibliographic::get_datum(W->md, I"Short Title")); @@ -225,9 +227,9 @@ which for many small webs will be the entire thing. Str::copy(tangle_leaf, Bibliographic::get_datum(W->md, I"Title")); Str::concatenate(tangle_leaf, W->main_language->file_extension); -@ If someone tangles, say, |2/eg| then the default filename is "Example Section". +@ If someone tangles, say, [[2/eg]] then the default filename is "Example Section". -@ = +<>= section *S = Reader::get_section_for_range(W, ins->chosen_range); tn = S->sect_target; if (tn == NULL) Errors::fatal("section cannot be independently tangled"); @@ -235,7 +237,7 @@ which for many small webs will be the entire thing. @ Weaving is not actually easier, it's just more thoroughly delegated: -@ = +<>= Numbering::number_web(W); theme_tag *tag = Tags::find_by_name(ins->tag_setting, FALSE); @@ -248,7 +250,7 @@ which for many small webs will be the entire thing. int r = Formats::begin_weaving(W, pattern); if (r != SWARM_OFF_SWM) ins->swarm_mode = r; - @; + <>; if (ins->swarm_mode == SWARM_OFF_SWM) { Swarm::weave_subset(W, ins->chosen_range, FALSE, tag, pattern, ins->weave_to_setting, ins->weave_into_setting, @@ -260,18 +262,18 @@ which for many small webs will be the entire thing. } Formats::end_weaving(W, pattern); -@ = +<>= section *S; int k = 1; LOOP_OVER(S, section) if (Reader::range_within(S->md->sect_range, ins->chosen_range)) S->printed_number = k++; -@h Error messages. +@ \section{Error messages.} The Foundation module provides convenient functions to issue error messages, but we'll use the following wrapper when issuing an error at a line of web source: -= +<<*>>= void Main::error_in_web(text_stream *message, source_line *sl) { if (sl) { Errors::in_text_file_S(message, &(sl->source)); diff --git a/Chapter_1/The Swarm.w b/Chapter_1/The_Swarm.nw similarity index 90% rename from Chapter_1/The Swarm.w rename to Chapter_1/The_Swarm.nw index d1e2e0f..ed79923 100644 --- a/Chapter_1/The Swarm.w +++ b/Chapter_1/The_Swarm.nw @@ -3,7 +3,7 @@ To feed multiple output requests to the weaver, and to present weaver results, and update indexes or contents pages. -@h Swarming. +@ \section{Swarming.} A "weave" occurs when Inweb takes a portion of the web -- one section, one chapter, or the whole thing -- and writes it out in a human-readable form (or in some intermediate state which can be made into one, like a TeX file). @@ -11,10 +11,10 @@ There can be many weaves in a single run of Inweb, in which case we call the resulting flurry a "swarm", like the glittering cloud of locusts in the title of Chapter 25 of "On the Banks of Plum Creek". -This routine is called with mode |SWARM_SECTIONS_SWM|, |SWARM_CHAPTERS_SWM| or -|SWARM_INDEX_SWM|, so in a non-swarming run it isn't called at all. +This routine is called with mode [[SWARM_SECTIONS_SWM]], [[SWARM_CHAPTERS_SWM]] or +[[SWARM_INDEX_SWM]], so in a non-swarming run it isn't called at all. -= +<<*>>= weave_order *swarm_leader = NULL; /* the most inclusive one we weave */ void Swarm::weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag, @@ -47,26 +47,26 @@ void Swarm::weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag, from the swarm, or has been specified at the command line (in which case the call comes from Program Control). -= +<<*>>= weave_order *Swarm::weave_subset(web *W, text_stream *range, int open_afterwards, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, linked_list *breadcrumbs, filename *navigation) { weave_order *wv = NULL; if (no_inweb_errors == 0) { Analyser::analyse_code(W); - @; + <>; if (Weaver::weave(wv) == 0) /* i.e., the number of lines woven was zero */ Errors::fatal("empty weave request"); Patterns::post_process(wv->pattern, wv); Formats::post_process_weave(wv, open_afterwards); - @; + <>; } return wv; } @ Each individual weave generates one of the following sets of instructions: -= +<<*>>= typedef struct weave_order { struct web *weave_web; /* which web we weave */ struct text_stream *weave_range; /* which parts of the web in this weave */ @@ -78,16 +78,16 @@ typedef struct weave_order { void *post_processing_results; /* optional typesetting diagnostics after running through */ int self_contained; /* make a self-contained file if possible */ struct linked_list *breadcrumbs; /* non-standard breadcrumb trail, if any */ - struct filename *navigation; /* navigation links, or |NULL| if not supplied */ - struct linked_list *plugins; /* of |weave_plugin|: these are for HTML extensions */ - struct linked_list *colour_schemes; /* of |colour_scheme|: these are for HTML */ + struct filename *navigation; /* navigation links, or [[NULL]] if not supplied */ + struct linked_list *plugins; /* of [[weave_plugin]]: these are for HTML extensions */ + struct linked_list *colour_schemes; /* of [[colour_scheme]]: these are for HTML */ /* used for workspace during an actual weave: */ struct source_line *current_weave_line; CLASS_DEFINITION } weave_order; -@ = +<>= wv = CREATE(weave_order); wv->weave_web = W; wv->weave_range = Str::duplicate(range); @@ -116,7 +116,7 @@ typedef struct weave_order { Errors::fatal("no sections match that range"); TEMPORARY_TEXT(leafname) - @; + <>; pathname *H = W->redirect_weaves_to; if (H == NULL) H = into; if (H == NULL) { @@ -136,7 +136,7 @@ typedef struct weave_order { @ From the range and the theme, we work out the weave title, the leafname, and details of any cover-sheet to use. -@ = +<>= match_results mr = Regexp::create_mr(); if (Str::eq_wide_string(range, L"0")) { if (W->md->single_file) { @@ -146,7 +146,7 @@ and details of any cover-sheet to use. wv->booklet_title = Str::new_from_wide_string(L"Complete Program"); WRITE_TO(leafname, "Complete"); } - if (wv->theme_match) @; + if (wv->theme_match) <>; } else if (Regexp::match(&mr, range, L"%d+")) { Str::clear(wv->booklet_title); WRITE_TO(wv->booklet_title, "Chapter %S", range); @@ -174,19 +174,19 @@ and details of any cover-sheet to use. WRITE_TO(leafname, "%S", Formats::file_extension(wv->format)); Regexp::dispose_of(&mr); -@ = +<>= Str::clear(wv->booklet_title); WRITE_TO(wv->booklet_title, "Extracts: %S", wv->theme_match->tag_name); Str::copy(leafname, wv->theme_match->tag_name); @ Each weave results in a compressed one-line printed report: -@ = +<>= PRINT("[%S: %S -> %f", wv->booklet_title, wv->format->format_name, wv->weave_to); Formats::report_on_post_processing(wv); PRINT("]\n"); -@ = +<<*>>= void Swarm::ensure_plugin(weave_order *wv, text_stream *name) { weave_plugin *existing; LOOP_OVER_LINKED_LIST(existing, weave_plugin, wv->plugins) @@ -227,7 +227,7 @@ void Swarm::include_plugins(OUTPUT_STREAM, web *W, weave_order *wv, filename *fr @ After every swarm, we rebuild the index: -= +<<*>>= void Swarm::weave_index_templates(web *W, text_stream *range, weave_pattern *pattern, pathname *into, filename *nav, linked_list *crumbs) { if (!(Bibliographic::data_exists(W->md, I"Version Number")))