From a6dc7f2f92162dc9a9930c3fe676c23a03ef35b8 Mon Sep 17 00:00:00 2001 From: Alex Karle Date: Wed, 15 Dec 2021 00:25:31 -0500 Subject: [PATCH] Add initial support for links --- blag.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 17 deletions(-) diff --git a/blag.c b/blag.c index 08d968c..46de1e0 100644 --- a/blag.c +++ b/blag.c @@ -20,23 +20,13 @@ * * Inline `code` * - * TODO: + * Escaping via \ + * * [[url|Links]] - * -> if we see [[ - * -> print out - * -> just putchar - * -> else - * -> printf ">url - * -> once we hit ]] - * -> * - * --> error reporting for unclosed links?? - * -> errx in closeblock() if in link parser + * TODO: + * ----- + * - error reporting for malformed blocks */ #include #include @@ -60,6 +50,10 @@ enum Block { OLIST_START, OLIST_PARSE, OLIST_BREAK, + LINK_URL_PARSE, + LINK_DESC_PARSE, + POTENTIAL_LINK, + POTENTIAL_LINK_END }; int closeblock(int in, int hlvl) { @@ -100,13 +94,47 @@ int closeblock(int in, int hlvl) { } int parse() { - /* Mini state machine */ + /* Mini state machine (home grown spaghetti code) + * + * Key: global "line level" state in `in`, secondary mid-line states + * (inline code & links) use dedicated states. A newline triggers many of + * the line-level blocks to enter "BREAK" mode, where they can either + * continue or truly be broken on a second newline (PARAGRAPH, CODE, + * U/OLIST, etc). Several of the variable length tokens (like ordered + * list numbers, header level, etc) enter a "PARSE" mode where special + * action is taken until the parsing is done (usually on ' ', but for + * links on '|') + */ int c; enum Block in = NONE; + enum Block in_link = NONE; int hlvl = 0; int in_code; + int escape = 0; while ((c = getchar()) != EOF) { + /* Handle Escapes before all else */ + if (escape) { + if (in == NONE) { + in = PARAGRAPH; + printf("

\n"); + } + putchar(c); + escape = 0; + continue; + } + + /* Reset special "potential" states */ + if (c != '[' && in_link == POTENTIAL_LINK) { + in_link = NONE; + } else if (c != ']' && in_link == POTENTIAL_LINK_END) { + in_link = NONE; + } + + /* Handle unique state changes by char */ switch (c) { + case '\\': + escape = 1; + break; case '#': if (in == NONE) { in = HEADER_PARSE; @@ -120,7 +148,7 @@ int parse() { break; case ' ': if (in == HEADER_PARSE) { - printf("", hlvl); + printf("", hlvl); in = HEADER; } else if (in == ULIST_START) { printf("