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