From 20c65ca373908f6e5cb916e3b6d9466ee029faa8 Mon Sep 17 00:00:00 2001
From: Judson Lester
Date: Wed, 6 Sep 2023 16:19:09 -0700
Subject: [PATCH] Adding linebreak stripping
---
README.md | 1 +
docker-compose.yaml | 2 +-
main.go | 11 ++-
pkg/mark/markdown.go | 9 ++-
pkg/mark/markdown_test.go | 72 +++++++++++++++----
pkg/mark/renderer/text.go | 71 ++++++++++++++++++
pkg/mark/testdata/codes-droph1.html | 20 ++++++
pkg/mark/testdata/codes-stripnewlines.html | 19 +++++
pkg/mark/testdata/header-droph1.html | 6 ++
pkg/mark/testdata/header-stripnewlines.html | 7 ++
.../testdata/issue-64-broken-link-droph1.html | 1 +
.../issue-64-broken-link-stripnewlines.html | 1 +
pkg/mark/testdata/links-droph1.html | 17 +++++
pkg/mark/testdata/links-stripnewlines.html | 17 +++++
pkg/mark/testdata/lists-droph1.html | 21 ++++++
pkg/mark/testdata/lists-stripnewlines.html | 21 ++++++
pkg/mark/testdata/macro-include-droph1.html | 6 ++
.../testdata/macro-include-stripnewlines.html | 2 +
pkg/mark/testdata/newlines-droph1.html | 10 +++
pkg/mark/testdata/newlines-stripnewlines.html | 8 +++
pkg/mark/testdata/pagelayout-droph1.html | 18 +++++
.../testdata/pagelayout-stripnewlines.html | 18 +++++
pkg/mark/testdata/quotes-droph1.html | 34 +++++++++
pkg/mark/testdata/quotes-stripnewlines.html | 33 +++++++++
pkg/mark/testdata/quotes.html | 4 ++
pkg/mark/testdata/quotes.md | 2 +
pkg/mark/testdata/table-droph1.html | 14 ++++
pkg/mark/testdata/table-stripnewlines.html | 14 ++++
pkg/mark/testdata/tags-droph1.html | 6 ++
pkg/mark/testdata/tags-stripnewlines.html | 3 +
30 files changed, 448 insertions(+), 20 deletions(-)
create mode 100644 pkg/mark/renderer/text.go
create mode 100644 pkg/mark/testdata/codes-droph1.html
create mode 100644 pkg/mark/testdata/codes-stripnewlines.html
create mode 100644 pkg/mark/testdata/header-droph1.html
create mode 100644 pkg/mark/testdata/header-stripnewlines.html
create mode 100644 pkg/mark/testdata/issue-64-broken-link-droph1.html
create mode 100644 pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
create mode 100644 pkg/mark/testdata/links-droph1.html
create mode 100644 pkg/mark/testdata/links-stripnewlines.html
create mode 100644 pkg/mark/testdata/lists-droph1.html
create mode 100644 pkg/mark/testdata/lists-stripnewlines.html
create mode 100644 pkg/mark/testdata/macro-include-droph1.html
create mode 100644 pkg/mark/testdata/macro-include-stripnewlines.html
create mode 100644 pkg/mark/testdata/newlines-droph1.html
create mode 100644 pkg/mark/testdata/newlines-stripnewlines.html
create mode 100644 pkg/mark/testdata/pagelayout-droph1.html
create mode 100644 pkg/mark/testdata/pagelayout-stripnewlines.html
create mode 100644 pkg/mark/testdata/quotes-droph1.html
create mode 100644 pkg/mark/testdata/quotes-stripnewlines.html
create mode 100644 pkg/mark/testdata/table-droph1.html
create mode 100644 pkg/mark/testdata/table-stripnewlines.html
create mode 100644 pkg/mark/testdata/tags-droph1.html
create mode 100644 pkg/mark/testdata/tags-stripnewlines.html
diff --git a/README.md b/README.md
index 4ef65cb..e73e80a 100644
--- a/README.md
+++ b/README.md
@@ -750,6 +750,7 @@ GLOBAL OPTIONS:
--dry-run resolve page and ancestry, show resulting HTML and exit. (default: false) [$MARK_DRY_RUN]
--edit-lock, -k lock page editing to current user only to prevent accidental manual edits over Confluence Web UI. (default: false) [$MARK_EDIT_LOCK]
--drop-h1, --h1_drop don't include the first H1 heading in Confluence output. (default: false) [$MARK_H1_DROP]
+ --strip-linebreak remove linebreaks inside of tags, to accomodate Confluence non-standard behavior (default: false)
--title-from-h1, --h1_title extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata. (default: false) [$MARK_H1_TITLE]
--minor-edit don't send notifications while updating Confluence page. (default: false) [$MARK_MINOR_EDIT]
--color value display logs in color. Possible values: auto, never. (default: "auto") [$MARK_COLOR]
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 7928355..0689b9b 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -23,7 +23,7 @@ services:
# Linux 32-bit
# - GOOS=linux
# - GOARCH=386
-
+
# Windows 64-bit
# - GOOS=windows
# - GOARCH=amd64
diff --git a/main.go b/main.go
index ff9b5f7..8f8f7f1 100644
--- a/main.go
+++ b/main.go
@@ -63,6 +63,13 @@ var flags = []cli.Flag{
Usage: "don't include the first H1 heading in Confluence output.",
EnvVars: []string{"MARK_H1_DROP"},
}),
+ altsrc.NewBoolFlag(&cli.BoolFlag{
+ Name: "strip-linebreaks",
+ Value: false,
+ Aliases: []string{"L"},
+ Usage: "remove linebreaks inside of tags, to accomodate non-standard Confluence behavior",
+ EnvVars: []string{"MARK_STRIP_LINEBREAK"},
+ }),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "title-from-h1",
Value: false,
@@ -383,7 +390,7 @@ func processFile(
)
}
- html, _ := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Float64("mermaid-scale"), cCtx.Bool("drop-h1"))
+ html, _ := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Float64("mermaid-scale"), cCtx.Bool("drop-h1"), cCtx.Bool("strip-linebreaks"))
fmt.Println(html)
os.Exit(0)
}
@@ -459,7 +466,7 @@ func processFile(
)
}
- html, inlineAttachments := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Float64("mermaid-scale"), cCtx.Bool("drop-h1"))
+ html, inlineAttachments := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Float64("mermaid-scale"), cCtx.Bool("drop-h1"), cCtx.Bool("strip-linebreaks"))
// Resolve attachements detected from markdown
_, err = attachment.ResolveAttachments(
diff --git a/pkg/mark/markdown.go b/pkg/mark/markdown.go
index f970257..996100d 100644
--- a/pkg/mark/markdown.go
+++ b/pkg/mark/markdown.go
@@ -26,11 +26,12 @@ type ConfluenceExtension struct {
MermaidProvider string
MermaidScale float64
DropFirstH1 bool
+ StripNewlines bool
Attachments []attachment.Attachment
}
// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
-func NewConfluenceExtension(stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool) *ConfluenceExtension {
+func NewConfluenceExtension(stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool, stripNewlines bool) *ConfluenceExtension {
return &ConfluenceExtension{
Config: html.NewConfig(),
Stdlib: stdlib,
@@ -38,6 +39,7 @@ func NewConfluenceExtension(stdlib *stdlib.Lib, path string, mermaidProvider str
MermaidProvider: mermaidProvider,
MermaidScale: mermaidScale,
DropFirstH1: dropFirstH1,
+ StripNewlines: stripNewlines,
Attachments: []attachment.Attachment{},
}
}
@@ -45,6 +47,7 @@ func NewConfluenceExtension(stdlib *stdlib.Lib, path string, mermaidProvider str
func (c *ConfluenceExtension) Extend(m goldmark.Markdown) {
m.Renderer().AddOptions(renderer.WithNodeRenderers(
+ util.Prioritized(crenderer.NewConfluenceTextRenderer(c.StripNewlines), 100),
util.Prioritized(crenderer.NewConfluenceBlockQuoteRenderer(), 100),
util.Prioritized(crenderer.NewConfluenceCodeBlockRenderer(c.Stdlib, c.Path), 100),
util.Prioritized(crenderer.NewConfluenceFencedCodeBlockRenderer(c.Stdlib, &c.Attachments, c.MermaidProvider, c.MermaidScale), 100),
@@ -61,10 +64,10 @@ func (c *ConfluenceExtension) Extend(m goldmark.Markdown) {
))
}
-func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool) (string, []attachment.Attachment) {
+func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidProvider string, mermaidScale float64, dropFirstH1 bool, stripNewlines bool) (string, []attachment.Attachment) {
log.Tracef(nil, "rendering markdown:\n%s", string(markdown))
- confluenceExtension := NewConfluenceExtension(stdlib, path, mermaidProvider, mermaidScale, dropFirstH1)
+ confluenceExtension := NewConfluenceExtension(stdlib, path, mermaidProvider, mermaidScale, dropFirstH1, stripNewlines)
converter := goldmark.New(
goldmark.WithExtensions(
diff --git a/pkg/mark/markdown_test.go b/pkg/mark/markdown_test.go
index 79edc82..eaf18cd 100644
--- a/pkg/mark/markdown_test.go
+++ b/pkg/mark/markdown_test.go
@@ -10,6 +10,24 @@ import (
"github.com/stretchr/testify/assert"
)
+func loadData(t *testing.T, filename, variant string) ([]byte, string, []byte) {
+ t.Helper()
+ basename := filepath.Base(filename)
+ testname := strings.TrimSuffix(basename, ".md")
+ htmlname := filepath.Join(filepath.Dir(filename), testname+variant+".html")
+
+ markdown, err := os.ReadFile(filename)
+ if err != nil {
+ panic(err)
+ }
+ html, err := os.ReadFile(htmlname)
+ if err != nil {
+ panic(err)
+ }
+
+ return markdown, htmlname, html
+}
+
func TestCompileMarkdown(t *testing.T) {
test := assert.New(t)
@@ -19,24 +37,50 @@ func TestCompileMarkdown(t *testing.T) {
}
for _, filename := range testcases {
- basename := filepath.Base(filename)
- testname := strings.TrimSuffix(basename, ".md")
- htmlname := filepath.Join(filepath.Dir(filename), testname+".html")
-
- markdown, err := os.ReadFile(filename)
- if err != nil {
- panic(err)
- }
- html, err := os.ReadFile(htmlname)
- if err != nil {
- panic(err)
- }
-
lib, err := stdlib.New(nil)
if err != nil {
panic(err)
}
- actual, _ := CompileMarkdown(markdown, lib, filename, "", 1.0, false)
+ markdown, htmlname, html := loadData(t, filename, "")
+ actual, _ := CompileMarkdown(markdown, lib, filename, "", 1.0, false, false)
+ test.EqualValues(string(html), actual, filename+" vs "+htmlname)
+ }
+}
+
+func TestCompileMarkdownDropH1(t *testing.T) {
+ test := assert.New(t)
+
+ testcases, err := filepath.Glob("testdata/*.md")
+ if err != nil {
+ panic(err)
+ }
+
+ for _, filename := range testcases {
+ lib, err := stdlib.New(nil)
+ if err != nil {
+ panic(err)
+ }
+ markdown, htmlname, html := loadData(t, filename, "-droph1")
+ actual, _ := CompileMarkdown(markdown, lib, filename, "", 1.0, true, false)
+ test.EqualValues(string(html), actual, filename+" vs "+htmlname)
+ }
+}
+
+func TestCompileMarkdownStripNewlines(t *testing.T) {
+ test := assert.New(t)
+
+ testcases, err := filepath.Glob("testdata/*.md")
+ if err != nil {
+ panic(err)
+ }
+
+ for _, filename := range testcases {
+ lib, err := stdlib.New(nil)
+ if err != nil {
+ panic(err)
+ }
+ markdown, htmlname, html := loadData(t, filename, "-stripnewlines")
+ actual, _ := CompileMarkdown(markdown, lib, filename, "", 1.0, false, true)
test.EqualValues(string(html), actual, filename+" vs "+htmlname)
}
}
diff --git a/pkg/mark/renderer/text.go b/pkg/mark/renderer/text.go
new file mode 100644
index 0000000..e7db208
--- /dev/null
+++ b/pkg/mark/renderer/text.go
@@ -0,0 +1,71 @@
+package renderer
+
+import (
+ "unicode/utf8"
+
+ //"github.com/kovetskiy/mark/pkg/mark/stdlib"
+ "github.com/yuin/goldmark/ast"
+ "github.com/yuin/goldmark/renderer"
+ "github.com/yuin/goldmark/renderer/html"
+ "github.com/yuin/goldmark/util"
+)
+
+type ConfluenceTextRenderer struct {
+ html.Config
+ softBreak rune
+}
+
+// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
+func NewConfluenceTextRenderer(stripNL bool, opts ...html.Option) renderer.NodeRenderer {
+ sb := '\n'
+ if stripNL {
+ sb = ' '
+ }
+ return &ConfluenceTextRenderer{
+ Config: html.NewConfig(),
+ softBreak: sb,
+ }
+}
+
+// RegisterFuncs implements NodeRenderer.RegisterFuncs .
+func (r *ConfluenceTextRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
+ reg.Register(ast.KindText, r.renderText)
+}
+
+func (r *ConfluenceTextRenderer) renderText(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+ if !entering {
+ return ast.WalkContinue, nil
+ }
+ n := node.(*ast.Text)
+ segment := n.Segment
+ if n.IsRaw() {
+ r.Writer.RawWrite(w, segment.Value(source))
+ } else {
+ value := segment.Value(source)
+ r.Writer.Write(w, value)
+ if n.HardLineBreak() || (n.SoftLineBreak() && r.HardWraps) {
+ if r.XHTML {
+ _, _ = w.WriteString("
\n")
+ } else {
+ _, _ = w.WriteString("
\n")
+ }
+ } else if n.SoftLineBreak() {
+ if r.EastAsianLineBreaks && len(value) != 0 {
+ sibling := node.NextSibling()
+ if sibling != nil && sibling.Kind() == ast.KindText {
+ if siblingText := sibling.(*ast.Text).Text(source); len(siblingText) != 0 {
+ thisLastRune := util.ToRune(value, len(value)-1)
+ siblingFirstRune, _ := utf8.DecodeRune(siblingText)
+ if !(util.IsEastAsianWideRune(thisLastRune) &&
+ util.IsEastAsianWideRune(siblingFirstRune)) {
+ _ = w.WriteByte(byte(r.softBreak))
+ }
+ }
+ }
+ } else {
+ _ = w.WriteByte(byte(r.softBreak))
+ }
+ }
+ }
+ return ast.WalkContinue, nil
+}
diff --git a/pkg/mark/testdata/codes-droph1.html b/pkg/mark/testdata/codes-droph1.html
new file mode 100644
index 0000000..733410b
--- /dev/null
+++ b/pkg/mark/testdata/codes-droph1.html
@@ -0,0 +1,20 @@
+inline
+falsebashfalsebashfalseunknownfalsetext
+text 2
+unknownfalseshfalseA b cbashtrueA b cctruenestedfalsefalsetruefalseB;
+ A-->C;
+ B-->D;
+ C-->D;]]>truetruemy mermaid graphB;
+ A-->C;
+ B-->D;
+ C-->D;]]>truefalsemy mermaid graphB;
+ A-->C;
+ B-->D;
+ C-->D;]]>
\ No newline at end of file
diff --git a/pkg/mark/testdata/codes-stripnewlines.html b/pkg/mark/testdata/codes-stripnewlines.html
new file mode 100644
index 0000000..63eff28
--- /dev/null
+++ b/pkg/mark/testdata/codes-stripnewlines.html
@@ -0,0 +1,19 @@
+inline
+falsebashfalsebashfalseunknownfalsetext text 2
+unknownfalseshfalseA b cbashtrueA b cctruenestedfalsefalsetruefalseB;
+ A-->C;
+ B-->D;
+ C-->D;]]>truetruemy mermaid graphB;
+ A-->C;
+ B-->D;
+ C-->D;]]>truefalsemy mermaid graphB;
+ A-->C;
+ B-->D;
+ C-->D;]]>
\ No newline at end of file
diff --git a/pkg/mark/testdata/header-droph1.html b/pkg/mark/testdata/header-droph1.html
new file mode 100644
index 0000000..c63a140
--- /dev/null
+++ b/pkg/mark/testdata/header-droph1.html
@@ -0,0 +1,6 @@
+b
+c
+d
+e
+f
+g
diff --git a/pkg/mark/testdata/header-stripnewlines.html b/pkg/mark/testdata/header-stripnewlines.html
new file mode 100644
index 0000000..566c4ae
--- /dev/null
+++ b/pkg/mark/testdata/header-stripnewlines.html
@@ -0,0 +1,7 @@
+a
+b
+c
+d
+e
+f
+g
diff --git a/pkg/mark/testdata/issue-64-broken-link-droph1.html b/pkg/mark/testdata/issue-64-broken-link-droph1.html
new file mode 100644
index 0000000..0d39ce8
--- /dev/null
+++ b/pkg/mark/testdata/issue-64-broken-link-droph1.html
@@ -0,0 +1 @@
+v71
diff --git a/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html b/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
new file mode 100644
index 0000000..0d39ce8
--- /dev/null
+++ b/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
@@ -0,0 +1 @@
+v71
diff --git a/pkg/mark/testdata/links-droph1.html b/pkg/mark/testdata/links-droph1.html
new file mode 100644
index 0000000..82fd040
--- /dev/null
+++ b/pkg/mark/testdata/links-droph1.html
@@ -0,0 +1,17 @@
+Use https://example.com
+Use aaa
+Use
+Use
+Use
+Use
+
+
+Use footnotes link
+
diff --git a/pkg/mark/testdata/links-stripnewlines.html b/pkg/mark/testdata/links-stripnewlines.html
new file mode 100644
index 0000000..82fd040
--- /dev/null
+++ b/pkg/mark/testdata/links-stripnewlines.html
@@ -0,0 +1,17 @@
+Use https://example.com
+Use aaa
+Use
+Use
+Use
+Use
+
+
+Use footnotes link
+
diff --git a/pkg/mark/testdata/lists-droph1.html b/pkg/mark/testdata/lists-droph1.html
new file mode 100644
index 0000000..af27c54
--- /dev/null
+++ b/pkg/mark/testdata/lists-droph1.html
@@ -0,0 +1,21 @@
+
+- dash 1-1
+- dash 1-2
+- dash 1-3
+
+- dash 1-3-1
+- dash 1-3-2
+- dash 1-3-3
+
+
+
+
+
+text
+
diff --git a/pkg/mark/testdata/lists-stripnewlines.html b/pkg/mark/testdata/lists-stripnewlines.html
new file mode 100644
index 0000000..af27c54
--- /dev/null
+++ b/pkg/mark/testdata/lists-stripnewlines.html
@@ -0,0 +1,21 @@
+
+- dash 1-1
+- dash 1-2
+- dash 1-3
+
+- dash 1-3-1
+- dash 1-3-2
+- dash 1-3-3
+
+
+
+
+
+text
+
diff --git a/pkg/mark/testdata/macro-include-droph1.html b/pkg/mark/testdata/macro-include-droph1.html
new file mode 100644
index 0000000..8d8ba05
--- /dev/null
+++ b/pkg/mark/testdata/macro-include-droph1.html
@@ -0,0 +1,6 @@
+bar
+
+true
+Attention
+This is an info!
+
diff --git a/pkg/mark/testdata/macro-include-stripnewlines.html b/pkg/mark/testdata/macro-include-stripnewlines.html
new file mode 100644
index 0000000..52e4af7
--- /dev/null
+++ b/pkg/mark/testdata/macro-include-stripnewlines.html
@@ -0,0 +1,2 @@
+bar
+ true Attention This is an info!
diff --git a/pkg/mark/testdata/newlines-droph1.html b/pkg/mark/testdata/newlines-droph1.html
new file mode 100644
index 0000000..b97e510
--- /dev/null
+++ b/pkg/mark/testdata/newlines-droph1.html
@@ -0,0 +1,10 @@
+one-1
+one-2
+two-1
+two-2
+three-1
+three-2
+space-1
+space-2
+2space-1
+2space-2
diff --git a/pkg/mark/testdata/newlines-stripnewlines.html b/pkg/mark/testdata/newlines-stripnewlines.html
new file mode 100644
index 0000000..2fd4dc0
--- /dev/null
+++ b/pkg/mark/testdata/newlines-stripnewlines.html
@@ -0,0 +1,8 @@
+one-1 one-2
+two-1
+two-2
+three-1
+three-2
+space-1 space-2
+2space-1
+2space-2
diff --git a/pkg/mark/testdata/pagelayout-droph1.html b/pkg/mark/testdata/pagelayout-droph1.html
new file mode 100644
index 0000000..66f5783
--- /dev/null
+++ b/pkg/mark/testdata/pagelayout-droph1.html
@@ -0,0 +1,18 @@
+
+
+
+More Content
+
+
+More Content
+
+
+Even More Content
+
+
+
+
+Still More Content
+
+
+
diff --git a/pkg/mark/testdata/pagelayout-stripnewlines.html b/pkg/mark/testdata/pagelayout-stripnewlines.html
new file mode 100644
index 0000000..66f5783
--- /dev/null
+++ b/pkg/mark/testdata/pagelayout-stripnewlines.html
@@ -0,0 +1,18 @@
+
+
+
+More Content
+
+
+More Content
+
+
+Even More Content
+
+
+
+
+Still More Content
+
+
+
diff --git a/pkg/mark/testdata/quotes-droph1.html b/pkg/mark/testdata/quotes-droph1.html
new file mode 100644
index 0000000..d8fdcdf
--- /dev/null
+++ b/pkg/mark/testdata/quotes-droph1.html
@@ -0,0 +1,34 @@
+First Heading
+true
+NOTES:
+
+- Note number one
+- Note number two
+
+
+a
+b
+
+Warn (Should not be picked as blockquote type)
+
+Second Heading
+true
+Warn
+
+- Warn bullet 1
+- Warn bullet 2
+
+
+
+- Regular list
+that runs long
+
+Third Heading
+true
+
+Test
+
+Simple Blockquote
+
+This paragraph is a simple blockquote
+
diff --git a/pkg/mark/testdata/quotes-stripnewlines.html b/pkg/mark/testdata/quotes-stripnewlines.html
new file mode 100644
index 0000000..7a43019
--- /dev/null
+++ b/pkg/mark/testdata/quotes-stripnewlines.html
@@ -0,0 +1,33 @@
+Main Heading
+First Heading
+true
+NOTES:
+
+- Note number one
+- Note number two
+
+
+a b
+
+Warn (Should not be picked as blockquote type)
+
+Second Heading
+true
+Warn
+
+- Warn bullet 1
+- Warn bullet 2
+
+
+
+- Regular list that runs long
+
+Third Heading
+true
+
+Test
+
+Simple Blockquote
+
+This paragraph is a simple blockquote
+
diff --git a/pkg/mark/testdata/quotes.html b/pkg/mark/testdata/quotes.html
index acb61d6..c1519c7 100644
--- a/pkg/mark/testdata/quotes.html
+++ b/pkg/mark/testdata/quotes.html
@@ -20,6 +20,10 @@ b
Warn bullet 2
+
+- Regular list
+that runs long
+
Third Heading
true
diff --git a/pkg/mark/testdata/quotes.md b/pkg/mark/testdata/quotes.md
index f6b9958..995f67f 100644
--- a/pkg/mark/testdata/quotes.md
+++ b/pkg/mark/testdata/quotes.md
@@ -19,6 +19,8 @@
> * Warn bullet 1
> * Warn bullet 2
+* Regular list
+ that runs long
## Third Heading
>
diff --git a/pkg/mark/testdata/table-droph1.html b/pkg/mark/testdata/table-droph1.html
new file mode 100644
index 0000000..9b4f80a
--- /dev/null
+++ b/pkg/mark/testdata/table-droph1.html
@@ -0,0 +1,14 @@
+
+
+
+| HEADER1 |
+HEADER2 |
+
+
+
+
+| row1 |
+row2 |
+
+
+
diff --git a/pkg/mark/testdata/table-stripnewlines.html b/pkg/mark/testdata/table-stripnewlines.html
new file mode 100644
index 0000000..9b4f80a
--- /dev/null
+++ b/pkg/mark/testdata/table-stripnewlines.html
@@ -0,0 +1,14 @@
+
+
+
+| HEADER1 |
+HEADER2 |
+
+
+
+
+| row1 |
+row2 |
+
+
+
diff --git a/pkg/mark/testdata/tags-droph1.html b/pkg/mark/testdata/tags-droph1.html
new file mode 100644
index 0000000..a5161db
--- /dev/null
+++ b/pkg/mark/testdata/tags-droph1.html
@@ -0,0 +1,6 @@
+bold
+bold
+vitalik
+vitalik
+strikethrough
+strikethrough
diff --git a/pkg/mark/testdata/tags-stripnewlines.html b/pkg/mark/testdata/tags-stripnewlines.html
new file mode 100644
index 0000000..cc0698b
--- /dev/null
+++ b/pkg/mark/testdata/tags-stripnewlines.html
@@ -0,0 +1,3 @@
+bold bold
+vitalik vitalik
+strikethrough strikethrough