提交 a88df6f6 编写于 作者: M Mislav Marohnić

Add HTML template for man pages

上级 cf02dd11
SOURCES = $(shell script/build files) SOURCES = $(shell script/build files)
TODAY_DATE = $(shell date '+%d %b %Y')
HUB_VERSION = $(shell hub version | tail -1)
MIN_COVERAGE = 89.4 MIN_COVERAGE = 89.4
...@@ -59,8 +61,11 @@ man-pages: $(HELP_ALL:=.md) $(HELP_ALL) $(HELP_ALL:=.txt) ...@@ -59,8 +61,11 @@ man-pages: $(HELP_ALL:=.md) $(HELP_ALL) $(HELP_ALL:=.txt)
groff -Wall -mtty-char -mandoc -Tutf8 -rLL=$(TEXT_WIDTH)n $< | col -b >$@ groff -Wall -mtty-char -mandoc -Tutf8 -rLL=$(TEXT_WIDTH)n $< | col -b >$@
$(HELP_ALL): share/man/.man-pages.stamp $(HELP_ALL): share/man/.man-pages.stamp
share/man/.man-pages.stamp: $(HELP_ALL:=.md) share/man/.man-pages.stamp: $(HELP_ALL:=.md) ./man-template.html
go run md2roff-bin/cmd.go --organization=GITHUB --manual="Hub Manual" share/man/man1/*.md go run md2roff-bin/cmd.go --manual="hub manual" \
--date="$(TODAY_DATE)" --version="$(HUB_VERSION)" \
--template=./man-template.html \
share/man/man1/*.md
touch $@ touch $@
%.1.md: bin/hub %.1.md: bin/hub
......
<!doctype html>
<title>{{.Name}}({{.Section}}) - {{.Title}}</title>
<meta charset="utf-8">
<style>
body {
margin: 0;
font: 15px/1.4 -apple-system,Segoe UI,Helvetica,Arial,sans-serif;
}
pre, code, var, dt, .man-head {
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
}
header, footer {
padding: .5em 2em;
}
.man-head {
color: #999;
padding: 0;
width: 100%;
float: left;
list-style-type: none;
}
header .man-head {
text-transform: uppercase;
}
.man-head li {
width: 33%;
float: left;
}
.tl { text-align: left }
.tc { text-align: center }
.tr { text-align: right; float: right }
article {
max-width: 110ex;
margin: 4em auto 2em;
}
h1 {
font-size: 1em;
font-weight: normal;
}
h2 {
text-transform: uppercase;
}
code {
color: darkslategray;
font-weight: bold;
}
var {
color: orangered;
font-weight: normal;
font-style: normal;
}
dt {
margin: .5em 0;
}
dd {
margin-bottom: 1em;
}
pre {
background: #eee;
padding: 1em 1.5em;
}
pre code {
color: inherit;
font-weight: inherit;
}
var::before { content: "<" }
var::after { content: ">" }
a:link, a:hover, a:visited { color: blue }
</style>
<header>
<ol class="man-head">
<li class="tl">{{.Name}}({{.Section}})</li>
<li class="tc">{{.Manual}}</li>
<li class="tr">{{.Name}}({{.Section}})</li>
</ol>
</header>
<article>
<h1>{{.Title}}</h1>
{{.Contents}}
</article>
<footer>
<ol class="man-head">
<li class="tl">{{.Version}}</li>
<li class="tc">{{.Date}}</li>
<li class="tr"></li>
</ol>
</footer>
package main package main
import ( import (
"bytes"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
"text/template"
"github.com/github/hub/md2roff" "github.com/github/hub/md2roff"
flag "github.com/ogier/pflag" flag "github.com/ogier/pflag"
...@@ -12,14 +15,30 @@ import ( ...@@ -12,14 +15,30 @@ import (
var ( var (
flagManual, flagManual,
flagVersion,
flagTemplate,
flagDate string flagDate string
pageIndex map[string]bool
) )
func init() { func init() {
flag.StringVarP(&flagManual, "manual", "m", "", "MANUAL") flag.StringVarP(&flagManual, "manual", "m", "", "MANUAL")
flag.StringVarP(&flagVersion, "version", "", "", "VERSION")
flag.StringVarP(&flagTemplate, "template", "t", "", "TEMPLATE")
flag.StringVarP(&flagDate, "date", "d", "", "DATE") flag.StringVarP(&flagDate, "date", "d", "", "DATE")
} }
type templateData struct {
Contents string
Manual string
Date string
Version string
Title string
Name string
Section uint8
}
func generateFromFile(mdFile string) error { func generateFromFile(mdFile string) error {
content, err := ioutil.ReadFile(mdFile) content, err := ioutil.ReadFile(mdFile)
if err != nil { if err != nil {
...@@ -48,11 +67,51 @@ func generateFromFile(mdFile string) error { ...@@ -48,11 +67,51 @@ func generateFromFile(mdFile string) error {
Date: flagDate, Date: flagDate,
} }
htmlGenBuf := &bytes.Buffer{}
var htmlWriteBuf io.Writer = htmlBuf
if flagTemplate != "" {
htmlWriteBuf = htmlGenBuf
}
md2roff.Generate(content, md2roff.Generate(content,
md2roff.Opt(roffBuf, roff), md2roff.Opt(roffBuf, roff),
md2roff.Opt(htmlBuf, html), md2roff.Opt(htmlWriteBuf, html),
) )
if flagTemplate != "" {
htmlGenBytes, err := ioutil.ReadAll(htmlGenBuf)
if err != nil {
return err
}
content := ""
if contentLines := strings.Split(string(htmlGenBytes), "\n"); len(contentLines) > 1 {
content = strings.Join(contentLines[1:], "\n")
}
tmplData := templateData{
Manual: roff.Manual,
Date: roff.Date,
Contents: content,
Title: roff.Title,
Section: roff.Section,
Name: roff.Name,
Version: flagVersion,
}
templateFile, err := ioutil.ReadFile(flagTemplate)
if err != nil {
return err
}
tmpl, err := template.New("test").Parse(string(templateFile))
if err != nil {
return err
}
err = tmpl.Execute(htmlBuf, tmplData)
if err != nil {
return err
}
}
return nil return nil
} }
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"regexp" "regexp"
"strconv"
"github.com/russross/blackfriday" "github.com/russross/blackfriday"
) )
...@@ -35,8 +36,11 @@ func escape(src []byte, re *regexp.Regexp) []byte { ...@@ -35,8 +36,11 @@ func escape(src []byte, re *regexp.Regexp) []byte {
} }
type RoffRenderer struct { type RoffRenderer struct {
Manual string Manual string
Date string Date string
Title string
Name string
Section uint8
listWasTerm bool listWasTerm bool
} }
...@@ -89,7 +93,7 @@ func (r *RoffRenderer) RenderNode(buf io.Writer, node *blackfriday.Node, enterin ...@@ -89,7 +93,7 @@ func (r *RoffRenderer) RenderNode(buf io.Writer, node *blackfriday.Node, enterin
} }
} }
case blackfriday.Heading: case blackfriday.Heading:
renderHeading(buf, node, r.Date, r.Manual) r.renderHeading(buf, node)
return blackfriday.SkipChildren return blackfriday.SkipChildren
} }
} }
...@@ -147,7 +151,7 @@ func textContent(node *blackfriday.Node) []byte { ...@@ -147,7 +151,7 @@ func textContent(node *blackfriday.Node) []byte {
return buf.Bytes() return buf.Bytes()
} }
func renderHeading(buf io.Writer, node *blackfriday.Node, date, version string) { func (r *RoffRenderer) renderHeading(buf io.Writer, node *blackfriday.Node) {
text := textContent(node) text := textContent(node)
switch node.HeadingData.Level { switch node.HeadingData.Level {
case 1: case 1:
...@@ -155,12 +159,17 @@ func renderHeading(buf io.Writer, node *blackfriday.Node, date, version string) ...@@ -155,12 +159,17 @@ func renderHeading(buf io.Writer, node *blackfriday.Node, date, version string)
var num []byte var num []byte
if match := titleRe.FindAllSubmatch(text, 1); match != nil { if match := titleRe.FindAllSubmatch(text, 1); match != nil {
name, num, text = match[0][1], match[0][2], match[0][3] name, num, text = match[0][1], match[0][2], match[0][3]
r.Name = string(name)
if sectionNum, err := strconv.Atoi(string(num)); err == nil {
r.Section = uint8(sectionNum)
}
r.Title = string(text)
} }
fmt.Fprintf(buf, ".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", fmt.Fprintf(buf, ".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
escape(name, headingEscape), escape(name, headingEscape),
num, num,
escape([]byte(date), headingEscape), escape([]byte(r.Date), headingEscape),
escape([]byte(version), headingEscape), escape([]byte(r.Manual), headingEscape),
escape(text, headingEscape), escape(text, headingEscape),
) )
io.WriteString(buf, ".nh\n") // disable hyphenation io.WriteString(buf, ".nh\n") // disable hyphenation
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册