diff --git a/style/book.css b/style/book.css index e06f120..2eca62e 100644 --- a/style/book.css +++ b/style/book.css @@ -1,9 +1,55 @@ +/* Reset */ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} body { - font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* Typography and Layout */ +body { + font-family: 'Book Antiqua'; font-size: 15px; line-height: 20px; color: #252519; - margin: 0; padding: 0; + margin: 0; + padding: 0; } a { color: #261a3b; @@ -12,119 +58,59 @@ a { color: #261a3b; } p { - margin: 0 0 15px 0; + margin: 0 0 20px 0; } h1, h2, h3, h4, h5, h6 { - margin: 0px 0 15px 0; + margin: 0px 0 20px 0; } - h1 { - margin-top: 40px; + h2 { + margin-top: 40px; + font-size: 40px; + line-height: 40px; } -hr { - border: 0 none; - border-top: 1px solid #e5e5ee; - height: 1px; - margin: 20px 0; -} #container { position: relative; } #background { position: fixed; - top: 0; left: 525px; right: 0; bottom: 0; + top: 0; left: 455px; right: 0; bottom: 0; background: #f5f5ff; border-left: 1px solid #e5e5ee; z-index: -1; } -#jump_to, #jump_page { - background: white; - -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; - -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - font: 10px Arial; - text-transform: uppercase; - cursor: pointer; - text-align: right; -} -#jump_to, #jump_wrapper { - position: fixed; - right: 0; top: 0; - padding: 5px 10px; -} - #jump_wrapper { - padding: 0; - display: none; - } - #jump_to:hover #jump_wrapper { - display: block; - } - #jump_page { - padding: 5px 0 3px; - margin: 0 0 25px 25px; - } - #jump_page .source { - display: block; - padding: 5px 10px; - text-decoration: none; - border-top: 1px solid #eee; - } - #jump_page .source:hover { - background: #f5f5ff; - } - #jump_page .source:first-child { - } table td { border: 0; outline: 0; } - td.docs, th.docs { + td.docs { max-width: 350px; min-width: 350px; - min-height: 5px; - padding: 10px 25px 1px 50px; - overflow-x: hidden; + min-height: 5px; /* ? */ + padding: 0px 30px 0px 60px; + overflow-x: hidden; /* ? */ vertical-align: top; text-align: left; } - .docs pre { - margin: 15px 0 15px; - padding-left: 15px; - } .docs p tt, .docs p code { background: #f8f8ff; border: 1px solid #dedede; - font-size: 12px; padding: 0 0.2em; } - .pilwrap { - position: relative; - } - .pilcrow { - font: 12px Arial; - text-decoration: none; - color: #454545; - position: absolute; - top: 3px; left: -20px; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; - } - td.docs:hover .pilcrow { - opacity: 1; - } - td.code, th.code { - padding: 14px 15px 16px 25px; + td.code { + padding: 0px 20px 0px 30px; width: 100%; vertical-align: top; background: #f5f5ff; border-left: 1px solid #e5e5ee; } pre, tt, code { - font-size: 12px; line-height: 18px; - font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + font-size: 14px; + line-height: 18px; + font-family: Menlo; 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 } diff --git a/style/golit.html b/style/golit.html new file mode 100644 index 0000000..272b587 --- /dev/null +++ b/style/golit.html @@ -0,0 +1,193 @@ + + + +
+ +Line Filters+ | ///
+
+ |
Generate literate-programming style HTML +documentation form Go source files. + | package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "regexp"
+ "strings"
+)
+
+ |
Recognize doc lines, extract their comment prefixes. + | var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s")
+
+ |
Abort on non-nil errors. + | func check(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+ |
For docs and code rendering: pipe source data +through binary at path with given argv, return +the output. + | func pipedCmd(path string, argv []string, source string) string {
+ cmd := exec.Command(path, argv...)
+ in, err := cmd.StdinPipe()
+ check(err)
+ out, err := cmd.StdoutPipe()
+ check(err)
+ err = cmd.Start()
+ check(err)
+ in.Write([]byte(source))
+ check(err)
+ err = in.Close()
+ check(err)
+ bytes, err := ioutil.ReadAll(out)
+ check(err)
+ err = cmd.Wait()
+ check(err)
+ return string(bytes)
+}
+
+ |
We'll break the code into {docs, code} pairs, +and then render those text segments before +including them in the HTML doc. + | type segment struct {
+ docs, code, docsRendered, codeRendered string
+}
+
+func main() {
+ |
Accept exactly 1 argument - the input filename. + | if len(os.Args) != 2 {
+ fmt.Fprintln(os.Stderr, "Usage: tool/generate input.go > output.html")
+ os.Exit(1)
+ }
+
+ |
Ensure that we have | markdownPath, err := exec.LookPath("markdown")
+ check(err)
+ pygmentizePath, err := exec.LookPath("pygmentize")
+ check(err)
+
+ |
Read the source file in, split into lines. + | sourceBytes, err := ioutil.ReadFile(os.Args[1])
+ check(err)
+ lines := strings.Split(string(sourceBytes), "\n")
+
+ |
Group lines into docs/code segments. + | segments := []*segment{}
+ segments = append(segments, &segment{code: "", docs: ""})
+ lastLine := ""
+ for _, line := range lines {
+ head := segments[len(segments)-1]
+ |
Doc line - trim off the comment markers. + | if (line == "" && lastLine == "docs") || docsPat.MatchString(line) {
+ trimLine := docsPat.ReplaceAllString(line, "")
+ if !(lastLine == "code" && head.docs != "") {
+ head.docs = head.docs + "\n" + trimLine
+ } else {
+ segments = append(segments, &segment{docs: trimLine, code: ""})
+ }
+ lastLine = "docs"
+ |
Code line - preserve all whitespace. + | } else {
+ if !(lastLine == "docs" && head.code != "") {
+ head.code = head.code + "\n" + line
+ } else {
+ segments = append(segments, &segment{docs: "", code: line})
+ }
+ lastLine = "code"
+ }
+ }
+
+ |
Render docs via | for _, seg := range segments {
+ seg.docsRendered = pipedCmd(markdownPath, []string{}, seg.docs)
+ seg.codeRendered = pipedCmd(pygmentizePath, []string{"-l", "go", "-f", "html"}, seg.code + " ")
+ }
+
+ |
Print HTML header. + | fmt.Print(`
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-eqiv="content-type" content="text/html;charset=utf-8">
+ <title>Page Title</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>`)
+
+ |
Print HTML docs/code segments. + | for _, seg := range segments {
+ fmt.Printf("<tr><td class=docs>%s</td><td class=code>%s</td></tr>\n", seg.docsRendered, seg.codeRendered)
+ }
+
+ |
Print HTML footer. + | fmt.Print(`
+ </tbody>
+ </table>
+ </div>
+ </body>
+</html>
+`)
+}
+
+ |