diff options
| author | Shulhan <ms@kilabit.info> | 2021-12-06 18:37:49 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-12-06 18:37:49 +0700 |
| commit | 51c845f8b738fba508f99dc7c7400d11f65bd12d (patch) | |
| tree | 54f89d4c995938b9eb55b34847430eea39cf7117 | |
| parent | d0ebdcaeaa5c52b7ff8513d1a324607e104ead3c (diff) | |
| download | asciidoctor-go-51c845f8b738fba508f99dc7c7400d11f65bd12d.tar.xz | |
all: fix parsing and rendering cross reference
Previously, when parsing cross reference we assume that if the string
contains upper-case letter then it's a label so we store it as title
to search for ID later.
The bug is when ID is set manually and its contains upper-case for
example "[#Id]".
This changes fix this issue by storing cross reference first, not
assuming it as ID or title, and then when doing rendering we check
whether its ID or title.
| -rw-r--r-- | element.go | 33 | ||||
| -rw-r--r-- | inline_parser.go | 33 | ||||
| -rw-r--r-- | parser.go | 11 | ||||
| -rw-r--r-- | testdata/got.test.html | 2 |
4 files changed, 31 insertions, 48 deletions
@@ -739,15 +739,34 @@ func (el *element) toHTML(doc *Document, w io.Writer) { doc.Attributes.apply(el.key, el.value) case elKindCrossReference: - href, ok := el.Attrs[attrNameHref] - if !ok { - title, ok := el.Attrs[attrNameTitle] - if !ok { - title = el.Attrs[attrNameRefText] + var ( + href = el.Attrs[attrNameHref] + label = string(el.raw) + ) + anchor := doc.anchors[href] + if anchor == nil { + href = doc.titleID[href] + if len(href) > 0 { + anchor = doc.anchors[href] + if anchor != nil { + if len(label) == 0 { + label = anchor.label + } + } + } else { + // href is not ID nor label, assume its broken + // link. + href = el.Attrs[attrNameHref] + if len(label) == 0 { + label = href + } + } + } else { + if len(label) == 0 { + label = anchor.label } - href = doc.titleID[title] } - fmt.Fprintf(w, "<a href=\"#%s\">%s</a>", href, el.raw) + fmt.Fprintf(w, "<a href=\"#%s\">%s</a>", href, label) case elKindMacroTOC: if doc.tocIsEnabled && doc.tocPosition == metaValueMacro { diff --git a/inline_parser.go b/inline_parser.go index 872a669..401c6b6 100644 --- a/inline_parser.go +++ b/inline_parser.go @@ -414,45 +414,20 @@ func (pi *inlineParser) parseCrossRef() bool { var ( href string label string - title string - ok bool ) parts := bytes.Split(raw, []byte(",")) + href = string(parts[0]) if len(parts) >= 2 { label = string(bytes.TrimSpace(parts[1])) } - if isRefTitle(parts[0]) { - // Get ID by title. - href, ok = pi.doc.titleID[string(parts[0])] - if ok { - if len(label) == 0 { - label = string(parts[0]) - } - } else { - // Store the label for cross reference later. - title = string(parts[0]) - } - } else if isValidID(parts[0]) { - href = string(parts[0]) - if len(label) == 0 { - anchor := pi.doc.anchors[href] - if anchor != nil { - label = anchor.label - } - } - } else { - return false - } - - // The ID field will we non-empty if href is empty, it will be - // revalidated later when rendered. + // Set attribute href to the first part, we will revalidated later + // when rendering the element. elCrossRef := &element{ elementAttribute: elementAttribute{ Attrs: map[string]string{ - attrNameHref: href, - attrNameTitle: title, + attrNameHref: href, }, }, kind: elKindCrossReference, @@ -458,17 +458,6 @@ func isLineDescriptionItem(line []byte) bool { return x > 0 } -// isRefTitle will return true if one of character is upper case or white -// space. -func isRefTitle(s []byte) bool { - for _, r := range string(s) { - if unicode.IsUpper(r) || unicode.IsSpace(r) { - return true - } - } - return false -} - func isStyleAdmonition(style int64) bool { return style&styleAdmonition > 0 } diff --git a/testdata/got.test.html b/testdata/got.test.html index a688a13..854ff6f 100644 --- a/testdata/got.test.html +++ b/testdata/got.test.html @@ -2308,7 +2308,7 @@ D</p></td> <p>Cross reference with ID <a href="#_anchors">This is anchor</a>.</p> </div> <div class="paragraph"> -<p>Cross reference with block title <a href="#_anchors">Anchors</a>.</p> +<p>Cross reference with block title <a href="#_anchors">This is anchor</a>.</p> </div> <div class="paragraph"> <p>Cross reference with reftext <a href="#_anchors">This is anchor</a>.</p> |
