1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-17 06:24:24 +03:00
inform7/docs/problems-module/2-pl1.html
2020-05-03 16:34:53 +01:00

418 lines
75 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Problems, Level 1</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</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="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</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.html"><span class="selectedlink">problems</span></a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Problems, Level 1' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">problems</a></li><li><a href="index.html#2">Chapter 2: Problems</a></li><li><b>Problems, Level 1</b></li></ul></div>
<p class="purpose">To render problem messages either as plain text or HTML, and write them out to files.</p>
<ul class="toc"><li><a href="2-pl1.html#SP1">&#167;1. Buffering</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Buffering. </b>Only one error text needs to be stored in memory at any one time, so we keep
it in a single text stream:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::clear</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Problems::Buffer::clear</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>Roughly speaking, text for problem messages comes from two possible sources:
fairly short standard texts inside Inform, and quotations (direct or indirect)
from the source text. The latter are inserted by the routines in this section,
and they are the ones we should be wary of, since bizarre input might cause
absurdly long quotations to be made. A quotation involves copying text from
word <span class="extract"><span class="extract-syntax">w1</span></span> to <span class="extract"><span class="extract-syntax">w2</span></span>, so there are two dangers: copying a single very long word,
or copying too many of them. We protect against the first by using the
<span class="extract"><span class="extract-syntax">%&lt;W</span></span> escape, which truncates long literals. We protect against the second
overflow hazard by limiting the amount of text we are prepared to quote from
any sentence in one go:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">QUOTATION_TOLERANCE_LIMIT</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::copy_text_into_problem_buffer</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Problems::Buffer::copy_text_into_problem_buffer</span></span>:<br/><a href="2-pl1.html#SP4">&#167;4</a><br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP11_1_1">&#167;11.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::truncate</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="constant-syntax">QUOTATION_TOLERANCE_LIMIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"%&lt;W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>Diverting source quotes.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::redirect_problem_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from</span><span class="plain-syntax">; </span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">A</span><span class="plain-syntax">; </span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>A special escape sequence, marked by starting and finishing with a character
which otherwise can never occur, is expanded to a source code link. If we used
an asterisk to denote this, then a source reference is fed into
<span class="extract"><span class="extract-syntax">HTMLFiles::char_out</span></span> as the following stream of characters:
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">*source text*Source/story.ni*14*</span></span>
</p>
<p class="commentary">(with <span class="extract"><span class="extract-syntax">SOURCE_REF_CHAR</span></span> used in place of the asterisk).
</p>
<p class="commentary">But of course we don't use an asterisk as trigger &mdash; we use character <span class="extract"><span class="extract-syntax">F0</span></span>.
Arguably this is dodgy, since the character is legal in ISO Latin-1. But it
is a lower-case Icelandic eth, which is not allowed in unquoted Inform 7 source
text (because of being absent from the ZSCII character set).
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\xf0'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FORCE_NEW_PARA_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\xd0'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\x01'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="character-syntax">'\x02'</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::copy_source_reference_into_problem_buffer</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Problems::Buffer::copy_source_reference_into_problem_buffer</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP10">&#167;10</a>, <a href="2-pl2.html#SP11_1_1">&#167;11.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;no text&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">source_file</span><span class="plain-syntax"> *</span><span class="identifier-syntax">referred</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">referred</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TextFromFiles::get_filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">referred</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">SUPERVISOR_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Projects::path</span><span class="plain-syntax">(</span><span class="identifier-syntax">Supervisor::project</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">proj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">proj</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::prefix_eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::delete_n_characters</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">project_prefix</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">, </span><span class="string-syntax">"(no file)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"'"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP2" class="function-link"><span class="function-syntax">Problems::Buffer::copy_text_into_problem_buffer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">file</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">SUPERVISOR_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"source text"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Extensions::corresponding_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">referred</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">work</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">work</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Works::is_standard_rules</span><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"the Standard Rules"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">work</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Works::is_basic_inform</span><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"Basic Inform"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">file</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">"' %c%S%c%S%c%d%c"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">paraphrase</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">file</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::location</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">).</span><span class="identifier-syntax">line_number</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_sentence</span><span class="plain-syntax">), </span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">" (which asserts that "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP4" class="function-link"><span class="function-syntax">Problems::Buffer::copy_source_reference_into_problem_buffer</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_to_A</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">" is/are "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP4" class="function-link"><span class="function-syntax">Problems::Buffer::copy_source_reference_into_problem_buffer</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">redirected_to_B</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>Once the error message is fully constructed, we will want to output it
to a file: in fact, by default it will go in three directions, to
<span class="extract"><span class="extract-syntax">stderr</span></span>, to the debugging log and of course to the error log. The main
thing is to word-wrap it, since it is likely to be a paragraph-sized
chunk of text, not a single line. The unprintable <span class="extract"><span class="extract-syntax">SOURCE_REF_CHAR</span></span> and
<span class="extract"><span class="extract-syntax">FORCE_NEW_PARA_CHAR</span></span> are simply filtered out for plain text output: for
HTML, they are dealt with elsewhere.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">define</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></span>:<br/><a href="2-pl1.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> == </span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">) </span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">indentation</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">+=2; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">L</span><span class="plain-syntax">=</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">In HTML mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">In plain text mode, remove bold and italic HTML tags</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">Issue plain text paraphrase of source reference</span><span class="named-paragraph-number">5.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1"></a><b>&#167;5.1. </b>The plain text "may I draw your attention to the following paragraph"
marker,
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">&gt;--&gt; Which looks like this.</span></span>
</p>
<p class="commentary">is converted into a suitable CSS-styled HTML paragraph with hanging
indentation. And similarly for <span class="extract"><span class="extract-syntax">&gt;++&gt;</span></span>, used to mark continuations.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In HTML mode, convert drawing-your-attention arrows</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&gt;--&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"hang\""</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;Problem.&lt;/b&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">+=3; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&gt;++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"in2\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">+=3; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&gt;---&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">); </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">problem_count_at_last_in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">+=4; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&gt;+++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"halftightin3\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">+=4; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&gt;++++&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"class=\"tightin3\""</span><span class="plain-syntax">) </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">+=5; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2"></a><b>&#167;5.2. </b>The problem messages are put together (by Level 2 below) in a plain text
way, but with a little formatting included: in particular, they contain
HTML-style <span class="extract"><span class="extract-syntax">&lt;i&gt;</span></span>, <span class="extract"><span class="extract-syntax">&lt;b&gt;</span></span> and <span class="extract"><span class="extract-syntax">&lt;span&gt;</span></span> tags, which the following code strips
out when writing to plain text format.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In plain text mode, remove bold and italic HTML tags</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;i&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;b&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;img&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;a&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;font&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;i "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;b "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;img "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;a "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;font "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;span "</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/i&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/b&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/img&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/a&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/span&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::includes_wide_string_at_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"&lt;/font&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3"></a><b>&#167;5.3. </b>Okay, so the format for a source reference here is:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> XparaphraseXfilenameXnumberX</span>
</pre>
<p class="commentary">e.g., <span class="extract"><span class="extract-syntax">Xmain textXsource/story.niX102</span></span>, where <span class="extract"><span class="extract-syntax">X</span></span> is the unprintable
<span class="extract"><span class="extract-syntax">SOURCE_REF_CHAR</span></span>. The counter <span class="extract"><span class="extract-syntax">i</span></span> is at the first <span class="extract"><span class="extract-syntax">X</span></span>, and we must now
convert this to something fit for printing to <span class="extract"><span class="extract-syntax">stdout</span></span>, finishing up with <span class="extract"><span class="extract-syntax">i</span></span>
pointing to the last <span class="extract"><span class="extract-syntax">X</span></span>.
</p>
<p class="commentary">We always use the paraphrase, not the filename, on <span class="extract"><span class="extract-syntax">stdout</span></span> because (i) that's
slightly easier to understand for the user, but more importantly (ii) it
makes the output the same on all platforms when only main text and Standard
Rules are referred to, and that simplifies <span class="extract"><span class="extract-syntax">intest</span></span> and the Test Suite quite
a bit, because we don't have to worry about trivial differences between OS X
and Windows caused by the slashes going the wrong way, and so on.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue plain text paraphrase of source reference</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) ;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", line "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> += </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">i</span><span class="plain-syntax">) != </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">Output single character of problem message</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4"></a><b>&#167;5.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Output single character of problem message</span><span class="named-paragraph-number">5.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> this starts a run of whitespace</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">))) </span><span class="identifier-syntax">l</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> omit any trailing spaces</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">l</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> skip to final whitespace character of the run</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">' '</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pl1.html#SP5_4_1" class="named-paragraph-link"><span class="named-paragraph">In plain text mode, wrap the line or print a space as necessary</span><span class="named-paragraph-number">5.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_LT_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">PROTECTED_GT_CHAR</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">html_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">PROBLEMS_HTML_EMITTER</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="constant-syntax">FORCE_NEW_PARA_CHAR</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%c"</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5">&#167;5</a>, <a href="2-pl1.html#SP5_3">&#167;5.3</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4_1"></a><b>&#167;5.4.1. </b>At this point, <span class="extract"><span class="extract-syntax">l</span></span> is the position of the first non-whitespace character
after the sequence of whitespace.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain-syntax"> </span><span class="constant-syntax">80</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">In plain text mode, wrap the line or print a space as necessary</span><span class="named-paragraph-number">5.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">word_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((!</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">))) &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">PBUFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">l</span><span class="plain-syntax">) != </span><span class="constant-syntax">SOURCE_REF_CHAR</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">++, </span><span class="identifier-syntax">word_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> + </span><span class="identifier-syntax">word_width</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">l</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">l</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">indentation</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">l</span><span class="plain-syntax">++) { </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">+=2; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><span class="identifier-syntax">line_width</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-pl1.html#SP5_4">&#167;5.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>The following handles the three-way distribution of problems, but also
allows us to route individual messages to only one output of our choice by
temporarily setting the <span class="extract"><span class="extract-syntax">probl</span></span> variable: which is a convenience for
informational messages such as appear in index files, for instance.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::redirect_problem_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">probl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">telemetry_recording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Problems::Buffer::output_problem_buffer</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Problems::Buffer::output_problem_buffer</span></span>:<br/>Problems, Level 2 - <a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">probl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">problems_file</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_FLUSH</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">telemetry_recording</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">telmy</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">telmy</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">telmy</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="2-pl1.html#SP5" class="function-link"><span class="function-syntax">Problems::Buffer::output_problem_buffer_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">probl</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-pl0.html">&#10094;</a></li><li class="progresschapter"><a href="1-pm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-pl0.html">pl0</a></li><li class="progresscurrent">pl1</li><li class="progresssection"><a href="2-pl2.html">pl2</a></li><li class="progresssection"><a href="2-pl3.html">pl3</a></li><li class="progressnext"><a href="2-pl2.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>