]> Cypherpunks repositories - gostls13.git/commitdiff
bye-bye to old makehtml.
authorRob Pike <r@golang.org>
Wed, 14 Oct 2009 05:10:16 +0000 (22:10 -0700)
committerRob Pike <r@golang.org>
Wed, 14 Oct 2009 05:10:16 +0000 (22:10 -0700)
go can do the job just fine.

R=rsc
DELTA=290  (209 added, 13 deleted, 68 changed)
OCL=35699
CL=35699

doc/Makefile [new file with mode: 0644]
doc/go_tutorial.head [deleted file]
doc/go_tutorial.html
doc/go_tutorial.txt
doc/htmlgen.go [new file with mode: 0644]
doc/makehtml [new file with mode: 0755]

diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..0abb881
--- /dev/null
@@ -0,0 +1,11 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.$(GOARCH)
+
+TARG=htmlgen
+GOFILES=\
+       htmlgen.go\
+
+include $(GOROOT)/src/Make.cmd
diff --git a/doc/go_tutorial.head b/doc/go_tutorial.head
deleted file mode 100644 (file)
index a15e536..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- Let's Go -->
-
-<h2>Introduction</h2>
index f966ef936a4e7ba50e6e8f8e0d7055bc85f1e31e..27710ed268c5669b13a09475d34cbc22c987e55c 100644 (file)
@@ -1,15 +1,14 @@
 <!-- Let's Go -->
-
 <h2>Introduction</h2>
 <p>
 This document is a tutorial introduction to the basics of the Go systems programming
 language, intended for programmers familiar with C or C++. It is not a comprehensive
 guide to the language; at the moment the document closest to that is the
-<a href=/doc/go_spec.html>language specification.</a>
+<a href='/doc/go_spec.html'>language specification.</a>
 <p>
 The presentation proceeds through a series of modest programs to illustrate
 key features of the language.  All the programs work (at time of writing) and are
-checked into the repository in the directory <a href=/doc/progs><code>/doc/progs</code></a>.
+checked into the repository in the directory <a href='/doc/progs'><code>/doc/progs/</code></a>.
 <p>
 Program snippets are annotated with the line number in the original file; for
 cleanliness, blank lines remain blank.
@@ -45,8 +44,8 @@ The comment convention is the same as in C++:
 <pre>
     /* ... */
     // ...
-
 </pre>
+<p>
 Later we'll have much more to say about printing.
 <p>
 <h2>Echo</h2>
@@ -94,8 +93,8 @@ But it's not necessary to do so; we could have said
 <pre>
     const Space = " "
     const Newline = "\n"
-
 </pre>
+<p>
 Semicolons aren't needed here; in fact, semicolons are unnecessary after any
 top-level declaration, even though they are needed as separators <i>within</i>
 a parenthesized list of declarations.
@@ -128,8 +127,8 @@ The declaration statement has the form
 <p>
 <pre>
     var s string = "";
-
 </pre>
+<p>
 This is the <code>var</code> keyword, followed by the name of the variable, followed by
 its type, followed by an equals sign and an initial value for the variable.
 <p>
@@ -139,14 +138,14 @@ We could write
 <p>
 <pre>
     var s = "";
-
 </pre>
+<p>
 or we could go even shorter and write the idiom
 <p>
 <pre>
     s := "";
-
 </pre>
+<p>
 The <code>:=</code> operator is used a lot in Go to represent an initializing declaration.
 (For those who know Sawzall, its <code>:=</code> construct is the same, but notice
 that Go has no colon after the name in a full <code>var</code> declaration.
@@ -177,8 +176,8 @@ It's defined that way.  Falling off the end of <code>main.main</code> means
 <p>
 <pre>
     os.Exit(1)
-
 </pre>
+<p>
 The <code>os</code> package contains other essentials for getting
 started; for instance, <code>os.Args</code> is an array used by the
 <code>flag</code> package to access the command-line arguments.
@@ -213,8 +212,8 @@ a <code>string</code> value:
 <pre>
     s[0] = 'x';
     (*p)[1] = 'y';
-
 </pre>
+<p>
 In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers
 to strings are analogous to <code>const string</code> references.
 <p>
@@ -225,8 +224,8 @@ Arrays are declared like this:
 <p>
 <pre>
     var array_of_int [10]int;
-
 </pre>
+<p>
 Arrays, like strings, are values, but they are mutable. This differs
 from C, in which <code>array_of_int</code> would be usable as a pointer to <code>int</code>.
 In Go, since arrays are values, it's meaningful (and useful) to talk
@@ -286,21 +285,21 @@ elements for you, use <code>...</code> as the array size:
 <p>
 <pre>
     s := sum(&amp;[...]int{1,2,3});
-
 </pre>
+<p>
 In practice, though, unless you're meticulous about storage layout within a
 data structure, a slice itself - using empty brackets and no <code>&</code> - is all you need:
 <p>
 <pre>
     s := sum([]int{1,2,3});
-
 </pre>
+<p>
 There are also maps, which you can initialize like this:
 <p>
 <pre>
     m := map[string] int {"one":1 , "two":2}
-
 </pre>
+<p>
 The built-in function <code>len()</code>, which returns number of elements,
 makes its first appearance in <code>sum</code>.  It works on strings, arrays,
 slices, and maps.
@@ -317,14 +316,14 @@ returns a pointer to the allocated storage.
 <pre>
     type T struct { a, b int }
     var t *T = new(T);
-
 </pre>
+<p>
 or the more idiomatic
 <p>
 <pre>
     t := new(T);
-
 </pre>
+<p>
 Some types - maps, slices, and channels (see below) - have reference semantics.
 If you're holding a slice or a map and you modify its contents, other variables
 referencing the same underlying data will see the modification.  For these three
@@ -332,15 +331,15 @@ types you want to use the built-in function <code>make()</code>:
 <p>
 <pre>
     m := make(map[string] int);
-
 </pre>
+<p>
 This statement initializes a new map ready to store entries.
 If you just declare the map, as in
 <p>
 <pre>
     var m map[string] int;
-
 </pre>
+<p>
 it creates a <code>nil</code> reference that cannot hold anything. To use the map,
 you must first initialize the reference using <code>make()</code> or by assignment to an
 existing map.
@@ -360,8 +359,8 @@ too little precision to represent the value.
 <p>
 <pre>
     const hard_eight = (1 &lt;&lt; 100) &gt;&gt; 97  // legal
-
 </pre>
+<p>
 There are nuances that deserve redirection to the legalese of the
 language specification but here are some illustrative examples:
 <p>
@@ -373,8 +372,8 @@ language specification but here are some illustrative examples:
     x := 1.5          // a float
     i3div2 := 3/2     // integer division - result is 1
     f3div2 := 3./2.   // floating point division - result is 1.5
-
 </pre>
+<p>
 Conversions only work for simple cases such as converting <code>ints</code> of one
 sign or size to another, and between <code>ints</code> and <code>floats</code>, plus a few other
 simple cases.  There are no automatic numeric conversions of any kind in Go,
@@ -446,8 +445,8 @@ object.  We could write
     n.fd = fd;
     n.name = name;
     return n
-
 </pre>
+<p>
 but for simple structures like <code>File</code> it's easier to return the address of a nonce
 composite literal, as is done here on line 21.
 <p>
@@ -585,8 +584,8 @@ Finally we can run the program:
     hello, world
     can't open file; err=No such file or directory
     %
-
 </pre>
+<p>
 <h2>Rotting cats</h2>
 <p>
 Building on the <code>file</code> package, here's a simple version of the Unix utility <code>cat(1)</code>,
@@ -864,8 +863,8 @@ Within the <code>fmt</code> package, <code>Printf</code> is declared with this s
 <p>
 <pre>
     Printf(format string, v ...) (n int, errno os.Error)
-
 </pre>
+<p>
 That <code>...</code> represents the variadic argument list that in C would
 be handled using the <code>stdarg.h</code> macros, but in Go is passed using
 an empty interface variable (<code>interface {}</code>) that is then unpacked
@@ -888,8 +887,8 @@ prints
 <p>
 <pre>
     18446744073709551615 -1
-
 </pre>
+<p>
 In fact, if you're lazy the format <code>%v</code> will print, in a simple
 appropriate style, any value, even an array or structure.  The output of
 <p>
@@ -904,8 +903,8 @@ is
 <p>
 <pre>
     18446744073709551615 {77 Sunset Strip} [1 2 3 4]
-
 </pre>
+<p>
 You can drop the formatting altogether if you use <code>Print</code> or <code>Println</code>
 instead of <code>Printf</code>.  Those routines do fully automatic formatting.
 The <code>Print</code> function just prints its elements out using the equivalent
@@ -946,8 +945,8 @@ default formatter for that type will use it and produce the output
 <p>
 <pre>
     77 Sunset Strip
-
 </pre>
+<p>
 Observe that the <code>String()</code> method calls <code>Sprint</code> (the obvious Go
 variant that returns a string) to do its formatting; special formatters
 can use the <code>fmt</code> library recursively.
@@ -970,15 +969,17 @@ Schematically, given a value <code>v</code>, it does this:
     type Stringer interface {
         String() string
     }
-
+</pre>
+<p>
+<pre>
     s, ok := v.(Stringer);  // Test whether v implements "String()"
     if ok {
         result = s.String()
     } else {
         result = default_output(v)
     }
-
 </pre>
+<p>
 The code uses a ``type assertion'' (<code>v.(Stringer)</code>) to test if the value stored in
 <code>v</code> satisfies the <code>Stringer</code> interface; if it does, <code>s</code>
 will become an interface variable implementing the method and <code>ok</code> will
@@ -1000,8 +1001,8 @@ interface type defined in the <code>io</code> library:
     type Writer interface {
         Write(p []byte) (n int, err os.Error);
     }
-
 </pre>
+<p>
 (This interface is another conventional name, this time for <code>Write</code>; there are also
 <code>io.Reader</code>, <code>io.ReadWriter</code>, and so on.)
 Thus you can call <code>Fprintf</code> on any type that implements a standard <code>Write()</code>
@@ -1081,8 +1082,8 @@ computation but in the same address space:
 <p>
 <pre>
     go sum(huge_array); // calculate sum in the background
-
 </pre>
+<p>
 If you want to know when the calculation is done, pass a channel
 on which it can report back:
 <p>
@@ -1091,8 +1092,8 @@ on which it can report back:
     go sum(huge_array, ch);
     // ... do something else for a while
     result := &lt;-ch;  // wait for, and retrieve, result
-
 </pre>
+<p>
 Back to our prime sieve.  Here's how the sieve pipeline is stitched
 together:
 <p>
index 15e29281b58ae38c1352a75c43c58fdcf561c11d..dd7cd9fd87809c1b40b57f4fd9b64a260ca7a852 100644 (file)
@@ -1,14 +1,15 @@
-Let's Go
+<!-- Let's Go -->
+Introduction
 ----
 
 This document is a tutorial introduction to the basics of the Go systems programming
 language, intended for programmers familiar with C or C++. It is not a comprehensive
 guide to the language; at the moment the document closest to that is the
-<a href=/doc/go_spec.html>language specification.</a>
+<a href='/doc/go_spec.html'>language specification.</a>
 
 The presentation proceeds through a series of modest programs to illustrate
 key features of the language.  All the programs work (at time of writing) and are
-checked into the repository in the directory <a href=/doc/progs>"/doc/progs"</a>.
+checked into the repository in the directory <a href='/doc/progs'>"/doc/progs/"</a>.
 
 Program snippets are annotated with the line number in the original file; for
 cleanliness, blank lines remain blank.
@@ -215,7 +216,7 @@ pointer to "sum()" by (automatically) promoting it to a slice.
 If you are creating a regular array but want the compiler to count the
 elements for you, use "..." as the array size:
 
-       s := sum(&[...]int{1,2,3});
+       s := sum(&amp;[...]int{1,2,3});
 
 In practice, though, unless you're meticulous about storage layout within a
 data structure, a slice itself - using empty brackets and no "&" - is all you need:
@@ -277,7 +278,7 @@ constants are evaluated as large-precision values that
 can overflow only when they are assigned to an integer variable with
 too little precision to represent the value.
 
-       const hard_eight = (1 << 100) >> 97  // legal
+       const hard_eight = (1 &lt;&lt; 100) &gt;&gt; 97  // legal
 
 There are nuances that deserve redirection to the legalese of the
 language specification but here are some illustrative examples:
@@ -542,7 +543,7 @@ to implement the three methods for that type, like this:
 
 
 Printing
----
+----
 
 The examples of formatted printing so far have been modest.  In this section
 we'll talk about how formatted I/O can be done well in Go.
@@ -721,7 +722,7 @@ on which it can report back:
        ch := make(chan int);
        go sum(huge_array, ch);
        // ... do something else for a while
-       result := <-ch;  // wait for, and retrieve, result
+       result := &lt;-ch;  // wait for, and retrieve, result
 
 Back to our prime sieve.  Here's how the sieve pipeline is stitched
 together:
@@ -824,3 +825,6 @@ at the end of main:
 
 There's a lot more to Go programming and concurrent programming in general but this
 quick tour should give you some of the basics.
+</table>
+</body>
+</html>
diff --git a/doc/htmlgen.go b/doc/htmlgen.go
new file mode 100644 (file)
index 0000000..8d44fc0
--- /dev/null
@@ -0,0 +1,192 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Process plain text into HTML.
+//     - h2's are made from lines followed by a line "----\n"
+//     - tab-indented blocks become <pre> blocks
+//     - blank lines become <p> marks
+//     - "quoted strings" become <code>quoted strings</code>
+
+package main
+
+import (
+       "bufio";
+       "bytes";
+       "log";
+       "os";
+       "strings";
+)
+
+var (
+       lines = make([][]byte, 0, 10000);       // assume big enough
+       linebuf = make([]byte, 10000);          // assume big enough
+
+       empty = strings.Bytes("");
+       newline = strings.Bytes("\n");
+       tab = strings.Bytes("\t");
+       quote = strings.Bytes(`"`);
+
+       sectionMarker = strings.Bytes("----\n");
+       preStart = strings.Bytes("<pre>");
+       preEnd = strings.Bytes("</pre>\n");
+       pp = strings.Bytes("<p>\n");
+);
+
+func main() {
+       read();
+       headings();
+       paragraphs();
+       coalesce(preStart, foldPre);
+       coalesce(tab, foldTabs);
+       quotes();
+       write();
+}
+
+func read() {
+       b := bufio.NewReader(os.Stdin);
+       for {
+               line, err := b.ReadBytes('\n');
+               if err == os.EOF {
+                       break;
+               }
+               if err != nil {
+                       log.Exit(err)
+               }
+               n := len(lines);
+               lines = lines[0:n+1];
+               lines[n] = line;
+       }
+}
+
+func write() {
+       b := bufio.NewWriter(os.Stdout);
+       for _, line := range lines {
+               b.Write(expandTabs(line));
+       }
+       b.Flush();
+}
+
+// each time prefix is found on a line, call fold and replace
+// line with return value from fold.
+func coalesce(prefix []byte, fold func(i int) (n int, line []byte)) {
+       j := 0; // output line number; goes up by one each loop
+       for i := 0; i < len(lines); {
+               if bytes.HasPrefix(lines[i], prefix) {
+                       nlines, block := fold(i);
+                       lines[j] = block;
+                       i += nlines;
+               } else {
+                       lines[j] = lines[i];
+                       i++;
+               }
+               j++;
+       }
+       lines = lines[0:j];
+}
+
+// return the <pre> block as a single slice
+func foldPre(i int) (n int, line []byte) {
+       buf := new(bytes.Buffer);
+       for i < len(lines) {
+               buf.Write(lines[i]);
+               n++;
+               if bytes.Equal(lines[i], preEnd) {
+                       break
+               }
+               i++;
+       }
+       return n, buf.Bytes();
+}
+
+// return the tab-indented block as a single <pre>-bounded slice
+func foldTabs(i int) (n int, line []byte) {
+       buf := new(bytes.Buffer);
+       buf.WriteString("<pre>\n");
+       for i < len(lines) {
+               if !bytes.HasPrefix(lines[i], tab) {
+                       break;
+               }
+               buf.Write(lines[i]);
+               n++;
+               i++;
+       }
+       buf.WriteString("</pre>\n");
+       return n, buf.Bytes();
+}
+
+func headings() {
+       b := bufio.NewWriter(os.Stdout);
+       for i, l := range lines {
+               if i > 0 && bytes.Equal(l, sectionMarker) {
+                       lines[i-1] = strings.Bytes("<h2>" + string(trim(lines[i-1])) + "</h2>\n");
+                       lines[i] = empty;
+               }
+       }
+       b.Flush();
+}
+
+func paragraphs() {
+       for i, l := range lines {
+               if bytes.Equal(l, newline) {
+                       lines[i] = pp;
+               }
+       }
+}
+
+func quotes() {
+       for i, l := range lines {
+               lines[i] = codeQuotes(l);
+       }
+}
+
+func codeQuotes(l []byte) []byte {
+       if bytes.HasPrefix(l, preStart) {
+               return l
+       }
+       n := bytes.Index(l, quote);
+       if n < 0 {
+               return l
+       }
+       buf := new(bytes.Buffer);
+       inQuote := false;
+       for _, c := range l {
+               if c == '"' {
+                       if inQuote {
+                               buf.WriteString("</code>")
+                       } else {
+                               buf.WriteString("<code>")
+                       }
+                       inQuote = !inQuote
+               } else {
+                       buf.WriteByte(c)
+               }
+       }
+       return buf.Bytes();
+}
+
+// drop trailing newline
+func trim(l []byte) []byte {
+       n := len(l);
+       if n > 0 && l[n-1] == '\n' {
+               return l[0:n-1]
+       }
+       return l
+}
+
+// expand tabs to 4 spaces. don't worry about columns.
+func expandTabs(l []byte) []byte {
+       j := 0; // position in linebuf.
+       for _, c := range l {
+               if c == '\t' {
+                       for k := 0; k < 4; k++ {
+                               linebuf[j] = ' ';
+                               j++;
+                       }
+               } else {
+                       linebuf[j] = c;
+                       j++;
+               }
+       }
+       return linebuf[0:j];
+}
diff --git a/doc/makehtml b/doc/makehtml
new file mode 100755 (executable)
index 0000000..c9ac0c8
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+set -e
+
+TXT=${1:-go_tutorial.txt}              # input file
+HTML=$(basename $TXT .txt).html                # output file (basename)
+TMP=TEMP.txt                           # input to htmlgen
+
+if ! test -w $HTML
+then
+       echo 1>&2 makehtml: cannot open $HTML for write
+       exit 1
+fi
+
+if grep -q '^--PROG' $TXT
+then
+       echo >&2 makehtml: processing PROG sections
+       <$TXT >$TMP awk '
+               /^--PROG/ { system("sh ./prog.sh "$2" "$3" "$4" "); getline }
+               /^/ {print}
+       '
+else
+       cp $TXT $TMP
+fi
+
+make htmlgen && ./htmlgen < $TMP > $HTML
+
+rm -f $TMP