forked from tslocum/godoc-static
Write documentation to docs.zip
This commit is contained in:
parent
7f2dab8f89
commit
d35eebc599
|
@ -1,4 +1,5 @@
|
|||
0.1.6:
|
||||
- Write documentation to docs.zip
|
||||
- Create temporary directory when missing
|
||||
|
||||
0.1.5:
|
||||
|
|
22
README.md
22
README.md
|
@ -38,22 +38,10 @@ Packages are not downloaded/updated automatically.
|
|||
|
||||
### Usage examples
|
||||
|
||||
Generate documentation for `archive`, `net/http` and `gitlab.com/tslocum/cview` targeting `https://docs.rocketnine.space`:
|
||||
Generate documentation for `archive`, `net/http` and `gitlab.com/tslocum/cview`:
|
||||
|
||||
```bash
|
||||
godoc-static \
|
||||
-base-path=/ \
|
||||
-site-name="Rocket Nine Labs Documentation" \
|
||||
-site-description="Welcome!" \
|
||||
-destination=/home/user/sites/docs \
|
||||
archive net/http gitlab.com/tslocum/cview
|
||||
```
|
||||
|
||||
Targeting `https://rocketnine.space/docs/`:
|
||||
|
||||
```bash
|
||||
godoc-static \
|
||||
-base-path=/docs/ \
|
||||
-site-name="Rocket Nine Labs Documentation" \
|
||||
-site-description-file=/home/user/sitefiles/description.md \
|
||||
-destination=/home/user/sites/docs \
|
||||
|
@ -62,9 +50,6 @@ godoc-static \
|
|||
|
||||
### Options
|
||||
|
||||
#### -base-path
|
||||
Site relative URL path with trailing slash.
|
||||
|
||||
#### -destination
|
||||
Path to write site to.
|
||||
|
||||
|
@ -95,6 +80,9 @@ Site name.
|
|||
#### -verbose
|
||||
Enable verbose logging.
|
||||
|
||||
#### -zip
|
||||
Site ZIP file name.
|
||||
|
||||
## Support
|
||||
|
||||
Please share issues/suggestions [here](https://gitlab.com/tslocum/godoc-static/issues).
|
||||
Please share issues and suggestions [here](https://gitlab.com/tslocum/godoc-static/issues).
|
||||
|
|
76
main.go
76
main.go
|
@ -2,6 +2,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
|
@ -27,18 +28,19 @@ import (
|
|||
|
||||
var (
|
||||
listenAddress string
|
||||
basePath string
|
||||
siteName string
|
||||
siteDescription string
|
||||
siteDescriptionFile string
|
||||
siteFooter string
|
||||
siteFooterFile string
|
||||
siteDestination string
|
||||
siteZip string
|
||||
linkIndex bool
|
||||
excludePackages string
|
||||
verbose bool
|
||||
|
||||
godoc *exec.Cmd
|
||||
godoc *exec.Cmd
|
||||
outZip *zip.Writer
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -46,13 +48,13 @@ func main() {
|
|||
log.SetFlags(0)
|
||||
|
||||
flag.StringVar(&listenAddress, "listen-address", "localhost:9001", "address for godoc to listen on while scraping pages")
|
||||
flag.StringVar(&basePath, "base-path", "/", "site relative URL path with trailing slash")
|
||||
flag.StringVar(&siteName, "site-name", "Documentation", "site name")
|
||||
flag.StringVar(&siteDescription, "site-description", "", "site description (markdown-enabled)")
|
||||
flag.StringVar(&siteDescriptionFile, "site-description-file", "", "path to markdown file containing site description")
|
||||
flag.StringVar(&siteFooter, "site-footer", "", "site footer (markdown-enabled)")
|
||||
flag.StringVar(&siteFooterFile, "site-footer-file", "", "path to markdown file containing site footer")
|
||||
flag.StringVar(&siteDestination, "destination", "", "path to write site to")
|
||||
flag.StringVar(&siteDestination, "destination", "", "path to write site HTML")
|
||||
flag.StringVar(&siteZip, "zip", "docs.zip", "name of site ZIP file (blank to disable)")
|
||||
flag.BoolVar(&linkIndex, "link-index", false, "set link targets to index.html instead of folder")
|
||||
flag.StringVar(&excludePackages, "exclude", "", "list of packages to exclude from index")
|
||||
flag.BoolVar(&verbose, "verbose", false, "enable verbose logging")
|
||||
|
@ -78,6 +80,28 @@ func getTmpDir() string {
|
|||
return tmpDir
|
||||
}
|
||||
|
||||
func writeFile(buf *bytes.Buffer, fileDir string, fileName string) error {
|
||||
if outZip != nil {
|
||||
fn := fileDir
|
||||
if fn != "" {
|
||||
fn += "/"
|
||||
}
|
||||
fn += fileName
|
||||
|
||||
outZipFile, err := outZip.Create(fn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create zip file %s: %s", fn, err)
|
||||
}
|
||||
|
||||
_, err = outZipFile.Write(buf.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write zip file %s: %s", fn, err)
|
||||
}
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(path.Join(siteDestination, fileDir, fileName), buf.Bytes(), 0755)
|
||||
}
|
||||
|
||||
func run() error {
|
||||
var buf bytes.Buffer
|
||||
timeStarted := time.Now()
|
||||
|
@ -138,10 +162,15 @@ func run() error {
|
|||
siteFooter = buf.String()
|
||||
}
|
||||
|
||||
if siteFooter != "" {
|
||||
siteFooter += "<p>" + footerText + "</p>"
|
||||
} else {
|
||||
siteFooter = footerText
|
||||
if siteZip != "" {
|
||||
outZipFile, err := os.Create(filepath.Join(siteDestination, siteZip))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create zip file %s: %s", filepath.Join(siteDestination, siteZip), err)
|
||||
}
|
||||
defer outZipFile.Close()
|
||||
|
||||
outZip = zip.NewWriter(outZipFile)
|
||||
defer outZip.Close()
|
||||
}
|
||||
|
||||
if verbose {
|
||||
|
@ -285,7 +314,7 @@ func run() error {
|
|||
|
||||
doc.Find("title").First().SetHtml(fmt.Sprintf("%s - %s", path.Base(pkg), siteName))
|
||||
|
||||
updatePage(doc, basePath, siteName)
|
||||
updatePage(doc, relativeBasePath(pkg), siteName)
|
||||
|
||||
localPkgPath := path.Join(siteDestination, pkg)
|
||||
|
||||
|
@ -301,7 +330,7 @@ func run() error {
|
|||
done <- fmt.Errorf("failed to render HTML: %s", err)
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile(path.Join(localPkgPath, "index.html"), buf.Bytes(), 0755)
|
||||
err = writeFile(&buf, pkg, "index.html")
|
||||
if err != nil {
|
||||
done <- fmt.Errorf("failed to write docs for %s: %s", pkg, err)
|
||||
return
|
||||
|
@ -378,7 +407,7 @@ func run() error {
|
|||
|
||||
doc.Find("title").First().SetHtml(fmt.Sprintf("%s - %s", path.Base(pkg), siteName))
|
||||
|
||||
updatePage(doc, basePath, siteName)
|
||||
updatePage(doc, relativeBasePath("src/"+pkg), siteName)
|
||||
|
||||
doc.Find(".layout").First().Find("a").Each(func(_ int, selection *goquery.Selection) {
|
||||
href := selection.AttrOr("href", "")
|
||||
|
@ -404,7 +433,7 @@ func run() error {
|
|||
if !strings.HasSuffix(outFileName, ".html") {
|
||||
outFileName += ".html"
|
||||
}
|
||||
err = ioutil.WriteFile(path.Join(pkgSrcPath, outFileName), buf.Bytes(), 0755)
|
||||
err = writeFile(&buf, "src/"+pkg, outFileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write docs for %s: %s", pkg, err)
|
||||
}
|
||||
|
@ -427,17 +456,19 @@ func run() error {
|
|||
return fmt.Errorf("failed to get syle.css: %s", err)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(res.Body)
|
||||
buf.Reset()
|
||||
|
||||
_, err = buf.ReadFrom(res.Body)
|
||||
res.Body.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get style.css: %s", err)
|
||||
}
|
||||
|
||||
content = append(content, []byte("\n"+additionalCSS+"\n")...)
|
||||
buf.WriteString("\n" + additionalCSS)
|
||||
|
||||
err = ioutil.WriteFile(path.Join(siteDestination, "lib", "style.css"), content, 0755)
|
||||
err = writeFile(&buf, "lib", "style.css")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write index: %s", err)
|
||||
return fmt.Errorf("failed to write style.css: %s", err)
|
||||
}
|
||||
|
||||
// Write index
|
||||
|
@ -446,7 +477,7 @@ func run() error {
|
|||
log.Println("Writing index...")
|
||||
}
|
||||
|
||||
err = writeIndex(&buf, siteDestination, basePath, siteName, pkgs, filterPkgs)
|
||||
err = writeIndex(&buf, pkgs, filterPkgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write index: %s", err)
|
||||
}
|
||||
|
@ -457,6 +488,17 @@ func run() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func relativeBasePath(p string) string {
|
||||
var r string
|
||||
if p != "" {
|
||||
r += "../"
|
||||
}
|
||||
for i := strings.Count(p, "/"); i > 0; i-- {
|
||||
r += "../"
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func uniqueStrings(strSlice []string) []string {
|
||||
keys := make(map[string]bool)
|
||||
var unique []string
|
||||
|
|
36
page.go
36
page.go
|
@ -3,7 +3,6 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
@ -21,7 +20,7 @@ summary { margin-left: 20px; cursor: pointer; }
|
|||
#footer > p, #footer > li { max-width: none; word-wrap: normal; }
|
||||
`
|
||||
|
||||
const footerText = `Documentation generated with <a href="https://godoc.org/golang.org/x/tools/godoc" target="_blank">godoc</a> + <a href="https://gitlab.com/tslocum/godoc-static" target="_blank">godoc-static</a>`
|
||||
const footerText = `Generated by <a href="https://godoc.org/golang.org/x/tools/godoc" target="_blank">godoc</a> + <a href="https://gitlab.com/tslocum/godoc-static" target="_blank">godoc-static</a>`
|
||||
|
||||
func topBar(basePath string, siteName string) string {
|
||||
var index string
|
||||
|
@ -34,11 +33,30 @@ func topBar(basePath string, siteName string) string {
|
|||
<div class="top-heading" id="heading-narrow"><a href="` + basePath + index + `">` + siteName + `</a></div>
|
||||
<!--<a href="#" id="menu-button"><span id="menu-button-arrow">▽</span></a>-->
|
||||
<div id="menu">
|
||||
<a href="` + basePath + index + `" style="margin-right: 10px;">Packages</a>
|
||||
<a href="` + basePath + index + `" style="margin-right: 10px;">Package Index</a>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
func siteFooterText(basePath string) string {
|
||||
footer := siteFooter
|
||||
addP := footer != ""
|
||||
|
||||
if addP {
|
||||
footer += "<p>"
|
||||
}
|
||||
|
||||
if siteZip != "" {
|
||||
footer += `<a href="` + basePath + siteZip + `">Download ` + siteZip + `</a> to browse offline - `
|
||||
}
|
||||
footer += footerText
|
||||
|
||||
if addP {
|
||||
footer += "</p>"
|
||||
}
|
||||
return footer
|
||||
}
|
||||
|
||||
func updatePage(doc *goquery.Document, basePath string, siteName string) {
|
||||
doc.Find("link").Remove()
|
||||
doc.Find("script").Remove()
|
||||
|
@ -157,10 +175,10 @@ func updatePage(doc *goquery.Document, basePath string, siteName string) {
|
|||
}
|
||||
})
|
||||
|
||||
doc.Find("#footer").Last().SetHtml(siteFooter)
|
||||
doc.Find("#footer").Last().SetHtml(siteFooterText(basePath))
|
||||
}
|
||||
|
||||
func writeIndex(buf *bytes.Buffer, outDir string, basePath string, siteName string, pkgs []string, filterPkgs []string) error {
|
||||
func writeIndex(buf *bytes.Buffer, pkgs []string, filterPkgs []string) error {
|
||||
var index string
|
||||
if linkIndex {
|
||||
index = "/index.html"
|
||||
|
@ -174,7 +192,7 @@ func writeIndex(buf *bytes.Buffer, outDir string, basePath string, siteName stri
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#375EAB">
|
||||
<title>` + siteName + `</title>
|
||||
<link type="text/css" rel="stylesheet" href="` + basePath + `lib/style.css">
|
||||
<link type="text/css" rel="stylesheet" href="lib/style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
@ -182,7 +200,7 @@ func writeIndex(buf *bytes.Buffer, outDir string, basePath string, siteName stri
|
|||
...
|
||||
</div><!-- #lowframe -->
|
||||
|
||||
<div id="topbar" class="wide">` + topBar(basePath, siteName) + `</div>
|
||||
<div id="topbar" class="wide">` + topBar("", siteName) + `</div>
|
||||
<div id="page" class="wide">
|
||||
<div class="container">
|
||||
`)
|
||||
|
@ -264,12 +282,12 @@ PACKAGEINDEX:
|
|||
buf.WriteString(`
|
||||
</table>
|
||||
</div>
|
||||
<div id="footer">` + siteFooter + `</div>
|
||||
<div id="footer">` + siteFooterText("") + `</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
|
||||
return ioutil.WriteFile(path.Join(outDir, "index.html"), buf.Bytes(), 0755)
|
||||
return writeFile(buf, "", "index.html")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue