diff --git a/renderer.go b/renderer.go
index 9eeae6c..01e7aba 100644
--- a/renderer.go
+++ b/renderer.go
@@ -2,6 +2,7 @@
package markdown
import (
+ "bytes"
"fmt"
"strings"
@@ -59,10 +60,10 @@ func (r *Renderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
// inlines
reg.Register(ast.KindText, r.renderText)
reg.Register(ast.KindLink, r.renderLink)
+ reg.Register(ast.KindCodeSpan, r.renderCodeSpan)
/* TODO
reg.Register(ast.KindString, r.renderString)
reg.Register(ast.KindAutoLink, r.renderAutoLink)
- reg.Register(ast.KindCodeSpan, r.renderCodeSpan)
reg.Register(ast.KindEmphasis, r.renderEmphasis)
reg.Register(ast.KindImage, r.renderImage)
reg.Register(ast.KindRawHTML, r.renderRawHTML)
@@ -248,7 +249,13 @@ func (r *Renderer) renderListItem(w util.BufWriter, source []byte, node ast.Node
func (r *Renderer) renderText(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.Text)
if entering {
- r.writer.Write(w, n.Text(source))
+ text := n.Text(source)
+
+ if r.rc.inCodeSpan {
+ text = bytes.ReplaceAll(text, []byte("\n"), []byte(" "))
+ }
+
+ r.writer.Write(w, text)
if n.SoftLineBreak() {
r.writer.WriteString(w, "\n")
}
@@ -272,11 +279,29 @@ func (r *Renderer) renderLink(w util.BufWriter, source []byte, node ast.Node, en
return ast.WalkContinue, nil
}
+func (r *Renderer) renderCodeSpan(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+ if bytes.Count(node.Text(source), []byte("`"))%2 != 0 {
+ r.writer.WriteString(w, "``")
+ } else {
+ r.writer.WriteString(w, "`")
+ }
+
+ if entering {
+ r.rc.inCodeSpan = true
+ } else {
+ r.rc.inCodeSpan = false
+ }
+
+ return ast.WalkContinue, nil
+}
+
type renderContext struct {
// listIndent is the current indentation level for List
listIndent int
// listMarker is the marker character used for the current list
listMarker byte
+ // inCodeSpan is true if inside a code span
+ inCodeSpan bool
}
// renderWriter wraps util.BufWriter methods to implement error handling.
diff --git a/renderer_test.go b/renderer_test.go
index 1a3cd44..9c88022 100644
--- a/renderer_test.go
+++ b/renderer_test.go
@@ -130,6 +130,129 @@ func TestRenderedOutput(t *testing.T) {
"\tfoo\n\tbar\n\tbaz",
" foo\n bar\n baz\n",
},
+ // Code Span
+ {
+ "Simple code span",
+ []Option{},
+ "`foo`",
+ "`foo`\n",
+ },
+ {
+ "Two-backtick code span",
+ []Option{},
+ "``foo ` bar``",
+ "``foo ` bar``\n",
+ },
+ {
+ "Code span stripping leading and trailing spaces",
+ []Option{},
+ "` `` `",
+ "````\n",
+ },
+ {
+ "Code span stripping one space",
+ []Option{},
+ "` `` `",
+ "` `` `\n",
+ },
+ {
+ "Unstrippable left space only",
+ []Option{},
+ "` a`",
+ "` a`\n",
+ },
+ {
+ "Unstrippable only spaces",
+ []Option{},
+ "` `\n` `",
+ "` `\n` `\n",
+ },
+ {
+ "Multiple line-endings treated as spaces",
+ []Option{},
+ "``\nfoo\nbar \nbaz\n``",
+ "`foo bar baz`\n",
+ },
+ {
+ "Line-ending treated as space",
+ []Option{},
+ "``\nfoo \n``",
+ "`foo `\n",
+ },
+ {
+ "Interior spaces are not collapsed",
+ []Option{},
+ "`foo bar \nbaz`",
+ "`foo bar baz`\n",
+ },
+ {
+ "Backlashes are treated literally",
+ []Option{},
+ "`foo\\`bar`",
+ "`foo\\`bar`\n",
+ },
+ {
+ "Two backticks act as delimiters",
+ []Option{},
+ "``foo`bar``",
+ "``foo`bar``\n",
+ },
+ {
+ "Two backtics inside single ones with spaces trimmed",
+ []Option{},
+ "` foo `` bar `",
+ "`foo `` bar`\n",
+ },
+ {
+ "Codespan backticks have precedence over emphasis",
+ []Option{},
+ "*foo`*`",
+ "*foo`*`\n",
+ },
+ {
+ "Codespan backticks have equal precedence with HTML",
+ []Option{},
+ "``",
+ "``\n",
+ },
+ // TODO: panic upstream
+ // {
+ // "HTML tag with backtick",
+ // []Option{},
+ // "`",
+ // "`",
+ // },
+ {
+ "Autolink split by a backtick",
+ []Option{},
+ "``",
+ "``\n",
+ },
+ // TODO: panic upstream
+ // {
+ // "Autolink with a backtick",
+ // []Option{},
+ // "`",
+ // "`\n",
+ // },
+ {
+ "Unbalanced 3-2 backticks remain intact",
+ []Option{},
+ "```foo``",
+ "```foo``\n",
+ },
+ {
+ "Unbalanced 1-0 backticks remain intact",
+ []Option{},
+ "`foo",
+ "`foo\n",
+ },
+ {
+ "Unbalanced double backticks",
+ []Option{},
+ "`foo``bar``",
+ "`foo`bar`\n",
+ },
// Paragraph
{
"Simple paragraph",