+ newln(p);
+ putchar('\n');
+}
+
+
+static void
+stringa(struct termp *p, const char *s)
+{
+
+ /* XXX - speed up if not passing to chara. */
+ for ( ; *s; s++)
+ chara(p, *s);
+}
+
+
+static void
+chara(struct termp *p, char c)
+{
+
+ /* TODO: dynamically expand the buffer. */
+ if (p->col + 1 >= p->maxcols)
+ errx(1, "line overrun");
+ p->buf[(p->col)++] = c;
+}
+
+
+static void
+style(struct termp *p, enum termstyle esc)
+{
+
+ if (p->col + 4 >= p->maxcols)
+ errx(1, "line overrun");
+
+ p->buf[(p->col)++] = 27;
+ p->buf[(p->col)++] = '[';
+ switch (esc) {
+ case (STYLE_CLEAR):
+ p->buf[(p->col)++] = '0';
+ break;
+ case (STYLE_BOLD):
+ p->buf[(p->col)++] = '1';
+ break;
+ case (STYLE_UNDERLINE):
+ p->buf[(p->col)++] = '4';
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ p->buf[(p->col)++] = 'm';
+}
+
+
+static void
+pescape(struct termp *p, const char *word, size_t *i, size_t len)
+{
+
+ (*i)++;
+ assert(*i < len);
+
+ if ('(' == word[*i]) {
+ /* Two-character escapes. */
+ (*i)++;
+ assert(*i + 1 < len);
+
+ if ('r' == word[*i] && 'B' == word[*i + 1])
+ chara(p, ']');
+ else if ('l' == word[*i] && 'B' == word[*i + 1])
+ chara(p, '[');
+ else if ('<' == word[*i] && '-' == word[*i + 1])
+ stringa(p, "<-");
+ else if ('-' == word[*i] && '>' == word[*i + 1])
+ stringa(p, "->");
+ else if ('l' == word[*i] && 'q' == word[*i + 1])
+ chara(p, '\"');
+ else if ('r' == word[*i] && 'q' == word[*i + 1])
+ chara(p, '\"');
+
+ (*i)++;
+ return;