1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/8-ef.html
2020-01-27 01:22:21 +00:00

901 lines
96 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>7/rs</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '8/ef' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#8">Chapter 8: Extensions</a></li><li><b>Extension Files</b></li></ul><p class="purpose">To keep details of the extensions currently loaded, their authors, titles, versions and rubrics, and to index and credit them suitably.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP4">&#167;4. How the application should install extensions</a></li><li><a href="#SP5">&#167;5. The extension census</a></li><li><a href="#SP6">&#167;6. What happens in census mode</a></li><li><a href="#SP14">&#167;14. Printing names of extensions</a></li><li><a href="#SP18">&#167;18. Checking version numbers</a></li><li><a href="#SP19">&#167;19. Credit for extensions</a></li><li><a href="#SP21">&#167;21. Indexing extensions in the Contents index</a></li><li><a href="#SP22">&#167;22. Updating the documentation</a></li><li><a href="#SP24">&#167;24. Writing the extensions home pages</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Extensions are files of source text, normally combined with an appendix
of documentation, provided by third parties for users to include with the
source text of their own projects. Extensions are intended to provide general
solutions to typical needs, and an archive of extensions for download is
provided by the Inform website: those are licenced by their authors with
a Creative Commons Attribution licence, and because of that, Inform behaves
as if all extensions it sees require attribution (unless the author requests
anonymity). A user of Inform 7 will certainly have nine or ten extensions
available to him, because that many are built into the standard distribution:
as of 2007 it is typical for users to have installed 50 to 90 others, and
the total is steadily rising. Our routines here therefore need to be
scalable.
</p>
<p class="inwebparagraph">Extensions are stored in two places: a built-in area, inside the Inform 7
application, and an external area. Inform knows the location of the former
because the application passes this as <code class="display"><span class="extract">-rules</span></code> on the command line, and it
knows the location of the latter because this is standard and fixed for
each platform: see Platform-Specific Definitions.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>An extension has a title and an author name, each of which is limited in
length to one character less than the following constants:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain"> 51</span>
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain"> 51</span>
</pre>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. How the application should install extensions. </b>When the Inform 7 application looks at a file chosen by the user to
be installed, it should look at the first line. (Note that this might have
any of <code class="display"><span class="extract">0a</span></code>, <code class="display"><span class="extract">0d</span></code>, <code class="display"><span class="extract">0a0d</span></code>, <code class="display"><span class="extract">0d0a</span></code>, or Unicode line division as its line
ending: and that the file might, or might not, begin with a Unicode BOM,
"byte order marker", code. Characters within the line will be encoded as
UTF-8, though &mdash; except possibly for some exotic forms of space &mdash; they
will all be found in the ISO Latin-1 set.) The first line is required to
have one of the following forms, possibly with white space before or after,
but definitely without line breaks before:
</p>
<blockquote>
<p>Locksmith Extra by Emily Short begins here.</p>
</blockquote>
<blockquote>
<p>Version 2 of Locksmith Extra by Emily Short begins here.</p>
</blockquote>
<blockquote>
<p>Version 060430 of Locksmith Extra by Emily Short begins here.</p>
</blockquote>
<blockquote>
<p>Version 2/060430 of Locksmith Extra by Emily Short begins here.</p>
</blockquote>
<p class="inwebparagraph">If the name of the extension finishes with a bracketed clause, that
should be disregarded. Such clauses are used to specify virtual machine
requirements, at present, and could conceivably be used for other purposes
later, so let's reserve them now.
</p>
<blockquote>
<p>Version 2 of Glulx Text Effects (for Glulx only) by Emily Short begins here.</p>
</blockquote>
<p class="inwebparagraph">The application should reject (that is, politely refuse to install) any
purported extension file whose first line does not conform to the above.
</p>
<p class="inwebparagraph">Ignoring any version number given, the Inform application should then
store the file in the external extensions area. For instance,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">~/Library/Inform/Extensions/Emily Short/Glulx Text Effects</span>
(OS X) <span class="plain">My Documents\Inform\Extensions\Emily Short\Glulx Text Effects</span>
(Windows)</pre>
<p class="inwebparagraph">Note that the file will probably not have the right name initially, and
will need to be renamed as well as moved. (Note the lack of a file
extension.) The subfolders <code class="display"><span class="extract">Inform</span></code>, <code class="display"><span class="extract">Extensions</span></code> and <code class="display"><span class="extract">Emily Short</span></code> must be
created if not already present.
</p>
<p class="inwebparagraph">If to install such an extension would result in over-writing an extension
already present at that filename, the user should be given a warning and
asked if he wants to proceed.
</p>
<p class="inwebparagraph">However, note that it is not an error to install an extension with
the same name and author as one in the built-in extensions folder. This
does not result in overwriting, since the newly installed version will live
in the external area, not the built-in area.
</p>
<p class="inwebparagraph">An extension may be uninstalled simply by deleting the file: but the
application must not allow the user to uninstall any extension from
the built-in area. We must assume that the latter could be on a read-only
disc, or could be part of a cryptographically signed application bundle.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The extension census. </b>The Inform application should run Inform in "census mode" in order to
keep extension documentation up to date. Inform should be run in census mode
on three occasions:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) when the Inform application starts up;
</li><li>(b) when the Inform application installs a new extension;
</li><li>(c) when the Inform application uninstalls an extension.
</li></ul>
<p class="inwebparagraph">When Inform is run in "census mode", it should be run with the command
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">ni -rules (...) -census</span>
</pre>
<p class="inwebparagraph">where the argument for <code class="display"><span class="extract">-rules</span></code> is the same as for any other run. All
output from Inform should be ignored, including its return code: ideally,
not even a fatal error should provoke a reaction from the application.
If the census doesn't work for some file-system reason, never mind &mdash;
it's not mission-critical.
</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. What happens in census mode. </b>The census has two purposes: first, to create provisional documentation
where needed for new and unused extensions; and second, to create the
following index files in the external documentation area (not in
the external extension area):
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">.../Extensions.html</span>
(basically a contents page) <span class="plain">.../ExtIndex.html</span>
(basically an index)</pre>
<p class="inwebparagraph">Documentation for any individual extension is stored at, e.g.,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">.../Extensions/Victoria Saxe-Coburg-Gotha/Werewolves.html</span>
</pre>
<p class="inwebparagraph">Inform can generate such a file, for an individual extension, in two ways: (a)
provisionally, with much less detail, and (b) fully. Whenever it
successfully compiles a work using extension X, it rewrites the
documentation for X fully, and updates both the two indexing pages.
</p>
<p class="inwebparagraph">When Inform runs in <code class="display"><span class="extract">-census</span></code> mode, what it does is to scan for all extensions.
If Inform finds a valid extension with no documentation page, it writes a
provisional one; and again, it updates both the two indexing pages.
</p>
<p class="inwebparagraph">(Inform in fact runs a census on every compilation, as well, so <code class="display"><span class="extract">-census</span></code> runs
do nothing "extra" that a normal run of Inform does not also do. On every
census, Inform automatically checks for misfiled or broken extensions, and
places a descriptive report of what's wrong on the <code class="display"><span class="extract">Extensions.html</span></code> index
page &mdash; if people move around or edit extensions by hand, they may run into
these errors.)
</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>With that general discussion out of the way, we can get on with
implementation. A modest structure is used to store details of extension
files loaded into Inform: or rather, to store requests to include them, and then
to keep track of the results.
</p>
<p class="inwebparagraph">The rubric of an extension is text found near its opening, describing
its purpose.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">extension_file</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">extension_identifier</span><span class="plain"> </span><span class="identifier">ef_id</span><span class="plain">; </span> <span class="comment">Texts of title and author with hash code</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">author_text</span><span class="plain">; </span> <span class="comment">Author's name</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">title_text</span><span class="plain">; </span> <span class="comment">Extension name</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">body_text</span><span class="plain">; </span> <span class="comment">Body of source text supplied in extension, if any</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">body_text_unbroken</span><span class="plain">; </span> <span class="comment">Does this contain text waiting to be sentence-broken?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">documentation_text</span><span class="plain">; </span> <span class="comment">Documentation supplied in extension, if any</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">VM_restriction_text</span><span class="plain">; </span> <span class="comment">Restricting use to certain VMs</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">min_version_needed</span><span class="plain">; </span> <span class="comment">As stipulated by source</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_loaded</span><span class="plain">; </span> <span class="comment">As actually loaded</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">loaded_from_built_in_area</span><span class="plain">; </span> <span class="comment">Located within Inform application</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">authorial_modesty</span><span class="plain">; </span> <span class="comment">Do not credit in the compiled game</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inclusion_sentence</span><span class="plain">; </span> <span class="comment">Where the source called for this</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">read_into_file</span><span class="plain">; </span> <span class="comment">Which source file loaded this</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">rubric_as_lexed</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">extra_credit_as_lexed</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">extension_file</span><span class="plain">;</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">standard_rules_extension</span><span class="plain">; </span> <span class="comment">the Standard Rules by Graham Nelson</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure extension_file is accessed in 3/rst, 8/ie, 8/ed, 8/ed2, 19/tb, 26/uo, 27/cm and here.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>We begin with some housekeeping, really: the code required to create new
extension file structures, and to manage existing ones.
</p>
<pre class="display">
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="functiontext">Extensions::Files::new</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">VMW</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_word</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">violation</span><span class="plain">);</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain">);</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain"> = </span><span class="identifier">AW</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain"> = </span><span class="identifier">NW</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Create EID for new extension file</span> <span class="cwebmacronumber">8.1</span>&gt;<span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;min_version_needed</span><span class="plain"> = </span><span class="identifier">version_word</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;VM_restriction_text</span><span class="plain"> = </span><span class="identifier">VMW</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;body_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;body_text_unbroken</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;documentation_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain"> = -1;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;loaded_from_built_in_area</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;authorial_modesty</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;rubric_as_lexed</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">violation</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"So %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">violation</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::extension_problem_S</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_IncludesTooLong</span><span class="plain">), </span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">violation</span><span class="plain">); </span> <span class="comment">see below</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">violation</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ef</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::new is used in 8/ie (<a href="8-ie.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b>We protect ourselves a little against absurdly long requested author or
title names, and then produce problem messages in the event of only longish
ones, unless the census is going on: in which case it's better to leave the
matter to the census errors system elsewhere.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Create EID for new extension file</span> <span class="cwebmacronumber">8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Extensions::Census::currently_recording_errors</span><span class="plain">() == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">) &gt;= </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">violation</span><span class="plain">,</span>
<span class="string">"has an author's name which is too long, exceeding the maximum "</span>
<span class="string">"allowed (%d characters) by %d"</span><span class="plain">,</span>
<span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">-1,</span>
<span class="plain">(</span><span class="reserved">int</span><span class="plain">) (1+</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">)-</span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">));</span>
<span class="identifier">Str::truncate</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">-1);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">) &gt;= </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">violation</span><span class="plain">,</span>
<span class="string">"has a title which is too long, exceeding the maximum allowed "</span>
<span class="string">"(%d characters) by %d"</span><span class="plain">,</span>
<span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain">-1,</span>
<span class="plain">(</span><span class="reserved">int</span><span class="plain">) (1+</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">)-</span><span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain">));</span>
<span class="identifier">Str::truncate</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">-1);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">Extensions::IDs::new</span><span class="plain">(&amp;(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id</span><span class="plain">), </span><span class="identifier">exfa</span><span class="plain">, </span><span class="identifier">exft</span><span class="plain">, </span><span class="constant">LOADED_EIDBC</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Extensions::IDs::is_standard_rules</span><span class="plain">(&amp;(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id</span><span class="plain">))) </span><span class="identifier">standard_rules_extension</span><span class="plain"> = </span><span class="identifier">ef</span><span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Three pieces of information (not available when the EF is created) will
be set later on, by other parts of Inform calling the routines below.
</p>
<p class="inwebparagraph">The rubric text for an extension, which is double-quoted matter just below
its "begins here" line, is parsed as a sentence and will be read as an
assertion in the usual way when the material from this extension is being
worked through (quite a long time after the EF structure was created). When
that happens, the following routine will be called to set the rubric; and
the one after for the optional extra credit line, used to acknowledge I6
sources, collaborators, translators and so on.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_rubric</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">) {</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;rubric_as_lexed</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Extension rubric: %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;rubric_as_lexed</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_extra_credit</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">) {</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Extension extra credit: %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::set_rubric is used in 9/tfa (<a href="9-tfa.html#SP11_1">&#167;11.1</a>).</p>
<p class="endnote">The function Extensions::Files::set_extra_credit is used in 9/tfa (<a href="9-tfa.html#SP11_1">&#167;11.1</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Once we start reading text from the file (if it can successfully be found:
when the EF structure is created, we don't know that yet), we need to tally
it up with the corresponding source file structure.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_corresponding_source_file</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">) {</span>
<span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;read_into_file</span><span class="plain"> = </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">source_file</span><span class="plain"> *</span><span class="functiontext">Extensions::Files::get_corresponding_source_file</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;read_into_file</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::set_corresponding_source_file is used in 3/rst (<a href="3-rst.html#SP5">&#167;5</a>).</p>
<p class="endnote">The function Extensions::Files::get_corresponding_source_file is used in 8/ed (<a href="8-ed.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>When headings cross-refer to extensions, they need to read extension IDs, so:
</p>
<pre class="display">
<span class="reserved">extension_identifier</span><span class="plain"> *</span><span class="functiontext">Extensions::Files::get_eid</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> &amp;(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::get_eid is used in 7/hdn (<a href="7-hdn.html#SP20">&#167;20</a>, <a href="7-hdn.html#SP20_2">&#167;20.2</a>), 17/rs (<a href="17-rs.html#SP7_3_1_1">&#167;7.3.1.1</a>), 21/rl2 (<a href="21-rl2.html#SP23_11">&#167;23.11</a>), 27/cm (<a href="27-cm.html#SP2_1">&#167;2.1</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>A few problem messages need the version number loaded, so:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Extensions::Files::get_version_wn</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::get_version_wn is used in 7/hdn (<a href="7-hdn.html#SP20_2">&#167;20.2</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The use option "authorial modesty" is unusual in applying to the extension
it is found in, not the whole source text. When we read it, we call one of
the following routines, depending on whether it was in an extension or in
the main source text:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">general_authorial_modesty</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_authorial_modesty</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) { </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;authorial_modesty</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_general_authorial_modesty</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) { </span><span class="identifier">general_authorial_modesty</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::set_authorial_modesty is used in 26/uo (<a href="26-uo.html#SP13_1">&#167;13.1</a>).</p>
<p class="endnote">The function Extensions::Files::set_general_authorial_modesty is used in 26/uo (<a href="26-uo.html#SP13_1">&#167;13.1</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Printing names of extensions. </b>We can print the name of the extension in a variety of ways and to a
variety of destinations, but it all comes down to the same thing in the end.
First, printing the name to an arbitrary UTF-8 file:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_name_to_file</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_author_to_file</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_name_to_file is used in 22/pi (<a href="22-pi.html#SP1_1">&#167;1.1</a>).</p>
<p class="endnote">The function Extensions::Files::write_author_to_file is used in 22/pi (<a href="22-pi.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>Next, the debugging log:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::log</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;null-extension-file&gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%W by %W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::log is used in 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>Next, printing the name in the form of a comment in an (ISO Latin-1)
Inform 6 source file:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_I6_comment_describing</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain"> == </span><span class="identifier">standard_rules_extension</span><span class="plain">) {</span>
<span class="identifier">Produce::comment</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"From the Standard Rules"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"From \</span><span class="plain">"</span><span class="string">%~W\</span><span class="plain">"</span><span class="string"> by %~W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="identifier">Produce::comment</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_I6_comment_describing is used in 25/cp (<a href="25-cp.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>And finally printing the name to a C string:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_full_title_to_stream</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W by %+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_full_title_to_stream is used in 2/sq (<a href="2-sq.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Checking version numbers. </b>It's only at the end of semantic analysis, when all extensions have been
loaded, that we check that all the version numbers are sufficient to meet
the requests made. The reason we don't do this one at a time, as we load
them in, is that we might load E at a time when version V is required,
and find that it matches; but then an extension loaded later might turn out
to require E version V+1. So it is only when all extensions have been
loaded that we know the full set of requirements, and only then do we
check that they have been met.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::check_versions</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">have</span><span class="plain"> = </span><span class="functiontext">Extensions::Inclusion::parse_version</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain">),</span>
<span class="identifier">need</span><span class="plain"> = </span><span class="functiontext">Extensions::Inclusion::parse_version</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;min_version_needed</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">need</span><span class="plain"> &gt; </span><span class="identifier">have</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Need %d, have %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">need</span><span class="plain">, </span><span class="identifier">have</span><span class="plain">);</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_extension</span><span class="plain">(2, </span><span class="identifier">ef</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ExtVersionTooLow</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1: but my copy of %2 is only version %3."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ExtNoVersion</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1: but my copy of %2 contains no version "</span>
<span class="string">"number, and is therefore considered to be earlier than "</span>
<span class="string">"all numbered versions."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::check_versions is used in 1/mr (<a href="1-mr.html#SP4_10">&#167;4.10</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Credit for extensions. </b>Here we compile an I6 routine to print out credits for all the extensions
present in the compiled work. This is important because the extensions
published at the Inform website are available under a Creative Commons
license which requires users to give credit to the authors: Inform
ensures that this happens automatically.
</p>
<p class="inwebparagraph">Use of authorial modesty (see above) will suppress a credit in the
<code class="display"><span class="extract">ShowExtensionVersions</span></code> routine, but the system is set up so that one can
only be modest about one's own extensions: this would otherwise violate a
CC license of somebody else. General authorial modesty thus suppresses
credits for all extensions used which are by the user himself. On the
other hand, if an extension contains an authorial modesty disclaimer
in its own text, then that must have been the wish of its author, so
we can suppress the credit whoever that author was.
</p>
<p class="inwebparagraph">In <code class="display"><span class="extract">I7FullExtensionVersions</span></code> all extensions are credited whatever anyone's
feelings of modesty.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::ShowExtensionVersions_routine</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SHOWEXTENSIONVERSIONS_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">the_author_name</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">the_author_name</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">self_penned</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Bibliographic::story_author_is</span><span class="plain">(</span><span class="identifier">the_author_name</span><span class="plain">)) </span><span class="identifier">self_penned</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;authorial_modesty</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; </span> <span class="comment">if (1) extension doesn't ask to be modest</span>
<span class="plain">((</span><span class="identifier">general_authorial_modesty</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || </span> <span class="comment">and (2) author doesn't ask to be modest, or...</span>
<span class="plain">(</span><span class="identifier">self_penned</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">))) { </span> <span class="comment">...didn't write this extension</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::credit_ef</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">); </span> <span class="comment">then we award a credit</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">the_author_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SHOWFULLEXTENSIONVERSIONS_HL</span><span class="plain">);</span>
<span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::credit_ef</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SHOWONEEXTENSION_HL</span><span class="plain">);</span>
<span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">id_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"id"</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">id_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) (</span><span class="identifier">ef</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain"> + 1));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::credit_ef</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::ShowExtensionVersions_routine is used in 1/mr (<a href="1-mr.html#SP4_15">&#167;4.15</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>The actual credit consists of a single line, with name, version number
and author. These are printed as I6 strings, hence the ISO encoding.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::credit_ef</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">with_newline</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id.raw_title</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain"> &gt;= 0)</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" version %+W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain">));</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" by %S"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id.raw_author_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain">) &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (%S)"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">with_newline</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::credit_ef is used in <a href="#SP19">&#167;19</a>.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Indexing extensions in the Contents index. </b>The routine below places a list of extensions used in the Contents index,
giving only minimal entries about them.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"EXTENSIONS"</span><span class="plain">); </span><span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::index_extensions_from</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> != </span><span class="identifier">standard_rules_extension</span><span class="plain">)</span>
<span class="functiontext">Extensions::Files::index_extensions_from</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::index_extensions_from</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">standard_rules_extension</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">); </span><span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::index_extensions_from</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">show_head</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) {</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain"> == </span><span class="identifier">standard_rules_extension</span><span class="plain">) </span><span class="identifier">owner</span><span class="plain"> = </span><span class="identifier">standard_rules_extension</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain">))) {</span>
<span class="identifier">source_location</span><span class="plain"> </span><span class="identifier">sl</span><span class="plain"> = </span><span class="identifier">Wordings::location</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">file_of_origin</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">owner</span><span class="plain"> = </span><span class="identifier">standard_rules_extension</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">owner</span><span class="plain"> = </span><span class="functiontext">SourceFiles::get_extension_corresponding</span><span class="plain">(</span>
<span class="identifier">Lexer::file_of_origin</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain">))));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner</span><span class="plain"> != </span><span class="identifier">from</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">show_head</span><span class="plain">) {</span>
<span class="identifier">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 2, </span><span class="string">"hanging"</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"808080"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Included "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">standard_rules_extension</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"automatically by Inform"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"from the source text"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"by the extension %+W"</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">show_head</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"ul"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">leaders\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"li"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">leaded indent2\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W "</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;title_text</span><span class="plain">);</span>
<span class="functiontext">Extensions::IDs::begin_extension_link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/help.png"</span><span class="plain">);</span>
<span class="functiontext">Extensions::IDs::end_extension_link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, &amp;(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;ef_id</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain"> != </span><span class="identifier">standard_rules_extension</span><span class="plain">) { </span> <span class="comment">give author and inclusion links, but not for SR</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" by %+W"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;author_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">smaller\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"version %+W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;version_loaded</span><span class="plain">));</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">smaller\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(%S)"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;extra_credit_as_lexed</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d words"</span><span class="plain">, </span><span class="identifier">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;read_into_file</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">-</span><span class="element">&gt;inclusion_sentence</span><span class="plain">)));</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"li"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"ul"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::index appears nowhere else.</p>
<p class="endnote">The function Extensions::Files::index_extensions_from appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Updating the documentation. </b>This is done in the course of taking an extension census, which is called
for in one of two circumstances: when Inform is being run in "census mode" to
notify it that extensions have been installed or uninstalled; or when Inform
has completed the successful compilation of a source text. In the latter
case, it knows quite a lot about the extensions actually used in that
compilation, and so can write detailed versions of their documentation:
since it is updating extension documentation anyway, it conducts a census
as well. (In both cases the extension dictionary is also worked upon.) The
two alternatives are expressed here:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::handle_census_mode</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">census_mode</span><span class="plain">) {</span>
<span class="functiontext">Extensions::Dictionary::load</span><span class="plain">();</span>
<span class="functiontext">Extensions::Census::perform</span><span class="plain">();</span>
<span class="functiontext">Extensions::Files::write_top_level_of_extensions_documentation</span><span class="plain">();</span>
<span class="functiontext">Extensions::Files::write_sketchy_documentation_for_extensions_found</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::update_census</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">;</span>
<span class="functiontext">Extensions::Dictionary::load</span><span class="plain">();</span>
<span class="functiontext">Extensions::Census::perform</span><span class="plain">();</span>
<span class="functiontext">Extensions::Files::write_top_level_of_extensions_documentation</span><span class="plain">();</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) </span><span class="functiontext">Extensions::Documentation::write_detailed</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">);</span>
<span class="functiontext">Extensions::Files::write_sketchy_documentation_for_extensions_found</span><span class="plain">();</span>
<span class="functiontext">Extensions::Dictionary::write_back</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Log::aspect_switched_on</span><span class="plain">(</span><span class="constant">EXTENSIONS_CENSUS_DA</span><span class="plain">)) </span><span class="functiontext">Extensions::IDs::log_EID_hash_table</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::handle_census_mode is used in 1/mr (<a href="1-mr.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Extensions::Files::update_census appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>Documenting extensions seen but not used: we run through the census
results in no particular order and create a sketchy page of documentation,
if there's no better one already.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_sketchy_documentation_for_extensions_found</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_census_datum</span><span class="plain"> *</span><span class="identifier">ecd</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ecd</span><span class="plain">, </span><span class="reserved">extension_census_datum</span><span class="plain">)</span>
<span class="functiontext">Extensions::Documentation::write_sketchy</span><span class="plain">(</span><span class="identifier">ecd</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_sketchy_documentation_for_extensions_found is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. Writing the extensions home pages. </b>Extensions documentation forms a mini-website within the Inform
documentation. There is a top level consisting of two home pages: a
directory of all installed extensions, and an index to the terms defined in
those extensions. A cross-link switches between them. Each of these links
down to the bottom level, where there is a page for every installed
extension (wherever it is installed). The picture is therefore something
like this:
</p>
<pre class="display">
<span class="plain">(Main documentation contents page)</span>
<span class="plain">|</span>
<span class="plain">Extensions.html--ExtIndex.html</span>
<span class="plain">| \/ |</span>
<span class="plain">| /\ |</span>
<span class="plain">Nigel Toad/Eggs Barnabas Dundritch/Neopolitan Iced Cream ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>These pages are stored at the relative pathnames
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Extensions/Documentation/Extensions.html</span>
<span class="plain">Extensions/Documentation/ExtIndex.html</span>
</pre>
<p class="inwebparagraph">They are made by inserting content in place of the material between the
HTML anchors <code class="display"><span class="extract">on</span></code> and <code class="display"><span class="extract">off</span></code> in a template version of the page built in
to the application, with a leafname which varies from platform to
platform, for reasons as always to do with the vagaries of Internet
Explorer 7 for Windows.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_top_level_of_extensions_documentation</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Extensions::Files::write_top_level_extensions_page</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Extensions.html"</span><span class="plain">, 1);</span>
<span class="functiontext">Extensions::Files::write_top_level_extensions_page</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"ExtIndex.html"</span><span class="plain">, 2);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_top_level_of_extensions_documentation is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Files::write_top_level_extensions_page</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">content</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> </span><span class="identifier">HOMEPAGE_struct</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = &amp;</span><span class="identifier">HOMEPAGE_struct</span><span class="plain">;</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">pathname_of_extension_docs</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">STREAM_OPEN_TO_FILE</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">UTF8_ENC</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Problems::Fatal::filename_related</span><span class="plain">(</span>
<span class="string">"Unable to open extensions documentation index for writing"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="identifier">HTML::declare_as_HTML</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">HTML::begin_head</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML::title</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions"</span><span class="plain">);</span>
<span class="identifier">HTML::incorporate_javascript</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">,</span>
<span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">pathname_of_HTML_models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensions.js"</span><span class="plain">));</span>
<span class="identifier">HTML::incorporate_CSS</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
<span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">pathname_of_HTML_models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"main.css"</span><span class="plain">));</span>
<span class="identifier">HTML::end_head</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::begin_body</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML::begin_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 0, 4, 0, 0, 0);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"src='inform:/doc_images/extensions@2x.png' border=0 width=150 height=150"</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">headingboxDark\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">headingtextWhite\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Installed Extensions"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">headingrubricWhite\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Bundles of extra rules or phrases to extend what Inform can do"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">content</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="functiontext">Extensions::Census::write_results</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2: </span><span class="functiontext">Extensions::Dictionary::write_to_HTML</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">HTML::end_body</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::write_top_level_extensions_page is used in <a href="#SP25">&#167;25</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 8: Extensions.)</i></li><li><a href="8-ie.html">Continue with 'Including Extensions'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>