diff --git a/README.md b/README.md
index 6ba1c31e5..8f0f1a9cf 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Inform 7
-[Version](notes/versioning.md): 10.2.0-beta+6X15 'Krypton' (9 September 2023)
+[Version](notes/versioning.md): 10.2.0-beta+6X16 'Krypton' (10 September 2023)
## About Inform
diff --git a/build.txt b/build.txt
index 09fbf5366..8d22e12f0 100644
--- a/build.txt
+++ b/build.txt
@@ -1,3 +1,3 @@
Prerelease: beta
-Build Date: 9 September 2023
-Build Number: 6X15
+Build Date: 10 September 2023
+Build Number: 6X16
diff --git a/docs/supervisor-module/2-wrk.html b/docs/supervisor-module/2-wrk.html
index 1111bdd19..23b7aa23c 100644
--- a/docs/supervisor-module/2-wrk.html
+++ b/docs/supervisor-module/2-wrk.html
@@ -85,7 +85,7 @@ combination of the textual names and the hash code:
CLASS_DEFINITION
} inbuild_work ;
-
+
+
+Adaptations to extension documentation for rendering inside the app.
+
+
+
+
+
+
+void Manuals::duplex_contents_page ( OUTPUT_STREAM , compiled_documentation * cd ) {
+ Manuals::write_javascript_for_contents_buttons ( OUT , cd );
+ HTML_OPEN_WITH ( "div" , "class=\"midnight\"" );
+ HTML_OPEN_WITH ( "table" , "cellspacing=\"3\" border=\"0\" width=\"100%%\"" );
+ HTML_OPEN ( "tr" );
+ HTML_OPEN_WITH ( "td" , "style=\"width:80px; height:120px;\"" );
+ HTML_TAG_WITH ( "img" , "src=\"inform:/doc_images/wwi_cover@2x.png\" class=\"thinbordered\" style=\"width:80px; height:120px;\"" );
+ HTML_CLOSE ( "td" );
+ HTML_OPEN_WITH ( "td" , "style=\"width:80px; height:120px;\"" );
+ HTML_TAG_WITH ( "img" , "src=\"inform:/doc_images/irb_cover@2x.png\" class=\"thinbordered\" style=\"width:80px; height:120px;\"" );
+ HTML_CLOSE ( "td" );
+ HTML_OPEN_WITH ( "td" , "style=\"width:100%%;\"" );
+ HTML_OPEN_WITH ( "div" , "class=\"headingboxhigh\"" );
+ HTML_OPEN_WITH ( "div" , "class=\"headingtext\"" );
+ WRITE ( "Documentation" );
+ HTML_CLOSE ( "div" );
+ HTML_OPEN_WITH ( "div" , "class=\"headingrubric\"" );
+ WRITE ( "Two complete books about Inform:" );
+ HTML_TAG ( "br" );
+ WRITE ( "<i>Writing with Inform</i>, a comprehensive introduction" );
+ HTML_TAG ( "br" );
+ WRITE ( "<i>The Inform Recipe Book</i>, practical solutions for authors to use" );
+ HTML_CLOSE ( "div" );
+ HTML_CLOSE ( "div" );
+ HTML_CLOSE ( "td" );
+ HTML_CLOSE ( "tr" );
+ HTML_CLOSE ( "table" );
+ TEMPORARY_TEXT ( title )
+ WRITE_TO ( title , "Contents" );
+ int column = 0 ;
+ cd_volume * volumes [2] = { NULL , NULL };
+ cd_volume * V ;
+ LOOP_OVER_LINKED_LIST ( V , cd_volume , cd -> volumes ) {
+ volumes [ column ++] = V ;
+ if ( column == 2 ) break ;
+ }
+ HTML_OPEN_WITH ( "table" , "class=\"fullwidth\"" );
+ for ( column =0; column <2; column ++)
+ if ( volumes [ column ])
+ Render this column of the contents 1.1 ;
+ HTML_CLOSE ( "table" );
+
+ DISCARD_TEXT ( title )
+ HTML_CLOSE ( "div" );
+}
+
+
+
+
+ if ( column == 0 ) HTML_OPEN_WITH ( "td" , "class=\"midnightlefthalfpage\"" )
+ else HTML_OPEN_WITH ( "td" , "class=\"midnightrighthalfpage\"" );
+ Render a heavyweight column of links 1.1.1 ;
+ HTML_CLOSE ( "td" );
+
+
+
+
+
+
+
+
+
+ cd_volume * V = volumes [ column ];
+
+ TEMPORARY_TEXT ( extra )
+ Manuals::all_extras_link ( extra , V -> label );
+ Manuals::midnight_contents_column_banner ( OUT , V -> title , V , extra );
+ DISCARD_TEXT ( extra )
+
+ int extra_count = 0 ;
+ Manuals::duplex_r ( OUT , V -> volume_item , column , & extra_count );
+ if ( extra_count > 0 ) HTML::end_div ( OUT );
+
+ for ( int ix =0; ix < NO_CD_INDEXES ; ix ++)
+ if ((( column == 0 ) && (( ix == 1 ) || ( ix == 3 ))) ||
+ (( column == 1 ) && (( ix == 0 ) || ( ix == 2 ))))
+ if ( cd -> include_index [ ix ]) {
+ Manuals::mc_link_A ( OUT , cd -> index_URL_pattern [ ix ], cd -> index_title [ ix ]);
+ }
+
+ WRITE ( "\n" );
+
+This code is used in §1.1 .
+
+
+
+void Manuals::midnight_contents_column_banner ( OUTPUT_STREAM , text_stream * title , cd_volume * V , text_stream * extra ) {
+ HTML_OPEN_WITH ( "table" , "class=\"fullwidth midnightblack\"" );
+ HTML_OPEN ( "tr" );
+ HTML_OPEN_WITH ( "td" , "class=\"midnightbannerleftcell\"" );
+ WRITE ( "%S" , extra );
+ HTML_CLOSE ( "td" );
+ HTML_OPEN_WITH ( "td" , "class=\"midnightbannercentrecell\"" );
+ HTML_OPEN_WITH ( "span" , "class=\"midnightbannertext\"" );
+ WRITE ( "%S" , title );
+ HTML_CLOSE ( "span" );
+ HTML_CLOSE ( "td" );
+ HTML_CLOSE ( "tr" );
+ HTML_CLOSE ( "table" );
+}
+
+void Manuals::duplex_r ( OUTPUT_STREAM , markdown_item * md , int column , int * extra_count ) {
+ if (( md -> type == HEADING_MIT ) && ( Markdown::get_heading_level ( md ) == 1 )) {
+ if (* extra_count > 0 ) HTML::end_div ( OUT );
+ int id = column *1000 + (* extra_count )++;
+ HTML_OPEN_WITH ( "p" , "class=\"midnightcontentsA\"" );
+ Manuals::extra_link ( OUT , id );
+ DocumentationRenderer::link_to ( OUT , md );
+ for ( markdown_item * ch = md -> down ; ch ; ch = ch -> next )
+ Markdown::render_extended ( OUT , ch , InformFlavouredMarkdown::variation ());
+ HTML_CLOSE ( "a" );
+ HTML_CLOSE ( "p" );
+ Manuals::extra_div_open ( OUT , id );
+ }
+ if (( md -> type == HEADING_MIT ) && ( Markdown::get_heading_level ( md ) == 2 )) {
+ HTML_OPEN_WITH ( "p" , "class=\"midnightcontentsB\"" );
+ DocumentationRenderer::link_to ( OUT , md );
+ for ( markdown_item * ch = md -> down ; ch ; ch = ch -> next )
+ Markdown::render_extended ( OUT , ch , InformFlavouredMarkdown::variation ());
+ HTML_CLOSE ( "a" );
+ HTML_CLOSE ( "p" );
+ }
+ for ( markdown_item * ch = md -> down ; ch ; ch = ch -> next )
+ Manuals::duplex_r ( OUT , ch , column , extra_count );
+}
+
+
+
+
+void Manuals::extra_div_open ( OUTPUT_STREAM , int id ) {
+ HTML_OPEN_WITH ( "div" , "id=\"extra%d\" style=\"display: none;\"" , id );
+}
+
+
+
+
+void Manuals::extra_icon ( OUTPUT_STREAM , text_stream * name ) {
+ WRITE ( "inform:/doc_images/%S.png" , name );
+}
+
+void Manuals::extra_link ( OUTPUT_STREAM , int id ) {
+ TEMPORARY_TEXT ( onclick )
+ WRITE_TO ( onclick , "showExtra('extra%d', 'plus%d'); return false;" , id , id );
+ HTML::begin_link_with_class_onclick ( OUT , NULL , I "#" , onclick );
+ DISCARD_TEXT ( onclick )
+ TEMPORARY_TEXT ( details )
+ WRITE_TO ( details , "alt=\"show\" id=\"plus%d\" src=\"" , id );
+ Manuals::extra_icon ( details , I "extra" );
+ WRITE_TO ( details , "\"" );
+ HTML::tag ( OUT , "img" , details );
+ DISCARD_TEXT ( details )
+ HTML_CLOSE ( "a" );
+ WRITE ( " " );
+}
+
+void Manuals::all_extras_link ( OUTPUT_STREAM , text_stream * from ) {
+ WRITE ( " " );
+ TEMPORARY_TEXT ( onclick )
+ WRITE_TO ( onclick , "showExtra%S(); return false;" , from );
+ HTML::begin_link_with_class_onclick ( OUT , NULL , I "#" , onclick );
+ DISCARD_TEXT ( onclick )
+ TEMPORARY_TEXT ( details )
+ WRITE_TO ( details , "alt=\"show\" id=\"plus%S\" src=\"" , from );
+ Manuals::extra_icon ( details , I "extrab" );
+ WRITE_TO ( details , "\"" );
+ HTML::tag ( OUT , "img" , details );
+ DISCARD_TEXT ( details )
+ HTML_CLOSE ( "a" );
+}
+
+
+
+
+void Manuals::mc_link_A ( OUTPUT_STREAM , text_stream * to , text_stream * text ) {
+ HTML_OPEN_WITH ( "p" , "class=\"midnightcontentsA\"" );
+ IndexUtilities::general_link ( OUT , I "standardlink" , to , text );
+ HTML_CLOSE ( "p" );
+}
+
+void Manuals::mc_link_B ( OUTPUT_STREAM , text_stream * to , text_stream * text ) {
+ HTML_OPEN_WITH ( "p" , "class=\"midnightcontentsB\"" );
+ IndexUtilities::general_link ( OUT , I "standardlink" , to , text );
+ HTML_CLOSE ( "p" );
+}
+
+void Manuals::midnight_section_title ( text_stream * OUT , compiled_documentation * cd ,
+ filename * linkleft , text_stream * title , filename * linkright ) {
+ HTML::begin_div_with_class_S ( OUT , I "bookheader" , __FILE__ , __LINE__ );
+ TEMPORARY_TEXT ( lf )
+ TEMPORARY_TEXT ( rf )
+ WRITE_TO ( lf , "%/f" , linkleft );
+ WRITE_TO ( rf , "%/f" , linkright );
+ Manuals::midnight_banner ( OUT , cd ,
+ title , cd -> contents_URL_pattern , lf , rf );
+ HTML::end_div ( OUT );
+ DISCARD_TEXT ( lf )
+ DISCARD_TEXT ( rf )
+}
+
+
+
+
+void Manuals::image_with_id ( OUTPUT_STREAM , text_stream * name , text_stream * id ) {
+ TEMPORARY_TEXT ( details )
+ WRITE_TO ( details , "alt=\"%S\" src=\"inform:/doc_images/%S\" id=\"%S\"" , name , name , id );
+ HTML::tag ( OUT , "img" , details );
+ DISCARD_TEXT ( details )
+}
+
+void Manuals::midnight_banner_for_indexes ( text_stream * OUT , compiled_documentation * cd ,
+ text_stream * title ) {
+ Manuals::midnight_banner ( OUT , cd , title , NULL , NULL , NULL );
+}
+
+void Manuals::midnight_banner ( OUTPUT_STREAM , compiled_documentation * cd , text_stream * title ,
+ text_stream * linkcentre , text_stream * linkleft , text_stream * linkright ) {
+ HTML_OPEN_WITH ( "div" , "class=\"midnight\"" );
+ TEMPORARY_TEXT ( url )
+ WRITE_TO ( url , "%S" , cd -> contents_URL_pattern );
+ HTML_OPEN_WITH ( "table" , "class=\"fullwidth midnightblack\"" );
+ HTML_OPEN ( "tr" );
+ HTML_OPEN_WITH ( "td" , "class=\"midnightbannerleftcell\"" );
+ if ( Str::len ( linkleft ) > 0 ) {
+ TEMPORARY_TEXT ( img )
+ Manuals::image_with_id ( img , I "Hookleft.png" , I "hookleft" );
+ IndexUtilities::general_link ( OUT , I "standardlink" , linkleft , img );
+ DISCARD_TEXT ( img )
+ }
+ HTML_CLOSE ( "td" );
+ HTML_OPEN_WITH ( "td" , "class=\"midnightbannercentrecell\"" );
+ if ( Str::len ( linkcentre ) > 0 ) HTML::begin_link_with_class ( OUT , I "standardlink" , url );
+ HTML_OPEN_WITH ( "span" , "class=\"midnightbannertext\"" );
+ WRITE ( "%S" , title );
+ HTML_CLOSE ( "span" );
+ if ( Str::len ( linkcentre ) > 0 ) HTML::end_link ( OUT );
+ HTML_CLOSE ( "td" );
+ HTML_OPEN_WITH ( "td" , "class=\"midnightbannerrightcell\"" );
+ TEMPORARY_TEXT ( img )
+ Manuals::image_with_id ( img , I "Hookup.png" , I "hookup" );
+ IndexUtilities::general_link ( OUT , I "standardlink" , url , img );
+ DISCARD_TEXT ( img )
+ if ( Str::len ( linkright ) > 0 ) {
+ TEMPORARY_TEXT ( img )
+ Manuals::image_with_id ( img , I "Hookright.png" , I "hookright" );
+ IndexUtilities::general_link ( OUT , I "standardlink" , linkright , img );
+ DISCARD_TEXT ( img )
+ }
+ HTML_CLOSE ( "td" );
+ HTML_CLOSE ( "tr" );
+ HTML_CLOSE ( "table" );
+ DISCARD_TEXT ( url )
+ HTML_CLOSE ( "div" );
+}
+
+void Manuals::write_javascript_for_contents_buttons ( OUTPUT_STREAM , compiled_documentation * cd ) {
+ HTML::open_javascript ( OUT , FALSE );
+ WRITE ( " function openExtra(id, imid) {\n" );
+ WRITE ( " document.getElementById(id).style.display = 'block';\n" );
+ WRITE ( " document.getElementById(imid).src = '" );
+ Manuals::extra_icon ( OUT , I "extraclose" );
+ WRITE ( "';\n" );
+ WRITE ( " }\n" );
+ WRITE ( " function closeExtra(id, imid) {\n" );
+ WRITE ( " document.getElementById(id).style.display = 'none';\n" );
+ WRITE ( " document.getElementById(imid).src = '" );
+ Manuals::extra_icon ( OUT , I "extra" );
+ WRITE ( "';\n" );
+ WRITE ( " }\n" );
+ int column = 0 ;
+ cd_volume * volumes [2] = { NULL , NULL };
+ int counts [2] = { 0 , 0 };
+ cd_volume * V ;
+ LOOP_OVER_LINKED_LIST ( V , cd_volume , cd -> volumes ) {
+ counts [ column ] = Manuals::chapter_count ( V );
+ volumes [ column ++] = V ;
+ if ( column == 2 ) break ;
+ }
+ for ( column =0; column <2; column ++)
+ if ( volumes [ column ]) {
+ cd_volume * V = volumes [ column ];
+ WRITE ( " function showExtra%S() {\n" , V -> label );
+ WRITE ( " if (document.getElementById('plus%S').src.indexOf('" , V -> label );
+ Manuals::extra_icon ( OUT , I "extrab" );
+ WRITE ( "') >= 0) {\n" );
+ for ( int i =0; i < counts [ column ]; i ++) {
+ int bn = ( column )*1000+ i ;
+ WRITE ( " openExtra('extra%d', 'plus%d');\n" , bn , bn );
+ }
+ WRITE ( " document.getElementById('plus%S').src = '" , V -> label );
+ Manuals::extra_icon ( OUT , I "extracloseb" );
+ WRITE ( "';\n" );
+ WRITE ( " } else {\n" );
+ for ( int i =0; i < counts [ column ]; i ++) {
+ int bn = ( column )*1000+ i ;
+ WRITE ( " closeExtra('extra%d', 'plus%d');\n" , bn , bn );
+ }
+ WRITE ( " document.getElementById('plus%S').src = '" , V -> label );
+ Manuals::extra_icon ( OUT , I "extrab" );
+ WRITE ( "';\n" );
+ WRITE ( " }\n" );
+ WRITE ( " }\n" );
+ }
+ HTML::close_javascript ( OUT );
+}
+
+int Manuals::chapter_count ( cd_volume * V ) {
+ return Manuals::chapter_count_r ( V -> volume_item , 0 );
+}
+
+int Manuals::chapter_count_r ( markdown_item * md , int count ) {
+ if (( md -> type == HEADING_MIT ) && ( Markdown::get_heading_level ( md ) == 1 )) count ++;
+ if ( md -> type == MATERIAL_MIT ) return count ;
+ for ( markdown_item * ch = md -> down ; ch ; ch = ch -> next )
+ count = Manuals::chapter_count_r ( ch , count );
+ return count ;
+}
+
+
+
+
+
+
+
+
diff --git a/docs/supervisor-module/7-iu.html b/docs/supervisor-module/7-iu.html
index 0403b41ed..ba46446f2 100644
--- a/docs/supervisor-module/7-iu.html
+++ b/docs/supervisor-module/7-iu.html
@@ -78,7 +78,7 @@ function togglePopup(material_id) {
Making RTP Pages -
diff --git a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w
index 96b31b867..cf0a5632b 100644
--- a/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w
+++ b/inbuild/supervisor-module/Chapter 7/Documentation Compiler.w
@@ -68,6 +68,8 @@ typedef struct compiled_documentation {
struct linked_list *layout_errors; /* of |cd_layout_error| */
struct linked_list *volumes; /* of |cd_volume| */
+ struct text_stream *contents_URL_pattern;
+ int duplex_contents_page;
struct markdown_item *markdown_content;
struct md_links_dictionary *link_references;
@@ -270,6 +272,7 @@ compiled_documentation *DocumentationCompiler::new_cd(pathname *P,
cd->id = Indexes::new_indexing_data();
cd->examples_lettered = TRUE;
cd->example_URL_pattern = I"eg_#.html";
+ cd->contents_URL_pattern = I"index.html";
cd->index_URL_pattern[ALPHABETICAL_EG_INDEX] = I"alphabetical_index.html";
cd->index_URL_pattern[NUMERICAL_EG_INDEX] = I"numerical_index.html";
cd->index_URL_pattern[THEMATIC_EG_INDEX] = I"thematic_index.html";
@@ -284,6 +287,7 @@ compiled_documentation *DocumentationCompiler::new_cd(pathname *P,
cd->include_index[GENERAL_INDEX] = FALSE;
cd->layout_errors = NEW_LINKED_LIST(cd_layout_error);
cd->volumes = NEW_LINKED_LIST(cd_volume);
+ cd->duplex_contents_page = FALSE;
cd->source_files = NEW_LINKED_LIST(cd_source_file);
cd->domain = P;
@@ -319,7 +323,12 @@ void DocumentationCompiler::read_layout_helper(text_stream *cl, text_file_positi
if (Regexp::match(&mr, cl, U" *#%c*")) { Regexp::dispose_of(&mr); return; }
if (Regexp::match(&mr, cl, U" *")) { Regexp::dispose_of(&mr); return; }
- if (Regexp::match(&mr, cl, U" *examples: *(%c+?) to \"(%c*)\"")) {
+ if (Regexp::match(&mr, cl, U" *contents: *(%c+?) to \"(%c*)\"")) {
+ if (Str::eq(mr.exp[0], I"standard")) cd->duplex_contents_page = FALSE;
+ else if (Str::eq(mr.exp[0], I"duplex")) cd->duplex_contents_page = TRUE;
+ else DocumentationCompiler::layout_error(cd, I"'contents:' must be 'standard' or 'duplex'", cl, tfp);
+ cd->contents_URL_pattern = Str::duplicate(mr.exp[1]);
+ } else if (Regexp::match(&mr, cl, U" *examples: *(%c+?) to \"(%c*)\"")) {
if (Str::eq(mr.exp[0], I"lettered")) cd->examples_lettered = TRUE;
else if (Str::eq(mr.exp[0], I"numbered")) cd->examples_lettered = FALSE;
else DocumentationCompiler::layout_error(cd, I"'examples:' must be 'lettered' or 'numbered'", cl, tfp);
diff --git a/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w b/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w
index f13387ffc..bd63509f7 100644
--- a/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w
+++ b/inbuild/supervisor-module/Chapter 7/Documentation Renderer.w
@@ -40,22 +40,29 @@ void DocumentationRenderer::as_HTML(pathname *P, compiled_documentation *cd, tex
Languages::set_default_directory(LP);
}
if (cd) {
- text_stream *OUT = DocumentationRenderer::open_subpage(P, I"index.html");
+ text_stream *OUT = DocumentationRenderer::open_subpage(P, cd->contents_URL_pattern);
if (OUT) {
markdown_item *md = NULL;
if ((cd->markdown_content) && (cd->markdown_content->down) &&
(cd->markdown_content->down->down) &&
(cd->markdown_content->down->down->type == FILE_MIT)) {
filename *F = Markdown::get_filename(cd->markdown_content->down->down);
- if (Str::eq(Filenames::get_leafname(F), I"index.html"))
+ if (Str::eq(Filenames::get_leafname(F), cd->contents_URL_pattern))
md = cd->markdown_content->down->down;
}
- DocumentationRenderer::render_index_page(OUT, cd, md, extras);
+ if (cd->duplex_contents_page) {
+ InformPages::header(OUT, I"Contents", JAVASCRIPT_FOR_STANDARD_PAGES_IRES, NULL);
+ Manuals::duplex_contents_page(OUT, cd);
+ } else {
+ DocumentationRenderer::render_index_page(OUT, cd, md, extras);
+ }
DocumentationRenderer::close_subpage();
}
+ int vcount = 0;
for (markdown_item *vol = cd->markdown_content->down; vol; vol = vol->next) {
+ vcount++;
text_stream *home_URL = DocumentationCompiler::home_URL_at_volume_item(vol);
- if (Str::ne(home_URL, I"index.html")) {
+ if (Str::ne(home_URL, cd->contents_URL_pattern)) {
text_stream *OUT = DocumentationRenderer::open_subpage(P, home_URL);
if (OUT) {
text_stream *volume_title = DocumentationCompiler::title_at_volume_item(cd, vol);
@@ -89,7 +96,7 @@ void DocumentationRenderer::as_HTML(pathname *P, compiled_documentation *cd, tex
if (Str::ne(Filenames::get_leafname(F), home_URL)) {
text_stream *OUT = DocumentationRenderer::open_subpage(P, Filenames::get_leafname(F));
if (OUT) {
- DocumentationRenderer::render_chapter_page(OUT, cd, prev_md, md, md->next);
+ DocumentationRenderer::render_chapter_page(OUT, cd, prev_md, md, md->next, vcount);
DocumentationRenderer::close_subpage();
}
}
@@ -114,7 +121,12 @@ void DocumentationRenderer::as_HTML(pathname *P, compiled_documentation *cd, tex
if (cd->include_index[ix]) {
text_stream *OUT = DocumentationRenderer::open_subpage(P, cd->index_URL_pattern[ix]);
if (OUT) {
- DocumentationRenderer::render_header(OUT, cd->title, cd->index_title[ix], cd->within_extension);
+ if (cd->duplex_contents_page) {
+ InformPages::header(OUT, I"Contents", JAVASCRIPT_FOR_STANDARD_PAGES_IRES, NULL);
+ Manuals::midnight_banner_for_indexes(OUT, cd, cd->index_title[ix]);
+ } else {
+ DocumentationRenderer::render_header(OUT, cd->title, cd->index_title[ix], cd->within_extension);
+ }
switch (ix) {
case GENERAL_INDEX:
Indexes::write_general_index(OUT, cd);
@@ -216,10 +228,22 @@ void DocumentationRenderer::render_example_page(OUTPUT_STREAM, compiled_document
}
void DocumentationRenderer::render_chapter_page(OUTPUT_STREAM, compiled_documentation *cd,
- markdown_item *prev_file, markdown_item *file_marker, markdown_item *next_file) {
+ markdown_item *prev_file, markdown_item *file_marker, markdown_item *next_file,
+ int vcount) {
TEMPORARY_TEXT(title)
DocumentationRenderer::file_title(title, file_marker);
- DocumentationRenderer::render_header(OUT, cd->title, title, cd->within_extension);
+ if (cd->duplex_contents_page) {
+ InformPages::header(OUT, title, JAVASCRIPT_FOR_ONE_EXTENSION_IRES, NULL);
+ Manuals::midnight_section_title(OUT, cd, Markdown::get_filename(prev_file),
+ title, Markdown::get_filename(next_file));
+ if (vcount == 1) {
+ HTML_OPEN_WITH("div", "class=\"duplexleftpage\"");
+ } else {
+ HTML_OPEN_WITH("div", "class=\"duplexrightpage\"");
+ }
+ } else {
+ DocumentationRenderer::render_header(OUT, cd->title, title, cd->within_extension);
+ }
DISCARD_TEXT(title)
HTML_OPEN_WITH("div", "class=\"markdowncontent\"");
Markdown::render_extended(OUT, file_marker, InformFlavouredMarkdown::variation());
@@ -238,6 +262,9 @@ void DocumentationRenderer::render_chapter_page(OUTPUT_STREAM, compiled_document
HTML_CLOSE("a");
}
@;
+ if (cd->duplex_contents_page) {
+ HTML_CLOSE("div");
+ }
DocumentationRenderer::render_footer(OUT);
}
diff --git a/inbuild/supervisor-module/Chapter 7/In-App Manuals.w b/inbuild/supervisor-module/Chapter 7/In-App Manuals.w
new file mode 100644
index 000000000..309386841
--- /dev/null
+++ b/inbuild/supervisor-module/Chapter 7/In-App Manuals.w
@@ -0,0 +1,322 @@
+[Manuals::] In-App Manuals.
+
+Adaptations to extension documentation for rendering inside the app.
+
+@h Duplex contents page.
+
+=
+void Manuals::duplex_contents_page(OUTPUT_STREAM, compiled_documentation *cd) {
+ Manuals::write_javascript_for_contents_buttons(OUT, cd);
+ HTML_OPEN_WITH("div", "class=\"midnight\"");
+ HTML_OPEN_WITH("table", "cellspacing=\"3\" border=\"0\" width=\"100%%\"");
+ HTML_OPEN("tr");
+ HTML_OPEN_WITH("td", "style=\"width:80px; height:120px;\"");
+ HTML_TAG_WITH("img", "src=\"inform:/doc_images/wwi_cover@2x.png\" class=\"thinbordered\" style=\"width:80px; height:120px;\"");
+ HTML_CLOSE("td");
+ HTML_OPEN_WITH("td", "style=\"width:80px; height:120px;\"");
+ HTML_TAG_WITH("img", "src=\"inform:/doc_images/irb_cover@2x.png\" class=\"thinbordered\" style=\"width:80px; height:120px;\"");
+ HTML_CLOSE("td");
+ HTML_OPEN_WITH("td", "style=\"width:100%%;\"");
+ HTML_OPEN_WITH("div", "class=\"headingboxhigh\"");
+ HTML_OPEN_WITH("div", "class=\"headingtext\"");
+ WRITE("Documentation");
+ HTML_CLOSE("div");
+ HTML_OPEN_WITH("div", "class=\"headingrubric\"");
+ WRITE("Two complete books about Inform:");
+ HTML_TAG("br");
+ WRITE("Writing with Inform , a comprehensive introduction");
+ HTML_TAG("br");
+ WRITE("The Inform Recipe Book , practical solutions for authors to use");
+ HTML_CLOSE("div");
+ HTML_CLOSE("div");
+ HTML_CLOSE("td");
+ HTML_CLOSE("tr");
+ HTML_CLOSE("table");
+ TEMPORARY_TEXT(title)
+ WRITE_TO(title, "Contents");
+ int column = 0;
+ cd_volume *volumes[2] = { NULL, NULL };
+ cd_volume *V;
+ LOOP_OVER_LINKED_LIST(V, cd_volume, cd->volumes) {
+ volumes[column++] = V;
+ if (column == 2) break;
+ }
+ HTML_OPEN_WITH("table", "class=\"fullwidth\"");
+ for (column=0; column<2; column++)
+ if (volumes[column])
+ @;
+ HTML_CLOSE("table");
+
+ DISCARD_TEXT(title)
+ HTML_CLOSE("div");
+}
+
+@ =
+ if (column == 0) HTML_OPEN_WITH("td", "class=\"midnightlefthalfpage\"")
+ else HTML_OPEN_WITH("td", "class=\"midnightrighthalfpage\"");
+ @;
+ HTML_CLOSE("td");
+
+@ The lines linking to sections within a chapter are grouped into a || for
+that chapter, which can be hidden or revealed -- it contains "extra" material,
+as we put it.
+
+We assume here that there are fewer than 1000 chapters in each volume;
+there are in practice about 25.
+
+@
=
+ cd_volume *V = volumes[column];
+
+ TEMPORARY_TEXT(extra)
+ Manuals::all_extras_link(extra, V->label);
+ Manuals::midnight_contents_column_banner(OUT, V->title, V, extra);
+ DISCARD_TEXT(extra)
+
+ int extra_count = 0;
+ Manuals::duplex_r(OUT, V->volume_item, column, &extra_count);
+ if (extra_count > 0) HTML::end_div(OUT);
+
+ for (int ix=0; ixinclude_index[ix]) {
+ Manuals::mc_link_A(OUT, cd->index_URL_pattern[ix], cd->index_title[ix]);
+ }
+
+ WRITE("\n");
+
+@
+
+=
+void Manuals::midnight_contents_column_banner(OUTPUT_STREAM, text_stream *title, cd_volume *V, text_stream *extra) {
+ HTML_OPEN_WITH("table", "class=\"fullwidth midnightblack\"");
+ HTML_OPEN("tr");
+ HTML_OPEN_WITH("td", "class=\"midnightbannerleftcell\"");
+ WRITE("%S", extra);
+ HTML_CLOSE("td");
+ HTML_OPEN_WITH("td", "class=\"midnightbannercentrecell\"");
+ HTML_OPEN_WITH("span", "class=\"midnightbannertext\"");
+ WRITE("%S", title);
+ HTML_CLOSE("span");
+ HTML_CLOSE("td");
+ HTML_CLOSE("tr");
+ HTML_CLOSE("table");
+}
+
+void Manuals::duplex_r(OUTPUT_STREAM, markdown_item *md, int column, int *extra_count) {
+ if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) == 1)) {
+ if (*extra_count > 0) HTML::end_div(OUT);
+ int id = column*1000 + (*extra_count)++;
+ HTML_OPEN_WITH("p", "class=\"midnightcontentsA\"");
+ Manuals::extra_link(OUT, id);
+ DocumentationRenderer::link_to(OUT, md);
+ for (markdown_item *ch = md->down; ch; ch = ch->next)
+ Markdown::render_extended(OUT, ch, InformFlavouredMarkdown::variation());
+ HTML_CLOSE("a");
+ HTML_CLOSE("p");
+ Manuals::extra_div_open(OUT, id);
+ }
+ if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) == 2)) {
+ HTML_OPEN_WITH("p", "class=\"midnightcontentsB\"");
+ DocumentationRenderer::link_to(OUT, md);
+ for (markdown_item *ch = md->down; ch; ch = ch->next)
+ Markdown::render_extended(OUT, ch, InformFlavouredMarkdown::variation());
+ HTML_CLOSE("a");
+ HTML_CLOSE("p");
+ }
+ for (markdown_item *ch = md->down; ch; ch = ch->next)
+ Manuals::duplex_r(OUT, ch, column, extra_count);
+}
+
+@ The "extra" functions here are for revealing or concealing page content
+when the user clicks a button. Each such piece of content is in its own
+uniquely-ID'd ||, as follows:
+
+=
+void Manuals::extra_div_open(OUTPUT_STREAM, int id) {
+ HTML_OPEN_WITH("div", "id=\"extra%d\" style=\"display: none;\"", id);
+}
+
+@ And the following links provide the wiring for the buttons:
+
+=
+void Manuals::extra_icon(OUTPUT_STREAM, text_stream *name) {
+ WRITE("inform:/doc_images/%S.png", name);
+}
+
+void Manuals::extra_link(OUTPUT_STREAM, int id) {
+ TEMPORARY_TEXT(onclick)
+ WRITE_TO(onclick, "showExtra('extra%d', 'plus%d'); return false;", id, id);
+ HTML::begin_link_with_class_onclick(OUT, NULL, I"#", onclick);
+ DISCARD_TEXT(onclick)
+ TEMPORARY_TEXT(details)
+ WRITE_TO(details, "alt=\"show\" id=\"plus%d\" src=\"", id);
+ Manuals::extra_icon(details, I"extra");
+ WRITE_TO(details, "\"");
+ HTML::tag(OUT, "img", details);
+ DISCARD_TEXT(details)
+ HTML_CLOSE("a");
+ WRITE(" ");
+}
+
+void Manuals::all_extras_link(OUTPUT_STREAM, text_stream *from) {
+ WRITE(" ");
+ TEMPORARY_TEXT(onclick)
+ WRITE_TO(onclick, "showExtra%S(); return false;", from);
+ HTML::begin_link_with_class_onclick(OUT, NULL, I"#", onclick);
+ DISCARD_TEXT(onclick)
+ TEMPORARY_TEXT(details)
+ WRITE_TO(details, "alt=\"show\" id=\"plus%S\" src=\"", from);
+ Manuals::extra_icon(details, I"extrab");
+ WRITE_TO(details, "\"");
+ HTML::tag(OUT, "img", details);
+ DISCARD_TEXT(details)
+ HTML_CLOSE("a");
+}
+
+
+@ And here are the level A and B contents entry link paragraphs:
+
+=
+void Manuals::mc_link_A(OUTPUT_STREAM, text_stream *to, text_stream *text) {
+ HTML_OPEN_WITH("p", "class=\"midnightcontentsA\"");
+ IndexUtilities::general_link(OUT, I"standardlink", to, text);
+ HTML_CLOSE("p");
+}
+
+void Manuals::mc_link_B(OUTPUT_STREAM, text_stream *to, text_stream *text) {
+ HTML_OPEN_WITH("p", "class=\"midnightcontentsB\"");
+ IndexUtilities::general_link(OUT, I"standardlink", to, text);
+ HTML_CLOSE("p");
+}
+
+void Manuals::midnight_section_title(text_stream *OUT, compiled_documentation *cd,
+ filename *linkleft, text_stream *title, filename *linkright) {
+ HTML::begin_div_with_class_S(OUT, I"bookheader", __FILE__, __LINE__);
+ TEMPORARY_TEXT(lf)
+ TEMPORARY_TEXT(rf)
+ WRITE_TO(lf, "%/f", linkleft);
+ WRITE_TO(rf, "%/f", linkright);
+ Manuals::midnight_banner(OUT, cd,
+ title, cd->contents_URL_pattern, lf, rf);
+ HTML::end_div(OUT);
+ DISCARD_TEXT(lf)
+ DISCARD_TEXT(rf)
+}
+
+@ =
+void Manuals::image_with_id(OUTPUT_STREAM, text_stream *name, text_stream *id) {
+ TEMPORARY_TEXT(details)
+ WRITE_TO(details, "alt=\"%S\" src=\"inform:/doc_images/%S\" id=\"%S\"", name, name, id);
+ HTML::tag(OUT, "img", details);
+ DISCARD_TEXT(details)
+}
+
+void Manuals::midnight_banner_for_indexes(text_stream *OUT, compiled_documentation *cd,
+ text_stream *title) {
+ Manuals::midnight_banner(OUT, cd, title, NULL, NULL, NULL);
+}
+
+void Manuals::midnight_banner(OUTPUT_STREAM, compiled_documentation *cd, text_stream *title,
+ text_stream *linkcentre, text_stream *linkleft, text_stream *linkright) {
+ HTML_OPEN_WITH("div", "class=\"midnight\"");
+ TEMPORARY_TEXT(url)
+ WRITE_TO(url, "%S", cd->contents_URL_pattern);
+ HTML_OPEN_WITH("table", "class=\"fullwidth midnightblack\"");
+ HTML_OPEN("tr");
+ HTML_OPEN_WITH("td", "class=\"midnightbannerleftcell\"");
+ if (Str::len(linkleft) > 0) {
+ TEMPORARY_TEXT(img)
+ Manuals::image_with_id(img, I"Hookleft.png", I"hookleft");
+ IndexUtilities::general_link(OUT, I"standardlink", linkleft, img);
+ DISCARD_TEXT(img)
+ }
+ HTML_CLOSE("td");
+ HTML_OPEN_WITH("td", "class=\"midnightbannercentrecell\"");
+ if (Str::len(linkcentre) > 0) HTML::begin_link_with_class(OUT, I"standardlink", url);
+ HTML_OPEN_WITH("span", "class=\"midnightbannertext\"");
+ WRITE("%S", title);
+ HTML_CLOSE("span");
+ if (Str::len(linkcentre) > 0) HTML::end_link(OUT);
+ HTML_CLOSE("td");
+ HTML_OPEN_WITH("td", "class=\"midnightbannerrightcell\"");
+ TEMPORARY_TEXT(img)
+ Manuals::image_with_id(img, I"Hookup.png", I"hookup");
+ IndexUtilities::general_link(OUT, I"standardlink", url, img);
+ DISCARD_TEXT(img)
+ if (Str::len(linkright) > 0) {
+ TEMPORARY_TEXT(img)
+ Manuals::image_with_id(img, I"Hookright.png", I"hookright");
+ IndexUtilities::general_link(OUT, I"standardlink", linkright, img);
+ DISCARD_TEXT(img)
+ }
+ HTML_CLOSE("td");
+ HTML_CLOSE("tr");
+ HTML_CLOSE("table");
+ DISCARD_TEXT(url)
+ HTML_CLOSE("div");
+}
+
+void Manuals::write_javascript_for_contents_buttons(OUTPUT_STREAM, compiled_documentation *cd) {
+ HTML::open_javascript(OUT, FALSE);
+ WRITE(" function openExtra(id, imid) {\n");
+ WRITE(" document.getElementById(id).style.display = 'block';\n");
+ WRITE(" document.getElementById(imid).src = '");
+ Manuals::extra_icon(OUT, I"extraclose");
+ WRITE("';\n");
+ WRITE(" }\n");
+ WRITE(" function closeExtra(id, imid) {\n");
+ WRITE(" document.getElementById(id).style.display = 'none';\n");
+ WRITE(" document.getElementById(imid).src = '");
+ Manuals::extra_icon(OUT, I"extra");
+ WRITE("';\n");
+ WRITE(" }\n");
+ int column = 0;
+ cd_volume *volumes[2] = { NULL, NULL };
+ int counts[2] = { 0, 0 };
+ cd_volume *V;
+ LOOP_OVER_LINKED_LIST(V, cd_volume, cd->volumes) {
+ counts[column] = Manuals::chapter_count(V);
+ volumes[column++] = V;
+ if (column == 2) break;
+ }
+ for (column=0; column<2; column++)
+ if (volumes[column]) {
+ cd_volume *V = volumes[column];
+ WRITE(" function showExtra%S() {\n", V->label);
+ WRITE(" if (document.getElementById('plus%S').src.indexOf('", V->label);
+ Manuals::extra_icon(OUT, I"extrab");
+ WRITE("') >= 0) {\n");
+ for (int i=0; ilabel);
+ Manuals::extra_icon(OUT, I"extracloseb");
+ WRITE("';\n");
+ WRITE(" } else {\n");
+ for (int i=0; ilabel);
+ Manuals::extra_icon(OUT, I"extrab");
+ WRITE("';\n");
+ WRITE(" }\n");
+ WRITE(" }\n");
+ }
+ HTML::close_javascript(OUT);
+}
+
+int Manuals::chapter_count(cd_volume *V) {
+ return Manuals::chapter_count_r(V->volume_item, 0);
+}
+
+int Manuals::chapter_count_r(markdown_item *md, int count) {
+ if ((md->type == HEADING_MIT) && (Markdown::get_heading_level(md) == 1)) count++;
+ if (md->type == MATERIAL_MIT) return count;
+ for (markdown_item *ch = md->down; ch; ch = ch->next)
+ count = Manuals::chapter_count_r(ch, count);
+ return count;
+}
+
diff --git a/inbuild/supervisor-module/Contents.w b/inbuild/supervisor-module/Contents.w
index 98490329a..0eb9146ef 100644
--- a/inbuild/supervisor-module/Contents.w
+++ b/inbuild/supervisor-module/Contents.w
@@ -66,6 +66,7 @@ Chapter 7: Extension Management
The Converter
Documentation Compiler
Documentation Renderer
+ In-App Manuals
Making RTP Pages
Indexing Utilities
General Index
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index c619c6068..a64af0753 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,4 +1,4 @@
-Total memory consumption was 139585K = 136 MB
+Total memory consumption was 139589K = 136 MB
---- was used for 2127144 objects, in 374797 frames in 0 x 800K = 0K = 0 MB:
@@ -182,14 +182,14 @@ Total memory consumption was 139585K = 136 MB
---- runtime_kind_structure 13 objects, 1040 bytes
---- quantifier 16 objects, 1024 bytes
---- web_md 7 objects, 1008 bytes
- ---- named_rulebook_outcome 15 objects, 960 bytes
---- pipeline_stage 20 objects, 960 bytes
+ ---- named_rulebook_outcome 15 objects, 960 bytes
---- JSON_pair_requirement 29 objects, 928 bytes
---- control_structure_phrase 12 objects, 864 bytes
- ---- cached_understanding 21 objects, 840 bytes
+ ---- compiled_documentation 3 objects, 840 bytes
---- kit_configuration 21 objects, 840 bytes
+ ---- cached_understanding 21 objects, 840 bytes
---- phrase_option_array 1 x 100 objects, 824 bytes
- ---- compiled_documentation 3 objects, 792 bytes
---- inform_kit 7 objects, 784 bytes
---- copy_error 7 objects, 784 bytes
---- internal_test 15 objects, 720 bytes
@@ -197,10 +197,10 @@ Total memory consumption was 139585K = 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
- ---- inter_annotation_form 14 objects, 560 bytes
---- generated_segment 14 objects, 560 bytes
---- module 7 objects, 560 bytes
+ ---- inter_annotation_form 14 objects, 560 bytes
+ ---- inter_warehouse_room 10 objects, 560 bytes
---- rulebook_outcome 17 objects, 544 bytes
---- small_word_set 11 objects, 528 bytes
---- markdown_variation 3 objects, 528 bytes
@@ -264,7 +264,7 @@ Total memory consumption was 139585K = 136 MB
99.9% was used for memory not allocated for objects:
- 62.3% text stream storage 89187140 bytes in 512607 claims
+ 62.3% text stream storage 89191168 bytes in 512638 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 139585K = 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 - -195223016 bytes = -190647K = -186 MB
+-136.-5% was overhead - -195223064 bytes = -190647K = -186 MB
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index 242deac96..31bccf985 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
- 45.9% in //Sequence::undertake_queued_tasks//
+ 68.0% in compilation to Inter
+ 46.3% in //Sequence::undertake_queued_tasks//
4.4% in //MajorNodes::pre_pass//
3.6% in //MajorNodes::pass_1//
1.8% in //ImperativeDefinitions::assess_all//
@@ -14,15 +14,15 @@
0.3% in //Sequence::undertake_queued_tasks//
0.3% in //World::stage_V//
4.8% not specifically accounted for
- 27.5% in running Inter pipeline
+ 27.2% in running Inter pipeline
8.8% in step 14/15: generate inform6 -> auto.inf
- 7.3% in step 5/15: load-binary-kits
- 6.2% in step 6/15: make-synoptic-module
+ 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 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
- 1.8% not specifically accounted for
+ 2.2% not specifically accounted for
4.0% in supervisor
0.8% not specifically accounted for
diff --git a/inform7/Internal/HTML/main.css b/inform7/Internal/HTML/main.css
index e35d6af14..a58558e0b 100644
--- a/inform7/Internal/HTML/main.css
+++ b/inform7/Internal/HTML/main.css
@@ -860,3 +860,183 @@ div.generalindex span.indexcommandpartbracketed {
font-size: 0.9em;
}
+/* In Midnight, there's a black status line at the top of each page, made
+as a "fullwidth" table which also has this class: */
+
+div.midnight, div.midnight td {
+ font-size: 16px;
+ line-height: 20px;
+}
+
+div.midnight table.fullwidth {
+ border-collapse: collapse;
+ width: 100%;
+}
+
+div.midnight table.midnightblack {
+ background-color: #000000;
+}
+
+/* The table is a single row of three cells: */
+
+div.midnight td.midnightbannerleftcell {
+ height: 26px;
+ width: 38px;
+ text-align: center;
+ vertical-align: middle;
+}
+
+div.midnight td.midnightbannercentrecell {
+ text-align: left;
+ vertical-align: middle;
+}
+
+div.midnight td.midnightbannerrightcell {
+ height: 26px;
+ width: 56px;
+ text-align: right;
+ vertical-align: middle;
+ white-space: nowrap;
+}
+
+/* Within the centre cell, the running-head text is styled with: */
+
+div.midnight span.midnightbannertext {
+ color: #FFFFFF; /* needs to match the colour of the papertint */
+ font-size: 0.75em;
+}
+
+/* Midnight pages end with a Previous - Contents - Next footer area, which is
+done with a table using the following cells */
+
+div.midnight td.footerprevious {
+ width: 33%;
+ text-align: left;
+}
+
+div.midnight td.footercontents {
+ width: 33%;
+ text-align: center;
+}
+
+div.midnight td.footernext {
+ width: 33%;
+ text-align: right;
+}
+
+/* Links in the footer are styled with: */
+
+div.midnight a.footerlink {
+ color: #808080;
+ font-size: 0.75em;
+}
+
+/* At the first section, e.g., there's no "previous", but this is used to
+style the unlinked word "Previous": */
+
+div.midnight span.footernonlink {
+ color: #000000;
+ font-size: 0.75em;
+}
+
+/* Midnight features an elaborate contents page in two columns. */
+
+div.midnight td.midnightlefthalfpage {
+ background-color: #eeeeee;
+ width: 50%;
+ text-align: left;
+ vertical-align: top;
+}
+
+div.midnight td.midnightrighthalfpage {
+ background-color: #ffffe5;
+ width: 50%;
+ text-align: left;
+ vertical-align: top;
+}
+
+/* There are A- and B-level subheadings: */
+
+div.midnight p.midnightcontentsA {
+ font-size: 0.8em;
+ margin-top: 2px;
+ margin-bottom: 0px;
+ text-indent: -3em;
+ margin-left: 3em;
+ margin-right: 1em;
+ padding-left: 15px;
+}
+
+div.midnight p.midnightcontentsB {
+ font-size: 0.75em;
+ margin-top: 2px;
+ margin-bottom: 0px;
+ text-indent: -2em;
+ margin-left: 4em;
+ margin-right: 1em;
+ padding-left: 6px;
+}
+
+div.midnight div.headingboxhigh {
+ position: relative;
+ height: 117px;
+ padding: 0px;
+ white-space:nowrap;
+ background: #eeeeee; /* grey */
+ font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
+ -webkit-font-smoothing: antialiased;
+}
+
+div.midnight .headingtext {
+ position: absolute;
+ top: -4px;
+ left: -1px;
+ width: 100%;
+ color: #222222;
+ padding: 14px 10px 0px 10px;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+div.midnight .headingrubric {
+ position: absolute;
+ top: 36px;
+ width: 100%;
+ color: #222222;
+ padding: 0px 10px 0px 10px;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+div.midnight a:link { /* unvisited link */
+ text-decoration: none;
+ color: #202020;
+}
+div.midnight a:visited { /* visited link */
+ text-decoration: none;
+ color: #202020;
+}
+div.midnight a:hover { /* mouse over link */
+ text-decoration: none;
+ color: #D00000;
+}
+div.midnight a:active { /* selected link */
+ text-decoration: none;
+ color: #D00000;
+}
+
+div.duplexleftpage {
+ background-color: #ffffff;
+}
+
+div.duplexrightpage {
+ background-color: #ffffe5;
+}
+
+img.thinbordered {
+ border-style: solid;
+ border-width: 1px;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
diff --git a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json
index 67732807f..19ec8c9b5 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"compatibility": "16-bit",
"kit-details": {
diff --git a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json
index 692f13d71..e054c7b3b 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"compatibility": "32-bit",
"kit-details": {
diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json
index fece0732a..05c6c1105 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"needs": [ {
"need": {
diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json
index 503fb1d5e..3d15dba93 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"needs": [ {
"need": {
diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json
index c6ab8da3d..04e325941 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"needs": [ {
"need": {
diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json
index d84e5e396..2347de7f1 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+6X15"
+ "version": "10.2.0-beta+6X16"
},
"needs": [ {
"need": {