From ad34e6af37ea601c1c49325ed20ada1ecc18e0cd Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Wed, 1 Feb 2012 21:10:06 +0330 Subject: [PATCH] fmt: reintroduce simple tables and cleanup inline markup handling --- fmt.c | 123 ++++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 48 deletions(-) diff --git a/fmt.c b/fmt.c index e83b349..407e849 100644 --- a/fmt.c +++ b/fmt.c @@ -45,30 +45,17 @@ static char *fmt_line(struct fmt *fmt, int line) return s; } -static char *marker_char(char c) +static char *marker_char(char c, char p, char n) { int i; + if (p == '\\' || (p && !isspace(p)) || isspace(n)) + return NULL; for (i = 0; i < LENGTH(markers); i++) if (markers[i][0] == c) return markers[i]; return NULL; } -static char *possible_inline(char *s) -{ - char *home = s; - char *m = NULL; - while (*s) { - if (*s == '\\') - return s; - if ((s == home || isspace(*(s - 1))) && !isspace(*(s + 1))) - if ((m = marker_char(*s))) - return s; - s++; - } - return NULL; -} - static char *fillbuf(char *beg, char *end) { static char buf[MAXLINE]; @@ -77,42 +64,28 @@ static char *fillbuf(char *beg, char *end) return buf; } -static char *fmt_put_inline(struct fmt *fmt, char *s) -{ - char *r = NULL; - char *marker; - if (*s == '\\') { - if (marker_char(*(s + 1))) { - fmt->ops->put(fmt->doc, fillbuf(s + 1, s + 2)); - return s + 2; - } - return NULL; - } - marker = marker_char(*s); - if (marker) - r = strchr(s + 1, marker[1]); - if (r) { - fmt->ops->put_txt(fmt->doc, fillbuf(s + 1, r), marker); - r++; - } - return r; -} - static void put_text(struct fmt *fmt, char *s) { - char *done = s; + char *_s = s; + char *o = s; while (*s) { - char *r = possible_inline(s); - if (!r) + char *r, *m; + while (*s && !marker_char(*s, s == _s ? 0 : s[-1], s[1])) + s++; + if (!*s) break; - fmt->ops->put(fmt->doc, fillbuf(done, r)); - s = done = r; - if ((r = fmt_put_inline(fmt, r))) - s = done = r; - else + m = marker_char(*s, s == _s ? 0 : s[-1], s[1]); + r = strchr(s + 1, m[1]); + if (r) { + fmt->ops->put(fmt->doc, fillbuf(o, s)); + fmt->ops->put_txt(fmt->doc, fillbuf(s + 1, r), m); + o = r + 1; + s = r + 1; + } else { s++; + } } - fmt->ops->put(fmt->doc, done); + fmt->ops->put(fmt->doc, o); } static void raw_line(struct fmt *fmt, char *s) @@ -320,6 +293,7 @@ static int fmt_list(struct fmt *fmt, int beg, int end) return i - beg; } +/* .T1/.T2 tables */ static int fmt_table(struct fmt *fmt, int beg, int end) { char *hdr = fmt_line(fmt, beg); @@ -371,8 +345,61 @@ static int fmt_table(struct fmt *fmt, int beg, int end) return i - beg + 1; } -static int (*parts[])(struct fmt *fmt, int beg, int end) = - {fmt_head, fmt_list, fmt_table, fmt_block, fmt_rawline, fmt_par}; +/* simple tables */ + +static int table_columns(char *line) +{ + int n; + for (n = 0; *line; n++) { + while (*line == '\t') + line++; + while (*line && *line != '\t') + line++; + } + return n; +} + +static void table_row(struct fmt *fmt, char *s) +{ + if (*s == '=' || *s == '-') + return; + fmt->ops->row_beg(fmt->doc); + while (*s) { + char *r = s; + while (*s && *s != '\t') + s++; + fmt->ops->entry_beg(fmt->doc); + put_text(fmt, fillbuf(r, s)); + fmt->ops->entry_end(fmt->doc); + while (*s == '\t') + s++; + } + fmt->ops->row_end(fmt->doc); +} + +static int fmt_tableascii(struct fmt *fmt, int beg, int end) +{ + int i; + int n; + if (*fmt_line(fmt, beg) != '=') + return 0; + n = table_columns(fmt_line(fmt, beg + 1)); + fmt->ops->table_beg(fmt->doc, n); + for (i = beg + 1; i < end; i++) { + if (!fmt->level && !*fmt_line(fmt, i)) + break; + table_row(fmt, fmt_line(fmt, i)); + } + fmt->ops->table_end(fmt->doc); + return i - beg; +} + +/* parsing text */ + +static int (*parts[])(struct fmt *fmt, int beg, int end) = { + fmt_head, fmt_list, fmt_table, fmt_tableascii, + fmt_block, fmt_rawline, fmt_par +}; static void fmt_handle(struct fmt *fmt, int beg, int end, int level) { -- 2.11.4.GIT