1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-17 07:40:47 +03:00

Relocated some headings code

This commit is contained in:
Graham Nelson 2021-06-05 11:21:06 +01:00
parent 32dc947b8e
commit 654b0f38b5
8 changed files with 120 additions and 115 deletions

View file

@ -711,3 +711,67 @@ void Headings::suppress_dependencies(parse_node *pn) {
copy_error *CE = CopyErrors::new(SYNTAX_CE, UnequalHeadingInPlaceOf_SYNERROR);
CopyErrors::supply_node(CE, h->sentence_declaring);
Copies::attach_error(C, CE);
@h The XML file.
This is provided as a convenience to the application using Inform, which may want
to have a pull-down menu or similar gadget allowing the user to jump to a given
heading. This tells the interface where every heading is, thus saving it from
having to parse the source.
The property list contains a single dictionary, whose keys are the numbers
0, 1, 2, ..., $n-1$, where there are $n$ headings in all.
A special key, the only non-numerical one, called "Application Version", contains
the Inform build number.
=
void Headings::write_as_XML(parse_node_tree *T, filename *F) {
text_stream xf_struct; text_stream *OUT = &xf_struct;
if (STREAM_OPEN_TO_FILE(OUT, F, UTF8_ENC) == FALSE) {
#ifdef CORE_MODULE
Problems::fatal_on_file("Can't open headings file", F);
#endif
#ifndef CORE_MODULE
Errors::fatal_with_file("can't open headings file", F);
#endif
}
heading *h;
@<Write DTD indication for XML headings file@>;
WRITE("<plist version=\"1.0\"><dict>\n");
INDENT;
WRITE("<key>Application Version</key><string>%B (build %B)</string>\n", FALSE, TRUE);
LOOP_OVER_LINKED_LIST(h, heading, T->headings->subordinates) {
WRITE("<key>%d</key><dict>\n", h->allocation_id);
INDENT;
@<Write the dictionary of properties for a single heading@>;
OUTDENT;
WRITE("</dict>\n");
}
OUTDENT;
WRITE("</dict></plist>\n");
STREAM_CLOSE(OUT);
}
@ We use a convenient Apple DTD:
@<Write DTD indication for XML headings file@> =
WRITE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
@ Note that a level of 0, and a title of |--|, signifies a File (0) level
heading: external tools can probably ignore such records. Similarly, it is
unlikely that they will ever see a record without a "Filename" key, but they
are optional all the same.
@<Write the dictionary of properties for a single heading@> =
if (h->start_location.file_of_origin)
WRITE("<key>Filename</key><string>%f</string>\n",
TextFromFiles::get_filename(h->start_location.file_of_origin));
WRITE("<key>Line</key><integer>%d</integer>\n", h->start_location.line_number);
if (Wordings::nonempty(h->heading_text))
WRITE("<key>Title</key><string>%+W</string>\n", h->heading_text);
else
WRITE("<key>Title</key><string>--</string>\n");
WRITE("<key>Level</key><integer>%d</integer>\n", h->level);
WRITE("<key>Indentation</key><integer>%d</integer>\n", h->indentation);

View file

@ -18,6 +18,7 @@ which use this module:
@e RELATION_DEFINITIONS_DA
=
COMPILE_WRITER(heading *, NameResolution::log_headings)
COMPILE_WRITER(table *, Tables::log)
COMPILE_WRITER(table_column *, Tables::Columns::log)
@ -35,6 +36,10 @@ void AssertionsModule::start(void) {
AdjectivesByInterFunction::start();
AdjectivesByInterCondition::start();
REGISTER_WRITER('H', NameResolution::log_headings);
REGISTER_WRITER('B', Tables::log);
REGISTER_WRITER('C', Tables::Columns::log);
Log::declare_aspect(ASSEMBLIES_DA, L"assemblies", FALSE, FALSE);
Log::declare_aspect(ASSERTIONS_DA, L"assertions", FALSE, TRUE);
Log::declare_aspect(IMPLICATIONS_DA, L"implications", FALSE, TRUE);

View file

@ -222,10 +222,10 @@ and produce an internal error if not.
if (c != nouns_placed_under_headings) {
LOG("Reordering failed from $H\n", h);
LOG("%d nouns under headings, %d in ordering\n", nouns_placed_under_headings, c);
IXContents::log_all_headings();
NameResolution::log_all_headings();
LOG("Making fresh tree:\n");
NameResolution::make_the_tree();
IXContents::log_all_headings();
NameResolution::log_all_headings();
internal_error_tree_unsafe("reordering of nouns failed");
}
@ -340,3 +340,41 @@ noun_usage *NameResolution::choose_highest_scoring_noun(parse_node *p, int commo
}
return NULL; /* should never in fact happen */
}
@h The debugging log.
This is really just for checking the correctness of the code above.
=
void NameResolution::log_headings(heading *h) {
if (h==NULL) { LOG("<null heading>\n"); return; }
heading *pseud = NameResolution::pseudo_heading();
if (h == pseud) { LOG("<pseudo_heading>\n"); return; }
LOG("H%d ", h->allocation_id);
if (h->start_location.file_of_origin)
LOG("<%f, line %d>",
TextFromFiles::get_filename(h->start_location.file_of_origin),
h->start_location.line_number);
else LOG("<nowhere>");
LOG(" level:%d indentation:%d", h->level, h->indentation);
}
@ And here we log the whole heading tree by recursing through it, and
surreptitiously check that it is correctly formed at the same time.
=
void NameResolution::log_all_headings(void) {
heading *h;
parse_node_tree *T = Task::syntax_tree();
LOOP_OVER_LINKED_LIST(h, heading, T->headings->subordinates) LOG("$H\n", h);
LOG("\n");
NameResolution::log_heading_recursively(NameResolution::pseudo_heading(), 0);
}
void NameResolution::log_heading_recursively(heading *h, int depth) {
if (h == NULL) return;
for (int i=0; i<depth; i++) LOG(" ");
LOG("$H\n", h);
if (depth-1 != h->indentation) LOG("*** indentation should be %d ***\n", depth-1);
NameResolution::log_heading_recursively(h->child_heading, depth+1);
NameResolution::log_heading_recursively(h->next_heading, depth);
}

View file

@ -115,7 +115,7 @@ will divide according to these units.
BENCH(Hierarchy::establish)
BENCH(GenericModule::compile);
BENCH(NameResolution::make_the_tree)
BENCH(IXContents::write_as_xml)
BENCH(Task::write_XML_headings_file)
BENCH(CompilationUnits::determine)
@ Most of the conceptual infrastructure in Inform is created by Inform source

View file

@ -326,6 +326,14 @@ pathname *Task::index_path(void) {
return NULL;
}
@ The XML file of headings is written by the supervisor, but only if we ask
it to, and this is where:
=
void Task::write_XML_headings_file(void) {
Headings::write_as_XML(Task::syntax_tree(), Index::xml_headings_file());
}
@ That's it for the project folder, but other project-related stuff is in
the materials folder, which we turn to next.

View file

@ -10,17 +10,12 @@ which use this module:
@ Like all modules, this one must define a |start| and |end| function:
@e PHRASE_USAGE_DA
@e INDEX_SORTING_MREASON
@e MAP_INDEX_MREASON
@e TYPE_TABLES_MREASON
=
COMPILE_WRITER(heading *, IXContents::log)
void IndexModule::start(void) {
REGISTER_WRITER('H', IXContents::log);
Log::declare_aspect(PHRASE_USAGE_DA, L"phrase usage", FALSE, FALSE);
Memory::reason_name(INDEX_SORTING_MREASON, "index sorting");
Memory::reason_name(MAP_INDEX_MREASON, "map in the World index");
Memory::reason_name(TYPE_TABLES_MREASON, "tables of details of the kinds of values");

View file

@ -2,46 +2,6 @@
To produce the index contents listing and the XML headings file.
@h The debugging log.
Finally, three ways to describe the run of headings: to the debugging log,
to the index of the project, and to a freestanding XML file.
=
void IXContents::log(heading *h) {
if (h==NULL) { LOG("<null heading>\n"); return; }
heading *pseud = NameResolution::pseudo_heading();
if (h == pseud) { LOG("<pseudo_heading>\n"); return; }
LOG("H%d ", h->allocation_id);
if (h->start_location.file_of_origin)
LOG("<%f, line %d>",
TextFromFiles::get_filename(h->start_location.file_of_origin),
h->start_location.line_number);
else LOG("<nowhere>");
LOG(" level:%d indentation:%d", h->level, h->indentation);
}
@ And here we log the whole heading tree by recursing through it, and
surreptitiously check that it is correctly formed at the same time.
=
void IXContents::log_all_headings(void) {
heading *h;
parse_node_tree *T = Task::syntax_tree();
LOOP_OVER_LINKED_LIST(h, heading, T->headings->subordinates) LOG("$H\n", h);
LOG("\n");
IXContents::log_headings_recursively(NameResolution::pseudo_heading(), 0);
}
void IXContents::log_headings_recursively(heading *h, int depth) {
int i;
if (h==NULL) return;
for (i=0; i<depth; i++) LOG(" ");
LOG("$H\n", h);
if (depth-1 != h->indentation) LOG("*** indentation should be %d ***\n", depth-1);
IXContents::log_headings_recursively(h->child_heading, depth+1);
IXContents::log_headings_recursively(h->next_heading, depth);
}
@h The index.
=
@ -190,71 +150,6 @@ in practice strews distractingly many orange berries across the page.
}
if (c > 0) { HTML::end_colour(OUT); HTML_CLOSE("p"); }
@h The XML file.
This is provided as a convenience to the application using Inform, which may want
to have a pull-down menu or similar gadget allowing the user to jump to a given
heading. This tells the interface where every heading is, thus saving it from
having to parse the source.
The property list contains a single dictionary, whose keys are the numbers
0, 1, 2, ..., $n-1$, where there are $n$ headings in all. (The pseudo-heading
is not included.) A special key, the only non-numerical one, called "Application
Version", contains the Inform build number in its usual form: "4Q34", for instance.
=
void IXContents::write_as_xml(void) {
text_stream xf_struct; text_stream *xf = &xf_struct;
filename *F = Index::xml_headings_file();
if (STREAM_OPEN_TO_FILE(xf, F, UTF8_ENC) == FALSE)
Problems::fatal_on_file("Can't open headings file", F);
IXContents::write_headings_as_xml_inner(xf);
STREAM_CLOSE(xf);
}
void IXContents::write_headings_as_xml_inner(OUTPUT_STREAM) {
heading *h;
@<Write DTD indication for XML headings file@>;
WRITE("<plist version=\"1.0\"><dict>\n");
INDENT;
WRITE("<key>Application Version</key><string>%B (build %B)</string>\n", FALSE, TRUE);
parse_node_tree *T = Task::syntax_tree();
LOOP_OVER_LINKED_LIST(h, heading, T->headings->subordinates) {
WRITE("<key>%d</key><dict>\n", h->allocation_id);
INDENT;
@<Write the dictionary of properties for a single heading@>;
OUTDENT;
WRITE("</dict>\n");
}
OUTDENT;
WRITE("</dict></plist>\n");
}
@ We use a convenient Apple DTD:
@<Write DTD indication for XML headings file@> =
WRITE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
@ Note that a level of 0, and a title of |--|, signifies a File (0) level
heading: external tools can probably ignore such records. Similarly, it is
unlikely that they will ever see a record without a "Filename" key --
this would mean a heading arising from text created internally within Inform,
which will only happen if someone has done something funny with |.i6t| files --
but should this arise then the best recourse is to ignore the heading.
@<Write the dictionary of properties for a single heading@> =
if (h->start_location.file_of_origin)
WRITE("<key>Filename</key><string>%f</string>\n",
TextFromFiles::get_filename(h->start_location.file_of_origin));
WRITE("<key>Line</key><integer>%d</integer>\n", h->start_location.line_number);
if (Wordings::nonempty(h->heading_text))
WRITE("<key>Title</key><string>%+W</string>\n", h->heading_text);
else
WRITE("<key>Title</key><string>--</string>\n");
WRITE("<key>Level</key><integer>%d</integer>\n", h->level);
WRITE("<key>Indentation</key><integer>%d</integer>\n", h->indentation);
@h Indexing extensions in the Contents index.
The routine below places a list of extensions used in the Contents index,
giving only minimal entries about them.

View file

@ -11,6 +11,7 @@ which use this module:
@ Like all modules, this one must define a |start| and |end| function:
@e OBJECT_CREATIONS_DA
@e PHRASE_USAGE_DA
@e SPECIFICITIES_DA
@e TEXT_SUBSTITUTIONS_DA
@e VARIABLE_CREATIONS_DA
@ -25,12 +26,11 @@ void ValuesModule::start(void) {
Tables::Relations::start();
Writers::register_writer('I', &Instances::writer);
Log::declare_aspect(OBJECT_CREATIONS_DA, L"object creations", FALSE, FALSE);
Log::declare_aspect(PHRASE_USAGE_DA, L"phrase usage", FALSE, FALSE);
Log::declare_aspect(SPECIFICITIES_DA, L"specificities", FALSE, FALSE);
Log::declare_aspect(TEXT_SUBSTITUTIONS_DA, L"text substitutions", FALSE, FALSE);
Log::declare_aspect(VARIABLE_CREATIONS_DA, L"variable creations", FALSE, FALSE);
Log::declare_aspect(TABLES_DA, L"table construction", FALSE, FALSE);
REGISTER_WRITER('B', Tables::log);
REGISTER_WRITER('C', Tables::Columns::log);
REGISTER_WRITER('O', Instances::log);
REGISTER_WRITER('q', Equations::log);
REGISTER_WRITER('Z', NonlocalVariables::log);