tt / index.html 183 lines  7.28 kB  Raw
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>



<meta content="text/html; charset=windows-1252" http-equiv="content-type"><title>tt (tangle to): literate progamming tool</title>

<style type="text/css">
pre {
  margin-left: 40px;
}
table pre {
  margin: 0;
}

</style>
  <meta content="John Ankarström" name="author"></head><body>
<h1>tt (“tangle to”)</h1>
<pre><a href="src/">Source</a> / <a href="src/1.1/">Latest</a><br><br><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. <br>
If this is desired, then multiple passes are required.<br>
</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>
</body></html>