Dynamic page index
This commit is contained in:
parent
86de41d87c
commit
f79292d9f3
442
srohtml.c
442
srohtml.c
|
@ -9,31 +9,61 @@
|
||||||
#define CLS_MAX 16
|
#define CLS_MAX 16
|
||||||
#define DATE_LEN 10
|
#define DATE_LEN 10
|
||||||
#define FAVICON "data:image/gif;base64,R0lGODlhEAAQAKEAAAAAcP///wAAcAAAcCH5BAEKAAIALAAAAAAQABAAQAIwlBWZxxwAQWjtTQRvlZhTnGSfYT3eZ3WaE4mjGa1UasoH7c6tzYanfqmhJMKXglcAADs="
|
#define FAVICON "data:image/gif;base64,R0lGODlhEAAQAKEAAAAAcP///wAAcAAAcCH5BAEKAAIALAAAAAAQABAAQAIwlBWZxxwAQWjtTQRvlZhTnGSfYT3eZ3WaE4mjGa1UasoH7c6tzYanfqmhJMKXglcAADs="
|
||||||
|
#define INDEX_START 16
|
||||||
#define LANG_LEN 2
|
#define LANG_LEN 2
|
||||||
#define LINE_MAX 1000
|
#define LINE_MAX 1000
|
||||||
#define LINE_START 80
|
#define LINE_START 80
|
||||||
#define NOTES_START 8
|
#define NOTES_START 8
|
||||||
#define NOTES_MAX_DIGITS 3
|
#define NOTES_MAX_DIGITS 3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int indentation;
|
||||||
|
char *name;
|
||||||
|
} closure;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int index;
|
||||||
|
int size;
|
||||||
|
closure *tags;
|
||||||
|
} closures;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
tag_content = 0,
|
||||||
|
tag_attribute = 1
|
||||||
|
} html_val_type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size;
|
||||||
|
char *str;
|
||||||
|
} string;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *desc;
|
||||||
|
char *id;
|
||||||
|
char heading;
|
||||||
|
} index_title;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int index;
|
||||||
|
int size;
|
||||||
|
index_title *titles;
|
||||||
|
} index;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *desc;
|
char *desc;
|
||||||
char *href;
|
char *href;
|
||||||
} note;
|
} note;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t index;
|
int index;
|
||||||
size_t size;
|
|
||||||
note *notes;
|
note *notes;
|
||||||
|
int size;
|
||||||
} references;
|
} references;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t len;
|
|
||||||
size_t size;
|
|
||||||
char *str;
|
|
||||||
} string;
|
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
static size_t add_note(const char *href, const char *desc);
|
static void add_closure(closures *dst, const char *tag, const int ind);
|
||||||
|
static void add_h_to_index(const char heading, const char *id);
|
||||||
|
static int add_note(const char *href, const char *desc);
|
||||||
static void cmd(char *line);
|
static void cmd(char *line);
|
||||||
static void cmd_close(void);
|
static void cmd_close(void);
|
||||||
static void cmd_a(const char *line);
|
static void cmd_a(const char *line);
|
||||||
|
@ -45,6 +75,7 @@ static void cmd_fi(const char *line);
|
||||||
static void cmd_h(const char *line);
|
static void cmd_h(const char *line);
|
||||||
static void cmd_hr(void);
|
static void cmd_hr(void);
|
||||||
static void cmd_i(const char *line);
|
static void cmd_i(const char *line);
|
||||||
|
static void cmd_in();
|
||||||
static void cmd_la(const char *line);
|
static void cmd_la(const char *line);
|
||||||
static void cmd_le(void);
|
static void cmd_le(void);
|
||||||
static void cmd_ls(void);
|
static void cmd_ls(void);
|
||||||
|
@ -55,11 +86,16 @@ static void cmd_q(const char *line);
|
||||||
static void cmd_st(const char *line);
|
static void cmd_st(const char *line);
|
||||||
static void cmd_tm(const char *line);
|
static void cmd_tm(const char *line);
|
||||||
static void cmd_ur(const char *line);
|
static void cmd_ur(const char *line);
|
||||||
|
static void findent(const int ind, FILE *f);
|
||||||
static void footer(void);
|
static void footer(void);
|
||||||
static void footnotes(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 size_t fread_line(FILE *file, char **str, size_t *len);
|
||||||
static void indent_str(char **str);
|
static void free_closures(closures *dst);
|
||||||
|
static void indent_str(char **str, const int ind);
|
||||||
|
static void nav_index(FILE *f);
|
||||||
static void page_head(void);
|
static void page_head(void);
|
||||||
|
static void pop_closure(closures *dst);
|
||||||
static void print_help(void);
|
static void print_help(void);
|
||||||
static void print_usage(void);
|
static void print_usage(void);
|
||||||
static void print_version(void);
|
static void print_version(void);
|
||||||
|
@ -67,27 +103,68 @@ static void *safe_malloc(const size_t size);
|
||||||
static void *safe_realloc(void *ptr, 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 size_t stread_param(const char *src, char **str);
|
||||||
static char *string_cat(string *dst, const char *src);
|
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 char *string_cat_html(string *dst, const char *src, const html_val_type t);
|
||||||
static void string_enlarge(string *old, const size_t size);
|
static void string_enlarge(string *old, const size_t size);
|
||||||
static int string_putc(string *dst, const char c);
|
static int string_putc(string *dst, const char c);
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
int imgs_presence = 0;
|
|
||||||
char *author = NULL;
|
char *author = NULL;
|
||||||
char closure[CLS_MAX];
|
string body;
|
||||||
char *description = NULL;
|
char *description = NULL;
|
||||||
|
string head;
|
||||||
|
size_t heading_position = 0;
|
||||||
|
int imgs_presence = 0;
|
||||||
int indentation = 2;
|
int indentation = 2;
|
||||||
|
size_t index_position = 0;
|
||||||
char *language = NULL;
|
char *language = NULL;
|
||||||
int licence_container = 0;
|
int licence_container = 0;
|
||||||
int space = 0;
|
index page_index;
|
||||||
string head;
|
|
||||||
string body;
|
|
||||||
char *pub_date = NULL;
|
char *pub_date = NULL;
|
||||||
references sitography;
|
references sitography;
|
||||||
|
int space = 0;
|
||||||
|
char tag_closure[CLS_MAX];
|
||||||
char *title = NULL;
|
char *title = NULL;
|
||||||
|
|
||||||
/* function implementations */
|
/* function implementations */
|
||||||
size_t
|
void
|
||||||
|
add_closure(closures *dst, const char *name, const int ind)
|
||||||
|
{
|
||||||
|
closure *tag;
|
||||||
|
|
||||||
|
if (dst->index == dst->size) {
|
||||||
|
dst->size *= 2;
|
||||||
|
dst->tags = safe_realloc(dst->tags, sizeof(closure) * dst->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = dst->tags + dst->index;
|
||||||
|
|
||||||
|
tag->indentation = ind;
|
||||||
|
tag->name = safe_malloc(sizeof(char) * (strlen(name) + 1));
|
||||||
|
strcpy(tag->name, name);
|
||||||
|
dst->index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
add_h_to_index(const char heading, const char *id)
|
||||||
|
{
|
||||||
|
index_title *new;
|
||||||
|
|
||||||
|
if (page_index.index == page_index.size) {
|
||||||
|
page_index.size *= 2;
|
||||||
|
page_index.titles = safe_realloc(page_index.titles, sizeof(index_title) * page_index.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
new = page_index.titles + page_index.index;
|
||||||
|
|
||||||
|
new->desc = NULL;
|
||||||
|
new->heading = heading;
|
||||||
|
new->id = safe_malloc(sizeof(char) * (strlen(id) + 1));
|
||||||
|
strcpy(new->id, id);
|
||||||
|
|
||||||
|
heading_position = strlen(body.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
add_note(const char *href, const char *desc)
|
add_note(const char *href, const char *desc)
|
||||||
{
|
{
|
||||||
note *new;
|
note *new;
|
||||||
|
@ -147,6 +224,8 @@ cmd(char *line)
|
||||||
cmd_hr();
|
cmd_hr();
|
||||||
else if (!strncmp(line, "I", cmdlen))
|
else if (!strncmp(line, "I", cmdlen))
|
||||||
cmd_i(line);
|
cmd_i(line);
|
||||||
|
else if (!strncmp(line, "IN", cmdlen))
|
||||||
|
cmd_in();
|
||||||
else if (!strncmp(line, "LA", cmdlen))
|
else if (!strncmp(line, "LA", cmdlen))
|
||||||
cmd_la(line);
|
cmd_la(line);
|
||||||
else if (!strncmp(line, "LE", cmdlen))
|
else if (!strncmp(line, "LE", cmdlen))
|
||||||
|
@ -199,11 +278,11 @@ cmd_a(const char *line)
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
if (strcmp(title, "")) {
|
if (strcmp(title, "")) {
|
||||||
string_cat(&body, " title=\"");
|
string_cat(&body, " title=\"");
|
||||||
string_cat_html(&body, title, 1);
|
string_cat_html(&body, title, tag_attribute);
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
}
|
}
|
||||||
string_cat(&body, ">");
|
string_cat(&body, ">");
|
||||||
string_cat_html(&body, in, 1);
|
string_cat_html(&body, in, tag_attribute);
|
||||||
string_cat(&body, "</a>");
|
string_cat(&body, "</a>");
|
||||||
|
|
||||||
free(href);
|
free(href);
|
||||||
|
@ -237,9 +316,28 @@ cmd_br(void)
|
||||||
void
|
void
|
||||||
cmd_close(void)
|
cmd_close(void)
|
||||||
{
|
{
|
||||||
string_cat(&body, closure);
|
index_title *title;
|
||||||
|
|
||||||
|
title = NULL;
|
||||||
|
|
||||||
|
if ((!strcmp(tag_closure, "</h3>") ||
|
||||||
|
!strcmp(tag_closure, "</h4>") ||
|
||||||
|
!strcmp(tag_closure, "</h5>") ||
|
||||||
|
!strcmp(tag_closure, "</h6>")) &&
|
||||||
|
index_position && heading_position) {
|
||||||
|
|
||||||
|
title = page_index.titles + page_index.index;
|
||||||
|
|
||||||
|
title->desc = safe_malloc(sizeof(char) * (strlen(body.str + heading_position) + 1));
|
||||||
|
strcpy(title->desc, body.str + heading_position);
|
||||||
|
page_index.index++;
|
||||||
|
heading_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_cat(&body, tag_closure);
|
||||||
string_cat(&body, "\n");
|
string_cat(&body, "\n");
|
||||||
strcpy(closure, "");
|
|
||||||
|
strcpy(tag_closure, "");
|
||||||
space = 0;
|
space = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,12 +358,12 @@ cmd_dt(const char *line)
|
||||||
if (space)
|
if (space)
|
||||||
string_cat(&body, " ");
|
string_cat(&body, " ");
|
||||||
string_cat(&body, "<time datetime=\"");
|
string_cat(&body, "<time datetime=\"");
|
||||||
string_cat_html(&body, datetime, 1);
|
string_cat_html(&body, datetime, tag_attribute);
|
||||||
string_cat(&body, "\">");
|
string_cat(&body, "\">");
|
||||||
if (!strcmp(in, ""))
|
if (!strcmp(in, ""))
|
||||||
string_cat_html(&body, datetime, 0);
|
string_cat_html(&body, datetime, tag_content);
|
||||||
else
|
else
|
||||||
string_cat_html(&body, in, 0);
|
string_cat_html(&body, in, tag_content);
|
||||||
string_cat(&body, "</time>");
|
string_cat(&body, "</time>");
|
||||||
|
|
||||||
free(datetime);
|
free(datetime);
|
||||||
|
@ -301,7 +399,7 @@ cmd_fi(const char *line)
|
||||||
/* move past argument, once found it */
|
/* move past argument, once found it */
|
||||||
line += stread_param(line, &src);
|
line += stread_param(line, &src);
|
||||||
|
|
||||||
indent_str(&ind);
|
indent_str(&ind, indentation);
|
||||||
|
|
||||||
string_cat(&body, ind);
|
string_cat(&body, ind);
|
||||||
string_cat(&body, "<figure><img src=\"");
|
string_cat(&body, "<figure><img src=\"");
|
||||||
|
@ -315,18 +413,28 @@ cmd_fi(const char *line)
|
||||||
void
|
void
|
||||||
cmd_h(const char *line)
|
cmd_h(const char *line)
|
||||||
{
|
{
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
id = NULL;
|
||||||
|
|
||||||
string_cat(&body, "\t\t<h");
|
string_cat(&body, "\t\t<h");
|
||||||
string_putc(&body, line[1]);
|
string_putc(&body, line[1]);
|
||||||
if (line[2] == ' ' && line[3] != '\0') {
|
if (strlen(line) > 4 && line[2] == ' ' && line[3] != '\0') {
|
||||||
|
id = line + 3;
|
||||||
|
|
||||||
string_cat(&body, " id=\"");
|
string_cat(&body, " id=\"");
|
||||||
string_cat_html(&body, line + 3, 1);
|
string_cat_html(&body, id, tag_attribute);
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
}
|
}
|
||||||
string_cat(&body, ">");
|
string_cat(&body, ">");
|
||||||
strcpy(closure, "</h");
|
|
||||||
closure[3] = line[1];
|
strcpy(tag_closure, "</h");
|
||||||
closure[4] = '>';
|
tag_closure[3] = line[1];
|
||||||
closure[5] = '\0';
|
tag_closure[4] = '>';
|
||||||
|
tag_closure[5] = '\0';
|
||||||
|
|
||||||
|
if (id != NULL && index_position != 0)
|
||||||
|
add_h_to_index(line[1], id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -349,6 +457,14 @@ cmd_i(const char *line)
|
||||||
string_cat(&body, "<i>");
|
string_cat(&body, "<i>");
|
||||||
string_cat(&body, line);
|
string_cat(&body, line);
|
||||||
string_cat(&body, "</i>");
|
string_cat(&body, "</i>");
|
||||||
|
|
||||||
|
space = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_in(void)
|
||||||
|
{
|
||||||
|
index_position = strlen(body.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -379,7 +495,7 @@ cmd_le(void)
|
||||||
ind = NULL;
|
ind = NULL;
|
||||||
|
|
||||||
indentation--;
|
indentation--;
|
||||||
indent_str(&ind);
|
indent_str(&ind, indentation);
|
||||||
string_cat(&body, ind);
|
string_cat(&body, ind);
|
||||||
string_cat(&body, "</div>\n");
|
string_cat(&body, "</div>\n");
|
||||||
|
|
||||||
|
@ -394,14 +510,14 @@ cmd_ls(void)
|
||||||
ind = NULL;
|
ind = NULL;
|
||||||
licence_container = 1;
|
licence_container = 1;
|
||||||
|
|
||||||
indent_str(&ind);
|
indent_str(&ind, indentation);
|
||||||
string_cat(&body, ind);
|
string_cat(&body, ind);
|
||||||
string_cat(&body, "<div class=\"contenitore-licenza\">\n");
|
string_cat(&body, "<div class=\"contenitore-licenza\">\n");
|
||||||
indentation++;
|
indentation++;
|
||||||
|
|
||||||
free(ind);
|
free(ind);
|
||||||
ind = NULL;
|
ind = NULL;
|
||||||
indent_str(&ind);
|
indent_str(&ind, indentation);
|
||||||
string_cat(&body, ind);
|
string_cat(&body, ind);
|
||||||
string_cat(&body, "<hr>\n");
|
string_cat(&body, "<hr>\n");
|
||||||
|
|
||||||
|
@ -435,7 +551,7 @@ cmd_no(const char *line)
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
if (strcmp(title, "")) {
|
if (strcmp(title, "")) {
|
||||||
string_cat(&body, " title=\"");
|
string_cat(&body, " title=\"");
|
||||||
string_cat_html(&body, title, 1);
|
string_cat_html(&body, title, tag_attribute);
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
}
|
}
|
||||||
string_cat(&body, ">[");
|
string_cat(&body, ">[");
|
||||||
|
@ -454,11 +570,11 @@ cmd_p(void)
|
||||||
|
|
||||||
ind = NULL;
|
ind = NULL;
|
||||||
|
|
||||||
indent_str(&ind);
|
indent_str(&ind, indentation);
|
||||||
|
|
||||||
string_cat(&body, ind);
|
string_cat(&body, ind);
|
||||||
string_cat(&body, "<p>");
|
string_cat(&body, "<p>");
|
||||||
strcpy(closure, "</p>");
|
strcpy(tag_closure, "</p>");
|
||||||
|
|
||||||
free(ind);
|
free(ind);
|
||||||
}
|
}
|
||||||
|
@ -500,12 +616,12 @@ cmd_q(const char *line)
|
||||||
string_cat(&body, "<q");
|
string_cat(&body, "<q");
|
||||||
if (strcmp(cite, "")) {
|
if (strcmp(cite, "")) {
|
||||||
string_cat(&body, " cite=\"");
|
string_cat(&body, " cite=\"");
|
||||||
string_cat_html(&body, cite, 1);
|
string_cat_html(&body, cite, tag_attribute);
|
||||||
string_cat(&body, "\"");
|
string_cat(&body, "\"");
|
||||||
}
|
}
|
||||||
string_cat(&body, ">");
|
string_cat(&body, ">");
|
||||||
space = 0;
|
space = 0;
|
||||||
strcpy(closure, "</q></p>");
|
strcpy(tag_closure, "</q></p>");
|
||||||
|
|
||||||
free(cite);
|
free(cite);
|
||||||
|
|
||||||
|
@ -514,13 +630,17 @@ cmd_q(const char *line)
|
||||||
void
|
void
|
||||||
cmd_st(const char *line)
|
cmd_st(const char *line)
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(body.str);
|
||||||
|
|
||||||
/* move past "ST" */
|
/* move past "ST" */
|
||||||
line += 2;
|
line += 2;
|
||||||
/* move past space, if present */
|
/* move past space, if present */
|
||||||
if (line[0] == ' ')
|
if (line[0] == ' ')
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
if (space && body.str[body.len - 1] != '\'')
|
if (space && len > 0 && body.str[len - 1] != '\'')
|
||||||
string_cat(&body, " ");
|
string_cat(&body, " ");
|
||||||
string_cat(&body, "<strong>");
|
string_cat(&body, "<strong>");
|
||||||
string_cat(&body, line);
|
string_cat(&body, line);
|
||||||
|
@ -548,7 +668,7 @@ cmd_tm(const char *line)
|
||||||
string_cat(&body, hours);
|
string_cat(&body, hours);
|
||||||
}
|
}
|
||||||
string_cat(&body, "\">");
|
string_cat(&body, "\">");
|
||||||
string_cat_html(&body, in, 0);
|
string_cat_html(&body, in, tag_content);
|
||||||
string_cat(&body, "</time>");
|
string_cat(&body, "</time>");
|
||||||
|
|
||||||
free(date);
|
free(date);
|
||||||
|
@ -568,12 +688,24 @@ cmd_ur(const char *line)
|
||||||
if (space)
|
if (space)
|
||||||
string_cat(&body, " ");
|
string_cat(&body, " ");
|
||||||
string_cat(&body, "<<a class=\"url\" href=\"");
|
string_cat(&body, "<<a class=\"url\" href=\"");
|
||||||
string_cat_html(&body, line, 1);
|
string_cat_html(&body, line, tag_attribute);
|
||||||
string_cat(&body, "\">");
|
string_cat(&body, "\">");
|
||||||
string_cat_html(&body, line, 0);
|
string_cat_html(&body, line, tag_content);
|
||||||
string_cat(&body, "</a>>");
|
string_cat(&body, "</a>>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
findent(const int ind, FILE *f)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = NULL;
|
||||||
|
|
||||||
|
indent_str(&str, ind);
|
||||||
|
fputs(str, f);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
footer(void)
|
footer(void)
|
||||||
{
|
{
|
||||||
|
@ -620,10 +752,10 @@ footer(void)
|
||||||
string_cat(&body, "\">");
|
string_cat(&body, "\">");
|
||||||
|
|
||||||
strftime(str, max, "%x", now);
|
strftime(str, max, "%x", now);
|
||||||
string_cat_html(&body, str, 0);
|
string_cat_html(&body, str, tag_content);
|
||||||
|
|
||||||
strftime(str, max, " %R", now);
|
strftime(str, max, " %R", now);
|
||||||
string_cat_html(&body, str, 0);
|
string_cat_html(&body, str, tag_content);
|
||||||
string_cat(&body, "</time></p>\n");
|
string_cat(&body, "</time></p>\n");
|
||||||
|
|
||||||
string_cat(&body, "\t\t</footer>\n");
|
string_cat(&body, "\t\t</footer>\n");
|
||||||
|
@ -633,7 +765,8 @@ void
|
||||||
footnotes(void)
|
footnotes(void)
|
||||||
{
|
{
|
||||||
note *cur;
|
note *cur;
|
||||||
size_t i, dig_num, x;
|
int i;
|
||||||
|
size_t dig_num, x;
|
||||||
char id[NOTES_MAX_DIGITS + 1];
|
char id[NOTES_MAX_DIGITS + 1];
|
||||||
char pad[6 * (NOTES_MAX_DIGITS - 1) + 1];
|
char pad[6 * (NOTES_MAX_DIGITS - 1) + 1];
|
||||||
|
|
||||||
|
@ -663,13 +796,13 @@ footnotes(void)
|
||||||
string_cat(&body, id);
|
string_cat(&body, id);
|
||||||
string_cat(&body, "</a></span> ");
|
string_cat(&body, "</a></span> ");
|
||||||
if (strcmp(cur->desc, "")) {
|
if (strcmp(cur->desc, "")) {
|
||||||
string_cat_html(&body, cur->desc, 0);
|
string_cat_html(&body, cur->desc, tag_content);
|
||||||
string_cat(&body, " ");
|
string_cat(&body, " ");
|
||||||
}
|
}
|
||||||
string_cat(&body, "<<a class=\"url\" href=\"");
|
string_cat(&body, "<<a class=\"url\" href=\"");
|
||||||
string_cat(&body, cur->href);
|
string_cat(&body, cur->href);
|
||||||
string_cat(&body, "\">");
|
string_cat(&body, "\">");
|
||||||
string_cat_html(&body, cur->href, 0);
|
string_cat_html(&body, cur->href, tag_content);
|
||||||
string_cat(&body, "</a>></p>\n");
|
string_cat(&body, "</a>></p>\n");
|
||||||
free(cur->desc);
|
free(cur->desc);
|
||||||
free(cur->href);
|
free(cur->href);
|
||||||
|
@ -679,6 +812,33 @@ footnotes(void)
|
||||||
string_cat(&body, "\t\t</div>\n");
|
string_cat(&body, "\t\t</div>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fputs_html(const char *str, FILE *f, const html_val_type t)
|
||||||
|
{
|
||||||
|
size_t i, len;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
len = strlen(str);
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (res == EOF)
|
||||||
|
return EOF;
|
||||||
|
if (t == tag_attribute && str[i] == '"')
|
||||||
|
res = fputs(""", f);
|
||||||
|
else if (str[i] == '&')
|
||||||
|
res = fputs("&", f);
|
||||||
|
else if (str[i] == '<')
|
||||||
|
res = fputs("<", f);
|
||||||
|
else if (str[i] == '>')
|
||||||
|
res = fputs(">", f);
|
||||||
|
else
|
||||||
|
res = fputc(str[i], f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
fread_line(FILE *file, char **str, size_t *len)
|
fread_line(FILE *file, char **str, size_t *len)
|
||||||
{
|
{
|
||||||
|
@ -707,14 +867,23 @@ fread_line(FILE *file, char **str, size_t *len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
indent_str(char **str)
|
free_closures(closures *dst)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*str = safe_malloc(sizeof(char) * (indentation + 1));
|
for (i = 0; i < dst->index; i++)
|
||||||
for (i = 0; i < indentation; i++)
|
free(dst->tags[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
indent_str(char **str, const int ind)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*str = safe_malloc(sizeof(char) * (ind + 1));
|
||||||
|
for (i = 0; i < ind; i++)
|
||||||
(*str)[i] = '\t';
|
(*str)[i] = '\t';
|
||||||
(*str)[indentation] = '\0';
|
(*str)[ind] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -748,21 +917,23 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
head.size = BODY_START_SIZE / 4;
|
head.size = BODY_START_SIZE / 4;
|
||||||
head.str = safe_malloc(head.size);
|
head.str = safe_malloc(sizeof(char) * head.size);
|
||||||
strcpy(head.str, "");
|
strcpy(head.str, "");
|
||||||
head.len = 0;
|
|
||||||
|
|
||||||
body.size = BODY_START_SIZE;
|
body.size = BODY_START_SIZE;
|
||||||
body.str = safe_malloc(body.size);
|
body.str = safe_malloc(sizeof(char) * body.size);
|
||||||
strcpy(body.str, "");
|
strcpy(body.str, "");
|
||||||
body.len = 0;
|
|
||||||
|
|
||||||
string_cat(&body, "\t<body>\n");
|
page_index.index = 0;
|
||||||
|
page_index.size = INDEX_START;
|
||||||
|
page_index.titles = safe_malloc(sizeof(index_title) * page_index.size);
|
||||||
|
|
||||||
sitography.index = 0;
|
sitography.index = 0;
|
||||||
sitography.size = NOTES_START;
|
sitography.size = NOTES_START;
|
||||||
sitography.notes = malloc(sizeof(note) * sitography.size);
|
sitography.notes = malloc(sizeof(note) * sitography.size);
|
||||||
|
|
||||||
|
string_cat(&body, "\t<body>\n");
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
line = NULL;
|
line = NULL;
|
||||||
while (fread_line(in, &line, &len) != EOF) {
|
while (fread_line(in, &line, &len) != EOF) {
|
||||||
|
@ -782,7 +953,7 @@ main (int argc, char *argv[])
|
||||||
line[0] != ';' &&
|
line[0] != ';' &&
|
||||||
line[0] != '?')
|
line[0] != '?')
|
||||||
string_cat(&body, " ");
|
string_cat(&body, " ");
|
||||||
string_cat_html(&body, line, 0);
|
string_cat_html(&body, line, tag_content);
|
||||||
space = 1;
|
space = 1;
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
|
@ -793,7 +964,7 @@ main (int argc, char *argv[])
|
||||||
if (in != stdin)
|
if (in != stdin)
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
if (strcmp(closure, ""))
|
if (strcmp(tag_closure, ""))
|
||||||
cmd_close();
|
cmd_close();
|
||||||
|
|
||||||
page_head();
|
page_head();
|
||||||
|
@ -812,12 +983,104 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(head.str, out);
|
fputs(head.str, out);
|
||||||
|
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
c = body.str[index_position];
|
||||||
|
body.str[index_position] = '\0';
|
||||||
fputs(body.str, out);
|
fputs(body.str, out);
|
||||||
|
if (index_position)
|
||||||
|
nav_index(out);
|
||||||
|
body.str[index_position] = c;
|
||||||
|
fputs(body.str + index_position, out);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nav_index(FILE *f)
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
int ind;
|
||||||
|
closure *tag;
|
||||||
|
closures nav_cls;
|
||||||
|
index_title *next_title, *title;
|
||||||
|
|
||||||
|
ind = 2;
|
||||||
|
nav_cls.index = 0;
|
||||||
|
nav_cls.size = 4;
|
||||||
|
nav_cls.tags = safe_malloc(sizeof(closure) * nav_cls.size);
|
||||||
|
tag = NULL;
|
||||||
|
|
||||||
|
findent(ind++, f);
|
||||||
|
fputs("<nav>\n", f);
|
||||||
|
findent(ind, f);
|
||||||
|
fputs("<hr>\n", f);
|
||||||
|
findent(ind, f);
|
||||||
|
fputs("<h3 id=\"indice\">Indice</h3>\n", f);
|
||||||
|
for (i = 0; i < page_index.index; i++) {
|
||||||
|
title = page_index.titles + i;
|
||||||
|
next_title = i == page_index.index - 1 ? NULL : title + 1;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
findent(ind, f);
|
||||||
|
fputs("<ul>\n", f);
|
||||||
|
add_closure(&nav_cls, "ul", ind);
|
||||||
|
ind++;
|
||||||
|
}
|
||||||
|
|
||||||
|
findent(ind, f);
|
||||||
|
fputs("<li><a href=\"#", f);
|
||||||
|
fputs_html(title->id, f, tag_attribute);
|
||||||
|
fprintf(f, "\">%s</a>", title->desc);
|
||||||
|
add_closure(&nav_cls, "li", ind);
|
||||||
|
|
||||||
|
if (i == page_index.index - 1) {
|
||||||
|
fputs("</li>\n", f);
|
||||||
|
ind--;
|
||||||
|
pop_closure(&nav_cls);
|
||||||
|
for (n = nav_cls.index - 1; n >= 0; n--) {
|
||||||
|
tag = nav_cls.tags + n;
|
||||||
|
findent(tag->indentation, f);
|
||||||
|
fprintf(f, "</%s>\n", tag->name);
|
||||||
|
}
|
||||||
|
findent(tag->indentation, f);
|
||||||
|
fputs("<hr>\n", f);
|
||||||
|
ind--;
|
||||||
|
} else if (next_title->heading < title->heading) {
|
||||||
|
fputs("</li>\n", f);
|
||||||
|
pop_closure(&nav_cls);
|
||||||
|
findent(--ind, f);
|
||||||
|
fputs("</ul>\n", f);
|
||||||
|
pop_closure(&nav_cls);
|
||||||
|
findent(--ind, f);
|
||||||
|
fputs("</li>\n", f);
|
||||||
|
pop_closure(&nav_cls);
|
||||||
|
} else if (next_title->heading > title->heading) {
|
||||||
|
fputs("\n", f);
|
||||||
|
findent(++ind, f);
|
||||||
|
fputs("<ul>\n", f);
|
||||||
|
add_closure(&nav_cls, "ul", ind);
|
||||||
|
ind++;
|
||||||
|
} else if ((title + 1)->heading == title->heading) {
|
||||||
|
fputs("</li>\n", f);
|
||||||
|
pop_closure(&nav_cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(title->desc);
|
||||||
|
free(title->id);
|
||||||
|
}
|
||||||
|
findent(--tag->indentation, f);
|
||||||
|
fputs("</nav>\n", f);
|
||||||
|
|
||||||
|
free_closures(&nav_cls);
|
||||||
|
free(nav_cls.tags);
|
||||||
|
free(page_index.titles);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
page_head(void)
|
page_head(void)
|
||||||
{
|
{
|
||||||
|
@ -826,7 +1089,7 @@ page_head(void)
|
||||||
string_cat(&head, "<html");
|
string_cat(&head, "<html");
|
||||||
if (language != NULL) {
|
if (language != NULL) {
|
||||||
string_cat(&head, " lang=\"");
|
string_cat(&head, " lang=\"");
|
||||||
string_cat_html(&head, language, 1);
|
string_cat_html(&head, language, tag_attribute);
|
||||||
string_cat(&head, "\"");
|
string_cat(&head, "\"");
|
||||||
|
|
||||||
free(language);
|
free(language);
|
||||||
|
@ -841,7 +1104,7 @@ page_head(void)
|
||||||
|
|
||||||
if (author != NULL) {
|
if (author != NULL) {
|
||||||
string_cat(&head, "\t\t<meta name=\"author\" content=\"");
|
string_cat(&head, "\t\t<meta name=\"author\" content=\"");
|
||||||
string_cat_html(&head, author, 1);
|
string_cat_html(&head, author, tag_attribute);
|
||||||
string_cat(&head, "\">\n");
|
string_cat(&head, "\">\n");
|
||||||
|
|
||||||
free(author);
|
free(author);
|
||||||
|
@ -849,7 +1112,7 @@ page_head(void)
|
||||||
|
|
||||||
if (description != NULL) {
|
if (description != NULL) {
|
||||||
string_cat(&head, "\t\t<meta name=\"description\" content=\"");
|
string_cat(&head, "\t\t<meta name=\"description\" content=\"");
|
||||||
string_cat_html(&head, description, 1);
|
string_cat_html(&head, description, tag_attribute);
|
||||||
string_cat(&head, "\">\n");
|
string_cat(&head, "\">\n");
|
||||||
|
|
||||||
free(description);
|
free(description);
|
||||||
|
@ -864,7 +1127,13 @@ page_head(void)
|
||||||
" width: 90%;\n" \
|
" width: 90%;\n" \
|
||||||
" }\n" \
|
" }\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" p {\n" \
|
" p"
|
||||||
|
);
|
||||||
|
if (index_position)
|
||||||
|
string_cat(&head, ",\n\t\t\tli {");
|
||||||
|
else
|
||||||
|
string_cat(&head, " {");
|
||||||
|
string_cat(&head, "\n" \
|
||||||
" line-height: 1.5;\n" \
|
" line-height: 1.5;\n" \
|
||||||
" }\n" \
|
" }\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
|
@ -935,8 +1204,18 @@ page_head(void)
|
||||||
" @media print {\n" \
|
" @media print {\n" \
|
||||||
" body {\n" \
|
" body {\n" \
|
||||||
" max-width: 90%;\n" \
|
" max-width: 90%;\n" \
|
||||||
" }\n" \
|
" }\n"
|
||||||
"\n" \
|
);
|
||||||
|
|
||||||
|
if (index_position) {
|
||||||
|
string_cat(&head, "\n" \
|
||||||
|
" nav {\n" \
|
||||||
|
" display: none;\n" \
|
||||||
|
" }\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
string_cat(&head, "\n" \
|
||||||
" a.nav {\n" \
|
" a.nav {\n" \
|
||||||
" color: inherit;\n" \
|
" color: inherit;\n" \
|
||||||
" text-decoration: none;\n" \
|
" text-decoration: none;\n" \
|
||||||
|
@ -948,7 +1227,7 @@ page_head(void)
|
||||||
|
|
||||||
if (title != NULL) {
|
if (title != NULL) {
|
||||||
string_cat(&head, "\t\t<title>");
|
string_cat(&head, "\t\t<title>");
|
||||||
string_cat_html(&head, title, 0);
|
string_cat_html(&head, title, tag_content);
|
||||||
string_cat(&head, "</title>\n");
|
string_cat(&head, "</title>\n");
|
||||||
|
|
||||||
free(title);
|
free(title);
|
||||||
|
@ -994,6 +1273,19 @@ print_version(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pop_closure(closures *dst)
|
||||||
|
{
|
||||||
|
closure *tag;
|
||||||
|
|
||||||
|
if (dst->index <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tag = dst->tags + (dst->index - 1);
|
||||||
|
free(tag->name);
|
||||||
|
dst->index--;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
safe_malloc(const size_t size)
|
safe_malloc(const size_t size)
|
||||||
{
|
{
|
||||||
|
@ -1062,24 +1354,23 @@ string_cat(string *dst, const char *src)
|
||||||
|
|
||||||
len = strlen(src);
|
len = strlen(src);
|
||||||
|
|
||||||
if (len >= (dst->size - dst->len))
|
if (len >= (dst->size - strlen(dst->str)))
|
||||||
string_enlarge(dst, (dst->size + len) * 2 + 1);
|
string_enlarge(dst, (dst->size + len) * 2 + 1);
|
||||||
|
|
||||||
strcat(dst->str, src);
|
strcat(dst->str, src);
|
||||||
dst->len = dst->len + len;
|
|
||||||
|
|
||||||
return dst->str;
|
return dst->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
string_cat_html(string *dst, const char *src, const int is_attr_val)
|
string_cat_html(string *dst, const char *src, const html_val_type t)
|
||||||
{
|
{
|
||||||
size_t i, len;
|
size_t i, len;
|
||||||
|
|
||||||
len = strlen(src);
|
len = strlen(src);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (is_attr_val && src[i] == '"')
|
if (t == tag_attribute && src[i] == '"')
|
||||||
string_cat(dst, """);
|
string_cat(dst, """);
|
||||||
else if (src[i] == '&')
|
else if (src[i] == '&')
|
||||||
string_cat(dst, "&");
|
string_cat(dst, "&");
|
||||||
|
@ -1104,12 +1395,15 @@ string_enlarge(string *old, const size_t size)
|
||||||
int
|
int
|
||||||
string_putc(string *dst, const char c)
|
string_putc(string *dst, const char c)
|
||||||
{
|
{
|
||||||
if ((dst->size - dst->len) <= 1)
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(dst->str);
|
||||||
|
|
||||||
|
if ((dst->size - len) <= 1)
|
||||||
string_enlarge(dst, (dst->size + 1) * 2 + 1);
|
string_enlarge(dst, (dst->size + 1) * 2 + 1);
|
||||||
|
|
||||||
dst->str[dst->len] = c;
|
dst->str[len] = c;
|
||||||
dst->str[dst->len + 1] = '\0';
|
dst->str[len + 1] = '\0';
|
||||||
dst->len++;
|
|
||||||
|
|
||||||
return (int) c;
|
return (int) c;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue