Improved paragraph breaking, added link support

This commit is contained in:
Nate Choe
2022-04-22 18:04:14 -05:00
parent aaacccbb58
commit 1ae5adec62
2 changed files with 92 additions and 40 deletions
+1 -1
View File
@@ -92,7 +92,7 @@ int main(int argc, char **argv) {
static void printhelp(FILE *file, char *name) { static void printhelp(FILE *file, char *name) {
fprintf(file, fprintf(file,
"Usage: %s -b [header] -t [template] -e [footer] -o [output]", name); "Usage: %s -b [header] -t [template] -e [footer] -o [output]\n", name);
fputs( fputs(
"This program is free software. You can redistribute and/or modify it under\n" "This program is free software. You can redistribute and/or modify it under\n"
"the terms of the GNU General Public License as published by the Free\n" "the terms of the GNU General Public License as published by the Free\n"
+91 -39
View File
@@ -37,6 +37,12 @@ enum paratype {
HL HL
}; };
enum inlinetype {
ITALIC,
BOLD,
CODE
};
static const struct { static const struct {
char c; char c;
char *escape; char *escape;
@@ -71,12 +77,15 @@ static long strsearch(char *data, long start, size_t datalen, char c, int reps);
* c = '.', reps = 2, data = ".. ...", returns 4 * c = '.', reps = 2, data = ".. ...", returns 4
* c = '.', reps = 1, data = " ...", returns 3 * c = '.', reps = 1, data = " ...", returns 3
* */ * */
static int writeescape(char c, FILE *outfile);
static int writedata(char *data, size_t len, FILE *outfile); static int writedata(char *data, size_t len, FILE *outfile);
static int writesimple(char *data, size_t len, FILE *outfile); static int writesimple(char *data, size_t len, FILE *outfile);
static void ungetline(struct linefile *file, char *line); static void ungetline(struct linefile *file, char *line);
static char *getline(struct linefile *file); static char *getline(struct linefile *file);
static const char *escapedchars = "!\"#%&'()*,./:;?@[\\]^{|}~";
int parsetemplate(FILE *infile, FILE *outfile) { int parsetemplate(FILE *infile, FILE *outfile) {
struct linefile realin; struct linefile realin;
realin.prevline = NULL; realin.prevline = NULL;
@@ -143,8 +152,29 @@ static int parsepara(struct linefile *infile, FILE *outfile) {
} }
} }
static int isbreak(char *line) {
int count, i;
char whitechar;
count = 0;
whitechar = '\0';
for (i = 0; line[i] != '\0'; ++i) {
if (line[i] == line[0])
++count;
else if (line[i] == ' ' || line[i] == '\t') {
if (whitechar == '\0')
whitechar = line[i];
if (whitechar != line[i])
return 0;
}
else
return 0;
}
return count >= 3;
return 0;
}
static enum paratype identifypara(char *line, char **contentret) { static enum paratype identifypara(char *line, char **contentret) {
int i, count; int i;
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
if (line[i] == ' ') if (line[i] == ' ')
continue; continue;
@@ -165,25 +195,25 @@ whitegone:
case '#': case '#':
for (i = 0; i < 6 && line[i] == '#'; ++i) ; for (i = 0; i < 6 && line[i] == '#'; ++i) ;
*contentret = line + i; *contentret = line + i;
if (line[i] != '\0' && line[i] != ' ')
goto normal;
return H1 + i - 1; return H1 + i - 1;
case '>': case '>':
*contentret = line + 1; *contentret = line + 1;
return BLOCKQUOTE; return BLOCKQUOTE;
case '-':
count = 0;
for (i = 0; line[i] != '\0'; ++i) {
if (line[i] == '-')
++count;
if (count == 3)
return HL;
}
case '*': case '*':
if (isbreak(line))
return HL;
*contentret = line + 1; *contentret = line + 1;
return UL; return UL;
case '-': case '_':
if (isbreak(line))
return HL;
goto normal;
case '`': case '`':
for (i = 0; i < 3; ++i) for (i = 0; i < 3; ++i)
if (line[i] != '`') if (line[i] != '`')
return NORMAL; goto normal;
return CODEBACK; return CODEBACK;
default: default:
if (isdigit(line[0])) { if (isdigit(line[0])) {
@@ -193,6 +223,8 @@ whitegone:
return OL; return OL;
} }
} }
goto normal;
normal:
*contentret = line; *contentret = line;
return NORMAL; return NORMAL;
} }
@@ -290,6 +322,7 @@ static int parahardcase(struct linefile *infile, FILE *outfile,
} }
else else
buff = untrail(buff); buff = untrail(buff);
fputc(' ', outfile);
} }
fprintf(outfile, "</%s>", tag); fprintf(outfile, "</%s>", tag);
@@ -367,7 +400,18 @@ success:
return i; return i;
} }
/* TODO: Finish this */ static int writeescape(char c, FILE *outfile) {
int i;
for (i = 0; i < sizeof escapes / sizeof *escapes; ++i) {
if (escapes[i].c == c) {
fputs(escapes[i].escape, outfile);
return 0;
}
}
fputc(c, outfile);
return 0;
}
static int writedata(char *data, size_t len, FILE *outfile) { static int writedata(char *data, size_t len, FILE *outfile) {
long i; long i;
long start; long start;
@@ -388,20 +432,16 @@ static int writedata(char *data, size_t len, FILE *outfile) {
STANDOUT_CHAR('*'); STANDOUT_CHAR('*');
STANDOUT_CHAR('_'); STANDOUT_CHAR('_');
italic: italic:
if (end < 0) { if (end < 0)
putchar(data[i]); goto normal;
break;
}
fputs("<i>", outfile); fputs("<i>", outfile);
writedata(data + start, end - start, outfile); writedata(data + start, end - start, outfile);
fputs("</i>", outfile); fputs("</i>", outfile);
i = end; i = end;
break; break;
bold: bold:
if (end < 0) { if (end < 0)
putchar(data[i]); goto normal;
break;
}
fputs("<b>", outfile); fputs("<b>", outfile);
writedata(data + start, end - start, outfile); writedata(data + start, end - start, outfile);
fputs("</b>", outfile); fputs("</b>", outfile);
@@ -411,24 +451,41 @@ static int writedata(char *data, size_t len, FILE *outfile) {
case '`': case '`':
end = strsearch(data, i, len, '`', 1); end = strsearch(data, i, len, '`', 1);
if (end < 0) if (end < 0)
break; goto normal;
fputs("<code>", outfile); fputs("<code>", outfile);
writedata(data + i, end - i, outfile); writedata(data + i, end - i, outfile);
fputs("</code>", outfile); fputs("</code>", outfile);
i = end; i = end;
break; break;
default: { case '[': {
int j; long linkend, textend;
for (j = 0; j < sizeof escapes / sizeof *escapes; ++j) { textend = strsearch(data, i, len, ']', 1);
if (escapes[j].c == data[i]) { if (textend < 0)
fputs(escapes[j].escape, outfile); goto normal;
goto end; linkend = strsearch(data, textend, len, ')', 1);
} if (linkend < 0)
} goto normal;
fputc(data[i], outfile); fputs("<a href='", outfile);
end: writesimple(data + textend + 2,
linkend - textend - 2, outfile);
fputs("'>", outfile);
writesimple(data + i + 1,
textend - i - 1, outfile);
fputs("</a>", outfile);
i = linkend;
break; break;
} }
case '\\':
if (i == len ||
strchr(escapedchars, data[i+1]) == NULL) {
fputc('\\', outfile);
break;
}
++i;
goto normal;
default: normal:
writeescape(data[i], outfile);
break;
} }
} }
return 0; return 0;
@@ -437,15 +494,10 @@ end:
static int writesimple(char *data, size_t len, FILE *outfile) { static int writesimple(char *data, size_t len, FILE *outfile) {
long i; long i;
for (i = 0; (len < 0 && data[i] != '\0') || i < len; ++i) { for (i = 0; (len < 0 && data[i] != '\0') || i < len; ++i) {
int j; if (data[i] == '\\')
for (j = 0; j < sizeof escapes / sizeof *escapes; ++j) { if (strchr(escapedchars, data[i]) == NULL)
if (escapes[j].c == data[i]) { fputc('\\', outfile);
fputs(escapes[j].escape, outfile); writeescape(data[i], outfile);
goto end;
}
}
fputc(data[i], outfile);
end:;
} }
return 0; return 0;
} }