just use go/run

This commit is contained in:
Mark McGranaghan 2012-09-29 14:17:53 -07:00
parent dbf69907cc
commit 905d6d97c3
3 changed files with 16 additions and 213 deletions

View File

@ -3,17 +3,11 @@
Go by Example book source.
### Building Tools
```console
$ tool/build
```
### Numbering
### Number'ing
```console
$ mate tool/index.txt
$ tool/number
$ go run tool/number.go
```
@ -22,3 +16,11 @@ $ tool/number
```console
$ tool/gofmt
```
### Golit'ing
```console
$ go run tool/generate.go tool/generate > build/generate.html
$ open build/generate.html
```

View File

@ -1,199 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
<title>golit</title>
<link rel=stylesheet href="book.css">
</head>
<body>
<div id="container">
<div id="background"></div>
<table cellspacing="0" cellpadding="0">
<thead>
<tr><td class=docs></td><td class=code></td></tr>
</thead>
<tbody><tr><td class=docs><h2>golit</h2>
</td><td class=code><div class="highlight"><pre>
</pre></div>
</td></tr>
<tr><td class=docs><p>Generate literate-programming style HTML
documentation form Go source files.</p>
</td><td class=code><div class="highlight"><pre><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;io/ioutil&quot;</span>
<span class="s">&quot;os&quot;</span>
<span class="s">&quot;os/exec&quot;</span>
<span class="s">&quot;regexp&quot;</span>
<span class="s">&quot;strings&quot;</span>
<span class="p">)</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Recognize doc lines, extract their comment prefixes.</p>
</td><td class=code><div class="highlight"><pre><span class="k">var</span> <span class="n">docsPat</span> <span class="p">=</span> <span class="n">regexp</span><span class="p">.</span><span class="n">MustCompile</span><span class="p">(</span><span class="s">&quot;^\\s*\\/\\/\\s&quot;</span><span class="p">)</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Recognize title prefixes, for titling web page.</p>
</td><td class=code><div class="highlight"><pre><span class="k">var</span> <span class="n">titlePat</span> <span class="p">=</span> <span class="n">regexp</span><span class="p">.</span><span class="n">MustCompile</span><span class="p">(</span><span class="s">&quot;^\\/\\/\\s##\\s&quot;</span><span class="p">)</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Abort on non-nil errors.</p>
</td><td class=code><div class="highlight"><pre><span class="k">func</span> <span class="n">check</span><span class="p">(</span><span class="n">err</span> <span class="n">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="n">err</span> <span class="p">!=</span> <span class="n">nil</span> <span class="p">{</span>
<span class="n">panic</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>We'll implement Markdown rendering and Pygments syntax
highlighting by piping data through external programs.
This is a general helper for handling both cases.</p>
</td><td class=code><div class="highlight"><pre><span class="k">func</span> <span class="n">pipedCmd</span><span class="p">(</span><span class="n">binary</span> <span class="nb">string</span><span class="p">,</span> <span class="n">argv</span> <span class="p">[]</span><span class="nb">string</span><span class="p">,</span> <span class="n">input</span> <span class="nb">string</span><span class="p">)</span> <span class="nb">string</span> <span class="p">{</span>
<span class="n">cmd</span> <span class="p">:=</span> <span class="n">exec</span><span class="p">.</span><span class="n">Command</span><span class="p">(</span><span class="n">binary</span><span class="p">,</span> <span class="n">argv</span><span class="p">...)</span>
<span class="n">in</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">StdinPipe</span><span class="p">()</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">out</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">StdoutPipe</span><span class="p">()</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">err</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">Start</span><span class="p">()</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">in</span><span class="p">.</span><span class="n">Write</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="n">input</span><span class="p">))</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">err</span> <span class="p">=</span> <span class="n">in</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">bytes</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">ioutil</span><span class="p">.</span><span class="n">ReadAll</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">err</span> <span class="p">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">Wait</span><span class="p">()</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">string</span><span class="p">(</span><span class="n">bytes</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>We'll break the code into {docs, code} pairs,
and then render those text segments before
including them in the HTML doc.</p>
</td><td class=code><div class="highlight"><pre><span class="k">type</span> <span class="n">segment</span> <span class="k">struct</span> <span class="p">{</span>
<span class="n">docs</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">docsRendered</span><span class="p">,</span> <span class="n">codeRendered</span> <span class="nb">string</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Accept exactly 1 argument - the input filename.</p>
</td><td class=code><div class="highlight"><pre> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">Args</span><span class="p">)</span> <span class="p">!=</span> <span class="mi">2</span> <span class="p">{</span>
<span class="n">fmt</span><span class="p">.</span><span class="n">Fprintln</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">Stderr</span><span class="p">,</span> <span class="s">&quot;Usage: tool/generate input.go &gt; output.html&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="p">.</span><span class="n">Exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Ensure that we have <code>markdown</code> and <code>pygmentize</code>,
binaries, remember their paths.</p>
</td><td class=code><div class="highlight"><pre> <span class="n">markdownPath</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">exec</span><span class="p">.</span><span class="n">LookPath</span><span class="p">(</span><span class="s">&quot;markdown&quot;</span><span class="p">)</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">pygmentizePath</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">exec</span><span class="p">.</span><span class="n">LookPath</span><span class="p">(</span><span class="s">&quot;pygmentize&quot;</span><span class="p">)</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Read the source file in, split into lines.</p>
</td><td class=code><div class="highlight"><pre> <span class="n">sourceBytes</span><span class="p">,</span> <span class="n">err</span> <span class="p">:=</span> <span class="n">ioutil</span><span class="p">.</span><span class="n">ReadFile</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">Args</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">check</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="n">lines</span> <span class="p">:=</span> <span class="n">strings</span><span class="p">.</span><span class="n">Split</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="n">sourceBytes</span><span class="p">),</span> <span class="s">&quot;\n&quot;</span><span class="p">)</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Group lines into docs/code segments.
Special case the header to go in its own segment.</p>
</td><td class=code><div class="highlight"><pre> <span class="n">segments</span> <span class="p">:=</span> <span class="p">[]*</span><span class="n">segment</span><span class="p">{}</span>
<span class="n">segments</span> <span class="p">=</span> <span class="n">append</span><span class="p">(</span><span class="n">segments</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">segment</span><span class="p">{</span><span class="n">code</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">docs</span><span class="p">:</span> <span class="n">docsPat</span><span class="p">.</span><span class="n">ReplaceAllString</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&quot;&quot;</span><span class="p">)})</span>
<span class="n">segments</span> <span class="p">=</span> <span class="n">append</span><span class="p">(</span><span class="n">segments</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">segment</span><span class="p">{</span><span class="n">code</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">docs</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">})</span>
<span class="n">lastLine</span> <span class="p">:=</span> <span class="s">&quot;&quot;</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">line</span> <span class="p">:=</span> <span class="k">range</span> <span class="n">lines</span><span class="p">[</span><span class="mi">2</span><span class="p">:]</span> <span class="p">{</span>
<span class="n">head</span> <span class="p">:=</span> <span class="n">segments</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">segments</span><span class="p">)-</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Doc line - trim off the comment markers.</p>
</td><td class=code><div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="n">line</span> <span class="p">==</span> <span class="s">&quot;&quot;</span> <span class="p">&amp;&amp;</span> <span class="n">lastLine</span> <span class="p">==</span> <span class="s">&quot;docs&quot;</span><span class="p">)</span> <span class="p">||</span> <span class="n">docsPat</span><span class="p">.</span><span class="n">MatchString</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="p">{</span>
<span class="n">trimLine</span> <span class="p">:=</span> <span class="n">docsPat</span><span class="p">.</span><span class="n">ReplaceAllString</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="p">!(</span><span class="n">lastLine</span> <span class="p">==</span> <span class="s">&quot;code&quot;</span> <span class="p">&amp;&amp;</span> <span class="n">head</span><span class="p">.</span><span class="n">docs</span> <span class="p">!=</span> <span class="s">&quot;&quot;</span><span class="p">)</span> <span class="p">{</span>
<span class="n">head</span><span class="p">.</span><span class="n">docs</span> <span class="p">=</span> <span class="n">head</span><span class="p">.</span><span class="n">docs</span> <span class="p">+</span> <span class="s">&quot;\n&quot;</span> <span class="p">+</span> <span class="n">trimLine</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">segments</span> <span class="p">=</span> <span class="n">append</span><span class="p">(</span><span class="n">segments</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">segment</span><span class="p">{</span><span class="n">docs</span><span class="p">:</span> <span class="n">trimLine</span><span class="p">,</span> <span class="n">code</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">})</span>
<span class="p">}</span>
<span class="n">lastLine</span> <span class="p">=</span> <span class="s">&quot;docs&quot;</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Code line - preserve all whitespace.</p>
</td><td class=code><div class="highlight"><pre> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">!(</span><span class="n">lastLine</span> <span class="p">==</span> <span class="s">&quot;docs&quot;</span> <span class="p">&amp;&amp;</span> <span class="n">head</span><span class="p">.</span><span class="n">code</span> <span class="p">!=</span> <span class="s">&quot;&quot;</span><span class="p">)</span> <span class="p">{</span>
<span class="n">head</span><span class="p">.</span><span class="n">code</span> <span class="p">=</span> <span class="n">head</span><span class="p">.</span><span class="n">code</span> <span class="p">+</span> <span class="s">&quot;\n&quot;</span> <span class="p">+</span> <span class="n">line</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">segments</span> <span class="p">=</span> <span class="n">append</span><span class="p">(</span><span class="n">segments</span><span class="p">,</span> <span class="p">&amp;</span><span class="n">segment</span><span class="p">{</span><span class="n">docs</span><span class="p">:</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">code</span><span class="p">:</span> <span class="n">line</span><span class="p">})</span>
<span class="p">}</span>
<span class="n">lastLine</span> <span class="p">=</span> <span class="s">&quot;code&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Render docs via <code>markdown</code> and code via
<code>pygmentize</code> in each segment.</p>
</td><td class=code><div class="highlight"><pre> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">seg</span> <span class="p">:=</span> <span class="k">range</span> <span class="n">segments</span> <span class="p">{</span>
<span class="n">seg</span><span class="p">.</span><span class="n">docsRendered</span> <span class="p">=</span> <span class="n">pipedCmd</span><span class="p">(</span><span class="n">markdownPath</span><span class="p">,</span> <span class="p">[]</span><span class="nb">string</span><span class="p">{},</span> <span class="n">seg</span><span class="p">.</span><span class="n">docs</span><span class="p">)</span>
<span class="n">seg</span><span class="p">.</span><span class="n">codeRendered</span> <span class="p">=</span> <span class="n">pipedCmd</span><span class="p">(</span><span class="n">pygmentizePath</span><span class="p">,</span> <span class="p">[]</span><span class="nb">string</span><span class="p">{</span><span class="s">&quot;-l&quot;</span><span class="p">,</span> <span class="s">&quot;go&quot;</span><span class="p">,</span> <span class="s">&quot;-f&quot;</span><span class="p">,</span> <span class="s">&quot;html&quot;</span><span class="p">},</span> <span class="n">seg</span><span class="p">.</span><span class="n">code</span><span class="p">+</span><span class="s">&quot; &quot;</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Print HTML header.</p>
</td><td class=code><div class="highlight"><pre> <span class="n">fmt</span><span class="p">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">`</span>
<span class="s">&lt;!DOCTYPE html&gt;</span>
<span class="s">&lt;html&gt;</span>
<span class="s"> &lt;head&gt;</span>
<span class="s"> &lt;meta http-eqiv=&quot;content-type&quot; content=&quot;text/html;charset=utf-8&quot;&gt;</span>
<span class="s"> &lt;title&gt;%s&lt;/title&gt;</span>
<span class="s"> &lt;link rel=stylesheet href=&quot;book.css&quot;&gt;</span>
<span class="s"> &lt;/head&gt;</span>
<span class="s"> &lt;body&gt;</span>
<span class="s"> &lt;div id=&quot;container&quot;&gt;</span>
<span class="s"> &lt;div id=&quot;background&quot;&gt;&lt;/div&gt;</span>
<span class="s"> &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;</span>
<span class="s"> &lt;thead&gt;</span>
<span class="s"> &lt;tr&gt;&lt;td class=docs&gt;&lt;/td&gt;&lt;td class=code&gt;&lt;/td&gt;&lt;/tr&gt;</span>
<span class="s"> &lt;/thead&gt;</span>
<span class="s"> &lt;tbody&gt;`</span><span class="p">,</span> <span class="n">titlePat</span><span class="p">.</span><span class="n">ReplaceAllString</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&quot;&quot;</span><span class="p">))</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Print HTML docs/code segments.</p>
</td><td class=code><div class="highlight"><pre> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">seg</span> <span class="p">:=</span> <span class="k">range</span> <span class="n">segments</span> <span class="p">{</span>
<span class="n">fmt</span><span class="p">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">&quot;&lt;tr&gt;&lt;td class=docs&gt;%s&lt;/td&gt;&lt;td class=code&gt;%s&lt;/td&gt;&lt;/tr&gt;\n&quot;</span><span class="p">,</span> <span class="n">seg</span><span class="p">.</span><span class="n">docsRendered</span><span class="p">,</span> <span class="n">seg</span><span class="p">.</span><span class="n">codeRendered</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td></tr>
<tr><td class=docs><p>Print HTML footer.</p>
</td><td class=code><div class="highlight"><pre> <span class="n">fmt</span><span class="p">.</span><span class="n">Print</span><span class="p">(</span><span class="s">`</span>
<span class="s"> &lt;/tbody&gt;</span>
<span class="s"> &lt;/table&gt;</span>
<span class="s"> &lt;/div&gt;</span>
<span class="s"> &lt;/body&gt;</span>
<span class="s">&lt;/html&gt;</span>
<span class="s">`</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td></tr>
</tbody>
</table>
</div>
</body>
</html>

View File

@ -1,7 +1,7 @@
// ## golit
// Generate literate-programming style HTML
// documentation form Go source files.
// **golit** generates literate-programming style HTML
// documentation from a Go source files.
package main
@ -57,9 +57,9 @@ type segment struct {
}
func main() {
// Accept exactly 1 argument - the input filename.
// Accept exactly 1 argument - the input filename, less the .go extension.
if len(os.Args) != 2 {
fmt.Fprintln(os.Stderr, "Usage: tool/generate input.go > output.html")
fmt.Fprintln(os.Stderr, "Usage: go run tool/generate.go input > output.html")
os.Exit(1)
}
@ -71,7 +71,7 @@ func main() {
check(err)
// Read the source file in, split into lines.
sourceBytes, err := ioutil.ReadFile(os.Args[1])
sourceBytes, err := ioutil.ReadFile(os.Args[1]+".go")
check(err)
lines := strings.Split(string(sourceBytes), "\n")
@ -117,7 +117,7 @@ func main() {
<head>
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
<title>%s</title>
<link rel=stylesheet href="book.css">
<link rel=stylesheet href="http://jashkenas.github.com/docco/resources/docco.css">
</head>
<body>
<div id="container">