first pass at templates
This commit is contained in:
parent
f15c0f6d54
commit
3436d87b1f
@ -11,7 +11,7 @@ This repo contains:
|
|||||||
* `src`: Go and Bash source code for the site
|
* `src`: Go and Bash source code for the site
|
||||||
* `meta`: metadata used to generate the site
|
* `meta`: metadata used to generate the site
|
||||||
* `tool`: toolchain used to generate the site
|
* `tool`: toolchain used to generate the site
|
||||||
* `style`: CSS for the site
|
* `template`: HTML templates and CSS for the site
|
||||||
|
|
||||||
The site is built by extracting the code & comments from
|
The site is built by extracting the code & comments from
|
||||||
the `.go` and `.sh` source files in `src` and rendering
|
the `.go` and `.sh` source files in `src` and rendering
|
||||||
|
22
template/chapter.tmpl
Normal file
22
template/chapter.tmpl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
|
||||||
|
<title>Go by Example: {{.Name}}</title>
|
||||||
|
<link rel=stylesheet href="../template/site.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="chapter" id="{{.Id}}">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
{{range .Segs}}
|
||||||
|
<tr>
|
||||||
|
<td class=docs>{{.DocsRendered}}</td>
|
||||||
|
<td class="{{.CodeClasses}}">{{.CodeRendered}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
18
template/index.tmpl
Normal file
18
template/index.tmpl
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
|
||||||
|
<title>Go by Example</title>
|
||||||
|
<link rel=stylesheet href="../template/site.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="intro">
|
||||||
|
<h2>Go by Example</h2>
|
||||||
|
<ul>
|
||||||
|
{{range .}}
|
||||||
|
<li><a href="{{.Id}}.html">{{.Name}}</a></li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -11,6 +11,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cacheDir = "/tmp/gobyexample-cache"
|
var cacheDir = "/tmp/gobyexample-cache"
|
||||||
@ -103,18 +104,19 @@ var docsPat = regexp.MustCompile("^\\s*(\\/\\/|#)\\s")
|
|||||||
var todoPat = regexp.MustCompile("\\/\\/ todo: ")
|
var todoPat = regexp.MustCompile("\\/\\/ todo: ")
|
||||||
|
|
||||||
type Seg struct {
|
type Seg struct {
|
||||||
docs, code, docsRendered, codeRendered string
|
Docs, DocsRendered string
|
||||||
|
Code, CodeRendered, CodeClasses string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Chapter struct {
|
type Chapter struct {
|
||||||
id, name string
|
Id, Name string
|
||||||
segs []*Seg
|
Segs []*Seg
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSegs(sourcePath string) []*Seg {
|
func parseSegs(sourcePath string) []*Seg {
|
||||||
lines := readLines(sourcePath)
|
lines := readLines(sourcePath)
|
||||||
segs := []*Seg{}
|
segs := []*Seg{}
|
||||||
segs = append(segs, &Seg{code: "", docs: ""})
|
segs = append(segs, &Seg{Code: "", Docs: ""})
|
||||||
lastSeen := ""
|
lastSeen := ""
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if line == "" {
|
if line == "" {
|
||||||
@ -127,44 +129,44 @@ func parseSegs(sourcePath string) []*Seg {
|
|||||||
matchDocs := docsPat.MatchString(line)
|
matchDocs := docsPat.MatchString(line)
|
||||||
matchCode := !matchDocs
|
matchCode := !matchDocs
|
||||||
lastSeg := segs[len(segs)-1]
|
lastSeg := segs[len(segs)-1]
|
||||||
newDocs := (lastSeen == "") || ((lastSeen != "docs") && (lastSeg.docs != ""))
|
newDocs := (lastSeen == "") || ((lastSeen != "docs") && (lastSeg.Docs != ""))
|
||||||
newCode := (lastSeen == "") || ((lastSeen != "code") && (lastSeg.code != ""))
|
newCode := (lastSeen == "") || ((lastSeen != "code") && (lastSeg.Code != ""))
|
||||||
if newDocs || newCode {
|
if newDocs || newCode {
|
||||||
debug("NEWSEG")
|
debug("NEWSEG")
|
||||||
}
|
}
|
||||||
if matchDocs {
|
if matchDocs {
|
||||||
trimmed := docsPat.ReplaceAllString(line, "")
|
trimmed := docsPat.ReplaceAllString(line, "")
|
||||||
if newDocs {
|
if newDocs {
|
||||||
newSeg := Seg{docs: trimmed, code: ""}
|
newSeg := Seg{Docs: trimmed, Code: ""}
|
||||||
segs = append(segs, &newSeg)
|
segs = append(segs, &newSeg)
|
||||||
} else {
|
} else {
|
||||||
lastSeg.docs = lastSeg.docs + "\n" + trimmed
|
lastSeg.Docs = lastSeg.Docs + "\n" + trimmed
|
||||||
}
|
}
|
||||||
debug("DOCS: " + line)
|
debug("DOCS: " + line)
|
||||||
lastSeen = "docs"
|
lastSeen = "docs"
|
||||||
} else if matchCode {
|
} else if matchCode {
|
||||||
if newCode {
|
if newCode {
|
||||||
newSeg := Seg{docs: "", code: line}
|
newSeg := Seg{Docs: "", Code: line}
|
||||||
segs = append(segs, &newSeg)
|
segs = append(segs, &newSeg)
|
||||||
} else {
|
} else {
|
||||||
lastSeg.code = lastSeg.code + "\n" + line
|
lastSeg.Code = lastSeg.Code + "\n" + line
|
||||||
}
|
}
|
||||||
debug("CODE: " + line)
|
debug("CODE: " + line)
|
||||||
lastSeen = "code"
|
lastSeen = "code"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return append(segs, &Seg{code: "", docs: ""})
|
return append(segs, &Seg{Code: "", Docs: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAndRenderSegs(sourcePath string) []*Seg {
|
func parseAndRenderSegs(sourcePath string) []*Seg {
|
||||||
segs := parseSegs(sourcePath)
|
segs := parseSegs(sourcePath)
|
||||||
lexer := whichLexer(sourcePath)
|
lexer := whichLexer(sourcePath)
|
||||||
for _, seg := range segs {
|
for _, seg := range segs {
|
||||||
if seg.docs != "" {
|
if seg.Docs != "" {
|
||||||
seg.docsRendered = markdown(seg.docs)
|
seg.DocsRendered = markdown(seg.Docs)
|
||||||
}
|
}
|
||||||
if seg.code != "" {
|
if seg.Code != "" {
|
||||||
seg.codeRendered = cachedPygmentize(lexer, seg.code)
|
seg.CodeRendered = cachedPygmentize(lexer, seg.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return segs
|
return segs
|
||||||
@ -175,9 +177,9 @@ func parseChapters() []*Chapter {
|
|||||||
chapters := make([]*Chapter, 0)
|
chapters := make([]*Chapter, 0)
|
||||||
for _, chapterId := range chapterLines {
|
for _, chapterId := range chapterLines {
|
||||||
if (chapterId != "") && !strings.HasPrefix(chapterId, "#") {
|
if (chapterId != "") && !strings.HasPrefix(chapterId, "#") {
|
||||||
chapter := Chapter{id: chapterId}
|
chapter := Chapter{Id: chapterId}
|
||||||
chapterLines := readLines("src/" + chapterId + "/" + chapterId + ".go")
|
chapterLines := readLines("src/" + chapterId + "/" + chapterId + ".go")
|
||||||
chapter.name = chapterLines[0][6:]
|
chapter.Name = chapterLines[0][6:]
|
||||||
chapterPath := "src/" + chapterId
|
chapterPath := "src/" + chapterId
|
||||||
sourcePaths := mustGlob(chapterPath + "/*")
|
sourcePaths := mustGlob(chapterPath + "/*")
|
||||||
segs := []*Seg{}
|
segs := []*Seg{}
|
||||||
@ -185,7 +187,7 @@ func parseChapters() []*Chapter {
|
|||||||
sourceSegs := parseAndRenderSegs(sourcePath)
|
sourceSegs := parseAndRenderSegs(sourcePath)
|
||||||
segs = append(segs, sourceSegs...)
|
segs = append(segs, sourceSegs...)
|
||||||
}
|
}
|
||||||
chapter.segs = segs
|
chapter.Segs = segs
|
||||||
chapters = append(chapters, &chapter)
|
chapters = append(chapters, &chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,56 +195,28 @@ func parseChapters() []*Chapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderIndex(chapters []*Chapter) {
|
func renderIndex(chapters []*Chapter) {
|
||||||
|
indexTmpl := template.New("index")
|
||||||
|
_, err := indexTmpl.Parse(mustReadFile("template/index.tmpl"))
|
||||||
|
check(err)
|
||||||
indexF, err := os.Create(siteDir + "/index.html")
|
indexF, err := os.Create(siteDir + "/index.html")
|
||||||
check(err)
|
check(err)
|
||||||
fmt.Fprint(indexF,
|
indexTmpl.Execute(indexF, chapters)
|
||||||
`<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
|
|
||||||
<title>Go by Example</title>
|
|
||||||
<link rel=stylesheet href="../style/site.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="intro">
|
|
||||||
<h2>Go by Example</h2>
|
|
||||||
<ul>`)
|
|
||||||
|
|
||||||
for _, chapter := range chapters {
|
|
||||||
fmt.Fprintf(indexF, `<li><a href="%s.html">%s</a></li>`, chapter.id, chapter.name)
|
|
||||||
}
|
|
||||||
fmt.Fprint(indexF, `</ul></div></body></html>`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderChapters(chapters []*Chapter) {
|
func renderChapters(chapters []*Chapter) {
|
||||||
for _, chapter := range chapters {
|
chapterTmpl := template.New("chapter")
|
||||||
chapterF, err := os.Create(siteDir + "/" + chapter.id + ".html")
|
_, err := chapterTmpl.Parse(mustReadFile("template/chapter.tmpl"))
|
||||||
check(err)
|
check(err)
|
||||||
fmt.Fprintf(chapterF,
|
for _, chapter := range chapters {
|
||||||
`<!DOCTYPE html>
|
for _, seg := range chapter.Segs {
|
||||||
<html>
|
seg.CodeClasses = "code"
|
||||||
<head>
|
if seg.Code == "" {
|
||||||
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
|
seg.CodeClasses = seg.CodeClasses + " empty"
|
||||||
<title>Go by Example: %s</title>
|
|
||||||
<link rel=stylesheet href="../style/site.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="chapter" id="%s">
|
|
||||||
<table cellspacing="0" cellpadding="0"><tbody>`,
|
|
||||||
chapter.name, chapter.id)
|
|
||||||
for _, seg := range chapter.segs {
|
|
||||||
codeClasses := "code"
|
|
||||||
if seg.code == "" {
|
|
||||||
codeClasses = codeClasses + " empty"
|
|
||||||
}
|
}
|
||||||
fmt.Fprintf(chapterF,
|
|
||||||
`<tr>
|
|
||||||
<td class=docs>%s</td>
|
|
||||||
<td class="%s">%s</td>
|
|
||||||
</tr>`,
|
|
||||||
seg.docsRendered, codeClasses, seg.codeRendered)
|
|
||||||
}
|
}
|
||||||
fmt.Fprint(chapterF, `</tbody></table></div></body></html>`)
|
chapterF, err := os.Create(siteDir + "/" + chapter.Id + ".html")
|
||||||
|
check(err)
|
||||||
|
chapterTmpl.Execute(chapterF, chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user