736 lines
62 KiB
HTML
736 lines
62 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>How This Program Works</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
|
|
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
|
|
|
<script src="../docs-assets/Bigfoot.js"></script>
|
|
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Octagram.png" width=72 height=72">
|
|
</a></h1>
|
|
<ul><li><a href="index.html"><span class="selectedlink">inweb</span></a></li>
|
|
</ul><h2>Foundation Module</h2><ul>
|
|
<li><a href="../foundation-module/index.html">foundation</a></li>
|
|
<li><a href="../foundation-test/index.html">foundation-test</a></li>
|
|
</ul><h2>Example Webs</h2><ul>
|
|
<li><a href="../goldbach/index.html">goldbach</a></li>
|
|
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
|
|
<li><a href="../eastertide/index.html">eastertide</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inform/docs/index.html">inform</a></li>
|
|
<li><a href="../../../intest/docs/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'How This Program Works' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inweb</a></li><li><a href="index.html#P">Preliminaries</a></li><li><b>How This Program Works</b></li></ul></div>
|
|
<p class="purpose">An overview of how Inweb works, with links to all of its important functions.</p>
|
|
|
|
<ul class="toc"><li><a href="P-htpw.html#SP1">§1. Prerequisites</a></li><li><a href="P-htpw.html#SP2">§2. Working out what to do, and what to do it to</a></li><li><a href="P-htpw.html#SP7">§7. Programming languages</a></li><li><a href="P-htpw.html#SP8">§8. Weaving mode</a></li><li><a href="P-htpw.html#SP14">§14. Tangling mode</a></li><li><a href="P-htpw.html#SP15">§15. Analysis mode</a></li><li><a href="P-htpw.html#SP16">§16. Translation mode</a></li><li><a href="P-htpw.html#SP17">§17. Adding to Inweb</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Prerequisites. </b>This page is to help readers to get their bearings in the source code for
|
|
Inweb, which is a literate program or "web". Before diving in:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) It helps to have some experience of reading webs. The short examples
|
|
<a href="../goldbach/index.html" class="internal">goldbach</a> and <a href="../twinprimes/twinprimes.html" class="internal">twinprimes</a> are enough to give the idea.
|
|
</li><li>(b) Inweb is written in C, in fact ANSI C99, but this is disguised by the
|
|
fact that it uses some extension syntaxes provided by <a href="index.html" class="internal">inweb</a> itself.
|
|
Turn to <a href="M-tid.html" class="internal">The InC Dialect</a> for full details, but essentially: it's plain
|
|
old C without predeclarations or header files, and where functions have names
|
|
like <span class="extract"><span class="extract-syntax">Tags::add_by_name</span></span> rather than just <span class="extract"><span class="extract-syntax">add_by_name</span></span>.
|
|
</li><li>(c) Inweb makes use of a "module" of utility functions called <a href="../foundation-module/index.html" class="internal">foundation</a>.
|
|
This is a web in its own right. There's no need to read it, but you may want
|
|
to take a quick look at <a href="../foundation-module/P-abgtf.html" class="internal">A Brief Guide to Foundation (in foundation)</a> or the
|
|
example <a href="../eastertide/index.html" class="internal">eastertide</a>.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Working out what to do, and what to do it to. </b>Inweb is a C program, so it begins at <a href="1-pc.html#SP6" class="internal">main</a>, in <a href="1-pc.html" class="internal">Program Control</a>. PC
|
|
works out where Inweb is installed, then calls <a href="1-cnf.html" class="internal">Configuration</a>, which
|
|
<a href="1-cnf.html#SP2" class="internal">reads the command line options</a>.
|
|
</p>
|
|
|
|
<p class="commentary">The user's choices are stored in an <a href="1-cnf.html#SP1" class="internal">inweb_instructions</a> object, and Inweb
|
|
is put into one of four modes: <span class="extract"><span class="extract-syntax">TANGLE_MODE</span></span>, <span class="extract"><span class="extract-syntax">WEAVE_MODE</span></span>, <span class="extract"><span class="extract-syntax">ANALYSE_MODE</span></span>, or
|
|
<span class="extract"><span class="extract-syntax">TRANSLATE_MODE</span></span>.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Inweb never changes mode: once set, it remains
|
|
for the rest of the run. Inweb also acts on only one main web in any run,
|
|
unless in <span class="extract"><span class="extract-syntax">TRANSLATE_MODE</span></span>, in which case none.
|
|
</p>
|
|
|
|
<p class="commentary">Once it has worked through the command line, <a href="1-cnf.html" class="internal">Configuration</a> also calls
|
|
<a href="6-cln.html#SP4" class="internal">Colonies::load</a> to read the colony file, if one was given (see
|
|
<a href="M-mwiw.html" class="internal">Making Weaves into Websites</a>), and uses this to preset some settings:
|
|
see <a href="1-cnf.html#SP4" class="internal">Configuration::member_and_colony</a>.
|
|
</p>
|
|
|
|
<p class="commentary">All errors in configuration are sent to <a href="../foundation-module/3-em.html#SP2" class="internal">Errors::fatal</a>, from whose bourne
|
|
no traveller returns.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Tangling and weaving are fundamental to all LP tools. Analysis means, say,
|
|
reading a web and listing functions in it. Translation is for side-activities
|
|
like <a href="6-mkf.html" class="internal">making makefiles</a> or <a href="6-gs.html" class="internal">gitignores</a>.
|
|
Strictly speaking there is also <span class="extract"><span class="extract-syntax">NO_MODE</span></span> for runs where the user simply
|
|
asked for <span class="extract"><span class="extract-syntax">-help</span></span> at the command line.
|
|
<a href="#fnref:1" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b><a href="1-pc.html" class="internal">Program Control</a> then resumes, calling <a href="1-pc.html#SP7" class="internal">Main::follow_instructions</a> to
|
|
act on the <a href="1-cnf.html#SP1" class="internal">inweb_instructions</a> object. If the user did specify a web to
|
|
work on, PC then goes through three stages to understand it.
|
|
</p>
|
|
|
|
<p class="commentary">First, PC calls <a href="2-tr.html#SP4" class="internal">Reader::load_web</a> to read the metadata of the web — that is,
|
|
its title and author, how it breaks down into chapters and sections, and what
|
|
modules it imports. The real work is done by the Foundation library function
|
|
<a href="../foundation-module/8-ws.html#SP5" class="internal">WebMetadata::get</a>, which returns a <a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a> object, providing details
|
|
such as its declared author and title (see <a href="../foundation-module/8-bdfw.html" class="internal">Bibliographic Data for Webs (in foundation)</a>),
|
|
and also references to a <a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a> for each chapter, and a <a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>
|
|
for each section. There is always at least one <a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a>, each of which
|
|
has at least one <a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>.<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> The "range text" for each chapter and
|
|
section is set here, which affects leafnames used in woven websites.<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> The
|
|
optional <span class="extract"><span class="extract-syntax">build.txt</span></span> file for a web is read by <a href="../foundation-module/8-bf.html#SP3" class="internal">BuildFiles::read</a>, and the
|
|
semantic version number determined at <a href="../foundation-module/8-bf.html#SP6" class="internal">BuildFiles::deduce_semver</a>.
|
|
</p>
|
|
|
|
<p class="commentary">Where a web imports a module, as for instance the <a href="../eastertide/index.html" class="internal">eastertide</a> example does,
|
|
<a href="../foundation-module/8-ws.html#SP5" class="internal">WebMetadata::get</a> creates a <a href="../foundation-module/8-wm.html#SP1" class="internal">module</a> object for each import. In any event,
|
|
it also creates a module called <span class="extract"><span class="extract-syntax">"(main)"</span></span> to represent the main, non-imported,
|
|
part of the overall program. Each module object also refers to the <a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a>
|
|
and <a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a> objects.<sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">The result of <a href="2-tr.html#SP4" class="internal">Reader::load_web</a> is an object called a <a href="2-tr.html#SP1" class="internal">web</a>, which expands
|
|
on the metadata considerably. If <span class="extract"><span class="extract-syntax">W</span></span> is a web, <span class="extract"><span class="extract-syntax">W->md</span></span> produces its <a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a>
|
|
metadata, but <span class="extract"><span class="extract-syntax">W</span></span> also has numerous other fields.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> For single-file webs like <a href="../twinprimes/twinprimes.html" class="internal">twinprimes</a>, with no contents pages, Inweb
|
|
makes what it calls an "implied" chapter and section heading.
|
|
<a href="#fnref:2" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:3"><p class="inwebfootnote"><sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> Range texts are used at the command line, and in <span class="extract"><span class="extract-syntax">-catalogue</span></span> output, for
|
|
example; and also to determine leafnames of pages in a website being woven.
|
|
A range is really just an abbreviation. For example, <span class="extract"><span class="extract-syntax">M</span></span> is the range for the
|
|
Manual chapter, <span class="extract"><span class="extract-syntax">2/tp</span></span> for the section "The Parser" in Chapter 2.
|
|
<a href="#fnref:3" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:4"><p class="inwebfootnote"><sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup> The difference is that the <a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a> lists every chapter and section,
|
|
imported or not, whereas the <a href="../foundation-module/8-wm.html#SP1" class="internal">module</a> lists only those falling under its
|
|
own aegis.
|
|
<a href="#fnref:4" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>After loading, the second stage is to call <a href="2-tr.html#SP5" class="internal">Reader::read_web</a>. Whereas
|
|
loading was rapid and involved looking only at the contents page, reading
|
|
takes longer and means extracting every line of commentary or code. Just
|
|
as the loader wrapped the <a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a> in a larger <a href="2-tr.html#SP1" class="internal">web</a> object, so too
|
|
the reader wraps each <a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a> in a <a href="2-tr.html#SP2" class="internal">chapter</a>, and each <a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>
|
|
in a <a href="2-tr.html#SP3" class="internal">section</a>.
|
|
</p>
|
|
|
|
<p class="commentary">Inweb syntax is heavily line-based, and every line of every section file (except
|
|
the Contents page) becomes a <a href="2-lc.html#SP1" class="internal">source_line</a>. In the end, then, Inweb has built
|
|
a four-level hierarchy on top of the more basic three-level hierarchy produced
|
|
by <a href="../foundation-module/index.html" class="internal">foundation</a>:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="function-syntax">INWEB</span><span class="plain-syntax"> </span><a href="2-tr.html#SP1" class="internal">web</a><span class="plain-syntax"> ----> </span><a href="2-tr.html#SP2" class="internal">chapter</a><span class="plain-syntax"> ----> </span><a href="2-tr.html#SP3" class="internal">section</a><span class="plain-syntax"> ----> </span><a href="2-lc.html#SP1" class="internal">source_line</a>
|
|
<span class="plain-syntax"> | | |</span>
|
|
<span class="function-syntax">FOUNDATION</span><span class="plain-syntax"> </span><a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a><span class="plain-syntax"> ----> </span><a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a><span class="plain-syntax"> ----> </span><a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>
|
|
<span class="plain-syntax"> </span><a href="../foundation-module/8-wm.html#SP1" class="internal">module</a>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>The third stage is to call <a href="2-tp.html#SP1" class="internal">Parser::parse_web</a>. This is where we check that
|
|
the web is syntactically valid line-by-line, reporting errors if any using
|
|
by calling <a href="1-pc.html#SP8" class="internal">Main::error_in_web</a>. Each line is assigned a "category": for
|
|
example, the category <span class="extract"><span class="extract-syntax">DEFINITIONS_LCAT</span></span> is given to lines holding definitions
|
|
made with <span class="extract"><span class="extract-syntax">@d</span></span> or <span class="extract"><span class="extract-syntax">@e</span></span>. See <a href="2-lc.html" class="internal">Line Categories</a> for the complete roster.<sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup>
|
|
Running Inweb with the <span class="extract"><span class="extract-syntax">-scan</span></span> switch lists out the lines parsed in this way;
|
|
for example:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">web "The Twin Primes Conjecture": 1 section : 3 paragraphs : 55 lines</span>
|
|
<span class="plain-syntax">Scan of source lines for '0'</span>
|
|
<span class="plain-syntax">0000001 SECTION_HEADING..... Main.</span>
|
|
<span class="plain-syntax">0000002 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000003 PURPOSE............. Implied Purpose: This example of using inweb is a whole web in a single short file, to look for twin primes, a classic problem in number theory.</span>
|
|
<span class="plain-syntax">0000004 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000005 HEADING_START....... @h The conjecture.</span>
|
|
<span class="plain-syntax">0000006 COMMENT_BODY........ It is widely believed that there are an infinite number of twin primes, that</span>
|
|
<span class="plain-syntax">0000007 COMMENT_BODY........ is, prime numbers occurring in pairs different by 2. Twins are known to exist</span>
|
|
<span class="plain-syntax">0000008 COMMENT_BODY........ at least as far out as $10^{388,342}$ (as of 2016), and there are infinitely</span>
|
|
<span class="plain-syntax">0000009 COMMENT_BODY........ many pairs of primes closer together than about 250 (Zhang, 2013; Tao, Maynard,</span>
|
|
<span class="plain-syntax">0000010 COMMENT_BODY........ and many others, 2014).</span>
|
|
<span class="plain-syntax">0000011 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000012 COMMENT_BODY........ This program finds a few small pairs of twins, by the simplest method possible,</span>
|
|
<span class="plain-syntax">0000013 COMMENT_BODY........ and should print output like so:</span>
|
|
<span class="plain-syntax">0000014 BEGIN_CODE.......... = (text)</span>
|
|
<span class="plain-syntax">0000015 TEXT_EXTRACT........ 3 and 5</span>
|
|
<span class="plain-syntax">0000016 TEXT_EXTRACT........ 5 and 7</span>
|
|
<span class="plain-syntax">0000017 TEXT_EXTRACT........ 11 and 13</span>
|
|
<span class="plain-syntax">0000018 TEXT_EXTRACT........ ...</span>
|
|
<span class="plain-syntax">0000019 END_EXTRACT......... =</span>
|
|
<span class="plain-syntax">0000020 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000021 BEGIN_DEFINITION.... @d RANGE 100 /* the upper limit to the numbers we will consider */</span>
|
|
<span class="plain-syntax">0000022 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000023 BEGIN_CODE.......... =</span>
|
|
<span class="plain-syntax">0000024 C_LIBRARY_INCLUDE... #include <stdio.h></span>
|
|
<span class="plain-syntax">0000025 CODE_BODY........... </span>
|
|
<span class="plain-syntax">0000026 CODE_BODY........... int main(int argc, char *argv[]) {</span>
|
|
<span class="plain-syntax">0000027 CODE_BODY........... for (int i=1; i<RANGE; i++)</span>
|
|
<span class="plain-syntax">0000028 CODE_BODY........... @<Test for twin prime at i@>;</span>
|
|
<span class="plain-syntax">0000029 CODE_BODY........... }</span>
|
|
<span class="plain-syntax">0000030 CODE_BODY........... </span>
|
|
<span class="plain-syntax">0000031 PARAGRAPH_START..... @</span>
|
|
<span class="plain-syntax">0000032 MACRO_DEFINITION.... @<Test for twin prime at i@> =</span>
|
|
<span class="plain-syntax">0000033 CODE_BODY........... if ((isprime(i)) && (isprime(i+2)))</span>
|
|
<span class="plain-syntax">0000034 CODE_BODY........... printf("%d and %d\n", i, i+2);</span>
|
|
<span class="plain-syntax">0000035 CODE_BODY........... </span>
|
|
<span class="plain-syntax">0000036 HEADING_START....... @h Primality.</span>
|
|
<span class="plain-syntax">0000037 COMMENT_BODY........ This simple and slow test tries to divide by every whole number at least</span>
|
|
<span class="plain-syntax">0000038 COMMENT_BODY........ 2 and up to the square root: if none divide exactly, the number is prime.</span>
|
|
<span class="plain-syntax">0000039 COMMENT_BODY........ A common error with this algorithm is to check where $m^2 < n$, rather</span>
|
|
<span class="plain-syntax">0000040 COMMENT_BODY........ than $m^2 \leq n$, thus wrongly considering 4, 9, 25, 49, ... as prime:</span>
|
|
<span class="plain-syntax">0000041 COMMENT_BODY........ Cambridge folklore has it that this bug occurred on the first computation</span>
|
|
<span class="plain-syntax">0000042 COMMENT_BODY........ of the EDSAC computer on 6 May 1949.</span>
|
|
<span class="plain-syntax">0000043 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000044 BEGIN_DEFINITION.... @d TRUE 1</span>
|
|
<span class="plain-syntax">0000045 BEGIN_DEFINITION.... @d FALSE 0</span>
|
|
<span class="plain-syntax">0000046 COMMENT_BODY........ </span>
|
|
<span class="plain-syntax">0000047 BEGIN_CODE.......... =</span>
|
|
<span class="plain-syntax">0000048 CODE_BODY........... int isprime(int n) {</span>
|
|
<span class="plain-syntax">0000049 CODE_BODY........... if (n <= 1) return FALSE;</span>
|
|
<span class="plain-syntax">0000050 CODE_BODY........... for (int m = 2; m*m <= n; m++)</span>
|
|
<span class="plain-syntax">0000051 CODE_BODY........... if (n % m == 0)</span>
|
|
<span class="plain-syntax">0000052 CODE_BODY........... return FALSE;</span>
|
|
<span class="plain-syntax">0000053 CODE_BODY........... return TRUE;</span>
|
|
<span class="plain-syntax">0000054 CODE_BODY........... }</span>
|
|
<span class="plain-syntax">0000055 CODE_BODY........... </span>
|
|
</pre>
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:5"><p class="inwebfootnote"><sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup> There are more than 20, but many are no longer needed in "version 2" of
|
|
the Inweb syntax, which is the only one anyone should still use. Continuing
|
|
to support version 1 makes <a href="2-tp.html" class="internal">The Parser</a> much fiddlier, and at some point we
|
|
will probably drop this quixotic goal.
|
|
<a href="#fnref:5" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>The parser also recognises headings and footnotes, but most importantly, it
|
|
introduces an additional concept: the <a href="2-tp.html#SP1_1_7_5_1_8_1" class="internal">paragraph</a>. Each nunbered passage
|
|
corresponds to one <a href="2-tp.html#SP1_1_7_5_1_8_1" class="internal">paragraph</a> object; it may actually contain several
|
|
paragraphs of prose in the everyday English sense, but has just one heading,
|
|
usually a number like "2.3.1". Those numbers are assigned hierarchically,<sup id="fnref:6"><a href="#fn:6" rel="footnote">6</a></sup>
|
|
which is not a trivial algorithm: see <a href="2-pn.html#SP1" class="internal">Numbering::number_web</a>.
|
|
</p>
|
|
|
|
<p class="commentary">It is the parser which finds all of the "paragraph macros", the term used
|
|
in the source code for named stretches of code in <span class="extract"><span class="extract-syntax">@<...@></span></span> notation. A
|
|
<a href="2-pm.html#SP1" class="internal">para_macro</a> object is created for each one, and every section has its own
|
|
collection, stored in a <span class="extract"><span class="extract-syntax">linked_list</span></span>.<sup id="fnref:7"><a href="#fn:7" rel="footnote">7</a></sup> Similarly, the parser finds all of
|
|
the footnote texts, and works out their proper numbering; each becomes a
|
|
<a href="2-tp.html#SP1_1_4_2" class="internal">footnote</a> object.<sup id="fnref:8"><a href="#fn:8" rel="footnote">8</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">At the end of the third stage, then, everything's ready to go, and in memory
|
|
we now have something like this:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="function-syntax">INWEB</span><span class="plain-syntax"> </span><a href="2-tr.html#SP1" class="internal">web</a><span class="plain-syntax"> ----> </span><a href="2-tr.html#SP2" class="internal">chapter</a><span class="plain-syntax"> ----> </span><a href="2-tr.html#SP3" class="internal">section</a><span class="plain-syntax"> ----> </span><a href="2-tp.html#SP1_1_7_5_1_8_1" class="internal">paragraph</a><span class="plain-syntax"> ----> </span><a href="2-lc.html#SP1" class="internal">source_line</a>
|
|
<span class="plain-syntax"> | | | </span><a href="2-pm.html#SP1" class="internal">para_macro</a>
|
|
<span class="function-syntax">FOUNDATION</span><span class="plain-syntax"> </span><a href="../foundation-module/8-ws.html#SP2" class="internal">web_md</a><span class="plain-syntax"> ----> </span><a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a><span class="plain-syntax"> ----> </span><a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>
|
|
<span class="plain-syntax"> </span><a href="../foundation-module/8-wm.html#SP1" class="internal">module</a>
|
|
</pre>
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:6"><p class="inwebfootnote"><sup id="fnref:6"><a href="#fn:6" rel="footnote">6</a></sup> Unlike in CWEB and other past literate programming tools, in which
|
|
paragraphs — sometimes called "sections" by those programs, a different use
|
|
of the word to ours — are numbered simply 1, 2, 3, ..., through the entire
|
|
program. Doing this would entail some webs in the Inform project running up
|
|
to nearly 8000.
|
|
<a href="#fnref:6" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:7"><p class="inwebfootnote"><sup id="fnref:7"><a href="#fn:7" rel="footnote">7</a></sup> In real-world use, to use a <span class="extract"><span class="extract-syntax">dictionary</span></span> instead would involve more
|
|
overhead than gain: there are never very many paragraph macros per section.
|
|
<a href="#fnref:7" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:8"><p class="inwebfootnote"><sup id="fnref:8"><a href="#fn:8" rel="footnote">8</a></sup> Though the parser is not able to check that the footnotes are all used;
|
|
that's done at weaving time instead.
|
|
<a href="#fnref:8" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Programming languages. </b>The contents page of a web usually mentions one or more programming languages.
|
|
A line at the top like
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="element-syntax">Language</span><span class="plain-syntax">:</span><span class="string-syntax"> C</span>
|
|
</pre>
|
|
<p class="commentary">results in the text "C" being stored in the bibliographic datum <span class="extract"><span class="extract-syntax">"Language"</span></span>,
|
|
and if contents lines for chapters or sections specify other languages,<sup id="fnref:9"><a href="#fn:9" rel="footnote">9</a></sup>
|
|
the loader stores those in the relevant <a href="../foundation-module/8-ws.html#SP3" class="internal">chapter_md</a> or <a href="../foundation-module/8-ws.html#SP4" class="internal">section_md</a>
|
|
objects. But to the loader, these are all just names.
|
|
</p>
|
|
|
|
<p class="commentary">The reader then loads in definitions of these programming languages by
|
|
calling <a href="4-pl.html#SP2" class="internal">Languages::find_by_name</a>, and the parser does the same when it
|
|
finds extract lines like
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> = (text as ACME)</span>
|
|
</pre>
|
|
<p class="commentary">to say that a passage of text must be syntax-coloured like the ACME language.
|
|
</p>
|
|
|
|
<p class="commentary"><a href="4-pl.html#SP2" class="internal">Languages::find_by_name</a> is thus called at any time when Inweb finds need
|
|
of a language; it looks for a language definition file (see documentation
|
|
at <a href="M-spl.html" class="internal">Supporting Programming Languages</a>), parses it one line at a time using
|
|
<a href="4-pl.html#SP8" class="internal">Languages::read_definition_line</a>, and returns a <a href="4-pl.html#SP6" class="internal">programming_language</a>
|
|
object. These correspond to their names: you cannot have two different PL
|
|
objects with languages both called "Python", say.
|
|
</p>
|
|
|
|
<p class="commentary">The practical effect is that a web can involve many languages, even though
|
|
the main use case is to have just one throughout. <a href="2-tr.html#SP1" class="internal">web</a>, <a href="2-tr.html#SP2" class="internal">chapter</a>,
|
|
<a href="2-tr.html#SP3" class="internal">section</a> and even individual <a href="2-lc.html#SP1" class="internal">source_line</a> objects all contain pointers
|
|
to a <a href="4-pl.html#SP6" class="internal">programming_language</a>.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:9"><p class="inwebfootnote"><sup id="fnref:9"><a href="#fn:9" rel="footnote">9</a></sup> A little-used feature of Inweb, which should arguably be taken out as
|
|
unnecessary now that colonies allow for multiple webs to coexist happily.
|
|
<a href="#fnref:9" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. Weaving mode. </b>Let's get back to <a href="1-pc.html" class="internal">Program Control</a>, which has now set everything up and is
|
|
about to take action. What it does depends on which of the four modes Inweb
|
|
is in; we'll start with <span class="extract"><span class="extract-syntax">WEAVE_MODE</span></span>, the most difficult.
|
|
</p>
|
|
|
|
<p class="commentary">Weaves are highly comfigurable, so they depend on several factors:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) Which format is used, as represented by a <a href="5-fm.html#SP1" class="internal">weave_format</a> object. For
|
|
example, HTML, ePub and PDF are all formats.
|
|
</li><li>(b) Which pattern is used, as represented by a <a href="1-ptt.html#SP1" class="internal">weave_pattern</a> object. A
|
|
pattern is a choice of format together with some naming conventions and
|
|
auxiliary files. For example, <span class="extract"><span class="extract-syntax">GitHubPages</span></span> is a pattern which imposes HTML
|
|
format but also throws in, for example, the GitHub logo icon.
|
|
</li><li>(c) Whether a filter to particular tags is used, as represented by a
|
|
<a href="2-tgs.html#SP1" class="internal">theme_tag</a>.<sup id="fnref:10"><a href="#fn:10" rel="footnote">10</a></sup>
|
|
</li><li>(d) What subset of the web the user wants to weave — by default the whole
|
|
thing, but sometimes just one chapter, or just one section, and sometimes
|
|
a special setting for "do all chapters one at a time" or "do all sections
|
|
one at a time", a procedure called <a href="1-ts.html" class="internal">The Swarm</a>.
|
|
</li></ul>
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:10"><p class="inwebfootnote"><sup id="fnref:10"><a href="#fn:10" rel="footnote">10</a></sup> For example, Inweb automatically applies the <span class="extract"><span class="extract-syntax">"Functions"</span></span> tag to any
|
|
paragraph defining one (see <a href="4-taf.html" class="internal">Types and Functions</a>), and using <span class="extract"><span class="extract-syntax">-weave-tag</span></span>
|
|
at the command line filters the weave down to just these. Sing to the tune
|
|
of Suzanne Vega's "Freeze Tag".
|
|
<a href="#fnref:10" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b><a href="1-pc.html" class="internal">Program Control</a> begins by attempting to load the weave pattern, with
|
|
<a href="1-ptt.html#SP2" class="internal">Patterns::find</a>; the syntax of weave pattern files can be found in
|
|
<a href="1-ptt.html#SP3" class="internal">Patterns::scan_pattern_line</a>.
|
|
</p>
|
|
|
|
<p class="commentary">It then either calls <a href="1-ts.html#SP2" class="internal">Swarm::weave_subset</a> — meaning, a subset of the
|
|
web, going into a single output file — or <a href="1-ts.html#SP1" class="internal">Swarm::weave</a>, which it turn
|
|
splits the web into subsets and sends each of those to <a href="1-ts.html#SP2" class="internal">Swarm::weave_subset</a>.
|
|
</p>
|
|
|
|
<p class="commentary"><a href="1-ts.html#SP1" class="internal">Swarm::weave</a> also causes an "index" to be made, though "index" here is
|
|
Inweb jargon for something which is more likely a contents page listing the
|
|
sections and linking to them.<sup id="fnref:11"><a href="#fn:11" rel="footnote">11</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">Either way, each single weaving operation arrives at <a href="1-ts.html#SP2" class="internal">Swarm::weave_subset</a>,
|
|
which consolidates all the settings needed into a <a href="1-ts.html#SP2_1" class="internal">weave_order</a> object:
|
|
it says, in effect, "weave content X into file Y using pattern Z".<sup id="fnref:12"><a href="#fn:12" rel="footnote">12</a></sup>
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:11"><p class="inwebfootnote"><sup id="fnref:11"><a href="#fn:11" rel="footnote">11</a></sup> No index is made if the user asked for only a single section or chapter
|
|
to be woven; only if there was a swarm.
|
|
<a href="#fnref:11" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:12"><p class="inwebfootnote"><sup id="fnref:12"><a href="#fn:12" rel="footnote">12</a></sup> So when Inweb is used to construct the website you are, perhaps, reading
|
|
this text on, around 80 <a href="1-ts.html#SP2_1" class="internal">weave_order</a> objects will be made, one for each
|
|
call to <a href="1-ts.html#SP2" class="internal">Swarm::weave_subset</a>, which in turn is one for each section of the
|
|
source-code web of Inweb itself.
|
|
<a href="#fnref:12" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>And so we descend into <a href="3-tw.html" class="internal">The Weaver</a>, where the function <a href="3-tw.html#SP1" class="internal">Weaver::weave</a>
|
|
is given the <a href="1-ts.html#SP2_1" class="internal">weave_order</a> and told to get on with it.<sup id="fnref:13"><a href="#fn:13" rel="footnote">13</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">Rather than directly converting the source to (say) an HTML representation,
|
|
the Weaver first produces a "weave tree" which amounts to a format-neutral
|
|
list of rendering instructions: it then hands the tree over to
|
|
<a href="5-fm.html#SP5" class="internal">Formats::render</a>. In this way, all specifics of individual output formats
|
|
are kept at arm's length from the actual weaving algorithm.
|
|
</p>
|
|
|
|
<p class="commentary">The weave tree is a simple business, built in a single pass of a depth-first
|
|
traverse of the web. The weaver keeps track of a modicum of "state" as it works,
|
|
and these running details are stored in a <a href="3-tw.html#SP2_5" class="internal">weaver_state</a> object, but this is
|
|
thrown away as soon as the weaver finishes.
|
|
</p>
|
|
|
|
<p class="commentary">The trickiest point of building the weave tree is done by <a href="3-twot.html" class="internal">The Weaver of Text</a>,
|
|
which breaks up lines of commentary or code to identify uses of mathematical
|
|
notation, footnote cues, function calls, and so on.
|
|
</p>
|
|
|
|
<p class="commentary">A convenience for testing the weave algorithm is to <span class="extract"><span class="extract-syntax">-weave-as TestingInweb</span></span>.
|
|
<span class="extract"><span class="extract-syntax">TestingInweb</span></span> is a weave pattern that outputs a textual representation of
|
|
the weave tree. For example:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">document weave order 0</span>
|
|
<span class="plain-syntax"> head banner <Weave of 'The Twin Primes Conjecture' generated by Inweb></span>
|
|
<span class="plain-syntax"> body</span>
|
|
<span class="plain-syntax"> chapter <Sections></span>
|
|
<span class="plain-syntax"> chapter header <Sections></span>
|
|
<span class="plain-syntax"> section <Main></span>
|
|
<span class="plain-syntax"> section header <Main></span>
|
|
<span class="plain-syntax"> section purpose <This example of using inweb is a whole web in a single short file, to look for twin primes, a classic problem in number theory.></span>
|
|
<span class="plain-syntax"> toc - <S/all></span>
|
|
<span class="plain-syntax"> toc line - <S1, The conjecture> P1'The conjecture'</span>
|
|
<span class="plain-syntax"> toc line - <S2, Primality> P2'Primality'</span>
|
|
<span class="plain-syntax"> paragraph P1'The conjecture'</span>
|
|
<span class="plain-syntax"> material discussion</span>
|
|
<span class="plain-syntax"> commentary <It is widely believed that there are an infinite number of twin primes, that\n></span>
|
|
<span class="plain-syntax"> commentary <is, prime numbers occurring in pairs different by 2. Twins are known to exist\n></span>
|
|
<span class="plain-syntax"> commentary <at least as far out as ></span>
|
|
<span class="plain-syntax"> mathematics <10^{388,342}></span>
|
|
<span class="plain-syntax"> commentary < (as of 2016), and there are infinitely\n></span>
|
|
<span class="plain-syntax"> commentary <many pairs of primes closer together than about 250 (Zhang, 2013; Tao, Maynard,\n></span>
|
|
<span class="plain-syntax"> commentary <and many others, 2014).\n></span>
|
|
<span class="plain-syntax"> vskip (in comment)</span>
|
|
<span class="plain-syntax"> commentary <This program finds a few small pairs of twins, by the simplest method possible,\n></span>
|
|
<span class="plain-syntax"> commentary <and should print output like so:\n></span>
|
|
<span class="plain-syntax"> material code: C</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < 3 and 5></span>
|
|
<span class="plain-syntax"> _ppppppppppp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < 5 and 7></span>
|
|
<span class="plain-syntax"> _ppppppppppp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < 11 and 13></span>
|
|
<span class="plain-syntax"> _ppppppppppppp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < ...></span>
|
|
<span class="plain-syntax"> _ppppppp_</span>
|
|
<span class="plain-syntax"> material definition</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> defn <define></span>
|
|
<span class="plain-syntax"> source_code <RANGE 100 ></span>
|
|
<span class="plain-syntax"> _nnnnnpnnnp_</span>
|
|
<span class="plain-syntax"> commentary < the upper limit to the numbers we will consider> (code)</span>
|
|
<span class="plain-syntax"> material code: C</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code <#include <stdio.h>></span>
|
|
<span class="plain-syntax"> _piiiiiiippiiiiipip_</span>
|
|
<span class="plain-syntax"> vskip</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code <int main(int argc, char *argv[]) {></span>
|
|
<span class="plain-syntax"> _rrrpffffprrrpiiiipprrrrppiiiippppp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < for (int i=1; i<RANGE; i++)></span>
|
|
<span class="plain-syntax"> _pppprrrpprrrpippppipnnnnnppippp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < ></span>
|
|
<span class="plain-syntax"> _pppppppp_</span>
|
|
<span class="plain-syntax"> pmac <Test for twin prime at i></span>
|
|
<span class="plain-syntax"> source_code <;></span>
|
|
<span class="plain-syntax"> _p_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code <}></span>
|
|
<span class="plain-syntax"> _p_</span>
|
|
<span class="plain-syntax"> paragraph P1.1</span>
|
|
<span class="plain-syntax"> material paragraph macro</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> pmac <Test for twin prime at i> (definition)</span>
|
|
<span class="plain-syntax"> material code: C</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < if ((></span>
|
|
<span class="plain-syntax"> _pppprrppp_</span>
|
|
<span class="plain-syntax"> function usage <isprime></span>
|
|
<span class="plain-syntax"> source_code <(i)) && (></span>
|
|
<span class="plain-syntax"> _pippppppp_</span>
|
|
<span class="plain-syntax"> function usage <isprime></span>
|
|
<span class="plain-syntax"> source_code <(i+2)))></span>
|
|
<span class="plain-syntax"> _pippppp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < printf("%d and %d\n", i, i+2);></span>
|
|
<span class="plain-syntax"> _ppppppppiiiiiipsssssssssssssppippipppp_</span>
|
|
<span class="plain-syntax"> material endnotes</span>
|
|
<span class="plain-syntax"> endnote</span>
|
|
<span class="plain-syntax"> commentary <This code is ></span>
|
|
<span class="plain-syntax"> commentary <used in ></span>
|
|
<span class="plain-syntax"> locale P1'The conjecture'</span>
|
|
<span class="plain-syntax"> commentary <.></span>
|
|
<span class="plain-syntax"> paragraph P2'Primality'</span>
|
|
<span class="plain-syntax"> material discussion</span>
|
|
<span class="plain-syntax"> commentary <This simple and slow test tries to divide by every whole number at least\n></span>
|
|
<span class="plain-syntax"> commentary <2 and up to the square root: if none divide exactly, the number is prime.\n></span>
|
|
<span class="plain-syntax"> commentary <A common error with this algorithm is to check where ></span>
|
|
<span class="plain-syntax"> mathematics <m^2 < n></span>
|
|
<span class="plain-syntax"> commentary <, rather\n></span>
|
|
<span class="plain-syntax"> commentary <than ></span>
|
|
<span class="plain-syntax"> mathematics <m^2 \leq n></span>
|
|
<span class="plain-syntax"> commentary <, thus wrongly considering 4, 9, 25, 49, ... as prime:\n></span>
|
|
<span class="plain-syntax"> commentary <Cambridge folklore has it that this bug occurred on the first computation\n></span>
|
|
<span class="plain-syntax"> commentary <of the EDSAC computer on 6 May 1949.\n></span>
|
|
<span class="plain-syntax"> material definition</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> defn <define></span>
|
|
<span class="plain-syntax"> source_code <TRUE 1></span>
|
|
<span class="plain-syntax"> _nnnnpn_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> defn <define></span>
|
|
<span class="plain-syntax"> source_code <FALSE 0></span>
|
|
<span class="plain-syntax"> _nnnnnpn_</span>
|
|
<span class="plain-syntax"> material code: C</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code <int ></span>
|
|
<span class="plain-syntax"> _rrrp_</span>
|
|
<span class="plain-syntax"> function defn <isprime></span>
|
|
<span class="plain-syntax"> locale P1.1</span>
|
|
<span class="plain-syntax"> source_code <(int n) {></span>
|
|
<span class="plain-syntax"> _prrrpippp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < if (n <= 1) return FALSE;></span>
|
|
<span class="plain-syntax"> _pppprrppippppnpprrrrrrpnnnnnp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < for (int m = 2; m*m <= n; m++)></span>
|
|
<span class="plain-syntax"> _pppprrrpprrrpipppnppipippppippippp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < if (n % m == 0)></span>
|
|
<span class="plain-syntax"> _pppppppprrppipppippppnp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < return FALSE;></span>
|
|
<span class="plain-syntax"> _pppppppppppprrrrrrpnnnnnp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code < return TRUE;></span>
|
|
<span class="plain-syntax"> _pppprrrrrrpnnnnp_</span>
|
|
<span class="plain-syntax"> code line</span>
|
|
<span class="plain-syntax"> source_code <}></span>
|
|
<span class="plain-syntax"> _p_</span>
|
|
<span class="plain-syntax"> section footer <Main></span>
|
|
<span class="plain-syntax"> chapter footer <Sections></span>
|
|
<span class="plain-syntax"> tail rennab <End of weave></span>
|
|
</pre>
|
|
<p class="commentary">This is a "heterogeneous tree", in that its <a href="../foundation-module/2-trs.html#SP3" class="internal">tree_node</a> nodes are annotated
|
|
by data structures of different types. For example, a node for a section
|
|
heading is annotated with a <a href="5-wt.html#SP1" class="internal">weave_section_header_node</a> structure. The
|
|
necessary types and object constructors are laid tediously out in
|
|
<a href="5-wt.html" class="internal">Weave Tree</a>, a section which intentionally contains no non-trivial code.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:13"><p class="inwebfootnote"><sup id="fnref:13"><a href="#fn:13" rel="footnote">13</a></sup> "Weaver, weave" really ought to be a folk song, but if so, I can't find
|
|
it on Spotify.
|
|
<a href="#fnref:13" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>Syntax-colouring is worth further mention. Just as the Weaver tries not to
|
|
get itself into fiddly details of formats, it also avoids specifics of
|
|
programming languages. It does this by calling <a href="4-lm.html#SP25" class="internal">LanguageMethods::syntax_colour</a>,
|
|
which in turn calls the <span class="extract"><span class="extract-syntax">SYNTAX_COLOUR_WEA_MTID</span></span> method for the relevant
|
|
instance of <a href="4-pl.html#SP6" class="internal">programming_language</a>. In effect the weaver sends a snippet
|
|
of code and asks to be told how it's to be coloured: not in terms of green
|
|
vs blue, but in terms of <span class="extract"><span class="extract-syntax">IDENTIFIER_COLOUR</span></span> vs <span class="extract"><span class="extract-syntax">RESERVED_COLOUR</span></span> and so on.
|
|
</p>
|
|
|
|
<p class="commentary">Thus, the object representing "the C programming language" can in principle
|
|
choose any semantic colouring that it likes. In practice, if (as is usual) it
|
|
assigns no particular code to this, what instead happens is that the generic
|
|
handler function in <a href="4-as.html" class="internal">ACME Support</a> takes on the task.<sup id="fnref:14"><a href="#fn:14" rel="footnote">14</a></sup> This runs the
|
|
colouring program in the language's definition file. Colouring programs are,
|
|
in effect, a mini-language of their own, which is compiled by
|
|
<a href="4-pl.html" class="internal">Programming Languages</a> and then run in a low-level interpreter by
|
|
<a href="4-tp.html" class="internal">The Painter</a>.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:14"><p class="inwebfootnote"><sup id="fnref:14"><a href="#fn:14" rel="footnote">14</a></sup> "ACME" is used here in the sense of "generic".
|
|
<a href="#fnref:14" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. </b>So, then, the weave tree is now made. Just as each programming language
|
|
has an object representing it, so does each format, and at render time the
|
|
method call <span class="extract"><span class="extract-syntax">RENDER_FOR_MTID</span></span> is sent to it. This has to turn the tree into
|
|
HTML, plain text, TeX source, or whatever may be. It's understood that not
|
|
every rendering instruction in the weave tree can be fully followed in every
|
|
format: for example, there's not much that plain text can do to render an
|
|
image carousel.
|
|
</p>
|
|
|
|
<p class="commentary">Inweb currently contains four renderers:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) <a href="5-df.html" class="internal">Debugging Format</a> renders the weave tree as a plain text display, and
|
|
is solely for testing.
|
|
</li><li>(b) <a href="5-tf.html" class="internal">TeX Format</a> renders the weave tree as TeX markup code — in the early
|
|
days of literate programming, this was the sole weave format used; now it
|
|
has been eclipsed by...
|
|
</li><li>(c) ...<a href="5-hf.html" class="internal">HTML Formats</a>, which renders to HTML and also handles ePub ebooks.
|
|
</li><li>(d) There is also <a href="5-ptf.html" class="internal">Plain Text Format</a>, a comically minimal approach.
|
|
</li></ul>
|
|
<p class="commentary">Renderers should make requests for weave plugins or colour schemes if, and
|
|
only if, the need arises: for example, the HTML renderer requests the plugin
|
|
<span class="extract"><span class="extract-syntax">Carousel</span></span> only if an image carousel is actually called for. Requests are
|
|
made by calling <a href="1-ts.html#SP3" class="internal">Swarm::ensure_plugin</a> or <a href="1-ts.html#SP3" class="internal">Swarm::ensure_colour_scheme</a>,
|
|
and see also the underlying code at <a href="1-apacs.html" class="internal">Assets, Plugins and Colour Schemes</a>.
|
|
(We want our HTML to run as little JavaScript as necessary at load time, which
|
|
is why we don't just give every weave every possible facility.)
|
|
</p>
|
|
|
|
<p class="commentary">The most complex issue for HTML rendering is working out the URLs for links:
|
|
for example, when weaving the text you are currently reading, Inweb has to
|
|
decide where to send <a href="../foundation-module/2-str.html#SP15" class="internal">text_stream</a>. This is handled by a suite of useful
|
|
functions in <a href="6-cln.html" class="internal">Colonies</a> which coordinate URLs across websites so
|
|
that one web's weave can safely link to another's. In particular, cross-references
|
|
written in <span class="extract"><span class="extract-syntax">//this notation//</span></span> are "resolved" by <a href="6-cln.html#SP10" class="internal">Colonies::resolve_reference_in_weave</a>,
|
|
and the function <a href="6-cln.html#SP11" class="internal">Colonies::reference_URL</a> turns them into relative URLs
|
|
from any given file. Within the main web being woven, <a href="6-cln.html#SP11" class="internal">Colonies::paragraph_URL</a>
|
|
can make a link to any paragraph of your choice.<sup id="fnref:15"><a href="#fn:15" rel="footnote">15</a></sup>
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:15"><p class="inwebfootnote"><sup id="fnref:15"><a href="#fn:15" rel="footnote">15</a></sup> Inweb anchors at paragraphs; it does not anchor at individual lines.
|
|
This is intentional, as it's intended to take the reader to just enough
|
|
context and explanation to understand what is being linked to.
|
|
<a href="#fnref:15" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>Finally on weaving, special mention should go to <a href="3-tc.html" class="internal">The Collater</a>, a
|
|
subsystem which amounts to a stream editor. Its role is to work through a
|
|
"template" and substitute in material from outside — from the weave rendering,
|
|
from the bibliographic data for a web, and so on — to produce a final file.
|
|
For example, a simple use of the collater is to work through the template:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"></span>
|
|
<span class="plain-syntax"> <html></span>
|
|
<span class="plain-syntax"> <head></span>
|
|
<span class="plain-syntax"> <title>[[Booklet Title]]</title></span>
|
|
<span class="plain-syntax"> [[Plugins]]</span>
|
|
<span class="plain-syntax"> </head></span>
|
|
<span class="plain-syntax"> <body></span>
|
|
<span class="plain-syntax"> [[Weave Content]]</span>
|
|
<span class="plain-syntax"> </body></span>
|
|
<span class="plain-syntax"> </html></span>
|
|
</pre>
|
|
<p class="commentary">and to collate material already generated by other parts of Inweb to fill the
|
|
double-squared placeholders, such as <span class="extract"><span class="extract-syntax">[[Plugins]]</span></span>. The Collater, in fact,
|
|
is ultimately what generates all of the files made in a weave, even though
|
|
other parts of Inweb did all of the real work.
|
|
</p>
|
|
|
|
<p class="commentary">With that said, it's not a trivial algorithm, because it can also loop through
|
|
chapters and sections, as it does when it generates an index page to accompany
|
|
a swarm of individual section weaves. The contents pages for typical webs
|
|
presented online are made this way. The Collater is also recursive, in that
|
|
some collation commands call for further acts of collation to happen inside
|
|
the original. See <a href="M-awwp.html" class="internal">Advanced Weaving with Patterns</a> for more on collation,
|
|
and see <a href="3-tc.html#SP1" class="internal">Collater::collate</a> for the machinery.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. Tangling mode. </b>Alternatively, we're in <span class="extract"><span class="extract-syntax">TANGLE_MODE</span></span>, which is more straightforward.
|
|
<a href="1-pc.html" class="internal">Program Control</a> simply works out what we want to tangle, selecting the
|
|
appropriate <a href="2-tr.html#SP11" class="internal">tangle_target</a> object, and calls <a href="3-tt.html#SP1" class="internal">Tangler::tangle</a>.
|
|
Most webs have just one "tangle target", meaning that the whole web makes
|
|
a single program — in that case, the choice is obvious. However, the
|
|
contents section can mark certain chapters or sections as being independent
|
|
targets.<sup id="fnref:16"><a href="#fn:16" rel="footnote">16</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary"><a href="3-tt.html#SP1" class="internal">Tangler::tangle</a> works hierarchically, calling down to <a href="3-tt.html#SP2" class="internal">Tangler::tangle_paragraph</a>
|
|
and finally <a href="3-tt.html#SP3" class="internal">Tangler::tangle_line</a> on individual lines of code. Throughout
|
|
the process, the Tangler makes method calls to the current programming
|
|
language; see <a href="4-lm.html" class="internal">Language Methods</a>. As with syntax-colouring, the default
|
|
arrangement is that these methods are handled by the generic "ACME" language,
|
|
following instructions from the language definition file.
|
|
</p>
|
|
|
|
<p class="commentary">Languages declaring themselves "C-like" have access to special tangling
|
|
facilities, all implemented with non-ACME method calls: see <a href="4-cl.html" class="internal">C-Like Languages</a>.
|
|
In particular, for coping with how <span class="extract"><span class="extract-syntax">#ifdef</span></span> affects <span class="extract"><span class="extract-syntax">#include</span></span> see
|
|
<a href="4-cl.html#SP5" class="internal">CLike::additional_early_matter</a>; for predeclaration of functions and
|
|
structs and <span class="extract"><span class="extract-syntax">typedef</span></span>s, see <a href="4-cl.html#SP6" class="internal">CLike::additional_predeclarations</a>.
|
|
</p>
|
|
|
|
<p class="commentary">The language calling itself "InC" gets even more: see <a href="4-is.html" class="internal">InC Support</a>, and
|
|
in particular <a href="4-is.html#SP3_2_1_1" class="internal">text_literal</a> for text constants like <span class="extract"><span class="extract-syntax">I"banana"</span></span>
|
|
and <a href="4-is.html#SP3_1_2" class="internal">preform_nonterminal</a> for Preform grammar notation like
|
|
<span class="extract"><span class="extract-syntax"><sentence-ending></span></span>.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:16"><p class="inwebfootnote"><sup id="fnref:16"><a href="#fn:16" rel="footnote">16</a></sup> The original intention of this feature was that a program might want
|
|
to have, as "appendices", certain configuration files or other extraneous
|
|
matter needing explanation. The author was motivated here by the example of
|
|
"TeX", which was presented as a literate program, but was difficult fully
|
|
to understand without also reading its format files quite carefully. However,
|
|
it now seems better practice to make such a sidekick file its own web, and
|
|
use a colony file to make everything tidy on a woven website. So maybe this
|
|
feature can go.
|
|
<a href="#fnref:16" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. Analysis mode. </b>Alternatively, we're in <span class="extract"><span class="extract-syntax">ANALYSE_MODE</span></span>. There's not much to this: <a href="1-pc.html" class="internal">Program Control</a>
|
|
simply calls <a href="3-ta.html#SP2" class="internal">Analyser::catalogue_the_sections</a>, or else makes use of the same
|
|
functions as <span class="extract"><span class="extract-syntax">TRANSLATE_MODE</span></span> would — but in the context of having read in a
|
|
web. If it makes a <span class="extract"><span class="extract-syntax">.gitignore</span></span> file, for example, it does so for that specific
|
|
web, whereas if the same feature is used in <span class="extract"><span class="extract-syntax">TRANSLATE_MODE</span></span>, it does so in
|
|
the abstract and for no particular web.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. Translation mode. </b>Or, finally, we're in <span class="extract"><span class="extract-syntax">TRANSLATE_MODE</span></span>. We can:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) make a makefile by calling <a href="6-mkf.html#SP1" class="internal">Makefiles::write</a>;
|
|
</li><li>(b) make a <span class="extract"><span class="extract-syntax">.gitignore</span></span> file by calling <a href="6-gs.html#SP1" class="internal">Git::write_gitignore</a>;
|
|
</li><li>(c) advance the build number in a build file, by calling out to the
|
|
Foundation code at <a href="../foundation-module/8-bf.html#SP7" class="internal">BuildFiles::advance</a>;
|
|
</li><li>(d) run a syntax-colouring test to help debug a programming language definition —
|
|
see <a href="1-pc.html" class="internal">Program Control</a> itself for details.
|
|
</li></ul>
|
|
<p class="commentary">And that is essentially it. Inweb winds up by returning exit code 1 if there
|
|
were errors, or 0 if not, like a good Unix citizen.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>§17. Adding to Inweb. </b>Here's some miscellaneous advice for those who would like to add to Inweb:
|
|
</p>
|
|
|
|
<p class="commentary">1. To add a new command-line switch, declare at <a href="1-cnf.html#SP2" class="internal">Configuration::read</a> and
|
|
add a field to <a href="1-cnf.html#SP1" class="internal">inweb_instructions</a> which holds the setting; don't act on it
|
|
then and there, only in <a href="1-pc.html" class="internal">Program Control</a> later. But we don't want these
|
|
settings to proliferate: ask first if adding a feature to, say, <a href="6-cln.html" class="internal">Colonies</a>
|
|
or <a href="1-ptt.html#SP1" class="internal">weave_pattern</a> files would meet the same need.
|
|
</p>
|
|
|
|
<p class="commentary">2. To add new programming languages, try if possible to do everything you
|
|
need with a new definition file alone: see <a href="M-spl.html" class="internal">Supporting Programming Languages</a>.
|
|
Failing that, see if making definition files more powerful would do it (for
|
|
example, by making the ACME support more general-purpose). Failing even that,
|
|
follow the model of <a href="4-cl.html" class="internal">C-Like Languages</a>: that is, add logic to
|
|
<a href="4-pl.html#SP7" class="internal">Languages::read_definition</a> which adds method receiver functions
|
|
to a language with a given name, or, preferably, some given declaration in
|
|
the language definition file. On no account insert any language bias into
|
|
<a href="3-tw.html" class="internal">The Weaver</a> or <a href="3-tt.html" class="internal">The Tangler</a>.
|
|
</p>
|
|
|
|
<p class="commentary">3. To add new forms of weave output, try if possible to make a new pattern:
|
|
see <a href="M-awwp.html" class="internal">Advanced Weaving with Patterns</a>. But this won't always be good enough.
|
|
For example, "an HTML website but done differently" should be a pattern based
|
|
on HTML, but Markdown would require a genuinely new format. (Though you would
|
|
still also create a new pattern in order to use it.) If you go down this road,
|
|
make a new section in <a href="5-wt.html" class="internal">Chapter 5: Formats</a> following the model of, say,
|
|
<a href="5-ptf.html" class="internal">Plain Text Format</a> and then adding methods gradually.
|
|
(But don't forget to call your new format's creator function from
|
|
<a href="5-fm.html#SP3" class="internal">Formats::create_weave_formats</a>.)
|
|
</p>
|
|
|
|
<p class="commentary">4. As with any program built on Foundation, if you are creating a new class of
|
|
object, don't forget to declare it in <a href="1-bsc.html" class="internal">Basics</a>.
|
|
</p>
|
|
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="M-rc.html">❮</a></li><li class="progresschapter"><a href="M-iti.html">M</a></li><li class="progresscurrentchapter">P</li><li class="progresscurrent">htpw</li><li class="progresschapter"><a href="1-bsc.html">1</a></li><li class="progresschapter"><a href="2-tr.html">2</a></li><li class="progresschapter"><a href="3-ta.html">3</a></li><li class="progresschapter"><a href="4-pl.html">4</a></li><li class="progresschapter"><a href="5-wt.html">5</a></li><li class="progresschapter"><a href="6-mkf.html">6</a></li><li class="progressnext"><a href="1-bsc.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|