mirror of
https://github.com/ganelson/inform.git
synced 2024-06-30 22:14:58 +03:00
Written about half of an indoc manual
This commit is contained in:
parent
0e06463b2f
commit
9dbeba91b7
|
@ -30,7 +30,7 @@ void Basics::end(void) {
|
|||
@h Setting up the memory manager.
|
||||
We need to itemise the structures we'll want to allocate:
|
||||
|
||||
@e indoc_instructions_MT
|
||||
@e settings_block_MT
|
||||
@e volume_MT
|
||||
@e chapter_MT
|
||||
@e section_MT
|
||||
|
@ -49,7 +49,7 @@ We need to itemise the structures we'll want to allocate:
|
|||
@ And then expand:
|
||||
|
||||
=
|
||||
ALLOCATE_INDIVIDUALLY(indoc_instructions)
|
||||
ALLOCATE_INDIVIDUALLY(settings_block)
|
||||
ALLOCATE_INDIVIDUALLY(volume)
|
||||
ALLOCATE_INDIVIDUALLY(chapter)
|
||||
ALLOCATE_INDIVIDUALLY(section)
|
||||
|
|
|
@ -14,7 +14,7 @@ void Configuration::add_instructions_file(filename *F) {
|
|||
ADD_TO_LINKED_LIST(F, filename, instructions_files);
|
||||
}
|
||||
|
||||
void Configuration::read_instructions(text_stream *target, indoc_instructions *settings) {
|
||||
void Configuration::read_instructions(text_stream *target, settings_block *settings) {
|
||||
Instructions::read_instructions(target, instructions_files, settings);
|
||||
}
|
||||
|
||||
|
@ -23,18 +23,16 @@ void Configuration::read_instructions(text_stream *target, indoc_instructions *s
|
|||
=
|
||||
typedef struct cl_state {
|
||||
struct text_stream *target_chosen;
|
||||
struct indoc_instructions *settings;
|
||||
struct settings_block *settings;
|
||||
} cl_state;
|
||||
|
||||
void Configuration::read_command_line(int argc, char **argv, indoc_instructions *settings) {
|
||||
pathname *IM = Pathnames::from_text(I"indoc");
|
||||
IM = Pathnames::subfolder(IM, I"Materials");
|
||||
filename *basics = Filenames::in_folder(IM, I"basic-instructions.txt");
|
||||
Configuration::add_instructions_file(basics);
|
||||
void Configuration::read_command_line(int argc, char **argv, settings_block *settings) {
|
||||
cl_state state;
|
||||
state.target_chosen = Str::new();
|
||||
state.settings = settings;
|
||||
@<Read the command line@>;
|
||||
Configuration::add_instructions_file(
|
||||
Filenames::in_folder(path_to_indoc_materials, I"basic-instructions.txt"));
|
||||
Configuration::add_instructions_file(
|
||||
Filenames::in_folder(settings->book_folder, I"indoc-instructions.txt"));
|
||||
Configuration::read_instructions(state.target_chosen, settings);
|
||||
|
@ -73,7 +71,7 @@ void Configuration::read_command_line(int argc, char **argv, indoc_instructions
|
|||
|
||||
@ =
|
||||
void Configuration::switch(int id, int val, text_stream *arg, void *v_cl_state) {
|
||||
indoc_instructions *settings = ((cl_state *) v_cl_state)->settings;
|
||||
settings_block *settings = ((cl_state *) v_cl_state)->settings;
|
||||
switch (id) {
|
||||
case VERBOSE_CLSW: settings->verbose_mode = val; break;
|
||||
case TEST_INDEX_CLSW: settings->test_index_mode = val; break;
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
Instructions of indoc to different output types.
|
||||
|
||||
@h Definitions.
|
||||
|
||||
@ A few fundamental options set at the command line.
|
||||
The command-line and Instructions-file-set values provide a large slate of
|
||||
what used to be global variables in the Perl version of Indoc. Today they
|
||||
are herded together into an instance of the |settings_block| structure,
|
||||
and in particular into a global instance of this called |indoc_settings|.
|
||||
|
||||
@d LETTER_ALPHABETIZATION 1
|
||||
@d WORD_ALPHABETIZATION 2
|
||||
|
@ -29,7 +31,7 @@ Instructions of indoc to different output types.
|
|||
@d WRAPPER_zip 3
|
||||
|
||||
=
|
||||
typedef struct indoc_instructions {
|
||||
typedef struct settings_block {
|
||||
int verbose_mode;
|
||||
int test_index_mode;
|
||||
|
||||
|
@ -85,13 +87,13 @@ typedef struct indoc_instructions {
|
|||
struct navigation_design *navigation;
|
||||
|
||||
MEMORY_MANAGEMENT
|
||||
} indoc_instructions;
|
||||
} settings_block;
|
||||
|
||||
@
|
||||
|
||||
=
|
||||
indoc_instructions *Instructions::clean_slate(void) {
|
||||
indoc_instructions *settings = CREATE(indoc_instructions);
|
||||
settings_block *Instructions::clean_slate(void) {
|
||||
settings_block *settings = CREATE(settings_block);
|
||||
settings->verbose_mode = FALSE;
|
||||
settings->test_index_mode = FALSE;
|
||||
|
||||
|
@ -145,18 +147,11 @@ indoc_instructions *Instructions::clean_slate(void) {
|
|||
settings->wrapper = WRAPPER_none;
|
||||
settings->ebook = NULL;
|
||||
|
||||
settings->navigation = Gadgets::default();
|
||||
settings->navigation = Nav::default();
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
@ =
|
||||
typedef struct dc_metadatum {
|
||||
struct text_stream *dc_key;
|
||||
struct text_stream *dc_val;
|
||||
MEMORY_MANAGEMENT
|
||||
} dc_metadatum;
|
||||
|
||||
@h Instructions file.
|
||||
Note that |indoc| reports errors in the instructions file, but doesn't halt on
|
||||
them until all have been found. (The user may as well get all of the bad news,
|
||||
|
@ -164,13 +159,12 @@ not just the beginning of it.)
|
|||
|
||||
=
|
||||
void Instructions::read_instructions(text_stream *target_sought, linked_list *L,
|
||||
indoc_instructions *settings) {
|
||||
settings_block *settings) {
|
||||
int found_flag = FALSE; /* was a target of this name actually found? */
|
||||
|
||||
settings->change_logs_folder = Pathnames::subfolder(settings->book_folder, I"Change Logs");
|
||||
settings->examples_directory = Pathnames::subfolder(settings->book_folder, I"Examples");
|
||||
pathname *Materials = Pathnames::subfolder(Pathnames::from_text(I"indoc"), I"Materials");
|
||||
settings->css_source_file = Filenames::in_folder(Materials, I"base.css");
|
||||
settings->css_source_file = Filenames::in_folder(path_to_indoc_materials, I"base.css");
|
||||
settings->definitions_index_leafname = Str::duplicate(I"general_index.html");
|
||||
|
||||
filename *F;
|
||||
|
@ -181,7 +175,7 @@ void Instructions::read_instructions(text_stream *target_sought, linked_list *L,
|
|||
@<Reconcile any conflicting instructions@>;
|
||||
@<Declare the format and wrapper as symbols@>;
|
||||
|
||||
HTMLUtilities::add_image_source(Pathnames::subfolder(Materials, I"images"));
|
||||
HTMLUtilities::add_image_source(Pathnames::subfolder(path_to_indoc_materials, I"images"));
|
||||
|
||||
if (found_flag == FALSE)
|
||||
Errors::fatal_with_text("unknown target %S", target_sought);
|
||||
|
@ -201,13 +195,13 @@ applies 20 for all targets except |hypercard|, where it applies 40.
|
|||
=
|
||||
typedef struct ins_helper_state {
|
||||
int found_aim;
|
||||
struct indoc_instructions *settings;
|
||||
struct settings_block *settings;
|
||||
struct text_stream *desired_target;
|
||||
struct text_stream *scanning_target;
|
||||
} ins_helper_state;
|
||||
|
||||
int Instructions::read_instructions_from(filename *F, text_stream *desired,
|
||||
indoc_instructions *settings) {
|
||||
settings_block *settings) {
|
||||
ins_helper_state ihs;
|
||||
ihs.scanning_target = Str::new();
|
||||
ihs.desired_target = desired;
|
||||
|
@ -222,7 +216,7 @@ int Instructions::read_instructions_from(filename *F, text_stream *desired,
|
|||
void Instructions::read_instructions_helper(text_stream *cl, text_file_position *tfp,
|
||||
void *v_ihs) {
|
||||
ins_helper_state *ihs = (ins_helper_state *) v_ihs;
|
||||
indoc_instructions *settings = ihs->settings;
|
||||
settings_block *settings = ihs->settings;
|
||||
match_results mr = Regexp::create_mr();
|
||||
|
||||
if (Regexp::match(&mr, cl, L" *#%c*")) { Regexp::dispose_of(&mr); return; }
|
||||
|
@ -269,9 +263,7 @@ void Instructions::read_instructions_helper(text_stream *cl, text_file_position
|
|||
settings->book_contains_examples = TRUE;
|
||||
} else if (Regexp::match(&mr, cl, L" *dc:(%C+): *(%c*?) *")) {
|
||||
@<Disallow this in a specific target@>;
|
||||
dc_metadatum *dcm = CREATE(dc_metadatum);
|
||||
dcm->dc_key = Str::duplicate(mr.exp[0]);
|
||||
dcm->dc_val = Str::duplicate(mr.exp[1]);
|
||||
Instructions::create_ebook_metadata(Str::duplicate(mr.exp[0]), Str::duplicate(mr.exp[1]));
|
||||
} else if (Regexp::match(&mr, cl, L" *css: *(%c*?) *")) {
|
||||
@<Act on a CSS tweak@>;
|
||||
} else if (Regexp::match(&mr, cl, L" *index: *(%c*?) *")) {
|
||||
|
@ -397,15 +389,20 @@ taste). In a multiple-line value, each line is terminated with a newline.
|
|||
|
||||
@<Set an instructions option@> =
|
||||
if (Str::eq_wide_string(key, L"alphabetization")) {
|
||||
if (Str::eq_wide_string(val, L"word-by-word")) { settings->index_alphabetisation_algorithm = WORD_ALPHABETIZATION; }
|
||||
else if (Str::eq_wide_string(val, L"letter-by-letter")) { settings->index_alphabetisation_algorithm = LETTER_ALPHABETIZATION; }
|
||||
if (Str::eq_wide_string(val, L"word-by-word"))
|
||||
settings->index_alphabetisation_algorithm = WORD_ALPHABETIZATION;
|
||||
else if (Str::eq_wide_string(val, L"letter-by-letter"))
|
||||
settings->index_alphabetisation_algorithm = LETTER_ALPHABETIZATION;
|
||||
else Errors::in_text_file("no such alphabetization", tfp);
|
||||
}
|
||||
else if (Str::eq_wide_string(key, L"assume_Public_Library")) {
|
||||
settings->assume_Public_Library = Instructions::set_yn(key, val, tfp); }
|
||||
else if (Str::eq_wide_string(key, L"change_logs_directory")) { settings->change_logs_folder = Instructions::set_path(val, settings); }
|
||||
else if (Str::eq_wide_string(key, L"contents_leafname")) { settings->contents_leafname = Str::duplicate(val); }
|
||||
else if (Str::eq_wide_string(key, L"contents_expandable")) { settings->contents_expandable = Instructions::set_yn(key, val, tfp); }
|
||||
else if (Str::eq_wide_string(key, L"assume_Public_Library"))
|
||||
settings->assume_Public_Library = Instructions::set_yn(key, val, tfp);
|
||||
else if (Str::eq_wide_string(key, L"change_logs_directory"))
|
||||
settings->change_logs_folder = Instructions::set_path(val, settings);
|
||||
else if (Str::eq_wide_string(key, L"contents_leafname"))
|
||||
settings->contents_leafname = Str::duplicate(val);
|
||||
else if (Str::eq_wide_string(key, L"contents_expandable"))
|
||||
settings->contents_expandable = Instructions::set_yn(key, val, tfp);
|
||||
else if (Str::eq_wide_string(key, L"css_source_file")) { settings->css_source_file = Instructions::set_file(val, settings); }
|
||||
else if (Str::eq_wide_string(key, L"definitions_filename")) { settings->definitions_filename = Instructions::set_file(val, settings); }
|
||||
else if (Str::eq_wide_string(key, L"definitions_index_filename")) {
|
||||
|
@ -452,7 +449,7 @@ taste). In a multiple-line value, each line is terminated with a newline.
|
|||
settings->link_to_extensions_index = Str::duplicate(val); }
|
||||
else if (Str::eq_wide_string(key, L"manifest_leafname")) { settings->manifest_leafname = Str::duplicate(val); }
|
||||
else if (Str::eq_wide_string(key, L"navigation")) {
|
||||
settings->navigation = Gadgets::parse(val);
|
||||
settings->navigation = Nav::parse(val);
|
||||
if (settings->navigation == NULL) Errors::in_text_file("no such navigation mode", tfp);
|
||||
}
|
||||
else if (Str::eq_wide_string(key, L"retina_images")) {
|
||||
|
@ -487,7 +484,7 @@ taste). In a multiple-line value, each line is terminated with a newline.
|
|||
}
|
||||
settings->contents_expandable = FALSE;
|
||||
settings->images_copy = 1;
|
||||
settings->navigation = Gadgets::for_ebook(settings->navigation);
|
||||
settings->navigation = Nav::for_ebook(settings->navigation);
|
||||
settings->format = HTML_FORMAT;
|
||||
settings->XHTML = TRUE;
|
||||
settings->ebook = Epub::new(I"untitled ebook", "");
|
||||
|
@ -511,7 +508,7 @@ taste). In a multiple-line value, each line is terminated with a newline.
|
|||
}
|
||||
|
||||
if (settings->format == PLAIN_FORMAT)
|
||||
settings->navigation = Gadgets::for_plain_text(settings->navigation);
|
||||
settings->navigation = Nav::for_plain_text(settings->navigation);
|
||||
|
||||
@<Declare the format and wrapper as symbols@> =
|
||||
if (settings->wrapper == WRAPPER_epub) Symbols::declare_symbol(I"EPUB");
|
||||
|
@ -526,7 +523,7 @@ Note the Unix-style conveniences for pathnames: an initial |~| means the
|
|||
home folder, |~~| means the book folder.
|
||||
|
||||
=
|
||||
pathname *Instructions::set_path(text_stream *val, indoc_instructions *settings) {
|
||||
pathname *Instructions::set_path(text_stream *val, settings_block *settings) {
|
||||
if (Str::get_at(val, 0) == '~') {
|
||||
if (Str::get_at(val, 1) == '~') {
|
||||
if ((Str::get_at(val, 2) == '/') || (Str::get_at(val, 2) == FOLDER_SEPARATOR)) {
|
||||
|
@ -549,7 +546,7 @@ pathname *Instructions::set_path(text_stream *val, indoc_instructions *settings)
|
|||
}
|
||||
|
||||
@ =
|
||||
filename *Instructions::set_file(text_stream *val, indoc_instructions *settings) {
|
||||
filename *Instructions::set_file(text_stream *val, settings_block *settings) {
|
||||
if (Str::get_at(val, 0) == '~') {
|
||||
if (Str::get_at(val, 1) == '~') {
|
||||
if ((Str::get_at(val, 2) == '/') || (Str::get_at(val, 2) == FOLDER_SEPARATOR)) {
|
||||
|
@ -605,6 +602,18 @@ int Instructions::set_yn(text_stream *key, text_stream *val, text_file_position
|
|||
@ For ebooks only.
|
||||
|
||||
=
|
||||
typedef struct dc_metadatum {
|
||||
struct text_stream *dc_key;
|
||||
struct text_stream *dc_val;
|
||||
MEMORY_MANAGEMENT
|
||||
} dc_metadatum;
|
||||
|
||||
void Instructions::create_ebook_metadata(text_stream *key, text_stream *value) {
|
||||
dc_metadatum *dcm = CREATE(dc_metadatum);
|
||||
dcm->dc_key = Str::duplicate(key);
|
||||
dcm->dc_val = Str::duplicate(value);
|
||||
}
|
||||
|
||||
void Instructions::apply_ebook_metadata(ebook *E) {
|
||||
dc_metadatum *dcm;
|
||||
LOOP_OVER(dcm, dc_metadatum) {
|
||||
|
|
|
@ -2,39 +2,15 @@
|
|||
|
||||
The top level of the program.
|
||||
|
||||
@h Definitions.
|
||||
|
||||
@ Indoc is one of the earliest Inform tools, and it spent much of its
|
||||
life as a hacky Perl script: like all too many quick-fix Perl scripts, it
|
||||
was still in use ten years later. In 2012, I spent some time tidying it up
|
||||
to generate better HTML, and moved it over to literate code. This took an
|
||||
exasperatingly long time, not least because the original had produced
|
||||
typically sloppy turn-of-the-century HTML, with tables for layout and
|
||||
no CSS, and with many now-deprecated tags and elements. The 2012 edition,
|
||||
by contrast, needed to produce validatable XHTML 1.1 Strict in order to
|
||||
make EPUBs which read roughly correctly in today's ebook-readers, and
|
||||
when they call this Strict they're not kidding. It took something like
|
||||
four weeks of spare evenings.
|
||||
|
||||
Just as I was finishing up, the programmer and commentator John Siracusa
|
||||
described an almost identical web-content-and-ebook generation task on his
|
||||
podcast (Hypercritical 85): "My solution for this is... I was trying to
|
||||
think of a good analogy for what happens when you're a programmer and you
|
||||
have this sort of task in front of you. Is it, the cobbler's children have
|
||||
no shoes? ... You would expect someone who is a programmer to make some
|
||||
awesome system which would generate these three things. But when you're a
|
||||
programmer, you have the ability to do whatever you want really, really
|
||||
quickly in the crappiest possible way... And that's what I did. I wrote a
|
||||
series of incredibly disgusting Perl scripts."
|
||||
|
||||
This made me feel better. Nevertheless, in 2016, I rewrote in C.
|
||||
|
||||
@h Nutshell.
|
||||
We turn the source matter, "rawtext", into a batch of output files using the
|
||||
chosen format, a process we'll call "rendering". We do this in two passes.
|
||||
|
||||
=
|
||||
indoc_instructions *indoc_settings = NULL;
|
||||
pathname *path_to_indoc = NULL; /* where we are installed */
|
||||
pathname *path_to_indoc_materials = NULL; /* the materials pathname */
|
||||
|
||||
settings_block *indoc_settings = NULL;
|
||||
int no_volumes = 0;
|
||||
int no_examples = 0;
|
||||
|
||||
|
@ -61,10 +37,13 @@ int main(int argc, char **argv) {
|
|||
|
||||
@<Start up indoc@> =
|
||||
PRINT("indoc [[Version Number]] (Inform Tools Suite)\n");
|
||||
Gadgets::start();
|
||||
Nav::start();
|
||||
Symbols::start_up_symbols();
|
||||
indoc_settings = Instructions::clean_slate();
|
||||
Configuration::read_command_line(argc, argv, indoc_settings);
|
||||
path_to_indoc = Pathnames::installation_path("INDOC_PATH", I"indoc");
|
||||
if (indoc_settings->verbose_mode) PRINT("Installation path is %p\n", path_to_indoc);
|
||||
path_to_indoc_materials = Pathnames::subfolder(path_to_indoc, I"Materials");
|
||||
if (indoc_settings->wrapper == WRAPPER_epub) {
|
||||
HTMLUtilities::image_URL(NULL,
|
||||
Filenames::get_leafname(indoc_settings->book_cover_image));
|
||||
|
@ -97,7 +76,7 @@ section by section.
|
|||
volume *V;
|
||||
text_stream *TO = NULL;
|
||||
LOOP_OVER(V, volume) TO = Rawtext::process_large_rawtext_file(TO, V);
|
||||
Gadgets::render_navigation_contents_files();
|
||||
Nav::render_navigation_contents_files();
|
||||
|
||||
@ The following functions here are for use only when compiling documentation
|
||||
to go inside the Inform user interface application.
|
||||
|
|
|
@ -213,7 +213,7 @@ all CSS files, but here we know that |base.css| is tidily written.
|
|||
@ =
|
||||
void CSS::expand_IMAGES(text_stream *text) {
|
||||
match_results mr = Regexp::create_mr();
|
||||
if (indoc_settings->suppress_fonts == 1) {
|
||||
if (indoc_settings->suppress_fonts) {
|
||||
while (Regexp::match(&mr, text, L"(%c*?)font-family:(%c*?);(%c*)")) {
|
||||
text_stream *L = mr.exp[0], *M = NULL, *R = mr.exp[2];
|
||||
if (Regexp::match(NULL, mr.exp[1], L"%c*monospace%c*")) M = I"___MONOSPACE___";
|
||||
|
|
|
@ -85,11 +85,11 @@ routine which doesn't surround the text with navigational gadgets and headings.
|
|||
text_stream *Renderer::render_block(OUTPUT_STREAM, volume *V, section *S) {
|
||||
OUT = Renderer::formatted_file_must_be(OUT, V, S);
|
||||
|
||||
Gadgets::render_navigation_top(OUT, V, S);
|
||||
Nav::render_navigation_top(OUT, V, S);
|
||||
Renderer::render_text_of_block(OUT, V, S);
|
||||
Gadgets::render_navigation_middle(OUT, V, S);
|
||||
Nav::render_navigation_middle(OUT, V, S);
|
||||
@<Render the examples below the text of the block@>;
|
||||
Gadgets::render_navigation_bottom(OUT, V, S);
|
||||
Nav::render_navigation_bottom(OUT, V, S);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
@ -102,14 +102,14 @@ text_stream *Renderer::render_block(OUTPUT_STREAM, volume *V, section *S) {
|
|||
if (E->example_displayed_at_section[V->allocation_id] == S) {
|
||||
no_examples_rendered_here++;
|
||||
if (no_examples_rendered_here == 1)
|
||||
Gadgets::render_navigation_example_top(OUT, V, S);
|
||||
Nav::render_navigation_example_top(OUT, V, S);
|
||||
@<Render the example here@>;
|
||||
if (indoc_settings->examples_mode == EXMODE_open_internal) HTMLUtilities::ruled_line(OUT);
|
||||
}
|
||||
}
|
||||
|
||||
if (no_examples_rendered_here > 0)
|
||||
Gadgets::render_navigation_example_bottom(OUT, V, S);
|
||||
Nav::render_navigation_example_bottom(OUT, V, S);
|
||||
|
||||
@ Examples need to connect with particular sections of documentation, but
|
||||
they do so by title, not by block number, to protect them from renumbering
|
||||
|
|
|
@ -35,7 +35,7 @@ text_stream *IndexUtilities::open_page(text_stream *title, text_stream *leafname
|
|||
}
|
||||
DISCARD_TEXT(head);
|
||||
|
||||
Gadgets::render_navigation_index_top(OUT, leafname, title);
|
||||
Nav::render_navigation_index_top(OUT, leafname, title);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ heading includes these anyway.
|
|||
|
||||
=
|
||||
navigation_design *Architect::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"architect", FALSE, FALSE);
|
||||
navigation_design *ND = Nav::new(I"architect", FALSE, FALSE);
|
||||
ND->columnar = TRUE;
|
||||
ND->contents_body_class = I"paper architectpapertint";
|
||||
METHOD_ADD(ND, RENDER_SECTION_TITLE_MTID, Architect::architect_section_title);
|
||||
|
|
|
@ -7,7 +7,7 @@ no navigational features at all.
|
|||
|
||||
=
|
||||
navigation_design *Lacuna::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"lacuna", FALSE, TRUE);
|
||||
navigation_design *ND = Nav::new(I"lacuna", FALSE, TRUE);
|
||||
METHOD_ADD(ND, RENDER_CHAPTER_TITLE_MTID, Lacuna::lacuna_chapter_title);
|
||||
METHOD_ADD(ND, RENDER_SECTION_TITLE_MTID, Lacuna::lacuna_section_title);
|
||||
return ND;
|
||||
|
|
|
@ -6,7 +6,7 @@ The "midnight" style of navigational gadgets.
|
|||
|
||||
=
|
||||
navigation_design *Midnight::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"midnight", FALSE, FALSE);
|
||||
navigation_design *ND = Nav::new(I"midnight", FALSE, FALSE);
|
||||
ND->columnar = TRUE;
|
||||
METHOD_ADD(ND, RENDER_SECTION_TITLE_MTID, Midnight::midnight_section_title);
|
||||
METHOD_ADD(ND, RENDER_INDEX_TOP_MTID, Midnight::midnight_navigation_index_top);
|
||||
|
@ -197,7 +197,7 @@ void Midnight::write_contents_page(navigation_design *self, volume *V) {
|
|||
TEMPORARY_TEXT(title);
|
||||
WRITE_TO(title, "Contents");
|
||||
@<Begin the HTML page for the contents@>;
|
||||
Gadgets::navigation_contents_heading(OUT, V);
|
||||
Nav::navigation_contents_heading(OUT, V);
|
||||
|
||||
for (int column = 0; column < no_volumes; column++)
|
||||
if ((column == V->allocation_id) || (self->columnar))
|
||||
|
|
|
@ -6,7 +6,7 @@ The "roadsign" style of navigational gadgets.
|
|||
|
||||
=
|
||||
navigation_design *Roadsign::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"roadsign", TRUE, FALSE);
|
||||
navigation_design *ND = Nav::new(I"roadsign", TRUE, FALSE);
|
||||
METHOD_ADD(ND, RENDER_VOLUME_TITLE_MTID, Roadsign::roadsign_volume_title);
|
||||
METHOD_ADD(ND, RENDER_CHAPTER_TITLE_MTID, Roadsign::roadsign_chapter_title);
|
||||
METHOD_ADD(ND, RENDER_SECTION_TITLE_MTID, Roadsign::roadsign_section_title);
|
||||
|
|
|
@ -7,7 +7,7 @@ of "midnight".
|
|||
|
||||
=
|
||||
navigation_design *Twilight::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"twilight", FALSE, FALSE);
|
||||
navigation_design *ND = Nav::new(I"twilight", FALSE, FALSE);
|
||||
ND->simplified_examples = TRUE;
|
||||
ND->simplified_letter_rows = TRUE;
|
||||
METHOD_ADD(ND, RENDER_CHAPTER_TITLE_MTID, Twilight::twilight_chapter_title);
|
||||
|
|
|
@ -6,7 +6,7 @@ The "unsigned" style of navigational gadgets.
|
|||
|
||||
=
|
||||
navigation_design *Unsigned::create(void) {
|
||||
navigation_design *ND = Gadgets::new(I"unsigned", TRUE, FALSE);
|
||||
navigation_design *ND = Nav::new(I"unsigned", TRUE, FALSE);
|
||||
METHOD_ADD(ND, RENDER_VOLUME_TITLE_MTID, Unsigned::unsigned_volume_title);
|
||||
METHOD_ADD(ND, RENDER_CHAPTER_TITLE_MTID, Unsigned::unsigned_chapter_title);
|
||||
METHOD_ADD(ND, RENDER_SECTION_TITLE_MTID, Unsigned::unsigned_section_title);
|
||||
|
|
|
@ -1,221 +0,0 @@
|
|||
[Gadgets::] Navigational Gadgets.
|
||||
|
||||
To render linking gadgets in HTML forms of documentation, so that
|
||||
the reader can navigate from section to section.
|
||||
|
||||
@h
|
||||
|
||||
=
|
||||
typedef struct navigation_design {
|
||||
struct text_stream *codename;
|
||||
int ebook_friendly;
|
||||
int plain_friendly;
|
||||
int columnar;
|
||||
int simplified_examples;
|
||||
int simplified_letter_rows;
|
||||
struct text_stream *contents_body_class;
|
||||
METHOD_CALLS
|
||||
MEMORY_MANAGEMENT
|
||||
} navigation_design;
|
||||
|
||||
navigation_design *Gadgets::new(text_stream *code, int e, int p) {
|
||||
navigation_design *ND = CREATE(navigation_design);
|
||||
ND->codename = Str::duplicate(code);
|
||||
ND->ebook_friendly = e;
|
||||
ND->plain_friendly = p;
|
||||
ND->columnar = FALSE;
|
||||
ND->simplified_examples = FALSE;
|
||||
ND->simplified_letter_rows = FALSE;
|
||||
ND->contents_body_class = I"paper midnightpapertint";
|
||||
ND->methods = Methods::new_set();
|
||||
return ND;
|
||||
}
|
||||
|
||||
void Gadgets::start(void) {
|
||||
Midnight::create(); /* needs to be created first */
|
||||
Twilight::create();
|
||||
Architect::create();
|
||||
Roadsign::create(); /* needs to be created before unsigned */
|
||||
Unsigned::create();
|
||||
Lacuna::create();
|
||||
}
|
||||
|
||||
navigation_design *Gadgets::default(void) {
|
||||
return FIRST_OBJECT(navigation_design);
|
||||
}
|
||||
|
||||
navigation_design *Gadgets::for_ebook(navigation_design *current) {
|
||||
if (current->ebook_friendly) return current;
|
||||
navigation_design *ND;
|
||||
LOOP_OVER(ND, navigation_design)
|
||||
if (ND->ebook_friendly)
|
||||
return ND;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
navigation_design *Gadgets::for_plain_text(navigation_design *current) {
|
||||
if (current->plain_friendly) return current;
|
||||
navigation_design *ND;
|
||||
LOOP_OVER(ND, navigation_design)
|
||||
if (ND->plain_friendly)
|
||||
return ND;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
navigation_design *Gadgets::parse(text_stream *val) {
|
||||
navigation_design *ND;
|
||||
LOOP_OVER(ND, navigation_design)
|
||||
if (Str::eq(val, ND->codename))
|
||||
return ND;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@h Top.
|
||||
At the front end of a section, before any of its text.
|
||||
|
||||
@e RENDER_VOLUME_TITLE_MTID
|
||||
@e RENDER_CHAPTER_TITLE_MTID
|
||||
@e RENDER_SECTION_TITLE_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_VOLUME_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V)
|
||||
VMETHOD_TYPE(RENDER_CHAPTER_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, chapter *C)
|
||||
VMETHOD_TYPE(RENDER_SECTION_TITLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, chapter *C, section *S)
|
||||
|
||||
void Gadgets::render_navigation_top(OUTPUT_STREAM, volume *V, section *S) {
|
||||
if (V->sections[0] == S) VMETHOD_CALL(indoc_settings->navigation, RENDER_VOLUME_TITLE_MTID, OUT, V);
|
||||
|
||||
chapter *C = S->begins_which_chapter;
|
||||
if (C) VMETHOD_CALL(indoc_settings->navigation, RENDER_CHAPTER_TITLE_MTID, OUT, V, C);
|
||||
|
||||
if (indoc_settings->html_for_Inform_application)
|
||||
@<Write HTML comments giving the Inform user interface search assistance@>;
|
||||
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_SECTION_TITLE_MTID, OUT, V, C, S);
|
||||
}
|
||||
|
||||
@<Write HTML comments giving the Inform user interface search assistance@> =
|
||||
WRITE("\n");
|
||||
TEMPORARY_TEXT(comment);
|
||||
WRITE_TO(comment, "SEARCH TITLE \"%S\"", S->unlabelled_title);
|
||||
HTML::comment(OUT, comment);
|
||||
Str::clear(comment);
|
||||
WRITE_TO(comment, "SEARCH SECTION \"%S\"", S->label);
|
||||
HTML::comment(OUT, comment);
|
||||
Str::clear(comment);
|
||||
WRITE_TO(comment, "SEARCH SORT \"%S\"", S->sort_code);
|
||||
HTML::comment(OUT, comment);
|
||||
DISCARD_TEXT(comment);
|
||||
|
||||
@h Index top.
|
||||
And this is a variant for index pages, such as the index of examples.
|
||||
|
||||
@e RENDER_INDEX_TOP_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_INDEX_TOP_MTID, navigation_design *ND, text_stream *OUT, text_stream *filename, text_stream *title)
|
||||
|
||||
void Gadgets::render_navigation_index_top(OUTPUT_STREAM, text_stream *filename, text_stream *title) {
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_INDEX_TOP_MTID, OUT, filename, title);
|
||||
}
|
||||
|
||||
@h Middle.
|
||||
At the middle part, when the text is over, but before any example cues.
|
||||
|
||||
@e RENDER_NAV_MIDDLE_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_NAV_MIDDLE_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)
|
||||
|
||||
void Gadgets::render_navigation_middle(OUTPUT_STREAM, volume *V, section *S) {
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_NAV_MIDDLE_MTID, OUT, V, S);
|
||||
}
|
||||
|
||||
@h Example top.
|
||||
This is reached before the first example is rendered, provided at least
|
||||
one example will be:
|
||||
|
||||
@e RENDER_EXAMPLE_TOP_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_EXAMPLE_TOP_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)
|
||||
|
||||
void Gadgets::render_navigation_example_top(OUTPUT_STREAM, volume *V, section *S) {
|
||||
|
||||
if (indoc_settings->format == HTML_FORMAT) {
|
||||
HTML::begin_div_with_class_S(OUT, I"bookexamples");
|
||||
HTML_OPEN_WITH("p", "class=\"chapterheading\"");
|
||||
}
|
||||
|
||||
if (indoc_settings->examples_granularity == CHAPTER_GRANULARITY) {
|
||||
chapter *C = S->in_which_chapter;
|
||||
WRITE("Examples from %S", C->chapter_full_title);
|
||||
} else if (indoc_settings->examples_granularity == BOOK_GRANULARITY) {
|
||||
WRITE("Examples");
|
||||
}
|
||||
|
||||
if (indoc_settings->format == HTML_FORMAT) {
|
||||
HTML_CLOSE("p");
|
||||
} else { WRITE("\n\n"); }
|
||||
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_EXAMPLE_TOP_MTID, OUT, V, S);
|
||||
}
|
||||
|
||||
@h Example bottom.
|
||||
Any closing ornament at the end of examples? This is reached after the
|
||||
last example is rendered, provided at least one example has been.
|
||||
|
||||
@e RENDER_EXAMPLE_BOTTOM_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_EXAMPLE_BOTTOM_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)
|
||||
|
||||
void Gadgets::render_navigation_example_bottom(OUTPUT_STREAM, volume *V, section *S) {
|
||||
if (indoc_settings->format == PLAIN_FORMAT) {
|
||||
WRITE("\n\n");
|
||||
}
|
||||
|
||||
if (indoc_settings->format == HTML_FORMAT) {
|
||||
if (indoc_settings->examples_mode != EXMODE_open_internal) { HTMLUtilities::ruled_line(OUT); }
|
||||
HTML::end_div(OUT);
|
||||
}
|
||||
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_EXAMPLE_BOTTOM_MTID, OUT, V, S);
|
||||
}
|
||||
|
||||
@h Bottom.
|
||||
At the end of the section, after any example cues and perhaps also example
|
||||
bodied. (In a section with no examples, this immediately follows the middle.)
|
||||
|
||||
@e RENDER_NAV_BOTTOM_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_NAV_BOTTOM_MTID, navigation_design *ND, text_stream *OUT, volume *V, section *S)
|
||||
|
||||
void Gadgets::render_navigation_bottom(OUTPUT_STREAM, volume *V, section *S) {
|
||||
if (indoc_settings->format == HTML_FORMAT) {
|
||||
HTML::comment(OUT, I"START IGNORE");
|
||||
}
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_NAV_BOTTOM_MTID, OUT, V, S);
|
||||
if (indoc_settings->format == HTML_FORMAT) {
|
||||
HTML::comment(OUT, I"END IGNORE");
|
||||
}
|
||||
}
|
||||
|
||||
@h Contents page.
|
||||
Midnight provides a contents page of its very own.
|
||||
|
||||
@e RENDER_CONTENTS_MTID
|
||||
@e RENDER_CONTENTS_HEADING_MTID
|
||||
|
||||
=
|
||||
VMETHOD_TYPE(RENDER_CONTENTS_MTID, navigation_design *ND)
|
||||
VMETHOD_TYPE(RENDER_CONTENTS_HEADING_MTID, navigation_design *ND, text_stream *OUT, volume *V)
|
||||
|
||||
void Gadgets::render_navigation_contents_files(void) {
|
||||
VMETHOD_CALLV(indoc_settings->navigation, RENDER_CONTENTS_MTID);
|
||||
}
|
||||
|
||||
void Gadgets::navigation_contents_heading(OUTPUT_STREAM, volume *V) {
|
||||
VMETHOD_CALL(indoc_settings->navigation, RENDER_CONTENTS_HEADING_MTID, OUT, V);
|
||||
}
|
|
@ -12,11 +12,16 @@ Build Date: 16 February 2019
|
|||
|
||||
Import: foundation
|
||||
|
||||
Preliminaries
|
||||
Introduction to Indoc
|
||||
Volumes and Instructions
|
||||
Documentation Markup
|
||||
|
||||
Chapter 1: Setting Up
|
||||
Basics
|
||||
Instructions
|
||||
Configuration
|
||||
Main
|
||||
Configuration
|
||||
Instructions
|
||||
Context Symbols
|
||||
|
||||
Chapter 2: Processing
|
||||
|
@ -34,7 +39,7 @@ Chapter 3: Indexing
|
|||
Examples Index
|
||||
|
||||
Chapter 4: Navigation Styles
|
||||
Navigational Gadgets
|
||||
Navigational Designs
|
||||
Codename Lacuna
|
||||
Codename Midnight
|
||||
Codename Architect
|
||||
|
|
5
indoc/Preliminaries/Documentation Markup.w
Normal file
5
indoc/Preliminaries/Documentation Markup.w
Normal file
|
@ -0,0 +1,5 @@
|
|||
Documentation Markup.
|
||||
|
||||
How to mark up the plain-text source for Inform documentation.
|
||||
|
||||
@h Stuff.
|
93
indoc/Preliminaries/Introduction to Indoc.w
Normal file
93
indoc/Preliminaries/Introduction to Indoc.w
Normal file
|
@ -0,0 +1,93 @@
|
|||
Introduction to Indoc.
|
||||
|
||||
What Indoc is, and its limited but complicated uses.
|
||||
|
||||
@ Intest is a command line tool for generating (mainly) HTML or EPUB format
|
||||
documentation. A million of those have been written, and Indoc has no
|
||||
ambition to replace them. It is needed because Inform 7's documentation
|
||||
source consists of many small text files with idiosyncratic markup, while
|
||||
its formatted HTML version needs to be indexed in elaborate ways.
|
||||
|
||||
Indoc is a purely command-line tool, used in building Inform but not in
|
||||
running it: it's not present in the Inform UI apps.
|
||||
|
||||
If you have compiled the standard distribution of the command-line tools
|
||||
for Inform then the Indoc executable will be at |indoc/Tangled/indoc/|.
|
||||
Usage is very simple:
|
||||
|
||||
|$ indoc/Tangled/indoc [OPTIONS] TARGET|
|
||||
|
||||
By default, Indoc reads its source documentation from a direction called
|
||||
|Documentation| (with respect to the current working directory); the
|
||||
option |-from X| changes this path to |X|, but in this manual we'll call
|
||||
it |Documentation|.
|
||||
|
||||
In addition to documentation files, which will be described later, Indoc
|
||||
also reads instruction files. At minimum it will read
|
||||
|
||||
|Documentation/indoc-instructions.txt|
|
||||
|
||||
but the option |-instructions X| causes it to read |X| as well. Instructions
|
||||
files mainly specify indexing notations, or CSS styles, or miscellaneous
|
||||
settings, but they group these under named "targets". For example:
|
||||
|
||||
|windows_app {|
|
||||
| ...|
|
||||
|}|
|
||||
|
||||
declares a target called |windows_app|. (This is the form of HTML needed for
|
||||
use inside the Windows UI application for Inform.) The idea here is that
|
||||
there is probably no single form of HTML needed -- it will be needed in
|
||||
subtly different versions for different platforms: inside the app, as a
|
||||
stand-alone website, inside an Epub ebook. These different forms are
|
||||
called "targets". On any given run, Indoc generates a single target --
|
||||
the one named on the command line.
|
||||
|
||||
The HTML produced is placed, by default, in the directory:
|
||||
|
||||
|Documentation/Output|
|
||||
|
||||
This can be changed with the option |-to X|.
|
||||
|
||||
@ When it runs, Indoc needs to know where it is installed in the file
|
||||
system. There is no completely foolproof, cross-platform way to know this
|
||||
(on some Unixes, a program cannot determine its own location), so Indoc
|
||||
decides by the following set of rules:
|
||||
|
||||
(a) If the user, at the command line, specified |-at P|, for some path
|
||||
|P|, then we use that.
|
||||
(b) Otherwise, if the host operating system can indeed tell us where the
|
||||
executable is, we use that. This is currently implemented only on MacOS,
|
||||
Windows and Linux.
|
||||
(c) Otherwise, if the environment variable |$INDOC_PATH| exists and is
|
||||
non-empty, we use that.
|
||||
(d) And if all else fails, we assume that the location is |indoc|, with
|
||||
respect to the current working directory.
|
||||
|
||||
If you're not sure what Indoc has decided and suspect it may be wrong,
|
||||
running Indoc with the |-verbose| switch will cause it to print its belief
|
||||
about its location as it starts up.
|
||||
|
||||
@ As a program, Indoc began as a rat's nest of Perl in 2002, and you can still
|
||||
see where the rats used to live. Like all too many quick-fix Perl scripts, it
|
||||
was still in use ten years later. In 2012, I spent some time tidying it up to
|
||||
generate better HTML, and made it a web (that is, a literate program). The
|
||||
original had produced typically sloppy turn-of-the-century HTML, with tables
|
||||
for layout and no CSS, and with many now-deprecated tags and elements. The
|
||||
2012 edition, by contrast, needed to produce validatable XHTML 1.1 Strict in
|
||||
order to make EPUBs which read roughly correctly in today's ebook-readers, and
|
||||
when they call this Strict they're not kidding. It took something like four
|
||||
weeks of spare evenings.
|
||||
|
||||
Just as I was finishing up, the programmer and commentator John Siracusa
|
||||
described a not dissimilar web-content-and-ebook generation task on his
|
||||
podcast (Hypercritical 85): "I was trying to think of a good analogy for what
|
||||
happens when you're a programmer and you have this sort of task in front of
|
||||
you. Is it, the cobbler's children have no shoes? ... You would expect someone
|
||||
who is a programmer to make some awesome system which would generate these
|
||||
three things. But when you're a programmer, you have the ability to do
|
||||
whatever you want really, really quickly in the crappiest possible way... And
|
||||
that's what I did. I wrote a series of incredibly disgusting Perl scripts."
|
||||
|
||||
This made me feel better. Nevertheless, in 2016, indoc was rewritten in C,
|
||||
and it received a further revision in 2019.
|
321
indoc/Preliminaries/Volumes and Instructions.w
Normal file
321
indoc/Preliminaries/Volumes and Instructions.w
Normal file
|
@ -0,0 +1,321 @@
|
|||
Volumes and Instructions.
|
||||
|
||||
Dual- versus single-volume mode, and how to write instructions files.
|
||||
|
||||
@h Model.
|
||||
Conceptually, an Indoc project has either one or two volumes. The source for
|
||||
each volume is a single UTF-8 encoded plain text file. In the core Inform
|
||||
repository, there are two volumes, with the files being
|
||||
|
||||
|Documentation/Writing with Inform.txt|
|
||||
|Documentation/The Recipe Book.txt|
|
||||
|
||||
These are independent books, with individual titles. It would seem simpler
|
||||
just to make them two different Indoc projects, but in dual-volume mode,
|
||||
Indoc can generate joint contents pages, and provide crosswise HTML links
|
||||
between the two volumes.
|
||||
|
||||
The project can also include a number of "Examples", each being a single
|
||||
text file such as:
|
||||
|
||||
|Documentation/Examples/Prague.txt|
|
||||
|
||||
which is the source for an Inform example called "The Prague Job".
|
||||
(These same text files are also used by Intest to test that all of the code
|
||||
samples included in the Inform documentation actually work as claimed.)
|
||||
There can be any number of examples, including none; Inform currently has 468.
|
||||
|
||||
Each volume is divided into a series of chapters, and each chapter into a
|
||||
series of sections. Examples are always placed at the ends of sections;
|
||||
note that in dual-volume mode, examples are (mostly) present in both volumes,
|
||||
giving them two different locations. Thus, "The Prague Job" appears in section
|
||||
"More general linkages" of chapter "Scenes" of volume "Writing with Inform",
|
||||
and also in section "Scripted Scenes" of chapter "Time and Plot" of volume
|
||||
"The Recipe Book".
|
||||
|
||||
@h Project instructions.
|
||||
The main instructions file for an Indoc project is, as noted earlier, at:
|
||||
|
||||
|Documentation/indoc-instructions.txt|
|
||||
|
||||
An instruction file is a UTF-8 encoded plain text file. Single instructions
|
||||
occupy single lines (i.e., line breaks are significant). A white-space line,
|
||||
or a line whose first non-white-space character is a |#|, are ignored.
|
||||
|
||||
The file should begin by specifying one or two volumes, and then, if they
|
||||
will contain Examples in the above sense, by giving the special |examples|
|
||||
instruction. Inform opens thus:
|
||||
|
||||
|volume: Writing with Inform|
|
||||
|volume: The Inform Recipe Book (RB) = The Recipe Book.txt|
|
||||
|examples|
|
||||
|
||||
But a simpler, single-volume project might have just:
|
||||
|
||||
|volume: Pandemonium 2.0 for Fun and Profit|
|
||||
|
||||
Each volume has a title, and Indoc automatically generates an abbreviation
|
||||
for it: by default, it takes the capital letters from the title, so that it
|
||||
abbreviates "Writing with Inform" to WI. That same method would have made
|
||||
turned "The Inform Recipe Book" into TIRB, but because we didn't want that,
|
||||
we supplied our own abbreviation RB instead.
|
||||
|
||||
The third, also optional, part of a |volume| instruction specifies the
|
||||
leafname of the documentation source file for it. By default, this will be
|
||||
the title plus |.txt|: for example, |Writing with Inform.txt|. But we can
|
||||
use |= X| to specify that it should be |X| instead.
|
||||
|
||||
Two other project instructions exist:
|
||||
|
||||
If the project will contain images, then they will be looked for in a list
|
||||
of places. Top of the list is a directory internal to Indoc which includes
|
||||
some navigation icons such as |arrow-up.png|. The instruction |images: X|
|
||||
adds the directory |X| to this source list.
|
||||
|
||||
Lastly, the cover image for the project can be specified with an instruction
|
||||
such as:
|
||||
|
||||
|cover: combined_cover.png|
|
||||
|
||||
This specifies a leafname which must exist in one of the image sources
|
||||
mentioned above.
|
||||
|
||||
@h Durham Core metadata.
|
||||
If the project needs to generate Epub books, then these will need to have
|
||||
some basic DC ("Durham Core") metadata supplied. For example:
|
||||
|
||||
|dc:title: Inform - A Design System for Interactive Fiction|
|
||||
|dc:creator: Graham Nelson and Emily Short|
|
||||
|dc:subject: Interactive Fiction|
|
||||
|dc:identifier: wwi-rb-combined|
|
||||
|
||||
The instruction |dc:KEY: VALUE| supplies a DC key-value pair.
|
||||
|
||||
@h Targets.
|
||||
The instructions file typically begins as above, but then goes into a
|
||||
block of general settings or instructions (for which see below); and
|
||||
eventually gets around to describing one or more targets. A target
|
||||
looks like so:
|
||||
|
||||
|IDENTIFIER {|
|
||||
| ...|
|
||||
|}|
|
||||
|
||||
where |IDENTIFIER| is its name. Targets, as noted in the introduction,
|
||||
are different forms of the documentation we might need to produce: Inform,
|
||||
for example, has targets called |plain|, |website|, |linux_app| and so on.
|
||||
What's important here is not that these are written to different locations
|
||||
on disc (though they are) but that they have finicky little differences
|
||||
in settings. The |...| stretch of lines can specify these. For example:
|
||||
|
||||
|ebook {|
|
||||
| granularity = 2|
|
||||
| examples_mode = open|
|
||||
| follow: epub-css-tweaks.txt|
|
||||
|}|
|
||||
|
||||
makes two specific settings and one instruction, all applying only for the
|
||||
target |ebook|.
|
||||
|
||||
@h Symbols.
|
||||
The instruction |declare: SYMBOL| creates the symbol |SYMBOL|. These exist
|
||||
so that we can mark certain paragraphs of documentation as being present in
|
||||
only some of the targets.
|
||||
|
||||
For example, we might want Linux installation instructions to appear only
|
||||
in the Linux version of a manual. To do that, we'll need the symbol:
|
||||
|
||||
|linux_app {|
|
||||
| ...|
|
||||
| declare: Linux|
|
||||
| ...|
|
||||
|}|
|
||||
|
||||
In the documentation, we could then mark up a paragraph like so:
|
||||
|
||||
|{Linux:}To install, first...|
|
||||
|
||||
The symbol |indoc| is always declared, but by default no other symbols are.
|
||||
Lastly, |undeclare: SYMBOL| removes a symbol.
|
||||
|
||||
@h Other instructions.
|
||||
|follow: I| tells Indoc to follow the instructions file |I|. This works
|
||||
rather like |#include| in C, or similar languages. If the |follow:| is
|
||||
included inside a target block, then it affects only that target. On
|
||||
other targets, the file |I| won't even be opened, and need never exist.
|
||||
|
||||
|css:| specifies additional CSS (Cascading Style Sheet) styling. This
|
||||
will be needed only if, for example, unusual indexing features are used,
|
||||
in which different categories of index entry need different visual styling.
|
||||
For example,
|
||||
|
||||
|css: span.indextitle ++ {|
|
||||
| font-style: italic;|
|
||||
|}|
|
||||
|
||||
Here the material between the braces is pure CSS, not Indoc syntax. The
|
||||
notation |++| here tells Indoc that an entirely new CSS style is being
|
||||
created; |+| would supply new lines to an existing style.
|
||||
|
||||
|index: NOTATION = CATEGORY OPTION| defines a new indexing markup notation;
|
||||
for example,
|
||||
|
||||
|index: ^{@headword} = name (invert)|
|
||||
|
||||
says that markup notations like |^{@Andrew Plotkin}| put a name into the index,
|
||||
which should be an index entry of category |name|, and should be inverted,
|
||||
in that it will be alphabetised under "Plotkin, Andrew". The text |headword|
|
||||
in the prototype is where the entry text should appear in the notation.
|
||||
|
||||
@h Miscellaneous settings.
|
||||
There are a great many of these, but most are set to sensible defaults,
|
||||
and it is not compulsory to set any of them. Lines such as
|
||||
|
||||
|SETTING = VALUE|
|
||||
|
||||
change the default settings if need be. Here is an A-Z list; they're really
|
||||
too miscellaneous to be grouped usefully by subject matter.
|
||||
|
||||
|alphabetization| sets the index sorting algorithm. The default is
|
||||
|letter-by-letter|; the alternative is |word-by-word|. The difference is
|
||||
that letter-by-letter would ignore word divisions and sort in the order
|
||||
"peach", "peachpit", "peach tree"; whereas word-by-word would go for
|
||||
"peach", "peach tree", "peachpit".
|
||||
|
||||
|assume_Public_Library| can be |yes| or |no|. The default is |no|. This
|
||||
specifies whether special HTML links to the Public Library will be valid;
|
||||
outside of Inform UI apps, the answer is definitely no.
|
||||
|
||||
|change_logs_directory| is the path to a directory holding Inform release
|
||||
change log files. By default, this will be |Documentation/Change Logs|.
|
||||
|
||||
|contents_leafname| is the (unextended) leafname to give the HTML contents
|
||||
page. The default is |index|.
|
||||
|
||||
|contents_expandable| can be |yes| or |no|. The default is |no|. This sets
|
||||
whether Javascript-powered "expand" buttons are to be used in the contents
|
||||
page, and has effect only on the Midnight navigation design.
|
||||
|
||||
|css_source_file| is the filename of the CSS style sheet to use. The default
|
||||
is the |base.css| file included in the Indoc distribution.
|
||||
|
||||
|definitions_filename| is the filename to use if you would like Indoc to
|
||||
output a special file of Inform phrase definitions, for use by Inform itself
|
||||
when it generates indexes. The default for this is |definitions.html|. This
|
||||
has nothing to do with the |definitions_index_filename|.
|
||||
|
||||
|definitions_index_filename| is the leafname to use for the General Index
|
||||
in the documentation. The default is |general_index.html|. This
|
||||
has nothing to do with the |definitions_filename|.
|
||||
|
||||
|destination| is the directory into which output is generated. The default
|
||||
is |Documentation/Output|. Note that specifying |-to X| at the command line
|
||||
overrides this setting: if |-to| is used, |destination| is ignored.
|
||||
|
||||
|examples_directory| is the directory holding the Example files. The default
|
||||
is |Documentation/Examples|.
|
||||
|
||||
|examples_alphabetical_leafname| is the leafname to use for the alphabetical
|
||||
index of examples in the documentation. The default is |examples_alphabetical.html|.
|
||||
|
||||
|examples_granularity| is 1, 2, or 3. It can never be less than |granularity|,
|
||||
and by default is equal to it. It specifies where examples should appear:
|
||||
at the end of the relevant volume (1), chapter (2), or section (3).
|
||||
|
||||
|examples_mode| is |open| or |openable|, and is by default |open|. Open means
|
||||
that an example has its full contents visible by default; openable means that
|
||||
the contents are hidden behind a Javascript-powered button which causes them
|
||||
to be revealed.
|
||||
|
||||
|examples_numerical_leafname| is the leafname to use for the numerical
|
||||
index of examples in the documentation. The default is |examples_numerical.html|.
|
||||
|
||||
|examples_thematic_leafname| is the leafname to use for the thematic
|
||||
index of examples in the documentation. The default is |examples_thematic.html|.
|
||||
|
||||
|format| is the most important of all the settings, and is |HTML| or |text|,
|
||||
but by default |HTML| unless the target name is |plain|, in which case |text|.
|
||||
|
||||
|granularity| is 1, 2, or 3. The default is 3 unless the target is called
|
||||
|webpage| or |plain|, in which case it is 1. This specifies how much the
|
||||
documentation is broken down into pieces. 1 means "each volume in a single
|
||||
HTML file"; 2 means "each chapter", 3 means "each section". Low granularity
|
||||
means fewer but larger files, high granularity more but smaller files.
|
||||
|
||||
|html_for_Inform_application| can be |yes| or |no|. The default is |no|. This
|
||||
specifies whether the HTML is for use inside the Inform UI application, and
|
||||
can therefore use links with the special HTTP transports only available there.
|
||||
|
||||
|images_copy| can be |yes| or |no|. The default is |yes|. In this mode,
|
||||
any needed image files are copied into place into the |images_path|. (The
|
||||
alternative assumes they are already there, and should be used if |images_path|
|
||||
is some URL external to the HTML being generated.)
|
||||
|
||||
|images_path| is where the generated HTML expects to find its image files.
|
||||
The default is |~~/Images/|, where |~~| means the destination directory:
|
||||
that is, the default is a subdirectory called |Images| of the destination.
|
||||
|
||||
|inform_definitions_mode| can be |yes| or |no|. The default is |no|. This
|
||||
is cosmetic, and provides extra styling on lines of documentation giving the
|
||||
syntax for Inform phrases.
|
||||
|
||||
|javascript| can be |yes| or |no|. The default is |yes|. This indicates
|
||||
whetber Indoc is allowed to compile Javascript, or has to stick to inactive
|
||||
HTML.
|
||||
|
||||
|javascript_paste_method| can be |none|, |Andrew| or |David|. The default
|
||||
is |none|. The difference relates to how "paste Inform source" links are
|
||||
implemented inside the Inform application: |Andrew| mode is suitable for
|
||||
most platforms, but |David| is needed for Windows.
|
||||
|
||||
|link_to_extensions_index| is meaningful only if |html_for_Inform_application|
|
||||
is set, and specifies the URL of the Extensions index inside the app.
|
||||
|
||||
|manifest_leafname| is meaningful only if |html_for_Inform_application|
|
||||
is set, and is by default |manifest.txt|. This provides a cross-reference
|
||||
list of files generated by Indoc.
|
||||
|
||||
|navigation| is the design used for navigation links in the HTML produced.
|
||||
There are currently six designs, called |architect|, |lacuna|, |midnight|,
|
||||
|roadsign|, |twilight|, and |unsigned|; the default is |roadsign|, though
|
||||
inside the Inform applications, the design chosen is usually |architect|.
|
||||
If the format is |text| not |HTML|, then the design is always |lacuna|.
|
||||
|
||||
|retina_images| can be |yes| or |no|. The default is |no|. This indicates
|
||||
whether MacOS/iOS "retina" versions of the paste and create icons are
|
||||
available: |paste@2x.png| and |create@2x.png| respectively.
|
||||
|
||||
|support_creation| can be |yes| or |no|. The default is |no|. This indicates
|
||||
whether the Examples have a "create" button which creates a new Inform
|
||||
project demonstrating them in action; this can only be done in the UI apps,
|
||||
so it should always be |no| unless |html_for_Inform_application| is |yes|.
|
||||
|
||||
|suppress_fonts| can be |yes| or |no|. The default is |no|. If |yes|, this
|
||||
strips out lists of fonts to use in CSS, leaving only whether they are
|
||||
|monospace| or not.
|
||||
|
||||
|toc_granularity| is 1, 2, or 3. It can never be less than |granularity|,
|
||||
and by default is 3. It shows the level of detail in the table of contents: 1
|
||||
means volumes, 2 means volumes and chapters, 3 goes down to sections.
|
||||
|
||||
|top_and_tail| specifies a prototype HTML file to follow for the more
|
||||
important HTML pages generated by Indoc. The default is not to. If
|
||||
this exists, it can provide a surround for the HTML we generate -- for
|
||||
example, it can contain website-specific navigation, or a banner across
|
||||
the top. The prototype should somewhere include the text |[TEXT]|, and
|
||||
this will be replaced with whatever Indoc generates.
|
||||
|
||||
|top_and_tail_sections| is the same as |top_and_tail|, but for individual
|
||||
section files.
|
||||
|
||||
|treat_code_as_verbatim| can be |yes| or |no|. The default is |yes|. This
|
||||
affects the styling of marked-up code material in documentation. Without
|
||||
it, code markup is largely unavailable.
|
||||
|
||||
|wrapper| can be |EPUB|, |zip| or |none|. The default is |none|. The wrapper
|
||||
is put around the whole mass of generated HTML; |EPUB| makes the result an
|
||||
Epub-format ebook.
|
||||
|
||||
|XHTML| can be |yes| or |no|. The default is |no|. This forces the HTML we
|
||||
produce to conform to XHTML 1.1 Strict. If the |wrapper| is |EPUB|, then
|
||||
this is automatically set to |yes|.
|
Loading…
Reference in a new issue