improved package api
This commit is contained in:
parent
f744089b62
commit
3c3ea3c767
31
adoc.go
31
adoc.go
|
@ -1,22 +1,29 @@
|
||||||
package adoc
|
package adoc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"io"
|
||||||
|
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/document"
|
||||||
|
"ewintr.nl/adoc/formatter"
|
||||||
|
"ewintr.nl/adoc/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ADoc struct {
|
func NewDocument() *document.Document {
|
||||||
Title string
|
return document.New()
|
||||||
Attributes map[string]string
|
|
||||||
Author string
|
|
||||||
Date time.Time
|
|
||||||
Content []element.Element
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *ADoc {
|
func NewParser(reader io.Reader) *parser.Parser {
|
||||||
return &ADoc{
|
return parser.New(reader)
|
||||||
Attributes: map[string]string{},
|
|
||||||
Content: []element.Element{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTextFormatter() *formatter.Text {
|
||||||
|
return formatter.NewText()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAsciiDocFormatter() *formatter.AsciiDoc {
|
||||||
|
return formatter.NewAsciiDoc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHTMLFormatter() *formatter.HTML {
|
||||||
|
return formatter.NewHTML()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package document
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ewintr.nl/adoc/element"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Document struct {
|
||||||
|
Title string
|
||||||
|
Attributes map[string]string
|
||||||
|
Author string
|
||||||
|
Date time.Time
|
||||||
|
Content []element.Element
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *Document {
|
||||||
|
return &Document{
|
||||||
|
Attributes: map[string]string{},
|
||||||
|
Content: []element.Element{},
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -14,13 +14,13 @@ func TestCodeBlock(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
exp *adoc.ADoc
|
exp *document.Document
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
input: `----
|
input: `----
|
||||||
----`,
|
----`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{element.CodeBlock{}},
|
Content: []element.Element{element.CodeBlock{}},
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,7 @@ code
|
||||||
|
|
||||||
more
|
more
|
||||||
----`,
|
----`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{element.CodeBlock{
|
Content: []element.Element{element.CodeBlock{
|
||||||
element.Word("code"),
|
element.Word("code"),
|
||||||
|
@ -48,7 +48,7 @@ more
|
||||||
code
|
code
|
||||||
----
|
----
|
||||||
`,
|
`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{element.CodeBlock{
|
Content: []element.Element{element.CodeBlock{
|
||||||
element.Word("code"),
|
element.Word("code"),
|
||||||
|
@ -63,7 +63,7 @@ code
|
||||||
|
|
||||||
more
|
more
|
||||||
`,
|
`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{
|
Content: []element.Element{
|
||||||
element.Paragraph{[]element.Element{
|
element.Paragraph{[]element.Element{
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -15,12 +15,12 @@ func TestHeader(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
exp *adoc.ADoc
|
exp *document.Document
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "just title",
|
name: "just title",
|
||||||
input: "= Title",
|
input: "= Title",
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Title: "Title",
|
Title: "Title",
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{},
|
Content: []element.Element{},
|
||||||
|
@ -29,7 +29,7 @@ func TestHeader(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "empty title",
|
name: "empty title",
|
||||||
input: "= ",
|
input: "= ",
|
||||||
exp: adoc.New(),
|
exp: document.New(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "full header",
|
name: "full header",
|
||||||
|
@ -40,7 +40,7 @@ Author Name
|
||||||
:key2: value2
|
:key2: value2
|
||||||
|
|
||||||
First paragraph`,
|
First paragraph`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Title: "Title with words",
|
Title: "Title with words",
|
||||||
Date: time.Date(2022, time.Month(3), 4, 0, 0, 0, 0, time.UTC),
|
Date: time.Date(2022, time.Month(3), 4, 0, 0, 0, 0, time.UTC),
|
||||||
Author: "Author Name",
|
Author: "Author Name",
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -49,7 +49,7 @@ func TestLink(t *testing.T) {
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
par := parser.New(strings.NewReader(tc.input))
|
par := parser.New(strings.NewReader(tc.input))
|
||||||
exp := &adoc.ADoc{
|
exp := &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: tc.exp,
|
Content: tc.exp,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -69,7 +69,7 @@ and some text`,
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
par := parser.New(strings.NewReader(tc.input))
|
par := parser.New(strings.NewReader(tc.input))
|
||||||
exp := &adoc.ADoc{
|
exp := &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: tc.exp,
|
Content: tc.exp,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -14,12 +14,12 @@ func TestParagraph(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
exp *adoc.ADoc
|
exp *document.Document
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "single paragraph",
|
name: "single paragraph",
|
||||||
input: "some text",
|
input: "some text",
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{
|
Content: []element.Element{
|
||||||
element.Paragraph{Elements: []element.Element{
|
element.Paragraph{Elements: []element.Element{
|
||||||
|
@ -36,7 +36,7 @@ func TestParagraph(t *testing.T) {
|
||||||
paragraph one
|
paragraph one
|
||||||
|
|
||||||
paragraph two`,
|
paragraph two`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Title: "Title",
|
Title: "Title",
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{
|
Content: []element.Element{
|
||||||
|
@ -61,7 +61,7 @@ two
|
||||||
|
|
||||||
three
|
three
|
||||||
`,
|
`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{
|
Content: []element.Element{
|
||||||
element.Paragraph{Elements: []element.Element{element.Word("one")}},
|
element.Paragraph{Elements: []element.Element{element.Word("one")}},
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -93,7 +93,7 @@ func TestStyles(t *testing.T) {
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
par := parser.New(strings.NewReader(tc.input))
|
par := parser.New(strings.NewReader(tc.input))
|
||||||
exp := &adoc.ADoc{
|
exp := &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: tc.exp,
|
Content: tc.exp,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -38,7 +38,7 @@ func TestSubTitle(t *testing.T) {
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
exp := &adoc.ADoc{
|
exp := &document.Document{
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: tc.exp,
|
Content: tc.exp,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package format
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Text(doc *adoc.ADoc) string {
|
|
||||||
txt := fmt.Sprintf("%s\n\n", doc.Title)
|
|
||||||
for _, el := range doc.Content {
|
|
||||||
txt += fmt.Sprintf("%s\n\n", el.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
return txt
|
|
||||||
}
|
|
|
@ -1,17 +1,23 @@
|
||||||
package format
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AsciiDoc(doc *adoc.ADoc) string {
|
type AsciiDoc struct{}
|
||||||
return fmt.Sprintf("%s\n%s", AsciiDocHeader(doc), AsciiDocFragment(doc.Content...))
|
|
||||||
|
func NewAsciiDoc() *AsciiDoc {
|
||||||
|
return &AsciiDoc{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsciiDocHeader(doc *adoc.ADoc) string {
|
func (ad *AsciiDoc) Format(doc *document.Document) string {
|
||||||
|
return fmt.Sprintf("%s\n%s", asciiDocHeader(doc), ad.FormatFragments(doc.Content...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func asciiDocHeader(doc *document.Document) string {
|
||||||
header := fmt.Sprintf("= %s\n", doc.Title)
|
header := fmt.Sprintf("= %s\n", doc.Title)
|
||||||
if doc.Author != "" {
|
if doc.Author != "" {
|
||||||
header += fmt.Sprintf("%s\n", doc.Author)
|
header += fmt.Sprintf("%s\n", doc.Author)
|
||||||
|
@ -26,16 +32,16 @@ func AsciiDocHeader(doc *adoc.ADoc) string {
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsciiDocFragment(els ...element.Element) string {
|
func (ad *AsciiDoc) FormatFragments(els ...element.Element) string {
|
||||||
var asciiDoc string
|
var asciiDoc string
|
||||||
for _, el := range els {
|
for _, el := range els {
|
||||||
asciiDoc += asciiDocElement(el)
|
asciiDoc += ad.asciiDocElement(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
return asciiDoc
|
return asciiDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
func asciiDocElement(el element.Element) string {
|
func (ad *AsciiDoc) asciiDocElement(el element.Element) string {
|
||||||
switch v := el.(type) {
|
switch v := el.(type) {
|
||||||
case element.SubTitle:
|
case element.SubTitle:
|
||||||
return fmt.Sprintf("== %s\n\n", v.Text())
|
return fmt.Sprintf("== %s\n\n", v.Text())
|
||||||
|
@ -46,19 +52,19 @@ func asciiDocElement(el element.Element) string {
|
||||||
for _, i := range v {
|
for _, i := range v {
|
||||||
items = append(items, i)
|
items = append(items, i)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s\n", AsciiDocFragment(items...))
|
return fmt.Sprintf("%s\n", ad.FormatFragments(items...))
|
||||||
case element.ListItem:
|
case element.ListItem:
|
||||||
return fmt.Sprintf("* %s\n", AsciiDocFragment(v...))
|
return fmt.Sprintf("* %s\n", ad.FormatFragments(v...))
|
||||||
case element.CodeBlock:
|
case element.CodeBlock:
|
||||||
return fmt.Sprintf("----\n%s\n----\n\n", v.Text())
|
return fmt.Sprintf("----\n%s\n----\n\n", v.Text())
|
||||||
case element.Paragraph:
|
case element.Paragraph:
|
||||||
return fmt.Sprintf("%s\n\n", AsciiDocFragment(v.Elements...))
|
return fmt.Sprintf("%s\n\n", ad.FormatFragments(v.Elements...))
|
||||||
case element.Strong:
|
case element.Strong:
|
||||||
return fmt.Sprintf("*%s*", AsciiDocFragment(v...))
|
return fmt.Sprintf("*%s*", ad.FormatFragments(v...))
|
||||||
case element.Emphasis:
|
case element.Emphasis:
|
||||||
return fmt.Sprintf("_%s_", AsciiDocFragment(v...))
|
return fmt.Sprintf("_%s_", ad.FormatFragments(v...))
|
||||||
case element.Code:
|
case element.Code:
|
||||||
return fmt.Sprintf("`%s`", AsciiDocFragment(v...))
|
return fmt.Sprintf("`%s`", ad.FormatFragments(v...))
|
||||||
case element.Link:
|
case element.Link:
|
||||||
return fmt.Sprintf("%s[%s]", v.URL, v.Title)
|
return fmt.Sprintf("%s[%s]", v.URL, v.Title)
|
||||||
case element.Word:
|
case element.Word:
|
|
@ -1,48 +1,46 @@
|
||||||
package format_test
|
package formatter_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/format"
|
"ewintr.nl/adoc/formatter"
|
||||||
"ewintr.nl/adoc/parser"
|
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAsciiDoc(t *testing.T) {
|
func TestAsciiDoc(t *testing.T) {
|
||||||
input := `= A Title
|
input := &document.Document{
|
||||||
|
Title: "A Title",
|
||||||
Some document
|
Author: "Author",
|
||||||
|
Date: time.Date(2022, time.Month(6), 11, 0, 0, 0, 0, time.UTC),
|
||||||
With some text.
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
doc := parser.New(strings.NewReader(input)).Parse()
|
|
||||||
test.Equals(t, input, format.AsciiDoc(doc))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAsciiDocHeader(t *testing.T) {
|
|
||||||
input := &adoc.ADoc{
|
|
||||||
Title: "title",
|
|
||||||
Author: "author",
|
|
||||||
Date: time.Date(2022, time.Month(6), 11, 12, 0, 0, 0, time.UTC),
|
|
||||||
Attributes: map[string]string{
|
Attributes: map[string]string{
|
||||||
"key1": "value 1",
|
"key1": "value 1",
|
||||||
"key2": "value 2",
|
"key2": "value 2",
|
||||||
},
|
},
|
||||||
|
Content: []element.Element{
|
||||||
|
element.Paragraph{
|
||||||
|
Elements: []element.Element{
|
||||||
|
element.Word("some"),
|
||||||
|
element.WhiteSpace(" "),
|
||||||
|
element.Word("text"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
exp := `= title
|
|
||||||
author
|
exp := `= A Title
|
||||||
|
Author
|
||||||
2022-06-11
|
2022-06-11
|
||||||
:key1: value 1
|
:key1: value 1
|
||||||
:key2: value 2
|
:key2: value 2
|
||||||
|
|
||||||
|
some text
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
test.Equals(t, exp, format.AsciiDocHeader(input))
|
test.Equals(t, exp, formatter.NewAsciiDoc().Format(input))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAsciiDocFragment(t *testing.T) {
|
func TestAsciiDocFragment(t *testing.T) {
|
||||||
|
@ -172,7 +170,7 @@ some text
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
test.Equals(t, tc.exp, format.AsciiDocFragment(tc.input))
|
test.Equals(t, tc.exp, formatter.NewAsciiDoc().FormatFragments(tc.input))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package formatter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ewintr.nl/adoc/document"
|
||||||
|
"ewintr.nl/adoc/element"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Formatter interface {
|
||||||
|
Format(doc *document.Document) string
|
||||||
|
FormatFragments(els ...element.Element) string
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
package format
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/go-kit/slugify"
|
"ewintr.nl/go-kit/slugify"
|
||||||
)
|
)
|
||||||
|
@ -19,20 +19,26 @@ const htmlPageTemplate = `<!DOCTYPE html>
|
||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
|
|
||||||
func HTML(doc *adoc.ADoc) string {
|
type HTML struct{}
|
||||||
return fmt.Sprintf(htmlPageTemplate, html.EscapeString(doc.Title), HTMLFragment(doc.Content...))
|
|
||||||
|
func NewHTML() *HTML {
|
||||||
|
return &HTML{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func HTMLFragment(els ...element.Element) string {
|
func (h *HTML) Format(doc *document.Document) string {
|
||||||
|
return fmt.Sprintf(htmlPageTemplate, html.EscapeString(doc.Title), h.FormatFragments(doc.Content...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTML) FormatFragments(els ...element.Element) string {
|
||||||
var html string
|
var html string
|
||||||
for _, el := range els {
|
for _, el := range els {
|
||||||
html += htmlElement(el)
|
html += h.htmlElement(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
func htmlElement(el element.Element) string {
|
func (h *HTML) htmlElement(el element.Element) string {
|
||||||
switch v := el.(type) {
|
switch v := el.(type) {
|
||||||
case element.SubTitle:
|
case element.SubTitle:
|
||||||
return fmt.Sprintf("<h2 id=%q>%s</h2>\n", slugify.Slugify(v.Text()), html.EscapeString(v.Text()))
|
return fmt.Sprintf("<h2 id=%q>%s</h2>\n", slugify.Slugify(v.Text()), html.EscapeString(v.Text()))
|
||||||
|
@ -43,19 +49,19 @@ func htmlElement(el element.Element) string {
|
||||||
for _, i := range v {
|
for _, i := range v {
|
||||||
items = append(items, i)
|
items = append(items, i)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("<ul>\n%s</ul>\n", HTMLFragment(items...))
|
return fmt.Sprintf("<ul>\n%s</ul>\n", h.FormatFragments(items...))
|
||||||
case element.ListItem:
|
case element.ListItem:
|
||||||
return fmt.Sprintf("<li>%s</li>\n", HTMLFragment(v...))
|
return fmt.Sprintf("<li>%s</li>\n", h.FormatFragments(v...))
|
||||||
case element.CodeBlock:
|
case element.CodeBlock:
|
||||||
return fmt.Sprintf("<pre><code>%s</code></pre>", html.EscapeString(v.Text()))
|
return fmt.Sprintf("<pre><code>%s</code></pre>", html.EscapeString(v.Text()))
|
||||||
case element.Paragraph:
|
case element.Paragraph:
|
||||||
return fmt.Sprintf("<p>%s</p>\n", HTMLFragment(v.Elements...))
|
return fmt.Sprintf("<p>%s</p>\n", h.FormatFragments(v.Elements...))
|
||||||
case element.Strong:
|
case element.Strong:
|
||||||
return fmt.Sprintf("<strong>%s</strong>", HTMLFragment(v...))
|
return fmt.Sprintf("<strong>%s</strong>", h.FormatFragments(v...))
|
||||||
case element.Emphasis:
|
case element.Emphasis:
|
||||||
return fmt.Sprintf("<em>%s</em>", HTMLFragment(v...))
|
return fmt.Sprintf("<em>%s</em>", h.FormatFragments(v...))
|
||||||
case element.Code:
|
case element.Code:
|
||||||
return fmt.Sprintf("<code>%s</code>", HTMLFragment(v...))
|
return fmt.Sprintf("<code>%s</code>", h.FormatFragments(v...))
|
||||||
case element.Link:
|
case element.Link:
|
||||||
return fmt.Sprintf("<a href=%q>%s</a>", v.URL, html.EscapeString(v.Title))
|
return fmt.Sprintf("<a href=%q>%s</a>", v.URL, html.EscapeString(v.Title))
|
||||||
case element.Word:
|
case element.Word:
|
|
@ -1,11 +1,11 @@
|
||||||
package format_test
|
package formatter_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/format"
|
"ewintr.nl/adoc/formatter"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
)
|
)
|
||||||
|
@ -29,7 +29,7 @@ With some text.`
|
||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
doc := parser.New(strings.NewReader(input)).Parse()
|
doc := parser.New(strings.NewReader(input)).Parse()
|
||||||
test.Equals(t, exp, format.HTML(doc))
|
test.Equals(t, exp, formatter.NewHTML().Format(doc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHTMLFragment(t *testing.T) {
|
func TestHTMLFragment(t *testing.T) {
|
||||||
|
@ -160,7 +160,7 @@ func TestHTMLFragment(t *testing.T) {
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
test.Equals(t, tc.exp, format.HTMLFragment(tc.input))
|
test.Equals(t, tc.exp, formatter.NewHTML().FormatFragments(tc.input))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package formatter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ewintr.nl/adoc/document"
|
||||||
|
"ewintr.nl/adoc/element"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Text struct{}
|
||||||
|
|
||||||
|
func NewText() *Text {
|
||||||
|
return &Text{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Text) Format(doc *document.Document) string {
|
||||||
|
txt := fmt.Sprintf("%s\n\n", doc.Title)
|
||||||
|
txt += t.FormatFragments(doc.Content...)
|
||||||
|
return txt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Text) FormatFragments(els ...element.Element) string {
|
||||||
|
var text string
|
||||||
|
for _, el := range els {
|
||||||
|
text += fmt.Sprintf("%s\n\n", el.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
package format_test
|
package formatter_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc/format"
|
"ewintr.nl/adoc/formatter"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
)
|
)
|
||||||
|
@ -25,5 +25,5 @@ With some text.
|
||||||
`
|
`
|
||||||
|
|
||||||
doc := parser.New(strings.NewReader(input)).Parse()
|
doc := parser.New(strings.NewReader(input)).Parse()
|
||||||
test.Equals(t, exp, format.Text(doc))
|
test.Equals(t, exp, formatter.NewText().Format(doc))
|
||||||
}
|
}
|
|
@ -3,13 +3,13 @@ package parser
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/token"
|
"ewintr.nl/adoc/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Parser struct {
|
type Parser struct {
|
||||||
doc *adoc.ADoc
|
doc *document.Document
|
||||||
tr *token.TokenReader
|
tr *token.TokenReader
|
||||||
els []element.Element
|
els []element.Element
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,13 @@ func New(reader io.Reader) *Parser {
|
||||||
|
|
||||||
func NewParserFromChannel(toks chan token.Token) *Parser {
|
func NewParserFromChannel(toks chan token.Token) *Parser {
|
||||||
return &Parser{
|
return &Parser{
|
||||||
doc: adoc.New(),
|
doc: document.New(),
|
||||||
tr: token.NewTokenReader(toks),
|
tr: token.NewTokenReader(toks),
|
||||||
els: []element.Element{},
|
els: []element.Element{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) Parse() *adoc.ADoc {
|
func (p *Parser) Parse() *document.Document {
|
||||||
result, ok := element.NewHeaderFromTokens(p.tr)
|
result, ok := element.NewHeaderFromTokens(p.tr)
|
||||||
if ok {
|
if ok {
|
||||||
if h, ok := result.Element.(element.Header); ok {
|
if h, ok := result.Element.(element.Header); ok {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/adoc"
|
"ewintr.nl/adoc/document"
|
||||||
"ewintr.nl/adoc/element"
|
"ewintr.nl/adoc/element"
|
||||||
"ewintr.nl/adoc/parser"
|
"ewintr.nl/adoc/parser"
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
|
@ -14,11 +14,11 @@ func TestParser(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
exp *adoc.ADoc
|
exp *document.Document
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
exp: adoc.New(),
|
exp: document.New(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "codeblock paragraph edge",
|
name: "codeblock paragraph edge",
|
||||||
|
@ -29,7 +29,7 @@ a code block
|
||||||
----
|
----
|
||||||
|
|
||||||
And then some text`,
|
And then some text`,
|
||||||
exp: &adoc.ADoc{
|
exp: &document.Document{
|
||||||
Title: "some title",
|
Title: "some title",
|
||||||
Attributes: map[string]string{},
|
Attributes: map[string]string{},
|
||||||
Content: []element.Element{
|
Content: []element.Element{
|
||||||
|
|
Loading…
Reference in New Issue