aboutsummaryrefslogtreecommitdiff
path: root/mardown
diff options
context:
space:
mode:
Diffstat (limited to 'mardown')
-rw-r--r--mardown/ast.go107
-rw-r--r--mardown/ast_code.go66
-rw-r--r--mardown/ast_external.go179
-rw-r--r--mardown/ast_external_test.go49
-rw-r--r--mardown/ast_header.go39
-rw-r--r--mardown/ast_list.go79
-rw-r--r--mardown/ast_list_test.go44
-rw-r--r--mardown/ast_modifier.go150
-rw-r--r--mardown/ast_modifier_test.go22
-rw-r--r--mardown/ast_paragraph.go101
-rw-r--r--mardown/ast_paragraph_test.go20
-rw-r--r--mardown/ast_quote.go81
-rw-r--r--mardown/ast_quote_test.go23
-rw-r--r--mardown/ast_test.go62
-rw-r--r--mardown/error.go43
-rw-r--r--mardown/error_test.go26
-rw-r--r--mardown/eval.go16
-rw-r--r--mardown/lexer.go132
-rw-r--r--mardown/lexer_test.go30
19 files changed, 0 insertions, 1269 deletions
diff --git a/mardown/ast.go b/mardown/ast.go
deleted file mode 100644
index ceeec6f..0000000
--- a/mardown/ast.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package mardown
-
-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 == "![" {
- b, err = external(lxs)
- } else {
- b, err = paragraph(lxs, false)
- }
- case lexerQuote:
- if newLine {
- b, err = quote(lxs)
- } else {
- b, err = paragraph(lxs, false)
- }
- case lexerList:
- if newLine {
- b, err = list(lxs)
- } else {
- b, err = paragraph(lxs, false)
- }
- case lexerCode:
- if !newLine && len(lxs.Current().Value) == 3 {
- return nil, &ParseError{lxs: *lxs, internal: ErrInvalidCodeBlockPosition}
- }
- if len(lxs.Current().Value) == 1 {
- b, err = paragraph(lxs, false)
- } else {
- b, err = code(lxs)
- }
- case lexerLiteral, lexerModifier:
- b, err = paragraph(lxs, false)
- case lexerBreak: // do nothing
- default:
- err = &ParseError{
- lxs: *lxs,
- internal: errors.Join(ErrUnkownLexType, fmt.Errorf("type received: %s", lxs.Current().Type)),
- }
- }
- return b, err
-}
-
-func trimSpace(s template.HTML) template.HTML {
- return template.HTML(strings.TrimSpace(string(s)))
-}
diff --git a/mardown/ast_code.go b/mardown/ast_code.go
deleted file mode 100644
index f029df2..0000000
--- a/mardown/ast_code.go
+++ /dev/null
@@ -1,66 +0,0 @@
-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, *ParseError) {
- 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 "", &ParseError{lxs: lexers{}, internal: ErrUnknownCodeType}
- }
-}
-
-func code(lxs *lexers) (*astCode, *ParseError) {
- 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, &ParseError{lxs: *lxs, internal: ErrInvalidCodeFormat}
- }
- started := false
- for lxs.Next() && lxs.Current().Value != current {
- if lxs.Current().Type == lexerBreak {
- if tree.codeType == codeOneLine {
- return nil, &ParseError{lxs: *lxs, internal: 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_external.go b/mardown/ast_external.go
deleted file mode 100644
index 98a090e..0000000
--- a/mardown/ast_external.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package mardown
-
-import (
- "fmt"
- "html/template"
-)
-
-type astLink struct {
- content block
- href block
-}
-
-func (a *astLink) Eval() (template.HTML, *ParseError) {
- content, err := a.content.Eval()
- if err != nil {
- return "", err
- }
- href, err := a.href.Eval()
- if err != nil {
- return "", err
- }
- return template.HTML(fmt.Sprintf(`<a href="%s">%s</a>`, href, content)), nil
-}
-
-type astImage struct {
- alt block
- src block
- source []*astParagraph
-}
-
-func (a *astImage) Eval() (template.HTML, *ParseError) {
- alt, err := a.alt.Eval()
- if err != nil {
- return "", err
- }
- src, err := a.src.Eval()
- if err != nil {
- return "", err
- }
- if a.source == nil {
- return template.HTML(fmt.Sprintf(`<figure><img alt="%s" src="%s"></figure>`, alt, src)), nil
- }
- var s template.HTML
- for _, c := range a.source {
- ct, err := c.Eval()
- if err != nil {
- return "", err
- }
- s += ct + " "
- }
- s = s[:len(s)-1]
- return template.HTML(fmt.Sprintf(`<figure><img alt="%s" src="%s"><figcaption>%s</figcaption></figure>`, alt, src, s)), nil
-}
-
-func external(lxs *lexers) (block, *ParseError) {
- tp := lxs.Current().Value
- if !lxs.Next() {
- return astLiteral(tp), nil
- }
- lxs.Before() // because we call Next
- var b block
- var err *ParseError
- switch tp {
- case "![":
- b, err = image(lxs)
- case "[":
- b, err = link(lxs)
- default:
- b = astLiteral(tp)
- }
- return b, err
-}
-
-func link(lxs *lexers) (block, *ParseError) {
- lk := new(astLink)
- start := lxs.current
- content, href, _, ok := parseExternal(lxs, false)
- if !ok {
- return reset(lxs, start), nil
- }
- lk.content = astLiteral(content)
- lk.href = astLiteral(href)
- return lk, nil
-}
-
-func image(lxs *lexers) (block, *ParseError) {
- img := new(astImage)
- start := lxs.current
- alt, src, source, ok := parseExternal(lxs, true)
- if !ok {
- return reset(lxs, start), nil
- }
- img.alt = astLiteral(alt)
- img.src = astLiteral(src)
- img.source = source
- return img, nil
-}
-
-func parseExternal(lxs *lexers, withSource bool) (string, string, []*astParagraph, bool) {
- next := false
- var s string
- var first string
- var end string
- var ps []*astParagraph
- n := 0
- fn := func() bool {
- p, err := paragraph(lxs, true)
- if err != nil {
- return false
- }
- ps = append(ps, p)
- n = 0
- return true
- }
- for lxs.Next() && n < 2 {
- switch lxs.Current().Type {
- case lexerBreak:
- if !withSource {
- return "", "", nil, false
- }
- n += len(lxs.Current().Value)
- if first != "" && end != "" {
- if !lxs.Next() {
- return first, end, ps, true
- }
- ok := fn()
- if !ok {
- return "", "", nil, false
- }
- lxs.Before() // because we must parse lexerBreak
- }
- case lexerExternal:
- if first != "" && end != "" {
- return "", "", nil, false
- }
- if n > 0 && (first == "" || end == "") {
- return "", "", nil, false
- }
- n = 0
- if !next {
- if lxs.Current().Value != "](" || !lxs.Next() {
- return "", "", nil, false
- }
- lxs.Before() // because we called Next
- first = s
- s = ""
- next = true
- } else {
- if lxs.Current().Value != ")" {
- return "", "", nil, false
- }
- if !withSource {
- return first, s, nil, true
- }
- end = s
- s = ""
- if lxs.Next() && lxs.Current().Type != lexerBreak {
- return "", "", nil, false
- }
- lxs.Before() // because we called Next
- }
- default:
- if ps != nil {
- return "", "", nil, false
- }
- n = 0
- s += lxs.Current().Value
- }
- }
- if !withSource {
- return "", "", nil, false
- }
- return first, end, ps, true
-}
-
-func reset(lxs *lexers, start int) block {
- lxs.current = start
- return astLiteral(lxs.Current().Value)
-}
diff --git a/mardown/ast_external_test.go b/mardown/ast_external_test.go
deleted file mode 100644
index afae085..0000000
--- a/mardown/ast_external_test.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestExternal(t *testing.T) {
- lxs := lex("[content](href)")
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- got, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if string(got) != `<p><a href="href">content</a></p>` {
- t.Errorf("invalid value, got %s", got)
- }
-
- lxs = lex("![image alt](image src)")
- tree, err = ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- got, err = tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if string(got) != `<figure><img alt="image alt" src="image src"></figure>` {
- t.Errorf("invalid value, got %s", got)
- }
-
- lxs = lex(`
-![image alt](image src)
-source 1
-source 2
-`)
- tree, err = ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- got, err = tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if string(got) != `<figure><img alt="image alt" src="image src"><figcaption>source 1 source 2</figcaption></figure>` {
- t.Errorf("invalid value, got %s", got)
- }
-
-}
diff --git a/mardown/ast_header.go b/mardown/ast_header.go
deleted file mode 100644
index 0ce8a22..0000000
--- a/mardown/ast_header.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package mardown
-
-import (
- "errors"
- "fmt"
- "html/template"
-)
-
-var ErrInvalidHeader = errors.New("invalid header")
-
-type astHeader struct {
- level uint
- content *astParagraph
-}
-
-func (a *astHeader) Eval() (template.HTML, *ParseError) {
- if a.level > 6 {
- return "", &ParseError{lxs: lexers{}, internal: ErrInvalidCodeFormat}
- }
- var content template.HTML
- content, err := a.content.Eval()
- if err != nil {
- return "", err
- }
- return template.HTML(fmt.Sprintf("<h%d>%s</h%d>", a.level, trimSpace(content), a.level)), nil
-}
-
-func header(lxs *lexers) (*astHeader, *ParseError) {
- b := &astHeader{level: uint(len(lxs.Current().Value))}
- if !lxs.Next() {
- return nil, &ParseError{lxs: *lxs, internal: ErrInvalidHeader}
- }
- var err *ParseError
- b.content, err = paragraph(lxs, true)
- if err != nil {
- return nil, err
- }
- return b, nil
-}
diff --git a/mardown/ast_list.go b/mardown/ast_list.go
deleted file mode 100644
index 39f0178..0000000
--- a/mardown/ast_list.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package mardown
-
-import (
- "fmt"
- "html/template"
- "regexp"
-)
-
-var regexOrdered = regexp.MustCompile(`\d+\.`)
-
-type listType string
-
-const (
- listUnordered listType = "ul"
- listOrdered listType = "ol"
-)
-
-type astList struct {
- tag listType
- content []*astParagraph
-}
-
-func (a *astList) Eval() (template.HTML, *ParseError) {
- var content template.HTML
- for _, c := range a.content {
- ct, err := c.Eval()
- if err != nil {
- return "", err
- }
- content += template.HTML(fmt.Sprintf("<li>%s</li>", trimSpace(ct)))
- }
- return template.HTML(fmt.Sprintf("<%s>%s</%s>", a.tag, content, a.tag)), nil
-}
-
-func list(lxs *lexers) (block, *ParseError) {
- tree := new(astList)
- tree.tag = detectListType(lxs.Current().Value)
- if len(tree.tag) == 0 {
- return paragraph(lxs, false)
- }
- n := 0
- for lxs.Next() && n < 2 {
- switch lxs.Current().Type {
- case lexerBreak:
- n += len(lxs.Current().Value)
- case lexerList:
- n = 0
- tp := detectListType(lxs.Current().Value)
- if tp != tree.tag {
- lxs.Before() // because we dit not use it
- return tree, nil
- }
- default:
- n = 0
- c, err := paragraph(lxs, true)
- if err != nil {
- return nil, err
- }
- lxs.Before() // because we must parse the last char
- tree.content = append(tree.content, c)
- }
- }
- lxs.Before() // because we did not use it
- return tree, nil
-}
-
-func detectListType(val string) listType {
- first := []rune(val)[0]
- if first == '-' || first == '*' {
- if len(val) > 1 {
- return ""
- }
- return listUnordered
- }
- if !regexOrdered.MatchString(val) {
- return ""
- }
- return listOrdered
-}
diff --git a/mardown/ast_list_test.go b/mardown/ast_list_test.go
deleted file mode 100644
index 6736223..0000000
--- a/mardown/ast_list_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package mardown
-
-import (
- "strings"
- "testing"
-)
-
-var rw = `
-- item A
-- item B
-* item C
-
-1. item 1
-2. item 2
-`
-
-var expected = `
-<ul>
-<li>item A</li>
-<li>item B</li>
-<li>item C</li>
-</ul>
-<ol>
-<li>item 1</li>
-<li>item 2</li>
-</ol>
-`
-
-func TestList(t *testing.T) {
- lxs := lex(rw)
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- got, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- exp := strings.ReplaceAll(expected, "\n", "")
- if string(got) != exp {
- t.Errorf("invalid value, got %s", got)
- t.Logf("expected %s", exp)
- }
-}
diff --git a/mardown/ast_modifier.go b/mardown/ast_modifier.go
deleted file mode 100644
index 36c6193..0000000
--- a/mardown/ast_modifier.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package mardown
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "html/template"
-)
-
-var (
- ErrInvalidUsage = errors.Join(ErrInvalidParagraph, errors.New("invalid modifier usage"))
- ErrInvalidTypeInModifier = errors.Join(ErrInvalidParagraph, errors.New("invalid type in modifier"))
-)
-
-type modifierTag string
-
-const (
- boldTag modifierTag = "b"
- emTag modifierTag = "em"
-)
-
-type astModifier struct {
- symbols string
- tag modifierTag
- content []block
- super bool
-}
-
-func (a *astModifier) Eval() (template.HTML, *ParseError) {
- var content template.HTML
- for _, c := range a.content {
- ct, err := c.Eval()
- if err != nil {
- return "", &ParseError{lxs: lexers{}, internal: err}
- }
- content += ct
- }
- if a.super {
- return content, nil
- }
- return template.HTML(fmt.Sprintf("<%s>%s</%s>", a.tag, content, a.tag)), nil
-}
-
-func (a *astModifier) String() string {
- content := "["
- for _, c := range a.content {
- content += "\n\t"
- if v, ok := c.(fmt.Stringer); ok {
- content += v.String()
- } else {
- b, _ := json.MarshalIndent(a.content, "\t", " ")
- content += string(b)
- }
- content += ",\n\t"
- }
- content += "]"
- return fmt.Sprintf("modifier{sym: %s, tag: %s, super: %v, content: %s\n}", a.symbols, a.tag, a.super, content)
-}
-
-func modifier(lxs *lexers) (*astModifier, error) {
- current := lxs.Current().Value
- mod, err := modifierDetect(current)
- if err != nil {
- return nil, err
- }
- var s string
- for lxs.Next() {
- switch lxs.Current().Type {
- case lexerLiteral, lexerHeader, lexerList:
- s += lxs.Current().Value
- case lexerModifier:
- if mod.super && []rune(mod.symbols)[0] == []rune(lxs.Current().Value)[0] &&
- len(mod.symbols) >= len(lxs.Current().Value) {
- mod.symbols = mod.symbols[len(lxs.Current().Value):]
- subMod, err := modifierDetect(lxs.Current().Value)
- if err != nil {
- return nil, err
- }
- if !subMod.super {
- subMod.content = append(subMod.content, astLiteral(s))
- mod, err = modifierDetect(mod.symbols) // this trick is so cool :D
- if err != nil {
- return nil, err
- }
- } else {
- subMod, _ = modifierDetect("**")
- subEm, _ := modifierDetect("*")
- subEm.content = append(subEm.content, astLiteral(s))
- subMod.content = append(subMod.content, subEm)
- }
- s = ""
- mod.content = append(mod.content, subMod)
- if len(mod.symbols) == 0 {
- return mod, nil
- }
- } else {
- if lxs.Current().Value == mod.symbols {
- mod.content = append(mod.content, astLiteral(s))
- return mod, nil
- } else if len(s) != 0 {
- mod.content = append(mod.content, astLiteral(s))
- s = ""
- }
- c, err := modifier(lxs)
- if err != nil {
- return nil, err
- }
- mod.content = append(mod.content, c)
- }
- case lexerBreak:
- lxs.Before() // because we did not use it
- if len(s) != 0 {
- return nil, ErrInvalidUsage
- }
- return mod, nil
- case lexerExternal:
- if lxs.Current().Value == "!" {
- s += lxs.Current().Value
- } else {
- ext, err := external(lxs)
- if err != nil {
- return nil, err
- }
- mod.content = append(mod.content, ext)
- }
- default:
- return nil, ErrInvalidTypeInModifier
- }
- }
- if len(s) != 0 {
- return nil, ErrInvalidUsage
- }
- return mod, nil
-}
-
-func modifierDetect(val string) (*astModifier, error) {
- mod := new(astModifier)
- mod.symbols = val
- switch len(val) {
- case 1:
- mod.tag = emTag
- case 2:
- mod.tag = boldTag
- case 3:
- mod.super = true
- default:
- return nil, ErrInvalidUsage
- }
- return mod, nil
-}
diff --git a/mardown/ast_modifier_test.go b/mardown/ast_modifier_test.go
deleted file mode 100644
index ce0988f..0000000
--- a/mardown/ast_modifier_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestModifier(t *testing.T) {
- content := `
-**bo*n*soir**, ça ***va* bien** ?
-`
- lxs := lex(content)
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- c, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if c != "<p><b>bo<em>n</em>soir</b>, ça <b><em>va</em> bien</b> ?</p>" {
- t.Errorf("failed, got %s", c)
- t.Logf("lxs: %s\ntree: %s", lxs, tree)
- }
-}
diff --git a/mardown/ast_paragraph.go b/mardown/ast_paragraph.go
deleted file mode 100644
index 21dc1ef..0000000
--- a/mardown/ast_paragraph.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package mardown
-
-import (
- "errors"
- "fmt"
- "html/template"
-)
-
-var (
- ErrInvalidParagraph = errors.New("invalid paragraph")
-)
-
-type astParagraph struct {
- content []block
- oneLine bool
-}
-
-func (a *astParagraph) Eval() (template.HTML, *ParseError) {
- var content template.HTML
- for _, c := range a.content {
- ct, err := c.Eval()
- if err != nil {
- return "", err
- }
- content += ct
- }
- if a.oneLine {
- return content, nil
- }
- return template.HTML(fmt.Sprintf("<p>%s</p>", trimSpace(content))), nil
-}
-
-func paragraph(lxs *lexers, oneLine bool) (*astParagraph, *ParseError) {
- tree := new(astParagraph)
- tree.oneLine = oneLine
- maxBreak := 2
- if oneLine {
- maxBreak = 1
- }
- n := 0
- lxs.current-- // because we do not use it before the next
- for lxs.Next() && n < maxBreak {
- switch lxs.Current().Type {
- case lexerBreak:
- n += len(lxs.Current().Value)
- case lexerQuote, lexerList:
- if n > 0 {
- lxs.Before() // because we did not use it
- return tree, nil
- }
- tree.content = append(tree.content, astLiteral(lxs.Current().Value))
- case lexerLiteral, lexerHeader:
- s := lxs.Current().Value
- // replace line break by space
- if n > 0 {
- s = " " + s
- }
- n = 0
- tree.content = append(tree.content, astLiteral(s))
- case lexerModifier:
- n = 0
- mod, err := modifier(lxs)
- if err != nil {
- return nil, &ParseError{lxs: *lxs, internal: err}
- }
- tree.content = append(tree.content, mod)
- case lexerExternal:
- n = 0
- if lxs.Current().Value == "!" {
- tree.content = append(tree.content, astLiteral(lxs.Current().Value))
- } else {
- ext, err := external(lxs)
- if err != nil {
- return nil, err
- }
- tree.content = append(tree.content, ext)
- }
- case lexerCode:
- if len(lxs.Current().Value) > 1 {
- return nil, &ParseError{lxs: *lxs, internal: ErrInvalidCodeBlockPosition}
- }
- n = 0
- b, err := code(lxs)
- if err != nil {
- return nil, err
- }
- tree.content = append(tree.content, b)
- return tree, nil
- }
- }
- if !lxs.Finished() {
- lxs.Before() // because we never handle the last item
- }
- return tree, nil
-}
-
-type astLiteral string
-
-func (a astLiteral) Eval() (template.HTML, *ParseError) {
- return template.HTML(template.HTMLEscapeString(string(a))), nil
-}
diff --git a/mardown/ast_paragraph_test.go b/mardown/ast_paragraph_test.go
deleted file mode 100644
index 8daba99..0000000
--- a/mardown/ast_paragraph_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestParagraph(t *testing.T) {
- content := "bonsoir"
- lxs := lex(content)
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- c, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if c != "<p>bonsoir</p>" {
- t.Errorf("failed, got %s", c)
- t.Logf("lxs: %s\ntree: %s", lxs, tree)
- }
-}
diff --git a/mardown/ast_quote.go b/mardown/ast_quote.go
deleted file mode 100644
index ffc8e83..0000000
--- a/mardown/ast_quote.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package mardown
-
-import (
- "fmt"
- "html/template"
- "strings"
-)
-
-type astQuote struct {
- quote []*astParagraph
- source []*astParagraph
-}
-
-func (a *astQuote) Eval() (template.HTML, *ParseError) {
- var quote template.HTML
- for _, c := range a.quote {
- ct, err := c.Eval()
- if err != nil {
- return "", err
- }
- quote += ct
- }
- quote = template.HTML(fmt.Sprintf("<blockquote>%s</blockquote>", trimSpace(quote)))
- var source template.HTML
- for _, c := range a.source {
- ct, err := c.Eval()
- if err != nil {
- return "", err
- }
- source += ct
- }
- source = template.HTML(strings.TrimSpace(string(source)))
- if len(source) > 0 {
- return template.HTML(fmt.Sprintf(`<div class="quote">%s<p>%s</p></div>`, quote, source)), nil
- }
- return template.HTML(fmt.Sprintf(`<div class="quote">%s</div>`, quote)), nil
-}
-
-func quote(lxs *lexers) (*astQuote, *ParseError) {
- tree := new(astQuote)
- n := 0
- quoteContinue := true
- source := false
- for lxs.Next() && n < 2 {
- switch lxs.Current().Type {
- case lexerBreak:
- n += len(lxs.Current().Value)
- quoteContinue = false
- case lexerQuote:
- n = 0
- if source {
- // because the code did not use it
- lxs.Before()
- return tree, nil
- }
- quoteContinue = true
- case lexerLiteral, lexerModifier, lexerCode:
- n = 0
- if !quoteContinue {
- source = true
- }
- p, err := paragraph(lxs, true)
- if err != nil {
- return nil, err
- }
-
- if !source {
- tree.quote = append(tree.quote, p)
- } else {
- tree.source = append(tree.source, p)
- }
- n++
- quoteContinue = false
- default:
- // because the code did not use it
- lxs.Before()
- return tree, nil
- }
- }
- return tree, nil
-}
diff --git a/mardown/ast_quote_test.go b/mardown/ast_quote_test.go
deleted file mode 100644
index c3c7b3b..0000000
--- a/mardown/ast_quote_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestQuote(t *testing.T) {
- content := `
-> Bonsoir, je suis un **code**
-avec une source
-`
- lxs := lex(content)
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- c, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- if c != `<div class="quote"><blockquote>Bonsoir, je suis un <b>code</b></blockquote><p>avec une source</p></div>` {
- t.Errorf("failed, got %s", c)
- t.Logf("lxs: %s\ntree: %s", lxs, tree)
- }
-}
diff --git a/mardown/ast_test.go b/mardown/ast_test.go
deleted file mode 100644
index 2b47855..0000000
--- a/mardown/ast_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package mardown
-
-import (
- "strings"
- "testing"
-)
-
-var raw = `
-# Je suis un titre
-Avec une description classique,
-sur plusieurs lignes !
-
-Et je peux mettre du texte en **gras**,
-en *italique* et les **_deux en même temps_** !
-
-> Je suis une magnifique citation
-> sur plusieurs lignes
-avec une source
-> qui recommence après !
-
-- Ceci est une liste
-- pas ordonnée
-1. et maintenant
-2. elle l'est
-- hehe
-
-![Ceci est ma pfp :3](https://cdn.anhgelus.world/pfp.jpg)
-[Ma pfp](https://now.anhgelus.world/) hehe :D
-Elle est **magnifique**, n'est-ce pas ?
-`
-
-var parsed = `
-<h1>Je suis un titre</h1>
-<p>Avec une description classique, sur plusieurs lignes !</p>
-<p>Et je peux mettre du texte en <b>gras</b>, en <em>italique</em> et les <b><em>deux en même temps</em></b> !</p>
-<div class="quote"><blockquote>Je suis une magnifique citation sur plusieurs lignes</blockquote><p>avec une source</p></div>
-<div class="quote"><blockquote>qui recommence après !</blockquote></div>
-<ul><li>Ceci est une liste</li><li>pas ordonnée</li></ul>
-<ol><li>et maintenant</li><li>elle l&#39;est</li></ol>
-<ul><li>hehe</li></ul>
-<figure>
-<img alt="Ceci est ma pfp :3" src="https://cdn.anhgelus.world/pfp.jpg">
-<figcaption><a href="https://now.anhgelus.world/">Ma pfp</a> hehe :D Elle est <b>magnifique</b>, n&#39;est-ce pas ?</figcaption>
-</figure>
-`
-
-func TestAst(t *testing.T) {
- lxs := lex(raw)
- tree, err := ast(lxs)
- if err != nil {
- t.Fatal(err)
- }
- res, err := tree.Eval()
- if err != nil {
- t.Fatal(err)
- }
- wanted := strings.ReplaceAll(parsed, "\n", "")
- if string(res) != wanted {
- t.Errorf("invalid string, got\n%s", res)
- t.Logf("wanted\n%s", wanted)
- }
-}
diff --git a/mardown/error.go b/mardown/error.go
deleted file mode 100644
index ad279fe..0000000
--- a/mardown/error.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package mardown
-
-import "fmt"
-
-type ParseError struct {
- internal error
- lxs lexers
-}
-
-func (e *ParseError) Error() string {
- return e.internal.Error()
-}
-
-func (e *ParseError) Pretty() string {
- lxs := e.lxs
- if lxs.lexers == nil {
- return e.internal.Error()
- }
- current := lxs.current - 1
- for lxs.Before() && lxs.Current().Type != lexerBreak {
- }
- current -= lxs.current
- contxt := ""
- ind := ""
- for lxs.Next() && lxs.Current().Type != lexerBreak {
- contxt += lxs.Current().Value
- if lxs.current <= current {
- ch := "~"
- if lxs.current == current {
- ch = "^"
- }
- for range len(lxs.Current().Value) {
- ind += ch
- }
- }
- }
- if lxs.current == current {
- runes := []rune(ind)
- runes[len(runes)-1] = '^'
- ind = string(runes)
- }
- return fmt.Sprintf("%v\n\n%s\n%s", e, contxt, ind)
-}
diff --git a/mardown/error_test.go b/mardown/error_test.go
deleted file mode 100644
index bcf6143..0000000
--- a/mardown/error_test.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestError(t *testing.T) {
- v, err := Parse("**bonsoir")
- if err == nil {
- t.Errorf("expected error, got %s", v)
- } else {
- t.Log(err.Pretty())
- }
-
- v, err = Parse("bo*nso**ir")
- if err == nil {
- t.Errorf("expected error, got %s", v)
- } else {
- t.Log(err.Pretty())
- }
-
- v, err = Parse("test ``` hehe")
- if err == nil {
- t.Errorf("expected error, got %s", v)
- } else {
- t.Log(err.Pretty())
- }
-}
diff --git a/mardown/eval.go b/mardown/eval.go
deleted file mode 100644
index c085767..0000000
--- a/mardown/eval.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package mardown
-
-import "html/template"
-
-func Parse(s string) (template.HTML, *ParseError) {
- lxs := lex(s)
- tree, err := ast(lxs)
- if err != nil {
- return "", err
- }
- return tree.Eval()
-}
-
-func ParseBytes(b []byte) (template.HTML, *ParseError) {
- return Parse(string(b))
-}
diff --git a/mardown/lexer.go b/mardown/lexer.go
deleted file mode 100644
index c4ff988..0000000
--- a/mardown/lexer.go
+++ /dev/null
@@ -1,132 +0,0 @@
-package mardown
-
-import "fmt"
-
-type lexerType string
-
-const (
- lexerBreak lexerType = "break"
-
- lexerModifier lexerType = "modifier"
-
- lexerCode lexerType = "code"
-
- lexerHeader lexerType = "header"
- lexerQuote lexerType = "quote"
- lexerList lexerType = "list"
-
- lexerExternal lexerType = "external"
-
- lexerLiteral lexerType = "literal"
-)
-
-type lexer struct {
- Type lexerType
- Value string
-}
-
-func (l *lexer) String() string {
- return fmt.Sprintf("%s(%s)", l.Type, l.Value)
-}
-
-type lexers struct {
- current int
- lexers []lexer
-}
-
-func (l *lexers) Next() bool {
- l.current++
- return !l.Finished()
-}
-
-func (l *lexers) Current() lexer {
- return l.lexers[l.current]
-}
-
-func (l *lexers) Finished() bool {
- return l.current >= len(l.lexers)
-}
-
-func (l *lexers) Before() bool {
- l.current--
- return l.current >= 0 && !l.Finished()
-}
-
-func (l *lexers) String() string {
- s := "Lexers["
- for _, l := range l.lexers {
- s += l.String() + " "
- }
- return s + "]"
-}
-
-func lex(s string) *lexers {
- lxs := &lexers{current: -1}
- var lexs []lexer
- var currentType lexerType
- var previous string
- fn := func(c rune, t lexerType) {
- if currentType != t && len(previous) > 0 {
- lexs = append(lexs, lexer{Type: currentType, Value: previous})
- previous = ""
- }
- currentType = t
- previous += string(c)
- }
- newLine := true
- literalNext := false
- runes := []rune(s)
- for i, c := range runes {
- if literalNext {
- fn(c, lexerLiteral)
- literalNext = false
- continue
- }
- if c == '\\' {
- literalNext = true
- continue
- }
- switch c {
- case '*', '_':
- if c == '*' && newLine && i < len(runes)-1 && runes[i+1] == ' ' {
- fn(c, lexerList)
- } else {
- if (currentType != lexerModifier && len(previous) > 0) ||
- (len(previous) > 0 && []rune(previous)[0] != c) ||
- len(previous) >= 3 {
- lexs = append(lexs, lexer{Type: currentType, Value: previous})
- previous = ""
- }
- currentType = lexerModifier
- previous += string(c)
- }
- newLine = false
- case '`':
- newLine = false
- fn(c, lexerCode)
- case '\n':
- newLine = true
- fn(c, lexerBreak)
- case '#':
- newLine = false
- fn(c, lexerHeader)
- case '>':
- newLine = false
- fn(c, lexerQuote)
- case '[', ']', '(', ')', '!':
- newLine = false
- fn(c, lexerExternal)
- case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
- newLine = false
- fn(c, lexerList)
- default:
- newLine = false
- fn(c, lexerLiteral)
- }
- }
- if len(previous) > 0 {
- lexs = append(lexs, lexer{Type: currentType, Value: previous})
- }
- lxs.lexers = lexs
- return lxs
-}
diff --git a/mardown/lexer_test.go b/mardown/lexer_test.go
deleted file mode 100644
index 3ef87cc..0000000
--- a/mardown/lexer_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package mardown
-
-import "testing"
-
-func TestLex(t *testing.T) {
- lxs := lex("bonjour les gens")
- if lxs.String() != "Lexers[literal(bonjour les gens) ]" {
- t.Errorf("invalid lex, got %s", lxs)
- }
- lxs = lex("# bonjour les gens")
- if lxs.String() != "Lexers[header(#) literal( bonjour les gens) ]" {
- t.Errorf("invalid lex, got %s", lxs)
- }
- lxs = lex("# bonjour les gens\nComment ça va ?")
- if lxs.String() != "Lexers[header(#) literal( bonjour les gens) break(\n) literal(Comment ça va ?) ]" {
- t.Errorf("invalid lex, got %s", lxs)
- }
- lxs = lex("***hey***, what's up?")
- if lxs.String() != "Lexers[modifier(***) literal(hey) modifier(***) literal(, what's up?) ]" {
- t.Errorf("invalid lex, got %s", lxs)
- }
- lxs = lex(`Xxx\_DarkEmperor\_xxX`)
- if lxs.String() != `Lexers[literal(Xxx_DarkEmperor_xxX) ]` {
- t.Errorf("invalid lex, got %s", lxs)
- }
- lxs = lex(`* list`)
- if lxs.String() != `Lexers[list(*) literal( list) ]` {
- t.Errorf("invalid lex, got %s", lxs)
- }
-}