1% Copyright © 2025 Zhongying Qiao
    2% Licensed under the Apache License 2.0.
    3% See the LICENSE file for details or http://www.apache.org/licenses/LICENSE-2.0.
    4
    5:- module(plog_markdown, [
    6    render_paragraphs/2,
    7    inline/2
    8]).    9
   10:- use_module(library(pcre)).   11:- use_module(library(http/html_write)).   12
   13render_paragraphs([], []).
   14render_paragraphs([Line|Rest], [HTML|Out]) :-
   15    (
   16        re_matchsub("^# +(.*)", Line, D, []) -> HTML = h1(D.get(1));
   17        re_matchsub("^## +(.*)", Line, D, []) -> HTML = h2(D.get(1));
   18        re_matchsub("^### +(.*)", Line, D, []) -> HTML = h3(D.get(1));
   19        re_matchsub("^> +(.*)", Line, D, []) -> HTML = blockquote(p(D.get(1)));
   20        re_matchsub("^---$", Line, _, []) -> HTML = hr([]);
   21        inline(Line, Parts),
   22        HTML = p(Parts)
   23    ),
   24    render_paragraphs(Rest, Out).
   25
   26inline(Line, Parts) :-
   27    (   re_matchsub("^(.*?)\\!\\[(.*?)\\]\\((.*?)\\)(.*)$", Line, D, []) ->
   28        B = D.get(1),
   29        T = D.get(2),
   30        U = D.get(3),
   31        A = D.get(4),
   32        inline(B, PBefore),
   33        inline(A, PAfter),
   34        append(PBefore,
   35               [img([src(U), width('450'), height('400'), alt(T)])|PAfter],
   36               Parts)
   37    ;   re_matchsub("^(.*?)\\[(.*?)\\]\\((.*?)\\)(.*)$", Line, D, []) ->
   38        B = D.get(1),
   39        T = D.get(2),
   40        U = D.get(3),
   41        A = D.get(4),
   42        inline(B, PBefore),
   43        inline(A, PAfter),
   44        append(PBefore, [a([href(U)], T)|PAfter], Parts)
   45    ;   re_matchsub("^(.*?)`(.*?)`(.*)$", Line, D, []) ->
   46        B = D.get(1),
   47        M = D.get(2),
   48        A = D.get(3),
   49        inline(B, PBefore),
   50        inline(A, PAfter),
   51        append(PBefore, [code(M)|PAfter], Parts)
   52    ;   re_matchsub("^(.*?)\\*\\*(.*?)\\*\\*(.*)$", Line, D, []) ->
   53        B = D.get(1),
   54        M = D.get(2),
   55        A = D.get(3),
   56        inline(B, PBefore),
   57        inline(A, PAfter),
   58        append(PBefore, [b(M)|PAfter], Parts)
   59    ;   re_matchsub("^(.*?)_(.*?)_(.*)$", Line, D, []) ->
   60        B = D.get(1),
   61        M = D.get(2),
   62        A = D.get(3),
   63        inline(B, PBefore),
   64        inline(A, PAfter),
   65        append(PBefore, [i(M)|PAfter], Parts)
   66    ;   Parts = [Line]
   67    )