inweb-bootstrap/docs/inweb/4-pl.html
2020-03-23 15:04:43 +00:00

830 lines
93 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/tt</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../inweb/index.html">inweb</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../foundation-module/index.html">foundation-module</a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '4/pl' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="index.html">inweb</a></li><li><a href="index.html#4">Chapter 4: Languages</a></li><li><b>Programming Languages</b></li></ul><p class="purpose">To characterise the relevant differences in behaviour between the various programming languages supported.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Languages</a></li><li><a href="#SP3">&#167;3. Creation</a></li><li><a href="#SP4">&#167;4. Parsing methods</a></li><li><a href="#SP7">&#167;7. Tangling methods</a></li><li><a href="#SP22">&#167;22. Weaving methods</a></li><li><a href="#SP28">&#167;28. Analysis methods</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Languages. </b>The conventions for writing, weaving and tangling a web are really quite
independent of the programming language being written, woven or tangled;
Knuth began literate programming with Pascal, but now uses C, and the original
Pascal webs were mechanically translated into C ones with remarkably little
fuss or bother. Modern LP tools, such as <code class="display"><span class="extract">noweb</span></code>, aim to be language-agnostic.
But of course if you act the same on all languages, you give up the benefits
which might follow from knowing something about the languages you actually
write in.
</p>
<p class="inwebparagraph">The idea, then, is that Chapters 1 to 3 of the Inweb code treat all
material the same, and Chapter 4 contains all of the funny little exceptions
and special cases for particular programming languages. (This means Chapter 4
can't be understood without having at least browsed Chapters 1 to 3 first.)
</p>
<p class="inwebparagraph">Each language supported by Inweb has an instance of the following structure:
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">programming_language</span><span class="plain"> {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">language_name</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">file_extension</span><span class="plain">; </span> <span class="comment">by default output to a file whose name has this extension</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">source_file_extension</span><span class="plain">; </span> <span class="comment">by default input from a file whose name has this extension</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">supports_enumerations</span><span class="plain">; </span> <span class="comment">as it will, if it belongs to the C family of languages</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">supports_namespaces</span><span class="plain">; </span> <span class="comment">really just for InC</span>
<span class="constant">METHOD_CALLS</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">programming_language</span><span class="plain">;</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">default_language</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">Languages::default</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) { </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">default_language</span><span class="plain">; }</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">ext</span><span class="plain">) {</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain">);</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;language_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;file_extension</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">);</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;supports_enumerations</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;source_file_extension</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">".w"</span><span class="plain">;</span>
<span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">methods</span><span class="plain"> = </span><span class="functiontext">Methods::new_set</span><span class="plain">();</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;supports_namespaces</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">default_language</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">default_language</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::default is used in 2/tr (<a href="2-tr.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Languages::new_language is used in <a href="#SP3">&#167;3</a>, 4/cl (<a href="4-cl.html#SP1">&#167;1</a>), 4/is (<a href="4-is.html#SP1">&#167;1</a>), 4/ps (<a href="4-ps.html#SP1">&#167;1</a>), 4/is2 (<a href="4-is2.html#SP1">&#167;1</a>, <a href="4-is2.html#SP5">&#167;5</a>).</p>
<p class="endnote">The structure programming_language is accessed in 1/pc, 2/tr, 2/ec, 3/tt, 4/cl, 4/is, 4/is2 and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">Languages::find_by_name</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">lname</span><span class="plain">) {</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">lname</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;language_name</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="functiontext">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"unsupported programming language '%S'"</span><span class="plain">, </span><span class="identifier">lname</span><span class="plain">);</span>
<span class="reserved">return</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">The function Languages::find_by_name is used in 2/tr (<a href="2-tr.html#SP9_3_1">&#167;9.3.1</a>, <a href="2-tr.html#SP9_3_3_2_1">&#167;9.3.3.2.1</a>, <a href="2-tr.html#SP9_2_2_3_1">&#167;9.2.2.3.1</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Creation. </b>This must be performed very early in Inweb's run.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::create_programming_languages</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">CLike::create_C</span><span class="plain">(); </span> <span class="comment">must be first, to make C the default language</span>
<span class="functiontext">CLike::create_CPP</span><span class="plain">();</span>
<span class="functiontext">InCSupport::create</span><span class="plain">();</span>
<span class="functiontext">InformSupport::create_I6</span><span class="plain">();</span>
<span class="functiontext">InformSupport::create_I7</span><span class="plain">();</span>
<span class="functiontext">PerlSupport::create</span><span class="plain">();</span>
<span class="comment">together with a featureless language:</span>
<span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Plain Text"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">".txt"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::create_programming_languages is used in 1/pc (<a href="1-pc.html#SP6_1">&#167;6.1</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Parsing methods. </b>Really all of the functionality of languages is provided through method calls,
all of them made from this section. That means a lot of simple wrapper routines
which don't do very much. This section may still be useful to read, since it
documents what amounts to an API.
</p>
<p class="inwebparagraph">We begin with parsing extensions. When these are used, we have already read
the web into chapters, sections and paragraphs, but for some languages we will
need a more detailed picture.
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">FURTHER_PARSING_PAR_MTID</span></code> is "further" in that it is called when the main
parser has finished work; it typically looks over the whole web for something
of interest.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">FURTHER_PARSING_PAR_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">FURTHER_PARSING_PAR_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::further_parsing</span><span class="plain">(</span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">FURTHER_PARSING_PAR_MTID</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::further_parsing is used in 2/tp (<a href="2-tp.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b><code class="display"><span class="extract">SUBCATEGORISE_LINE_PAR_MTID</span></code> looks at a single line, after the main parser
has given it a category. The idea is not so much to second-guess the parser
(although we can) but to change to a more exotic category which it would
otherwise never produce.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SUBCATEGORISE_LINE_PAR_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SUBCATEGORISE_LINE_PAR_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::subcategorise_line</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SUBCATEGORISE_LINE_PAR_MTID</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::subcategorise_line is used in 2/tp (<a href="2-tp.html#SP1_1_6_8">&#167;1.1.6.8</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Comments have different syntax in different languages. The method here is
expected to look for a comment on the <code class="display"><span class="extract">line</span></code>, and if so to return <code class="display"><span class="extract">TRUE</span></code>,
but not before splicing the non-comment parts of the line before and
within the comment into the supplied strings.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">PARSE_COMMENT_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">PARSE_COMMENT_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">before</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">within</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::parse_comment</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">,</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">before</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">within</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PARSE_COMMENT_TAN_MTID</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">before</span><span class="plain">, </span><span class="identifier">within</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::parse_comment is used in 2/tp (<a href="2-tp.html#SP1_1_6_5_1_7">&#167;1.1.6.5.1.7</a>), 3/tw (<a href="3-tw.html#SP1_3_3_1_9_4">&#167;1.3.3.1.9.4</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Tangling methods. </b>We take these roughly in order of their effects on the tangled output, from
the top to the bottom of the file.
</p>
<p class="inwebparagraph">The top of the tangled file is a header called the "shebang". By default,
there's nothing there, but <code class="display"><span class="extract">SHEBANG_TAN_MTID</span></code> allows the language to add one.
For example, Perl prints <code class="display"><span class="extract">#!/usr/bin/perl</span></code> here.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SHEBANG_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SHEBANG_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::shebang</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SHEBANG_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">target</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::shebang is used in 3/tt (<a href="3-tt.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Next is the disclaimer, text warning the human reader that she is looking
at tangled (therefore not original) material.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SUPPRESS_DISCLAIMER_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SUPPRESS_DISCLAIMER_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::disclaimer</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">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALLV</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SUPPRESS_DISCLAIMER_TAN_MTID</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Languages::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled output generated by inweb: do not edit"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::disclaimer is used in 3/tt (<a href="3-tt.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Next is the disclaimer, text warning the human reader that she is looking
at tangled (therefore not original) material.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">ADDITIONAL_EARLY_MATTER_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">ADDITIONAL_EARLY_MATTER_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::additional_early_matter</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">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_EARLY_MATTER_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">target</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::additional_early_matter is used in 3/tt (<a href="3-tt.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>A tangled file then normally declares "definitions". The following write a
definition of the constant named <code class="display"><span class="extract">term</span></code> as the value given. If the value spans
multiple lines, the first-line part is supplied to <code class="display"><span class="extract">START_DEFN_TAN_MTID</span></code> and
then subsequent lines are fed in order to <code class="display"><span class="extract">PROLONG_DEFN_TAN_MTID</span></code>. At the end,
<code class="display"><span class="extract">END_DEFN_TAN_MTID</span></code> is called.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">START_DEFN_TAN_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">PROLONG_DEFN_TAN_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">END_DEFN_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">START_DEFN_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">start</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">PROLONG_DEFN_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">more</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">END_DEFN_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::start_definition</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">,</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">start</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">START_DEFN_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">start</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"this programming language does not support @d"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::prolong_definition</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">,</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">more</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PROLONG_DEFN_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">more</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"this programming language does not support multiline @d"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::end_definition</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">,</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">END_DEFN_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::start_definition is used in 2/ec (<a href="2-ec.html#SP4">&#167;4</a>), 3/tt (<a href="3-tt.html#SP1_1_1">&#167;1.1.1</a>).</p>
<p class="endnote">The function Languages::prolong_definition is used in 3/tt (<a href="3-tt.html#SP1_1_1">&#167;1.1.1</a>).</p>
<p class="endnote">The function Languages::end_definition is used in 2/ec (<a href="2-ec.html#SP4">&#167;4</a>), 3/tt (<a href="3-tt.html#SP1_1_1">&#167;1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>Then we have some "predeclarations"; for example, for C-like languages we
automatically predeclare all functions, obviating the need for header files.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">ADDITIONAL_PREDECLARATIONS_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">ADDITIONAL_PREDECLARATIONS_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::additional_predeclarations</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_PREDECLARATIONS_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::additional_predeclarations is used in 3/tt (<a href="3-tt.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>So much for the special material at the top of a tangle: now we're into
the more routine matter, tangling ordinary paragraphs into code.
</p>
<p class="inwebparagraph">Languages have the ability to suppress paragraph macro expansion:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SUPPRESS_EXPANSION_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SUPPRESS_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">material</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::allow_expansion</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">material</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SUPPRESS_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="identifier">material</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)?</span><span class="constant">FALSE</span><span class="plain">:</span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::allow_expansion is used in 3/tt (<a href="3-tt.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Inweb supports very few "tangle commands", that is, instructions written
inside double squares <code class="display"><span class="extract">[[Thus]]</span></code>. These can be handled by attaching methods
as follows, which return <code class="display"><span class="extract">TRUE</span></code> if they recognised and acted on the command.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">TANGLE_COMMAND_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">TANGLE_COMMAND_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">data</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::special_tangle_command</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">data</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">TANGLE_COMMAND_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">data</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::special_tangle_command is used in 3/tt (<a href="3-tt.html#SP3_2">&#167;3.2</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>The following methods make it possible for languages to tangle unorthodox
lines into code. Ordinarily, only <code class="display"><span class="extract">CODE_BODY_LCAT</span></code> lines are tangled, but
we can intervene to say that we want to tangle a different line; and if we
do so, we should then act on that basis.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">WILL_TANGLE_EXTRA_LINE_TAN_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">TANGLE_EXTRA_LINE_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">WILL_TANGLE_EXTRA_LINE_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">TANGLE_EXTRA_LINE_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::will_insert_in_tangle</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">WILL_TANGLE_EXTRA_LINE_TAN_MTID</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::insert_in_tangle</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">TANGLE_EXTRA_LINE_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::will_insert_in_tangle is used in 3/tt (<a href="3-tt.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Languages::insert_in_tangle is used in 3/tt (<a href="3-tt.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>In order for C compilers to report C syntax errors on the correct line,
despite rearranging by automatic tools, C conventionally recognises the
preprocessor directive <code class="display"><span class="extract">#line</span></code> to tell it that a contiguous extract follows
from the given file; we generate this automatically.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">INSERT_LINE_MARKER_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">INSERT_LINE_MARKER_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::insert_line_marker</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">INSERT_LINE_MARKER_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::insert_line_marker is used in 3/tt (<a href="3-tt.html#SP2_1">&#167;2.1</a>, <a href="3-tt.html#SP3_1">&#167;3.1</a>), 4/cl (<a href="4-cl.html#SP9_3">&#167;9.3</a>, <a href="4-cl.html#SP9_4">&#167;9.4</a>), 4/is (<a href="4-is.html#SP6">&#167;6</a>, <a href="4-is.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>The following hooks are provided so that we can top and/or tail the expansion
of paragraph macros in the code. For example, C-like languages, use this to
splice <code class="display"><span class="extract">{</span></code> and <code class="display"><span class="extract">}</span></code> around the expanded matter.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">BEFORE_MACRO_EXPANSION_TAN_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">AFTER_MACRO_EXPANSION_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">BEFORE_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">AFTER_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::before_macro_expansion</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">BEFORE_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">pmac</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::after_macro_expansion</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">AFTER_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">pmac</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::before_macro_expansion is used in 3/tt (<a href="3-tt.html#SP3_1">&#167;3.1</a>).</p>
<p class="endnote">The function Languages::after_macro_expansion is used in 3/tt (<a href="3-tt.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>It's a sad necessity, but sometimes we have to unconditionally tangle code
for a preprocessor to conditionally read: that is, to tangle code which contains
<code class="display"><span class="extract">#ifdef</span></code> or similar preprocessor directive.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">OPEN_IFDEF_TAN_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">CLOSE_IFDEF_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">OPEN_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">CLOSE_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::open_ifdef</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">OPEN_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::close_ifdef</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CLOSE_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::open_ifdef is used in 2/tgs (<a href="2-tgs.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Languages::close_ifdef is used in 2/tgs (<a href="2-tgs.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>Now a routine to tangle a comment. Languages without comment should write nothing.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">COMMENT_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">COMMENT_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">comm</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::comment</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">comm</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">COMMENT_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">comm</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::comment is used in <a href="#SP8">&#167;8</a>, 3/tt (<a href="3-tt.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>The inner code tangler now acts on all code known not to contain CWEB
macros or double-square substitutions. In almost every language this simply
passes the code straight through, printing <code class="display"><span class="extract">original</span></code> to <code class="display"><span class="extract">OUT</span></code>.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">TANGLE_CODE_UNUSUALLY_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">TANGLE_CODE_UNUSUALLY_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">text_stream</span><span class="plain"> *</span><span class="identifier">original</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::tangle_code</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">original</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">TANGLE_CODE_UNUSUALLY_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">original</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">original</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::tangle_code is used in 3/tt (<a href="3-tt.html#SP3">&#167;3</a>, <a href="3-tt.html#SP3_1">&#167;3.1</a>, <a href="3-tt.html#SP3_2">&#167;3.2</a>), 4/cl (<a href="4-cl.html#SP9_1">&#167;9.1</a>, <a href="4-cl.html#SP9_4">&#167;9.4</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>We finally reach the bottom of the tangled file, a footer called the "gnabehs":
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">GNABEHS_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">GNABEHS_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::gnabehs</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">GNABEHS_TAN_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::gnabehs is used in 3/tt (<a href="3-tt.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>But we still aren't quite done, because some languages need to produce
sidekick files alongside the main tangle file. This method exists to give
them the opportunity.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">ADDITIONAL_TANGLING_TAN_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">ADDITIONAL_TANGLING_TAN_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::additional_tangling</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_TANGLING_TAN_MTID</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">target</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::additional_tangling is used in 3/tt (<a href="3-tt.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Weaving methods. </b>This metnod shouldn't do any actual weaving: it should simply initialise
anything that the language in question might need later.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">BEGIN_WEAVE_WEA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">BEGIN_WEAVE_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::begin_weave</span><span class="plain">(</span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_language</span><span class="plain">, </span><span class="constant">BEGIN_WEAVE_WEA_MTID</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">wv</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::begin_weave is used in 3/tw (<a href="3-tw.html#SP1_3">&#167;1.3</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>This method allows languages to tell the weaver to ignore certain lines.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SKIP_IN_WEAVING_WEA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SKIP_IN_WEAVING_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::skip_in_weaving</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SKIP_IN_WEAVING_WEA_MTID</span><span class="plain">, </span><span class="identifier">wv</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::skip_in_weaving is used in 3/tw (<a href="3-tw.html#SP1_3_3">&#167;1.3.3</a>).</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>Languages most do syntax colouring by having a "state" (this is now inside
a comment, inside qupted text, and so on); the following method is provided
to reset that state, if so. Inweb runs it once per paragraph for safety's
sake, which minimises the knock-on effect of any colouring mistakes.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">RESET_SYNTAX_COLOURING_WEA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">RESET_SYNTAX_COLOURING_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::reset_syntax_colouring</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALLV</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">RESET_SYNTAX_COLOURING_WEA_MTID</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::reset_syntax_colouring is used in 3/tw (<a href="3-tw.html#SP1_3_3_1_9_6">&#167;1.3.3.1.9.6</a>, <a href="3-tw.html#SP1_3_3_1_10">&#167;1.3.3.1.10</a>).</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>And this is where colouring is done. The model here is that the code to
be coloured is in <code class="display"><span class="extract">matter</span></code>. A parallel text called <code class="display"><span class="extract">colouring</span></code> matches it
up, chatacter for character. For example, a language might colour like so:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">int x = 55;</span>
<span class="plain">rrrpipppnnp</span>
</pre>
<p class="inwebparagraph">The initial state is <code class="display"><span class="extract">ppp...p</span></code>, everything "plain", unless the following
method does something to change that.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SYNTAX_COLOUR_WEA_MTID</span>
<span class="definitionkeyword">define</span> <span class="constant">MACRO_COLOUR</span><span class="plain"> </span><span class="character">'m'</span>
<span class="definitionkeyword">define</span> <span class="constant">FUNCTION_COLOUR</span><span class="plain"> </span><span class="character">'f'</span>
<span class="definitionkeyword">define</span> <span class="constant">RESERVED_COLOUR</span><span class="plain"> </span><span class="character">'r'</span>
<span class="definitionkeyword">define</span> <span class="constant">ELEMENT_COLOUR</span><span class="plain"> </span><span class="character">'e'</span>
<span class="definitionkeyword">define</span> <span class="constant">IDENTIFIER_COLOUR</span><span class="plain"> </span><span class="character">'i'</span>
<span class="definitionkeyword">define</span> <span class="constant">CHAR_LITERAL_COLOUR</span><span class="plain"> </span><span class="character">'c'</span>
<span class="definitionkeyword">define</span> <span class="constant">CONSTANT_COLOUR</span><span class="plain"> </span><span class="character">'n'</span>
<span class="definitionkeyword">define</span> <span class="constant">STRING_COLOUR</span><span class="plain"> </span><span class="character">'s'</span>
<span class="definitionkeyword">define</span> <span class="constant">PLAIN_COLOUR</span><span class="plain"> </span><span class="character">'p'</span>
<span class="definitionkeyword">define</span> <span class="constant">EXTRACT_COLOUR</span><span class="plain"> </span><span class="character">'x'</span>
<span class="definitionkeyword">define</span> <span class="constant">COMMENT_COLOUR</span><span class="plain"> </span><span class="character">'!'</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">;</span>
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SYNTAX_COLOUR_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">,</span>
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::syntax_colour</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">,</span>
<span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">matter</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">i</span><span class="plain"> &lt; </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) </span><span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">PLAIN_COLOUR</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> != </span><span class="constant">TEXT_EXTRACT_LCAT</span><span class="plain">) {</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SYNTAX_COLOUR_WEA_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">wv</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">colouring</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::syntax_colour is used in 3/tw (<a href="3-tw.html#SP1_3_3_1_9">&#167;1.3.3.1.9</a>).</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b>This method is called for each code line to be woven. If it returns <code class="display"><span class="extract">FALSE</span></code>, the
weaver carries on in the normal way. If not, it does nothing, assuming that the
method has already woven something more attractive.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">WEAVE_CODE_LINE_WEA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">WEAVE_CODE_LINE_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</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">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">,</span>
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">concluding_comment</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::weave_code_line</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">,</span>
<span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">concluding_comment</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">WEAVE_CODE_LINE_WEA_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">wv</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">concluding_comment</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::weave_code_line is used in 3/tw (<a href="3-tw.html#SP1_3_3_1_9">&#167;1.3.3.1.9</a>).</p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. </b>When Inweb creates a new <code class="display"><span class="extract"> </span></code>, it lets everybody know about that.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">NOTIFY_NEW_TAG_WEA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">NOTIFY_NEW_TAG_WEA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">theme_tag</span><span class="plain"> *</span><span class="identifier">tag</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::new_tag_declared</span><span class="plain">(</span><span class="reserved">theme_tag</span><span class="plain"> *</span><span class="identifier">tag</span><span class="plain">) {</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">NOTIFY_NEW_TAG_WEA_MTID</span><span class="plain">, </span><span class="identifier">tag</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::new_tag_declared is used in 2/tgs (<a href="2-tgs.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Analysis methods. </b>These are really a little miscellaneous, but they all have to do with looking
at the code in a web and working out what's going on, rather than producing
any weave or tangle output.
</p>
<p class="inwebparagraph">This one provides details to add to the section catalogue if <code class="display"><span class="extract">-structures</span></code>
or <code class="display"><span class="extract">-functions</span></code> is used at the command line:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">CATALOGUE_ANA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">CATALOGUE_ANA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">functions_too</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::catalogue</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">functions_too</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CATALOGUE_ANA_MTID</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">functions_too</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::catalogue is used in 3/ta (<a href="3-ta.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. </b>The "preweave analysis" is an opportunity to look through the code before
any weaving of it occurs. It's never called on a tangle run. These methods
are called first and last in the process, respectively. (What happens in
between is essentially that Inweb looks for identifiers, for later syntax
colouring purposes.)
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">EARLY_PREWEAVE_ANALYSIS_ANA_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">LATE_PREWEAVE_ANALYSIS_ANA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">EARLY_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">LATE_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">)</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::early_preweave_analysis</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">EARLY_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Languages::late_preweave_analysis</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">LATE_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::early_preweave_analysis is used in 3/ta (<a href="3-ta.html#SP4_1">&#167;4.1</a>).</p>
<p class="endnote">The function Languages::late_preweave_analysis is used in 3/ta (<a href="3-ta.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. </b>And finally: in InC only, a few structure element names are given very slightly
special treatment, and this method decides which.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">SHARE_ELEMENT_ANA_MTID</span>
</pre>
<pre class="display">
<span class="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">SHARE_ELEMENT_ANA_MTID</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">element_name</span><span class="plain">)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Languages::share_element</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">element_name</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">rv</span><span class="plain">, </span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SHARE_ELEMENT_ANA_MTID</span><span class="plain">, </span><span class="identifier">element_name</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Languages::share_element is used in 4/cl (<a href="4-cl.html#SP3_2_3_6">&#167;3.2.3.6</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 4: Languages.)</i></li><li><a href="4-cl.html">Continue with 'C-Like Languages'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>