[BACK]Return to term.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/term.c between version 1.145 and 1.146

version 1.145, 2010/06/08 13:22:37 version 1.146, 2010/06/08 15:00:17
Line 22 
Line 22 
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
 #include <getopt.h>  
 #include <stdint.h>  #include <stdint.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <time.h>  
   
 #include "mandoc.h"  #include "mandoc.h"
 #include "chars.h"  #include "chars.h"
Line 37 
Line 35 
 #include "mdoc.h"  #include "mdoc.h"
 #include "main.h"  #include "main.h"
   
 #define PS_CHAR_WIDTH     6  
 #define PS_CHAR_HEIGHT    12  
 #define PS_CHAR_TOPMARG  (792 - 24)  
 #define PS_CHAR_TOP      (PS_CHAR_TOPMARG - 36)  
 #define PS_CHAR_LEFT      36  
 #define PS_CHAR_BOTMARG   24  
 #define PS_CHAR_BOT      (PS_CHAR_BOTMARG + 36)  
   
 static  void              spec(struct termp *, const char *, size_t);  static  void              spec(struct termp *, const char *, size_t);
 static  void              res(struct termp *, const char *, size_t);  static  void              res(struct termp *, const char *, size_t);
 static  void              buffera(struct termp *, const char *, size_t);  static  void              buffera(struct termp *, const char *, size_t);
 static  void              bufferc(struct termp *, char);  static  void              bufferc(struct termp *, char);
 static  void              adjbuf(struct termp *p, size_t);  static  void              adjbuf(struct termp *p, size_t);
 static  void              encode(struct termp *, const char *, size_t);  static  void              encode(struct termp *, const char *, size_t);
 static  void              advance(struct termp *, size_t);  
 static  void              endline(struct termp *);  
 static  void              letter(struct termp *, char);  
 static  void              pageopen(struct termp *);  
   
   
 void *  
 ascii_alloc(char *outopts)  
 {  
         struct termp    *p;  
         const char      *toks[2];  
         char            *v;  
   
         if (NULL == (p = term_alloc(TERMENC_ASCII)))  
                 return(NULL);  
   
         p->type = TERMTYPE_CHAR;  
   
         toks[0] = "width";  
         toks[1] = NULL;  
   
         while (outopts && *outopts)  
                 switch (getsubopt(&outopts, UNCONST(toks), &v)) {  
                 case (0):  
                         p->defrmargin = (size_t)atoi(v);  
                         break;  
                 default:  
                         break;  
                 }  
   
         /* Enforce a lower boundary. */  
         if (p->defrmargin < 58)  
                 p->defrmargin = 58;  
   
         return(p);  
 }  
   
   
 void  void
 ascii_free(void *arg)  
 {  
   
         term_free((struct termp *)arg);  
 }  
   
   
 void  
 term_free(struct termp *p)  term_free(struct termp *p)
 {  {
   
Line 110  term_free(struct termp *p)
Line 56  term_free(struct termp *p)
 }  }
   
   
 /*  
  * Push a single letter into our output engine.  
  */  
 static void  
 letter(struct termp *p, char c)  
 {  
   
         if (TERMTYPE_CHAR == p->type) {  
                 /*  
                  * If using the terminal device, just push the letter  
                  * out into the screen.  
                  */  
                 putchar(c);  
                 return;  
         }  
   
         if ( ! (PS_INLINE & p->psstate)) {  
                 /*  
                  * If we're not in a PostScript "word" context, then  
                  * open one now at the current cursor.  
                  */  
                 printf("%zu %zu moveto\n", p->pscol, p->psrow);  
                 putchar('(');  
                 p->psstate |= PS_INLINE;  
         }  
   
         /*  
          * We need to escape these characters as per the PostScript  
          * specification.  We would also escape non-graphable characters  
          * (like tabs), but none of them would get to this point and  
          * it's superfluous to abort() on them.  
          */  
   
         switch (c) {  
         case ('('):  
                 /* FALLTHROUGH */  
         case (')'):  
                 /* FALLTHROUGH */  
         case ('\\'):  
                 putchar('\\');  
                 break;  
         default:  
                 break;  
         }  
   
         /* Write the character and adjust where we are on the page. */  
         putchar(c);  
         p->pscol += PS_CHAR_WIDTH;  
 }  
   
   
 /*  
  * Begin a "terminal" context.  Since terminal encompasses PostScript,  
  * the actual terminal, etc., there are a few things we can do here.  
  */  
 void  void
 term_begin(struct termp *p, term_margin head,  term_begin(struct termp *p, term_margin head,
                 term_margin foot, const void *arg)                  term_margin foot, const void *arg)
Line 173  term_begin(struct termp *p, term_margin head, 
Line 64  term_begin(struct termp *p, term_margin head, 
         p->headf = head;          p->headf = head;
         p->footf = foot;          p->footf = foot;
         p->argf = arg;          p->argf = arg;
           (*p->begin)(p);
         if (TERMTYPE_CHAR == p->type) {  
                 /* Emit the header and be done. */  
                 (*p->headf)(p, p->argf);  
                 return;  
         }  
   
         /*  
          * Emit the standard PostScript prologue, set our initial page  
          * position, then run pageopen() on the initial page.  
          */  
   
         printf("%s\n", "%!PS");  
         printf("%s\n", "/Courier");  
         printf("%s\n", "10 selectfont");  
   
         p->pspage = 1;  
         p->psstate = 0;  
         pageopen(p);  
 }  }
   
   
 /*  
  * Open a page.  This is only used for -Tps at the moment.  It opens a  
  * page context, printing the header and the footer.  THE OUTPUT BUFFER  
  * MUST BE EMPTY.  If it is not, output will ghost on the next line and  
  * we'll be all gross and out of state.  
  */  
 static void  
 pageopen(struct termp *p)  
 {  
   
         assert(TERMTYPE_PS == p->type);  
         assert(0 == p->psstate);  
   
         p->pscol = PS_CHAR_LEFT;  
         p->psrow = PS_CHAR_TOPMARG;  
         p->psstate |= PS_MARGINS;  
   
         (*p->headf)(p, p->argf);  
         endline(p);  
   
         p->psstate &= ~PS_MARGINS;  
         assert(0 == p->psstate);  
   
         p->pscol = PS_CHAR_LEFT;  
         p->psrow = PS_CHAR_BOTMARG;  
         p->psstate |= PS_MARGINS;  
   
         (*p->footf)(p, p->argf);  
         endline(p);  
   
         p->psstate &= ~PS_MARGINS;  
         assert(0 == p->psstate);  
   
         p->pscol = PS_CHAR_LEFT;  
         p->psrow = PS_CHAR_TOP;  
   
 }  
   
   
 void  void
 term_end(struct termp *p)  term_end(struct termp *p)
 {  {
   
         if (TERMTYPE_CHAR == p->type) {          (*p->end)(p);
                 (*p->footf)(p, p->argf);  
                 return;  
         }  
   
         printf("%s\n", "%%END");  
 }  }
   
   
 static void  
 endline(struct termp *p)  
 {  
   
         if (TERMTYPE_CHAR == p->type) {  
                 putchar('\n');  
                 return;  
         }  
   
         if (PS_INLINE & p->psstate) {  
                 printf(") show\n");  
                 p->psstate &= ~PS_INLINE;  
         }  
   
         if (PS_MARGINS & p->psstate)  
                 return;  
   
         p->pscol = PS_CHAR_LEFT;  
         if (p->psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {  
                 p->psrow -= PS_CHAR_HEIGHT;  
                 return;  
         }  
   
         /*  
          * XXX: can't run pageopen() until we're certain a flushln() has  
          * occured, else the buf will reopen in an awkward state on the  
          * next line.  
          */  
         printf("showpage\n");  
         p->psrow = PS_CHAR_TOP;  
 }  
   
   
 /*  
  * Advance the output engine by a certain amount of whitespace.  
  */  
 static void  
 advance(struct termp *p, size_t len)  
 {  
         size_t          i;  
   
         if (TERMTYPE_CHAR == p->type) {  
                 /* Just print whitespace on the terminal. */  
                 for (i = 0; i < len; i++)  
                         putchar(' ');  
                 return;  
         }  
   
         if (PS_INLINE & p->psstate) {  
                 /* Dump out any existing line scope. */  
                 printf(") show\n");  
                 p->psstate &= ~PS_INLINE;  
         }  
   
         p->pscol += len ? len * PS_CHAR_WIDTH : 0;  
 }  
   
   
 struct termp *  struct termp *
 term_alloc(enum termenc enc)  term_alloc(enum termenc enc)
 {  {
Line 438  term_flushln(struct termp *p)
Line 209  term_flushln(struct termp *p)
                  */                   */
                 if (vend > bp && 0 == jhy && vis > 0) {                  if (vend > bp && 0 == jhy && vis > 0) {
                         vend -= vis;                          vend -= vis;
                         endline(p);                          (*p->endline)(p);
                         if (TERMP_NOBREAK & p->flags) {                          if (TERMP_NOBREAK & p->flags) {
                                 p->viscol = p->rmargin;                                  p->viscol = p->rmargin;
                                 advance(p, p->rmargin);                                  (*p->advance)(p, p->rmargin);
                                 vend += p->rmargin - p->offset;                                  vend += p->rmargin - p->offset;
                         } else {                          } else {
                                 p->viscol = 0;                                  p->viscol = 0;
Line 485  term_flushln(struct termp *p)
Line 256  term_flushln(struct termp *p)
                          * so write preceding white space now.                           * so write preceding white space now.
                          */                           */
                         if (vbl) {                          if (vbl) {
                                 advance(p, vbl);                                  (*p->advance)(p, vbl);
                                 p->viscol += vbl;                                  p->viscol += vbl;
                                 vbl = 0;                                  vbl = 0;
                         }                          }
   
                         if (ASCII_HYPH == p->buf[i])                          if (ASCII_HYPH == p->buf[i])
                                 letter(p, '-');                                  (*p->letter)(p, '-');
                         else                          else
                                 letter(p, p->buf[i]);                                  (*p->letter)(p, p->buf[i]);
   
                         p->viscol += 1;                          p->viscol += 1;
                 }                  }
Line 506  term_flushln(struct termp *p)
Line 277  term_flushln(struct termp *p)
   
         if ( ! (TERMP_NOBREAK & p->flags)) {          if ( ! (TERMP_NOBREAK & p->flags)) {
                 p->viscol = 0;                  p->viscol = 0;
                 endline(p);                  (*p->endline)(p);
                 return;                  return;
         }          }
   
Line 539  term_flushln(struct termp *p)
Line 310  term_flushln(struct termp *p)
         if (maxvis > vis + /* LINTED */          if (maxvis > vis + /* LINTED */
                         ((TERMP_TWOSPACE & p->flags) ? 1 : 0)) {                          ((TERMP_TWOSPACE & p->flags) ? 1 : 0)) {
                 p->viscol += maxvis - vis;                  p->viscol += maxvis - vis;
                 advance(p, maxvis - vis);                  (*p->advance)(p, maxvis - vis);
                 vis += (maxvis - vis);                  vis += (maxvis - vis);
         } else {        /* ...or newline break. */          } else {        /* ...or newline break. */
                 endline(p);                  (*p->endline)(p);
                 p->viscol = p->rmargin;                  p->viscol = p->rmargin;
                 advance(p, p->rmargin);                  (*p->advance)(p, p->rmargin);
         }          }
 }  }
   
Line 580  term_vspace(struct termp *p)
Line 351  term_vspace(struct termp *p)
   
         term_newln(p);          term_newln(p);
         p->viscol = 0;          p->viscol = 0;
         endline(p);          (*p->endline)(p);
 }  }
   
   

Legend:
Removed from v.1.145  
changed lines
  Added in v.1.146

CVSweb