1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/html-module/2-hf.html
2020-03-22 10:50:19 +00:00

451 lines
47 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/im</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<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>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '2/hf' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">html</a></li><li><a href="index.html#2">Chapter 2: HTML</a></li><li><b>HTML Files</b></li></ul><p class="purpose">To provide utilities for writing HTML files such as the problems report, the extension documentation, the index files and so forth.</p>
<ul class="toc"><li><a href="#SP2">&#167;2. The "inform:" URL scheme</a></li><li><a href="#SP3">&#167;3. The "source:" URL scheme</a></li><li><a href="#SP4">&#167;4. Icons with and without tooltips</a></li><li><a href="#SP5">&#167;5. Outcome images</a></li><li><a href="#SP6">&#167;6. Header and footer</a></li><li><a href="#SP7">&#167;7. HTML paragraphs with indentation</a></li><li><a href="#SP8">&#167;8. Writing HTML characters</a></li><li><a href="#SP9">&#167;9. Writing streams in XML-escaped form</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Inform documentation &mdash; its HTML text and the images, etc., used within
it &mdash; is stored in two areas: "built-in" and "external". The built-in
area is expected to be within the Inform 7 application itself. For
instance, on OS X, this is at:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">...wherever.../Inform.app/Contents/Resources/</span></code> and/or
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">...wherever.../Inform.app/Contents/Resources/English.lproj/</span></code>
</p>
<p class="inwebparagraph">(The duplication is a complication to do with localisation which we
can ignore here.) The material stored in this built-in area is fixed: the
Inform application needs to work even if stored on a read-only disc, or
where the user has insufficient permissions to alter it. NI itself neither
reads from, nor writes to, any file in the built-in documentation area.
</p>
<p class="inwebparagraph">Documentation for the installed extensions does, however, change: it is
written by NI as and when necessary. This is the material making up the
"external" area, and it needs to be somewhere which the user certainly
has the necessary permissions to write to. For instance:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">~/Library/Inform/Documentation/</span></code> (OS X)
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">My Documents\Inform\Documentation\| (Windows)
</span></code></p>
<p class="inwebparagraph">Pages in these two areas, built-in and external, need to link to each other by
links: in addition, pages in the external area need access to images stored in
the built-in area.
</p>
<p class="inwebparagraph">The other HTML files written by NI are stored within the relevant
project's bundle: these are the report of Problems (if any) and the
Index. They, too, need access to images stored in the built-in area.
</p>
<p class="inwebparagraph">The problem we face is that these three mini-websites &mdash; the built-in
documentation, the external documentation, and the project-specific
pages &mdash; are written by tools which cannot know the correct file URLs.
(For instance, it would not even help for the application to tell NI
where the built-in area is: because the HTML written by NI would then
cease to work if the user moved the application elsewhere in the
filing system after NI had run.)
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. The "inform:" URL scheme. </b>We solve this by requiring that the Inform 7 application must support
a new URL scheme.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) <code class="display"><span class="extract">&lt;inform://...&gt;</span></code> is interpreted as a file in the built-in documentation
area, except that
</li></ul>
<ul class="items"><li>(b) <code class="display"><span class="extract">&lt;inform://Extensions/...whatever...&gt;</span></code> should be fetched by first
checking for "...whatever..." in the external area, and then &mdash; if
that fails &mdash; also checking for "...whatever..." in the <code class="display"><span class="extract">ExtnDocs</span></code>
subfolder of the built-in area.
</li></ul>
<p class="inwebparagraph">For instance, Inform 7 for OS X would look for <code class="display"><span class="extract">inform://Extensions/magic.png</span></code>
at the following locations:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(i) <code class="display"><span class="extract">~/Library/Inform/Documentation/magic.png</span></code>
</li></ul>
<ul class="items"><li>(ii) <code class="display"><span class="extract">.../Inform.app/Contents/Resources/ExtnDocs/magic.png</span></code>
</li></ul>
<p class="inwebparagraph">If no file was found in either place, the link should simply do nothing:
the application is required not to produce a 404 error page, or to
blank out the page currently showing.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The "source:" URL scheme. </b>The other non-standard Inform URL scheme is "source:", which is used
for a link which, when clicked, opens the Source panel with the given
line made visible.
</p>
<p class="inwebparagraph">For instance, line 21 of file <code class="display"><span class="extract">Bits and Pieces/marbles.txt</span></code> has URL
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">source:Bits and Pieces/marbles.txt#line14</span></code>
</p>
<p class="inwebparagraph">Filenames are given relative to the current project bundle. However, if only
a leafname is supplied, then this is read as a file within the <code class="display"><span class="extract">Source</span></code>
subfolder of the project bundle. (Thus it is not possible to have a
source link to a source file at the root of the project bundle: but this is
no loss, since source is not allowed to be kept there.) For instance,
line 14 of file <code class="display"><span class="extract">Source/story.ni</span></code> has URL
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">source:story.ni#line14</span></code>
</p>
<p class="inwebparagraph">The following routine writes the clickable source-reference icon, and
is the only place in NI where "source:" is used.
</p>
<p class="inwebparagraph">Source which is generated internally to NI cannot be opened in the Source
panel, for obvious reasons, so we produce nothing if the location is internal.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_link_case</span><span class="plain"> = 0;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::set_source_link_case</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">source_link_case</span><span class="plain"> = </span><span class="identifier">Characters::toupper</span><span class="plain">(</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_source_link</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">int</span><span class="plain"> </span><span class="identifier">nonbreaking_space</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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">TextFromFiles::get_filename</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Projects::path</span><span class="plain">(</span><span class="identifier">Inbuild::project</span><span class="plain">())) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">Projects::path</span><span class="plain">(</span><span class="identifier">Inbuild::project</span><span class="plain">()));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">))</span>
<span class="identifier">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">+1);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::begins_with_wide_string</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Source"</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, 6) == </span><span class="identifier">FOLDER_SEPARATOR</span><span class="plain">))</span>
<span class="identifier">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, 7);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nonbreaking_space</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;"</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">" "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_link_case</span><span class="plain">)</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href=\</span><span class="plain">"</span><span class="string">source:%S?case=%c#line%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">source_link_case</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</span><span class="plain">)</span>
<span class="reserved">else</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href=\</span><span class="plain">"</span><span class="string">source:%S#line%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</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/Reveal.png"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::set_source_link_case appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::html_source_link is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Icons with and without tooltips. </b>Tooltips are the evanescent pop-up windows which appear, a little behind the
mouse arrow, when it is poised waiting over the icon. (We make heavy use of
these in the World index, for instance, to clarify what abbreviations mean.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_icon_with_tooltip</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">icon_name</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">tip</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">tip2</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/%s "</span><span class="plain">, </span><span class="identifier">icon_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tip</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"title=\</span><span class="plain">"</span><span class="string">%s"</span><span class="plain">, </span><span class="identifier">tip</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tip2</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">" %s"</span><span class="plain">, </span><span class="identifier">tip2</span><span class="plain">); </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</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">"%S"</span><span class="plain">, </span><span class="identifier">img</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::html_icon_with_tooltip is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Outcome images. </b>These are the two images used on the Problems page to visually indicate
success or failure. We also use special images on special occasions.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain"> 2</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">outcome_image_style</span><span class="plain"> = </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_outcome_image</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">image</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">verdict</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">""</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">be_festive</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">internal_error_thrown</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">be_festive</span><span class="plain"> = </span><span class="identifier">FALSE</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">be_festive</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">Time::feast</span><span class="plain">()) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">CHRISTMAS_FEAST</span><span class="plain">: </span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">"_2"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">EASTER_FEAST</span><span class="plain">: </span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">"_3"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vn</span><span class="plain">[0]) </span><span class="identifier">outcome_image_style</span><span class="plain"> = </span><span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="identifier">Problems::Issue::issue_problems_banner</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">verdict</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">outcome_image_style</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</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_OPEN</span><span class="plain">(</span><span class="string">"center"</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">"src=inform:/outcome_images/%s%s.png border=0"</span><span class="plain">, </span><span class="identifier">image</span><span class="plain">, </span><span class="identifier">vn</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"center"</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</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">, 110);</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:/outcome_images/%s%s@2x.png border=1 width=100 height=100"</span><span class="plain">, </span><span class="identifier">image</span><span class="plain">, </span><span class="identifier">vn</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="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HEADNOTE"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"style=\</span><span class="plain">"</span><span class="string">margin-top:0;\</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">"(Each time &lt;b&gt;Go&lt;/b&gt; or &lt;b&gt;Replay&lt;/b&gt; is clicked, Inform tries to "</span>
<span class="string">"translate the source text into a working story, and updates this report.)"</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="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PROBLEMS BEGIN"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::outcome_image_tail</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">outcome_image_style</span><span class="plain"> == </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain">) {</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PROBLEMS END"</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FOOTNOTE"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::html_outcome_image appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::outcome_image_tail appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Header and footer. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_header</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">title</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::incorporate_CSS</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
<span class="identifier">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">CSS_FOR_STANDARD_PAGES_IRES</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">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span><span class="plain">));</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">INDEX_MODULE</span>
<span class="identifier">Index::scripting</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</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::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CONTENT BEGINS"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_footer</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">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CONTENT ENDS"</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 HTMLFiles::html_header appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::html_footer appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. HTML paragraphs with indentation. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">class</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">margin</span><span class="plain"> = </span><span class="identifier">depth</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">margin</span><span class="plain"> &lt; 1) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"minimal HTML indentation is 1"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">margin</span><span class="plain"> &gt; 9) </span><span class="identifier">margin</span><span class="plain"> = 9;</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">%sin%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">class</span><span class="plain">, </span><span class="identifier">margin</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">depth</span><span class="plain"> &gt; 9) { </span><span class="identifier">depth</span><span class="plain">--; </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">); }</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::open_para appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Writing HTML characters. </b>The following routine is a low-level filter which takes ISO Latin-1
characters one at a time, feeding them out to the given stream with any
unsafe characters converted to suitable HTML elements. (The stream writer
will transcode to UTF-8 encoding, since all HTML file streams written by
Inform are declared as having the UTF-8 character encoding.)
</p>
<p class="inwebparagraph">Recall that a source reference is fed into <code class="display"><span class="extract">HTMLFiles::char_out</span></code> as the
following stream of characters:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">*source text*Source/story.ni*14*</span></code>
</p>
<p class="inwebparagraph">(with <code class="display"><span class="extract">SOURCE_REF_CHAR</span></code> used in place of the asterisk).
</p>
<p class="inwebparagraph">When we notice the trigger character, we cease to output HTML and instead
buffer up the reference until we reach the terminating trigger character:
we then parse a little, tidy up and send it to <code class="display"><span class="extract">HTMLFiles::html_source_link</span></code> to be
turned into a <code class="display"><span class="extract">source:</span></code> link.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">source_ref_fields</span><span class="plain">[3] = { </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> }; </span> <span class="comment">paraphrase, filename, line</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_ref_field</span><span class="plain"> = -1; </span> <span class="comment">which field we are buffering</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::char_out</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">charcode</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_field</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">] == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">] = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">charcode</span><span class="plain"> != </span><span class="identifier">SOURCE_REF_CHAR</span><span class="plain">) { </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">], </span><span class="identifier">charcode</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">], </span><span class="identifier">charcode</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">charcode</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'"'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;quot;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;lt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&gt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;amp;"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NEWLINE_IN_STRING</span><span class="plain">: </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">FORCE_NEW_PARA_CHAR</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="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">in2\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">HTMLFiles::html_icon_with_tooltip</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"ornament_flower.png"</span><span class="plain">, </span><span class="identifier">NULL</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">"&amp;nbsp;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">SOURCE_REF_CHAR</span><span class="plain">:</span>
<span class="identifier">source_ref_field</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_field</span><span class="plain"> == 3) {</span>
<span class="identifier">source_ref_field</span><span class="plain"> = -1;</span>
<span class="identifier">source_location</span><span class="plain"> </span><span class="identifier">sl</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">TextFromFiles::filename_to_source_file</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[1]);</span>
<span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</span><span class="plain"> = </span><span class="identifier">Str::atoi</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[2], 0);</span>
<span class="functiontext">HTMLFiles::html_source_link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">]);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">charcode</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::char_out is used in 2/hd (<a href="2-hd.html#SP9_5">&#167;9.5</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Writing streams in XML-escaped form. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::write_xml_safe_text</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">txt</span><span class="plain">) {</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;amp;"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;lt;"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&gt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;gt;"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</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 HTMLFiles::write_xml_safe_text appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: HTML.)</i></li><li><a href="2-jp.html">Continue with 'Javascript Pastes'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>