diff --git a/README.md b/README.md index da9d3c173..a134ddce4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6X07 'Krypton' (26 August 2023) +[Version](notes/versioning.md): 10.2.0-beta+6X08 'Krypton' (28 August 2023) ## About Inform diff --git a/build.txt b/build.txt index 1ec2659e6..d3c1d9826 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 26 August 2023 -Build Number: 6X07 +Build Date: 28 August 2023 +Build Number: 6X08 diff --git a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w index 7f0d65a8c..afd083283 100644 --- a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w +++ b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w @@ -12,9 +12,8 @@ typedef struct compiled_documentation { struct inform_extension *associated_extension; struct inform_extension *within_extension; struct markdown_item *alt_tree; - int total_headings[3]; - int total_examples; int empty; + struct linked_list *examples; /* of |satellite_test_case| */ struct linked_list *cases; /* of |satellite_test_case| */ CLASS_DEFINITION } compiled_documentation; @@ -26,11 +25,8 @@ compiled_documentation *DocumentationCompiler::new_wrapper(text_stream *source) cd->associated_extension = NULL; cd->within_extension = NULL; cd->alt_tree = NULL; - cd->total_examples = 0; - cd->total_headings[0] = 1; - cd->total_headings[1] = 0; - cd->total_headings[2] = 0; cd->empty = FALSE; + cd->examples = NEW_LINKED_LIST(IFM_example); cd->cases = NEW_LINKED_LIST(satellite_test_case); return cd; } @@ -62,6 +58,8 @@ compiled_documentation *DocumentationCompiler::compile_from_path(pathname *P, egs = FALSE; EP = Pathnames::down(P, I"Tests"); @; + int example_number = 0; + DocumentationCompiler::recursively_renumber_examples_r(cd->alt_tree, &example_number); return cd; } @@ -105,6 +103,23 @@ compiled_documentation *DocumentationCompiler::compile_from_path(pathname *P, @ += +void DocumentationCompiler::recursively_renumber_examples_r(markdown_item *md, int *example_number) { + if (md->type == INFORM_EXAMPLE_HEADING_MIT) { + IFM_example *E = RETRIEVE_POINTER_IFM_example(md->user_state); + int N = ++(*example_number); + int P = 1; + while (N > 26) { P += 1, N -= 26; } + Str::clear(E->insignia); + if (P > 1) WRITE_TO(E->insignia, "%d", P); + WRITE_TO(E->insignia, "%c", 'A'+N-1); + } + for (markdown_item *ch = md->down; ch; ch = ch->next) + DocumentationCompiler::recursively_renumber_examples_r(ch, example_number); +} + +@ + = typedef struct example_scanning_state { int star_count; @@ -135,7 +150,6 @@ typedef struct example_scanning_state { ; } else { alt_placement_node = InformFlavouredMarkdown::find_section(cd->alt_tree, ess.placement); - LOG("Looking for %S.\n", ess.placement); if (alt_placement_node == NULL) { DocumentationCompiler::example_error(&ess, I"example gives a Location which is not the name of any section"); @@ -147,9 +161,12 @@ typedef struct example_scanning_state { I"example does not give its Description"); } IFM_example *eg = InformFlavouredMarkdown::new_example( - ess.long_title, ess.desc, ess.star_count, ++(cd->total_examples)); + ess.long_title, ess.desc, ess.star_count, LinkedLists::len(cd->examples)); + eg->cue = alt_placement_node; + ADD_TO_LINKED_LIST(eg, IFM_example, cd->examples); markdown_item *eg_header = Markdown::new_item(INFORM_EXAMPLE_HEADING_MIT); + eg->header = eg_header; eg_header->user_state = STORE_POINTER_IFM_example(eg); markdown_item *md = alt_placement_node; if (md == NULL) { @@ -168,7 +185,6 @@ typedef struct example_scanning_state { markdown_item *alt_ecd = Markdown::parse_extended(ess.body_text, InformFlavouredMarkdown::variation()); eg_header->down = alt_ecd->down; - Markdown::debug_subtree(DL, eg_header); } else { DocumentationCompiler::example_error(&ess, I"example does not give any actual content"); diff --git a/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w b/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w index ae7aba4e6..55674e784 100644 --- a/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w +++ b/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w @@ -45,26 +45,28 @@ void DocumentationRenderer::as_HTML(pathname *P, compiled_documentation *cd, tex DocumentationRenderer::render_index_page(OUT, cd, extras); DocumentationRenderer::close_subpage(); } - for (int eg=1; eg<=cd->total_examples; eg++) { + IFM_example *egc; + LOOP_OVER_LINKED_LIST(egc, IFM_example, cd->examples) { TEMPORARY_TEXT(leaf) - WRITE_TO(leaf, "eg%d.html", eg); + WRITE_TO(leaf, "eg_%S.html", egc->insignia); OUT = DocumentationRenderer::open_subpage(P, leaf); if (OUT) { - DocumentationRenderer::render_example_page(OUT, cd, eg); + DocumentationRenderer::render_example_page(OUT, cd, egc); DocumentationRenderer::close_subpage(); } DISCARD_TEXT(leaf) } - for (int ch=1; ch<=cd->total_headings[1]; ch++) { - TEMPORARY_TEXT(leaf) - WRITE_TO(leaf, "chapter%d.html", ch); - OUT = DocumentationRenderer::open_subpage(P, leaf); - if (OUT) { - DocumentationRenderer::render_chapter_page(OUT, cd, ch); - DocumentationRenderer::close_subpage(); + for (markdown_item *prev_md = NULL, *md = cd->alt_tree->down; md; prev_md = md, md = md->next) + if (md->type == FILE_MIT) { + filename *F = Markdown::get_filename(md); + if (Str::ne(Filenames::get_leafname(F), I"index.html")) { + OUT = DocumentationRenderer::open_subpage(P, Filenames::get_leafname(F)); + if (OUT) { + DocumentationRenderer::render_chapter_page(OUT, cd, prev_md, md, md->next); + DocumentationRenderer::close_subpage(); + } + } } - DISCARD_TEXT(leaf) - } } } @@ -77,22 +79,19 @@ void DocumentationRenderer::render_index_page(OUTPUT_STREAM, compiled_documentat } HTML_TAG("hr"); - if (cd->total_headings[1] > 0) { /* there are chapters */ + if ((cd->alt_tree) && (cd->alt_tree->down) && (cd->alt_tree->down->next)) { /* there are multiple files */ DocumentationRenderer::render_toc(OUT, cd); HTML_OPEN("em"); InformFlavouredMarkdown::render_text(OUT, I"Click on Chapter, Section or Example numbers to read"); HTML_CLOSE("em"); markdown_item *md = cd->alt_tree->down; - if ((md) && ((md->type != HEADING_MIT) || (Markdown::get_heading_level(md) > 1))) { + filename *F = Markdown::get_filename(md); + if (Str::eq(Filenames::get_leafname(F), I"index.html")) { HTML_TAG("hr"); HTML_OPEN_WITH("p", "class=\"extensionsubheading\""); WRITE("introduction"); HTML_CLOSE("p"); - for (markdown_item *md = cd->alt_tree->down; md; md = md->next) { - if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) == 1)) - break; - Markdown::render_extended(OUT, md, InformFlavouredMarkdown::variation()); - } + Markdown::render_extended(OUT, md, InformFlavouredMarkdown::variation()); } } else { /* there are only sections and examples, or not even that */ HTML_OPEN_WITH("p", "class=\"extensionsubheading\""); @@ -130,39 +129,49 @@ void DocumentationRenderer::render_index_page(OUTPUT_STREAM, compiled_documentat @ = -void DocumentationRenderer::render_example_page(OUTPUT_STREAM, compiled_documentation *cd, int eg) { +void DocumentationRenderer::render_example_page(OUTPUT_STREAM, compiled_documentation *cd, + IFM_example *egc) { TEMPORARY_TEXT(title) - WRITE_TO(title, "Example %c", 'A' + eg - 1); + WRITE_TO(title, "Example %d", egc->number); DocumentationRenderer::render_header(OUT, cd->title, title, cd->within_extension); DISCARD_TEXT(title) - DocumentationRenderer::render_example(OUT, cd, eg); + DocumentationRenderer::render_example(OUT, cd, egc); DocumentationRenderer::render_footer(OUT); } -void DocumentationRenderer::render_chapter_page(OUTPUT_STREAM, compiled_documentation *cd, int ch) { +void DocumentationRenderer::render_chapter_page(OUTPUT_STREAM, compiled_documentation *cd, + markdown_item *prev_file, markdown_item *file_marker, markdown_item *next_file) { TEMPORARY_TEXT(title) - WRITE_TO(title, "Chapter %d", ch); + DocumentationRenderer::file_title(title, file_marker); DocumentationRenderer::render_header(OUT, cd->title, title, cd->within_extension); DISCARD_TEXT(title) - DocumentationRenderer::render_chapter(OUT, cd, ch); + HTML_OPEN("div"); + Markdown::render_extended(OUT, file_marker, InformFlavouredMarkdown::variation()); + HTML_CLOSE("div"); @; - WRITE("This is Chapter %d of %d", ch, cd->total_headings[1]); - if (ch > 1) { + if (prev_file) { WRITE(" • "); - HTML_OPEN_WITH("a", "href=\"chapter%d.html\"", ch-1); - WRITE("Chapter %d", ch-1); + HTML_OPEN_WITH("a", "href=\"%f\"", Markdown::get_filename(prev_file)); + DocumentationRenderer::file_title(OUT, prev_file); HTML_CLOSE("a"); } - if (ch < cd->total_headings[1]) { + if (next_file) { WRITE(" • "); - HTML_OPEN_WITH("a", "href=\"chapter%d.html\"", ch+1); - WRITE("Chapter %d", ch+1); + HTML_OPEN_WITH("a", "href=\"%f\"", Markdown::get_filename(next_file)); + DocumentationRenderer::file_title(OUT, next_file); HTML_CLOSE("a"); } @; DocumentationRenderer::render_footer(OUT); } +void DocumentationRenderer::file_title(OUTPUT_STREAM, markdown_item *file_marker) { + if ((file_marker->down) && (file_marker->down->type == HEADING_MIT)) + InformFlavouredMarkdown::render_text(OUT, file_marker->down->stashed); + else + WRITE("Preface"); +} + @ Each of these pages is equipped with the same Javascript and CSS. = @@ -234,6 +243,7 @@ in a hierarchical fashion. = void DocumentationRenderer::render_toc(OUTPUT_STREAM, compiled_documentation *cd) { +Markdown::debug_subtree(DL, cd->alt_tree); HTML_OPEN("div"); HTML_OPEN_WITH("p", "class=\"extensionsubheading\""); WRITE("contents"); @@ -246,57 +256,55 @@ void DocumentationRenderer::render_toc(OUTPUT_STREAM, compiled_documentation *cd void DocumentationRenderer::link_to(OUTPUT_STREAM, markdown_item *md) { if (md->type != HEADING_MIT) internal_error("not a heading"); - text_stream *ch = RETRIEVE_POINTER_text_stream(md->user_state); + text_stream *ch = MarkdownVariations::URL_for_heading(md); HTML_OPEN_WITH("a", "style=\"text-decoration: none\" href=%S", ch); } void DocumentationRenderer::render_toc_r(OUTPUT_STREAM, markdown_item *md, int L) { - if (md->type == HEADING_MIT) { + if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) <= 2)) { if (L > 0) { - HTML_OPEN_WITH("li", "class=\"exco%d\"", L); + HTML_OPEN_WITH("li", "class=\"exco%d\"", Markdown::get_heading_level(md)); HTML::begin_span(OUT, I"indexblack"); HTML_OPEN("b"); DocumentationRenderer::link_to(OUT, md); - Markdown::render_extended(OUT, md->down, - InformFlavouredMarkdown::variation()); + for (markdown_item *ch = md->down; ch; ch = ch->next) + Markdown::render_extended(OUT, ch, InformFlavouredMarkdown::variation()); HTML_CLOSE("a"); HTML_CLOSE("b"); HTML::end_span(OUT); HTML_CLOSE("li"); + WRITE("\n"); } } if (md->type == INFORM_EXAMPLE_HEADING_MIT) { HTML_OPEN_WITH("li", "class=\"exco%d\"", L); IFM_example *E = RETRIEVE_POINTER_IFM_example(md->user_state); TEMPORARY_TEXT(link) - WRITE_TO(link, "style=\"text-decoration: none\" href=\"eg%d.html#eg%d\"", - E->number, E->number); + WRITE_TO(link, "style=\"text-decoration: none\" href=\"eg_%S.html#eg%S\"", + E->insignia, E->insignia); HTML::begin_span(OUT, I"indexblack"); HTML_OPEN_WITH("a", "%S", link); - WRITE("Example %c — ", E->letter); + WRITE("Example %S — ", E->insignia); InformFlavouredMarkdown::render_text(OUT, E->name); HTML_CLOSE("a"); HTML::end_span(OUT); DISCARD_TEXT(link) HTML_CLOSE("li"); + WRITE("\n"); } for (markdown_item *ch = md->down; ch; ch = ch->next) DocumentationRenderer::render_toc_r(OUT, ch, L+1); } -void DocumentationRenderer::render_example(OUTPUT_STREAM, compiled_documentation *cd, int eg) { +void DocumentationRenderer::render_example(OUTPUT_STREAM, compiled_documentation *cd, + IFM_example *egc) { HTML_OPEN("div"); - markdown_item *alt_EN = InformFlavouredMarkdown::find_example(cd->alt_tree, eg); + markdown_item *alt_EN = egc->header; if (alt_EN == NULL) { - WRITE("Example %d is missing", eg); + WRITE("Example %d is missing", egc->number); } else { IFM_example *E = RETRIEVE_POINTER_IFM_example(alt_EN->user_state); - TEMPORARY_TEXT(link) - if (alt_EN->down) { - WRITE_TO(link, "style=\"text-decoration: none\" href=\"eg%d.html\"", E->number); - InformFlavouredMarkdown::render_example_heading(OUT, E, link); - } - DISCARD_TEXT(link) + InformFlavouredMarkdown::render_example_heading(OUT, E, TRUE); markdown_item *passage_node = alt_EN->down; while (passage_node) { Markdown::render_extended(OUT, passage_node, @@ -305,45 +313,13 @@ void DocumentationRenderer::render_example(OUTPUT_STREAM, compiled_documentation } HTML_CLOSE("div"); @; -/* WRITE("This example is drawn from "); - tree_node *H = EN->parent; - if (H->type == heading_TNT) { - cdoc_heading *E = RETRIEVE_POINTER_cdoc_heading(H->content); - if (E->level == 1) { - DocumentationRenderer::link_to(OUT, E); - WRITE("Chapter %S", E->count); - HTML_CLOSE("a"); - } else if (E->level == 2) { - DocumentationRenderer::link_to(OUT, E); - WRITE("Section %S", E->count); - HTML_CLOSE("a"); - } else { - HTML_OPEN_WITH("a", "href=\"index.html\""); - WRITE("the introduction"); - HTML_CLOSE("a"); - } + if (egc->cue) { + WRITE("This example is drawn from "); + DocumentationRenderer::link_to(OUT, egc->cue); + Markdown::render_extended(OUT, egc->cue->down, + InformFlavouredMarkdown::variation()); + HTML_CLOSE("a"); } -*/ @; } } - -void DocumentationRenderer::render_chapter(OUTPUT_STREAM, compiled_documentation *cd, int ch) { - HTML_OPEN("div"); - int found = FALSE; - TEMPORARY_TEXT(wanted) - WRITE_TO(wanted, "Chapter %d:", ch); - markdown_item *md = cd->alt_tree->down; - int rendering = FALSE; - while (md) { - if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) == 1)) { - text_stream *S = md->stashed; - if (Str::begins_with(S, wanted)) { rendering = TRUE; found = TRUE; } - else rendering = FALSE; - } - if (rendering) Markdown::render_extended(OUT, md, InformFlavouredMarkdown::variation()); - md = md->next; - } - if (found == FALSE) WRITE("Chapter %d is missing", ch); - HTML_CLOSE("div"); -} diff --git a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json index c2b0d09ca..5fd2931bf 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+6X07" + "version": "10.2.0-beta+6X08" }, "compatibility": "16-bit", "kit-details": { diff --git a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json index d1fce7594..30f77b6f9 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+6X07" + "version": "10.2.0-beta+6X08" }, "compatibility": "32-bit", "kit-details": { diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index c4357077d..0bbd27897 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+6X07" + "version": "10.2.0-beta+6X08" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index a9794923f..233e9c4f2 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+6X07" + "version": "10.2.0-beta+6X08" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index ffdcf5322..c8a86869e 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+6X07" + "version": "10.2.0-beta+6X08" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index c88bab541..29865e460 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+6X07" + "version": "10.2.0-beta+6X08" }, "needs": [ { "need": {