re-introduce basic generator
This commit is contained in:
parent
b15ef38abd
commit
2c1e578ac3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
build
|
build
|
||||||
|
tool/generate
|
||||||
|
121
style/book.css
121
style/book.css
@ -1 +1,122 @@
|
|||||||
|
/* PDF Formatting */
|
||||||
@page { margin: 10pt 0pt 10pt 0pt }
|
@page { margin: 10pt 0pt 10pt 0pt }
|
||||||
|
|
||||||
|
/*--------------------- Layout and Typography ----------------------------*/
|
||||||
|
body {
|
||||||
|
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #252519;
|
||||||
|
margin: 0; padding: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #261a3b;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #261a3b;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin: 0px 0 15px 0;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 0 none;
|
||||||
|
border-top: 1px solid #e5e5ee;
|
||||||
|
height: 1px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
#container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
td.docs {
|
||||||
|
max-width: 400px;
|
||||||
|
min-width: 400px;
|
||||||
|
min-height: 5px;
|
||||||
|
padding: 10px 15px 1px 30px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
td.code {
|
||||||
|
padding: 14px 30px 16px 15px;
|
||||||
|
width: 100%;
|
||||||
|
vertical-align: top;
|
||||||
|
border-left: 1px solid #e5e5ee;
|
||||||
|
}
|
||||||
|
pre, code {
|
||||||
|
font-size: 11px; line-height: 16px;
|
||||||
|
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
|
||||||
|
margin: 0; padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------- Syntax Highlighting -----------------------------*/
|
||||||
|
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
||||||
|
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
||||||
|
body .hll { background-color: #ffffcc }
|
||||||
|
body .err { border: 1px solid #FF0000 } /* Error */
|
||||||
|
body .c { color: #408080; font-style: italic } /* Comment */
|
||||||
|
body .k { color: #954121 } /* Keyword */
|
||||||
|
body .o { color: #666666 } /* Operator */
|
||||||
|
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||||
|
body .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||||
|
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||||
|
body .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||||
|
body .gd { color: #A00000 } /* Generic.Deleted */
|
||||||
|
body .ge { font-style: italic } /* Generic.Emph */
|
||||||
|
body .gr { color: #FF0000 } /* Generic.Error */
|
||||||
|
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||||
|
body .gi { color: #00A000 } /* Generic.Inserted */
|
||||||
|
body .go { color: #808080 } /* Generic.Output */
|
||||||
|
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||||
|
body .gs { font-weight: bold } /* Generic.Strong */
|
||||||
|
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||||
|
body .gt { color: #0040D0 } /* Generic.Traceback */
|
||||||
|
body .kc { color: #954121 } /* Keyword.Constant */
|
||||||
|
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
|
||||||
|
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
|
||||||
|
body .kp { color: #954121 } /* Keyword.Pseudo */
|
||||||
|
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
|
||||||
|
body .kt { color: #B00040 } /* Keyword.Type */
|
||||||
|
body .m { color: #666666 } /* Literal.Number */
|
||||||
|
body .s { color: #219161 } /* Literal.String */
|
||||||
|
body .na { color: #7D9029 } /* Name.Attribute */
|
||||||
|
body .nb { color: #954121 } /* Name.Builtin */
|
||||||
|
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||||
|
body .no { color: #880000 } /* Name.Constant */
|
||||||
|
body .nd { color: #AA22FF } /* Name.Decorator */
|
||||||
|
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||||
|
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||||
|
body .nf { color: #0000FF } /* Name.Function */
|
||||||
|
body .nl { color: #A0A000 } /* Name.Label */
|
||||||
|
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||||
|
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
|
||||||
|
body .nv { color: #19469D } /* Name.Variable */
|
||||||
|
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||||
|
body .w { color: #bbbbbb } /* Text.Whitespace */
|
||||||
|
body .mf { color: #666666 } /* Literal.Number.Float */
|
||||||
|
body .mh { color: #666666 } /* Literal.Number.Hex */
|
||||||
|
body .mi { color: #666666 } /* Literal.Number.Integer */
|
||||||
|
body .mo { color: #666666 } /* Literal.Number.Oct */
|
||||||
|
body .sb { color: #219161 } /* Literal.String.Backtick */
|
||||||
|
body .sc { color: #219161 } /* Literal.String.Char */
|
||||||
|
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
|
||||||
|
body .s2 { color: #219161 } /* Literal.String.Double */
|
||||||
|
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||||
|
body .sh { color: #219161 } /* Literal.String.Heredoc */
|
||||||
|
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||||
|
body .sx { color: #954121 } /* Literal.String.Other */
|
||||||
|
body .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||||
|
body .s1 { color: #219161 } /* Literal.String.Single */
|
||||||
|
body .ss { color: #19469D } /* Literal.String.Symbol */
|
||||||
|
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
|
||||||
|
body .vc { color: #19469D } /* Name.Variable.Class */
|
||||||
|
body .vg { color: #19469D } /* Name.Variable.Global */
|
||||||
|
body .vi { color: #19469D } /* Name.Variable.Instance */
|
||||||
|
body .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||||
|
136
style/lit.css
136
style/lit.css
@ -1,136 +0,0 @@
|
|||||||
/*--------------------- Layout and Typography ----------------------------*/
|
|
||||||
body {
|
|
||||||
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
color: #252519;
|
|
||||||
margin: 0; padding: 0;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #261a3b;
|
|
||||||
}
|
|
||||||
a:visited {
|
|
||||||
color: #261a3b;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 0 0 15px 0;
|
|
||||||
}
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
margin: 0px 0 15px 0;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
hr {
|
|
||||||
border: 0 none;
|
|
||||||
border-top: 1px solid #e5e5ee;
|
|
||||||
height: 1px;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
#container {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
#background {
|
|
||||||
position: fixed;
|
|
||||||
top: 0; left: 400px; right: 0; bottom: 0;
|
|
||||||
/* background: #f5f5ff; */
|
|
||||||
border-left: 1px solid #e5e5ee;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
table td {
|
|
||||||
border: 0;
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
td.docs, th.docs {
|
|
||||||
max-width: 400px;
|
|
||||||
min-width: 400px;
|
|
||||||
min-height: 5px;
|
|
||||||
padding: 10px 15px 1px 30px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
vertical-align: top;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.docs p tt, .docs p code {
|
|
||||||
background: #f8f8ff;
|
|
||||||
border: 1px solid #dedede;
|
|
||||||
font-size: 11px;
|
|
||||||
padding: 0 0.2em;
|
|
||||||
}
|
|
||||||
td.code, th.code {
|
|
||||||
padding: 14px 30px 16px 15px;
|
|
||||||
width: 100%;
|
|
||||||
vertical-align: top;
|
|
||||||
/* background: #f5f5ff; */
|
|
||||||
border-left: 1px solid #e5e5ee;
|
|
||||||
}
|
|
||||||
pre, tt, code {
|
|
||||||
font-size: 11px; line-height: 16px;
|
|
||||||
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
|
|
||||||
margin: 0; padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------- Syntax Highlighting -----------------------------*/
|
|
||||||
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
|
||||||
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
|
||||||
body .hll { background-color: #ffffcc }
|
|
||||||
body .err { border: 1px solid #FF0000 } /* Error */
|
|
||||||
body .c { color: #408080; font-style: italic } /* Comment */
|
|
||||||
body .k { color: #954121 } /* Keyword */
|
|
||||||
body .o { color: #666666 } /* Operator */
|
|
||||||
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
|
||||||
body .cp { color: #BC7A00 } /* Comment.Preproc */
|
|
||||||
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
|
||||||
body .cs { color: #408080; font-style: italic } /* Comment.Special */
|
|
||||||
body .gd { color: #A00000 } /* Generic.Deleted */
|
|
||||||
body .ge { font-style: italic } /* Generic.Emph */
|
|
||||||
body .gr { color: #FF0000 } /* Generic.Error */
|
|
||||||
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
|
||||||
body .gi { color: #00A000 } /* Generic.Inserted */
|
|
||||||
body .go { color: #808080 } /* Generic.Output */
|
|
||||||
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
|
||||||
body .gs { font-weight: bold } /* Generic.Strong */
|
|
||||||
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
|
||||||
body .gt { color: #0040D0 } /* Generic.Traceback */
|
|
||||||
body .kc { color: #954121 } /* Keyword.Constant */
|
|
||||||
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
|
|
||||||
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
|
|
||||||
body .kp { color: #954121 } /* Keyword.Pseudo */
|
|
||||||
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
|
|
||||||
body .kt { color: #B00040 } /* Keyword.Type */
|
|
||||||
body .m { color: #666666 } /* Literal.Number */
|
|
||||||
body .s { color: #219161 } /* Literal.String */
|
|
||||||
body .na { color: #7D9029 } /* Name.Attribute */
|
|
||||||
body .nb { color: #954121 } /* Name.Builtin */
|
|
||||||
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
|
||||||
body .no { color: #880000 } /* Name.Constant */
|
|
||||||
body .nd { color: #AA22FF } /* Name.Decorator */
|
|
||||||
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
|
||||||
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
|
||||||
body .nf { color: #0000FF } /* Name.Function */
|
|
||||||
body .nl { color: #A0A000 } /* Name.Label */
|
|
||||||
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
|
||||||
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
|
|
||||||
body .nv { color: #19469D } /* Name.Variable */
|
|
||||||
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
|
||||||
body .w { color: #bbbbbb } /* Text.Whitespace */
|
|
||||||
body .mf { color: #666666 } /* Literal.Number.Float */
|
|
||||||
body .mh { color: #666666 } /* Literal.Number.Hex */
|
|
||||||
body .mi { color: #666666 } /* Literal.Number.Integer */
|
|
||||||
body .mo { color: #666666 } /* Literal.Number.Oct */
|
|
||||||
body .sb { color: #219161 } /* Literal.String.Backtick */
|
|
||||||
body .sc { color: #219161 } /* Literal.String.Char */
|
|
||||||
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
|
|
||||||
body .s2 { color: #219161 } /* Literal.String.Double */
|
|
||||||
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
|
||||||
body .sh { color: #219161 } /* Literal.String.Heredoc */
|
|
||||||
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
|
||||||
body .sx { color: #954121 } /* Literal.String.Other */
|
|
||||||
body .sr { color: #BB6688 } /* Literal.String.Regex */
|
|
||||||
body .s1 { color: #219161 } /* Literal.String.Single */
|
|
||||||
body .ss { color: #19469D } /* Literal.String.Symbol */
|
|
||||||
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
|
|
||||||
body .vc { color: #19469D } /* Name.Variable.Class */
|
|
||||||
body .vg { color: #19469D } /* Name.Variable.Global */
|
|
||||||
body .vi { color: #19469D } /* Name.Variable.Instance */
|
|
||||||
body .il { color: #666666 } /* Literal.Number.Integer.Long */
|
|
137
tool/generate.go
Normal file
137
tool/generate.go
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// Generate an HTML file from the book source. Derived from golit.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pipe(bin string, arg []string, src string) string {
|
||||||
|
cmd := exec.Command(bin, arg...)
|
||||||
|
in, _ := cmd.StdinPipe()
|
||||||
|
out, _ := cmd.StdoutPipe()
|
||||||
|
cmd.Start()
|
||||||
|
in.Write([]byte(src))
|
||||||
|
in.Close()
|
||||||
|
bytes, _ := ioutil.ReadAll(out)
|
||||||
|
err := cmd.Wait()
|
||||||
|
check(err)
|
||||||
|
return string(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s")
|
||||||
|
|
||||||
|
var headerPat = regexp.MustCompile("^\\s*\\/\\/\\s#+\\s")
|
||||||
|
|
||||||
|
type seg struct {
|
||||||
|
docs, code, docsRendered, codeRendered string
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) != 3 {
|
||||||
|
fmt.Fprintln(os.Stderr, "usage: tool/generate input.go title > output.html")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
sourcePath := os.Args[1]
|
||||||
|
title := os.Args[2]
|
||||||
|
|
||||||
|
markdownPath, err := exec.LookPath("markdown")
|
||||||
|
check(err)
|
||||||
|
pygmentizePath, err := exec.LookPath("pygmentize")
|
||||||
|
check(err)
|
||||||
|
|
||||||
|
srcBytes, err := ioutil.ReadFile(sourcePath)
|
||||||
|
check(err)
|
||||||
|
lines := strings.Split(string(srcBytes), "\n")
|
||||||
|
|
||||||
|
segs := []*seg{}
|
||||||
|
segs = append(segs, &seg{code: "", docs: ""})
|
||||||
|
lastSeen := ""
|
||||||
|
for _, line := range lines {
|
||||||
|
headerMatch := headerPat.MatchString(line)
|
||||||
|
docsMatch := docsPat.MatchString(line)
|
||||||
|
emptyMatch := line == ""
|
||||||
|
lastSeg := segs[len(segs)-1]
|
||||||
|
lastHeader := lastSeen == "header"
|
||||||
|
lastDocs := lastSeen == "docs"
|
||||||
|
newHeader := (lastSeen != "header")
|
||||||
|
newDocs := (lastSeen != "docs") && lastSeg.docs != ""
|
||||||
|
newCode := (lastSeen != "code") && lastSeg.code != ""
|
||||||
|
if headerMatch || (emptyMatch && lastHeader) {
|
||||||
|
trimmed := docsPat.ReplaceAllString(line, "")
|
||||||
|
if newHeader {
|
||||||
|
newSeg := seg{docs: trimmed, code: ""}
|
||||||
|
segs = append(segs, &newSeg)
|
||||||
|
} else {
|
||||||
|
lastSeg.docs = lastSeg.docs + "\n" + trimmed
|
||||||
|
}
|
||||||
|
} else if docsMatch || (emptyMatch && lastDocs) {
|
||||||
|
trimmed := docsPat.ReplaceAllString(line, "")
|
||||||
|
if newDocs {
|
||||||
|
newSeg := seg{docs: trimmed, code: ""}
|
||||||
|
segs = append(segs, &newSeg)
|
||||||
|
} else {
|
||||||
|
lastSeg.docs = lastSeg.docs + "\n" + trimmed
|
||||||
|
}
|
||||||
|
lastSeen = "docs"
|
||||||
|
} else {
|
||||||
|
if newCode {
|
||||||
|
newSeg := seg{docs: "", code: line}
|
||||||
|
segs = append(segs, &newSeg)
|
||||||
|
} else {
|
||||||
|
lastSeg.code = lastSeg.code + "\n" + line
|
||||||
|
}
|
||||||
|
lastSeen = "code"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, seg := range segs {
|
||||||
|
seg.docsRendered = pipe(markdownPath, []string{}, seg.docs)
|
||||||
|
seg.codeRendered = pipe(pygmentizePath, []string{"-l", "go", "-f", "html"}, seg.code+" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf(`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
|
||||||
|
<title>%s</title>
|
||||||
|
<link rel=stylesheet href="../style/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>`, title)
|
||||||
|
|
||||||
|
for _, seg := range segs {
|
||||||
|
fmt.Printf(
|
||||||
|
`<tr>
|
||||||
|
<td class=docs>%s</td>
|
||||||
|
<td class=code>%s</td>
|
||||||
|
</tr>`, seg.docsRendered, seg.codeRendered)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print(`</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user