Merge d46e80044c
into e96880f42b
commit
ce2a892950
17
block.go
17
block.go
|
@ -1382,6 +1382,20 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
|
|||
eol--
|
||||
}
|
||||
|
||||
id := ""
|
||||
if p.flags&EXTENSION_HEADER_IDS != 0 && eol > prev+2 && data[eol-1] == '}' {
|
||||
for j := eol - 2; j > prev; j-- {
|
||||
if data[j] == '#' && data[j-1] == '{' {
|
||||
id = string(data[j+1 : eol-1])
|
||||
eol = j - 1
|
||||
for eol > prev && (data[eol-1] == ' ' || data[eol-1] == '\t') {
|
||||
eol--
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render the header
|
||||
// this ugly double closure avoids forcing variables onto the heap
|
||||
work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool {
|
||||
|
@ -1391,8 +1405,7 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
|
|||
}
|
||||
}(out, p, data[prev:eol])
|
||||
|
||||
id := ""
|
||||
if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
|
||||
if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
|
||||
id = SanitizedAnchorName(string(data[prev:eol]))
|
||||
}
|
||||
|
||||
|
|
44
html.go
44
html.go
|
@ -45,6 +45,10 @@ const (
|
|||
HTML_SMARTYPANTS_ANGLED_QUOTES // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering
|
||||
HTML_SMARTYPANTS_QUOTES_NBSP // enable "French guillemets" (with HTML_USE_SMARTYPANTS)
|
||||
HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source
|
||||
HTML_HEADER_LINKS // generate headings followed by direct link to the header #id
|
||||
HTML_CHECKLISTS // generate checkboxes for "[x]" and "[ ]" in list items
|
||||
HTML_LINK_CLASSES // add "autolink" class to auto-detected links, add "anchor" class to anchor links
|
||||
HTML_LOCAL_MD_LINKS_TO_HTML // links to local MD files will be converted to HTML: file.md -> file.html
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -236,6 +240,10 @@ func (options *Html) Header(out *bytes.Buffer, text func() bool, level int, id s
|
|||
options.TocHeaderWithAnchor(out.Bytes()[tocMarker:], level, id)
|
||||
}
|
||||
|
||||
if id != "" && options.flags&HTML_HEADER_LINKS != 0 {
|
||||
out.WriteString(fmt.Sprintf(" <a class=\"heading\" href=\"#%s\">#</a>", id))
|
||||
}
|
||||
|
||||
out.WriteString(fmt.Sprintf("</h%d>\n", level))
|
||||
}
|
||||
|
||||
|
@ -396,7 +404,16 @@ func (options *Html) ListItem(out *bytes.Buffer, text []byte, flags int) {
|
|||
} else if flags&LIST_TYPE_DEFINITION != 0 {
|
||||
out.WriteString("<dd>")
|
||||
} else {
|
||||
out.WriteString("<li>")
|
||||
if options.flags&HTML_CHECKLISTS != 0 && len(text) >= 3 && text[0] == '[' && text[2] == ']' {
|
||||
out.WriteString("<li style=\"list-style-type:none;\"><input type=\"checkbox\"")
|
||||
if text[1] != ' ' {
|
||||
out.WriteString(" checked")
|
||||
}
|
||||
out.WriteString(options.closeTag)
|
||||
text = text[3:]
|
||||
} else {
|
||||
out.WriteString("<li>")
|
||||
}
|
||||
}
|
||||
out.Write(text)
|
||||
if flags&LIST_TYPE_TERM != 0 {
|
||||
|
@ -458,6 +475,20 @@ func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) {
|
|||
out.WriteString("\" target=\"_blank")
|
||||
}
|
||||
|
||||
// add "autolink" class
|
||||
if options.flags&HTML_LINK_CLASSES != 0 {
|
||||
out.WriteString("\" class=\"autolink")
|
||||
}
|
||||
|
||||
// add "anchor" class to anchor autolink,
|
||||
// remove leading '#' from anchor autolink text
|
||||
if link[0] == '#' {
|
||||
if options.flags&HTML_LINK_CLASSES != 0 {
|
||||
out.WriteString(" anchor")
|
||||
}
|
||||
link = link[1:]
|
||||
}
|
||||
|
||||
out.WriteString("\">")
|
||||
|
||||
// Pretty print: if we get an email address as
|
||||
|
@ -551,6 +582,12 @@ func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content
|
|||
|
||||
out.WriteString("<a href=\"")
|
||||
options.maybeWriteAbsolutePrefix(out, link)
|
||||
// replace file extension in href attribute to .html for local .md files
|
||||
if options.flags&HTML_LOCAL_MD_LINKS_TO_HTML != 0 {
|
||||
if buf := []byte("//.md.html"); bytes.HasSuffix(link, buf[2:5]) && bytes.Index(link, buf[:2]) < 0 {
|
||||
link = append(link[:len(link)-3], buf[5:]...)
|
||||
}
|
||||
}
|
||||
attrEscape(out, link)
|
||||
if len(title) > 0 {
|
||||
out.WriteString("\" title=\"")
|
||||
|
@ -575,6 +612,11 @@ func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content
|
|||
out.WriteString("\" target=\"_blank")
|
||||
}
|
||||
|
||||
// add "anchor" class to anchor links
|
||||
if link[0] == '#' && options.flags&HTML_LINK_CLASSES != 0 {
|
||||
out.WriteString("\" class=\"anchor")
|
||||
}
|
||||
|
||||
out.WriteString("\">")
|
||||
out.Write(content)
|
||||
out.WriteString("</a>")
|
||||
|
|
|
@ -865,7 +865,7 @@ func tagLength(data []byte, autolink *int) int {
|
|||
i = 1
|
||||
}
|
||||
|
||||
if !isalnum(data[i]) {
|
||||
if !isalnum(data[i]) && data[i] != '#' {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -873,7 +873,7 @@ func tagLength(data []byte, autolink *int) int {
|
|||
*autolink = LINK_TYPE_NOT_AUTOLINK
|
||||
|
||||
// try to find the beginning of an URI
|
||||
for i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {
|
||||
for i < len(data) && data[i] != '#' && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {
|
||||
i++
|
||||
}
|
||||
|
||||
|
@ -887,6 +887,8 @@ func tagLength(data []byte, autolink *int) int {
|
|||
if i > 2 && i < len(data) && data[i] == ':' {
|
||||
*autolink = LINK_TYPE_NORMAL
|
||||
i++
|
||||
} else if i < len(data) && data[i] == '#' {
|
||||
*autolink = LINK_TYPE_NORMAL
|
||||
}
|
||||
|
||||
// complete autolink test: no whitespace or ' or "
|
||||
|
|
Loading…
Reference in New Issue