diff options
| -rw-r--r-- | mardown/ast.go | 9 | ||||
| -rw-r--r-- | mardown/ast_code.go | 66 | ||||
| -rw-r--r-- | mardown/ast_modifier.go | 9 | ||||
| -rw-r--r-- | mardown/ast_paragraph.go | 16 |
4 files changed, 78 insertions, 22 deletions
diff --git a/mardown/ast.go b/mardown/ast.go index eaafee6..3a16903 100644 --- a/mardown/ast.go +++ b/mardown/ast.go @@ -75,10 +75,13 @@ func getBlock(lxs *lexers, newLine bool) (block, error) { b, err = paragraph(lxs, false) } case lexerCode: - if newLine && len(lxs.Current().Value) == 3 { - //TODO: handle - } else { + if !newLine && len(lxs.Current().Value) == 3 { + return nil, ErrInvalidCodeBlockPosition + } + if len(lxs.Current().Value) == 1 { b, err = paragraph(lxs, false) + } else { + b, err = code(lxs) } case lexerLiteral, lexerEscape, lexerModifier: b, err = paragraph(lxs, false) diff --git a/mardown/ast_code.go b/mardown/ast_code.go new file mode 100644 index 0000000..7edd6ba --- /dev/null +++ b/mardown/ast_code.go @@ -0,0 +1,66 @@ +package mardown + +import ( + "errors" + "fmt" + "html/template" +) + +var ( + ErrUnknownCodeType = errors.New("unkown code type") + ErrInvalidCodeFormat = errors.New("invalid code format") + ErrInvalidCodeBlockPosition = errors.Join(ErrInvalidParagraph, errors.New("invalid code block position")) +) + +type codeType uint + +const ( + codeOneLine codeType = 1 + codeMultiLine codeType = 2 +) + +type astCode struct { + content string + before string + codeType codeType +} + +func (a *astCode) Eval() (template.HTML, error) { + switch a.codeType { + case codeOneLine: + return template.HTML(fmt.Sprintf("<code>%s</code>", template.HTMLEscapeString(a.content))), nil + case codeMultiLine: + return template.HTML(fmt.Sprintf("<pre><code>%s</code></pre>", template.HTMLEscapeString(a.content))), nil + default: + return "", ErrUnknownCodeType + } +} + +func code(lxs *lexers) (*astCode, error) { + tree := new(astCode) + current := lxs.Current().Value + if len(current) == 3 { + tree.codeType = codeMultiLine + } else if len(current) == 1 { + tree.codeType = codeOneLine + } else { + return nil, ErrInvalidCodeFormat + } + started := false + for lxs.Next() && lxs.Current().Value != current { + if lxs.Current().Type == lexerBreak { + if tree.codeType == codeOneLine { + return nil, ErrInvalidCodeFormat + } + if !started { + started = true + } + } + if started || tree.codeType == codeOneLine { + tree.content += lxs.Current().Value + } else { + tree.before += lxs.Current().Value + } + } + return tree, nil +} diff --git a/mardown/ast_modifier.go b/mardown/ast_modifier.go index 80552e2..570fbd2 100644 --- a/mardown/ast_modifier.go +++ b/mardown/ast_modifier.go @@ -17,7 +17,6 @@ type modifierTag string const ( boldTag modifierTag = "b" emTag modifierTag = "em" - codeTag modifierTag = "code" ) type astModifier struct { @@ -62,7 +61,7 @@ func modifier(lxs *lexers) (*astModifier, error) { switch lxs.Current().Type { case lexerLiteral: s += lxs.Current().Value - case lexerModifier, lexerCode: + case lexerModifier: n := len(modInside.symbols) if len(lxs.Current().Value) < n { return nil, ErrInvalidModifier @@ -87,11 +86,7 @@ func modifierDetect(val string) *astModifier { mod := new(astModifier) if len(val) == 1 { mod.symbols = val - if val == "`" { - mod.tag = codeTag - } else { - mod.tag = emTag - } + mod.tag = emTag return mod } if val[:2] == "**" || val[:2] == "__" { diff --git a/mardown/ast_paragraph.go b/mardown/ast_paragraph.go index 6149c30..e9855a7 100644 --- a/mardown/ast_paragraph.go +++ b/mardown/ast_paragraph.go @@ -7,8 +7,7 @@ import ( ) var ( - ErrInvalidParagraph = errors.New("invalid paragraph") - ErrInvalidCodeBlockPosition = errors.Join(ErrInvalidParagraph, errors.New("invalid code block position")) + ErrInvalidParagraph = errors.New("invalid paragraph") ) type astParagraph struct { @@ -61,19 +60,12 @@ func paragraph(lxs *lexers, oneLine bool) (*astParagraph, error) { n = 0 //TODO: handle case lexerCode: - n = 0 - if len(lxs.Current().Value) == 3 { - if n == 0 { - return nil, ErrInvalidCodeBlockPosition - } - lxs.current-- // because we do not use it before the next - return tree, nil - } - mod, err := modifier(lxs) + b, err := code(lxs) if err != nil { return nil, err } - tree.content = append(tree.content, mod) + tree.content = append(tree.content, b) + return tree, nil } } return tree, nil |
