slweb

Једноставни генератор статичких веб страна
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 174e486d56bef2513a6443680de1fbaa73a0d7ca
родитељ 45542ae421ec09a8a79b4ebadb1bfcd3d4688c89
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Thu, 17 Dec 2020 17:59:10 +0100

Added title variable processing and span form of links; bugfixes

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 4++--
Mdefs.h | 8+++++---
Mindex.html | 2+-
Mslweb.c | 340+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
измењених датотека: 4, додавања: 263(+), брисања: 91(-)

diff --git a/TODO b/TODO @@ -6,13 +6,13 @@ Migration to C checklist [ ] Add {=macro} parsing [ ] Add [=command Link](link) form of links - [ ] Add [(Link)](link) form of links + [x] Add [(Link)](link) form of links [ ] Add {include} processing [x] Add {.class} processing [x] Add {#id} processing [x] Convert strncat token processing to individual token-based [ ] Add {lsdir} - [ ] Add title: processing + [x] Add title: processing [ ] Update manpage [x] Add backslash-escaping of blank lines for normal tags diff --git a/defs.h b/defs.h @@ -22,9 +22,10 @@ #include <errno.h> #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include <string.h> -#include <stdio.h> #include <sys/stat.h> #include <unistr.h> #include <unistdio.h> @@ -76,8 +77,9 @@ const USHORT ST_CODE = 1 << 8; const USHORT ST_BLOCKQUOTE = 1 << 9; const USHORT ST_LINK = 1 << 10; const USHORT ST_LINK_SECOND_ARG = 1 << 11; -const USHORT ST_IMAGE = 1 << 12; -const USHORT ST_IMAGE_SECOND_ARG = 1 << 13; +const USHORT ST_LINK_SPAN = 1 << 12; +const USHORT ST_IMAGE = 1 << 13; +const USHORT ST_IMAGE_SECOND_ARG = 1 << 14; #pragma GCC diagnostic pop #endif /* __DEFS_H */ diff --git a/index.html b/index.html @@ -103,7 +103,7 @@ this program. If not, see &lt;https://www.gnu.org/licenses/&gt;. </p> <div id="git-log"> Previous commit: -index.slw 3285b51 2020-12-16 20:08:49 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) +index.slw 45542ae 2020-12-16 20:10:28 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) </div><!--git-log--> diff --git a/slweb.c b/slweb.c @@ -18,8 +18,6 @@ */ #include "defs.h" -#include <stdint.h> -#include <unistdio.h> static size_t lineno = 0; static size_t colno = 1; @@ -48,7 +46,7 @@ error(int code, uint8_t* fmt, ...) va_start(args, fmt); u8_vsnprintf(buf, sizeof(buf), (const char*)fmt, args); va_end(args); - fprintf(stderr, "%s: %s", PROGRAMNAME, buf); + fprintf(stderr, "%s:%lu:%lu: %s", PROGRAMNAME, lineno, colno, buf); return code; } @@ -273,6 +271,13 @@ process_italic(FILE* output, BOOL end_tag) } int +process_code(FILE* output, BOOL end_tag) +{ + fprintf(output, "<%scode>", end_tag ? "/" : ""); + return 0; +} + +int process_blockquote(FILE* output, BOOL end_tag) { fprintf(output, "<%sblockquote>", end_tag ? "/" : ""); @@ -394,9 +399,15 @@ add_css(FILE* output, KeyValue* vars, size_t vars_count) } int -end_head_start_body(FILE* output) +end_head_start_body(FILE* output, KeyValue* vars, size_t vars_count) { + uint8_t* title = get_value(vars, vars_count, (uint8_t*)"title"); + fprintf(output, "</head>\n<body>\n"); + + if (title) + fprintf(output, "<h2>%s</h2>\n", (char*)title); + return 0; } @@ -453,11 +464,11 @@ slweb_parse(uint8_t* buffer, FILE* output, plinks = *links; lineno = 0; - if (!read_yaml_macros_and_links) + if (!read_yaml_macros_and_links && !body_only) { begin_html_and_head(output, *vars, *vars_count); add_css(output, *vars, *vars_count); - end_head_start_body(output); + end_head_start_body(output, *vars, *vars_count); } do @@ -562,23 +573,46 @@ slweb_parse(uint8_t* buffer, FILE* output, pline += 3; colno += 3; } - else if (!(state & (ST_HEADING | ST_YAML | ST_PRE))) + else if (!(state & (ST_TAG | ST_HEADING | ST_YAML | ST_PRE))) { - state ^= ST_CODE; - - if (state & ST_CODE) + /* Handle ` within link text specially */ + if (state & ST_LINK) { + uint8_t* tag = state & ST_CODE + ? (uint8_t*)"</code>" + : (uint8_t*)"<code>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; + *ptoken = '\0'; - u8_strncat(ptoken, (uint8_t*)"<code>", strlen("<code>")); - ptoken += strlen("<code>"); + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } } else { - *ptoken = '\0'; - u8_strncat(ptoken, (uint8_t*)"</code>", strlen("</code>")); - ptoken += strlen("</code>"); + /* Output existing text up to ` */ + process_text_token(&state, first_line_in_doc, + previous_line_blank, + processed_start_of_line, + read_yaml_macros_and_links, + output, + &token, + &ptoken, + TRUE); + processed_start_of_line = TRUE; + + if (!read_yaml_macros_and_links + && !(state & (ST_PRE | ST_HEADING))) + process_code(output, state & ST_CODE); } + state ^= ST_CODE; + pline++; colno++; } @@ -623,20 +657,41 @@ slweb_parse(uint8_t* buffer, FILE* output, if (u8_strlen(pline) > 1 && *(pline+1) == '_') { - /* Output existing text up to __ */ - process_text_token(&state, first_line_in_doc, - previous_line_blank, - processed_start_of_line, - read_yaml_macros_and_links, - output, - &token, - &ptoken, - TRUE); - processed_start_of_line = TRUE; + /* Handle __ within link text specially */ + if (state & ST_LINK) + { + uint8_t* tag = state & ST_BOLD + ? (uint8_t*)"</strong>" + : (uint8_t*)"<strong>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; - if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) - process_bold(output, state & ST_BOLD); + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + } + else + { + /* Output existing text up to __ */ + process_text_token(&state, first_line_in_doc, + previous_line_blank, + processed_start_of_line, + read_yaml_macros_and_links, + output, + &token, + &ptoken, + TRUE); + processed_start_of_line = TRUE; + + if (!read_yaml_macros_and_links + && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + process_bold(output, state & ST_BOLD); + } state ^= ST_BOLD; pline += 2; @@ -644,20 +699,41 @@ slweb_parse(uint8_t* buffer, FILE* output, } else { - /* Output existing text up to _ */ - process_text_token(&state, first_line_in_doc, - previous_line_blank, - processed_start_of_line, - read_yaml_macros_and_links, - output, - &token, - &ptoken, - TRUE); - processed_start_of_line = TRUE; + /* Handle _ within link text specially */ + if (state & ST_LINK) + { + uint8_t* tag = state & ST_ITALIC + ? (uint8_t*)"</em>" + : (uint8_t*)"<em>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; - if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) - process_italic(output, state & ST_ITALIC); + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + } + else + { + /* Output existing text up to _ */ + process_text_token(&state, first_line_in_doc, + previous_line_blank, + processed_start_of_line, + read_yaml_macros_and_links, + output, + &token, + &ptoken, + TRUE); + processed_start_of_line = TRUE; + + if (!read_yaml_macros_and_links + && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + process_italic(output, state & ST_ITALIC); + } state ^= ST_ITALIC; pline++; @@ -676,20 +752,41 @@ slweb_parse(uint8_t* buffer, FILE* output, if (u8_strlen(pline) > 1 && *(pline+1) == '*') { - /* Output existing text up to * */ - process_text_token(&state, first_line_in_doc, - previous_line_blank, - processed_start_of_line, - read_yaml_macros_and_links, - output, - &token, - &ptoken, - TRUE); - processed_start_of_line = TRUE; + /* Handle ** within link text specially */ + if (state & ST_LINK) + { + uint8_t* tag = state & ST_BOLD + ? (uint8_t*)"</strong>" + : (uint8_t*)"<strong>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; - if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) - process_bold(output, state & ST_BOLD); + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + } + else + { + /* Output existing text up to * */ + process_text_token(&state, first_line_in_doc, + previous_line_blank, + processed_start_of_line, + read_yaml_macros_and_links, + output, + &token, + &ptoken, + TRUE); + processed_start_of_line = TRUE; + + if (!read_yaml_macros_and_links + && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + process_bold(output, state & ST_BOLD); + } state ^= ST_BOLD; pline += 2; @@ -697,20 +794,41 @@ slweb_parse(uint8_t* buffer, FILE* output, } else { - /* Output existing text up to * */ - process_text_token(&state, first_line_in_doc, - previous_line_blank, - processed_start_of_line, - read_yaml_macros_and_links, - output, - &token, - &ptoken, - TRUE); - processed_start_of_line = TRUE; + /* Handle * within link text specially */ + if (state & ST_LINK) + { + uint8_t* tag = state & ST_ITALIC + ? (uint8_t*)"</em>" + : (uint8_t*)"<em>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; - if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) - process_italic(output, state & ST_ITALIC); + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + } + else + { + /* Output existing text up to * */ + process_text_token(&state, first_line_in_doc, + previous_line_blank, + processed_start_of_line, + read_yaml_macros_and_links, + output, + &token, + &ptoken, + TRUE); + processed_start_of_line = TRUE; + + if (!read_yaml_macros_and_links + && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + process_italic(output, state & ST_ITALIC); + } state ^= ST_ITALIC; pline++; @@ -719,19 +837,15 @@ slweb_parse(uint8_t* buffer, FILE* output, break; case ' ': - if (u8_strlen(pline) == 2) + if (u8_strlen(pline) == 2 + && *(pline+1) == ' ') { - if (*(pline+1) == ' ') - { - *ptoken = '\0'; - u8_strncat(ptoken, (uint8_t*)"<br />", - strlen("<br />")); - ptoken += strlen("<br />"); - pline++; - colno++; - } - else - *ptoken++ = *pline; + *ptoken = '\0'; + u8_strncat(ptoken, (uint8_t*)"<br />", + strlen("<br />")); + ptoken += strlen("<br />"); + pline++; + colno++; } else if (!(state & ST_HEADING && *(pline-1) == '#')) @@ -742,7 +856,7 @@ slweb_parse(uint8_t* buffer, FILE* output, case '{': if (read_yaml_macros_and_links - || state & (ST_PRE | ST_HEADING)) + || (state & (ST_PRE | ST_YAML | ST_YAML_VAL | ST_HEADING))) { *ptoken++ = *pline++; colno++; @@ -884,16 +998,67 @@ slweb_parse(uint8_t* buffer, FILE* output, TRUE); processed_start_of_line = TRUE; - state |= ST_LINK; - *token = '\0'; ptoken = token; + state |= ST_LINK; + pline++; colno++; break; + case '(': + if (state & ST_LINK) + { + uint8_t* tag = (uint8_t*)"<span>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; + + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + + state |= ST_LINK_SPAN; + pline++; + } + else { + *ptoken++ = *pline++; + } + + colno++; + break; + case ')': + if (state & ST_LINK_SPAN) + { + if (u8_strlen(pline) > 1 + && *(pline+1) == ']') + { + uint8_t* tag = (uint8_t*)"</span>"; + size_t tag_len = u8_strlen(tag); + size_t token_len = 0; + + *ptoken = '\0'; + token_len = u8_strlen(token); + + if (token_len + tag_len < BUFSIZE) + { + u8_strncat(token, tag, tag_len); + ptoken += tag_len; + } + state &= ~ST_LINK_SPAN; + } + + pline++; + colno++; + break; + } + if (!(state & (ST_LINK_SECOND_ARG | ST_IMAGE_SECOND_ARG))) { *ptoken++ = *pline++; @@ -980,8 +1145,12 @@ slweb_parse(uint8_t* buffer, FILE* output, case '[': case '(': if (link_text) - link_text = (uint8_t*) realloc(link_text, - u8_strlen(token) * sizeof(uint8_t)); + { + size_t token_len = u8_strlen(token); + if (token_len > u8_strlen(link_text)) + link_text = (uint8_t*) realloc(link_text, + token_len * sizeof(uint8_t)); + } else link_text = (uint8_t*) calloc(u8_strlen(token), sizeof(uint8_t)); @@ -1006,6 +1175,7 @@ slweb_parse(uint8_t* buffer, FILE* output, } } break; + case '\\': /* *if (state & (ST_PRE | ST_CODE | ST_LINK_SECOND_ARG)) @@ -1117,7 +1287,7 @@ slweb_parse(uint8_t* buffer, FILE* output, } while (pbuffer && *pbuffer); - if (!read_yaml_macros_and_links) + if (!read_yaml_macros_and_links && !body_only) end_body_and_html(output); free(line);