Skip to content
This repository has been archived by the owner on Jul 29, 2021. It is now read-only.

Commit

Permalink
Add support for examples.
Browse files Browse the repository at this point in the history
Fixes #2
  • Loading branch information
abursavich committed Apr 16, 2018
1 parent deb306d commit ac43cc4
Show file tree
Hide file tree
Showing 9 changed files with 744 additions and 54 deletions.
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ readme:
godoc2md github.com/davecheney/godoc2md > README.md

examples:
godoc2md github.com/kr/fs > examples/fs/README.md
godoc2md github.com/codegangsta/martini > examples/martini/README.md
godoc2md github.com/gorilla/sessions > examples/sessions/README.md
godoc2md go/build > examples/build/README.md
godoc2md -ex github.com/kr/fs > examples/fs/README.md
godoc2md -ex github.com/codegangsta/martini > examples/martini/README.md
godoc2md -ex github.com/gorilla/sessions > examples/sessions/README.md
godoc2md -ex github.com/pkg/errors > examples/errors/README.md
godoc2md -ex go/build > examples/build/README.md

.PHONY: examples readme all
110 changes: 110 additions & 0 deletions example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"bytes"
"go/doc"
"go/printer"
"regexp"
"sort"
"strings"
"unicode"
"unicode/utf8"

"golang.org/x/tools/godoc"
)

type example struct {
Name string
Doc string
Code string
Output string
}

func examplesFunc(info *godoc.PageInfo, name string) []*example {
if !*showExamples {
return nil
}
var egs []*example
for _, eg := range info.Examples {
if name != "*" && stripExampleSuffix(eg.Name) != name {
continue
}
doc := eg.Doc
out := eg.Output
code, wholeFile := exampleCode(info, eg)
if wholeFile {
doc = ""
out = ""
}
egs = append(egs, &example{
Name: eg.Name,
Doc: doc,
Code: code,
Output: out,
})
}
sort.Slice(egs, func(i int, j int) bool {
ni, si := splitExampleName(egs[i].Name)
nj, sj := splitExampleName(egs[j].Name)
if ni == nj {
return si < sj
}
return ni < nj
})
return egs
}

var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*(unordered )?output:`)

func exampleCode(info *godoc.PageInfo, eg *doc.Example) (code string, wholeFile bool) {
// Print code
var buf bytes.Buffer
cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: *tabWidth}
config.Fprint(&buf, info.FSet, cnode)
code = strings.Trim(buf.String(), "\n")
wholeFile = true

if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' {
wholeFile = false
// Remove surrounding braces.
code = strings.Trim(code[1:n-1], "\n")
// Remove output from code.
if loc := exampleOutputRx.FindStringIndex(code); loc != nil {
code = strings.TrimRightFunc(code[:loc[0]], unicode.IsSpace)
}
// Unindent code.
lines := strings.Split(code, "\n")
unindent(lines)
code = strings.Join(lines, "\n")
}

return code, wholeFile
}

func splitExampleName(s string) (name, suffix string) {
i := strings.LastIndex(s, "_")
if 0 <= i && i < len(s)-1 && !startsWithUppercase(s[i+1:]) {
name = s[:i]
suffix = " (" + strings.Title(s[i+1:]) + ")"
return
}
name = s
return
}

// stripExampleSuffix strips lowercase braz in Foo_braz or Foo_Bar_braz from name
// while keeping uppercase Braz in Foo_Braz.
func stripExampleSuffix(name string) string {
if i := strings.LastIndex(name, "_"); i != -1 {
if i < len(name)-1 && !startsWithUppercase(name[i+1:]) {
name = name[:i]
}
}
return name
}

func startsWithUppercase(s string) bool {
r, _ := utf8.DecodeRuneInString(s)
return unicode.IsUpper(r)
}
32 changes: 17 additions & 15 deletions examples/build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ During a particular build, the following words are satisfied:
- "go1.6", from Go version 1.6 onward
- "go1.7", from Go version 1.7 onward
- "go1.8", from Go version 1.8 onward
- "go1.9", from Go version 1.9 onward
- "go1.10", from Go version 1.10 onward
- any additional words listed in ctxt.BuildTags

If a file's name, after stripping the extension and a possible _test suffix,
Expand Down Expand Up @@ -216,7 +218,7 @@ ToolDir is the directory containing build tools.



## <a name="ArchChar">func</a> [ArchChar](/src/target/build.go?s=45435:45479#L1563)
## <a name="ArchChar">func</a> [ArchChar](/src/target/build.go?s=47288:47332#L1611)
``` go
func ArchChar(goarch string) (string, error)
```
Expand All @@ -228,7 +230,7 @@ no longer vary by architecture; they are compile, link, .o, and a.out, respectiv



## <a name="IsLocalImport">func</a> [IsLocalImport](/src/target/build.go?s=44955:44991#L1553)
## <a name="IsLocalImport">func</a> [IsLocalImport](/src/target/build.go?s=46808:46844#L1601)
``` go
func IsLocalImport(path string) bool
```
Expand Down Expand Up @@ -321,7 +323,7 @@ if set, or else the compiled code's GOARCH, GOOS, and GOROOT.



### <a name="Context.Import">func</a> (\*Context) [Import](/src/target/build.go?s=16697:16787#L486)
### <a name="Context.Import">func</a> (\*Context) [Import](/src/target/build.go?s=16883:16973#L491)
``` go
func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error)
```
Expand All @@ -345,7 +347,7 @@ If an error occurs, Import returns a non-nil error and a non-nil



### <a name="Context.ImportDir">func</a> (\*Context) [ImportDir](/src/target/build.go?s=14860:14937#L434)
### <a name="Context.ImportDir">func</a> (\*Context) [ImportDir](/src/target/build.go?s=15046:15123#L439)
``` go
func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error)
```
Expand All @@ -355,7 +357,7 @@ the named directory.



### <a name="Context.MatchFile">func</a> (\*Context) [MatchFile](/src/target/build.go?s=30989:31061#L1032)
### <a name="Context.MatchFile">func</a> (\*Context) [MatchFile](/src/target/build.go?s=31854:31926#L1050)
``` go
func (ctxt *Context) MatchFile(dir, name string) (match bool, err error)
```
Expand All @@ -369,7 +371,7 @@ read some or all of the file's content.



### <a name="Context.SrcDirs">func</a> (\*Context) [SrcDirs](/src/target/build.go?s=7522:7561#L238)
### <a name="Context.SrcDirs">func</a> (\*Context) [SrcDirs](/src/target/build.go?s=7602:7641#L239)
``` go
func (ctxt *Context) SrcDirs() []string
```
Expand All @@ -380,7 +382,7 @@ that do not exist.



## <a name="ImportMode">type</a> [ImportMode](/src/target/build.go?s=9780:9800#L325)
## <a name="ImportMode">type</a> [ImportMode](/src/target/build.go?s=9966:9986#L330)
``` go
type ImportMode uint
```
Expand Down Expand Up @@ -441,7 +443,7 @@ const (



## <a name="MultiplePackageError">type</a> [MultiplePackageError](/src/target/build.go?s=15413:15621#L451)
## <a name="MultiplePackageError">type</a> [MultiplePackageError](/src/target/build.go?s=15599:15807#L456)
``` go
type MultiplePackageError struct {
Dir string // directory containing files
Expand All @@ -461,14 +463,14 @@ multiple buildable Go source files for multiple packages.



### <a name="MultiplePackageError.Error">func</a> (\*MultiplePackageError) [Error](/src/target/build.go?s=15623:15668#L457)
### <a name="MultiplePackageError.Error">func</a> (\*MultiplePackageError) [Error](/src/target/build.go?s=15809:15854#L462)
``` go
func (e *MultiplePackageError) Error() string
```



## <a name="NoGoError">type</a> [NoGoError](/src/target/build.go?s=15165:15202#L441)
## <a name="NoGoError">type</a> [NoGoError](/src/target/build.go?s=15351:15388#L446)
``` go
type NoGoError struct {
Dir string
Expand All @@ -487,14 +489,14 @@ test files, files hidden by build tags, and so on.)



### <a name="NoGoError.Error">func</a> (\*NoGoError) [Error](/src/target/build.go?s=15204:15238#L445)
### <a name="NoGoError.Error">func</a> (\*NoGoError) [Error](/src/target/build.go?s=15390:15424#L450)
``` go
func (e *NoGoError) Error() string
```



## <a name="Package">type</a> [Package](/src/target/build.go?s=11686:14547#L372)
## <a name="Package">type</a> [Package](/src/target/build.go?s=11872:14733#L377)
``` go
type Package struct {
Dir string // directory containing package sources
Expand Down Expand Up @@ -557,14 +559,14 @@ A Package describes the Go package found in a directory.



### <a name="Import">func</a> [Import](/src/target/build.go?s=33366:33433#L1117)
### <a name="Import">func</a> [Import](/src/target/build.go?s=34178:34245#L1135)
``` go
func Import(path, srcDir string, mode ImportMode) (*Package, error)
```
Import is shorthand for Default.Import.


### <a name="ImportDir">func</a> [ImportDir](/src/target/build.go?s=33531:33592#L1122)
### <a name="ImportDir">func</a> [ImportDir](/src/target/build.go?s=34343:34404#L1140)
``` go
func ImportDir(dir string, mode ImportMode) (*Package, error)
```
Expand All @@ -574,7 +576,7 @@ ImportDir is shorthand for Default.ImportDir.



### <a name="Package.IsCommand">func</a> (\*Package) [IsCommand](/src/target/build.go?s=14705:14739#L428)
### <a name="Package.IsCommand">func</a> (\*Package) [IsCommand](/src/target/build.go?s=14891:14925#L433)
``` go
func (p *Package) IsCommand() bool
```
Expand Down
Loading

0 comments on commit ac43cc4

Please sign in to comment.