diff options
Diffstat (limited to 'markdown/ast.go')
| -rw-r--r-- | markdown/ast.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/markdown/ast.go b/markdown/ast.go new file mode 100644 index 0000000..c45eb1e --- /dev/null +++ b/markdown/ast.go @@ -0,0 +1,107 @@ +package markdown + +import ( + "encoding/json" + "errors" + "fmt" + "html/template" + "strings" +) + +var ErrUnkownLexType = errors.New("unkown lex type") + +type block interface { + Eval() (template.HTML, *ParseError) +} + +type tree struct { + blocks []block +} + +func (t *tree) Eval() (template.HTML, *ParseError) { + var content template.HTML + for _, c := range t.blocks { + ct, err := c.Eval() + if err != nil { + return "", err + } + content += ct + } + return content, nil +} + +func (t *tree) String() string { + b, _ := json.MarshalIndent(t, "", " ") + return string(b) +} + +func ast(lxs *lexers) (*tree, *ParseError) { + tr := new(tree) + newLine := true + for lxs.Next() { + b, err := getBlock(lxs, newLine) + if err != nil { + return nil, err + } + if b != nil { + tr.blocks = append(tr.blocks, b) + } + if !lxs.Finished() { + newLine = lxs.Current().Type == lexerBreak + } + } + return tr, nil +} + +func getBlock(lxs *lexers, newLine bool) (block, *ParseError) { + var b block + var err *ParseError + switch lxs.Current().Type { + case lexerHeader: + if !newLine { + b, err = paragraph(lxs, false) + } else { + b, err = header(lxs) + } + case lexerExternal: + if newLine && lxs.Current().Value == "