Skip to content

Commit

Permalink
Add markdown format to docgen
Browse files Browse the repository at this point in the history
  • Loading branch information
antonmedv committed Mar 21, 2020
1 parent 0f43d1f commit e027ff6
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
48 changes: 48 additions & 0 deletions docgen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# DocGen

This package provides documentation generator with JSON or Markdown output.

## Usage

Create a file and put next code into it.

```go
package main

import (
"encoding/json"
"fmt"

"github.com/antonmedv/expr/docgen"
)

func main() {
// TODO: Replace env with your own types.
doc := docgen.CreateDoc(env)

buf, err := json.MarshalIndent(doc, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
}
```

Run `go run your_file.go`. Documentation will be printed in JSON format.

## Markdown

To generate markdown documentation:

```go
package main

import "github.com/antonmedv/expr/docgen"

func main() {
// TODO: Replace env with your own types.
doc := docgen.CreateDoc(env)

print(doc.Markdown())
}
```
9 changes: 8 additions & 1 deletion docgen/docgen_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package docgen_test

import (
"github.com/stretchr/testify/require"
"math"
"testing"

Expand Down Expand Up @@ -136,5 +137,11 @@ func TestCreateDoc_FromMap(t *testing.T) {
},
}

assert.Equal(t, litter.Sdump(expected), litter.Sdump(doc))
require.Equal(t, litter.Sdump(expected), litter.Sdump(doc))
}

func TestContext_Markdown(t *testing.T) {
doc := CreateDoc(&Env{})
md := doc.Markdown()
require.True(t, len(md) > 0)
}
93 changes: 93 additions & 0 deletions docgen/markdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package docgen

import (
"fmt"
"strings"
)

func (c *Context) Markdown() string {
out := `### Variables
| Name | Type |
|------|------|
`
for ident, v := range c.Variables {
if v.Kind == "func" {
continue
}
if v.Kind == "operator" {
continue
}
out += fmt.Sprintf("| %v | %v |\n", ident, link(v))
}

out += `
### Functions
| Name | Return type |
|------|-------------|
`
for ident, v := range c.Variables {
if v.Kind == "func" {
args := make([]string, len(v.Arguments))
for i, arg := range v.Arguments {
args[i] = link(arg)
}
out += fmt.Sprintf("| %v(%v) | %v |\n", ident, strings.Join(args, ", "), link(v.Return))
}
}

out += "\n### Types\n"
for name, t := range c.Types {
out += fmt.Sprintf("#### %v\n", name)
out += fields(t)
out += "\n"
}

return out
}

func link(t *Type) string {
if t == nil {
return "nil"
}
if t.Name != "" {
return fmt.Sprintf("[%v](#%v)", t.Name, t.Name)
}
if t.Kind == "array" {
return fmt.Sprintf("array(%v)", link(t.Type))
}
if t.Kind == "map" {
return fmt.Sprintf("map(%v => %v)", link(t.Key), link(t.Type))
}
return fmt.Sprintf("`%v`", t.Kind)
}

func fields(t *Type) string {
out := ""
foundFields := false
for ident, v := range t.Fields {
if v.Kind != "func" {
if !foundFields {
out += "| Field | Type |\n|---|---|\n"
}
foundFields = true

out += fmt.Sprintf("| %v | %v |\n", ident, link(v))
}
}
foundMethod := false
for ident, v := range t.Fields {
if v.Kind == "func" {
if !foundMethod {
out += "\n| Method | Returns |\n|---|---|\n"
}
foundMethod = true

args := make([]string, len(v.Arguments))
for i, arg := range v.Arguments {
args[i] = link(arg)
}
out += fmt.Sprintf("| %v(%v) | %v |\n", ident, strings.Join(args, ", "), link(v.Return))
}
}
return out
}

0 comments on commit e027ff6

Please sign in to comment.