Compare commits

..

4 Commits
0.2 ... master

Author SHA1 Message Date
Matteo Bini e13c6d2caa Remove locale dependency 2024-09-08 13:03:29 +02:00
Matteo Bini f2d9c56a12 Clearer code 2024-09-08 11:44:14 +02:00
Matteo Bini 5298a48e41 Typo 2024-09-07 21:18:49 +02:00
Matteo Bini 556d7b6ff8 Function implementations in alphabetical order 2024-09-07 21:00:25 +02:00
2 changed files with 100 additions and 123 deletions

2
README
View File

@ -4,7 +4,7 @@ the suckless philosophy [2].
The idea of updating a website with a roff-like syntax comes from my
preference for the groff typesetting system, obviously, and because my
texts are written without discarding the possibility of an hard copy.
texts are written without discarding the possibility of a hard copy.
With the right macro package you could ask groff to make a PDF out of my
web page sources.

221
srohtml.c
View File

@ -1,4 +1,3 @@
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -7,6 +6,7 @@
/* macros */
#define BODY_START_SIZE 26624 /* 26 x 1024 byte = 26 KiB */
#define CLS_MAX 16
#define DATE_FORMAT "%d/%m/%Y"
#define DATE_LEN 10
#define FAVICON "data:image/gif;base64,R0lGODlhEAAQAKEAAAAAcP///wAAcAAAcCH5BAEKAAIALAAAAAAQABAAQAIwlBWZxxwAQWjtTQRvlZhTnGSfYT3eZ3WaE4mjGa1UasoH7c6tzYanfqmhJMKXglcAADs="
#define FIGCAPTION_TAG_LEN 12
@ -17,6 +17,7 @@
#define LINE_START 80
#define NOTES_START 8
#define NOTES_MAX_DIGITS 3
#define TIME_FORMAT "%H:%M"
typedef struct {
void *data;
@ -89,9 +90,7 @@ static void footer(void);
static void footnotes(void);
static int fputs_html(const char *str, FILE *f, const html_val_type t);
static size_t fread_line(FILE *file, char **str, size_t *len);
static void free_arrays(void);
static void indent_str(char **str, const int ind);
static void init_arrays(void);
static void nav_index(FILE *f);
static void outputs(FILE *out);
static void page_head(void);
@ -177,6 +176,17 @@ array_at(array *a, const size_t i)
return (char *) a->data + i * a->unit_size;
}
void
array_init(array *a, const size_t size, size_t num)
{
num = num == 0 ? 1 : num;
a->data = safe_malloc(size * num);
a->length = 0;
a->size = num;
a->unit_size = size;
}
void *
array_pop(array *a)
{
@ -199,6 +209,54 @@ array_push(array *a)
return (char *) a->data + a->length++ * a->unit_size;
}
char *
array_strcat(array *dst, const char *src)
{
char *c;
size_t i, len;
len = strlen(src);
for (i = 0; i < len; i++) {
c = array_push(dst);
*c = src[i];
}
c = array_push(dst);
*c = '\0';
dst->length--;
return dst->data;
}
char *
array_strcat_html(array *dst, const char *src, const html_val_type t)
{
char *c;
size_t i, len;
len = strlen(src);
for (i = 0; i < len; i++) {
if (t == tag_attribute && src[i] == '"')
array_strcat(dst, "&quot;");
else if (src[i] == '&')
array_strcat(dst, "&amp;");
else if (src[i] == '<')
array_strcat(dst, "&lt;");
else if (src[i] == '>')
array_strcat(dst, "&gt;");
else {
c = array_push(dst);
*c = src[i];
}
}
c = array_push(dst);
*c = '\0';
dst->length--;
return dst->data;
}
void
cmd(char *line)
{
@ -864,15 +922,14 @@ footer(void)
{
size_t max;
struct tm *now;
char str[16];
char str[22];
time_t s;
int tm_mday, tm_mon, tm_year;
struct tm tm_pd = { 0 };
max = 16;
max = 22;
array_strcat(&body, "\t\t<footer>\n");
setlocale(LC_ALL, "");
if (publication_date != NULL) {
array_strcat(&body, "\t\t\t<p>Pubblicazione: <time datetime=\"");
@ -883,7 +940,7 @@ footer(void)
tm_pd.tm_mday = tm_mday;
tm_pd.tm_mon = --tm_mon;
tm_pd.tm_year = tm_year - 1900;
strftime(str, max, "%x", &tm_pd);
strftime(str, max, DATE_FORMAT, &tm_pd);
array_strcat(&body, str);
array_strcat(&body, "</time></p>\n");
@ -894,21 +951,11 @@ footer(void)
now = localtime(&s);
array_strcat(&body, "\t\t\t<p>Revisione: <time datetime=\"");
strftime(str, max, "%Y-%m-%d", now);
array_strcat(&body, str);
strftime(str, max, "%R", now);
array_strcat(&body, "T");
array_strcat(&body, str);
strftime(str, max, "%z", now);
strftime(str, max, "%Y-%m-%dT%H:%M%z", now);
array_strcat(&body, str);
array_strcat(&body, "\">");
strftime(str, max, "%x", now);
array_strcat_html(&body, str, tag_content);
strftime(str, max, " %R", now);
strftime(str, max, DATE_FORMAT " " TIME_FORMAT, now);
array_strcat_html(&body, str, tag_content);
array_strcat(&body, "</time></p>\n");
@ -1020,16 +1067,6 @@ fread_line(FILE *file, char **str, size_t *len)
return c == EOF ? EOF : i;
}
void
free_arrays(void)
{
free(head.data);
free(body.data);
free(figure_sizes.data);
free(index.data);
free(sitography.data);
}
void
indent_str(char **str, const int ind)
{
@ -1045,29 +1082,8 @@ indent_str(char **str, const int ind)
(*str)[ind] = '\0';
}
void
init_arrays(void)
{
array_init(&head, sizeof(char), BODY_START_SIZE / 4);
array_init(&body, sizeof(char), BODY_START_SIZE);
array_init(&figure_sizes, sizeof(img), FIGURE_SIZES_START);
array_init(&index, sizeof(index_title), INDEX_START);
array_init(&sitography, sizeof(note), NOTES_START);
}
void
array_init(array *a, const size_t size, size_t num)
{
num = num == 0 ? 1 : num;
a->data = safe_malloc(size * num);
a->length = 0;
a->size = num;
a->unit_size = size;
}
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
FILE *in, *out;
@ -1106,6 +1122,9 @@ main (int argc, char *argv[])
srohtml(in, out);
fclose(in);
fclose(out);
return 0;
}
@ -1443,6 +1462,23 @@ page_head(void)
array_strcat(&head, "\t</head>\n");
}
void
pop_closure(array *a)
{
closure *tag;
if (a->length <= 0)
return;
tag = array_at(a, a->length - 1);
if (tag == NULL) {
fprintf(stderr, BIN ": Can't find tag closure at position %i, in array type.\n", a->length - 1);
exit(1);
}
free(tag->name);
array_pop(a);
}
void
print_help(void)
{
@ -1514,23 +1550,9 @@ read_and_process(FILE *in)
line = NULL;
}
free(line);
}
void
pop_closure(array *a)
{
closure *tag;
if (a->length <= 0)
return;
tag = array_at(a, a->length - 1);
if (tag == NULL) {
fprintf(stderr, BIN ": Can't find tag closure at position %i, in array type.\n", a->length - 1);
exit(1);
}
free(tag->name);
array_pop(a);
if (strcmp(tag_closure, ""))
cmd_close();
}
void *
@ -1564,23 +1586,26 @@ safe_realloc(void *ptr, const size_t size)
void
srohtml(FILE *in, FILE *out)
{
init_arrays();
array_init(&head, sizeof(char), BODY_START_SIZE / 4);
array_init(&body, sizeof(char), BODY_START_SIZE);
array_init(&figure_sizes, sizeof(img), FIGURE_SIZES_START);
array_init(&index, sizeof(index_title), INDEX_START);
array_init(&sitography, sizeof(note), NOTES_START);
array_strcat(&body, "\t<body>\n");
read_and_process(in);
fclose(in);
if (strcmp(tag_closure, ""))
cmd_close();
page_head();
footnotes();
footer();
array_strcat(&body, "\t</body>\n</html>\n");
outputs(out);
fclose(out);
free_arrays();
free(head.data);
free(body.data);
free(figure_sizes.data);
free(index.data);
free(sitography.data);
}
size_t
@ -1615,51 +1640,3 @@ stread_param(const char *src, char **str)
return len + p;
}
char *
array_strcat(array *dst, const char *src)
{
char *c;
size_t i, len;
len = strlen(src);
for (i = 0; i < len; i++) {
c = array_push(dst);
*c = src[i];
}
c = array_push(dst);
*c = '\0';
dst->length--;
return dst->data;
}
char *
array_strcat_html(array *dst, const char *src, const html_val_type t)
{
char *c;
size_t i, len;
len = strlen(src);
for (i = 0; i < len; i++) {
if (t == tag_attribute && src[i] == '"')
array_strcat(dst, "&quot;");
else if (src[i] == '&')
array_strcat(dst, "&amp;");
else if (src[i] == '<')
array_strcat(dst, "&lt;");
else if (src[i] == '>')
array_strcat(dst, "&gt;");
else {
c = array_push(dst);
*c = src[i];
}
}
c = array_push(dst);
*c = '\0';
dst->length--;
return dst->data;
}