mirror of
https://github.com/ganelson/inform.git
synced 2024-07-02 23:14:57 +03:00
138 lines
5.7 KiB
OpenEdge ABL
138 lines
5.7 KiB
OpenEdge ABL
[ExtensionWebsite::] The Mini-Website.
|
|
|
|
To refresh the mini-website of available extensions presented in the
|
|
Inform GUI applications.
|
|
|
|
@ The Inform GUI apps present HTML in-app documentation on extensions: in
|
|
effect, a mini-website showing all the extensions available to the current
|
|
user, and giving detailed documentation on each one. The code in this
|
|
chapter of //supervisor// runs only if and when we want to generate or
|
|
update that website, and plays no part in Inform compilation or building
|
|
as such: it lives in //supervisor// because it's essentially concerned
|
|
with managing resources (i.e., extensions in nests).
|
|
|
|
A principle used throughout is that we fail safe and silent: if we can't
|
|
write the documentation website for any reason (permissions failures, for
|
|
example) then we make no complaint. It's a convenience for the user, but not
|
|
an essential. This point of view was encouraged by many Inform users working
|
|
clandestinely on thumb drives at their places of work, and whose employers
|
|
had locked their computers down fairly heavily.
|
|
|
|
@ The site has a very simple structure: there is an index page, and then
|
|
each visible extension is given its own page(s) concerning that extension alone.
|
|
|
|
Note that the "census" gives us a list of all extensions normally visible
|
|
to the project: those it has installed, and those built into the app. But
|
|
the project might also still be using an extension from the legacy external
|
|
area, so we have to document everything it uses as well as everything in
|
|
the census, to be on the safe side.
|
|
|
|
=
|
|
void ExtensionWebsite::update(inform_project *proj) {
|
|
LOGIF(EXTENSIONS_CENSUS, "Updating extensions documentation for project\n");
|
|
|
|
HTML::set_link_abbreviation_path(Projects::path(proj));
|
|
ExtensionIndex::write(proj);
|
|
|
|
inform_extension *E;
|
|
LOOP_OVER_LINKED_LIST(E, inform_extension, proj->extensions_included)
|
|
ExtensionPages::document_extension(E, FALSE, proj);
|
|
|
|
linked_list *census = Projects::perform_census(proj);
|
|
inbuild_search_result *res;
|
|
LOOP_OVER_LINKED_LIST(res, inbuild_search_result, census)
|
|
ExtensionPages::document_extension(Extensions::from_copy(res->copy), FALSE, proj);
|
|
}
|
|
|
|
@ The top-level index page is at this filename.
|
|
|
|
The distinction between these two calls is that |ExtensionWebsite::index_page_filename|
|
|
returns just the filename, and produces |NULL| only if there is no materials folder,
|
|
which certainly means we wouldn't want to be writing documentation to it;
|
|
but |ExtensionWebsite::cut_way_for_index_page| cuts its way through the file-system
|
|
with a machete in order to ensure that its parent directory will indeed exist.
|
|
That returns |NULL| if this fails because e.g. the file system objects.
|
|
|
|
=
|
|
filename *ExtensionWebsite::index_page_filename(inform_project *proj) {
|
|
if (proj == NULL) internal_error("no project");
|
|
pathname *P = ExtensionWebsite::path_to_site(proj, FALSE, FALSE);
|
|
if (P == NULL) return NULL;
|
|
return Filenames::in(P, I"Extensions.html");
|
|
}
|
|
|
|
filename *ExtensionWebsite::cut_way_for_index_page(inform_project *proj) {
|
|
if (proj == NULL) internal_error("no project");
|
|
pathname *P = ExtensionWebsite::path_to_site(proj, FALSE, TRUE);
|
|
if (P == NULL) return NULL;
|
|
return Filenames::in(P, I"Extensions.html");
|
|
}
|
|
|
|
@ And this finds, or if |use_machete| is set, also makes way for, the directory
|
|
in which our mini-website is to be built.
|
|
|
|
=
|
|
pathname *ExtensionWebsite::path_to_site(inform_project *proj, int relative, int use_machete) {
|
|
if (relative) use_machete = FALSE; /* just for safety's sake */
|
|
pathname *P = NULL;
|
|
if (relative == FALSE) {
|
|
if (proj == NULL) internal_error("no project");
|
|
P = Projects::materials_path(proj);
|
|
if (P == NULL) return NULL;
|
|
}
|
|
P = Pathnames::down(P, I"Extensions");
|
|
if ((use_machete) && (Pathnames::create_in_file_system(P) == 0)) return NULL;
|
|
P = Pathnames::down(P, I"Reserved");
|
|
if ((use_machete) && (Pathnames::create_in_file_system(P) == 0)) return NULL;
|
|
P = Pathnames::down(P, I"Documentation");
|
|
if ((use_machete) && (Pathnames::create_in_file_system(P) == 0)) return NULL;
|
|
return P;
|
|
}
|
|
|
|
@ And similarly for pages which hold individual extension documentation. Note
|
|
that if |eg_number| is positive, it should be 1, 2, 3, ... up to the number of
|
|
examples provided in the extension.
|
|
|
|
=
|
|
filename *ExtensionWebsite::page_filename(inform_project *proj, inbuild_edition *edition,
|
|
int eg_number) {
|
|
if (proj == NULL) internal_error("no project");
|
|
return ExtensionWebsite::page_filename_inner(proj, edition, eg_number, FALSE, FALSE);
|
|
}
|
|
|
|
filename *ExtensionWebsite::page_filename_relative_to_materials(inbuild_edition *edition,
|
|
int eg_number) {
|
|
return ExtensionWebsite::page_filename_inner(NULL, edition, eg_number, TRUE, FALSE);
|
|
}
|
|
|
|
filename *ExtensionWebsite::cut_way_for_page(inform_project *proj,
|
|
inbuild_edition *edition, int eg_number) {
|
|
if (proj == NULL) internal_error("no project");
|
|
return ExtensionWebsite::page_filename_inner(proj, edition, eg_number, FALSE, TRUE);
|
|
}
|
|
|
|
@ All of which use this private utility function:
|
|
|
|
=
|
|
filename *ExtensionWebsite::page_filename_inner(inform_project *proj, inbuild_edition *edition,
|
|
int eg_number, int relative, int use_machete) {
|
|
if (relative) use_machete = FALSE; /* just for safety's sake */
|
|
TEMPORARY_TEXT(leaf)
|
|
Editions::write_canonical_leaf(leaf, edition);
|
|
|
|
pathname *P = ExtensionWebsite::path_to_site(proj, relative, use_machete);
|
|
if (P == NULL) return NULL;
|
|
P = Pathnames::down(P, edition->work->author_name);
|
|
if ((use_machete) && (Pathnames::create_in_file_system(P) == 0)) return NULL;
|
|
P = Pathnames::down(P, leaf);
|
|
if ((use_machete) && (Pathnames::create_in_file_system(P) == 0)) return NULL;
|
|
Str::clear(leaf);
|
|
if (eg_number > 0) WRITE_TO(leaf, "eg%d.html", eg_number);
|
|
else WRITE_TO(leaf, "index.html");
|
|
|
|
filename *F = Filenames::in(P, leaf);
|
|
DISCARD_TEXT(leaf)
|
|
return F;
|
|
}
|
|
|