aboutsummaryrefslogtreecommitdiff
path: root/index.html
blob: 54769edb835645f532e9481a14ed2f4c90c1d204 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<h1>tt ('tangle to')</h1>
<pre><a href="#synopsis">Synopsis</a><br/><a href="#syntax">Syntax</a><br/><a href="#example-1">Example 1</a><br/><a href="#example-2">Example 2</a><br/></pre>

<h2 id="synopsis">Synopsis</h2>
<pre>tt [-c<i>CODE_PREFIX</i>] [-d<i>DOC_PREFIX</i>] [-o<i>OUT_PREFIX</i>] destinations [...]</pre>
<p><i>tt</i> is a tool for source code organization and/or literate
programming, which takes source code organized in a human-friendly
manner and 'tangles' it into source code organized in a
computer-friendly manner.</p>
<p>It takes any number of <i>destination files</i> as command-line arguments and <i>source input</i> on the standard input -- for example:</p>
<pre>$ tt computerfriendly.c &lt; humanfriendly.c</pre>
<ul>
  <li>Destination files are templates for the 'tangled' (computer-friendly) source code. They contain special sequences marking <i>destinations</i>: for example, <code>&lt;&lt;top&gt;&gt;</code>, <code>&lt;&lt;middle&gt;&gt;</code> and <code>&lt;&lt;bottom&gt;&gt;</code>.</li>
  <li>Source input, in turn, contains special sequences referencing these destinations: <code>-&gt; top</code>, <code>-&gt; middle</code> and <code>-&gt; bottom</code>. For instance, all code following <code>-&gt; top</code> will be inserted at any location marked by <code>&lt;&lt;top&gt;&gt;</code> in the destination files.</li>
</ul>
<h2 id="syntax">Syntax</h2>


<h3>Source input<br/>
</h3>

Source files contain <i>code lines</i> and <i>documentation lines</i>, formatted accordingly:<br/>


<pre>code line ::= CODE_PREFIX anything<br/>documentation line ::= DOC_PREFIX anything [reference]<br/><br/>reference ::= "-&gt;" [whitespace] identifier [whitespace]<br/>identifier ::= not whitespace<br/></pre>

<p>The default value of CODE_PREFIX is '&nbsp;&nbsp;&nbsp; ' (four spaces), while DOC_PREFIX, by default, is empty.<br/>
</p>

<p>Documentation lines <b>containing references</b> cause all subsequent code lines to be
tangled to the corresponding identifier(s) in destination files (until the next documentation line containing a reference).<br/>
</p>


<h3>Destination files</h3>

The files given as command-line arguments to <i>tt</i>, in this case <i>scripts.ahk</i>, contain <i>destination lines</i> and <i>plain text lines</i>.<br/>


<pre>destination line ::= [indentation] "&lt;&lt;" identifier "&gt;&gt;"<br/>plain text line ::= anything<br/><br/>indentation ::= " " [indentation]<br/></pre>

<p>Any indentation preceding an identifier will be preserved when the code lines from the source input are inserted.<br/>
</p>

<h2 id="example-1">Example 1: Pulling separate modules into a single file<br/>
</h2>

<p>Assuming the files<br/>
</p>
<table border="1" cellpadding="2" cellspacing="2" width="100">
  <tbody>
    <tr>
      <td valign="top"><i>plugins/nerdtree.vim<br/>
      </i></td>
      <td valign="top"><i>plugins/vimtex.vim<br/>
      </i></td>
      <td valign="top"><i>vimrc<br/>
      </i></td>
    </tr>
    <tr>
      <td valign="top">
      <pre>" -&gt; plugins<br/>Plug 'scrooloose/nerdtree'<br/>let g:NERDTreeWinSize = 30<br/></pre>
      </td>
      <td valign="top">
      <pre>" -&gt; plugins<br/>Plug 'lervag/vimtex'<br/>let g:tex_flavor = 'latex'<br/></pre>
      </td>
      <td valign="top">
      <pre>call plug#begin('~/.vim/plug')<br/>&lt;&lt;plugins&gt;&gt;<br/>call plug#end()<br/></pre>
      </td>
    </tr>
  </tbody>
</table>
<p>then the shell command<br/>
</p>
<p></p>
<pre>$ tt -d\" -c -o$HOME/. vimrc &lt; plugins/nerdtree.vim &lt; plugins/vimtex.vim<br/></pre>
<p>would create the file <i>$HOME/.vimrc</i> with the following contents:</p>
<table border="1" cellpadding="2" cellspacing="2" width="100">

  <tbody>
    <tr>
      <td valign="top"><i>$HOME/.vimrc<br/>
      </i></td>
      
      
    </tr>
    <tr>
      <td valign="top">
      <pre>call plug#begin('~/.vim/plug')<br/>Plug 'scrooloose/nerdtree'<br/>let g:NERDTreeWinSize = 30<br/>Plug 'lervag/vimtex'<br/>let g:tex_flavor = 'latex'<br/>call plug#end()</pre>
      </td>
      
      
    </tr>
  </tbody>
</table>


<h2 id="example-2">Example 2: Creating source code from literate program</h2>

<p><i>tt</i> is also well-suited for more traditional literate
programming, and its default options work especially well with Markdown
syntax.</p>
<p>It differs, however, from most other literate programming tools in that it doesn't resolve references within the same file.
If this is desired, then multiple passes are required.
</p>
<p>Assuming the files</p>



<table border="1" cellpadding="2" cellspacing="2" width="100">

  <tbody>
    <tr>
      <td valign="top"><i>program.markdown<br/>
      </i></td>
      
      <td valign="top"><i>program.c<br/>
      </i></td>
    </tr>
    <tr>
      <td valign="top">
      <pre># My program -&gt; program.c<br/><br/>    &lt;&lt;declarations&gt;&gt;<br/>    &lt;&lt;main&gt;&gt;<br/><br/>## Main function -&gt; main<br/><br/>Here is the main function:<br/><br/>    int main(int argc, char *argv[]) {<br/>      int i;<br/>      &lt;&lt;main.options&gt;&gt;<br/>      ...<br/>    }<br/><br/>### Command-line options -&gt; main.options<br/><br/>    for (i = 1; i &lt; argc; i++)<br/>      ...<br/><br/>### Declarations -&gt; declarations<br/><br/>So far, we have used the following global variables:<br/><br/>    char *line;<br/>    int line_length;<br/>    int line_size;<br/></pre>
      </td>
      
      <td valign="top">
      <pre>&lt;&lt;program.c&gt;&gt;<br/></pre>
      </td>
    </tr>
  </tbody>
</table>

<p>then the shell commands<br/>
</p>


<pre>$ mkdir 1 2 out<br/>$ tt -d"#" -o1/ program.markdown &lt; program.markdown<br/>$ tt -d"#" -o2/ program.markdown &lt; 1/program.markdown<br/>$ tt -d"#" -oout/ program.c &lt; 2/program.markdown<br/></pre>

<p>would create the file <i>out/program.c</i> with the following contents:</p>

<table border="1" cellpadding="2" cellspacing="2" width="100">


  <tbody>
    <tr>
      <td valign="top"><i>out/program.c<br/>
      </i></td>
      
      
    </tr>
    <tr>
      <td valign="top">
      <pre>char *line;<br/>int line_length;<br/>int line_size;<br/>int main(int argc, char *argv[]) {<br/>  int i;<br/>  for (i = 1; i &lt; argc; i++)<br/>    ...<br/>  ...<br/>}</pre>
      </td>
      
      
    </tr>
  </tbody>
</table>
<p>Three separate passes are required, because there are, in total, three re-locations of source code:</p>
<ol>
  <li><i>&#8594; main.options</i></li>
  <li><i>&#8594; main</i>, <i>declarations</i></li>
  <li>&#8594; <i>program.c</i></li>
</ol>
<p>This could conceivably be automated with a simple shell script:</p>
<pre>#!/bin/sh<br/>mkdir tmp out<br/>file=program.markdown<br/>i=0<br/>cp $file tmp/$i$file<br/>while grep '^ *&lt;&lt;[^\s]&gt;&gt;$' tmp/$i$file &gt; /dev/null; do<br/>  tt -d"#" -otmp/$((++i)) $file &lt; tmp/$((i-1))$file<br/>done<br/>tt -d"#" -oout/ program.c &lt; $i$file<br/></pre>