1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/indoc/2-rr.html

709 lines
78 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/rnd</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 '2/rr' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">indoc 4</a></li><li><a href="index.html#2">Chapter 2: Processing</a></li><li><b>Rawtext Reader</b></li></ul><p class="purpose">Reading the rawtext in, breaking it up into blocks, and sending them for output as formatted documentation.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. The rawtext files</a></li><li><a href="#SP3">&#167;3. The scanner</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. The rawtext files. </b>This reads an entire rawtext volume.
</p>
<pre class="display">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="functiontext">Rawtext::process_large_rawtext_file</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">volume</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
<span class="reserved">rawtext_helper_state</span><span class="plain"> </span><span class="identifier">rhs</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="element">.V</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="element">.OUT</span><span class="plain"> = </span><span class="identifier">OUT</span><span class="plain">;</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext">Rawtext::turn_rawtext_into_blocks</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;vol_rawtext_filename</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext">Renderer::close_formatted_file</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="reserved">return</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 Rawtext::process_large_rawtext_file is used in 1/mn (<a href="1-mn.html#SP1_3">&#167;1.3</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The other source of rawtext is an Example file. These, however, start with
a three-line header containing metadata &mdash; we need to skip this before
running the rawtext scanner. Examples are rendered as partial files, not as
multi-section rawtext volumes.
</p>
<pre class="display">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="functiontext">Rawtext::process_example_rawtext_file</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">,</span>
<span class="reserved">volume</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">example</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext">Rawtext::turn_rawtext_into_blocks</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;ex_filename</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
<span class="reserved">return</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 Rawtext::process_example_rawtext_file is used in 2/rnd (<a href="2-rnd.html#SP10">&#167;10</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The scanner. </b>And here is the common scanner used for both.
</p>
<p class="inwebparagraph">"Rawtext" is the very lightly marked-up form of plain text in which the Inform
manuals are written. Perhaps I should have used Markdown or REST, but those
formats were less well-known in the early 2000s, so rawtext is its own unique
flower.
</p>
<p class="inwebparagraph">A rawtext file is divided up into one or more blocks. The first of these
can optionally be introduced by a block heading line; any subsequent ones
must be. (A block ends when a new heading line appears, or at end of file.)
</p>
<pre class="display">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="functiontext">Rawtext::turn_rawtext_into_blocks</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">,</span>
<span class="reserved">volume</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">render_as_partial_file_only</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">example</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="reserved">rawtext_helper_state</span><span class="plain"> </span><span class="identifier">rhs_structure</span><span class="plain">;</span>
<span class="reserved">rawtext_helper_state</span><span class="plain"> *</span><span class="identifier">rhs</span><span class="plain"> = &amp;</span><span class="identifier">rhs_structure</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;OUT</span><span class="plain"> = </span><span class="identifier">OUT</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;E</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skipping_current_block</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain"> = 0;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;this_is_first_block_in_file</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;partial_only</span><span class="plain"> = </span><span class="identifier">render_as_partial_file_only</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_chapters_read_in_current_rawtext</span><span class="plain"> = 0;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_read_in_current_chapter</span><span class="plain"> = 0;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_pars_read_in_current_block</span><span class="plain"> = 0;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;title_of_block_being_read</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">(); </span> <span class="comment">Untitled until a block heading found</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</span><span class="plain">) </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skip_opening_lines</span><span class="plain"> = 3;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skip_opening_lines</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Prepare to read a new chapter of rawtext</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Prepare to read a new block of rawtext</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Scan the file and render blocks as they complete</span> <span class="cwebmacronumber">3.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Render the block just completed, unless it's empty</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="character">;</span>
<span class="functiontext">Str::dispose_of</span><span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;title_of_block_being_read</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">OUT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rawtext_helper_state</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">volume</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">example</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">skipping_current_block</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">skip_opening_lines</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_blocks_written</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_is_first_block_in_file</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_chapters_read_in_current_rawtext</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_blocks_read_in_current_chapter</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_pars_read_in_current_block</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">partial_only</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">title_of_block_being_read</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">rawtext_helper_state</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rawtext::turn_rawtext_into_blocks is used in <a href="#SP1">&#167;1</a>, <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The structure rawtext_helper_state is accessed in 2/exm, 2/utsr, 2/css and here.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Prepare to read a new chapter of rawtext</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_read_in_current_chapter</span><span class="plain"> = 0;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>, <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Prepare to read a new block of rawtext</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_read_in_current_chapter</span><span class="plain">++;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_pars_read_in_current_block</span><span class="plain"> = 0;</span>
<span class="functiontext">Renderer::clear_block_buffer</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>, <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Render the block just completed, unless it's empty</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_pars_read_in_current_block</span><span class="plain"> &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;E</span><span class="plain">) &amp;&amp; (</span><span class="identifier">no_paras_in_block_buffer</span><span class="plain"> &gt; 0)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">paragraphs</span><span class="plain">[</span><span class="identifier">no_paras_in_block_buffer</span><span class="plain">-1]</span><span class="element">.par_texts</span><span class="plain">) == 0) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">paragraphs</span><span class="plain">[</span><span class="identifier">no_paras_in_block_buffer</span><span class="plain">-1]</span><span class="element">.par_shortened</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="identifier">no_paras_in_block_buffer</span><span class="plain">--;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;partial_only</span><span class="plain">) {</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext">Renderer::render_text_of_block</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">index_to_examples</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext">Renderer::render_block</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">)?(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">-</span><span class="element">&gt;sections</span><span class="plain">[</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">]):</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;OUT</span><span class="plain"> = </span><span class="identifier">OUT</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;this_is_first_block_in_file</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">++;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>, <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Scan the file and render blocks as they complete</span> <span class="cwebmacronumber">3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">TextFiles::read</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="string">"can't open rawtext file"</span><span class="plain">,</span>
<span class="constant">TRUE</span><span class="plain">, </span><span class="functiontext">Rawtext::process_large_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">);</span>
<span class="identifier">OUT</span><span class="plain"> = </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;OUT</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rawtext::process_large_helper</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">rawl</span><span class="plain">, </span><span class="reserved">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">,</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">v_rhs</span><span class="plain">) {</span>
<span class="reserved">rawtext_helper_state</span><span class="plain"> *</span><span class="identifier">rhs</span><span class="plain"> = (</span><span class="reserved">rawtext_helper_state</span><span class="plain"> *) </span><span class="identifier">v_rhs</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skip_opening_lines</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skip_opening_lines</span><span class="plain">--; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">shortened</span><span class="plain"> = </span><span class="functiontext">Str::trim_white_space_at_end</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"%[(%c*?)%] (%c*)"</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Deal with a block heading</span> <span class="cwebmacronumber">4.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skipping_current_block</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">suppress_p_tag</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">HTML_prefix</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">css_style</span><span class="plain">);</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr2</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Deal with any permitted markup</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;treat_code_as_verbatim</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) || (</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">) != </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Deal with an insert-change-log notation</span> <span class="cwebmacronumber">4.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Deal with an insert-image notation</span> <span class="cwebmacronumber">4.5</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">abandon_para</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Deal with paragraph tags</span> <span class="cwebmacronumber">4.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">abandon_para</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Deal with a regular paragraph</span> <span class="cwebmacronumber">4.7</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">HTML_prefix</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">css_style</span><span class="plain">);</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rawtext::process_large_helper is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b>Block headings are paragraphs beginning with square-bracketed material:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">[x] The footwear kind</span>
</pre>
<p class="inwebparagraph">This one is a typical section heading. The <code class="display"><span class="extract">[x]</span></code> marks it as being a mere
level-B heading in the book; "The footwear kind" is the text of the title;
the braced <code class="display"><span class="extract">{kind_footwear}</span></code> is another documentation reference.
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">x</span></code> text is a meaningless placeholder. The way to get this noticed
is to write something like:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">[Chapter: Bananas] Introduction to soft yellow fruit</span>
</pre>
<p class="inwebparagraph">which creates a new chapter called "Bananas", within which this block will
be the first section.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with a block heading</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">block_header</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]; </span> <span class="comment">The text in the square brackets</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">title</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1];</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skipping_current_block</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr2</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">, </span><span class="identifier">block_header</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"{(%c*?):}(%c*?)"</span><span class="plain">)) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">block_header</span><span class="plain">, </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Symbols::perform_ifdef</span><span class="plain">(</span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[0]) == </span><span class="constant">FALSE</span><span class="plain">) {</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skipping_current_block</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;skipping_current_block</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;OUT</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Render the block just completed, unless it's empty</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="character">;</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;OUT</span><span class="plain"> = </span><span class="identifier">OUT</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Take note of documentation references</span> <span class="cwebmacronumber">4.1.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;title_of_block_being_read</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">, </span><span class="identifier">block_header</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Chapter: (%c*)"</span><span class="plain">)) {</span>
<span class="plain">++(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_chapters_read_in_current_rawtext</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Prepare to read a new chapter of rawtext</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Prepare to read a new block of rawtext</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_1_1"></a><b>&#167;4.1.1. </b>Section headings can be marked with braced documentation references:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">[x] The footwear kind {kind_footwear}</span>
&lt;<span class="cwebmacrodefn">Take note of documentation references</span> <span class="cwebmacronumber">4.1.1</span>&gt; =
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*) {(%C+)} *"</span><span class="plain">)) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="functiontext">Updater::add_reference_symbol</span><span class="plain">(</span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[1], </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">)?(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">-</span><span class="element">&gt;sections</span><span class="plain">[</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">]):</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b>Rawtext is not allowed to contain direct HTML markup, but it can contain
"span notations", which can in turn be configured to look like HTML markup.
So, for instance, the Inform documentation uses <code class="display"><span class="extract">&lt;b&gt;...&lt;/b&gt;</span></code> for bold and
<code class="display"><span class="extract">&lt;i&gt;...&lt;/i&gt;</span></code> for italic, but this is only because its instructions say so.
</p>
<p class="inwebparagraph">(We also look for indexing markup, and we need to do that first, because
smoke-test indexing mode applies direct markup to make its smoky black
rectangles.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with any permitted markup</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;treat_code_as_verbatim</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) || (</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">) != </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">)) {</span>
<span class="functiontext">Indexes::scan_indexingnotations</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">)?(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">-</span><span class="element">&gt;sections</span><span class="plain">[</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">]):</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;E</span><span class="plain">);</span>
<span class="functiontext">CSS::expand_spannotations</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="constant">MARKUP_SPP</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) </span><span class="functiontext">Regexp::replace</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;(%c*?)&gt;"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&amp;lt;%0&amp;gt;"</span><span class="plain">, </span><span class="constant">REP_REPEATING</span><span class="plain">);</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">replacement</span><span class="plain"> = </span><span class="identifier">L</span><span class="string">"%1"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) </span><span class="identifier">replacement</span><span class="plain"> = </span><span class="identifier">L</span><span class="string">"&lt;span class=\</span><span class="plain">"</span><span class="string">%0\</span><span class="plain">"</span><span class="string">&gt;%1&lt;/span&gt;"</span><span class="plain">;</span>
<span class="functiontext">Regexp::replace</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"___mu___(%c*?)___mo___(%c*?)___mc___"</span><span class="plain">, </span><span class="identifier">replacement</span><span class="plain">, </span><span class="constant">REP_REPEATING</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_3"></a><b>&#167;4.3. </b>The notation <code class="display"><span class="extract">///6X12.txt///</span></code> means "insert the change log for build 6X12 here".
It should be the only thing on its line.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with an insert-change-log notation</span> <span class="cwebmacronumber">4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*?)///(%c*?).txt/// *"</span><span class="plain">)) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="functiontext">HTML::hr</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="functiontext">HTML::open</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"pre"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"class='changelog'"</span><span class="plain">);</span>
<span class="identifier">suppress_p_tag</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">cl</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;change_logs_folder</span><span class="plain">, </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="functiontext">TextFiles::read</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="string">"can't open change log file"</span><span class="plain">,</span>
<span class="constant">TRUE</span><span class="plain">, </span><span class="functiontext">Rawtext::process_change_log_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">HTML::close</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"pre"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_4"></a><b>&#167;4.4. </b>Where, almost verbatim, we copy from the change log into the raw-line:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rawtext::process_change_log_helper</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">sml</span><span class="plain">, </span><span class="reserved">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">,</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">v_rawl</span><span class="plain">) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">rawl</span><span class="plain"> = (</span><span class="reserved">text_stream</span><span class="plain"> *) </span><span class="identifier">v_rawl</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="functiontext">Regexp::replace</span><span class="plain">(</span><span class="identifier">sml</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&amp;lt;"</span><span class="plain">, </span><span class="constant">REP_REPEATING</span><span class="plain">);</span>
<span class="functiontext">Regexp::replace</span><span class="plain">(</span><span class="identifier">sml</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&amp;gt;"</span><span class="plain">, </span><span class="constant">REP_REPEATING</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">sml</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rawtext::process_change_log_helper is used in <a href="#SP4_3">&#167;4.3</a>.</p>
<p class="inwebparagraph"><a id="SP4_5"></a><b>&#167;4.5. </b>Images are embedded with the notation
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">///filename.extension///</span>
</pre>
<p class="inwebparagraph">though only one of these may appear in each line. If the form
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">///classname:filename.extension///</span>
</pre>
<p class="inwebparagraph">is used, then the image is styled as <code class="display"><span class="extract">img.classname</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with an insert-image notation</span> <span class="cwebmacronumber">4.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*?)///(%c*?)///(%c*)"</span><span class="plain">)) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">left</span><span class="plain"> = </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain"> = </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[1];</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">mr2</span><span class="element">.exp</span><span class="plain">[2];</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr3</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr3</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*?): *(%c*)"</span><span class="plain">)) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="identifier">mr3</span><span class="element">.exp</span><span class="plain">[0]); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">mr3</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr3</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">);</span>
<span class="functiontext">HTMLUtilities::image_URL</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">);</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">left</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">details</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">details</span><span class="plain">, </span><span class="string">"alt=\</span><span class="plain">"</span><span class="string">%S\</span><span class="plain">"</span><span class="string"> src=\</span><span class="plain">"</span><span class="string">%S\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">url</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">) &gt; 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">details</span><span class="plain">, </span><span class="string">" class=\</span><span class="plain">"</span><span class="string">%S\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">);</span>
<span class="functiontext">HTML::tag_sc</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"img"</span><span class="plain">, </span><span class="identifier">details</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">details</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">right</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S(Image %S here)%S"</span><span class="plain">, </span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">right</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_6"></a><b>&#167;4.6. </b>A paragraph beginning with braced material, <code class="display"><span class="extract">{thus}</span></code>, is "tagged". There
can be multiple tags, in principle, which is why this is arranged as a loop,
though it's not often needed more than once. Tags are simply markers which
annotate the paragraph, so we extract each in turn from the left-hand side,
then act accordingly.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with paragraph tags</span> <span class="cwebmacronumber">4.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr3</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr4</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr3</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"{(%c*?)}(%c*)"</span><span class="plain">)) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">paragraph_tag</span><span class="plain"> = </span><span class="identifier">mr3</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">mr3</span><span class="element">.exp</span><span class="plain">[1]);</span>
&lt;<span class="cwebmacro">Deal with a conditional paragraph tag</span> <span class="cwebmacronumber">4.6.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Deal with a phrase definition paragraph tag</span> <span class="cwebmacronumber">4.6.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Deal with a CSS-styling paragraph tag</span> <span class="cwebmacronumber">4.6.3</span>&gt;<span class="plain">;</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"{%S} is not a tag I know"</span><span class="plain">, </span><span class="identifier">paragraph_tag</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr3</span><span class="plain">);</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr4</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_6_1"></a><b>&#167;4.6.1. </b>One use of paragraph tags is to mark a paragraph as being relevant only
to one of the platforms on which Inform runs. (We've already seen this done
for whole blocks of documentation: this is much finer control.) For example,
documentation might say:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{Windows}The My Documents folder can be reached using...</span>
</pre>
<p class="inwebparagraph">If we're generating for Windows, we ignore the tag: this looks like a
regular paragraph to us. If we're generating for some other platform, we
throw the whole paragraph away. If we're generating for no specific platform
(for example, for the Inform website), we keep the paragraph but annotate it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with a conditional paragraph tag</span> <span class="cwebmacronumber">4.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr4</span><span class="plain">, </span><span class="identifier">paragraph_tag</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*):"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Symbols::perform_ifdef</span><span class="plain">(</span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[0])) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">abandon_para</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_6">&#167;4.6</a>.</p>
<p class="inwebparagraph"><a id="SP4_6_2"></a><b>&#167;4.6.2. </b>Tags also mark the presence of phrase explanations in the main WWI:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{defn ph_letdefault}let (a name not so far used) be (name of kind)</span>
<span class="plain">...</span>
<span class="plain">{end}</span>
&lt;<span class="cwebmacrodefn">Deal with a phrase definition paragraph tag</span> <span class="cwebmacronumber">4.6.2</span>&gt; =
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr4</span><span class="plain">, </span><span class="identifier">paragraph_tag</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"defn *(%c*?)"</span><span class="plain">)) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">defn</span><span class="plain"> = </span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Characters::is_whitespace</span><span class="plain">(</span><span class="functiontext">Str::get_last_char</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">)))</span>
<span class="functiontext">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">);</span>
<span class="functiontext">Updater::add_reference_symbol</span><span class="plain">(</span><span class="identifier">defn</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">, (</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">)?(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">-</span><span class="element">&gt;sections</span><span class="plain">[</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">]):</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="functiontext">HTMLUtilities::definition_box</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">head</span><span class="plain">, </span><span class="identifier">defn</span><span class="plain">, </span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">)?(</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;V</span><span class="plain">-</span><span class="element">&gt;sections</span><span class="plain">[</span><span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_blocks_written</span><span class="plain">]):</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">suppress_p_tag</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">paragraph_tag</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"end"</span><span class="plain">)) {</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="functiontext">HTMLUtilities::end_definition_box</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="identifier">suppress_p_tag</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_6">&#167;4.6</a>.</p>
<p class="inwebparagraph"><a id="SP4_6_3"></a><b>&#167;4.6.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Deal with a CSS-styling paragraph tag</span> <span class="cwebmacronumber">4.6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr4</span><span class="plain">, </span><span class="identifier">paragraph_tag</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*)/"</span><span class="plain">)) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">css_style</span><span class="plain">, </span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_6">&#167;4.6</a>.</p>
<p class="inwebparagraph"><a id="SP4_7"></a><b>&#167;4.7. </b>Finally, then, we're left with a regular paragraph. It was never a
block heading, and whatever tags it once had have been removed.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deal with a regular paragraph</span> <span class="cwebmacronumber">4.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">indentation_count</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Establish the indentation level</span> <span class="cwebmacronumber">4.7.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Treat the text as necessary</span> <span class="cwebmacronumber">4.7.2</span>&gt;<span class="plain">;</span>
<span class="functiontext">Renderer::add_para_to_block_buffer</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="identifier">indentation_count</span><span class="plain">, </span><span class="identifier">suppress_p_tag</span><span class="plain">,</span>
<span class="identifier">HTML_prefix</span><span class="plain">, </span><span class="identifier">css_style</span><span class="plain">, </span><span class="identifier">shortened</span><span class="plain">);</span>
<span class="identifier">rhs</span><span class="plain">-</span><span class="element">&gt;no_pars_read_in_current_block</span><span class="plain">++;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_7_1"></a><b>&#167;4.7.1. </b>Initial tab characters (alone) are read as indentation.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Establish the indentation level</span> <span class="cwebmacronumber">4.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">) {</span>
<span class="identifier">indentation_count</span><span class="plain">++;</span>
<span class="functiontext">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_7">&#167;4.7</a>.</p>
<p class="inwebparagraph"><a id="SP4_7_2"></a><b>&#167;4.7.2. </b>In the case of HTML, we need to be careful not to turn double-quotes used
in tag elements into <code class="display"><span class="extract">&amp;quot;</span></code> escapes.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Treat the text as necessary</span> <span class="cwebmacronumber">4.7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">dequotee</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">dequotee</span><span class="plain">, </span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">);</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr4</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr4</span><span class="plain">, </span><span class="identifier">dequotee</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*?)&lt;(%c*?)&gt;(%c*)"</span><span class="plain">)) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[0]; </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">M</span><span class="plain"> = </span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[1]; </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">mr4</span><span class="element">.exp</span><span class="plain">[2];</span>
<span class="functiontext">Rawtext::escape_HTML_characters_in</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S&lt;%S&gt;"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">M</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">dequotee</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Rawtext::escape_HTML_characters_in</span><span class="plain">(</span><span class="identifier">dequotee</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">rawl</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">dequotee</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_7">&#167;4.7</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rawtext::escape_HTML_characters_in</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indoc_settings</span><span class="plain">-</span><span class="element">&gt;format</span><span class="plain"> == </span><span class="constant">HTML_FORMAT</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0, </span><span class="identifier">L</span><span class="plain">=</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">i</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">'\</span><span class="plain">"</span><span class="character">'</span><span class="plain">: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">, </span><span class="string">"&amp;quot;"</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_TO</span><span class="plain">(</span><span class="identifier">modified</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_TO</span><span class="plain">(</span><span class="identifier">modified</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">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1) == </span><span class="character">'#'</span><span class="plain">) { </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">modified</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="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">+1;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="functiontext">Characters::isalnum</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">))) </span><span class="identifier">j</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">j</span><span class="plain"> &gt; </span><span class="identifier">i</span><span class="plain">+1) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">) == </span><span class="character">';'</span><span class="plain">)) { </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">modified</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="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">modified</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">default</span><span class="plain">: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">modified</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="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">modified</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rawtext::escape_HTML_characters_in is used in <a href="#SP4_7_2">&#167;4.7.2</a>, 2/exm (<a href="2-exm.html#SP8_2_3">&#167;8.2.3</a>), 3/cai (<a href="3-cai.html#SP9_2_3_1">&#167;9.2.3.1</a>), 3/ei (<a href="3-ei.html#SP3_5">&#167;3.5</a>), 4/cr (<a href="4-cr.html#SP6_2">&#167;6.2</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-rnd.html">Back to 'Renderer'</a></li><li><a href="2-utsr.html">Continue with 'Updating the Standard Rules'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>