Added code blocks
This commit is contained in:
@@ -23,6 +23,7 @@ enum linetype {
|
||||
EMPTY,
|
||||
PLAIN,
|
||||
SPACECODE,
|
||||
FENCECODE,
|
||||
HR,
|
||||
SETEXT1,
|
||||
/* === */
|
||||
@@ -33,10 +34,14 @@ enum linetype {
|
||||
enum nodetype {
|
||||
PARAGRAPH,
|
||||
CODE,
|
||||
/* Used for code that starts with spaces */
|
||||
CODEBLOCK,
|
||||
/* Used for triple backtick code */
|
||||
NONE
|
||||
};
|
||||
|
||||
enum linetype identifyline(char *line);
|
||||
enum linetype identifyline(char *line, enum nodetype prev);
|
||||
/* prev is almost never used, but sometimes it is. */
|
||||
char *realcontent(char *line, enum linetype type);
|
||||
|
||||
#endif
|
||||
|
||||
4
src/io.c
4
src/io.c
@@ -39,11 +39,11 @@ char *getline(struct linefile *file) {
|
||||
return ret;
|
||||
}
|
||||
if (c == '\t') {
|
||||
while (len % 4 != 0) {
|
||||
do {
|
||||
ret = append(ret, ' ', &len, &alloc);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
}
|
||||
} while (len % 4 != 0);
|
||||
}
|
||||
else {
|
||||
ret = append(ret, c, &len, &alloc);
|
||||
|
||||
21
src/main.c
21
src/main.c
@@ -29,6 +29,7 @@ int main(int argc, char **argv) {
|
||||
char *header, *template, *footer, *out;
|
||||
FILE *outfile;
|
||||
int c;
|
||||
const char *filefailmsg = "Failed to open file %s\n";
|
||||
|
||||
header = template = footer = out = NULL;
|
||||
|
||||
@@ -63,25 +64,43 @@ int main(int argc, char **argv) {
|
||||
if (header != NULL) {
|
||||
FILE *headerfile;
|
||||
headerfile = fopen(header, "r");
|
||||
if (headerfile != NULL) {
|
||||
if (copyhtml(headerfile, outfile)) {
|
||||
fputs("Failed to copy header\n", stderr);
|
||||
fputs(filefailmsg, stderr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, filefailmsg, header);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (template != NULL) {
|
||||
FILE *templatefile;
|
||||
templatefile = fopen(template, "r");
|
||||
if (templatefile != NULL) {
|
||||
if (parsetemplate(templatefile, outfile))
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, filefailmsg, template);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (footer != NULL) {
|
||||
FILE *footerfile;
|
||||
footerfile = fopen(footer, "r");
|
||||
if (footerfile != NULL) {
|
||||
if (copyhtml(footerfile, outfile)) {
|
||||
fputs("Failed to copy footer\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, filefailmsg, footer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (outfile != stdout)
|
||||
fclose(outfile);
|
||||
return 0;
|
||||
|
||||
17
src/mdutil.c
17
src/mdutil.c
@@ -24,14 +24,16 @@
|
||||
|
||||
static char *truncate(char *str);
|
||||
|
||||
enum linetype identifyline(char *line) {
|
||||
enum linetype identifyline(char *line, enum nodetype prev) {
|
||||
int i;
|
||||
if (prev != PARAGRAPH) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (!isspace(line[i]))
|
||||
goto notcode;
|
||||
goto notspacecode;
|
||||
}
|
||||
return SPACECODE;
|
||||
notcode:
|
||||
}
|
||||
notspacecode:
|
||||
line = truncate(line);
|
||||
if (line[0] == '\0')
|
||||
return EMPTY;
|
||||
@@ -63,6 +65,13 @@ notcode:
|
||||
/* There has to be at least 3 delimiter characters */
|
||||
}
|
||||
nothr:
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (line[i] != '`')
|
||||
goto notfencedcode;
|
||||
}
|
||||
return FENCECODE;
|
||||
notfencedcode:
|
||||
|
||||
return PLAIN;
|
||||
}
|
||||
/* TODO: Finish this */
|
||||
@@ -75,7 +84,7 @@ static char *truncate(char *str) {
|
||||
|
||||
char *realcontent(char *line, enum linetype type) {
|
||||
switch (type) {
|
||||
case EMPTY: case HR: case SETEXT1: case SETEXT2:
|
||||
case EMPTY: case HR: case SETEXT1: case SETEXT2: case FENCECODE:
|
||||
return NULL;
|
||||
case PLAIN:
|
||||
return line;
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
struct parsestate {
|
||||
enum nodetype type;
|
||||
struct string *para;
|
||||
int isfirst;
|
||||
/* Used to insert <br> tags. Currently onlu used for FENCECODE. */
|
||||
};
|
||||
|
||||
static int parseline(char *line, struct parsestate *currstate, FILE *out);
|
||||
@@ -63,8 +65,20 @@ int parsetemplate(FILE *infile, FILE *outfile) {
|
||||
static int parseline(char *line, struct parsestate *currstate, FILE *out) {
|
||||
enum linetype type;
|
||||
|
||||
type = identifyline(line);
|
||||
fflush(stdout);
|
||||
type = identifyline(line, currstate->type);
|
||||
|
||||
if (currstate->type == CODEBLOCK) {
|
||||
if (type == FENCECODE) {
|
||||
currstate->type = NONE;
|
||||
fputs("</code>", out);
|
||||
return 0;
|
||||
}
|
||||
if (!currstate->isfirst)
|
||||
fputs("<br>", out);
|
||||
fputs(line, out);
|
||||
currstate->isfirst = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case EMPTY:
|
||||
@@ -120,6 +134,11 @@ static int parseline(char *line, struct parsestate *currstate, FILE *out) {
|
||||
* paragraph and only write after obtaining the whole thing
|
||||
* as to not include the wrong tags.
|
||||
* */
|
||||
case FENCECODE:
|
||||
fputs("<code class='block'>", out);
|
||||
currstate->type = CODEBLOCK;
|
||||
currstate->isfirst = 1;
|
||||
break;
|
||||
case SPACECODE:
|
||||
if (currstate->type != CODE) {
|
||||
endpara(currstate, out);
|
||||
@@ -142,7 +161,7 @@ static int endpara(struct parsestate *state, FILE *out) {
|
||||
fputs("</p>", out);
|
||||
resetstring(state->para);
|
||||
return 0;
|
||||
case CODE:
|
||||
case CODE: case CODEBLOCK:
|
||||
fputs("</code>", out);
|
||||
return 0;
|
||||
case NONE:
|
||||
|
||||
Reference in New Issue
Block a user