Welcome to little lamb

Code » qmdoc » commit 369cda7

Add support for "intra-links"

author Olivier Brunel
2023-01-12 19:49:59 UTC
committer Olivier Brunel
2023-01-12 19:49:59 UTC
parent ce2d85c3a89d12d85b641be5d9bd8b9b43105369

Add support for "intra-links"

That is, with a "wikilinks" syntax (e.g. [[foobar]]) we check if there's
a matching page to be generated;
- if so, link to saif page
- if not, assume it is/will be a title on the current page and link to
  the corresponding anchor

src/main.c +39 -2

diff --git a/src/main.c b/src/main.c
index 608c11d..cff4944 100644
--- a/src/main.c
+++ b/src/main.c
@@ -911,9 +911,41 @@ enter_span(MD_SPANTYPE type, void *details, void *ctx_)
                 return ERR_PARSER_ENTER_SPAN;
             break;
 
+        case MD_SPAN_WIKILINK:
+            {
+                MD_SPAN_WIKILINK_DETAIL *d = details;
+                const char *s = d->target.text;
+                size_t l = d->target.size;
+                int page = -1;
+
+                /* we treat "wikilinks" as such:
+                 * - if there's a page by the target name, link to said page
+                 * - else we assume there is/will be a title named as such and
+                 *   link to its anchor
+                 */
+                for (int i = 0; i < ctx->nb_pages; ++i) {
+                    if (!memcmp(s, ctx->sa.s + ctx->pages[i].fileoff, l)
+                            && !strcmp(".html", ctx->sa.s + ctx->pages[i].fileoff + l)) {
+                        page = i;
+                        break;
+                    }
+                }
+
+                if (!raw_str(ctx, "<a href=\"")
+                        || (page >= 0 && (
+                                !raw_str(ctx, ctx->sa.s + ctx->pages[page].fileoff)
+                                ))
+                        || (page < 0 && (
+                                !raw_text(ctx, "#", 1)
+                                || !anchor(ctx, s, l)
+                                ))
+                        || !raw_str(ctx, "\">"))
+                    return ERR_PARSER_ENTER_SPAN;
+            }
+            break;
+
         case MD_SPAN_LATEXMATH:
         case MD_SPAN_LATEXMATH_DISPLAY:
-        case MD_SPAN_WIKILINK:
             return ERR_NOTSUPP;
 
         case MD_SPAN_U:
@@ -1012,9 +1044,13 @@ leave_span(MD_SPANTYPE type, void *details, void *ctx_)
                 return ERR_PARSER_LEAVE_SPAN;
             break;
 
+        case MD_SPAN_WIKILINK:
+            if (!raw_str(ctx, "</a>"))
+                return ERR_PARSER_LEAVE_SPAN;
+            break;
+
         case MD_SPAN_LATEXMATH:
         case MD_SPAN_LATEXMATH_DISPLAY:
-        case MD_SPAN_WIKILINK:
             return ERR_NOTSUPP;
 
         case MD_SPAN_U:
@@ -1164,6 +1200,7 @@ convert_page(struct ctx *ctx, int fddest)
     const MD_PARSER parser = {
         .flags = MD_FLAG_COLLAPSEWHITESPACE | MD_FLAG_PERMISSIVEAUTOLINKS
             | MD_FLAG_NOHTMLBLOCKS | MD_FLAG_STRIKETHROUGH | MD_FLAG_UNDERLINE
+            | MD_FLAG_WIKILINKS
             | MD_FLAG_ITALIC | MD_FLAG_BOLD | MD_FLAG_BOX | MD_FLAG_HIGHLIGHT
             | MD_FLAG_INDENT,
         .enter_block = enter_block,