1 /* $Id: roff_term.c,v 1.11 2017/06/14 13:00:31 schwarze Exp $ */
3 * Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/types.h>
26 #define ROFF_TERM_ARGS struct termp *p, const struct roff_node *n
28 typedef void (*roff_term_pre_fp
)(ROFF_TERM_ARGS
);
30 static void roff_term_pre_br(ROFF_TERM_ARGS
);
31 static void roff_term_pre_ce(ROFF_TERM_ARGS
);
32 static void roff_term_pre_ft(ROFF_TERM_ARGS
);
33 static void roff_term_pre_ll(ROFF_TERM_ARGS
);
34 static void roff_term_pre_mc(ROFF_TERM_ARGS
);
35 static void roff_term_pre_sp(ROFF_TERM_ARGS
);
36 static void roff_term_pre_ta(ROFF_TERM_ARGS
);
37 static void roff_term_pre_ti(ROFF_TERM_ARGS
);
39 static const roff_term_pre_fp roff_term_pre_acts
[ROFF_MAX
] = {
40 roff_term_pre_br
, /* br */
41 roff_term_pre_ce
, /* ce */
42 roff_term_pre_ft
, /* ft */
43 roff_term_pre_ll
, /* ll */
44 roff_term_pre_mc
, /* mc */
45 roff_term_pre_ce
, /* rj */
46 roff_term_pre_sp
, /* sp */
47 roff_term_pre_ta
, /* ta */
48 roff_term_pre_ti
, /* ti */
53 roff_term_pre(struct termp
*p
, const struct roff_node
*n
)
55 assert(n
->tok
< ROFF_MAX
);
56 (*roff_term_pre_acts
[n
->tok
])(p
, n
);
60 roff_term_pre_br(ROFF_TERM_ARGS
)
63 if (p
->flags
& TERMP_BRIND
) {
64 p
->tcol
->offset
= p
->tcol
->rmargin
;
65 p
->tcol
->rmargin
= p
->maxrmargin
;
66 p
->flags
&= ~(TERMP_NOBREAK
| TERMP_BRIND
);
71 roff_term_pre_ce(ROFF_TERM_ARGS
)
73 const struct roff_node
*nc1
, *nc2
;
76 roff_term_pre_br(p
, n
);
83 if (nc2
->type
== ROFFT_TEXT
) {
86 len
+= term_strlen(p
, nc2
->string
);
89 } while (nc2
!= NULL
&& (nc2
->type
!= ROFFT_TEXT
||
90 (nc2
->flags
& NODE_LINE
) == 0));
91 p
->tcol
->offset
= len
>= p
->tcol
->rmargin
? 0 :
92 lm
+ len
>= p
->tcol
->rmargin
? p
->tcol
->rmargin
- len
:
93 n
->tok
== ROFF_rj
? p
->tcol
->rmargin
- len
:
94 (lm
+ p
->tcol
->rmargin
- len
) / 2;
96 if (nc1
->type
== ROFFT_TEXT
)
97 term_word(p
, nc1
->string
);
99 roff_term_pre(p
, nc1
);
102 p
->flags
|= TERMP_NOSPACE
;
105 p
->tcol
->offset
= lm
;
109 roff_term_pre_ft(ROFF_TERM_ARGS
)
111 switch (*n
->child
->string
) {
115 term_fontrepl(p
, TERMFONT_BOLD
);
119 term_fontrepl(p
, TERMFONT_UNDER
);
127 term_fontrepl(p
, TERMFONT_NONE
);
135 roff_term_pre_ll(ROFF_TERM_ARGS
)
137 term_setwidth(p
, n
->child
!= NULL
? n
->child
->string
: NULL
);
141 roff_term_pre_mc(ROFF_TERM_ARGS
)
144 p
->flags
|= TERMP_NOBREAK
;
146 p
->flags
&= ~(TERMP_NOBREAK
| TERMP_NOSPACE
);
148 if (n
->child
!= NULL
) {
149 p
->mc
= n
->child
->string
;
150 p
->flags
|= TERMP_NEWMC
;
152 p
->flags
|= TERMP_ENDMC
;
156 roff_term_pre_sp(ROFF_TERM_ARGS
)
161 if (n
->child
!= NULL
) {
162 if (a2roffsu(n
->child
->string
, &su
, SCALE_VS
) == NULL
)
164 len
= term_vspan(p
, &su
);
174 roff_term_pre_br(p
, n
);
178 roff_term_pre_ta(ROFF_TERM_ARGS
)
180 term_tab_set(p
, NULL
);
181 for (n
= n
->child
; n
!= NULL
; n
= n
->next
)
182 term_tab_set(p
, n
->string
);
186 roff_term_pre_ti(ROFF_TERM_ARGS
)
192 roff_term_pre_br(p
, n
);
194 if (n
->child
== NULL
)
196 cp
= n
->child
->string
;
200 } else if (*cp
== '-') {
206 if (a2roffsu(cp
, &su
, SCALE_EM
) == NULL
)
208 len
= term_hspan(p
, &su
) / 24;
211 p
->ti
= len
- p
->tcol
->offset
;
212 p
->tcol
->offset
= len
;
213 } else if (sign
== 1) {
215 p
->tcol
->offset
+= len
;
216 } else if ((size_t)len
< p
->tcol
->offset
) {
218 p
->tcol
->offset
-= len
;
220 p
->ti
= -p
->tcol
->offset
;