So, you need to use cweb
to write a C/C++ program plus its documentation. How to get started? Well, I will assume you have cweb
installed on your computer and you have a C/C++ compiler handy.
Cweb files have a .w
suffix. So hello.w
is an example cweb file. When writing a cweb program, we will write "chunks" of documentation plus code. A "chunk" is a technical term, it is either starred (written @*
and includes a name, e.g., @* Clearing the Caches.
) or unstarred (written @
). Example:
@* Hello World.
This is an example to demonstrate how cweb works.
We are writing the documentation part of the chunk.
This is everything that happens before the code.
The code will start when we write an {\tt \@@c}.
@
Now we get to the main method, which will just
print out to the screen "hello world!".
@c
#include <iostream>
int main() {
std::cout<<"Hello world!"<<std::endl;
return 0;
}
@
Great! Now, we're done, but future work could include
actually doing stuff. All cweb programs have an index
@^Index, all Cweb Programs@>
of variables used.
@* Index.
So, the code is stuck in the @c
sub-chunk.
Observe how starred chunks have their section names end with a period, that is important. Why use starred chunks at all? Well, several things happen with a starred chunk:
- They start on their own page. So if I was in the middle of the page when the last chunk ended, the next chunk (if starred) will pop up on the next page.
- They show up on the table of contents. Unstarred chunks do not.
- They group the code into logical components.
We also have an index automatically produced for us. We should isolate it in its own starred section.
So, great, you've got your first cweb program done. What now? Well, lets make the documentation. To do this, just call cweave hello.w
(or whatever you named your program), then pdftex hello.tex
(NOTE THE .TEX ENDING!!).
~/hello/$ cweave hello.w
This is CWEAVE, Version 3.64 (TeX Live 2015/dev/Debian)
*1*4
Writing the output file...*1*4
Writing the index...
Done.
(No errors were found.)
~/hello/$
~/hello/$ pdftex hello.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./hello.tex (/usr/share/texlive/texmf-dist/tex/plain/cweb/cwebmac.tex
(/usr/share/texlive/texmf-dist/tex/generic/pdftex/pdfcolor.tex)) *1 [1{/var/lib
/texmf/fonts/map/pdftex/updmap/pdftex.map}] *4 Index: (./hello.idx) [2]
Section names: (./hello.toc) (./hello.scn) Table of contents: (./hello.toc)
[0] )</usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb><
/usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/sh
are/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/share/texl
ive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></usr/share/texlive/texm
f-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/share/texlive/texmf-dist
/fonts/type1/public/amsfonts/cm/cmtex10.pfb></usr/share/texlive/texmf-dist/font
s/type1/public/amsfonts/cm/cmti10.pfb></usr/share/texlive/texmf-dist/fonts/type
1/public/amsfonts/cm/cmtt10.pfb>
Output written on hello.pdf (3 pages, 87844 bytes).
Transcript written on hello.log.
If you want to produce the binary, for C++ you have to call:
~/hello/$ ctangle hello.w - hello.cpp
This is CTANGLE, Version 3.64 (TeX Live 2015/dev/Debian)
*1*4
Writing the output file (hello.cpp):
Done.
(No errors were found.)
~/hello/$
~/hello/$ g++ hello.cpp
~/hello/$
If you are making a C program, then you can just call ctangle hello.w
. By default it produces a ".c" file. You must manually specify the output by writing ctangle input.w - myPreferredOutputFilename.c
, or whatever.
Things I may have forgotten to talk about, but are important nevertheless:
1. Index. You can add index entries manually by placing on a newline @^Entry Name@>
then on a new line continue writing.
2. Named Chunks. There are times when you want to name a chunk of code by what it does. This allows the pdf to have as output, e.g.,
void processVotes () {
<Clear the caches>
<Load the Delegates>
<Open the Source of Votes>
<Tally up the votes>
}
To do this, you just need to write in your cweb file:
@c
void processVotes () {
@<Clear the caches@>@;
@<Load the Delegates@>@;
@<Open the Source of Votes@>@;
@<Tally up the votes@>@;
}
@ @<Clear the caches@>=
// stick the implementation code here
@ @<Load the Delegates@>=
// stick the implementation code here
@ @<Open the Source of Votes@>=
// stick the implementation code here
@ Tallying the votes is harder than you think. Let me
explain the basic process. First we don't look at the votes
at all. We just generate a bunch of random numbers, then
pick Walter Mandale.
@<Tally up the votes@>=
// stick the implementation code here
This allows the code to be more "self-documenting", and gives some idea of what's going on. Of course, with this example, I probably would have replaced Tally up the votes
with Rig Election for Walter Mandale
...but that might be too incriminating ;)
3. Page Breaks. To disable pagebreaks altogether, include a line \secpagedepth=0
at the start of your cweb program. To have a page break at depth d
, include \secpagedepth=(d+1)
.
There are a number of examples to look at, to learn even more about Cweb.
- Donald Knuth's "Irredundant Intervals", source -- rename the file as a
.tar.gz
since the arXiv won't do it for you. - The Cweb Examples are full of good examples.
And of course, don't forget to read the fine documentation.