From a721e7ab4835b0963759d704ce85264f58709885 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Tue, 12 Sep 2023 10:51:37 +0100 Subject: [PATCH] Further enhancements --- README.md | 2 +- build.txt | 4 +- docs/inbuild/1-mn.html | 109 +++++++++++------- docs/inbuild/M-rc.html | 10 +- docs/supervisor-module/2-cps.html | 4 +- docs/supervisor-module/2-gnr.html | 2 +- docs/supervisor-module/4-ebm.html | 5 +- docs/supervisor-module/4-em.html | 5 +- docs/supervisor-module/5-es.html | 11 +- docs/supervisor-module/7-dc.html | 29 ++--- docs/supervisor-module/7-gi.html | 3 + docs/supervisor-module/7-tm.html | 4 +- inbuild/Chapter 1/Main.w | 37 +++++- inbuild/Figures/help.txt | 10 +- inbuild/supervisor-module/Chapter 2/Copies.w | 4 +- inbuild/supervisor-module/Chapter 2/Genres.w | 2 +- .../Chapter 4/Extension Bundle Manager.w | 5 +- .../Chapter 4/Extension Manager.w | 5 +- .../Chapter 5/Extension Services.w | 11 +- .../Chapter 7/Documentation Compiler.w | 29 ++--- .../Chapter 7/General Index.w | 3 + .../Chapter 7/The Mini-Website.w | 4 +- inform7/Figures/memory-diagnostics.txt | 48 ++++---- inform7/Figures/timings-diagnostics.txt | 12 +- .../Inter/Architecture16Kit/kit_metadata.json | 2 +- .../Inter/Architecture32Kit/kit_metadata.json | 2 +- .../Inter/BasicInformKit/kit_metadata.json | 2 +- .../Inter/CommandParserKit/kit_metadata.json | 2 +- .../EnglishLanguageKit/kit_metadata.json | 2 +- .../Inter/WorldModelKit/kit_metadata.json | 2 +- 30 files changed, 224 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index 15201c984..b188f3db1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6X16 'Krypton' (10 September 2023) +[Version](notes/versioning.md): 10.2.0-beta+6X17 'Krypton' (12 September 2023) ## About Inform diff --git a/build.txt b/build.txt index 8d22e12f0..f37a79265 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 10 September 2023 -Build Number: 6X16 +Build Date: 12 September 2023 +Build Number: 6X17 diff --git a/docs/inbuild/1-mn.html b/docs/inbuild/1-mn.html index ddf4a93d0..0f8cb4ad4 100644 --- a/docs/inbuild/1-mn.html +++ b/docs/inbuild/1-mn.html @@ -58,7 +58,7 @@ function togglePopup(material_id) {

A command-line interface for Inbuild functions which are not part of the normal operation of the Inform compiler.

-
+

§1. Settings variables. The following will be set at the command line.

@@ -79,6 +79,8 @@ function togglePopup(material_id) { text_stream *preprocess_HTML_app = NULL; inbuild_copy *to_install = NULL, *to_uninstall = NULL; filename *documentation_source = NULL; +pathname *documentation_set = NULL; +filename *documentation_sitemap = NULL; pathname *documentation_dest = NULL; typedef struct markdown_settings_struct { @@ -107,15 +109,16 @@ on; then to carry out that work, and then shut down again.
 int main(int argc, char **argv) {
     Start up the modules2.1;
-    Read the command line2.12;
+    Read the command line2.13;
     CommandLine::play_back_log();
     Complete the list of targets2.2;
     if (to_install) Perform an extension installation2.3
     else if (to_uninstall) Perform an extension uninstallation2.4
     else if ((markdown_settings.from) || (markdown_settings.from_dir)) Make HTML2.5
+    else if (documentation_set) Document from a set2.7
     else if (documentation_source) Document from a file2.6
-    else Act on the targets2.7;
-    Shut down the modules2.8;
+    else Act on the targets2.8;
+    Shut down the modules2.9;
     if (Errors::have_occurred()) return 1;
     return 0;
 }
@@ -160,7 +163,7 @@ error in this case.
 

-    linked_list *L = Main::list_of_targets();
+    linked_list *L = Main::list_of_targets();
     inbuild_copy *D = NULL, *C; int others_exist = FALSE;
     LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
         if ((C->edition->work->genre == project_bundle_genre) ||
@@ -180,10 +183,10 @@ error in this case.
         Supervisor::add_nest(
             Supervisor::default_internal_path(), INTERNAL_NEST_TAG);
     }
-    Supervisor::optioneering_complete(D, FALSE, &Main::load_preform);
+    Supervisor::optioneering_complete(D, FALSE, &Main::load_preform);
     inform_project *proj;
     LOOP_OVER(proj, inform_project)
-        Main::add_target(proj->as_copy);
+        Main::add_target(proj->as_copy);
     int count = 0;
     LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
         if ((C->edition->work->genre == project_bundle_genre) ||
@@ -191,7 +194,7 @@ error in this case.
             count++;
     if ((count > 1) && (inbuild_task != INSPECT_TTASK))
         Errors::with_text("can only work on one project bundle at a time", NULL);
-    if (Str::len(filter_text) > 0) Main::add_search_results_as_targets(filter_text);
+    if (Str::len(filter_text) > 0) Main::add_search_results_as_targets(filter_text);
 

§2.3. Perform an extension installation2.3 = @@ -235,15 +238,26 @@ error in this case. if (documentation_dest == NULL) Errors::fatal("need to specify '-document-to' directory"); compiled_documentation *cd = DocumentationCompiler::compile_from_file( - documentation_source, NULL); + documentation_source, NULL, documentation_sitemap); if (cd) DocumentationRenderer::as_HTML(documentation_dest, cd, NULL);

-

§2.7. We make the function call Supervisor::go_operational to signal to inbuild +

§2.7. Document from a set2.7 = +

+ +
+    if (documentation_dest == NULL)
+        Errors::fatal("need to specify '-document-to' directory");
+    compiled_documentation *cd = DocumentationCompiler::compile_from_path(
+        documentation_set, NULL, documentation_sitemap);
+    if (cd) DocumentationRenderer::as_HTML(documentation_dest, cd, NULL);
+
+ +

§2.8. We make the function call Supervisor::go_operational to signal to inbuild that we want to start work now.

-

Act on the targets2.7 = +

Act on the targets2.8 =

@@ -256,10 +270,10 @@ that we want to start work now.
     if (build_trace_mode) IncrementalBuild::enable_trace();
     JSON_value *obj = NULL;
     if (JSON_file_format) obj = JSON::new_object();
-    linked_list *L = Main::list_of_targets();
+    linked_list *L = Main::list_of_targets();
     inbuild_copy *C;
     LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
-        Carry out the required task on the copy C2.7.2;
+        Carry out the required task on the copy C2.8.2;
     if (obj) {
         Main::validate_JSON(obj);
         if (JSON_file_to_output) {
@@ -275,7 +289,7 @@ that we want to start work now.
     }
 
-

§2.7.1. The list of possible tasks is as follows; they basically all correspond to +

§2.8.1. The list of possible tasks is as follows; they basically all correspond to utility functions in the supervisor module, which we call.

@@ -296,7 +310,7 @@ utility functions in the enum DOCUMENT_TTASK enum MODERNISE_TTASK -

§2.7.2. Carry out the required task on the copy C2.7.2 = +

§2.8.2. Carry out the required task on the copy C2.8.2 =

@@ -333,12 +347,12 @@ utility functions in the         case DOCUMENT_TTASK:
             if (documentation_dest == NULL)
                 Errors::fatal("need to specify '-document-to' directory");
-            Copies::document(C, documentation_dest); break;
+            Copies::document(C, documentation_dest, documentation_sitemap); break;
         case MODERNISE_TTASK: Copies::modernise(OUT, C); break;
     }
 
- -

§2.8. Shut down the modules2.8 = +

+

§2.9. Shut down the modules2.9 =

@@ -350,7 +364,7 @@ utility functions in the     Foundation::end();  must be ended last
 
-

§2.9. Preform is the crowning jewel of the words module, and parses excerpts of +

§2.10. Preform is the crowning jewel of the words module, and parses excerpts of natural-language text against a "grammar". The inform7 executable makes very heavy-duty use of Preform, and we can use that too provided we have access to the English Preform syntax file stored inside the core Inform distribution, @@ -377,7 +391,7 @@ following is run, Preform is ready for use. } } -

§2.10. Target list. This where we keep the list of targets, in which no copy occurs more than +

§2.11. Target list. This where we keep the list of targets, in which no copy occurs more than once. The following code runs quadratically in the number of targets, but for Inbuild this number is never likely to be more than about 100 at a time.

@@ -385,7 +399,7 @@ Inbuild this number is never likely to be more than about 100 at a time.
 linked_list *targets = NULL;  of inbuild_copy
 
-void Main::add_target(inbuild_copy *to_add) {
+void Main::add_target(inbuild_copy *to_add) {
     if (targets == NULL) targets = NEW_LINKED_LIST(inbuild_copy);
     int found = FALSE;
     inbuild_copy *C;
@@ -395,7 +409,7 @@ Inbuild this number is never likely to be more than about 100 at a time.
     if (found == FALSE) ADD_TO_LINKED_LIST(to_add, inbuild_copy, targets);
 }
 
-

§2.11. The following sorts the list of targets before returning it. This is partly +

§2.12. The following sorts the list of targets before returning it. This is partly to improve the quality of the output of -inspect, but also to make the behaviour of inbuild more predictable across platforms — the raw target list tends to be in order of discovery of the copies, which in turn depends on @@ -403,7 +417,7 @@ the order in which filenames are read from a directory listing.

-linked_list *Main::list_of_targets(void) {
+linked_list *Main::list_of_targets(void) {
     if (targets == NULL) targets = NEW_LINKED_LIST(inbuild_copy);
     int no_entries = LinkedLists::len(targets);
     if (no_entries == 0) return targets;
@@ -431,7 +445,7 @@ the order in which filenames are read from a directory listing.
         Nests::search_for(req, Supervisor::shared_nest_list(), L);
         inbuild_search_result *R;
         LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L)
-            Main::add_target(R->copy);
+            Main::add_target(R->copy);
     }
     DISCARD_TEXT(errors)
 }
@@ -442,7 +456,7 @@ the order in which filenames are read from a directory listing.
     LOOP_OVER_LINKED_LIST(entry, text_stream, L) {
         TEMPORARY_TEXT(FILENAME)
         WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, entry);
-        Main::add_file_or_path_as_target(FILENAME, FALSE);
+        Main::add_file_or_path_as_target(FILENAME, FALSE);
         DISCARD_TEXT(FILENAME)
     }
 }
@@ -478,9 +492,9 @@ the order in which filenames are read from a directory listing.
 
 void Main::add_file_or_path_as_target(text_stream *arg, int throwing_error) {
     int is_folder = Platform::is_folder_separator(Str::get_last_char(arg));
-    inbuild_copy *C = Main::file_or_path_to_copy(arg, throwing_error);
+    inbuild_copy *C = Main::file_or_path_to_copy(arg, throwing_error);
     if (C) {
-        Main::add_target(C);
+        Main::add_target(C);
     } else if ((recursive) && (is_folder)) {
         pathname *P = Pathnames::from_text(arg);
         linked_list *L = Directories::listing(P);
@@ -488,13 +502,13 @@ the order in which filenames are read from a directory listing.
         LOOP_OVER_LINKED_LIST(entry, text_stream, L) {
             TEMPORARY_TEXT(FILENAME)
             WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, entry);
-            Main::add_file_or_path_as_target(FILENAME, throwing_error);
+            Main::add_file_or_path_as_target(FILENAME, throwing_error);
             DISCARD_TEXT(FILENAME)
         }
     }
 }
 
-

§2.12. Command line. Note the call below to Supervisor::declare_options, which adds a whole lot of +

§2.13. Command line. Note the call below to Supervisor::declare_options, which adds a whole lot of other options to the selection defined here.

@@ -533,10 +547,13 @@ other options to the selection defined here. enum VERBOSE_CLSW enum VERBOSITY_CLSW enum JSON_CLSW +enum MODERNISE_CLSW +enum DOCUMENTATION_SUITE_CLSG enum DOCUMENT_CLSW enum DOCUMENT_FROM_CLSW +enum DOCUMENT_SET_CLSW +enum DOCUMENT_SITEMAP_CLSW enum DOCUMENT_TO_CLSW -enum MODERNISE_CLSW enum MARKDOWN_SUITE_CLSG enum MARKDOWN_FROM_CLSW enum MARKDOWN_TO_CLSW @@ -545,7 +562,7 @@ other options to the selection defined here. enum MARKDOWN_MODEL_CLSW enum MARKDOWN_VARIATION_CLSW -

Read the command line2.12 = +

Read the command line2.13 =

@@ -620,14 +637,22 @@ other options to the selection defined here.
         U"how much explanation to print: lowest is 0 (default), highest is 3");
     CommandLine::declare_switch(JSON_CLSW, U"json", 2,
         U"write output of -inspect to a JSON file in X (or '-' for stdout)");
+    CommandLine::declare_switch(MODERNISE_CLSW, U"modernise", 1,
+        U"update copies to the newest available format");
+
+    CommandLine::begin_group(DOCUMENTATION_SUITE_CLSG,
+        I"for generating extension or kit documentation");
     CommandLine::declare_switch(DOCUMENT_CLSW, U"document", 1,
         U"(re-)generate documentation on this within current project");
     CommandLine::declare_switch(DOCUMENT_FROM_CLSW, U"document-from", 2,
-        U"generate documentation from documentation source file X");
+        U"generate documentation from documentation in a single Markdown file X");
+    CommandLine::declare_switch(DOCUMENT_SET_CLSW, U"document-set", 2,
+        U"generate documentation from a full documentation set in the path X");
+    CommandLine::declare_switch(DOCUMENT_SITEMAP_CLSW, U"document-sitemap", 2,
+        U"use file X as the 'sitemap.txt' when generating documentation sets");
     CommandLine::declare_switch(DOCUMENT_TO_CLSW, U"document-to", 2,
         U"divert generated documentation to directory X");
-    CommandLine::declare_switch(MODERNISE_CLSW, U"modernise", 1,
-        U"update copies to the newest available format");
+    CommandLine::end_group();
 
     CommandLine::begin_group(MARKDOWN_SUITE_CLSG, I"for generating HTML from Markdown");
     CommandLine::declare_switch(MARKDOWN_FROM_CLSW, U"markdown-from", 2,
@@ -655,7 +680,7 @@ other options to the selection defined here.
 

-void Main::option(int id, int val, text_stream *arg, void *state) {
+void Main::option(int id, int val, text_stream *arg, void *state) {
     switch (id) {
         case BUILD_CLSW: inbuild_task = BUILD_TTASK; break;
         case REBUILD_CLSW: inbuild_task = REBUILD_TTASK; break;
@@ -679,7 +704,7 @@ other options to the selection defined here.
             Supervisor::set_tools_location(path_to_tools); break;
         case MATCHING_CLSW: filter_text = Str::duplicate(arg); break;
         case CONTENTS_OF_CLSW: contents_of_used = TRUE;
-            Main::add_directory_contents_targets(Pathnames::from_text(arg)); break;
+            Main::add_directory_contents_targets(Pathnames::from_text(arg)); break;
         case RECURSIVE_CLSW: recursive = val;
             if (contents_of_used) Errors::fatal("-recursive must be used before -contents-of");
             break;
@@ -714,8 +739,8 @@ other options to the selection defined here.
             Registries::preprocess_HTML(T, F, preprocess_HTML_app);
             break;
         case REPAIR_CLSW: repair_mode = val; break;
-        case INSTALL_CLSW: to_install = Main::file_or_path_to_copy(arg, TRUE); break;
-        case UNINSTALL_CLSW: to_uninstall = Main::file_or_path_to_copy(arg, TRUE); break;
+        case INSTALL_CLSW: to_install = Main::file_or_path_to_copy(arg, TRUE); break;
+        case UNINSTALL_CLSW: to_uninstall = Main::file_or_path_to_copy(arg, TRUE); break;
         case RESULTS_CLSW: ExtensionInstaller::set_filename(Filenames::from_text(arg)); break;
         case CONFIRMED_CLSW: confirmed = val; break;
         case VERBOSE_CLSW: Supervisor::set_verbosity(1); break;
@@ -726,6 +751,8 @@ other options to the selection defined here.
                 JSON_file_to_output = Filenames::from_text(arg);
             break;
         case DOCUMENT_FROM_CLSW: documentation_source = Filenames::from_text(arg); break;
+        case DOCUMENT_SET_CLSW: documentation_set = Pathnames::from_text(arg); break;
+        case DOCUMENT_SITEMAP_CLSW: documentation_sitemap = Filenames::from_text(arg); break;
         case DOCUMENT_TO_CLSW: documentation_dest = Pathnames::from_text(arg); break;
 
         case MARKDOWN_FROM_CLSW: markdown_settings.from = Filenames::from_text(arg); break;
@@ -753,8 +780,8 @@ subordinate to any switch; we take it as the name of a copy.
 

-void Main::bareword(int id, text_stream *arg, void *state) {
-    Main::add_file_or_path_as_target(arg, TRUE);
+void Main::bareword(int id, text_stream *arg, void *state) {
+    Main::add_file_or_path_as_target(arg, TRUE);
 }
 

§5. JSON validation. For options which output JSON, we perform a check that what we've made @@ -762,7 +789,7 @@ conforms to what we say we make.

-void Main::validate_JSON(JSON_value *obj) {
+void Main::validate_JSON(JSON_value *obj) {
     filename *F = InstalledFiles::filename(INBUILD_JSON_REQS_IRES);
     dictionary *D = JSON::read_requirements_file(NULL, F);
     JSON_requirement *req = JSON::look_up_requirements(D, I"inbuild-output");
diff --git a/docs/inbuild/M-rc.html b/docs/inbuild/M-rc.html
index 394c384ac..ded06c218 100644
--- a/docs/inbuild/M-rc.html
+++ b/docs/inbuild/M-rc.html
@@ -71,9 +71,6 @@ and those not documented in this manual are covered in that one.
 -no-confirmed                  don't confirm installation in the Inform GUI apps (default is -confirmed)
 -contents-of X                 apply to all targets in the directory X
 -copy-to X                     copy target(s) to nest X
--document                      (re-)generate documentation on this within current project
--document-from X               generate documentation from documentation source file X
--document-to X                 divert generated documentation to directory X
 -dry                           make this a dry run (print but do not execute shell commands) (default is -no-dry)
 -graph                         show dependency graph of target(s) but take no action
 -inspect                       show target(s) but take no action
@@ -124,6 +121,13 @@ and those not documented in this manual are covered in that one.
   -pipeline-file X             specify code-generation pipeline as file X
   -variable X                  set pipeline variable X (in form name=value)
 
+for generating extension or kit documentation:
+  -document                    (re-)generate documentation on this within current project
+  -document-from X             generate documentation from documentation in a single Markdown file X
+  -document-set X              generate documentation from a full documentation set in the path X
+  -document-sitemap X          use file X as the 'sitemap.txt' when generating documentation sets
+  -document-to X               divert generated documentation to directory X
+
 for generating HTML from Markdown:
   -markdown-from X             generate HTML file from Markdown source file X
   -markdown-from-dir X         generate HTML files from all Markdown sources in X
diff --git a/docs/supervisor-module/2-cps.html b/docs/supervisor-module/2-cps.html
index 4286d6af9..ad29aff75 100644
--- a/docs/supervisor-module/2-cps.html
+++ b/docs/supervisor-module/2-cps.html
@@ -412,8 +412,8 @@ its main task: building an Inform project.
 

-void Copies::document(inbuild_copy *C, pathname *dest) {
-    VOID_METHOD_CALL(C->edition->work->genre, GENRE_DOCUMENT_MTID, C, dest);
+void Copies::document(inbuild_copy *C, pathname *dest, filename *sitemap) {
+    VOID_METHOD_CALL(C->edition->work->genre, GENRE_DOCUMENT_MTID, C, dest, sitemap);
 }
 

§17. And -modernise: diff --git a/docs/supervisor-module/2-gnr.html b/docs/supervisor-module/2-gnr.html index 089d00c95..9802e9029 100644 --- a/docs/supervisor-module/2-gnr.html +++ b/docs/supervisor-module/2-gnr.html @@ -270,7 +270,7 @@ the Inbuild command-line options VOID_METHOD_TYPE(GENRE_DOCUMENT_MTID, - inbuild_genre *gen, inbuild_copy *C, pathname *dest) + inbuild_genre *gen, inbuild_copy *C, pathname *dest, filename *sitemap)

§14. This performs some sort of automatic-update to the latest format:

diff --git a/docs/supervisor-module/4-ebm.html b/docs/supervisor-module/4-ebm.html index 8716866ea..9e6da302e 100644 --- a/docs/supervisor-module/4-ebm.html +++ b/docs/supervisor-module/4-ebm.html @@ -568,8 +568,9 @@ directory, we need to rsync§10. Documentation.

-void ExtensionBundleManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest) {
-    Extensions::document(Extensions::from_copy(C), dest);
+void ExtensionBundleManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest,
+    filename *sitemap) {
+    Extensions::document(Extensions::from_copy(C), dest, sitemap);
 }
 

§11. Modernisation.

diff --git a/docs/supervisor-module/4-em.html b/docs/supervisor-module/4-em.html index 46c654922..e079942fd 100644 --- a/docs/supervisor-module/4-em.html +++ b/docs/supervisor-module/4-em.html @@ -328,8 +328,9 @@ the current VM settings.

§10. Documentation.

-void ExtensionManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest) {
-    Extensions::document(Extensions::from_copy(C), dest);
+void ExtensionManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest,
+    filename *sitemap) {
+    Extensions::document(Extensions::from_copy(C), dest, sitemap);
 }
 

§11. Modernisation.

diff --git a/docs/supervisor-module/5-es.html b/docs/supervisor-module/5-es.html index 5ab991b14..b11831017 100644 --- a/docs/supervisor-module/5-es.html +++ b/docs/supervisor-module/5-es.html @@ -955,7 +955,7 @@ This is that time. if (E->read_into_file) { text_stream *doc = TextFromFiles::torn_off_documentation(E->read_into_file); if (Str::len(doc) > 0) - E->documentation = DocumentationCompiler::compile_from_text(doc, E); + E->documentation = DocumentationCompiler::compile_from_text(doc, E, NULL); else E->documentation = NULL; E->read_into_file->your_ref = STORE_POINTER_inbuild_copy(E->as_copy); Break the text into sentences10.2; @@ -1025,7 +1025,8 @@ then its sentences will go to the extension's own tree.

-compiled_documentation *Extensions::get_documentation(inform_extension *E) {
+compiled_documentation *Extensions::get_documentation(inform_extension *E,
+    filename *sitemap) {
     if (E == NULL) return NULL;
     Copies::get_source_text(E->as_copy, I"getting documentation");  in the unlikely event this has not happened yet
     if (E->documentation_sought == FALSE) {
@@ -1049,7 +1050,7 @@ then its sentences will go to the extension's own tree.
         Copies::attach_error(E->as_copy, CopyErrors::new_T(EXT_MISWORDED_CE, -1, error_text));
         DISCARD_TEXT(error_text)
     } else {
-        E->documentation = DocumentationCompiler::compile_from_path(D, E);
+        E->documentation = DocumentationCompiler::compile_from_path(D, E, sitemap);
     }
 
  • This code is used in §12.
@@ -1057,9 +1058,9 @@ then its sentences will go to the extension's own tree.

-void Extensions::document(inform_extension *E, pathname *dest) {
+void Extensions::document(inform_extension *E, pathname *dest, filename *sitemap) {
     SVEXPLAIN(1, "(documenting %X to %p)\n", E->as_copy->edition->work, dest);
-    compiled_documentation *cd = Extensions::get_documentation(E);
+    compiled_documentation *cd = Extensions::get_documentation(E, sitemap);
     DocumentationRenderer::as_HTML(dest, cd, NULL);
 }
 
diff --git a/docs/supervisor-module/7-dc.html b/docs/supervisor-module/7-dc.html index 971858e8f..648fe479e 100644 --- a/docs/supervisor-module/7-dc.html +++ b/docs/supervisor-module/7-dc.html @@ -69,11 +69,11 @@ ways to make one of these.
 compiled_documentation *DocumentationCompiler::compile_from_file(filename *F,
-    inform_extension *associated_extension) {
+    inform_extension *associated_extension, filename *sitemap) {
     TEMPORARY_TEXT(temp)
     TextFiles::write_file_contents(temp, F);
     compiled_documentation *cd =
-        DocumentationCompiler::compile_from_text(temp, associated_extension);
+        DocumentationCompiler::compile_from_text(temp, associated_extension, sitemap);
     DISCARD_TEXT(temp)
     return cd;
 }
@@ -84,9 +84,9 @@ torn-off documentation is found:
 
 
 compiled_documentation *DocumentationCompiler::compile_from_text(text_stream *scrap,
-    inform_extension *associated_extension) {
+    inform_extension *associated_extension, filename *sitemap) {
     SVEXPLAIN(1, "(compiling documentation: %d chars)\n", Str::len(scrap));
-    compiled_documentation *cd = DocumentationCompiler::new_cd(NULL, associated_extension);
+    compiled_documentation *cd = DocumentationCompiler::new_cd(NULL, associated_extension, sitemap);
     cd_volume *vol = FIRST_IN_LINKED_LIST(cd_volume, cd->volumes);
     cd_pageset *page = FIRST_IN_LINKED_LIST(cd_pageset, vol->pagesets);
     page->nonfile_content = scrap;
@@ -101,8 +101,8 @@ the documentation for a directory-format extension.
 
 
 compiled_documentation *DocumentationCompiler::compile_from_path(pathname *P,
-    inform_extension *associated_extension) {
-    compiled_documentation *cd = DocumentationCompiler::new_cd(P, associated_extension);
+    inform_extension *associated_extension, filename *sitemap) {
+    compiled_documentation *cd = DocumentationCompiler::new_cd(P, associated_extension, sitemap);
     DocumentationCompiler::compile_inner(cd);
     return cd;
 }
@@ -324,15 +324,16 @@ index page and otherwise not producting documentation at all:
 
 
 compiled_documentation *DocumentationCompiler::new_cd(pathname *P,
-    inform_extension *associated_extension) {
+    inform_extension *associated_extension, filename *sitemap) {
     compiled_documentation *cd = CREATE(compiled_documentation);
     Initialise the cd structure10.1;
     if (P) {
         cd_source_file *Documentation_md_cdsf = NULL;
         Find the possible Markdown source files10.2;
-        Read the layout file, if there is one10.3;
+        Read the contents and sitemap files, if they exist10.3;
     }
     Indexes::add_indexing_notation(cd, NULL, NULL, I"standard", NULL);
+    Indexes::add_indexing_notation(cd, I"@", NULL, I"name", I"(invert)");
     if (LinkedLists::len(cd->volumes) == 0) {
         cd_volume *implied = DocumentationCompiler::add_volume(cd, cd->title, NULL, I"index.html");
         ADD_TO_LINKED_LIST(I"Documentation.md", text_stream, implied->source_files);
@@ -413,18 +414,18 @@ index page and otherwise not producting documentation at all:
     }
 
  • This code is used in §10.
-

§10.3. Read the layout file, if there is one10.3 = +

§10.3. Read the contents and sitemap files, if they exist10.3 =

     filename *layout_file = Filenames::in(P, I"contents.txt");
-    filename *sitemap_file = Filenames::in(P, I"sitemap.txt");
+    if (sitemap == NULL) sitemap = Filenames::in(P, I"sitemap.txt");
     if (TextFiles::exists(layout_file))
         TextFiles::read(layout_file, FALSE, "can't open layout file",
             TRUE, DocumentationCompiler::read_contents_helper, NULL, cd);
     else if (Documentation_md_cdsf) Documentation_md_cdsf->used = TRUE;
-    if (TextFiles::exists(sitemap_file))
-        TextFiles::read(sitemap_file, FALSE, "can't open sitemap file",
+    if (TextFiles::exists(sitemap))
+        TextFiles::read(sitemap, FALSE, "can't open sitemap file",
             TRUE, DocumentationCompiler::read_sitemap_helper, NULL, cd);
 
  • This code is used in §10.
@@ -671,7 +672,9 @@ index page and otherwise not producting documentation at all: TEMPORARY_TEXT(expanded_dest) for (int i=0; i<Str::len(dest); i++) if (Str::get_at(dest, i) == '*') { - WRITE_TO(expanded_dest, "%S", sf); + for (int j=0; j<Str::len(sf)-3; j++) + PUT_TO(expanded_dest, Str::get_at(sf, j)); + } else { PUT_TO(expanded_dest, Str::get_at(dest, i)); } diff --git a/docs/supervisor-module/7-gi.html b/docs/supervisor-module/7-gi.html index b45b91d04..d71d0e1bd 100644 --- a/docs/supervisor-module/7-gi.html +++ b/docs/supervisor-module/7-gi.html @@ -147,6 +147,9 @@ and turn out to have a lot of fiddly options added.
 void Indexes::add_category(compiled_documentation *cd, text_stream *name, text_stream *options, text_stream *redirect) {
+    name = Str::duplicate(name);
+    options = Str::duplicate(options);
+    redirect = Str::duplicate(redirect);
     if (Str::len(redirect) > 0) This is a redirection3.1;
     if (Dictionaries::find(cd->id.categories_by_name, name) == NULL) {
         indexing_category *ic = CREATE(indexing_category);
diff --git a/docs/supervisor-module/7-tm.html b/docs/supervisor-module/7-tm.html
index 7eb5873ba..11bb2a372 100644
--- a/docs/supervisor-module/7-tm.html
+++ b/docs/supervisor-module/7-tm.html
@@ -218,7 +218,7 @@ examples provided in the extension.
         if (F == NULL) return;
         pathname *P = Filenames::up(F);
         if (Pathnames::create_in_file_system(P) == 0) return;
-        compiled_documentation *doc = Extensions::get_documentation(E);
+        compiled_documentation *doc = Extensions::get_documentation(E, NULL);
         TEMPORARY_TEXT(OUT)
         #ifdef CORE_MODULE
         TEMPORARY_TEXT(details)
@@ -298,7 +298,7 @@ examples provided in the extension.
     if (Pathnames::create_in_file_system(KP)) {
         pathname *KD = Pathnames::down(K->as_copy->location_if_path, I"Documentation");
         compiled_documentation *doc =
-            DocumentationCompiler::compile_from_path(KD, NULL);
+            DocumentationCompiler::compile_from_path(KD, NULL, NULL);
         if (doc == NULL) {
             text_stream *OUT = DocumentationRenderer::open_subpage(KP, I"index.html");
             DocumentationRenderer::render_header(OUT, K->as_copy->edition->work->title, NULL, E);
diff --git a/inbuild/Chapter 1/Main.w b/inbuild/Chapter 1/Main.w
index 154af35cc..c96d6054d 100644
--- a/inbuild/Chapter 1/Main.w	
+++ b/inbuild/Chapter 1/Main.w	
@@ -22,6 +22,8 @@ pathname *preprocess_HTML_destination = NULL;
 text_stream *preprocess_HTML_app = NULL;
 inbuild_copy *to_install = NULL, *to_uninstall = NULL;
 filename *documentation_source = NULL;
+pathname *documentation_set = NULL;
+filename *documentation_sitemap = NULL;
 pathname *documentation_dest = NULL;
 
 typedef struct markdown_settings_struct {
@@ -54,6 +56,7 @@ int main(int argc, char **argv) {
 	if (to_install) @
 	else if (to_uninstall) @
 	else if ((markdown_settings.from) || (markdown_settings.from_dir)) @
+	else if (documentation_set) @
 	else if (documentation_source) @
 	else @;
 	@;
@@ -151,7 +154,14 @@ error in this case.
 	if (documentation_dest == NULL)
 		Errors::fatal("need to specify '-document-to' directory");
 	compiled_documentation *cd = DocumentationCompiler::compile_from_file(
-		documentation_source, NULL);
+		documentation_source, NULL, documentation_sitemap);
+	if (cd) DocumentationRenderer::as_HTML(documentation_dest, cd, NULL);
+
+@ =
+	if (documentation_dest == NULL)
+		Errors::fatal("need to specify '-document-to' directory");
+	compiled_documentation *cd = DocumentationCompiler::compile_from_path(
+		documentation_set, NULL, documentation_sitemap);
 	if (cd) DocumentationRenderer::as_HTML(documentation_dest, cd, NULL);
 
 @ We make the function call |Supervisor::go_operational| to signal to |inbuild|
@@ -239,7 +249,7 @@ utility functions in the //supervisor// module, which we call.
 		case DOCUMENT_TTASK:
 			if (documentation_dest == NULL)
 				Errors::fatal("need to specify '-document-to' directory");
-			Copies::document(C, documentation_dest); break;
+			Copies::document(C, documentation_dest, documentation_sitemap); break;
 		case MODERNISE_TTASK: Copies::modernise(OUT, C); break;
 	}
 
@@ -432,10 +442,15 @@ other options to the selection defined here.
 @e VERBOSE_CLSW
 @e VERBOSITY_CLSW
 @e JSON_CLSW
+@e MODERNISE_CLSW
+
+@e DOCUMENTATION_SUITE_CLSG
+
 @e DOCUMENT_CLSW
 @e DOCUMENT_FROM_CLSW
+@e DOCUMENT_SET_CLSW
+@e DOCUMENT_SITEMAP_CLSW
 @e DOCUMENT_TO_CLSW
-@e MODERNISE_CLSW
 
 @e MARKDOWN_SUITE_CLSG
 
@@ -518,14 +533,22 @@ other options to the selection defined here.
 		U"how much explanation to print: lowest is 0 (default), highest is 3");
 	CommandLine::declare_switch(JSON_CLSW, U"json", 2,
 		U"write output of -inspect to a JSON file in X (or '-' for stdout)");
+	CommandLine::declare_switch(MODERNISE_CLSW, U"modernise", 1,
+		U"update copies to the newest available format");
+
+	CommandLine::begin_group(DOCUMENTATION_SUITE_CLSG,
+		I"for generating extension or kit documentation");
 	CommandLine::declare_switch(DOCUMENT_CLSW, U"document", 1,
 		U"(re-)generate documentation on this within current project");
 	CommandLine::declare_switch(DOCUMENT_FROM_CLSW, U"document-from", 2,
-		U"generate documentation from documentation source file X");
+		U"generate documentation from documentation in a single Markdown file X");
+	CommandLine::declare_switch(DOCUMENT_SET_CLSW, U"document-set", 2,
+		U"generate documentation from a full documentation set in the path X");
+	CommandLine::declare_switch(DOCUMENT_SITEMAP_CLSW, U"document-sitemap", 2,
+		U"use file X as the 'sitemap.txt' when generating documentation sets");
 	CommandLine::declare_switch(DOCUMENT_TO_CLSW, U"document-to", 2,
 		U"divert generated documentation to directory X");
-	CommandLine::declare_switch(MODERNISE_CLSW, U"modernise", 1,
-		U"update copies to the newest available format");
+	CommandLine::end_group();
 
 	CommandLine::begin_group(MARKDOWN_SUITE_CLSG, I"for generating HTML from Markdown");
 	CommandLine::declare_switch(MARKDOWN_FROM_CLSW, U"markdown-from", 2,
@@ -622,6 +645,8 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
 				JSON_file_to_output = Filenames::from_text(arg);
 			break;
 		case DOCUMENT_FROM_CLSW: documentation_source = Filenames::from_text(arg); break;
+		case DOCUMENT_SET_CLSW: documentation_set = Pathnames::from_text(arg); break;
+		case DOCUMENT_SITEMAP_CLSW: documentation_sitemap = Filenames::from_text(arg); break;
 		case DOCUMENT_TO_CLSW: documentation_dest = Pathnames::from_text(arg); break;
 		
 		case MARKDOWN_FROM_CLSW: markdown_settings.from = Filenames::from_text(arg); break;
diff --git a/inbuild/Figures/help.txt b/inbuild/Figures/help.txt
index 289c61532..a709039b6 100644
--- a/inbuild/Figures/help.txt
+++ b/inbuild/Figures/help.txt
@@ -13,9 +13,6 @@ usage: inbuild [-TASK] TARGET1 TARGET2 ...
 -no-confirmed                  don't confirm installation in the Inform GUI apps (default is -confirmed)
 -contents-of X                 apply to all targets in the directory X
 -copy-to X                     copy target(s) to nest X
--document                      (re-)generate documentation on this within current project
--document-from X               generate documentation from documentation source file X
--document-to X                 divert generated documentation to directory X
 -dry                           make this a dry run (print but do not execute shell commands) (default is -no-dry)
 -graph                         show dependency graph of target(s) but take no action
 -inspect                       show target(s) but take no action
@@ -66,6 +63,13 @@ for tweaking code generation from Inter:
   -pipeline-file X             specify code-generation pipeline as file X
   -variable X                  set pipeline variable X (in form name=value)
 
+for generating extension or kit documentation:
+  -document                    (re-)generate documentation on this within current project
+  -document-from X             generate documentation from documentation in a single Markdown file X
+  -document-set X              generate documentation from a full documentation set in the path X
+  -document-sitemap X          use file X as the 'sitemap.txt' when generating documentation sets
+  -document-to X               divert generated documentation to directory X
+
 for generating HTML from Markdown:
   -markdown-from X             generate HTML file from Markdown source file X
   -markdown-from-dir X         generate HTML files from all Markdown sources in X
diff --git a/inbuild/supervisor-module/Chapter 2/Copies.w b/inbuild/supervisor-module/Chapter 2/Copies.w
index d64ed11c5..92e639714 100644
--- a/inbuild/supervisor-module/Chapter 2/Copies.w	
+++ b/inbuild/supervisor-module/Chapter 2/Copies.w	
@@ -342,8 +342,8 @@ void Copies::overwrite_error(inbuild_copy *C, inbuild_nest *N) {
 @ And |-document|:
 
 =
-void Copies::document(inbuild_copy *C, pathname *dest) {
-	VOID_METHOD_CALL(C->edition->work->genre, GENRE_DOCUMENT_MTID, C, dest);
+void Copies::document(inbuild_copy *C, pathname *dest, filename *sitemap) {
+	VOID_METHOD_CALL(C->edition->work->genre, GENRE_DOCUMENT_MTID, C, dest, sitemap);
 }
 
 @ And |-modernise|:
diff --git a/inbuild/supervisor-module/Chapter 2/Genres.w b/inbuild/supervisor-module/Chapter 2/Genres.w
index 15b281e88..11a4c2cc5 100644
--- a/inbuild/supervisor-module/Chapter 2/Genres.w	
+++ b/inbuild/supervisor-module/Chapter 2/Genres.w	
@@ -194,7 +194,7 @@ VOID_METHOD_TYPE(GENRE_COPY_TO_NEST_MTID,
 
 =
 VOID_METHOD_TYPE(GENRE_DOCUMENT_MTID,
-	inbuild_genre *gen, inbuild_copy *C, pathname *dest)
+	inbuild_genre *gen, inbuild_copy *C, pathname *dest, filename *sitemap)
 
 @ This performs some sort of automatic-update to the latest format:
 
diff --git a/inbuild/supervisor-module/Chapter 4/Extension Bundle Manager.w b/inbuild/supervisor-module/Chapter 4/Extension Bundle Manager.w
index 09a1b617e..fd03f8501 100644
--- a/inbuild/supervisor-module/Chapter 4/Extension Bundle Manager.w	
+++ b/inbuild/supervisor-module/Chapter 4/Extension Bundle Manager.w	
@@ -487,8 +487,9 @@ void ExtensionBundleManager::read_source_text_for(inbuild_genre *G, inbuild_copy
 @h Documentation.
 
 =
-void ExtensionBundleManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest) {
-	Extensions::document(Extensions::from_copy(C), dest);
+void ExtensionBundleManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest,
+	filename *sitemap) {
+	Extensions::document(Extensions::from_copy(C), dest, sitemap);
 }
 
 @h Modernisation.
diff --git a/inbuild/supervisor-module/Chapter 4/Extension Manager.w b/inbuild/supervisor-module/Chapter 4/Extension Manager.w
index 60f881738..e5460fd8b 100644
--- a/inbuild/supervisor-module/Chapter 4/Extension Manager.w	
+++ b/inbuild/supervisor-module/Chapter 4/Extension Manager.w	
@@ -261,8 +261,9 @@ void ExtensionManager::read_source_text_for(inbuild_genre *G, inbuild_copy *C) {
 @h Documentation.
 
 =
-void ExtensionManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest) {
-	Extensions::document(Extensions::from_copy(C), dest);
+void ExtensionManager::document(inbuild_genre *gen, inbuild_copy *C, pathname *dest,
+	filename *sitemap) {
+	Extensions::document(Extensions::from_copy(C), dest, sitemap);
 }
 
 @h Modernisation.
diff --git a/inbuild/supervisor-module/Chapter 5/Extension Services.w b/inbuild/supervisor-module/Chapter 5/Extension Services.w
index fded30a28..cba78da9f 100644
--- a/inbuild/supervisor-module/Chapter 5/Extension Services.w	
+++ b/inbuild/supervisor-module/Chapter 5/Extension Services.w	
@@ -779,7 +779,7 @@ void Extensions::read_source_text_for(inform_extension *E) {
 	if (E->read_into_file) {
 		text_stream *doc = TextFromFiles::torn_off_documentation(E->read_into_file);
 		if (Str::len(doc) > 0)
-			E->documentation = DocumentationCompiler::compile_from_text(doc, E);
+			E->documentation = DocumentationCompiler::compile_from_text(doc, E, NULL);
 		else E->documentation = NULL;
 		E->read_into_file->your_ref = STORE_POINTER_inbuild_copy(E->as_copy);
 		@;
@@ -835,7 +835,8 @@ source_location Extensions::top_line_location(inform_extension *E) {
 @ In directory extensions, documentation can be stored separately:
 
 =
-compiled_documentation *Extensions::get_documentation(inform_extension *E) {
+compiled_documentation *Extensions::get_documentation(inform_extension *E,
+	filename *sitemap) {
 	if (E == NULL) return NULL;
 	Copies::get_source_text(E->as_copy, I"getting documentation"); /* in the unlikely event this has not happened yet */
 	if (E->documentation_sought == FALSE) {
@@ -856,15 +857,15 @@ compiled_documentation *Extensions::get_documentation(inform_extension *E) {
 		Copies::attach_error(E->as_copy, CopyErrors::new_T(EXT_MISWORDED_CE, -1, error_text));
 		DISCARD_TEXT(error_text)					
 	} else {
-		E->documentation = DocumentationCompiler::compile_from_path(D, E);
+		E->documentation = DocumentationCompiler::compile_from_path(D, E, sitemap);
 	}
 
 @ And this serves the |-document| feature of inbuild:
 
 =
-void Extensions::document(inform_extension *E, pathname *dest) {
+void Extensions::document(inform_extension *E, pathname *dest, filename *sitemap) {
 	SVEXPLAIN(1, "(documenting %X to %p)\n", E->as_copy->edition->work, dest);
-	compiled_documentation *cd = Extensions::get_documentation(E);
+	compiled_documentation *cd = Extensions::get_documentation(E, sitemap);
 	DocumentationRenderer::as_HTML(dest, cd, NULL);
 }
 
diff --git a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w
index 6c0e99e99..510aa33ee 100644
--- a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w	
+++ b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w	
@@ -11,11 +11,11 @@ We can compile either from a single one-off file:
 
 =
 compiled_documentation *DocumentationCompiler::compile_from_file(filename *F,
-	inform_extension *associated_extension) {
+	inform_extension *associated_extension, filename *sitemap) {
 	TEMPORARY_TEXT(temp)
 	TextFiles::write_file_contents(temp, F);
 	compiled_documentation *cd =
-		DocumentationCompiler::compile_from_text(temp, associated_extension);
+		DocumentationCompiler::compile_from_text(temp, associated_extension, sitemap);
 	DISCARD_TEXT(temp)
 	return cd;
 }
@@ -25,9 +25,9 @@ torn-off documentation is found:
 
 =
 compiled_documentation *DocumentationCompiler::compile_from_text(text_stream *scrap,
-	inform_extension *associated_extension) {
+	inform_extension *associated_extension, filename *sitemap) {
 	SVEXPLAIN(1, "(compiling documentation: %d chars)\n", Str::len(scrap));
-	compiled_documentation *cd = DocumentationCompiler::new_cd(NULL, associated_extension);
+	compiled_documentation *cd = DocumentationCompiler::new_cd(NULL, associated_extension, sitemap);
 	cd_volume *vol = FIRST_IN_LINKED_LIST(cd_volume, cd->volumes);
 	cd_pageset *page = FIRST_IN_LINKED_LIST(cd_pageset, vol->pagesets);
 	page->nonfile_content = scrap;
@@ -41,8 +41,8 @@ the documentation for a directory-format extension.
 
 =
 compiled_documentation *DocumentationCompiler::compile_from_path(pathname *P,
-	inform_extension *associated_extension) {
-	compiled_documentation *cd = DocumentationCompiler::new_cd(P, associated_extension);
+	inform_extension *associated_extension, filename *sitemap) {
+	compiled_documentation *cd = DocumentationCompiler::new_cd(P, associated_extension, sitemap);
 	DocumentationCompiler::compile_inner(cd);
 	return cd;
 }
@@ -252,15 +252,16 @@ int DocumentationCompiler::scold(OUTPUT_STREAM, compiled_documentation *cd) {
 
 =
 compiled_documentation *DocumentationCompiler::new_cd(pathname *P,
-	inform_extension *associated_extension) {
+	inform_extension *associated_extension, filename *sitemap) {
 	compiled_documentation *cd = CREATE(compiled_documentation);
 	@;
 	if (P) {
 		cd_source_file *Documentation_md_cdsf = NULL;
 		@;
-		@;
+		@;
 	}
 	Indexes::add_indexing_notation(cd, NULL, NULL, I"standard", NULL);
+	Indexes::add_indexing_notation(cd, I"@", NULL, I"name", I"(invert)");
 	if (LinkedLists::len(cd->volumes) == 0) {
 		cd_volume *implied = DocumentationCompiler::add_volume(cd, cd->title, NULL, I"index.html");
 		ADD_TO_LINKED_LIST(I"Documentation.md", text_stream, implied->source_files);
@@ -333,15 +334,15 @@ compiled_documentation *DocumentationCompiler::new_cd(pathname *P,
 		}
 	}
 
-@ =
+@ =
 	filename *layout_file = Filenames::in(P, I"contents.txt");
-	filename *sitemap_file = Filenames::in(P, I"sitemap.txt");
+	if (sitemap == NULL) sitemap = Filenames::in(P, I"sitemap.txt");
 	if (TextFiles::exists(layout_file))
 		TextFiles::read(layout_file, FALSE, "can't open layout file",
 			TRUE, DocumentationCompiler::read_contents_helper, NULL, cd);
 	else if (Documentation_md_cdsf) Documentation_md_cdsf->used = TRUE;
-	if (TextFiles::exists(sitemap_file))
-		TextFiles::read(sitemap_file, FALSE, "can't open sitemap file",
+	if (TextFiles::exists(sitemap))
+		TextFiles::read(sitemap, FALSE, "can't open sitemap file",
 			TRUE, DocumentationCompiler::read_sitemap_helper, NULL, cd);
 
 @ =
@@ -566,7 +567,9 @@ void DocumentationCompiler::read_sitemap_helper(text_stream *cl, text_file_posit
 				TEMPORARY_TEXT(expanded_dest)
 				for (int i=0; i 0) @;
 	if (Dictionaries::find(cd->id.categories_by_name, name) == NULL) {
 		indexing_category *ic = CREATE(indexing_category);
diff --git a/inbuild/supervisor-module/Chapter 7/The Mini-Website.w b/inbuild/supervisor-module/Chapter 7/The Mini-Website.w
index df094aa34..bc92fefd9 100644
--- a/inbuild/supervisor-module/Chapter 7/The Mini-Website.w	
+++ b/inbuild/supervisor-module/Chapter 7/The Mini-Website.w	
@@ -153,7 +153,7 @@ void ExtensionWebsite::document_extension(inform_extension *E, inform_project *p
 		if (F == NULL) return;
 		pathname *P = Filenames::up(F);
 		if (Pathnames::create_in_file_system(P) == 0) return;
-		compiled_documentation *doc = Extensions::get_documentation(E);
+		compiled_documentation *doc = Extensions::get_documentation(E, NULL);
 		TEMPORARY_TEXT(OUT)
 		#ifdef CORE_MODULE
 		TEMPORARY_TEXT(details)
@@ -222,7 +222,7 @@ void ExtensionWebsite::document_extension(inform_extension *E, inform_project *p
 	if (Pathnames::create_in_file_system(KP)) {
 		pathname *KD = Pathnames::down(K->as_copy->location_if_path, I"Documentation");
 		compiled_documentation *doc =
-			DocumentationCompiler::compile_from_path(KD, NULL);
+			DocumentationCompiler::compile_from_path(KD, NULL, NULL);
 		if (doc == NULL) {
 			text_stream *OUT = DocumentationRenderer::open_subpage(KP, I"index.html");
 			DocumentationRenderer::render_header(OUT, K->as_copy->edition->work->title, NULL, E);
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index e317a8870..0be775252 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,6 +1,6 @@
-Total memory consumption was 139592K = 136 MB
+Total memory consumption was 139597K = 136 MB
 
- ---- was used for 2127247 objects, in 374801 frames in 0 x 800K = 0K = 0 MB:
+ ---- was used for 2127253 objects, in 374807 frames in 0 x 800K = 0K = 0 MB:
 
     30.2%  inter_tree_node_array                    60 x 8192 = 491520 objects, 43255680 bytes
     19.4%  text_stream_array                        4926 x 100 = 492600 objects, 27743232 bytes
@@ -78,24 +78,24 @@ Total memory consumption was 139592K = 136 MB
      ----  property_inference_data                  1317 objects, 52680 bytes
      ----  response_message                         408 objects, 52224 bytes
      ----  ap_clause_array                          2 x 400 = 800 objects, 51264 bytes
+     ----  span_notation                            6 objects, 49440 bytes
      ----  HTML_tag_array                           1 x 1000 objects, 48032 bytes
      ----  heading                                  213 objects, 47712 bytes
      ----  to_family_data                           528 objects, 42240 bytes
      ----  text_substitution                        438 objects, 42048 bytes
-     ----  activity_list_array                      1 x 1000 objects, 40032 bytes
      ----  anl_clause_array                         1 x 1000 objects, 40032 bytes
+     ----  activity_list_array                      1 x 1000 objects, 40032 bytes
      ----  shared_variable_access_list_array        12 x 100 = 1200 objects, 38784 bytes
      ----  parsing_data                             677 objects, 37912 bytes
      ----  production_list                          627 objects, 35112 bytes
-     ----  counting_data                            677 objects, 32496 bytes
      ----  regions_data                             677 objects, 32496 bytes
+     ----  counting_data                            677 objects, 32496 bytes
      ----  property_permission                      96 objects, 31488 bytes
      ----  stack_frame_box                          307 objects, 29472 bytes
      ----  verb_sense                               407 objects, 29304 bytes
      ----  action_pattern_array                     7 x 100 = 700 objects, 28224 bytes
      ----  filename                                 705 objects, 28200 bytes
      ----  pathname                                 662 objects, 26480 bytes
-     ----  span_notation                            3 objects, 24720 bytes
      ----  shared_variable_set_array                6 x 100 = 600 objects, 24192 bytes
      ----  parse_node_tree                          27 objects, 23544 bytes
      ----  property                                 148 objects, 22496 bytes
@@ -111,8 +111,8 @@ Total memory consumption was 139592K = 136 MB
      ----  pcalc_prop_deferral                      86 objects, 17888 bytes
      ----  to_phrase_request                        63 objects, 17136 bytes
      ----  understanding_reference_array            2 x 100 = 200 objects, 16064 bytes
-     ----  match_avinue_array                       1 x 1000 objects, 16032 bytes
      ----  action_name_list_array                   1 x 1000 objects, 16032 bytes
+     ----  match_avinue_array                       1 x 1000 objects, 16032 bytes
      ----  md_doc_state                             3 objects, 15720 bytes
      ----  adjective                                140 objects, 15680 bytes
      ----  JSON_value                               174 objects, 15312 bytes
@@ -141,13 +141,13 @@ Total memory consumption was 139592K = 136 MB
      ----  explicit_action_array                    1 x 100 objects, 4832 bytes
      ----  value_property_data                      86 objects, 4816 bytes
      ----  compatibility_specification              100 objects, 4800 bytes
-     ----  method_set                               144 objects, 4608 bytes
      ----  parsing_pp_data                          96 objects, 4608 bytes
+     ----  method_set                               144 objects, 4608 bytes
      ----  command_line_switch                      56 objects, 4480 bytes
      ----  semver_range                             42 objects, 4368 bytes
      ----  use_option                               31 objects, 4216 bytes
-     ----  either_or_property_data                  62 objects, 3968 bytes
      ----  parse_node_annotation_type               124 objects, 3968 bytes
+     ----  either_or_property_data                  62 objects, 3968 bytes
      ----  definition                               48 objects, 3456 bytes
      ----  submodule_request                        86 objects, 3440 bytes
      ----  property_setting_bp_data                 86 objects, 3440 bytes
@@ -155,8 +155,8 @@ Total memory consumption was 139592K = 136 MB
      ----  target_vm                                21 objects, 3024 bytes
      ----  JSON_type                                39 objects, 2808 bytes
      ----  JSON_single_requirement                  55 objects, 2640 bytes
-     ----  parentage_inference_data                 79 objects, 2528 bytes
      ----  part_of_inference_data                   79 objects, 2528 bytes
+     ----  parentage_inference_data                 79 objects, 2528 bytes
      ----  kind_constructor_instance_rule_array     1 x 100 objects, 2432 bytes
      ----  kind_constructor_casting_rule_array      1 x 100 objects, 2432 bytes
      ----  equation_symbol                          30 objects, 2400 bytes
@@ -169,11 +169,11 @@ Total memory consumption was 139592K = 136 MB
      ----  inform_pipeline                          24 objects, 1536 bytes
      ----  inbuild_requirement                      37 objects, 1480 bytes
      ----  noun_filter_token                        22 objects, 1408 bytes
-     ----  inter_node_array                         35 objects, 1400 bytes
      ----  special_meaning_holder                   35 objects, 1400 bytes
+     ----  inter_node_array                         35 objects, 1400 bytes
      ----  JSON_requirement                         42 objects, 1344 bytes
-     ----  table_column                             16 objects, 1280 bytes
      ----  constant_phrase                          20 objects, 1280 bytes
+     ----  table_column                             16 objects, 1280 bytes
      ----  invocation_options_array                 1 x 100 objects, 1224 bytes
      ----  direction_inference_data                 30 objects, 1200 bytes
      ----  inbuild_search_result                    29 objects, 1160 bytes
@@ -197,34 +197,34 @@ Total memory consumption was 139592K = 136 MB
      ----  implication                              13 objects, 624 bytes
      ----  chapter_md                               7 objects, 616 bytes
      ----  code_generation                          1 object, 576 bytes
-     ----  inter_warehouse_room                     10 objects, 560 bytes
-     ----  generated_segment                        14 objects, 560 bytes
-     ----  module                                   7 objects, 560 bytes
      ----  inter_annotation_form                    14 objects, 560 bytes
+     ----  module                                   7 objects, 560 bytes
+     ----  generated_segment                        14 objects, 560 bytes
+     ----  inter_warehouse_room                     10 objects, 560 bytes
      ----  rulebook_outcome                         17 objects, 544 bytes
-     ----  small_word_set                           11 objects, 528 bytes
+     ----  indexing_category                        6 objects, 528 bytes
      ----  markdown_variation                       3 objects, 528 bytes
+     ----  small_word_set                           11 objects, 528 bytes
      ----  IFM_example                              4 objects, 512 bytes
-     ----  equation                                 4 objects, 480 bytes
      ----  i6_memory_setting                        15 objects, 480 bytes
+     ----  equation                                 4 objects, 480 bytes
      ----  bp_family                                14 objects, 448 bytes
      ----  inbuild_genre                            8 objects, 448 bytes
-     ----  inference_family                         11 objects, 440 bytes
      ----  source_file                              5 objects, 440 bytes
+     ----  inference_family                         11 objects, 440 bytes
      ----  article_usage                            8 objects, 384 bytes
+     ----  pronoun                                  8 objects, 320 bytes
      ----  door_dir_notice                          5 objects, 320 bytes
      ----  tree_inventory                           1 object, 320 bytes
      ----  module_request                           8 objects, 320 bytes
-     ----  grammatical_category                     8 objects, 320 bytes
-     ----  pronoun                                  8 objects, 320 bytes
      ----  cached_kind_declaration                  8 objects, 320 bytes
+     ----  grammatical_category                     8 objects, 320 bytes
      ----  inter_pipeline                           1 object, 312 bytes
      ----  up_family                                9 objects, 288 bytes
      ----  contents_entry                           7 objects, 280 bytes
      ----  explicit_bp_data                         5 objects, 280 bytes
      ----  door_to_notice                           5 objects, 280 bytes
      ----  compilation_unit                         5 objects, 280 bytes
-     ----  indexing_category                        3 objects, 264 bytes
      ----  verb_usage_tier                          5 objects, 240 bytes
      ----  kit_dependency                           5 objects, 240 bytes
      ----  inform_project                           1 object, 232 bytes
@@ -238,8 +238,8 @@ Total memory consumption was 139592K = 136 MB
      ----  build_skill                              5 objects, 200 bytes
      ----  attachment_instruction                   5 objects, 200 bytes
      ----  code_generator                           5 objects, 200 bytes
-     ----  element_activation                       6 objects, 192 bytes
      ----  plural_dictionary_entry                  4 objects, 192 bytes
+     ----  element_activation                       6 objects, 192 bytes
      ----  inter_architecture                       4 objects, 160 bytes
      ----  inference_subject_family                 5 objects, 160 bytes
      ----  imperative_defn_family                   4 objects, 160 bytes
@@ -262,9 +262,9 @@ Total memory consumption was 139592K = 136 MB
      ----  by_function_bp_data                      1 object, 40 bytes
      ----  target_pragma_setting                    1 object, 40 bytes
 
-100.0% was used for memory not allocated for objects:
+99.9% was used for memory not allocated for objects:
 
-    62.3%  text stream storage                      89193940 bytes in 512654 claims
+    62.3%  text stream storage                      89198656 bytes in 512697 claims
      3.8%  dictionary storage                       5497920 bytes in 7767 claims
      ----  sorting                                  2624 bytes in 531 claims
      5.0%  source text                              7200000 bytes in 3 claims
@@ -282,5 +282,5 @@ Total memory consumption was 139592K = 136 MB
      ----  code generation workspace for objects    3528 bytes in 19 claims
      0.1%  emitter array storage                    281184 bytes in 2006 claims
 
--136.-5% was overhead - -195230424 bytes = -190654K = -186 MB
+-136.-5% was overhead - -195255408 bytes = -190679K = -186 MB
 
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index 8e5d465f7..09b1600a7 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,6 +1,6 @@
 100.0% in inform7 run
-     67.6% in compilation to Inter
-         46.3% in //Sequence::undertake_queued_tasks//
+     68.0% in compilation to Inter
+         46.6% in //Sequence::undertake_queued_tasks//
           4.4% in //MajorNodes::pre_pass//
           3.6% in //MajorNodes::pass_1//
           1.8% in //ImperativeDefinitions::assess_all//
@@ -10,20 +10,20 @@
           0.7% in //ImperativeDefinitions::compile_first_block//
           0.7% in //Sequence::undertake_queued_tasks//
           0.3% in //CompletionModule::compile//
-          0.3% in //InferenceSubjects::emit_all//
           0.3% in //MajorNodes::pass_2//
           0.3% in //Sequence::undertake_queued_tasks//
           0.3% in //World::stage_V//
-          4.0% not specifically accounted for
+          4.4% not specifically accounted for
      27.2% in running Inter pipeline
           8.8% in step 14/15: generate inform6 -> auto.inf
           6.9% in step 5/15: load-binary-kits
           5.8% in step 6/15: make-synoptic-module
           1.8% in step 9/15: make-identifiers-unique
+          0.3% in step 11/15: eliminate-redundant-labels
           0.3% in step 12/15: eliminate-redundant-operations
           0.3% in step 4/15: compile-splats
           0.3% in step 7/15: shorten-wiring
           0.3% in step 8/15: detect-indirect-calls
-          2.2% not specifically accounted for
+          1.9% not specifically accounted for
       4.0% in supervisor
-      1.2% not specifically accounted for
+      0.8% not specifically accounted for
diff --git a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json
index 19ec8c9b5..0db4fb43e 100644
--- a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json
+++ b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "Architecture16Kit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "compatibility": "16-bit",
     "kit-details": {
diff --git a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json
index e054c7b3b..12a5b5564 100644
--- a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json
+++ b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "Architecture32Kit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "compatibility": "32-bit",
     "kit-details": {
diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json
index 05c6c1105..8008a08ee 100644
--- a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json
+++ b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "BasicInformKit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "needs": [ {
         "need": {
diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json
index 3d15dba93..08748a663 100644
--- a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json
+++ b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "CommandParserKit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "needs": [ {
         "need": {
diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json
index 04e325941..4a2c0f318 100644
--- a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json
+++ b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "EnglishLanguageKit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "needs": [ {
         "need": {
diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json
index 2347de7f1..14f89a4cf 100644
--- a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json
+++ b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "WorldModelKit",
-        "version": "10.2.0-beta+6X16"
+        "version": "10.2.0-beta+6X17"
     },
     "needs": [ {
         "need": {