Skip to content

Instantly share code, notes, and snippets.

@pqnelson
Forked from anonymous/cweb-tutorial.md
Last active August 2, 2016 14:57
Show Gist options
  • Save pqnelson/6e7c24c1fb47086eb31f to your computer and use it in GitHub Desktop.
Save pqnelson/6e7c24c1fb47086eb31f to your computer and use it in GitHub Desktop.
@q This file defines standard C++ namespaces and classes @>
@q Please send corrections to saroj-tamasa@@worldnet.att.net @>
@s std int
@s rel_ops int
@s bitset int
@s char_traits int
@s deque int
@s list int
@s map int
@s multimap int
@s multiset int
@s pair int
@s set int
@s stack int
@s exception int
@s logic_error int
@s runtime_error int
@s domain_error int
@s invalid_argument int
@s length_error int
@s out_of_range int
@s range_error int
@s overflow_error int
@s underflow_error int
@s back_insert_iterator int
@s front_insert_iterator int
@s insert_iterator int
@s reverse_iterator int
@s istream_iterator int
@s ostream_iterator int
@s istreambuf_iterator int
@s ostreambuf_iterator int
@s iterator_traits int
@s queue int
@s vector int
@s basic_string int
@s string int
@s auto_ptr int
@s valarray int
@s ios_base int
@s basic_ios int
@s basic_streambuf int
@s basic_istream int
@s basic_ostream int
@s basic_iostream int
@s basic_stringbuf int
@s basic_istringstream int
@s basic_ostringstream int
@s basic_stringstream int
@s basic_filebuf int
@s basic_ifstream int
@s basic_ofstream int
@s basic_fstream int
@s ctype int
@s collate int
@s collate_byname int
@s streambuf int
@s istream int
@s ostream int
@s iostream int
@s stringbuf int
@s istringstream int
@s ostringstream int
@s stringstream int
@s filebuf int
@s ifstream int
@s ofstream int
@s fstream int
@s wstreambuf int
@s wistream int
@s wostream int
@s wiostram int
@s wstringbuf int
@s wistringstream int
@s wostringstream int
@s wstringstream int
@s wfilebuf int
@s wifstream int
@s wofstream int
@s wfstream int
@s streamoff int
@s streamsize int
@s fpos int
@s streampos int
@s wstreampos int
@q Corrections I added by hand @>
@s bool int
@s static_cast int
@s ios int
@s typename const
@s using int
@s namespace enum
@s storage int
@s constexpr const
@q To make templates pretty-printed, don't forget the "@f _ make_pair" @>

Basic Idea

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:

  1. 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.
  2. They show up on the table of contents. Unstarred chunks do not.
  3. 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.

Producing the Documentation

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.

Producing the Program

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.

Advanced Features

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).

Examples to look at

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment