Skip to content
This repository was archived by the owner on Nov 10, 2020. It is now read-only.

Commit 8bc485b

Browse files
committed
Stringify the ial on per renderer basis
Move this to the render backend, because there are subtle difference between the backends. Largish cleanup of the whole thing.
1 parent e07fcb3 commit 8bc485b

File tree

8 files changed

+174
-110
lines changed

8 files changed

+174
-110
lines changed

block.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int {
410410
}
411411
}
412412

413-
p.r.SetInlineAttr(p.ial)
413+
p.r.SetAttr(p.ial)
414414
p.ial = nil
415415

416416
p.r.Header(out, work, level, id)
@@ -569,7 +569,7 @@ func (p *parser) specialHeader(out *bytes.Buffer, data []byte) int {
569569
p.inline(out, data[i:end])
570570
return true
571571
}
572-
p.r.SetInlineAttr(p.ial)
572+
p.r.SetAttr(p.ial)
573573
p.ial = nil
574574

575575
name := bytes.ToLower(data[i:end])
@@ -673,7 +673,7 @@ func (p *parser) partHeader(out *bytes.Buffer, data []byte) int {
673673
}
674674
}
675675

676-
p.r.SetInlineAttr(p.ial)
676+
p.r.SetAttr(p.ial)
677677
p.ial = nil
678678

679679
p.r.Part(out, work, id)
@@ -829,7 +829,7 @@ func (p *parser) renderHTMLBlock(out *bytes.Buffer, data []byte, start int, doRe
829829
// var cooked bytes.Buffer
830830
// p.inline(&cooked, data[:end])
831831

832-
p.r.SetInlineAttr(p.ial)
832+
p.r.SetAttr(p.ial)
833833
p.ial = nil
834834

835835
p.r.CommentHtml(out, data[:end])
@@ -1238,7 +1238,7 @@ func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int {
12381238
}
12391239

12401240
if doRender {
1241-
p.r.SetInlineAttr(p.ial)
1241+
p.r.SetAttr(p.ial)
12421242
p.ial = nil
12431243
if co != "" {
12441244
var callout bytes.Buffer
@@ -1312,7 +1312,7 @@ func (p *parser) table(out *bytes.Buffer, data []byte) int {
13121312
}
13131313
}
13141314

1315-
p.r.SetInlineAttr(p.ial)
1315+
p.r.SetAttr(p.ial)
13161316
p.ial = nil
13171317

13181318
p.r.Table(out, header.Bytes(), body.Bytes(), footer.Bytes(), columns, caption.Bytes())
@@ -1446,7 +1446,7 @@ func (p *parser) blockTable(out *bytes.Buffer, data []byte) int {
14461446
p.inline(&caption, data[i+7:j-1]) // +7 for 'Table: '
14471447
}
14481448

1449-
p.r.SetInlineAttr(p.ial)
1449+
p.r.SetAttr(p.ial)
14501450
p.ial = nil
14511451

14521452
p.r.Table(out, header.Bytes(), body.Bytes(), footer.Bytes(), columns, caption.Bytes())
@@ -1793,7 +1793,7 @@ func (p *parser) code(out *bytes.Buffer, data []byte) int {
17931793
co = p.ial.Value("callout")
17941794
}
17951795

1796-
p.r.SetInlineAttr(p.ial)
1796+
p.r.SetAttr(p.ial)
17971797
p.ial = nil
17981798

17991799
var capb bytes.Buffer
@@ -2055,7 +2055,7 @@ func (p *parser) list(out *bytes.Buffer, data []byte, flags, start int, group []
20552055
}
20562056
}
20572057

2058-
p.r.SetInlineAttr(p.ial)
2058+
p.r.SetAttr(p.ial)
20592059
p.ial = nil
20602060

20612061
if p.insideList > 1 {
@@ -2340,7 +2340,7 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
23402340
for prev < eol && data[prev] == ' ' {
23412341
prev++
23422342
}
2343-
for eol > prev && data[eol-1] == ' ' {
2343+
for eol > prev && data[eol-1] == ' ' {
23442344
eol--
23452345
}
23462346

@@ -2359,7 +2359,7 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
23592359
id = createSanitizedAnchorName(string(data[prev:eol]))
23602360
}
23612361

2362-
p.r.SetInlineAttr(p.ial)
2362+
p.r.SetAttr(p.ial)
23632363
p.ial = nil
23642364

23652365
p.r.Header(out, work, level, id)

html.go

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ func HtmlRendererWithParameters(flags int, css, head string, renderParameters Ht
107107
renderParameters.FootnoteReturnLinkContents = `<sup>[return]</sup>`
108108
}
109109

110-
anchorOrID = "id" // use id= when seeing #id. Also see ial.go
111-
112110
return &html{
113111
flags: flags,
114112
closeTag: closeTag,
@@ -259,7 +257,7 @@ func (options *html) Part(out *bytes.Buffer, text func() bool, id string) {
259257
}
260258

261259
func (options *html) Note(out *bytes.Buffer, text func() bool, id string) {
262-
options.inlineAttr() //reset the IAL
260+
options.Attr() //reset the IAL
263261
if id != "" {
264262
out.WriteString(fmt.Sprintf("<h1 class=\"note\" id=\"%s\">", id))
265263
} else {
@@ -270,7 +268,7 @@ func (options *html) Note(out *bytes.Buffer, text func() bool, id string) {
270268
}
271269

272270
func (options *html) SpecialHeader(out *bytes.Buffer, what []byte, text func() bool, id string) {
273-
options.inlineAttr() //reset the IAL
271+
options.Attr() //reset the IAL
274272
if id != "" {
275273
out.WriteString(fmt.Sprintf("<h1 class=\""+string(what)+"\" id=\"%s\">", id))
276274
} else {
@@ -284,13 +282,13 @@ func (options *html) Header(out *bytes.Buffer, text func() bool, level int, id s
284282
marker := out.Len()
285283
doubleSpace(out)
286284

287-
ial := options.inlineAttr()
285+
ial := options.Attr()
288286
ial.GetOrDefaultId(id)
289287
if options.appendix {
290288
ial.GetOrDefaultClass("appendix")
291289
}
292290

293-
out.WriteString(fmt.Sprintf("<h%d%s>", level, ial.String()))
291+
out.WriteString(fmt.Sprintf("<h%d%s>", level, options.AttrString(ial)))
294292

295293
if !text() {
296294
out.Truncate(marker)
@@ -346,13 +344,13 @@ func (options *html) CalloutText(out *bytes.Buffer, id string, ids []string) {
346344
}
347345

348346
func (options *html) BlockCode(out *bytes.Buffer, text []byte, lang string, caption []byte, subfigure, callout bool) {
349-
ial := options.inlineAttr()
347+
ial := options.Attr()
350348
doubleSpace(out)
351349

352350
prefix := ial.Value("prefix")
353351
ial.DropAttr("prefix") // it's a fake attribute, so drop it
354352
ial.DropAttr("callout") // it's a fake attribute, so drop it
355-
s := ial.String()
353+
s := options.AttrString(ial)
356354

357355
text = blockCodePrefix(prefix, text)
358356

@@ -403,13 +401,13 @@ func (options *html) BlockCode(out *bytes.Buffer, text []byte, lang string, capt
403401

404402
func (options *html) BlockQuote(out *bytes.Buffer, text []byte, attribution []byte) {
405403
// attribution can potentially be split on --: meta -- who
406-
ial := options.inlineAttr()
404+
ial := options.Attr()
407405
parts := bytes.Split(attribution, []byte("--"))
408406
for _, p := range parts {
409407
bytes.TrimSpace(p)
410408
}
411409
doubleSpace(out)
412-
out.WriteString("<blockquote" + ial.String() + ">\n")
410+
out.WriteString("<blockquote" + options.AttrString(ial) + ">\n")
413411
out.Write(text)
414412
if len(parts) == 2 {
415413
out.WriteString("<footer>")
@@ -434,10 +432,10 @@ func (options *html) Aside(out *bytes.Buffer, text []byte) {
434432
}
435433

436434
func (options *html) Table(out *bytes.Buffer, header []byte, body []byte, footer []byte, columnData []int, caption []byte) {
437-
ial := options.inlineAttr()
435+
ial := options.Attr()
438436

439437
doubleSpace(out)
440-
out.WriteString("<table" + ial.String() + ">\n")
438+
out.WriteString("<table" + options.AttrString(ial) + ">\n")
441439
if len(caption) > 0 {
442440
out.WriteString("<caption>\n")
443441
out.Write(caption)
@@ -551,7 +549,7 @@ func (options *html) List(out *bytes.Buffer, text func() bool, flags, start int,
551549
marker := out.Len()
552550
doubleSpace(out)
553551

554-
ial := options.inlineAttr()
552+
ial := options.Attr()
555553
if start > 1 {
556554
ial.GetOrDefaultAttr("start", strconv.Itoa(start))
557555
}
@@ -576,11 +574,11 @@ func (options *html) List(out *bytes.Buffer, text func() bool, flags, start int,
576574
ial.GetOrDefaultAttr("type", "I")
577575
}
578576
}
579-
out.WriteString("<ol" + ial.String() + ">")
577+
out.WriteString("<ol" + options.AttrString(ial) + ">")
580578
case flags&_LIST_TYPE_DEFINITION != 0:
581-
out.WriteString("<dl" + ial.String() + ">")
579+
out.WriteString("<dl" + options.AttrString(ial) + ">")
582580
default:
583-
out.WriteString("<ul" + ial.String() + ">")
581+
out.WriteString("<ul" + options.AttrString(ial) + ">")
584582
}
585583
if !text() {
586584
out.Truncate(marker)
@@ -636,8 +634,8 @@ func (options *html) Paragraph(out *bytes.Buffer, text func() bool, flags int) {
636634
}
637635

638636
func (options *html) Math(out *bytes.Buffer, text []byte, display bool) {
639-
ial := options.inlineAttr()
640-
s := ial.String()
637+
ial := options.Attr()
638+
s := options.AttrString(ial)
641639
oTag := "\\("
642640
cTag := "\\)"
643641
if display {
@@ -739,7 +737,8 @@ func (options *html) maybeWriteAbsolutePrefix(out *bytes.Buffer, link []byte) {
739737
}
740738

741739
func (options *html) Figure(out *bytes.Buffer, text []byte, caption []byte) {
742-
s := options.inlineAttr().String()
740+
ial := options.Attr()
741+
s := options.AttrString(ial)
743742
out.WriteString("<figure role=\"group\"" + s + ">\n")
744743
out.WriteString("<figcaption>")
745744
out.Write(caption)
@@ -752,7 +751,8 @@ func (options *html) Image(out *bytes.Buffer, link []byte, title []byte, alt []b
752751
if options.flags&HTML_SKIP_IMAGES != 0 {
753752
return
754753
}
755-
s := options.inlineAttr().String()
754+
ial := options.Attr()
755+
s := options.AttrString(ial)
756756
if subfigure {
757757
s += " role=\"group\""
758758
}
@@ -1146,17 +1146,43 @@ func (options *html) TocFinalize() {
11461146
}
11471147
}
11481148

1149-
func (options *html) SetInlineAttr(i *inlineAttr) {
1149+
func (options *html) SetAttr(i *inlineAttr) {
11501150
options.ial = i
11511151
}
11521152

1153-
func (options *html) inlineAttr() *inlineAttr {
1153+
func (options *html) Attr() *inlineAttr {
11541154
if options.ial == nil {
11551155
return newInlineAttr()
11561156
}
11571157
return options.ial
11581158
}
11591159

1160+
func (options *html) AttrString(i *inlineAttr) string {
1161+
if i == nil {
1162+
return ""
1163+
}
1164+
s := ""
1165+
if i.id != "" {
1166+
s = " id=\"" + i.id + "\""
1167+
}
1168+
1169+
keys := i.SortClasses()
1170+
if len(keys) > 0 {
1171+
s += " class=\"" + strings.Join(keys, " ") + "\""
1172+
}
1173+
1174+
keys = i.SortAttributes()
1175+
attr := make([]string, len(keys))
1176+
for j, k := range keys {
1177+
v := i.attr[k]
1178+
attr[j] = k + "=\"" + v + "\""
1179+
}
1180+
if len(keys) > 0 {
1181+
s += " " + strings.Join(attr, " ")
1182+
}
1183+
return s
1184+
}
1185+
11601186
func isHtmlTag(tag []byte, tagname string) bool {
11611187
found, _ := findHtmlTagPos(tag, tagname)
11621188
return found

ial.go

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@ package mmark
55
import (
66
"bytes"
77
"sort"
8-
"strings"
98
)
109

11-
// Do we return an anchor= when we see an #id or an id=
12-
var anchorOrID = "anchor"
13-
1410
// One or more of these can be attached to block elements
1511
type inlineAttr struct {
1612
id string // #id
@@ -131,41 +127,22 @@ func (i *inlineAttr) add(j *inlineAttr) *inlineAttr {
131127
return i
132128
}
133129

134-
// String renders an IAL and returns a string that can be included in the tag:
135-
// class="class" anchor="id" key="value". The string s has a space as the first character.k
136-
func (i *inlineAttr) String() (s string) {
137-
if i == nil {
138-
return ""
139-
}
140-
141-
// some fluff needed to make this all sorted.
142-
if i.id != "" {
143-
s = " " + anchorOrID + "=\"" + i.id + "\""
144-
}
145-
130+
func (i *inlineAttr) SortClasses() []string {
146131
keys := make([]string, 0, len(i.class))
147132
for k := range i.class {
148133
keys = append(keys, k)
149134
}
150135
sort.Strings(keys)
151-
if len(keys) > 0 {
152-
s += " class=\"" + strings.Join(keys, " ") + "\""
153-
}
136+
return keys
137+
}
154138

155-
keys = keys[:0]
139+
func (i *inlineAttr) SortAttributes() []string {
140+
keys := make([]string, 0, len(i.attr))
156141
for k := range i.attr {
157142
keys = append(keys, k)
158143
}
159144
sort.Strings(keys)
160-
attr := make([]string, len(keys))
161-
for j, k := range keys {
162-
v := i.attr[k]
163-
attr[j] = k + "=\"" + v + "\""
164-
}
165-
if len(keys) > 0 {
166-
s += " " + strings.Join(attr, " ")
167-
}
168-
return s
145+
return keys
169146
}
170147

171148
// GetOrDefaultAttr sets the value under key if is is not set or

inline.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int {
689689
var cooked bytes.Buffer
690690
p.inline(&cooked, title)
691691

692-
p.r.SetInlineAttr(p.ial)
692+
p.r.SetAttr(p.ial)
693693
p.ial = nil
694694
p.r.Image(out, uLink, cooked.Bytes(), content.Bytes(), p.insideFigure)
695695

@@ -1670,7 +1670,7 @@ func math(p *parser, out *bytes.Buffer, data []byte, offset int) int {
16701670
return 0
16711671
}
16721672
if p.displayMath {
1673-
p.r.SetInlineAttr(p.ial)
1673+
p.r.SetAttr(p.ial)
16741674
p.ial = nil
16751675
}
16761676
p.r.Math(out, data[i+1:end-2], p.displayMath)

markdown.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,12 @@ type Renderer interface {
242242
// Helper functions
243243
Flags() int
244244

245-
SetInlineAttr(*inlineAttr)
246-
inlineAttr() *inlineAttr
245+
// Attr returns the inline attribute.
246+
Attr() *inlineAttr
247+
// SetAttr set the inline attribute.
248+
SetAttr(*inlineAttr)
249+
// AttrString return the string representation of this inline attribute.
250+
AttrString(*inlineAttr) string
247251
}
248252

249253
// Callback functions for inline parsing. One such function is defined
@@ -1011,7 +1015,7 @@ func (p *parser) codeInclude(out *bytes.Buffer, data []byte) int {
10111015
co = p.ial.Value("callout")
10121016
}
10131017

1014-
p.r.SetInlineAttr(p.ial)
1018+
p.r.SetAttr(p.ial)
10151019
p.ial = nil
10161020

10171021
if co != "" {
@@ -1022,7 +1026,7 @@ func (p *parser) codeInclude(out *bytes.Buffer, data []byte) int {
10221026
p.callouts = nil
10231027
p.r.BlockCode(out, code, lang, caption.Bytes(), p.insideFigure, false)
10241028
}
1025-
p.r.SetInlineAttr(nil) // reset it again. TODO(miek): double check
1029+
p.r.SetAttr(nil) // reset it again. TODO(miek): double check
10261030

10271031
return end
10281032
}

0 commit comments

Comments
 (0)