2024-07-13 17:20:31 +00:00
|
|
|
#include <locale.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
/* macros */
|
|
|
|
#define BODY_START_SIZE 26624 /* 26 x 1024 byte = 26 KiB */
|
|
|
|
#define CLS_MAX 8
|
|
|
|
#define DATE_LEN 10
|
|
|
|
#define FAVICON "data:image/gif;base64,R0lGODlhEAAQAKEAAAAAcP///wAAcAAAcCH5BAEKAAIALAAAAAAQABAAQAIwlBWZxxwAQWjtTQRvlZhTnGSfYT3eZ3WaE4mjGa1UasoH7c6tzYanfqmhJMKXglcAADs="
|
|
|
|
#define LANG_LEN 2
|
|
|
|
#define LINE_MAX 1000
|
|
|
|
#define NOTES_START 8
|
|
|
|
#define NOTES_MAX_DIGITS 3
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char *desc;
|
|
|
|
char *href;
|
|
|
|
} note;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
size_t index;
|
|
|
|
size_t size;
|
|
|
|
note *notes;
|
|
|
|
} references;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
size_t len;
|
|
|
|
size_t size;
|
|
|
|
char *str;
|
|
|
|
} string;
|
|
|
|
|
|
|
|
/* function declarations */
|
|
|
|
static size_t add_note(const char *href, const char *desc);
|
|
|
|
static void cmd(char *line);
|
|
|
|
static void cmd_close(void);
|
|
|
|
static void cmd_a(const char *line);
|
|
|
|
static void cmd_au_de_ti(char **str, const char *line);
|
|
|
|
static void cmd_dt(const char *line);
|
|
|
|
static void cmd_h(const char *line);
|
|
|
|
static void cmd_hr(void);
|
|
|
|
static void cmd_la(const char *line);
|
|
|
|
static void cmd_le(void);
|
|
|
|
static void cmd_ls(void);
|
|
|
|
static void cmd_no(const char *line);
|
|
|
|
static void cmd_p(void);
|
|
|
|
static void cmd_pd(const char *line);
|
|
|
|
static void cmd_st(const char *line);
|
|
|
|
static void cmd_tm(const char *line);
|
|
|
|
static void cmd_ur(const char *line);
|
|
|
|
static void footer(void);
|
|
|
|
static void footnotes(void);
|
|
|
|
static int fread_line(FILE *file, char **str, size_t *len);
|
|
|
|
static void indent_str(char **str);
|
|
|
|
static void page_head(void);
|
|
|
|
static void *safe_malloc(const size_t size);
|
|
|
|
static void *safe_realloc(void *ptr, const size_t size);
|
|
|
|
static size_t stread_param(const char *src, char **str);
|
|
|
|
static char *string_cat(string *dst, const char *src);
|
|
|
|
static char *string_cat_html(string *dst, const char *src, const int is_attr_val);
|
|
|
|
static void string_enlarge(string *old, const size_t size);
|
|
|
|
static int string_putc(string *dst, const char c);
|
|
|
|
|
|
|
|
/* variables */
|
|
|
|
char *author = NULL;
|
|
|
|
char closure[CLS_MAX];
|
|
|
|
char *description = NULL;
|
|
|
|
int indentation = 2;
|
|
|
|
char language[LANG_LEN + 1] = "";
|
|
|
|
int licence_container = 0;
|
|
|
|
int space = 0;
|
|
|
|
string head;
|
|
|
|
string body;
|
|
|
|
char pub_date[DATE_LEN + 1] = "";
|
|
|
|
references sitography;
|
|
|
|
char *title = NULL;
|
|
|
|
|
|
|
|
/* function implementations */
|
|
|
|
size_t
|
|
|
|
add_note(const char *href, const char *desc)
|
|
|
|
{
|
|
|
|
note *new;
|
|
|
|
|
|
|
|
if (sitography.index == sitography.size) {
|
|
|
|
sitography.size *= 2;
|
|
|
|
sitography.notes = safe_realloc(sitography.notes, sizeof(note) * sitography.size);
|
|
|
|
}
|
|
|
|
|
|
|
|
new = sitography.notes + sitography.index;
|
|
|
|
new->href = safe_malloc(sizeof(char) * (strlen(href) + 1));
|
|
|
|
strcpy(new->href, href);
|
|
|
|
new->desc = safe_malloc(sizeof(char) * (strlen(desc) + 1));
|
|
|
|
strcpy(new->desc, desc);
|
|
|
|
sitography.index++;
|
|
|
|
|
|
|
|
return sitography.index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd(char *line)
|
|
|
|
{
|
|
|
|
char *end;
|
|
|
|
size_t cmdlen;
|
|
|
|
|
|
|
|
if (!(end = strchr(line, ' ')))
|
|
|
|
end = line + strlen(line);
|
|
|
|
cmdlen = end - ++line;
|
|
|
|
|
|
|
|
if (!strncmp(line, "A", cmdlen))
|
|
|
|
cmd_a(line);
|
|
|
|
else if (!strncmp(line, "AU", cmdlen))
|
|
|
|
cmd_au_de_ti(&author, line);
|
|
|
|
else if (!strncmp(line, "DE", cmdlen))
|
|
|
|
cmd_au_de_ti(&description, line);
|
|
|
|
else if (!strncmp(line, "DT", cmdlen))
|
|
|
|
cmd_dt(line);
|
|
|
|
else if (!strncmp(line, "H1", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "H2", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "H3", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "H4", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "H5", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "H6", cmdlen))
|
|
|
|
cmd_h(line);
|
|
|
|
else if (!strncmp(line, "HR", cmdlen))
|
|
|
|
cmd_hr();
|
|
|
|
else if (!strncmp(line, "LA", cmdlen))
|
|
|
|
cmd_la(line);
|
|
|
|
else if (!strncmp(line, "LE", cmdlen))
|
|
|
|
cmd_le();
|
|
|
|
else if (!strncmp(line, "LS", cmdlen))
|
|
|
|
cmd_ls();
|
|
|
|
else if (!strncmp(line, "NO", cmdlen))
|
|
|
|
cmd_no(line);
|
|
|
|
else if (!strncmp(line, "P", cmdlen))
|
|
|
|
cmd_p();
|
|
|
|
else if (!strncmp(line, "PD", cmdlen))
|
|
|
|
cmd_pd(line);
|
|
|
|
else if (!strncmp(line, "ST", cmdlen))
|
|
|
|
cmd_st(line);
|
|
|
|
else if (!strncmp(line, "TI", cmdlen))
|
|
|
|
cmd_au_de_ti(&title, line);
|
|
|
|
else if (!strncmp(line, "TM", cmdlen))
|
|
|
|
cmd_tm(line);
|
|
|
|
else if (!strncmp(line, "UR", cmdlen))
|
|
|
|
cmd_ur(line);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_a(const char *line)
|
|
|
|
{
|
|
|
|
char *href, *in, *title;
|
|
|
|
|
|
|
|
href = NULL;
|
|
|
|
in = NULL;
|
|
|
|
title = NULL;
|
|
|
|
|
|
|
|
/* move past "A" */
|
|
|
|
line += 1;
|
|
|
|
/* move past arguments, once found them */
|
|
|
|
line += stread_param(line, &href);
|
|
|
|
line += stread_param(line, &in);
|
|
|
|
line += stread_param(line, &title);
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat(&body, "<a class=\"");
|
|
|
|
if (!strcmp(href, in))
|
|
|
|
string_cat(&body, "url");
|
|
|
|
else
|
|
|
|
string_cat(&body, "nav");
|
|
|
|
string_cat(&body, "\" href=\"");
|
|
|
|
string_cat(&body, href);
|
|
|
|
string_cat(&body, "\"");
|
|
|
|
if (strcmp(title, "")) {
|
|
|
|
string_cat(&body, " title=\"");
|
|
|
|
string_cat_html(&body, title, 1);
|
|
|
|
string_cat(&body, "\"");
|
|
|
|
}
|
|
|
|
string_cat(&body, ">");
|
|
|
|
string_cat_html(&body, in, 1);
|
|
|
|
string_cat(&body, "</a>");
|
|
|
|
|
|
|
|
free(href);
|
|
|
|
free(in);
|
|
|
|
free(title);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_au_de_ti(char **str, const char *line)
|
|
|
|
{
|
|
|
|
/* move past command */
|
|
|
|
line += 2;
|
|
|
|
/* move past ' ', if present */
|
|
|
|
if (line[0] == ' ')
|
|
|
|
line++;
|
|
|
|
|
|
|
|
if (*str != NULL)
|
|
|
|
free(*str);
|
|
|
|
|
|
|
|
*str = safe_malloc(sizeof(char) * (strlen(line) + 1));
|
|
|
|
strcpy(*str, line);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_close(void)
|
|
|
|
{
|
|
|
|
string_cat(&body, closure);
|
|
|
|
string_cat(&body, "\n");
|
|
|
|
strcpy(closure, "");
|
|
|
|
space = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_dt(const char *line)
|
|
|
|
{
|
|
|
|
char *datetime, *in;
|
|
|
|
|
|
|
|
datetime = NULL;
|
|
|
|
in = NULL;
|
|
|
|
|
|
|
|
/* move past "DT" */
|
|
|
|
line += 2;
|
|
|
|
/* move past arguments, once found them */
|
|
|
|
line += stread_param(line, &datetime);
|
|
|
|
line += stread_param(line, &in);
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat(&body, "<time datetime=\"");
|
|
|
|
string_cat_html(&body, datetime, 1);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
if (!strcmp(in, ""))
|
|
|
|
string_cat_html(&body, datetime, 0);
|
|
|
|
else
|
|
|
|
string_cat_html(&body, in, 0);
|
|
|
|
string_cat(&body, "</time>");
|
|
|
|
|
|
|
|
free(datetime);
|
|
|
|
free(in);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_h(const char *line)
|
|
|
|
{
|
|
|
|
string_cat(&body, "\t\t<h");
|
|
|
|
string_putc(&body, line[1]);
|
|
|
|
if (line[2] == ' ' && line[3] != '\0') {
|
|
|
|
string_cat(&body, " id=\"");
|
|
|
|
string_cat_html(&body, line + 3, 1);
|
|
|
|
string_cat(&body, "\"");
|
|
|
|
}
|
|
|
|
string_cat(&body, ">");
|
|
|
|
strcpy(closure, "</h");
|
|
|
|
closure[3] = line[1];
|
|
|
|
closure[4] = '>';
|
|
|
|
closure[5] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_hr(void)
|
|
|
|
{
|
|
|
|
string_cat(&body, "\t\t<hr>");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_la(const char *line)
|
|
|
|
{
|
|
|
|
/* move past "LA" */
|
|
|
|
line += 2;
|
|
|
|
/* move past ' ', if present */
|
|
|
|
if (line[0] == ' ')
|
|
|
|
line++;
|
|
|
|
|
|
|
|
if (strlen(line) != LANG_LEN)
|
|
|
|
return;
|
|
|
|
|
|
|
|
strncpy(language, line, LANG_LEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_le(void)
|
|
|
|
{
|
|
|
|
char *ind;
|
|
|
|
|
|
|
|
ind = NULL;
|
|
|
|
|
|
|
|
indentation--;
|
|
|
|
indent_str(&ind);
|
|
|
|
string_cat(&body, ind);
|
|
|
|
string_cat(&body, "</div>\n");
|
|
|
|
|
|
|
|
free(ind);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_ls(void)
|
|
|
|
{
|
|
|
|
char *ind;
|
|
|
|
|
|
|
|
ind = NULL;
|
|
|
|
licence_container = 1;
|
|
|
|
|
|
|
|
indent_str(&ind);
|
|
|
|
string_cat(&body, ind);
|
|
|
|
string_cat(&body, "<div class=\"contenitore-licenza\">\n");
|
|
|
|
indentation++;
|
|
|
|
|
|
|
|
free(ind);
|
|
|
|
ind = NULL;
|
|
|
|
indent_str(&ind);
|
|
|
|
string_cat(&body, ind);
|
|
|
|
string_cat(&body, "<hr>\n");
|
|
|
|
|
|
|
|
free(ind);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_no(const char *line)
|
|
|
|
{
|
|
|
|
char *desc, *href, *title;
|
|
|
|
char index[NOTES_MAX_DIGITS + 1];
|
|
|
|
|
|
|
|
desc = NULL;
|
|
|
|
href = NULL;
|
|
|
|
title = NULL;
|
|
|
|
|
|
|
|
/* move past "NO" */
|
|
|
|
line += 2;
|
|
|
|
/* move past arguments, once found them */
|
|
|
|
line += stread_param(line, &href);
|
|
|
|
line += stread_param(line, &desc);
|
|
|
|
line += stread_param(line, &title);
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
sprintf(index, "%u", add_note(href, desc));
|
|
|
|
string_cat(&body, "<sup><a id=\"nota-");
|
|
|
|
string_cat(&body, index);
|
|
|
|
string_cat(&body, "\" class=\"nav\" href=\"#sitografia-");
|
|
|
|
string_cat(&body, index);
|
|
|
|
string_cat(&body, "\"");
|
|
|
|
if (strcmp(title, "")) {
|
|
|
|
string_cat(&body, " title=\"");
|
|
|
|
string_cat_html(&body, title, 1);
|
|
|
|
string_cat(&body, "\"");
|
|
|
|
}
|
|
|
|
string_cat(&body, ">[");
|
|
|
|
string_cat(&body, index);
|
|
|
|
string_cat(&body, "]</a></sup>");
|
|
|
|
|
|
|
|
free(desc);
|
|
|
|
free(href);
|
|
|
|
free(title);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_p(void)
|
|
|
|
{
|
|
|
|
char *ind;
|
|
|
|
|
|
|
|
ind = NULL;
|
|
|
|
|
|
|
|
indent_str(&ind);
|
|
|
|
string_cat(&body, ind);
|
|
|
|
string_cat(&body, "<p>");
|
|
|
|
strcpy(closure, "</p>");
|
|
|
|
|
|
|
|
free(ind);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_pd(const char *line)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
/* move past "PD" */
|
|
|
|
line += 2;
|
|
|
|
|
|
|
|
len = strlen(line);
|
|
|
|
/* move past ' ' after PD */
|
|
|
|
if (len && line[0] == ' ') {
|
|
|
|
line++;
|
|
|
|
len--;
|
|
|
|
if (len == DATE_LEN)
|
|
|
|
strncpy(pub_date, line, DATE_LEN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_st(const char *line)
|
|
|
|
{
|
|
|
|
/* move past "ST" */
|
|
|
|
line += 2;
|
|
|
|
/* move past space, if present */
|
|
|
|
if (line[0] == ' ')
|
|
|
|
line++;
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat(&body, "<strong>");
|
|
|
|
string_cat(&body, line);
|
|
|
|
string_cat(&body, "</strong>");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_tm(const char *line)
|
|
|
|
{
|
|
|
|
char *date, *hours, *in;
|
|
|
|
|
|
|
|
/* move past "TM" */
|
|
|
|
line += 2;
|
|
|
|
/* move past arguments, once found them */
|
|
|
|
line += stread_param(line, &date);
|
|
|
|
line += stread_param(line, &hours);
|
|
|
|
line += stread_param(line, &in);
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat(&body, "<time datetime=\"");
|
|
|
|
string_cat(&body, date);
|
|
|
|
if (strcmp(hours, "")) {
|
|
|
|
string_cat(&body, "T");
|
|
|
|
string_cat(&body, hours);
|
|
|
|
}
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
string_cat_html(&body, in, 0);
|
|
|
|
string_cat(&body, "</time>");
|
|
|
|
|
|
|
|
free(date);
|
|
|
|
free(hours);
|
|
|
|
free(in);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_ur(const char *line)
|
|
|
|
{
|
|
|
|
/* move past "UR" */
|
|
|
|
line += 2;
|
|
|
|
/* move past ' ', if present */
|
|
|
|
if (line[0] == ' ')
|
|
|
|
line++;
|
|
|
|
|
|
|
|
if (space)
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat(&body, "<<a class=\"url\" href=\"");
|
|
|
|
string_cat_html(&body, line, 1);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
string_cat_html(&body, line, 0);
|
|
|
|
string_cat(&body, "</a>>");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
footer(void)
|
|
|
|
{
|
|
|
|
size_t max;
|
|
|
|
struct tm *now;
|
|
|
|
char str[16];
|
|
|
|
time_t s;
|
|
|
|
int tm_mday, tm_mon, tm_year;
|
|
|
|
struct tm tm_pd = { 0 };
|
|
|
|
|
|
|
|
max = 16;
|
|
|
|
|
|
|
|
string_cat(&body, "\t\t<footer>\n");
|
|
|
|
|
|
|
|
if (strcmp(pub_date, "")) {
|
|
|
|
string_cat(&body, "\t\t\t<p>Pubblicazione: <time datetime=\"");
|
|
|
|
string_cat(&body, pub_date);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
|
|
|
|
sscanf(pub_date, "%4i-%2i-%2i", &tm_year, &tm_mon, &tm_mday);
|
|
|
|
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);
|
|
|
|
string_cat(&body, str);
|
|
|
|
string_cat(&body, "</time></p>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
s = time(NULL);
|
|
|
|
now = localtime(&s);
|
|
|
|
|
|
|
|
string_cat(&body, "\t\t\t<p>Revisione: <time datetime=\"");
|
|
|
|
strftime(str, max, "%Y-%m-%d", now);
|
|
|
|
string_cat(&body, str);
|
|
|
|
|
|
|
|
strftime(str, max, "%R", now);
|
|
|
|
string_cat(&body, "T");
|
|
|
|
string_cat(&body, str);
|
|
|
|
|
|
|
|
strftime(str, max, "%z", now);
|
|
|
|
string_cat(&body, str);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
|
|
|
|
strftime(str, max, "%x", now);
|
|
|
|
string_cat_html(&body, str, 0);
|
|
|
|
|
|
|
|
strftime(str, max, " %R", now);
|
|
|
|
string_cat_html(&body, str, 0);
|
|
|
|
string_cat(&body, "</time></p>\n");
|
|
|
|
|
|
|
|
string_cat(&body, "\t\t</footer>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
footnotes(void)
|
|
|
|
{
|
|
|
|
note *cur;
|
|
|
|
size_t i, dig_num, x;
|
|
|
|
char id[NOTES_MAX_DIGITS + 1];
|
|
|
|
char pad[6 * (NOTES_MAX_DIGITS - 1) + 1];
|
|
|
|
|
|
|
|
if (sitography.index == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
string_cat(&body, "\t\t<hr>\n");
|
|
|
|
string_cat(&body, "\t\t<div class=\"contenitore-sitografia\">\n");
|
|
|
|
string_cat(&body, "\t\t\t<h3 id=\"sitografia\">Sitografia</h3>\n");
|
|
|
|
|
|
|
|
sprintf(id, "%u", sitography.index);
|
|
|
|
dig_num = strlen(id);
|
|
|
|
|
|
|
|
for (i = 0; i < sitography.index; i++) {
|
|
|
|
cur = sitography.notes + i;
|
|
|
|
sprintf(id, "%u", i + 1);
|
|
|
|
string_cat(&body, "\t\t\t<p id=\"sitografia-");
|
|
|
|
string_cat(&body, id);
|
|
|
|
string_cat(&body, "\"><span>");
|
|
|
|
strcpy(pad, "");
|
|
|
|
for (x = strlen(id); x < dig_num; x++)
|
|
|
|
strcat(pad, " ");
|
|
|
|
string_cat(&body, pad);
|
|
|
|
string_cat(&body, "<a class=\"nav\" href=\"#nota-");
|
|
|
|
string_cat(&body, id);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
string_cat(&body, id);
|
|
|
|
string_cat(&body, "</a></span> ");
|
|
|
|
if (strcmp(cur->desc, "")) {
|
|
|
|
string_cat_html(&body, cur->desc, 0);
|
|
|
|
string_cat(&body, " ");
|
|
|
|
}
|
|
|
|
string_cat(&body, "<<a class=\"url\" href=\"");
|
|
|
|
string_cat(&body, cur->href);
|
|
|
|
string_cat(&body, "\">");
|
|
|
|
string_cat_html(&body, cur->href, 0);
|
|
|
|
string_cat(&body, "</a>></p>\n");
|
|
|
|
free(cur->desc);
|
|
|
|
free(cur->href);
|
|
|
|
}
|
|
|
|
free(sitography.notes);
|
|
|
|
|
|
|
|
string_cat(&body, "\t\t</div>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fread_line(FILE *file, char **str, size_t *len)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
char *end;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while ((c = fgetc(file)) && c != '\n' && c != EOF && i < LINE_MAX)
|
|
|
|
i++;
|
|
|
|
|
|
|
|
*str = safe_malloc(i + 1);
|
|
|
|
|
|
|
|
fseek(file, -i - 1, SEEK_CUR);
|
|
|
|
fread(*str, 1, i, file);
|
|
|
|
(*str)[i] = '\0';
|
|
|
|
*len = i;
|
|
|
|
fseek(file, 1, SEEK_CUR);
|
|
|
|
|
|
|
|
return c == EOF ? EOF : c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
indent_str(char **str)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
*str = safe_malloc(sizeof(char) * (indentation + 1));
|
|
|
|
for (i = 0; i < indentation; i++)
|
|
|
|
(*str)[i] = '\t';
|
|
|
|
(*str)[indentation] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
{
|
|
|
|
FILE *in, *out;
|
|
|
|
size_t len;
|
|
|
|
char *line;
|
|
|
|
|
|
|
|
setlocale(LC_ALL, "");
|
|
|
|
|
|
|
|
in = fopen(argv[1], "r");
|
|
|
|
if (in == NULL) {
|
2024-07-15 08:40:34 +00:00
|
|
|
fprintf(stderr, BIN ": Can't open %s.\n", argv[1]);
|
2024-07-13 17:20:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
head.size = BODY_START_SIZE / 4;
|
|
|
|
head.str = safe_malloc(head.size);
|
|
|
|
strcpy(head.str, "");
|
|
|
|
head.len = 0;
|
|
|
|
|
|
|
|
body.size = BODY_START_SIZE;
|
|
|
|
body.str = safe_malloc(body.size);
|
|
|
|
strcpy(body.str, "");
|
|
|
|
body.len = 0;
|
|
|
|
|
|
|
|
string_cat(&body, "\t<body>\n");
|
|
|
|
|
|
|
|
sitography.index = 0;
|
|
|
|
sitography.size = NOTES_START;
|
|
|
|
sitography.notes = malloc(sizeof(note) * sitography.size);
|
|
|
|
|
|
|
|
while (fread_line(in, &line, &len) != EOF) {
|
|
|
|
if (!len)
|
|
|
|
cmd_close();
|
|
|
|
else if (len >= 2 && line[0] == '.')
|
|
|
|
cmd(line);
|
|
|
|
else if (len >= 2 && line[0] == '\\' && line[1] == '"')
|
|
|
|
continue;
|
|
|
|
else {
|
|
|
|
if (space &&
|
|
|
|
line[0] != '!' &&
|
|
|
|
line[0] != ',' &&
|
|
|
|
line[0] != '.' &&
|
|
|
|
line[0] != '.' &&
|
|
|
|
line[0] != ';' &&
|
|
|
|
line[0] != '?')
|
|
|
|
string_cat(&body, " ");
|
|
|
|
string_cat_html(&body, line, 0);
|
|
|
|
space = 1;
|
|
|
|
}
|
|
|
|
free(line);
|
|
|
|
}
|
|
|
|
free(line);
|
|
|
|
fclose(in);
|
|
|
|
|
|
|
|
if (strcmp(closure, ""))
|
|
|
|
cmd_close();
|
|
|
|
|
|
|
|
page_head();
|
|
|
|
footnotes();
|
|
|
|
footer();
|
|
|
|
|
|
|
|
string_cat(&body, "\t</body>\n</html>\n");
|
|
|
|
|
|
|
|
if (argc < 3)
|
|
|
|
out = stdout;
|
|
|
|
else
|
|
|
|
out = fopen(argv[2], "w");
|
|
|
|
if (out == NULL) {
|
2024-07-15 08:40:34 +00:00
|
|
|
fprintf(stderr, BIN ": Can't open %s.\n", argv[2]);
|
2024-07-13 17:20:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fputs(head.str, out);
|
|
|
|
fputs(body.str, out);
|
|
|
|
fclose(out);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
page_head(void)
|
|
|
|
{
|
|
|
|
string_cat(&head, "<!doctype html>\n");
|
|
|
|
|
|
|
|
string_cat(&head, "<html lang=\"");
|
|
|
|
string_cat_html(&head, language, 1);
|
|
|
|
string_cat(&head, "\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t<head>\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<link rel=\"icon\" href=\"" FAVICON "\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<meta charset=\"utf-8\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<meta name=\"author\" content=\"");
|
|
|
|
string_cat_html(&head, author, 1);
|
|
|
|
string_cat(&head, "\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<meta name=\"description\" content=\"");
|
|
|
|
string_cat_html(&head, description, 1);
|
|
|
|
string_cat(&head, "\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<style>\n" \
|
|
|
|
" body {\n" \
|
|
|
|
" margin: .5em auto;\n" \
|
|
|
|
" max-width: 50em;\n" \
|
|
|
|
" width: 90%;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" p {\n" \
|
|
|
|
" line-height: 1.5;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" a.url {\n" \
|
2024-07-15 07:58:28 +00:00
|
|
|
" hyphens: manual;\n" \
|
2024-07-13 17:20:31 +00:00
|
|
|
" word-wrap: break-word;\n" \
|
|
|
|
" }\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (licence_container) {
|
|
|
|
string_cat(&head, "\n" \
|
|
|
|
" .contenitore-licenza {\n" \
|
|
|
|
" font-size: .8em;\n" \
|
|
|
|
" text-align: justify;\n" \
|
|
|
|
" }\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sitography.index > 0) {
|
|
|
|
string_cat(&head, "\n" \
|
|
|
|
" sup {\n" \
|
|
|
|
" font-size: .7em;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" .contenitore-sitografia p {\n" \
|
|
|
|
" margin: .5em 0;\n" \
|
|
|
|
" text-align: left;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" .contenitore-sitografia p span {\n" \
|
|
|
|
" font-family: monospace;\n" \
|
|
|
|
" }\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
string_cat(&head, "\n" \
|
|
|
|
" footer {\n" \
|
|
|
|
" margin: 2em auto 1em;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" footer p {\n" \
|
|
|
|
" margin: 0 auto;\n" \
|
|
|
|
" text-align: center;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" @media all and (min-width: 50em) {\n" \
|
|
|
|
" p {\n" \
|
|
|
|
" hyphens: auto;\n" \
|
|
|
|
" text-align: justify;\n" \
|
|
|
|
" }\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" @media print {\n" \
|
|
|
|
" body {\n" \
|
|
|
|
" max-width: 90%;\n" \
|
|
|
|
" }\n" \
|
|
|
|
"\n" \
|
|
|
|
" a.nav {\n" \
|
|
|
|
" color: inherit;\n" \
|
|
|
|
" text-decoration: none;\n" \
|
|
|
|
" }\n" \
|
|
|
|
" }\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t</style>\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t\t<title>");
|
|
|
|
string_cat_html(&head, title, 0);
|
|
|
|
string_cat(&head, "</title>\n");
|
|
|
|
|
|
|
|
string_cat(&head, "\t</head>\n");
|
|
|
|
|
|
|
|
free(author);
|
|
|
|
free(description);
|
2024-07-13 18:45:52 +00:00
|
|
|
free(title);
|
2024-07-13 17:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
safe_malloc(const size_t size)
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
ptr = malloc(size);
|
|
|
|
if (ptr == NULL) {
|
2024-07-15 08:40:34 +00:00
|
|
|
fprintf(stderr, BIN ": Can't allocate %lu bytes.\n", size);
|
2024-07-13 17:20:31 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
safe_realloc(void *ptr, const size_t size)
|
|
|
|
{
|
|
|
|
void *new;
|
|
|
|
|
|
|
|
new = realloc(ptr, size);
|
|
|
|
if (new == NULL) {
|
2024-07-15 08:40:34 +00:00
|
|
|
fprintf(stderr, BIN ": Can't allocate %lu bytes.\n", size);
|
2024-07-13 17:20:31 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
stread_param(const char *src, char **str)
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
char *end;
|
|
|
|
size_t i, len;
|
|
|
|
int p;
|
|
|
|
|
|
|
|
c = ' ';
|
|
|
|
p = 0;
|
|
|
|
if (src[0] == ' ') {
|
|
|
|
src++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
if (src[0] == '"' || src[0] == '\'') {
|
|
|
|
c = src[0];
|
|
|
|
src++;
|
|
|
|
p += 2;
|
|
|
|
}
|
|
|
|
end = strchr(src, c);
|
|
|
|
if (end)
|
|
|
|
len = end - src;
|
|
|
|
else
|
|
|
|
len = strlen(src);
|
|
|
|
|
|
|
|
*str = safe_malloc(len + 1);
|
|
|
|
for (i = 0; i <= len; i++)
|
|
|
|
(*str)[i] = '\0';
|
|
|
|
strncpy(*str, src, len);
|
|
|
|
|
|
|
|
return len + p;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
string_cat(string *dst, const char *src)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
len = strlen(src);
|
|
|
|
|
|
|
|
if (len >= (dst->size - dst->len))
|
|
|
|
string_enlarge(dst, (dst->size + len) * 2 + 1);
|
|
|
|
|
|
|
|
strcat(dst->str, src);
|
|
|
|
dst->len = dst->len + len;
|
|
|
|
|
|
|
|
return dst->str;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
string_cat_html(string *dst, const char *src, const int is_attr_val)
|
|
|
|
{
|
|
|
|
size_t i, len;
|
|
|
|
|
|
|
|
len = strlen(src);
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if (is_attr_val && src[i] == '"')
|
|
|
|
string_cat(dst, """);
|
|
|
|
else if (src[i] == '&')
|
|
|
|
string_cat(dst, "&");
|
|
|
|
else if (src[i] == '<')
|
|
|
|
string_cat(dst, "<");
|
|
|
|
else if (src[i] == '>')
|
|
|
|
string_cat(dst, ">");
|
|
|
|
else
|
|
|
|
string_putc(dst, src[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dst->str;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
string_enlarge(string *old, const size_t size)
|
|
|
|
{
|
|
|
|
old->str = safe_realloc(old->str, sizeof(char) * size);
|
|
|
|
old->size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
string_putc(string *dst, const char c)
|
|
|
|
{
|
|
|
|
if ((dst->size - dst->len) <= 1)
|
|
|
|
string_enlarge(dst, (dst->size + 1) * 2 + 1);
|
|
|
|
|
|
|
|
dst->str[dst->len] = c;
|
|
|
|
dst->str[dst->len + 1] = '\0';
|
|
|
|
dst->len++;
|
|
|
|
|
|
|
|
return (int) c;
|
|
|
|
}
|