slweb

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

чување 09cb6170cb3cd833940dd479429918006af56b77
родитељ 71b7c4d23f7e10960b89b9168988cc5c9663d3da
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sun, 22 Aug 2021 11:32:51 +0200

WIP image size

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

Diffstat:
Mdefs.h | 4++++
Mslweb.1.in | 27+++++++++++++++++----------
Mslweb.c | 209++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
At.slw | 2++
измењених датотека: 4, додавања: 151(+), брисања: 91(-)

diff --git a/defs.h b/defs.h @@ -48,6 +48,10 @@ static const char CMD_KATEX[] = "katex"; static const char* CMD_KATEX_INLINE_ARGS[] = { "katex", NULL }; static const char* CMD_KATEX_DISPLAY_ARGS[] = { "katex", "-d", NULL }; +static const char* CMD_IDENTIFY = + "identify %s | sed -e's/.* \\([0-9]\\+\\)x\\([0-9]\\+\\)" + ".*/width=\"\\1\" height=\"\\2\"/g'"; + typedef enum { FALSE = 0, diff --git a/slweb.1.in b/slweb.1.in @@ -244,11 +244,19 @@ Which will produce: <figure> <a href="/path/to/image.png" title="Some title" class="image" target="_blank"><img src="/path/to/image.png" alt="Some title" - /></a><figcaption>Some title</figcaption> + width="100" height="50" /></a><figcaption>Some title</figcaption> </figure> .CDE . .IP +The attributes \fCwidth\fP and \fCheight\fP will be determined automatically +using the command +.BR identify (1) +(if present), provided the \fCsrc\fP attribute contains a valid file path. (Also +see +.BR image-file-prefix ). +. +.IP As with links, a form similar to the \[lq]regular form\[rq] of links can also be used, using the image id instead of the direct .SM URL. @@ -798,6 +806,14 @@ The contents of this variable will be added to the start of the output body (inside a \fC<header>\fP tag if it is set), surrounded by \fC<p></p>\fP. . .IP \[bu] +.BR image-file-prefix . +If present, the value of \fCsrc\fP attribute will be appended to the contents of +this variable, with path separator added as necessary, when determining the +actual file path to pass to the +.BR identify (1) +command. Otherwise, \fCsrc\fP is appended to \[lq].\[rq]. +. +.IP \[bu] .BR lang . Contents of this variable will be used for the \fClang\fP attribute of the \fC<html>\fP tag. @@ -869,15 +885,6 @@ provided to the directive. . .IP \[bu] -.BR samedir-permalink . -If set to \[lq]1\[rq], path in the permalink generated by the presence of -.I date -variable will be converted (with -.BR realpath (1)) -to be relative to the directory containing the input file. Otherwise, directory -in the permalink will remain unchanged. -. -.IP \[bu] .BR site-desc . The contents of this variable will be inserted as the value of the .I content diff --git a/slweb.c b/slweb.c @@ -171,8 +171,7 @@ slweb_cleanup() return 0; } -int -slweb_parse(u8* buffer, FILE* output, BOOL body_only, +int slweb_parse(u8* buffer, FILE* output, BOOL body_only, BOOL read_yaml_macros_and_links); BOOL @@ -234,8 +233,8 @@ set_basedir(char* arg, char** basedir, size_t* basedir_size) } int -set_global_link_prefix( - char* arg, char** global_link_prefix, size_t* global_link_prefix_size) +set_global_link_prefix(char* arg, char** global_link_prefix, + size_t* global_link_prefix_size) { size_t arg_len = strlen(arg); @@ -317,7 +316,7 @@ print_output(FILE* output, char* fmt, ...) return 0; } -#define PIPE_READ_INDEX 0 +#define PIPE_READ_INDEX 0 #define PIPE_WRITE_INDEX 1 int @@ -445,8 +444,7 @@ read_file_into_buffer(u8** buffer, size_t* buffer_size, char* input_filename, return 0; } -int -read_csv(FILE* output, const char* filename, csv_callback_t callback); +int read_csv(FILE* output, const char* filename, csv_callback_t callback); int print_meta_var(FILE* output, u8** csv_header, u8** csv_register) @@ -489,8 +487,8 @@ process_heading(u8* token, FILE* output, UBYTE heading_level) if (!token || strlen((char*)token) < 1) warning(1, (u8*)"Empty heading"); - print_output( - output, "%s</h%d>", token ? (char*)token : "", heading_level); + print_output(output, "%s</h%d>", token ? (char*)token : "", + heading_level); return 0; } @@ -845,9 +843,9 @@ process_csv(u8* arg_token, FILE* output, BOOL read_yaml_macros_and_links, csv_iter = 0; u8* saveptr = NULL; - u8* args = (u8*)strtok_r( - (char*)arg_token, " ", (char**)&saveptr); - args = (u8*)strtok_r(NULL, " ", (char**)&saveptr); + u8* args = (u8*)strtok_r((char*)arg_token, " ", + (char**)&saveptr); + args = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (!args) exit(error(EINVAL, (u8*)"csv: Arguments required")); size_t args_len = strlen((char*)args); @@ -1087,8 +1085,7 @@ reverse_alphacompare(const struct dirent** a, const struct dirent** b) return -1 * strcmp((*a)->d_name, (*b)->d_name); } -int -process_timestamp(FILE* output, const u8* link_prefix, const char* link, +int process_timestamp(FILE* output, const u8* link_prefix, const char* link, u8* permalink_macro, u8* date); int @@ -1274,8 +1271,8 @@ process_incdir(u8* token, const u8* link_prefix, FILE* output, errno = 0; num = strtol((char*)arg, NULL, 10); if (errno) - exit(error( - errno, (u8*)"incdir: Invalid parameter 'num'")); + exit(error(errno, + (u8*)"incdir: Invalid parameter 'num'")); arg = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (arg) { @@ -1286,15 +1283,15 @@ process_incdir(u8* token, const u8* link_prefix, FILE* output, (u8*)"incdir: Third argument not " "macro")); } - macro_body = get_value( - macros, macros_count, arg + 1, NULL); + macro_body = get_value(macros, macros_count, arg + 1, + NULL); } } print_output(output, "<ul class=\"incdir\">\n"); - if ((names_total = scandir( - incdir, &namelist, &filter_subdirs, &reverse_alphacompare)) + if ((names_total = scandir(incdir, &namelist, &filter_subdirs, + &reverse_alphacompare)) < 0) { perror("scandir"); @@ -1322,8 +1319,7 @@ process_incdir(u8* token, const u8* link_prefix, FILE* output, return 0; } -BOOL -url_is_local(const char* url); +BOOL url_is_local(const char* url); int process_timestamp(FILE* output, const u8* link_prefix, const char* link, @@ -1388,8 +1384,8 @@ process_timestamp_cleanup: } int -process_macro( - u8* token, FILE* output, BOOL read_yaml_macros_and_links, BOOL end_tag) +process_macro(u8* token, FILE* output, BOOL read_yaml_macros_and_links, + BOOL end_tag) { if (!end_tag) { @@ -1493,14 +1489,14 @@ process_tag(u8* token, const u8* link_prefix, FILE* output, } else if (startswith((char*)token, "incdir")) /* {incdir} */ { - process_incdir( - token, link_prefix, output, read_yaml_macros_and_links); + process_incdir(token, link_prefix, output, + read_yaml_macros_and_links); *skip_eol = TRUE; } else if (*token == '=') /* {=macro} */ { - process_macro( - token, output, read_yaml_macros_and_links, end_tag); + process_macro(token, output, read_yaml_macros_and_links, + end_tag); *skip_eol = TRUE; } else if (!read_yaml_macros_and_links) /* general tags */ @@ -1531,8 +1527,8 @@ process_tag(u8* token, const u8* link_prefix, FILE* output, token++; print_output(output, " class=\""); while (*token) - print_output( - output, "%c", *token++); + print_output(output, "%c", + *token++); print_output(output, "\""); } } @@ -1548,8 +1544,8 @@ process_tag(u8* token, const u8* link_prefix, FILE* output, token++; print_output(output, " id=\""); while (*token) - print_output( - output, "%c", *token++); + print_output(output, "%c", + *token++); print_output(output, "\""); } } @@ -1728,14 +1724,67 @@ process_link(u8* link_text, const u8* link_prefix, u8* link_macro_body, u8* link_id, FILE* output) { u8* url = get_value(links, links_count, link_id, NULL); - return process_inline_link( - link_text, link_prefix, link_macro_body, url, output); + return process_inline_link(link_text, link_prefix, link_macro_body, url, + output); +} + +int +print_image_dimensions(FILE* output, const u8* image_file_prefix, + const u8* path, int* width, int* height) +{ + struct stat sb; + FILE* cmd_output = NULL; + char command[BUFSIZE]; + char cmd_output_line[BUFSIZE]; + char* eol = NULL; + char image_path[BUFSIZE]; + + if (!path || !*path) + return 1; + + snprintf(image_path, BUFSIZE - 1, "%s%s%s", + image_file_prefix ? (char*)image_file_prefix : ".", + *path == '/' ? "" : "/", + path); + + char cwd[BUFSIZE]; + getcwd(cwd, BUFSIZE-1); + fprintf(stderr, "image-file-prefix: %s\n", + image_file_prefix ? (char*)image_file_prefix : "(NULL)"); + fprintf(stderr, "cwd: %s\n", cwd); + fprintf(stderr, "basedir: %s\n", basedir); + fprintf(stderr, "image_path: %s\n", image_path); + if (stat(image_path, &sb) < 0) + return 1; + + snprintf(command, BUFSIZE, CMD_IDENTIFY, image_path); + cmd_output = popen(command, "r"); + if (!cmd_output) + return error(errno, (u8*)"print_image_dimensions: Cannot popen"); + if (!fgets(cmd_output_line, BUFSIZE, cmd_output)) + goto print_dimensions_cleanup; + + eol = strchr((char*)cmd_output_line, '\n'); + if (eol) + *eol = 0; + + print_output(output, "%s", cmd_output_line); + output_firstcol = FALSE; + +print_dimensions_cleanup: + pclose(cmd_output); + + return 0; } int -process_inline_image(u8* image_text, const u8* link_prefix, u8* image_url, - FILE* output, BOOL add_link, BOOL add_figcaption) +process_inline_image(u8* image_text, const u8* image_file_prefix, + const u8* link_prefix, u8* image_url, FILE* output, BOOL add_link, + BOOL add_figcaption) { + int width = -1; + int height = -1; + if (add_figcaption) print_output(output, "<figure>\n"); @@ -1748,8 +1797,13 @@ process_inline_image(u8* image_text, const u8* link_prefix, u8* image_url, link_prefix ? (const char*)link_prefix : "", image_url ? (char*)image_url : "", image_text); - print_output(output, "<img src=\"%s\" alt=\"%s\" />", + print_output(output, "<img src=\"%s\" alt=\"%s\" ", image_url ? (char*)image_url : "", image_text); + if (image_url) + print_image_dimensions(output, image_file_prefix, image_url, + &width, &height); + print_output(output, "%s/>", image_url ? " " : ""); + output_firstcol = FALSE; if (add_link) @@ -1765,12 +1819,12 @@ process_inline_image(u8* image_text, const u8* link_prefix, u8* image_url, } int -process_image(u8* image_text, const u8* link_prefix, u8* image_id, FILE* output, - BOOL add_link, BOOL add_figcaption) +process_image(u8* image_text, const u8* image_file_prefix, const u8* link_prefix, + u8* image_id, FILE* output, BOOL add_link, BOOL add_figcaption) { u8* url = get_value(links, links_count, image_id, NULL); - return process_inline_image( - image_text, link_prefix, url, output, add_link, add_figcaption); + return process_inline_image(image_text, image_file_prefix, link_prefix, url, + output, add_link, add_figcaption); } int @@ -1884,7 +1938,7 @@ process_inline_footnote(u8* token, BOOL read_yaml_macros_and_links, FILE* output token_len + 1); strncpy((char*)inline_footnotes[inline_footnote_count - 1], - (char*)token, token_len+1); + (char*)token, token_len + 1); *(inline_footnotes[inline_footnote_count - 1] + token_len) = 0; } else @@ -1901,8 +1955,8 @@ process_inline_footnote(u8* token, BOOL read_yaml_macros_and_links, FILE* output } int -process_footnote( - u8* token, BOOL footnote_definition, BOOL footnote_output, FILE* output) +process_footnote(u8* token, BOOL footnote_definition, BOOL footnote_output, + FILE* output) { current_footnote++; @@ -2091,11 +2145,9 @@ begin_article(FILE* output, const u8* link_prefix, if (date && input_filename) { char* link = strip_ext(input_filename); - u8* samedir_permalink = get_value( - vars, vars_count, (u8*)"samedir-permalink", NULL); - char* real_link = NULL; - u8* permalink_macro = get_value( - macros, macros_count, (u8*)"permalink", NULL); + char* real_link = NULL; + u8* permalink_macro = get_value(macros, macros_count, + (u8*)"permalink", NULL); CALLOC(real_link, char, BUFSIZE); if (ext_in_permalink) @@ -2105,13 +2157,6 @@ begin_article(FILE* output, const u8* link_prefix, if (permalink_url) process_timestamp(output, link_prefix, permalink_url, permalink_macro, date); - else if (samedir_permalink - && !strcmp((char*)samedir_permalink, "1")) - { - get_realpath(&real_link, input_dirname, link); - process_timestamp(output, link_prefix, real_link, - permalink_macro, date); - } else process_timestamp(output, link_prefix, link, permalink_macro, date); @@ -2204,6 +2249,7 @@ slweb_parse(u8* buffer, FILE* output, BOOL body_only, u8* var_add_image_links = NULL; u8* var_add_figcaption = NULL; u8* var_add_footnote_div = NULL; + u8* image_file_prefix = NULL; u8* link_prefix = NULL; u8* pbuffer = NULL; u8* line = NULL; @@ -2241,6 +2287,8 @@ slweb_parse(u8* buffer, FILE* output, BOOL body_only, author = get_value(vars, vars_count, (u8*)"author", NULL); date = get_value(vars, vars_count, (u8*)"date", NULL); permalink_url = get_value(vars, vars_count, (u8*)"permalink-url", NULL); + image_file_prefix + = get_value(vars, vars_count, (u8*)"image-file-prefix", NULL); ext_in_permalink = get_value(vars, vars_count, (u8*)"ext-in-permalink", NULL); var_add_article_header @@ -2510,8 +2558,8 @@ do_line: if (!read_yaml_macros_and_links && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) - process_strike( - output, state & ST_STRIKE); + process_strike(output, + state & ST_STRIKE); } state ^= ST_STRIKE; @@ -2736,8 +2784,8 @@ do_line: if (!read_yaml_macros_and_links && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) - process_italic( - output, state & ST_ITALIC); + process_italic(output, + state & ST_ITALIC); } state ^= ST_ITALIC; @@ -2935,8 +2983,8 @@ do_line: if (!read_yaml_macros_and_links && !(ANY(state, ST_PRE | ST_CODE | ST_HEADING))) - process_italic( - output, state & ST_ITALIC); + process_italic(output, + state & ST_ITALIC); } state ^= ST_ITALIC; @@ -2960,8 +3008,8 @@ do_line: if (!read_yaml_macros_and_links) { heading_count++; - process_heading_start( - output, heading_level, heading_count); + process_heading_start(output, heading_level, + heading_count); output_firstcol = FALSE; } state |= ST_HEADING_TEXT; @@ -3237,7 +3285,7 @@ do_line: process_table_end(output); output_firstcol = TRUE; } - pline = NULL; + pline = NULL; break; default: @@ -3628,8 +3676,8 @@ do_line: token, output); else process_inline_image(link_text, - link_prefix, token, output, - add_image_links, + image_file_prefix, link_prefix, + token, output, add_image_links, add_figcaption); } RESET_TOKEN(token, ptoken, token_size); @@ -3655,8 +3703,8 @@ do_line: *ptoken = 0; if (state & ST_INLINE_FOOTNOTE) { - process_inline_footnote( - token, read_yaml_macros_and_links, output); + process_inline_footnote(token, + read_yaml_macros_and_links, output); keep_token = FALSE; RESET_TOKEN(token, ptoken, token_size); @@ -3709,9 +3757,9 @@ do_line: else if (state & ST_IMAGE_SECOND_ARG) { if (!read_yaml_macros_and_links) - process_image(link_text, link_prefix, token, - output, add_image_links, - add_figcaption); + process_image(link_text, image_file_prefix, + link_prefix, token, output, + add_image_links, add_figcaption); RESET_TOKEN(token, ptoken, token_size); state &= ~(ST_IMAGE | ST_IMAGE_SECOND_ARG); pline++; @@ -3732,8 +3780,8 @@ do_line: } else { - REALLOCARRAY( - links, KeyValue, links_count); + REALLOCARRAY(links, KeyValue, + links_count); plinks = links + links_count - 1; } CALLOC(plinks->key, u8, KEYSIZE); @@ -4167,8 +4215,8 @@ done_line: state &= ~(ST_HEADING | ST_HEADING_TEXT); if (!read_yaml_macros_and_links) { - process_heading( - token, output, heading_level); + process_heading(token, output, + heading_level); output_firstcol = FALSE; } first_line_in_doc = FALSE; @@ -4378,8 +4426,8 @@ main(int argc, char** argv) else if (startswith(arg, "basedir")) { arg += strlen("basedir"); - result = set_basedir( - arg, &basedir, &basedir_size); + result = set_basedir(arg, &basedir, + &basedir_size); if (result) return result; } @@ -4435,8 +4483,8 @@ main(int argc, char** argv) if (cmd == CMD_BASEDIR) { - result = set_basedir( - arg, &basedir, &basedir_size); + result = set_basedir(arg, &basedir, + &basedir_size); if (result) return result; } @@ -4527,4 +4575,3 @@ main(int argc, char** argv) return result; } - diff --git a/t.slw b/t.slw @@ -0,0 +1,2 @@ +![image](logo-social.webp) +