pull/398/merge
Alexander 2021-02-26 16:58:41 +02:00 committed by GitHub
commit ce2a892950
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 5 deletions

View File

@ -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
View File

@ -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>")

View File

@ -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 "