slweb

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

чување cd686600d271edbae0942483cd85a72d6d940d3d
родитељ b30d2adab8047a27fa7baa30f887510bf3f28f78
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Mon,  1 Feb 2021 22:48:05 +0100

Added support for conditionals in CSV templates

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

Diffstat:
MTODO | 2++
Mdefs.h | 12++++++++----
Aexamples/csv/all.do | 2++
Aexamples/csv/index.slw | 11+++++++++++
Aexamples/csv/sales.csv | 4++++
Mindex.html | 2+-
Mslweb.1.in | 48++++++++++++++++++++++++++++++++++--------------
Mslweb.c | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
измењених датотека: 8, додавања: 212(+), брисања: 91(-)

diff --git a/TODO b/TODO @@ -9,6 +9,8 @@ [ ] Add numbered lists? + [ ] Add <abbr>? + [x] Add footnote support [x] Add initial support [x] Test diff --git a/defs.h b/defs.h @@ -119,10 +119,14 @@ typedef struct #define ST_FORMULA (1 << 25) #define ST_DISPLAY_FORMULA (1 << 26) -#define ST_CS_NONE 0 -#define ST_CS_HEADER 1 -#define ST_CS_REGISTER (1 << 2) -#define ST_CS_QUOTE (1 << 3) +#define ST_CS_NONE 0 +#define ST_CS_HEADER 1 +#define ST_CS_REGISTER (1 << 2) +#define ST_CS_QUOTE (1 << 3) +#define ST_CS_COND (1 << 4) +#define ST_CS_COND_NONEMPTY (1 << 5) +#define ST_CS_COND_EMPTY (1 << 6) +#define ST_CS_ESCAPE (1 << 7) #pragma GCC diagnostic pop #endif /* __DEFS_H */ diff --git a/examples/csv/all.do b/examples/csv/all.do @@ -0,0 +1,2 @@ +redo-ifchange index.html + diff --git a/examples/csv/index.slw b/examples/csv/index.slw @@ -0,0 +1,11 @@ +{csv "sales"} +{.sales-segment} +$#1 {q}$1{/q} sales by quarter for the last year in +thousands of units sold (for $$) were as follows: +$?2{.q1}$2{/.q1}$?!{.q1 na}N/A{/.q1}$?/ +$?3{.q2}$3{/.q2}$?!{.q2 na}N/A{/.q2}$?/ +$?4{.q3}$4{/.q3}$?!{.q3 na}N/A{/.q3}$?/ +$?5{.q4}$5{/.q4}$?!{.q4 na}N/A{/.q4}$?/ +{/.sales-segment} +{/csv} + diff --git a/examples/csv/sales.csv b/examples/csv/sales.csv @@ -0,0 +1,4 @@ +"Item";"Q1 2020";"Q2 2020";"Q3 2020";"Q4 2020" +"Toothpick";"15.2";"12";"";"10" +"Teapot";"1.2";"";"5";"3.5" + diff --git a/index.html b/index.html @@ -136,7 +136,7 @@ this program. If not, see &lt;<a href="https://www.gnu.org/licenses">https://www <div id="git-log"> Previous commit: -index.slw a16c8d7 2021-01-30 22:52:17 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) +index.slw b30d2ad 2021-01-31 15:54:11 +0100 (Страхиња Радић) (HEAD -> master, origin/master, origin/HEAD) </div><!--git-log--> diff --git a/slweb.1.in b/slweb.1.in @@ -441,8 +441,8 @@ home page. Directive \fC{csv "csvfile"}{/csv}\fP marks a template. Whatever is between \fC{csv}\fP and \fC{/csv}\fP will be processed by .B slweb -and collected as a template. Then, file \fIcsvfile.csv\fP will be read and for -each of its lines the collected template will be output, substituting each +and collected as a template. Afterwards, file \fIcsvfile.csv\fP will be read and +for each of its lines the collected template will be output, substituting each occurence of a register mark \fC$\f[CI]n\fR (where \fIn\fP is between 1 and 9, inclusive) with the corresponding .SM CSV @@ -457,15 +457,28 @@ variable in the calling file) and double quotation marks (") as field boundaries. First line in the .SM CSV file is parsed as a header and associated with register marks \fC$#1\fP to -\fC$#9\fP. The symbol $ is represented as \fC$$\fP. +\fC$#9\fP. The symbol $ is represented as \fC$$\fP. Consequently, math modes +(both inline and display) cannot be used within templates. . .IP "" 8 -For example, having a file \fIsales.csv\fP: +Parts of the template can be conditionally rendered by using the construct: +. +.CDS 8 +$?\f[CI]n\fP + <!-- code to include if $\f[CI]n\fC nonempty --> +$?! + <!-- code to include if $\f[CI]n\fC empty --> +$?/ +.CDE +. +.IP "" 4 +where \fIn\fP is between 1 and 9, inclusive. For example, having a file +\fIsales.csv\fP: . .CDS 8 "Item";"Q1 2020";"Q2 2020";"Q3 2020";"Q4 2020" -"Toothpick";"15.2";"12";"16.4";"10" -"Teapot";"1.2";"2";"5";"3.5" +"Toothpick";"15.2";"12";"";"10" +"Teapot";"1.2";"";"5";"3.5" .CDE . .IP "" 4 @@ -476,8 +489,10 @@ We can write {.sales-segment} $#1 {q}$1{/q} sales by quarter for the last year in thousands of units sold (for $$) were as follows: -{.q1}$2{/.q1} {.q2}$3{/.q2} -{.q3}$4{/.q3} {.q4}$5{/.q4} +$?2{.q1}$2{/.q1}$?!{.q1 na}N/A{/.q1}$?/ +$?3{.q2}$3{/.q2}$?!{.q2 na}N/A{/.q2}$?/ +$?4{.q3}$4{/.q3}$?!{.q3 na}N/A{/.q3}$?/ +$?5{.q4}$5{/.q4}$?!{.q4 na}N/A{/.q4}$?/ {/.sales-segment} {/csv} .CDE @@ -487,16 +502,21 @@ to get: . .CDS 8 <div class="sales-segment"> -Item <q>Toothpick</q> sales by quarter for the last year in +Item <q>Toothpick</q> sales by quarter for the last year in thousands of units sold (for $) were as follows: -<div class="q1">15.2</div> <div class="q2">12</div> -<div class="q3">16.4</div> <div class="q4">10</div> +<div class="q1">15.2</div> +<div class="q2">12</div> +<div class="q3 na">N/A</div> +<div class="q4">10</div> </div> + <div class="sales-segment"> -Item <q>Teapot</q> sales by quarter for the last year in +Item <q>Teapot</q> sales by quarter for the last year in thousands of units sold (for $) were as follows: -<div class="q1">1.2</div> <div class="q2">2</div> -<div class="q3">5</div> <div class="q4">3.5</div> +<div class="q1">1.2</div> +<div class="q2 na">N/A</div> +<div class="q3">5</div> +<div class="q4">3.5</div> </div> .CDE . diff --git a/slweb.c b/slweb.c @@ -75,6 +75,9 @@ static ULONG state = ST_NONE; REALLOC(token, uint8_t, token_size) \ *token = 0; ptoken = token; } +#define ALL(var, mask) ( ((var) & (mask)) == (mask) ) +#define ANY(var, mask) ( (var) & (mask) ) + int version() { @@ -447,68 +450,140 @@ process_git_log(FILE* output) return result ? warning(result, (uint8_t*)"git-log: Cannot run git") : 0; } +#define PRINTIF(format, arg) { \ + if ((ALL(csv_state, ST_CS_COND_NONEMPTY) \ + && *csv_register[conditional_index-1]) \ + || (ALL(csv_state, ST_CS_COND_EMPTY) \ + && !*csv_register[conditional_index-1]) \ + || !ANY(csv_state, ST_CS_COND_EMPTY | ST_CS_COND_NONEMPTY)) \ + { fprintf(output, format, arg); } } + int print_csv_row(FILE* output, uint8_t** csv_header, uint8_t** csv_register) { - uint8_t* pcsv_template = csv_template; - UBYTE csv_state = ST_CS_NONE; - UBYTE num = 0; + uint8_t* pcsv_template = csv_template; + UBYTE csv_state = ST_CS_NONE; + UBYTE num = 0; + UBYTE conditional_index = 0; while (*pcsv_template) { + if (csv_state & ST_CS_ESCAPE) + { + PRINTIF("%c", *pcsv_template) + csv_state &= ~ST_CS_ESCAPE; + pcsv_template++; + continue; + } + switch (*pcsv_template) { + case '\\': + csv_state |= ST_CS_ESCAPE; + pcsv_template++; + break; case '$': if (csv_state & ST_CS_REGISTER) { - fprintf(output, "$"); - csv_state &= ST_CS_REGISTER; + PRINTIF("%c", '$') + csv_state &= ~ST_CS_REGISTER; } else csv_state |= ST_CS_REGISTER; pcsv_template++; break; case '#': - if (csv_state & ST_CS_REGISTER) + if (csv_state & ST_CS_HEADER) { - if (csv_state & ST_CS_HEADER) - { - error(1, (uint8_t*)"csv: Invalid header register mark"); - csv_state &= ~(ST_CS_REGISTER | ST_CS_HEADER); - } - else - csv_state |= ST_CS_HEADER; + error(1, (uint8_t*)"csv: Invalid header register mark"); + csv_state &= ~(ST_CS_REGISTER | ST_CS_HEADER); + } + else if (csv_state & ST_CS_REGISTER) + { + csv_state &= ~ST_CS_REGISTER; + csv_state |= ST_CS_HEADER; + } + else + PRINTIF("%c", '#') + pcsv_template++; + break; + case '?': + if (csv_state & ST_CS_COND) + { + error(1, (uint8_t*)"csv: Invalid conditional mark"); + csv_state &= ~ST_CS_COND; + } + else if (csv_state & ST_CS_REGISTER) + { + csv_state &= ~ST_CS_REGISTER; + csv_state |= ST_CS_COND; + } + else + PRINTIF("%c", '?') + pcsv_template++; + break; + case '!': + if (ALL(csv_state, ST_CS_COND | ST_CS_COND_NONEMPTY)) + { + csv_state &= ~(ST_CS_COND | ST_CS_COND_NONEMPTY); + csv_state |= ST_CS_COND_EMPTY; + } + else if (csv_state & ST_CS_COND) + { + error(1, (uint8_t*)"Empty conditional before/without nonempty" + " conditional"); + csv_state &= ~(ST_CS_COND | ST_CS_COND_EMPTY); } else - fprintf(output, "#"); + PRINTIF("%c", '!') + pcsv_template++; + break; + case '/': + if (ALL(csv_state, ST_CS_COND | ST_CS_COND_EMPTY)) + csv_state &= ~(ST_CS_COND | ST_CS_COND_EMPTY); + else if (ALL(csv_state, ST_CS_COND)) + csv_state &= ~(ST_CS_COND | ST_CS_COND_NONEMPTY); + else + PRINTIF("%c", '/') pcsv_template++; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - if (csv_state & ST_CS_HEADER) + if (csv_state & ST_CS_COND) + { + conditional_index = *pcsv_template - '0'; + csv_state &= ~ST_CS_COND; + csv_state |= ST_CS_COND_NONEMPTY; + } + else if (csv_state & ST_CS_HEADER) { num = *pcsv_template - '0'; - fprintf(output, "%s", csv_header[num-1]); - csv_state &= ~(ST_CS_REGISTER | ST_CS_HEADER); + PRINTIF("%s", csv_header[num-1]) + csv_state &= ~ST_CS_HEADER; } else if (csv_state & ST_CS_REGISTER) { num = *pcsv_template - '0'; - fprintf(output, "%s", csv_register[num-1]); + PRINTIF("%s", csv_register[num-1]) csv_state &= ~ST_CS_REGISTER; } else - fprintf(output, "%c", *pcsv_template); + PRINTIF("%c", *pcsv_template) pcsv_template++; break; default: - if (csv_state & ST_CS_REGISTER) + if (csv_state & ST_CS_HEADER) + { + error(1, (uint8_t*)"csv: Invalid header register mark"); + csv_state &= ~ST_CS_HEADER; + } + else if (csv_state & ST_CS_REGISTER) { error(1, (uint8_t*)"csv: Invalid register mark"); csv_state &= ~ST_CS_REGISTER; } else - fprintf(output, "%c", *pcsv_template); + PRINTIF("%c", *pcsv_template) pcsv_template++; } } @@ -519,13 +594,13 @@ int process_csv(uint8_t* arg_token, FILE* output, BOOL read_yaml_macros_and_links, BOOL end_tag) { - if (read_yaml_macros_and_links) - return 0; - if (end_tag) { state &= ~ST_CSV_BODY; + if (read_yaml_macros_and_links) + return 0; + FILE* csv = fopen(csv_filename, "rt"); size_t csv_lineno = 0; uint8_t* bufline = NULL; @@ -665,6 +740,10 @@ process_csv(uint8_t* arg_token, FILE* output, BOOL read_yaml_macros_and_links, exit(error(1, (uint8_t*)"Can't nest csv directives")); state |= ST_CSV_BODY; + + if (read_yaml_macros_and_links) + return 0; + uint8_t* saveptr = NULL; uint8_t* args = u8_strtok(arg_token, (uint8_t*)" ", &saveptr); args = u8_strtok(NULL, (uint8_t*)" ", &saveptr); @@ -1419,7 +1498,7 @@ process_line_start(uint8_t* line, BOOL first_line_in_doc, BOOL list_para, FILE* output, uint8_t** token, uint8_t** ptoken) { if ((first_line_in_doc || previous_line_blank) - && !(state & (ST_BLOCKQUOTE | ST_PRE))) + && !(ANY(state, ST_BLOCKQUOTE | ST_PRE))) { if (!list_para) { @@ -1619,7 +1698,7 @@ begin_article(FILE* output, const BOOL add_article_header, const uint8_t* header_text, const char* title_heading_level, uint8_t* date, const BOOL ext_in_permalink, const char* permalink_url) { - if (title || date) + if (author || date || header_text || title) print_output(output, "<header>\n"); if (title) @@ -1661,7 +1740,7 @@ begin_article(FILE* output, const BOOL add_article_header, free(link); } - if (title || date) + if (author || date || header_text || title) print_output(output, "</header>\n"); return 0; @@ -1835,7 +1914,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, switch (*pline) { case '-': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_MACRO_BODY | ST_PRE | ST_YAML_VAL)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -1890,7 +1969,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case ':': if (state & ST_YAML - && !(state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + && !(ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HEADING | ST_IMAGE | ST_MACRO_BODY | ST_PRE | ST_TAG | ST_YAML_VAL)) && read_yaml_macros_and_links) @@ -1927,7 +2006,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '`': - if (state & (ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE + if (ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE | ST_MACRO_BODY)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -1952,10 +2031,10 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, /* Skip the rest of the line (language) */ pline = NULL; } - else if (!(state & (ST_PRE | ST_TAG | ST_YAML))) + else if (!ANY(state, ST_PRE | ST_TAG | ST_YAML)) { /* Handle ` within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { uint8_t* tag = state & ST_CODE @@ -1985,7 +2064,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_HEADING))) process_code(output, state & ST_CODE); } @@ -2003,7 +2082,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, case '#': if (colno == 1 - && !(state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + && !(ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_MACRO_BODY | ST_PRE | ST_YAML))) { state |= ST_HEADING; @@ -2026,7 +2105,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '_': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HTML_TAG | ST_IMAGE | ST_MACRO_BODY | ST_PRE | ST_TAG | ST_YAML)) { @@ -2038,7 +2117,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, if (u8_strlen(pline) > 1 && *(pline+1) == '_') { /* Handle __ within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { uint8_t* tag = state & ST_BOLD @@ -2068,7 +2147,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) process_bold(output, state & ST_BOLD); } @@ -2079,7 +2158,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, else { /* Handle _ within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { uint8_t* tag = state & ST_ITALIC @@ -2109,7 +2188,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) process_italic(output, state & ST_ITALIC); } @@ -2120,7 +2199,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '*': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HTML_TAG | ST_IMAGE | ST_MACRO_BODY | ST_PRE | ST_YAML)) { @@ -2151,7 +2230,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, else if (pline_len > 1 && *(pline+1) == '*') { /* Handle ** within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { uint8_t* tag = state & ST_BOLD @@ -2181,7 +2260,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) process_bold(output, state & ST_BOLD); } @@ -2192,7 +2271,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, else { /* Handle * within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { @@ -2223,7 +2302,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) process_italic(output, state & ST_ITALIC); } @@ -2234,7 +2313,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case ' ': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE | ST_MACRO_BODY | ST_PRE | ST_YAML_VAL)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2294,7 +2373,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '{': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HTML_TAG | ST_PRE | ST_YAML | ST_YAML_VAL)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2347,7 +2426,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '/': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE | ST_PRE | ST_HEADING | ST_YAML_VAL)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2367,7 +2446,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '}': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE | ST_PRE | ST_YAML | ST_YAML_VAL)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2392,7 +2471,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '|': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HTML_TAG | ST_IMAGE | ST_PRE | ST_TAG | ST_YAML)) { @@ -2404,7 +2483,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, if (u8_strlen(pline) > 1 && *(pline+1) == '|') { /* Handle || within footnotes, headings and link text specially */ - if (state & (ST_INLINE_FOOTNOTE | ST_HEADING + if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { uint8_t* tag = state & ST_KBD @@ -2434,7 +2513,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, processed_start_of_line = TRUE; if (!read_yaml_macros_and_links - && !(state & (ST_PRE | ST_CODE | ST_HEADING))) + && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) { state ^= ST_KBD; process_kbd(output, !(state & ST_KBD)); @@ -2453,15 +2532,15 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, case '<': if (read_yaml_macros_and_links - || (state & (ST_DISPLAY_FORMULA | ST_FORMULA - | ST_IMAGE))) + || ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA + | ST_IMAGE)) { CHECKCOPY(token, ptoken, token_size, pline) colno++; break; } - if (state & (ST_CODE | ST_KBD | ST_PRE)) + if (ANY(state, ST_CODE | ST_KBD | ST_PRE)) { size_t lt_len = u8_strlen((uint8_t*)"&lt;"); *ptoken = 0; @@ -2482,7 +2561,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, if (state & ST_HTML_TAG) state &= ~ST_HTML_TAG; - if (state & (ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE + if (ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA | ST_IMAGE | ST_MACRO_BODY)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2491,7 +2570,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, } if (!read_yaml_macros_and_links - && !(state & (ST_CODE | ST_HEADING | ST_PRE)) + && !ANY(state, ST_CODE | ST_HEADING | ST_PRE) && colno == 1) { if (!read_yaml_macros_and_links @@ -2511,7 +2590,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '!': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_FOOTNOTE_TEXT | ST_HEADING | ST_IMAGE | ST_INLINE_FOOTNOTE | ST_LINK | ST_MACRO_BODY | ST_PRE)) @@ -2547,7 +2626,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '=': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_MACRO_BODY | ST_PRE | ST_TAG)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2571,7 +2650,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, case '[': pline_len = u8_strlen(pline); - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HEADING | ST_IMAGE | ST_MACRO_BODY | ST_PRE)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2629,7 +2708,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '(': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_FOOTNOTE_TEXT | ST_HEADING | ST_INLINE_FOOTNOTE | ST_MACRO_BODY | ST_PRE)) CHECKCOPY(token, ptoken, token_size, pline) @@ -2657,7 +2736,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case ')': - if (state & (ST_DISPLAY_FORMULA | ST_FORMULA)) + if (ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA)) { CHECKCOPY(token, ptoken, token_size, pline) colno++; @@ -2685,7 +2764,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, } pline++; } - else if (state & (ST_LINK_SECOND_ARG | ST_IMAGE_SECOND_ARG)) + else if (ANY(state, ST_LINK_SECOND_ARG | ST_IMAGE_SECOND_ARG)) { *ptoken = 0; if (!read_yaml_macros_and_links) @@ -2710,7 +2789,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case ']': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_HEADING | ST_MACRO_BODY | ST_PRE)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -2844,7 +2923,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '^': - if (state & (ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_CODE | ST_DISPLAY_FORMULA | ST_FORMULA | ST_FOOTNOTE_TEXT | ST_IMAGE | ST_INLINE_FOOTNOTE | ST_PRE | ST_YAML)) { @@ -2876,7 +2955,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, case '\\': *ptoken = 0; - if (state & (ST_DISPLAY_FORMULA | ST_FORMULA + if (ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA | ST_HTML_TAG | ST_IMAGE | ST_LINK | ST_MACRO_BODY)) { @@ -2902,7 +2981,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, break; case '$': - if (state & (ST_CODE | ST_CSV_BODY | ST_IMAGE | ST_PRE + if (ANY(state, ST_CODE | ST_CSV_BODY | ST_IMAGE | ST_PRE | ST_YAML)) { CHECKCOPY(token, ptoken, token_size, pline) @@ -3012,7 +3091,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, REALLOC(token, uint8_t, token_size) ptoken = token + old_size - 1; } - u8_strncat(token, (state & (ST_IMAGE | ST_LINK)) + u8_strncat(token, ANY(state, ST_IMAGE | ST_LINK) ? (uint8_t*)" " : (uint8_t*)"\n", token_size - token_len - 1); ptoken++; @@ -3100,8 +3179,8 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, RESET_TOKEN(token, ptoken, token_size) heading_level = 0; } - else if (!(state & (ST_DISPLAY_FORMULA | ST_FORMULA - | ST_IMAGE | ST_LINK))) + else if (!ANY(state, ST_DISPLAY_FORMULA | ST_FORMULA + | ST_IMAGE | ST_LINK)) process_text_token(line, first_line_in_doc, previous_line_blank, processed_start_of_line, @@ -3110,7 +3189,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, TRUE); } - if (!(state & (ST_PRE | ST_IMAGE_SECOND_ARG | ST_LINK_SECOND_ARG)) + if (!ANY(state, ST_PRE | ST_IMAGE_SECOND_ARG | ST_LINK_SECOND_ARG) && (!*pbuffer || *pbuffer == '\n')) { if (state & ST_PARA_OPEN) @@ -3175,8 +3254,7 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL body_only, } if (!skip_eol && !keep_token && !read_yaml_macros_and_links - && !(state & (ST_YAML | ST_YAML_VAL - | ST_LINK_SECOND_ARG))) + && !ANY(state, ST_YAML | ST_YAML_VAL | ST_LINK_SECOND_ARG)) print_output(output, "\n"); if (!keep_token)