Inline code, bold text, and italics

This commit is contained in:
Nate Choe
2022-04-22 12:18:38 -05:00
parent a0adfafed3
commit aaacccbb58

View File

@@ -37,6 +37,16 @@ enum paratype {
HL
};
static const struct {
char c;
char *escape;
} escapes[] = {
{'&', "&"},
{';', ";"},
{'<', "&lt;"},
{'>', "&gt;"},
};
static int parsepara(struct linefile *infile, FILE *outfile);
static enum paratype identifypara(char *line, char **contentret);
@@ -53,6 +63,16 @@ static int parahardcase(struct linefile *infile, FILE *outfile,
static int paracodecase(struct linefile *infile, FILE *outfile,
char *line, char *buff,
char *vars, enum paratype type);
static long strsearch(char *data, long start, size_t datalen, char c, int reps);
/* strsearch finds instances in data with reps repetitions of c. returns the
* last instance in the first group. For example:
*
* c = '.', reps = 2, data = " ...", returns 2
* c = '.', reps = 2, data = ".. ...", returns 4
* c = '.', reps = 1, data = " ...", returns 3
* */
static int writedata(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 char *getline(struct linefile *file);
@@ -217,7 +237,7 @@ static int paraeasycase(struct linefile *infile, FILE *outfile,
fprintf(outfile, "<%s>", tag);
for (;;) {
fwrite(buff, sizeof(*buff), writelen, outfile);
writedata(buff, writelen, outfile);
free(line);
line = getline(infile);
if (line == NULL)
@@ -250,7 +270,7 @@ static int parahardcase(struct linefile *infile, FILE *outfile,
if (linetag != NULL)
fprintf(outfile, "<%s>", linetag);
fwrite(buff, sizeof(*buff), writelen, outfile);
writedata(buff, writelen, outfile);
if (islinebreak(line))
fputs("<br />", outfile);
if (linetag != NULL)
@@ -301,7 +321,7 @@ static int paracodecase(struct linefile *infile, FILE *outfile,
}
if (newtype != CODEBACK)
fputs(buff, outfile);
writesimple(buff, -1, outfile);
free(line);
line = getline(infile);
@@ -323,6 +343,113 @@ static int paracodecase(struct linefile *infile, FILE *outfile,
return 0;
}
static long strsearch(char *data, long start, size_t datalen,
char c, int reps) {
long i;
for (i = start; data[i] == c; ++i) ;
while (i + reps - 1 < datalen) {
int j;
for (j = 0; j < reps; ++j)
if (data[i + j] != c)
goto failure;
goto success;
continue;
failure:
++i;
}
return -1;
success:
while (data[i + reps] == c && i + reps < datalen)
++i;
return i;
}
/* TODO: Finish this */
static int writedata(char *data, size_t len, FILE *outfile) {
long i;
long start;
long end;
for (i = 0; i < len; ++i) {
switch (data[i]) {
#define STANDOUT_CHAR(c) \
case c: \
if (data[i + 1] == c) { \
start = i + 2; \
end = strsearch(data, start, len, \
c, 2); \
goto bold; \
} \
start = i + 1; \
end = strsearch(data, start, len, c, 1); \
goto italic;
STANDOUT_CHAR('*');
STANDOUT_CHAR('_');
italic:
if (end < 0) {
putchar(data[i]);
break;
}
fputs("<i>", outfile);
writedata(data + start, end - start, outfile);
fputs("</i>", outfile);
i = end;
break;
bold:
if (end < 0) {
putchar(data[i]);
break;
}
fputs("<b>", outfile);
writedata(data + start, end - start, outfile);
fputs("</b>", outfile);
i = end + 1;
break;
case '`':
end = strsearch(data, i, len, '`', 1);
if (end < 0)
break;
fputs("<code>", outfile);
writedata(data + i, end - i, outfile);
fputs("</code>", outfile);
i = end;
break;
default: {
int j;
for (j = 0; j < sizeof escapes / sizeof *escapes; ++j) {
if (escapes[j].c == data[i]) {
fputs(escapes[j].escape, outfile);
goto end;
}
}
fputc(data[i], outfile);
end:
break;
}
}
}
return 0;
}
static int writesimple(char *data, size_t len, FILE *outfile) {
long i;
for (i = 0; (len < 0 && data[i] != '\0') || i < len; ++i) {
int j;
for (j = 0; j < sizeof escapes / sizeof *escapes; ++j) {
if (escapes[j].c == data[i]) {
fputs(escapes[j].escape, outfile);
goto end;
}
}
fputc(data[i], outfile);
end:;
}
return 0;
}
static void ungetline(struct linefile *file, char *line) {
file->prevline = line;
}