When dealing with nested links, only the inner one is recognized as one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
diff --git a/md4c/md4c.c b/md4c/md4c.c
index fa6dccc..7ea3371 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -2591,10 +2591,7 @@ static int
md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
{
int opener_index = ctx->unresolved_link_head;
-
- // TODO: Handle nested links: we need to remember end offset of most recent
- // resolved link. If we later iterate to anything with opener BEFORE that
- // then it cannot be link.
+ OFF most_recent_link_beg = 0;
while(opener_index >= 0) {
MD_MARK* opener = &ctx->marks[opener_index];
@@ -2613,6 +2610,16 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
next_opener = NULL;
}
+ /* Links cannot be nested. If they are, the most nested one is the
+ * link and the outer one is not. Given the order of '[' ']' marks
+ * here is ordered by closer position, we enter the most inner brackets
+ * first. */
+ if(opener->beg < most_recent_link_beg) {
+ /* Cannot be a link as it is outer to some previously resolved link. */
+ opener_index = next_index;
+ continue;
+ }
+
// TODO: Check for inline link
if(next_opener != NULL && next_opener->beg == closer->end) {
@@ -2653,6 +2660,8 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
if(attr.title_needs_free)
md_mark_chain_append(ctx, &PTR_CHAIN, opener_index+2);
ctx->marks[opener_index+2].prev = attr.title_size;
+
+ most_recent_link_beg = opener->beg;
}
opener_index = next_index;