From 523e445c3456641012bd0cd142875c941eb52fc3 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Sat, 4 Feb 2012 23:27:39 +0330 Subject: [PATCH] troff: comment space handling variables --- troff.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/troff.c b/troff.c index fa1b8e5..0793afe 100644 --- a/troff.c +++ b/troff.c @@ -1,12 +1,35 @@ +/* + * The main challenge in troff backend is managing unnecessary spaces: + * + no newline should appear in the output, except in blocks + * + no excess whitespace should appear after inline dot commands + * like footnotes + * + * troff_put() manages white spaces: + * + gotnl: is set when the last character is a newline + * + eatspc: when one, ignore as much space as possible + * + inblk: we are in a block and no whitespace processing should be done + * + * After printing an inline macro, eatspc_on() is called which forces + * troff_put() to ignore all whitespaces until the first + * non-space character. Some care is necessary when handling dots; if + * a dot appears just after a newline, it is a troff macro, otherwise + * it is a printable dot and should be escaped. + */ #include #include #include #include "ctxt.h" -static int eatspc; /* jump space chars; always after a newline */ -static int gotnl; /* last output char was a space */ +static int eatspc; /* jump space chars */ +static int gotnl; /* last output char was a newline */ static int inblk; /* inside a block */ +static void eatspc_on(void) +{ + gotnl = 0; + eatspc = 1; +} + static void troff_doc_beg(struct doc *doc) { } @@ -24,12 +47,13 @@ static void troff_put(struct doc *doc, char *s) return; } if (eatspc) { - while (*s == ' ' || *s == '\t' || (*s == '\n' && s[1] != '.')) - s++; + while (*s == ' ' || *s == '\t' || *s == '\n') + gotnl = *s++ == '\n'; eatspc = *s == '\0'; /* more eatspc if s was space */ - gotnl = *s != '.'; /* set gotnl, unless there is a dot */ - if (*s == '.') + if (!gotnl && *s == '.') doc_write(doc, "\\&"); + else if (!eatspc) /* exiting eatspc; set gotnl */ + gotnl = 1; } while (gotnl && *s == '\n') s++; @@ -78,7 +102,7 @@ static void troff_list_beg(struct doc *doc) troff_put(doc, "\n.br\n"); if (!ldepth) troff_put(doc, ".sp 1\n"); - eatspc = 1; + eatspc_on(); ldepth++; if (ldepth > 1) doc_write(doc, ".RS\n"); @@ -94,7 +118,7 @@ static void troff_list_end(struct doc *doc) static void troff_item_beg(struct doc *doc) { doc_write(doc, ".IP \\(bu 2\n"); - eatspc = 1; + eatspc_on(); } static void troff_item_end(struct doc *doc) @@ -136,13 +160,13 @@ static void troff_put_txt(struct doc *doc, char *s, char *m) troff_put(doc, "\n.[[\n"); troff_put(doc, s); troff_put(doc, "\n.]]\n"); - eatspc = 1; + eatspc_on(); break; case '[': troff_put(doc, "\n.FS\n"); troff_put(doc, s); troff_put(doc, "\n.FE\n"); - eatspc = 1; + eatspc_on(); break; default: sprintf(b, "%c%s%c", m[0], s, m[1]); -- 2.11.4.GIT