simplify inline callback interface

This commit is contained in:
Russ Ross 2011-06-29 13:00:54 -06:00
parent 8b9cd447d7
commit 2aca667078
6 changed files with 70 additions and 110 deletions

61
html.go
View File

@ -374,12 +374,12 @@ func (options *Html) Paragraph(out *bytes.Buffer, text func() bool) {
out.WriteString("</p>\n")
}
func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) bool {
func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) {
if len(link) == 0 {
return false
return
}
if options.flags&HTML_SAFELINK != 0 && !isSafeLink(link) && kind != LINK_TYPE_EMAIL {
return false
return
}
out.WriteString("<a href=\"")
@ -404,44 +404,39 @@ func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) bool {
}
out.WriteString("</a>")
return true
}
func (options *Html) CodeSpan(out *bytes.Buffer, text []byte) bool {
func (options *Html) CodeSpan(out *bytes.Buffer, text []byte) {
out.WriteString("<code>")
attrEscape(out, text)
out.WriteString("</code>")
return true
}
func (options *Html) DoubleEmphasis(out *bytes.Buffer, text []byte) bool {
func (options *Html) DoubleEmphasis(out *bytes.Buffer, text []byte) {
if len(text) == 0 {
return false
return
}
out.WriteString("<strong>")
out.Write(text)
out.WriteString("</strong>")
return true
}
func (options *Html) Emphasis(out *bytes.Buffer, text []byte) bool {
func (options *Html) Emphasis(out *bytes.Buffer, text []byte) {
if len(text) == 0 {
return false
return
}
out.WriteString("<em>")
out.Write(text)
out.WriteString("</em>")
return true
}
func (options *Html) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) bool {
func (options *Html) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
if options.flags&HTML_SKIP_IMAGES != 0 {
return false
return
}
if len(link) == 0 {
return false
return
}
out.WriteString("<img src=\"")
attrEscape(out, link)
@ -456,22 +451,21 @@ func (options *Html) Image(out *bytes.Buffer, link []byte, title []byte, alt []b
out.WriteByte('"')
out.WriteString(options.closeTag)
return true
return
}
func (options *Html) LineBreak(out *bytes.Buffer) bool {
func (options *Html) LineBreak(out *bytes.Buffer) {
out.WriteString("<br")
out.WriteString(options.closeTag)
return true
}
func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) bool {
func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
if options.flags&HTML_SKIP_LINKS != 0 {
return false
return
}
if options.flags&HTML_SAFELINK != 0 && !isSafeLink(link) {
return false
return
}
out.WriteString("<a href=\"")
@ -483,44 +477,41 @@ func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content
out.WriteString("\">")
out.Write(content)
out.WriteString("</a>")
return true
return
}
func (options *Html) RawHtmlTag(out *bytes.Buffer, text []byte) bool {
func (options *Html) RawHtmlTag(out *bytes.Buffer, text []byte) {
if options.flags&HTML_SKIP_HTML != 0 {
return true
return
}
if options.flags&HTML_SKIP_STYLE != 0 && isHtmlTag(text, "style") {
return true
return
}
if options.flags&HTML_SKIP_LINKS != 0 && isHtmlTag(text, "a") {
return true
return
}
if options.flags&HTML_SKIP_IMAGES != 0 && isHtmlTag(text, "img") {
return true
return
}
out.Write(text)
return true
}
func (options *Html) TripleEmphasis(out *bytes.Buffer, text []byte) bool {
func (options *Html) TripleEmphasis(out *bytes.Buffer, text []byte) {
if len(text) == 0 {
return false
return
}
out.WriteString("<strong><em>")
out.Write(text)
out.WriteString("</em></strong>")
return true
}
func (options *Html) StrikeThrough(out *bytes.Buffer, text []byte) bool {
func (options *Html) StrikeThrough(out *bytes.Buffer, text []byte) {
if len(text) == 0 {
return false
return
}
out.WriteString("<del>")
out.Write(text)
out.WriteString("</del>")
return true
}
func (options *Html) Entity(out *bytes.Buffer, entity []byte) {

View File

@ -139,9 +139,7 @@ func inlineCodeSpan(parser *Parser, out *bytes.Buffer, data []byte, offset int)
}
// render the code span
if !parser.r.CodeSpan(out, data[fBegin:fEnd]) {
end = 0
}
parser.r.CodeSpan(out, data[fBegin:fEnd])
return end
@ -164,13 +162,8 @@ func inlineLineBreak(parser *Parser, out *bytes.Buffer, data []byte, offset int)
return 0
}
if parser.r.LineBreak(out) {
return 1
} else {
return 0
}
return 0
parser.r.LineBreak(out)
return 1
}
// '[': parse a link or an image
@ -415,8 +408,12 @@ func inlineLink(parser *Parser, out *bytes.Buffer, data []byte, offset int) int
uLink = uLinkBuf.Bytes()
}
// links need something to click on and somewhere to go
if len(uLink) == 0 || content.Len() == 0 {
return 0
}
// call the relevant rendering function
ret := false
if isImg {
outSize := out.Len()
outBytes := out.Bytes()
@ -424,15 +421,12 @@ func inlineLink(parser *Parser, out *bytes.Buffer, data []byte, offset int) int
out.Truncate(outSize - 1)
}
ret = parser.r.Image(out, uLink, title, content.Bytes())
parser.r.Image(out, uLink, title, content.Bytes())
} else {
ret = parser.r.Link(out, uLink, title, content.Bytes())
parser.r.Link(out, uLink, title, content.Bytes())
}
if ret {
return i
}
return 0
return i
}
// '<' when tags or autolinks are allowed
@ -440,21 +434,17 @@ func inlineLAngle(parser *Parser, out *bytes.Buffer, data []byte, offset int) in
data = data[offset:]
altype := LINK_TYPE_NOT_AUTOLINK
end := tagLength(data, &altype)
ret := false
if end > 2 {
if altype != LINK_TYPE_NOT_AUTOLINK {
var uLink bytes.Buffer
unescapeText(&uLink, data[1:end+1-2])
ret = parser.r.AutoLink(out, uLink.Bytes(), altype)
parser.r.AutoLink(out, uLink.Bytes(), altype)
} else {
ret = parser.r.RawHtmlTag(out, data[:end])
parser.r.RawHtmlTag(out, data[:end])
}
}
if !ret {
return 0
}
return end
}
@ -867,11 +857,8 @@ func inlineHelperEmph1(parser *Parser, out *bytes.Buffer, data []byte, c byte) i
var work bytes.Buffer
parser.parseInline(&work, data[:i])
if parser.r.Emphasis(out, work.Bytes()) {
return i + 1
} else {
return 0
}
parser.r.Emphasis(out, work.Bytes())
return i + 1
}
}
@ -891,19 +878,14 @@ func inlineHelperEmph2(parser *Parser, out *bytes.Buffer, data []byte, c byte) i
if i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {
var work bytes.Buffer
parser.parseInline(&work, data[:i])
success := false
// pick the right renderer
if c == '~' {
success = parser.r.StrikeThrough(out, work.Bytes())
parser.r.StrikeThrough(out, work.Bytes())
} else {
success = parser.r.DoubleEmphasis(out, work.Bytes())
}
if success {
return i + 2
} else {
return 0
parser.r.DoubleEmphasis(out, work.Bytes())
}
return i + 2
}
i++
}
@ -933,11 +915,8 @@ func inlineHelperEmph3(parser *Parser, out *bytes.Buffer, data []byte, offset in
var work bytes.Buffer
parser.parseInline(&work, data[:i])
if parser.r.TripleEmphasis(out, work.Bytes()) {
return i + 3
} else {
return 0
}
parser.r.TripleEmphasis(out, work.Bytes())
return i + 3
case (i+1 < len(data) && data[i+1] == c):
// double symbol found, hand over to emph1
length = inlineHelperEmph1(parser, out, origData[offset-2:], c)

View File

@ -276,7 +276,7 @@ func TestInlineLink(t *testing.T) {
"<p><a href=\"/bar/ title with no quotes\">foo with a title</a></p>\n",
"[foo]()\n",
"<p><a href=\"\">foo</a></p>\n",
"<p>[foo]()</p>\n",
"![foo](/bar/)\n",
"<p><img src=\"/bar/\" alt=\"foo\" />\n</p>\n",
@ -294,7 +294,7 @@ func TestInlineLink(t *testing.T) {
"<p><img src=\"/bar/ title with no quotes\" alt=\"foo with a title\" />\n</p>\n",
"![foo]()\n",
"<p>[foo]()</p>\n",
"<p>![foo]()</p>\n",
"[a link]\t(/with_a_tab/)\n",
"<p><a href=\"/with_a_tab/\">a link</a></p>\n",

View File

@ -151,7 +151,7 @@ func (options *Latex) TableCell(out *bytes.Buffer, text []byte, align int) {
out.Write(text)
}
func (options *Latex) AutoLink(out *bytes.Buffer, link []byte, kind int) bool {
func (options *Latex) AutoLink(out *bytes.Buffer, link []byte, kind int) {
out.WriteString("\\href{")
if kind == LINK_TYPE_EMAIL {
out.WriteString("mailto:")
@ -160,31 +160,27 @@ func (options *Latex) AutoLink(out *bytes.Buffer, link []byte, kind int) bool {
out.WriteString("}{")
out.Write(link)
out.WriteString("}")
return true
}
func (options *Latex) CodeSpan(out *bytes.Buffer, text []byte) bool {
func (options *Latex) CodeSpan(out *bytes.Buffer, text []byte) {
out.WriteString("\\texttt{")
escapeSpecialChars(out, text)
out.WriteString("}")
return true
}
func (options *Latex) DoubleEmphasis(out *bytes.Buffer, text []byte) bool {
func (options *Latex) DoubleEmphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\textbf{")
out.Write(text)
out.WriteString("}")
return true
}
func (options *Latex) Emphasis(out *bytes.Buffer, text []byte) bool {
func (options *Latex) Emphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\textit{")
out.Write(text)
out.WriteString("}")
return true
}
func (options *Latex) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) bool {
func (options *Latex) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
if bytes.HasPrefix(link, []byte("http://")) || bytes.HasPrefix(link, []byte("https://")) {
// treat it like a link
out.WriteString("\\href{")
@ -197,39 +193,33 @@ func (options *Latex) Image(out *bytes.Buffer, link []byte, title []byte, alt []
out.Write(link)
out.WriteString("}")
}
return true
}
func (options *Latex) LineBreak(out *bytes.Buffer) bool {
func (options *Latex) LineBreak(out *bytes.Buffer) {
out.WriteString(" \\\\\n")
return true
}
func (options *Latex) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) bool {
func (options *Latex) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
out.WriteString("\\href{")
out.Write(link)
out.WriteString("}{")
out.Write(content)
out.WriteString("}")
return true
}
func (options *Latex) RawHtmlTag(out *bytes.Buffer, tag []byte) bool {
return true
func (options *Latex) RawHtmlTag(out *bytes.Buffer, tag []byte) {
}
func (options *Latex) TripleEmphasis(out *bytes.Buffer, text []byte) bool {
func (options *Latex) TripleEmphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\textbf{\\textit{")
out.Write(text)
out.WriteString("}}")
return true
}
func (options *Latex) StrikeThrough(out *bytes.Buffer, text []byte) bool {
func (options *Latex) StrikeThrough(out *bytes.Buffer, text []byte) {
out.WriteString("\\sout{")
out.Write(text)
out.WriteString("}")
return true
}
func needsBackslash(c byte) bool {

View File

@ -114,17 +114,17 @@ type Renderer interface {
TableRow(out *bytes.Buffer, text []byte)
TableCell(out *bytes.Buffer, text []byte, flags int)
// Span-level callbacks---return false prints the span verbatim
AutoLink(out *bytes.Buffer, link []byte, kind int) bool
CodeSpan(out *bytes.Buffer, text []byte) bool
DoubleEmphasis(out *bytes.Buffer, text []byte) bool
Emphasis(out *bytes.Buffer, text []byte) bool
Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) bool
LineBreak(out *bytes.Buffer) bool
Link(out *bytes.Buffer, link []byte, title []byte, content []byte) bool
RawHtmlTag(out *bytes.Buffer, tag []byte) bool
TripleEmphasis(out *bytes.Buffer, text []byte) bool
StrikeThrough(out *bytes.Buffer, text []byte) bool
// Span-level callbacks
AutoLink(out *bytes.Buffer, link []byte, kind int)
CodeSpan(out *bytes.Buffer, text []byte)
DoubleEmphasis(out *bytes.Buffer, text []byte)
Emphasis(out *bytes.Buffer, text []byte)
Image(out *bytes.Buffer, link []byte, title []byte, alt []byte)
LineBreak(out *bytes.Buffer)
Link(out *bytes.Buffer, link []byte, title []byte, content []byte)
RawHtmlTag(out *bytes.Buffer, tag []byte)
TripleEmphasis(out *bytes.Buffer, text []byte)
StrikeThrough(out *bytes.Buffer, text []byte)
// Low-level callbacks
Entity(out *bytes.Buffer, entity []byte)

View File

@ -8,4 +8,4 @@
<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
<p><a href="">Empty</a>.</p>
<p>[Empty]().</p>