]> git.cameronkatri.com Git - mandoc.git/commitdiff
First, roff_res() has no need to invoke ROFF_RERUN: since it's executed
authorKristaps Dzonsons <kristaps@bsd.lv>
Wed, 27 Jul 2011 07:09:41 +0000 (07:09 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Wed, 27 Jul 2011 07:09:41 +0000 (07:09 +0000)
before any other roff processing occurs, it's Ok to just let it do its
thing and pass through.  Also, make sure this function is ALWAYS called,
not just when first_string is defined.

Second, add a new function, roff_parsetext(), that post-processes
non-macro lines.  This, for the time being, amounts to detecting soft
hyphens.  This fixes a long-standing bug in that -man now has proper
hyphen breaking!

mdoc.c
roff.c

diff --git a/mdoc.c b/mdoc.c
index 786ef67e5fdc83dada57726e78a0369cc66605d6..4d3c5fb6f4a4304bd8d68e399d9b2855b0963ebd 100644 (file)
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/*     $Id: mdoc.c,v 1.191 2011/07/25 15:37:00 kristaps Exp $ */
+/*     $Id: mdoc.c,v 1.192 2011/07/27 07:09:41 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
@@ -755,11 +755,6 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
        ws = NULL;
        for (c = end = buf + offs; *c; c++) {
                switch (*c) {
-               case '-':
-                       if (mandoc_hyph(buf + offs, c))
-                               *c = ASCII_HYPH;
-                       ws = NULL;
-                       break;
                case ' ':
                        if (NULL == ws)
                                ws = c;
diff --git a/roff.c b/roff.c
index 498e85be2ca37ff86fab7caab9e86b4462817f4c..e287a80b2dd30722378c067b5744e1bce09f6eef 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/*     $Id: roff.c,v 1.153 2011/07/26 14:24:06 kristaps Exp $ */
+/*     $Id: roff.c,v 1.154 2011/07/27 07:09:41 kristaps Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -159,7 +159,7 @@ static      const char      *roff_getstrn(const struct roff *,
                                const char *, size_t);
 static enum rofferr     roff_line_ignore(ROFF_ARGS);
 static enum rofferr     roff_nr(ROFF_ARGS);
-static int              roff_res(struct roff *, 
+static void             roff_res(struct roff *, 
                                char **, size_t *, int, int);
 static enum rofferr     roff_rm(ROFF_ARGS);
 static void             roff_setstr(struct roff *,
@@ -400,8 +400,8 @@ roff_alloc(struct mparse *parse)
  * `\*', e.g., `\*(ab').  These must be handled before the actual line
  * is processed. 
  * This also checks the syntax of regular escapes.
-*/
-static int
+ */
+static void
 roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 {
        enum mandoc_esc  esc;
@@ -413,8 +413,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
        size_t           nsz;
        char            *n;
 
-       /* Search for a leading backslash and save a pointer to it. */
-
+again:
        cp = *bufp + pos;
        while (NULL != (cp = strchr(cp, '\\'))) {
                stesc = cp++;
@@ -426,7 +425,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                 */
 
                if ('\0' == *cp)
-                       return(1);
+                       return;
 
                if ('*' != *cp) {
                        res = cp;
@@ -437,7 +436,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                        mandoc_msg
                                (MANDOCERR_BADESCAPE, r->parse, 
                                 ln, (int)(stesc - *bufp), NULL);
-                       continue;
+                       return;
                }
 
                cp++;
@@ -450,7 +449,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 
                switch (*cp) {
                case ('\0'):
-                       return(1);
+                       return;
                case ('('):
                        cp++;
                        maxl = 2;
@@ -473,7 +472,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                                        (MANDOCERR_BADESCAPE, 
                                         r->parse, ln, 
                                         (int)(stesc - *bufp), NULL);
-                               return(1); 
+                               return;
                        }
                        if (0 == maxl && ']' == *cp)
                                break;
@@ -495,6 +494,8 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 
                /* Replace the escape sequence by the string. */
 
+               pos += (stesc - *bufp);
+
                nsz = *szp + strlen(res) + 1;
                n = mandoc_malloc(nsz);
 
@@ -506,10 +507,41 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 
                *bufp = n;
                *szp = nsz;
-               return(0);
+               goto again;
+       }
+}
+
+/*
+ * Process text streams: convert all breakable hyphens into ASCII_HYPH.
+ */
+static enum rofferr
+roff_parsetext(char *p)
+{
+       size_t           sz;
+       const char      *start;
+       enum mandoc_esc  esc;
+
+       start = p;
+
+       while ('\0' != *p) {
+               sz = strcspn(p, "-\\");
+               p += sz;
+
+               if ('\\' == *p) {
+                       /* Skip over escapes. */
+                       p++;
+                       esc = mandoc_escape
+                               ((const char **)&p, NULL, NULL);
+                       if (ESCAPE_ERROR == esc)
+                               break;
+               } else if ('-' == *p) {
+                       if (mandoc_hyph(start, p))
+                               *p = ASCII_HYPH;
+                       p++;
+               }
        }
 
-       return(1);
+       return(ROFF_CONT);
 }
 
 enum rofferr
@@ -525,8 +557,7 @@ roff_parseln(struct roff *r, int ln, char **bufp,
         * words to fill in.
         */
 
-       if ( ! roff_res(r, bufp, szp, ln, pos))
-               return(ROFF_REPARSE);
+       roff_res(r, bufp, szp, ln, pos);
 
        ppos = pos;
        ctl = mandoc_getcontrol(*bufp, &pos);
@@ -551,13 +582,13 @@ roff_parseln(struct roff *r, int ln, char **bufp,
                        return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
                if (r->tbl)
                        return(tbl_read(r->tbl, ln, *bufp, pos));
-               return(ROFF_CONT);
+               return(roff_parsetext(*bufp + pos));
        } else if ( ! ctl) {
                if (r->eqn)
                        return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
                if (r->tbl)
                        return(tbl_read(r->tbl, ln, *bufp, pos));
-               return(ROFF_CONT);
+               return(roff_parsetext(*bufp + pos));
        } else if (r->eqn)
                return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));