[writan/format.c] add tables
This commit is contained in:
parent
0974e90eb2
commit
274264e4c4
95
format.c
95
format.c
|
@ -53,6 +53,41 @@ emit_sanitized_char(char c)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
emit_sanitized_string(char *str)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
emit_sanitized_char(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* read n bytes from IN */
|
||||
void
|
||||
read_n_bytes(size_t n, char *buf)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++)
|
||||
buf[i] = fgetc(IN);
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
/* remove occurrences of c from the right side of buf */
|
||||
void
|
||||
rstrip(char *buf, char c)
|
||||
{
|
||||
size_t i = strlen(buf) - 1;
|
||||
printf("i: %ld\n", i);
|
||||
|
||||
for(;;) {
|
||||
if (buf[i] == c)
|
||||
buf[i] = '\0';
|
||||
else if (i <= 0 || buf[i] != c)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/* headings */
|
||||
int
|
||||
heading_level(void)
|
||||
|
@ -309,6 +344,49 @@ emit_image(void)
|
|||
fseek(IN, -1L, SEEK_CUR);
|
||||
}
|
||||
|
||||
void
|
||||
emit_table(void)
|
||||
{
|
||||
char buf[256] = {0};
|
||||
char *bufptr = buf;
|
||||
|
||||
fprintf(OUT, "<table border=\"1\"><tbody>\n");
|
||||
|
||||
for(;;) {
|
||||
read_n_bytes(4, buf);
|
||||
if (!strcmp("===\n", buf)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
fseek(IN, -4L, SEEK_CUR);
|
||||
memset(buf, '\0', 256);
|
||||
fprintf(OUT, "<tr>\n");
|
||||
char c;
|
||||
while ((c = fgetc(IN)) != '\n') {
|
||||
if (c == '|') {
|
||||
rstrip(buf, ' ');
|
||||
fprintf(OUT, "<td>");
|
||||
emit_sanitized_string(buf);
|
||||
fprintf(OUT, "</td>\n");
|
||||
memset(buf, '\0', 256);
|
||||
bufptr = buf;
|
||||
}
|
||||
else {
|
||||
*(bufptr++) = c;
|
||||
}
|
||||
}
|
||||
rstrip(buf, ' ');
|
||||
fprintf(OUT, "<td>");
|
||||
emit_sanitized_string(buf);
|
||||
fprintf(OUT, "</td>\n");
|
||||
fprintf(OUT, "</tr>\n");
|
||||
bufptr = buf;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(OUT, "</tbody></table>\n");
|
||||
}
|
||||
|
||||
/* main formatter */
|
||||
void
|
||||
format(void)
|
||||
|
@ -333,10 +411,7 @@ format(void)
|
|||
}
|
||||
else if (c == '$') { /* maybe image */
|
||||
char buf[5];
|
||||
size_t i;
|
||||
for (i = 0; i < 4; i++)
|
||||
buf[i] = fgetc(IN);
|
||||
buf[i] = '\0';
|
||||
read_n_bytes(4, buf);
|
||||
|
||||
if (!strcmp(buf, "img ")) {
|
||||
emit_image();
|
||||
|
@ -359,6 +434,18 @@ format(void)
|
|||
else if (c == '>' && lastc == '\n') { /* quote */
|
||||
emit_blockquote();
|
||||
}
|
||||
else if (c == '=' && lastc == '\n') { /* maybe table */
|
||||
char buf[4];
|
||||
read_n_bytes(3, buf);
|
||||
|
||||
if (!strcmp(buf, "==\n")) {
|
||||
emit_table();
|
||||
}
|
||||
else {
|
||||
fseek(IN, -3L, SEEK_CUR);
|
||||
emit_sanitized_char(c);
|
||||
}
|
||||
}
|
||||
else if (lastc == '\n' && c == '\n') { /* new paragraph */
|
||||
fprintf(OUT, "\n<p>");
|
||||
last_was_paragraph = true;
|
||||
|
|
|
@ -34,3 +34,8 @@ An image is embedded like follows. The filename is expanded to
|
|||
resources/img/image-file.png.
|
||||
|
||||
$img image-file.png
|
||||
|
||||
===
|
||||
this|is |a |table
|
||||
they|may|be|aligned
|
||||
===
|
||||
|
|
|
@ -4,3 +4,6 @@ Haskell is a purely functional, lazy, strongly and statically typed, general
|
|||
purpose programming language based on the typed {lambda-calculus}. It famously
|
||||
uses monads to express I/O interactions. Many of its strengths come from its
|
||||
powerful type system.
|
||||
|
||||
{https://haskellbook.com/ Haskell programming from first principles}
|
||||
{https://www.youtube.com/watch?v=re96UgMk6GQ Escape from the ivory tower}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
* Test page
|
||||
|
||||
[
|
||||
``
|
||||
code block
|
||||
]
|
||||
``
|
||||
|
||||
** Second level heading
|
||||
|
||||
|
@ -26,3 +26,8 @@ newline replaced with a space in the HTML version.
|
|||
{http://example.com external link}
|
||||
|
||||
<>&"'
|
||||
|
||||
===
|
||||
column 1|column 2|column 3
|
||||
row2! |row 2
|
||||
===
|
||||
|
|
Loading…
Reference in New Issue