2019-02-04 22:26:45 +00:00
|
|
|
Webs, Tangling and Weaving.
|
|
|
|
|
|
|
|
How to use Inweb to weave or tangle a web already written.
|
|
|
|
|
|
|
|
@h All-in-one webs.
|
|
|
|
A program written for use with Inweb is called a "web". Inweb was primarily
|
|
|
|
designed for large, multisection webs, but it can also be used in a much
|
|
|
|
simpler way on smaller webs. In this documentation we'll call those
|
|
|
|
"all-in-one webs", meaning that there is just a single source code file for
|
|
|
|
the program.
|
|
|
|
|
|
|
|
Such a file should be a UTF-8 encoded plain text file with the file
|
|
|
|
extension |.inweb|. The following is a "hello world" example, which can
|
|
|
|
be found in the Inweb distribution as |inweb/Examples/hellow.inweb|:
|
|
|
|
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as Inweb)
|
2019-02-04 22:26:45 +00:00
|
|
|
Title: hellow
|
|
|
|
Author: Graham Nelson
|
|
|
|
Purpose: A minimal example of a C program written for inweb.
|
|
|
|
Language: C
|
|
|
|
|
|
|
|
@ =
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
printf("Hello world!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
@ This of course is just a regular C "hello world" program written below
|
|
|
|
the |@ =| marker, and some metadata written above it. The metadata above
|
|
|
|
is called the "contents section": for a larger web, it would expand out
|
|
|
|
to something more like a contents page, though here it's more like a
|
|
|
|
title page. The Title, Author and Purpose make no functional difference
|
|
|
|
to the program produced - they are purely descriptive - but the Language
|
|
|
|
setting is another matter, as we shall see.
|
|
|
|
|
|
|
|
The contents end, and the code begins, when the first "paragraph" begins.
|
|
|
|
Code in an Inweb web is divided into paragraphs. The core Inform compiler
|
|
|
|
currently has 8362 paragraphs, whereas |hellow| has just one. (If you are
|
|
|
|
reading this documentation in a web page or a PDF, you will see that it's
|
|
|
|
divided up into little numbered sections: those are individual paragraphs
|
|
|
|
from the |inweb| web.) More on this below, but the use of an |@| character
|
|
|
|
in column 1 of the web file is what marks a paragraph break.
|
|
|
|
|
|
|
|
As mentioned earlier, there are two basic things we can do with a web:
|
|
|
|
tangle, to make a program ready to compile and run; and weave, to make
|
|
|
|
a comfortably legible version for human eyes instead. Let's now tangle:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb/Examples/hellow.inweb -tangle
|
|
|
|
web "hellow": 1 section(s) : 1 paragraph(s) : 9 line(s)
|
|
|
|
tangling <inweb/Examples/hellow.c> (written in C)
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
And |inweb/Examples/hellow.c| is now a regular C program which can then be
|
|
|
|
compiled. If we had wanted it to be written somewhere else, or called
|
|
|
|
something else, we could have used |-tangle-to F| to specify a file |F|
|
|
|
|
to create instead.
|
|
|
|
|
|
|
|
In general, you never need to look at or edit tangled code, but if
|
|
|
|
we take a look at this one to see what has happened, two things are worth
|
|
|
|
noting.
|
|
|
|
|
|
|
|
(a) First, the use of the |#line| C preprocessor feature, which ensures that
|
|
|
|
any compilation errors occurring will be reported at the correct point of
|
|
|
|
origin in the original Inweb file, not in the tangled file.
|
|
|
|
|
|
|
|
(b) Secondly, notice that the |main| function has automatically been
|
|
|
|
predeclared at the top of the file. Because Inweb does this for C programs,
|
|
|
|
the programmer can freely call functions defined lower down in the source
|
|
|
|
code, without having to write tiresome predeclarations or header files. (As it
|
|
|
|
happens, there was no need in the case of |main|, but nor was there any harm.)
|
|
|
|
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as C)
|
2019-02-04 22:26:45 +00:00
|
|
|
/* Tangled output generated by inweb: do not edit */
|
|
|
|
#include <stdio.h>
|
|
|
|
#line 9 "inweb/Examples/hellow.inweb"
|
|
|
|
int main(int argc, char *argv[]) ;
|
|
|
|
#line 8 "inweb/Examples/hellow.inweb"
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
printf("Hello world!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
@ So much for tangling: we can also weave. |hellow| is so uninteresting
|
|
|
|
to look at that this seems a good point to switch to |inweb/Examples/twinprimes.inweb|,
|
|
|
|
a C program to find twin prime numbers. If we weave:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb/Examples/twinprimes.inweb -weave
|
2022-08-14 14:39:01 +00:00
|
|
|
web "twinprimes": 1 section(s) : 3 paragraph(s) : 55 line(s)
|
2020-04-07 22:04:32 +00:00
|
|
|
[Complete Program: HTML -> inweb/Examples/twinprimes.html]
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
As with tangling, we can override this destination with |-weave-to F|, telling
|
|
|
|
Inweb to weave into just a single file (which in this instance it was going
|
|
|
|
to do anyway) and call it |F|; or we can similarly |-weave-into D|, telling
|
|
|
|
Inweb to weave a set of file into the directory |D|, rather than the usual
|
|
|
|
|Woven| subdirectory of the web in question.
|
|
|
|
|
|
|
|
By default, |-weave| makes an HTML representation of the program. (On a larger
|
|
|
|
web, with multiple sections, it would make a set of linked pages, but here
|
|
|
|
there's just one.) This can then be looked at with a browser such as Chrome or
|
|
|
|
Safari. HTML is not the only format we can produce. Inweb performs the weave
|
2020-04-07 22:04:32 +00:00
|
|
|
by following a "pattern", and it has several patterns built in, notably |HTML|,
|
2022-08-14 14:39:01 +00:00
|
|
|
|Ebook|, |TeX| and |PDFTeX|.
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
Running Inweb with |-weave-as P| tells it to weave with pattern |P|; the
|
|
|
|
plain command |-weave| is equivalent to |-weave-as HTML|. The |Ebook| pattern
|
|
|
|
makes an EPUB file suitable for readers such as Apple's Books app, but that
|
|
|
|
would be overkill for such a tiny program. Instead:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
2022-08-14 14:39:01 +00:00
|
|
|
$ inweb/Tangled/inweb inweb/Examples/twinprimes.inweb -weave-as PDFTeX
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
This will only work if you have the mathematical typesetting system TeX
|
|
|
|
installed, and in particular, the |pdftex| tool. (This comes as part of
|
|
|
|
the standard TeXLive distribution, so simply "installing TeX" on your
|
|
|
|
platform will probably install |pdftex| automatically.) Now the response
|
|
|
|
is like so:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
2022-08-14 14:39:01 +00:00
|
|
|
$ inweb/Tangled/inweb inweb/Examples/twinprimes.inweb -weave-as PDFTeX
|
|
|
|
web "twinprimes": 1 section(s) : 3 paragraph(s) : 55 line(s)
|
2020-04-07 22:04:32 +00:00
|
|
|
[Complete Program: PDF -> inweb/Examples/twinprimes.tex: 1pp 103K]
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
Inweb automatically creates |twinprimes.tex| and runs it through |pdftex|
|
|
|
|
to produce |twinprimes.pdf|: it reads over the TeX log file to see how
|
|
|
|
many pages that comes to, and reports back. All being well, the |.tex|
|
|
|
|
and |.log| files are silently removed, leaving just |twinprimes.pdf| behind.
|
|
|
|
|
|
|
|
@h Multi-section webs.
|
|
|
|
The |twinprimes.inweb| example was a program so small that it could
|
|
|
|
comfortably fit into one source file, but for really large programs, that
|
|
|
|
would be madness. The core Inform compiler, for example, runs to about
|
|
|
|
210,000 lines of code, and distributes those across 418 source files
|
|
|
|
called "sections", together with a special 419th section which forms
|
|
|
|
its contents page. It's a matter of personal taste how much should be
|
|
|
|
in a section, but an ideal section file might contain 500 to 1000 lines
|
|
|
|
of material and weave to a standalone essay, describing and implementing
|
|
|
|
a single well-defined component of the whole program.
|
|
|
|
|
|
|
|
In this documentation, we'll call such webs "multi-section".
|
|
|
|
|
|
|
|
A multi-section web is stored as a directory, whose name should be (a
|
|
|
|
short version of) the name of the program. For example, Inweb's own
|
|
|
|
source is in a directory called |inweb|. A web directory is a tidy,
|
|
|
|
self-contained area in which the program can be written, compiled and
|
|
|
|
used.
|
|
|
|
|
|
|
|
Inweb expects that a multi-section web will contain at least two source
|
|
|
|
files, each of which is a UTF-8 encoded text file with the file extension
|
|
|
|
|.w|. One source file is special, must always be called |Contents.w|,
|
|
|
|
and must be directly stored in the web directory. All other section files
|
|
|
|
are stored in subdirectories of the web directory:
|
|
|
|
|
|
|
|
(a) If the web is still relatively small, there may only be a few of these,
|
|
|
|
stored in a single subdirectory called |Sections|.
|
|
|
|
|
|
|
|
(b) Alternatively (not additionally), a larger web can use chapter
|
2020-03-22 11:24:10 +00:00
|
|
|
subdirectories called |Manual|, |Preliminaries|, |Chapter 1|, |Chapter 2|, ...,
|
2019-02-04 22:26:45 +00:00
|
|
|
|Appendix A|, |Appendix B|, ...; preliminaries and appendices being optional.
|
2020-03-22 11:24:10 +00:00
|
|
|
(There can't be a Chapter 0, though there can be Appendix A, B, C, ..., L.)
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
A multi-section web can contain a variety of other subdirectories as needed.
|
|
|
|
Two in particular, |Woven| and |Tangled|, are automatically created by Inweb
|
|
|
|
as needed to store the results of tangling and weaving, respectively: they
|
|
|
|
are not intended to hold any material of lasting value, and can be emptied
|
|
|
|
at any time and regenerated later.
|
|
|
|
|
|
|
|
@ Uniquely, the |Contents.w| section provides neither typeset output nor
|
|
|
|
compiled code: it is instead a roster telling Inweb about the rest of the
|
|
|
|
web, and how the other sections are organised. It has a completely different
|
|
|
|
syntax from all other sections. (It's essentially a fuller version of the
|
|
|
|
top part of an all-in-one web file as demonstrated above, but now it
|
|
|
|
occupies the whole file.)
|
|
|
|
|
|
|
|
The contents section opens with some bibliographic data. For example:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as Inweb)
|
|
|
|
Title: inter
|
|
|
|
Author: Graham Nelson
|
|
|
|
Purpose: For handling intermediate Inform code
|
|
|
|
Language: InC
|
|
|
|
Licence: Artistic License 2.0
|
|
|
|
Version Number: 1
|
|
|
|
Version Name: Axion
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
This is a simply a block of name-value pairs specifying some bibliographic
|
|
|
|
details; there is then a skipped line, and the roster of sections begins.
|
|
|
|
|
|
|
|
Note that the program's |Title| need not be the same as the directory-name
|
|
|
|
for the web, which is useful if the program has a long or file-system-unfriendly
|
|
|
|
name. The |Purpose| should be brief enough to fit onto one line. |Licence| can
|
|
|
|
also have the US spelling, |License|; Inweb treats these as equivalent.
|
|
|
|
Version number and name are, of course, optional.
|
|
|
|
|
2020-04-07 22:04:32 +00:00
|
|
|
The |Language| is the programming language in which the code is written: much
|
|
|
|
more on that later on, but for now, the important ones are probably |C|, |InC|
|
|
|
|
and |Plain Text|.
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
@ After the header block of details, then, we have the roster of sections.
|
|
|
|
This is like a contents page -- the order is the order in which the sections
|
|
|
|
are presented on any website, or in any of the larger PDFs woven. For a short,
|
|
|
|
unchaptered web, we might have for instance:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Sections
|
|
|
|
Program Control
|
|
|
|
Command Line and Configuration
|
|
|
|
Scan Documentation
|
|
|
|
HTML and Javascript
|
|
|
|
Renderer
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
And then Inweb will expect to find, for instance, the section file
|
|
|
|
|Scan Documentation.w| in the |Sections| directory.
|
|
|
|
|
|
|
|
A larger web, however, won't have a "Sections" directory. It may have a
|
|
|
|
much longer roster, such as:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Preliminaries
|
|
|
|
Preface
|
|
|
|
Thematic Index
|
|
|
|
Licence and Copyright Declaration
|
|
|
|
BNF Grammar
|
|
|
|
|
|
|
|
Chapter 1: Definitions
|
|
|
|
"In which some globally-used constants are defined and the standard C libraries
|
|
|
|
are interfaced with, with all the differences between platforms (Mac OS X,
|
|
|
|
Windows, Linux, Solaris, Sugar/XO and so forth) taken care of once and for all."
|
|
|
|
Basic Definitions
|
|
|
|
Platform-Specific Definitions
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
... and so on...
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Appendix A: The Standard Rules (Independent Inform 7)
|
|
|
|
"This is the body of Inform 7 source text automatically included with every
|
2020-04-14 16:57:22 +00:00
|
|
|
project run through the Inform compiler, and which defines most of what end users
|
2020-04-07 22:04:32 +00:00
|
|
|
see as the Inform language."
|
|
|
|
SR0 - Preamble
|
|
|
|
SR1 - Physical World Model
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
... and so on. Here the sections appear in directories called Preliminaries,
|
2020-03-22 11:24:10 +00:00
|
|
|
Chapter 1, Chapter 2, ..., Appendix A. (There can't be a Chapter 0, though
|
|
|
|
there can be Appendix B, C, ..., O; there can also be a Manual chapter, in
|
|
|
|
the sense of documentation.)
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
In case of any doubt we can use the following command-line switch to see
|
|
|
|
how Inweb is actually reading the sections of a web |W|:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb W -catalogue -verbose
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
@h Tangling.
|
|
|
|
At this point, it may be worth experimenting with a second mathematical
|
|
|
|
example: |inweb/Examples/goldbach|, which is to do with a problem in number
|
|
|
|
theory called the Goldbach Conjecture. This is a multi-section web, though
|
|
|
|
really only for the sake of an example: it's still a very small web.
|
|
|
|
|
|
|
|
This is once again a C program. Actually building and running this is a
|
|
|
|
little trouble, of course, and because there are multiple source files, it's
|
|
|
|
not so easy to keep track of whether the program is built up to date.
|
|
|
|
So a convenience of Inweb is that it can make makefiles to help with this:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb/Examples/goldbach -makefile inweb/Examples/goldbach/goldbach.mk
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
With this done,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ make -f inweb/Examples/goldbach/goldbach.mk
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
tangles and then compiles the program as necessary. The tangling part of that
|
|
|
|
is nothing fancy - as before, it's just
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb/Examples/goldbach -tangle
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
Assuming all goes well:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Examples/goldbach/Tangled/goldbach
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
should then print out some results.
|
|
|
|
|
|
|
|
@ It is legal in some circumstances to tangle only part of a web. This is done
|
|
|
|
by specifying a "range", much as will be seen later with weaving - but
|
|
|
|
because it's not normally meaningful to tangle only part of a program, the
|
|
|
|
possible ranges are much more restricted. In fact, the only partial tangles
|
|
|
|
allowed are for chapters or sections marked in the |Contents.w| as being
|
|
|
|
"Independent". For example:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Appendix A: The Standard Rules (Independent Inform 7)
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
declares that Appendix A is a sort of sidekick program, written in the
|
|
|
|
language "Inform 7". As a result, it won't be included in a regular |-tangle|,
|
|
|
|
and to obtain it we have to:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inform7 -tangle A
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
@ In some C programs, it's useful to require that a header file be added to
|
|
|
|
a tangle. This can be done by adding:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Header: H
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
to the contents page of a web. The heacer file |H| in question should then
|
|
|
|
be stored in the web's |Headers| subdirectory. (At one time, the Foundation
|
|
|
|
module used this to bring in a Windows-only header file.)
|
|
|
|
|
|
|
|
@h Weaving.
|
|
|
|
As with all-in-one webs, the commands for weaving are like so:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb inweb/Examples/goldbach -weave
|
2022-08-14 14:39:01 +00:00
|
|
|
$ inweb inweb/Examples/goldbach -weave-as PDFTeX
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
This will produce single HTML or PDF files of the woven form of the whole
|
|
|
|
program. (Note that the PDF file now has a cover page: on a web with just
|
|
|
|
a single section, this wouldn't happen.) But with a growing web, that can
|
|
|
|
be cumbersome.
|
|
|
|
|
|
|
|
@ After setting |-weave| or |-weave-as|, we can also optionally choose a
|
|
|
|
range. The default range is |all|, so up to now we have implicitly
|
|
|
|
been running weaves like these:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb inweb/Examples/goldbach -weave all
|
2022-08-14 14:39:01 +00:00
|
|
|
$ inweb inweb/Examples/goldbach -weave-as PDFTeX all
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
The opposite extreme from |all| is |sections|. This still weaves the entire
|
|
|
|
web, but now cuts it up into individual files, one for each section. For
|
|
|
|
example,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb inweb/Examples/goldbach -weave sections
|
|
|
|
=
|
2020-04-20 22:26:08 +00:00
|
|
|
makes a miniature website; files include some CSS, and:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
inweb/Examples/goldbach/Woven/index.html
|
|
|
|
inweb/Examples/goldbach/Woven/S-tgc.html
|
|
|
|
inweb/Examples/goldbach/Woven/S-tsoe.html
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
Those abbreviated names |S-tgc| and |S-tsoe| are cut down from the full
|
|
|
|
names of the sections involved, "The Goldbach Conjecture" and "The Sieve
|
|
|
|
of Eratosthenes". Similarly,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
2022-08-14 14:39:01 +00:00
|
|
|
$ inweb inweb/Examples/goldbach -weave-as PDFTeX sections
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
creates the files:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
inweb/Examples/goldbach/Woven/index.html
|
|
|
|
inweb/Examples/goldbach/Woven/S-tgc.pdf
|
|
|
|
inweb/Examples/goldbach/Woven/S-tsoe.pdf
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
The index file here is a table of contents offering links to the PDFs.
|
|
|
|
|
|
|
|
An intermediate level of granularity is the range |chapters|, which makes
|
|
|
|
sense only for chaptered webs, and puts each chapter into its own file.
|
|
|
|
|
|
|
|
@ Ranges can also be used to weave only part of a web:
|
|
|
|
|
|
|
|
(a) In a chaptered web, chapters are abbreviated to just their numbers: for
|
2020-03-22 11:24:10 +00:00
|
|
|
example, the range |2| means "just Chapter 2". The Preliminaries alone is |P|;
|
|
|
|
the Manual, |M|. Appendix A, B, C are |A|, |B|, |C| and so on. (This is why
|
|
|
|
Appendices can only run up to L.)
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
(b) In an unchaptered web, |S| means "all the sections". This is almost but not
|
|
|
|
quite the same as |all|: the cover sheet (a sort of title page) is omitted.
|
|
|
|
|
|
|
|
(c) The abbreviation for a section makes a range of just that section. For
|
|
|
|
example, |S/tgc| and |S/tsoe| in the Goldbach web example, or |2/ec| for
|
|
|
|
the "Enumerated Constants" section of Chapter 2 of Inweb itself. Note that
|
|
|
|
running Inweb with |-catalogue| shows all the sections of a web, and their
|
2020-04-03 15:29:03 +00:00
|
|
|
abbreviations. If it's a nuisance that these section ranges are hard to
|
|
|
|
predict, run with |-sequential| to have them simply be |X/s1|, |X/s2|, ...,
|
|
|
|
within each chapter, where |X| is the chapter range.
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
@h Weave tags.
|
|
|
|
An alternative to a range is to specify a tag. Rather than weaving contiguous
|
|
|
|
pieces of the web, this collates together all those paragraphs with a given
|
|
|
|
tag. The result is a booklet of extracts.
|
|
|
|
|
|
|
|
Most paragraphs are never tagged. A tag is simply a word; paragraphs can have
|
|
|
|
multiple tags, but for each individual tags they either have it or don't.
|
|
|
|
A very few tags are automatically applied by Inweb:
|
|
|
|
|
|
|
|
If the program is for a C-like language, Inweb automatically tags any
|
|
|
|
paragraph containing a |typedef struct| with the tag |Structures|. So,
|
|
|
|
for example,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb -weave-tag Structures
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
weaves just the structure definitions culled from a much larger web; this
|
|
|
|
can make a convenient reference. Similarly, any paragraph containing an
|
|
|
|
illustration is automatically tagged |Figures|, and any paragraph in an
|
|
|
|
|InC| web which defines Preform grammar is automatically tagged |Preform|.
|
|
|
|
(In the Inform project, this is used to generate the PDF of the formal
|
|
|
|
syntax of the language.)
|
|
|
|
|
|
|
|
All other tags must be typed by hand. If the line introducing a paragraph
|
|
|
|
is marked at the end with |^"Fun"|, then that paragraph will be tagged
|
|
|
|
as |Fun|, and so on. Paragraphs can have multiple tags:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as Inweb)
|
|
|
|
@ ^"Algorithms" ^"History"
|
|
|
|
The original version of the program used an in-place insertion sort, but
|
|
|
|
...
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
A tag can optionally supply a caption. For example:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as Inweb)
|
|
|
|
@ ^"Algorithms: Sorting rulebooks"
|
|
|
|
The original version of the program used an in-place insertion sort, but
|
|
|
|
...
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
Here the tag is just |Algorithms|, but when a |-weave-to Algorithms| is
|
|
|
|
performed, the caption text "Sorting rulebooks" will be used in a subheading
|
|
|
|
in the resulting booklet.
|
|
|
|
|
|
|
|
Beyond that, an entire section can be tagged from the |Contents.w| page.
|
|
|
|
For example:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Sections
|
|
|
|
The Goldbach Conjecture
|
|
|
|
The Sieve of Eratosthenes ^"Greek"
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
tags every paragraph in the section "The Sieve of Eratosthenes" with the
|
|
|
|
tag |Greek|. In this instance, a caption is not allowed.
|
|
|
|
|
|
|
|
Note that if we |-weave-to| a tag which does not exist - or rather, which no
|
|
|
|
paragraph in the range has - then rather than producing an empty document,
|
|
|
|
Inweb will halt with an "empty weave request" error.
|
|
|
|
|
|
|
|
@h Modules.
|
|
|
|
Up to now, the webs described have all been self-contained: one web makes
|
|
|
|
one program, and contains the code in its entirety. But Inweb also supports
|
|
|
|
"modules". A module is simply a web which provides a compoment of a program
|
|
|
|
but is not a program in its own right.
|
|
|
|
|
|
|
|
For example, all of the Inform tools (including Inweb itself) make use of
|
|
|
|
a module called |foundation|, which is written in InC and provides
|
|
|
|
facilities for managing memory, manipulating strings, filenames, and so on.
|
|
|
|
On the other hand, the Inform project also includes a module called |inter|
|
|
|
|
which is used only by the core compiler |inform7| and by a wrapper utility
|
|
|
|
also called |inter|; in fact, |inform7| is entirely divided up into modules,
|
|
|
|
some of which are used only by itself.
|
|
|
|
|
|
|
|
@ It makes little sense to tangle a module on its own. Instead, a web which
|
|
|
|
wishes to use a module needs to declare this on its |Contents.w| page. This
|
|
|
|
is done with a list of "imports", after the metadata but before the list
|
|
|
|
of sections. For example,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Import: foundation
|
|
|
|
|
|
|
|
Chapter 1
|
|
|
|
Startup
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
...and so on. When this new web is tangled, the module's code will tangled
|
|
|
|
into it. Any functions or variables defined in the module will thus be
|
|
|
|
available to the new web.
|
|
|
|
|
|
|
|
However, it makes perfectly good sense to weave a module. For example:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb/foundation-module -weave sections
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
@ That's everything there is to say about modules, except where Inweb looks
|
|
|
|
to find them. When it reads a request from a web |W| to import a module |M|,
|
|
|
|
it looks for a web directory called |M-module| (note the hyphen). For
|
|
|
|
example, |Import: fruit| would look for the directory |fruit-module|. Inweb
|
|
|
|
tries the following locations, in sequence, until it finds it:
|
|
|
|
|
|
|
|
(1) Directly inside |W|.
|
|
|
|
(2) In the directory containing |W| (i.e., one directory higher up).
|
|
|
|
(3) Directly inside Inweb's own web directory.
|
|
|
|
(4) In the directory specified by |-import-from D| at the command line, if any.
|
|
|
|
|
|
|
|
@h The section catalogue.
|
|
|
|
Inweb can do a handful of other things. One is to list the contents of a web:
|
|
|
|
|
|
|
|
(a) |-catalogue| (or |-catalog|) lists the sections in the web.
|
|
|
|
|
|
|
|
(b) |-structures| lists the sections, and all of the structure definitions
|
|
|
|
made in them (for C-like languages).
|
|
|
|
|
|
|
|
(c) |-functions| lists the sections, with all structure definitions and also
|
|
|
|
all function definitions.
|
|
|
|
|
|
|
|
In addition, for debugging purposes, |-scan| shows how Inweb is parsing lines
|
|
|
|
of source code in the web, and |-verbose| makes it generally print out more
|
|
|
|
descriptive output.
|
|
|
|
|
|
|
|
@h Makefile.
|
|
|
|
As mentioned earlier, Inweb can construct a suitable makefile for a web:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb W -makefile M
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
creates a makefile for the web |W| and stores it in |M|. For example,
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb inweb -makefile inweb/inweb.mk
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
The makefile is constructed using a prototype file called a "makescript".
|
|
|
|
Ordinarily the script used will be the one stored in
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
2022-04-23 13:08:38 +00:00
|
|
|
W/W.mkscript
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
or, if no such file exists, the default one stored in Inweb:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
2022-04-23 13:08:38 +00:00
|
|
|
inweb/Materials/default.mkscript
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
but this can be changed by using |-prototype S|, which tells Inweb to use
|
|
|
|
|S| as the script. If a |-prototype| is given, then there's no need to
|
|
|
|
specify any one web for Inweb to use: this allows Inweb to construct more
|
2022-04-23 13:08:38 +00:00
|
|
|
elaborate makefiles for multi-web projects.
|
2019-02-04 22:26:45 +00:00
|
|
|
|
2022-04-23 13:08:38 +00:00
|
|
|
@ A makescript is really just copied out to produce the makefile, except that:
|
|
|
|
|
|
|
|
(*) Comment lines, those beginning with |#|, are stripped out.
|
|
|
|
|
|
|
|
(*) Material in balanced braces |{ ... }| is expanded into something more
|
|
|
|
interesting.
|
|
|
|
|
2022-07-25 22:41:35 +00:00
|
|
|
(*) Literal braces can be written with a backslash, |\{| and |\}|, which
|
|
|
|
expand just into |{| and |}|. Literal backslashes are written |\\|, which
|
|
|
|
"expands" to |\|. A backslash is not allowed to precede any other character,
|
|
|
|
so something like |\fish| produces an error message.
|
|
|
|
|
2022-04-23 13:08:38 +00:00
|
|
|
@ Makescripts support variables, whose names have to be in capital letters,
|
|
|
|
perhaps with underscores and digits added. For example:
|
|
|
|
= (text)
|
|
|
|
{set name: SUPPORTED_BUILDS value: 6L02, 6L38, 6M62}
|
|
|
|
...
|
|
|
|
echo "I support any of {SUPPORTED_BUILDS}."
|
|
|
|
=
|
|
|
|
expands to
|
|
|
|
= (text)
|
|
|
|
echo "I support any of 6L02, 6L38, 6M62."
|
|
|
|
=
|
|
|
|
What happens is that the |set| macro sets the variable |SUPPORTED_BUILDS| and
|
|
|
|
gives it the value |6L02, 6L38, 6M62|. Anywhere below this in the file,[1]
|
|
|
|
|{SUPPORTED_BUILDS}| is replaced by that value.
|
|
|
|
|
|
|
|
[1] If you set a variable inside a repeat loop, it will exist only in the loop.
|
|
|
|
|
|
|
|
@ Makescripts support repetition. For example:
|
|
|
|
= (text)
|
|
|
|
{repeat with: BUILD in: 6L02, 6L38, 6M62}
|
|
|
|
echo "I support {BUILD}."
|
|
|
|
{end-repeat}
|
|
|
|
=
|
|
|
|
produces:
|
|
|
|
= (text)
|
|
|
|
echo "I support 6L02."
|
|
|
|
echo "I support 6L38."
|
|
|
|
echo "I support 6M62."
|
|
|
|
=
|
|
|
|
|
|
|
|
@ Like |set|, |repeat| is a "macro". This has two parameters, |with:|, naming
|
|
|
|
the loop variable, and |in:|, giving a comma-separated list of values for it
|
|
|
|
to run through in order. In some macros parameters are optional, but not these.
|
|
|
|
|
|
|
|
Note that variables can be used within the parameters of macros, as in this example:
|
|
|
|
= (text)
|
|
|
|
{repeat with: BUILD in: {SUPPORTED_BUILDS}}
|
|
|
|
echo "I support {BUILD}."
|
|
|
|
{end-repeat}
|
|
|
|
=
|
|
|
|
|
|
|
|
Loops can be nested, for those who like to live on the edge. So:
|
|
|
|
= (text)
|
|
|
|
{repeat with: X in: alpha, beta, gamma}
|
|
|
|
{repeat with: Y in: 5, 11}
|
|
|
|
echo "Greetings, Agent {X}-{Y}."
|
|
|
|
{end-repeat}
|
|
|
|
{end-repeat}
|
|
|
|
=
|
|
|
|
produces:
|
|
|
|
= (text)
|
|
|
|
echo "Greetings, Agent alpha-5."
|
|
|
|
echo "Greetings, Agent alpha-11."
|
|
|
|
echo "Greetings, Agent beta-5."
|
|
|
|
echo "Greetings, Agent beta-11."
|
|
|
|
echo "Greetings, Agent gamma-5."
|
|
|
|
echo "Greetings, Agent gamma-11."
|
|
|
|
=
|
|
|
|
|
|
|
|
@ You can also define your own macros, as in this example:
|
|
|
|
= (text)
|
|
|
|
{define: link to: TO from: FROM ?options: OPTS}
|
|
|
|
clang $(CCOPTS) -g -o {TO} {FROM} {OPTS}
|
|
|
|
{end-define}
|
|
|
|
=
|
|
|
|
And here is a usage of it:
|
|
|
|
= (text)
|
|
|
|
{link from: frog.o to: frog.c}
|
|
|
|
=
|
|
|
|
This doesn't specify "options: ...", but doesn't have to, because that's optional --
|
|
|
|
note the question mark in the macro declaration. But it does specify "from: ..."
|
|
|
|
and "to: ...", which are compulsory. Parameters are always named, as this example
|
|
|
|
suggests, and can be given in any order so long as all the non-optional ones are
|
|
|
|
present.
|
|
|
|
|
|
|
|
This usage results in the following line in the final makefile:
|
|
|
|
= (text)
|
|
|
|
clang $(CCOPTS) -g -o frog.c frog.o
|
|
|
|
=
|
|
|
|
Note the difference between |$(CCOPTS)|, which is a make variable, and the braced
|
|
|
|
tokens |{TO}|, |{FROM}| and |{OPTS}|, which are makescript variables (which exist
|
|
|
|
only inside the definition).
|
|
|
|
|
|
|
|
@ A few more built-in macros special to makefiles may be useful:
|
|
|
|
|
|
|
|
(*) |{platform-settings}| (which has no parameters) includes a file of makescript
|
|
|
|
material useful for compiling C-based tools on your current operating system or
|
|
|
|
"platform". It gets this file at |inweb/Materials/platforms/YOURPLATFORM.mkscript|,
|
|
|
|
where |YOURPLATFORM| may be |macos|, |windows|, |linux| and so on.
|
|
|
|
|
|
|
|
(*) |{identity-settings}| (which has no parameters) writes out make declarations
|
|
|
|
for make variables |INWEB|, |INTEST|, |MYNAME| and |ME|. The first two are paths
|
|
|
|
to the inweb and intest tools respectivly. |MYNAME| and |ME| are set only if
|
|
|
|
inweb has been given a specific web |W| to work with at the command line, and
|
|
|
|
are then expanded to the directory name and web name respectively for |W|. (These
|
|
|
|
are very often the same name, e.g., |inform7|.)
|
|
|
|
|
2022-04-30 10:41:53 +00:00
|
|
|
(*) |{modify-filenames original: ORIGINAL suffix: SUFFIX prefix: PREFIX}|. Here
|
|
|
|
both |suffix:| and |prefix:| are optional, but if neither is given then the result
|
|
|
|
is that no modification occurs. The idea here is that ORIGINAL is a whitespace-divided
|
|
|
|
list of filenames, as typically appears in a makefile, and that we modify each
|
|
|
|
filename by applying the prefix or suffix to its unextended leafname. So, for
|
|
|
|
example, |{modify-filenames original: peach.o others/*.o prefix: x86_ suffix: _v12}| would
|
|
|
|
expand to |x86_peach_v12.o others/x86_*_v12.o|.
|
|
|
|
|
2022-04-23 13:08:38 +00:00
|
|
|
(*) |{component symbol: SYMBOL webname: WEBNAME path: PATH set: SET type: TYPE}|
|
|
|
|
is used only in a makescript for a makefile trying to orchestrate complicated
|
|
|
|
operations on colonies of large numbers of webs. (See the |inform.mkscript|
|
|
|
|
script in the main Inform repository for an example.) This macro says that one
|
|
|
|
of the webs it will talk about is called |WEBNAME|, located at |PATH| in the
|
|
|
|
file system, belongs to a set you want to call |SET|, has the |TYPE| of one
|
|
|
|
of |tool|, |web| or |module|. (A |tool| is the main web for an executable;
|
|
|
|
a |module| for one of the modules making up an executable; a |web| for some
|
|
|
|
other kind of resource tangled by Inweb but which doesn't make an executable.)
|
|
|
|
|
|
|
|
(*) |{dependent-files tool: WEBNAME}| then expands to a list of source files
|
|
|
|
inside the web |WEBNAME| on which its tangled output depends, written in the
|
|
|
|
usual make-file way, i.e., divided by spaces. |WEBNAME| has to be one which
|
|
|
|
has already been declared as having |type: tool| in a |{component ...}| line.
|
|
|
|
|
|
|
|
(*) And similarly |{dependent-files module: WEBNAME}|.
|
|
|
|
|
|
|
|
(*) More elaborately, |{dependent-files tool-and-modules: WEBNAME}| lists the
|
|
|
|
dependent files not only in the main web for a tool, which also in any of the
|
|
|
|
modules which it includes.
|
|
|
|
|
|
|
|
(*) A form of loop, |{components type: TYPE set: SET} ... {end-components}|
|
|
|
|
repeats through all the declared components with the given type and set. (The
|
|
|
|
set is optional: if not given, the repetition is over everything with that type.)
|
|
|
|
As before, |TYPE| must be one of |tool|, |web| or |module|. Inside the loop,
|
|
|
|
|{NAME}| expands to the |SYMBOL| which the component was declared with. For
|
|
|
|
example:
|
|
|
|
= (text)
|
|
|
|
.PHONY: versions
|
|
|
|
versions:
|
|
|
|
{components type: tool}
|
|
|
|
$({SYMBOL}X) -version
|
|
|
|
{end-components}
|
|
|
|
=
|
2019-02-04 22:26:45 +00:00
|
|
|
|
|
|
|
@h Gitignore.
|
|
|
|
A similar convenience exists for users who want to use the git source control
|
|
|
|
tool with a web: for example, uploading it to Github.
|
|
|
|
|
|
|
|
The files produced by weaving or tangling a web are not significant and should
|
|
|
|
probably not be subject to source control: they should be "ignored", in git
|
|
|
|
terminology. This means writing a special file called |.gitignore| which
|
|
|
|
specifies the files to be ignored. The following does so for a web |W|:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb W -gitignore W/.gitignore
|
|
|
|
=
|
2022-04-23 13:08:38 +00:00
|
|
|
Once again, Inweb does this by working from a script, and the rules are almost
|
|
|
|
exactly the same as for makefiles except that the file extension is |.giscript|,
|
|
|
|
not |.mkscript|, and:
|
|
|
|
|
|
|
|
(*) The special makefile macros are not available, though |set| and |repeat| are;
|
|
|
|
|
|
|
|
(*) The special macro |{basics}| expands to the contents of the file
|
|
|
|
|inweb/Materials/default.giscript|. This does the same thing as would be done
|
|
|
|
if the web provided no script of its own; the idea is that you can then list
|
|
|
|
some additional things to ignore.
|
2019-02-04 22:26:45 +00:00
|
|
|
|
2020-03-23 23:02:37 +00:00
|
|
|
@h README files.
|
|
|
|
Repositories at Github customarily have |README.mk| files, in Markdown
|
|
|
|
syntax, explaining what they are. These of course should probably include
|
|
|
|
current version numbers, and it's a pain keeping that up to date. For
|
|
|
|
really complicated repositories, containing multiple webs, some automation
|
|
|
|
is essential, and once again Inweb can oblige.
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text as ConsoleText)
|
2022-04-23 22:41:01 +00:00
|
|
|
$ inweb/Tangled/inweb W -prototype W/W.rmscript -write-me W/README.mk
|
2020-04-07 22:04:32 +00:00
|
|
|
=
|
2022-04-23 22:41:01 +00:00
|
|
|
The same conventions and notations are used here as for makefiles and gitignores
|
|
|
|
(see above), except that the comment character is no longer |#|, since a |#|
|
|
|
|
at the start of a line means a heading in Markdown. Instead, a line is a comment
|
|
|
|
if its first non-whitespace character is a forward-slash |/|.
|
|
|
|
|
|
|
|
(*) The special makefile macros are not available, though |set| and |repeat| are;
|
|
|
|
|
|
|
|
(*) The special macro |{bibliographic datum: ... of: ...}| expands to the value
|
|
|
|
of the named bibliographic datum for the program named. |Version Number| is
|
|
|
|
especially useful, and is available even for some Inform assets which are not
|
|
|
|
webs and do not therefore have bibliographic data of their own -- interpreter
|
|
|
|
templates and Inform 7 extensions, for example.
|
2020-03-23 23:02:37 +00:00
|
|
|
|
2020-03-23 15:04:43 +00:00
|
|
|
@h Semantic version numbering and build metadata.
|
|
|
|
When Inweb reads in a web, it also looks for a file called |build.txt| in
|
|
|
|
the web's directory; if that isn't there, it looks for the same file in the
|
|
|
|
current working directory; if that's not there either, never mind.
|
|
|
|
|
|
|
|
Such a file contains up to three text fields, all optional:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Prerelease: alpha.1
|
|
|
|
Build Date: 23 March 2020
|
|
|
|
Build Number: 6Q26
|
|
|
|
=
|
2020-03-23 15:04:43 +00:00
|
|
|
The bibliographic variables |Prerelease| and so on are then set from this
|
|
|
|
file. (They can equally well be set by the Contents section of the web, and
|
|
|
|
if so then that takes priority.)
|
|
|
|
|
|
|
|
The Prerelease and Build Number, if given, are used in combination with the
|
|
|
|
Version Number (set in the Contents) to produce the semantic version number,
|
|
|
|
or semver, for the web. For example, if the Contents included:
|
2020-04-07 22:04:32 +00:00
|
|
|
= (text)
|
|
|
|
Version Number: 6.2.12
|
|
|
|
=
|
2020-03-23 15:04:43 +00:00
|
|
|
then the semver would be |6.2.12-alpha.1+6Q26|. This is accessible within
|
|
|
|
the web as the variable |Semantic Version Number|.
|
|
|
|
|
2020-04-09 13:00:28 +00:00
|
|
|
For more on semvers, see: https://semver.org
|
|
|
|
|
2020-03-23 15:04:43 +00:00
|
|
|
@ A special advancing mechanism exists to update build numbers and dates.
|
|
|
|
Running Inweb with |-advance-build W| checks the build date for web |W|:
|
|
|
|
if it differs from today, then it is changed to today, and the build code
|
|
|
|
is advanced by one.
|
|
|
|
|
|
|
|
Running |-advance-build-file B| does this for a stand-alone build file |B|,
|
|
|
|
without need of a web.
|
2022-04-23 22:41:01 +00:00
|
|
|
|
|
|
|
@h Ctags.
|
|
|
|
Each time a web is tangled, Inweb writes a |tags| file to the web's home
|
|
|
|
directory, containing a list of //Universal ctags -> https://ctags.io//
|
|
|
|
for any structures, functions or constant definitions found in the web. You
|
|
|
|
need do nothing to make this happen, and can ignore the file if it's of no
|
|
|
|
use. If you are editing a web in certain text editors, though, such as
|
|
|
|
//BBEdit -> https://www.barebones.com/products/bbedit// for MacOS, then this
|
|
|
|
should make code completion and definition lookup features work.
|
|
|
|
|
|
|
|
You can however write the file elsewhere:
|
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb W -tangle -ctags-to secret_lair/my_nifty.ctags
|
|
|
|
=
|
|
|
|
or not at all:
|
|
|
|
= (text as ConsoleText)
|
|
|
|
$ inweb/Tangled/inweb W -tangle -no-ctags
|
|
|
|
=
|