Skip to content

Commit

Permalink
Let full reference links override footnotes
Browse files Browse the repository at this point in the history
  • Loading branch information
robinst committed Jun 1, 2024
1 parent aa90ab0 commit 947b1e5
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.commonmark.ext.footnotes.FootnoteDefinition;
import org.commonmark.ext.footnotes.FootnoteReference;
import org.commonmark.node.LinkReferenceDefinition;
import org.commonmark.parser.InlineParserContext;
import org.commonmark.parser.beta.BracketInfo;
import org.commonmark.parser.beta.BracketProcessor;
Expand All @@ -14,6 +15,12 @@ public BracketResult process(BracketInfo bracketInfo, Scanner scanner, InlinePar
// TODO: Does parsing need to be more strict here?
var text = bracketInfo.text();
if (text.startsWith("^")) {
if (bracketInfo.label() != null && context.getDefinition(LinkReferenceDefinition.class, bracketInfo.label()) != null) {
// If there's a label after the text and the label has a definition -> it's a link, and it should
// take preference.
return BracketResult.none();
}

var label = text.substring(1);
// Check if we have a definition, otherwise ignore (same behavior as for link reference definitions)
var def = context.getDefinition(FootnoteDefinition.class, label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,24 @@ public void testRefWithBracket() {
assertNull(tryFind(doc, FootnoteReference.class));
}

// Interesting test cases:

// Test [^*foo*][foo]
//
// [^*foo*]: /url
//
// [foo]: /url
//
// vs
//
// Test [^*foo*][foo]
//
// [^*foo*]: /url
@Test
public void testPreferReferenceLink() {
// This is tricky because `[^*foo*][foo]` is a valid link already. If `[foo]` was not defined, the first bracket
// would be a footnote.
var doc = PARSER.parse("Test [^*foo*][foo]\n\n[^*foo*]: /url\n\n[foo]: /url");
assertNull(tryFind(doc, FootnoteReference.class));
}

@Test
public void testReferenceLinkWithoutDefinition() {
// Similar to previous test but there's no definition
var doc = PARSER.parse("Test [^*foo*][foo]\n\n[^*foo*]: def\n");
var ref = find(doc, FootnoteReference.class);
assertEquals("*foo*", ref.getLabel());
var paragraph = (Paragraph) doc.getFirstChild();
assertText("Test ", paragraph.getFirstChild());
assertText("[foo]", paragraph.getLastChild());
}

private static <T> T find(Node parent, Class<T> nodeClass) {
return Objects.requireNonNull(tryFind(parent, nodeClass), "Could not find a " + nodeClass.getSimpleName() + " node in " + parent);
Expand Down

0 comments on commit 947b1e5

Please sign in to comment.