summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-12-06 18:37:49 +0700
committerShulhan <ms@kilabit.info>2021-12-06 18:37:49 +0700
commit51c845f8b738fba508f99dc7c7400d11f65bd12d (patch)
tree54f89d4c995938b9eb55b34847430eea39cf7117
parentd0ebdcaeaa5c52b7ff8513d1a324607e104ead3c (diff)
downloadasciidoctor-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.go33
-rw-r--r--inline_parser.go33
-rw-r--r--parser.go11
-rw-r--r--testdata/got.test.html2
4 files changed, 31 insertions, 48 deletions
diff --git a/element.go b/element.go
index 8b7a46c..c16fcce 100644
--- a/element.go
+++ b/element.go
@@ -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,
diff --git a/parser.go b/parser.go
index 8b0b8d5..9990b2c 100644
--- a/parser.go
+++ b/parser.go
@@ -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>