void term_tab_set(const struct termp *p, const char *arg) { static int recording_period; struct roffsu su; struct tablist *tl; size_t pos; int add; /* Special arguments: clear all tabs or switch lists. */ if (arg == NULL) { tabs.a.n = tabs.p.n = 0; recording_period = 0; if (tabs.d == 0) { a2roffsu(".8i", &su, SCALE_IN); tabs.d = term_hspan(p, &su) / 24; } return; } if (arg[0] == 'T' && arg[1] == '\0') { recording_period = 1; return; } /* Parse the sign, the number, and the unit. */ if (*arg == '+') { add = 1; arg++; } else add = 0; if (a2roffsu(arg, &su, SCALE_EM) == NULL) return; /* Select the list, and extend it if it is full. */ tl = recording_period ? &tabs.p : &tabs.a; if (tl->n >= tl->s) { tl->s += 8; tl->t = mandoc_reallocarray(tl->t, tl->s, sizeof(*tl->t)); } /* Append the new position. */ pos = term_hspan(p, &su); tl->t[tl->n] = pos; if (add && tl->n) tl->t[tl->n] += tl->t[tl->n - 1]; tl->n++; }
static int pre_IP(DECL_ARGS) { struct roffsu su; const struct roff_node *nn; int len, savelit; switch (n->type) { case ROFFT_BODY: p->flags |= TERMP_NOSPACE; break; case ROFFT_HEAD: p->flags |= TERMP_NOBREAK; p->trailspace = 1; break; case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: return 1; } /* Calculate the offset from the optional second argument. */ if ((nn = n->parent->head->child) != NULL && (nn = nn->next) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) len = term_len(p, p->defindent); mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; switch (n->type) { case ROFFT_HEAD: p->offset = mt->offset; p->rmargin = mt->offset + len; savelit = MANT_LITERAL & mt->fl; mt->fl &= ~MANT_LITERAL; if (n->child) print_man_node(p, mt, n->child, meta); if (savelit) mt->fl |= MANT_LITERAL; return 0; case ROFFT_BODY: p->offset = mt->offset + len; p->rmargin = p->maxrmargin; break; default: break; } return 1; }
static int man_br_pre(MAN_ARGS) { struct roffsu su; struct htmlpair tag; SCALE_VS_INIT(&su, 1); if (MAN_sp == n->tok) { if (NULL != (n = n->child)) if ( ! a2roffsu(n->string, &su, SCALE_VS)) SCALE_VS_INIT(&su, atoi(n->string)); } else su.scale = 0.0; bufinit(h); bufcat_su(h, "height", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); /* So the div isn't empty: */ print_text(h, "\\~"); return(0); }
static int termp_sp_pre(DECL_ARGS) { struct roffsu su; int i, len; switch (n->tok) { case MDOC_sp: if (n->child) { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } else len = 1; break; case MDOC_br: len = 0; break; default: len = 1; fn_prio = 0; break; } if (0 == len) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); return 0; }
static int pre_RS(DECL_ARGS) { struct roffsu su; switch (n->type) { case MAN_BLOCK: term_newln(p); return(1); case MAN_HEAD: return(0); default: break; } n = n->parent->head; n->aux = SHRT_MAX + 1; if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EN)) n->aux = term_hspan(p, &su); if (n->aux < 0 && (size_t)(-n->aux) > mt->offset) n->aux = -mt->offset; else if (n->aux > SHRT_MAX) n->aux = term_len(p, p->defindent); mt->offset += n->aux; p->offset = mt->offset; p->rmargin = p->maxrmargin; if (++mt->lmarginsz < MAXMARGINS) mt->lmargincur = mt->lmarginsz; mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1]; return(1); }
void term_setwidth(struct termp *p, const char *wstr) { struct roffsu su; size_t width; int iop; iop = 0; width = 0; if (NULL != wstr) { switch (*wstr) { case '+': iop = 1; wstr++; break; case '-': iop = -1; wstr++; break; default: break; } if (a2roffsu(wstr, &su, SCALE_MAX)) width = term_hspan(p, &su); else iop = 0; } (*p->setwidth)(p, iop, width); }
static int a2width(const struct roff_node *n, struct roffsu *su) { if (n->type != ROFFT_TEXT) return 0; return a2roffsu(n->string, su, SCALE_EN) != NULL; }
/* ARGSUSED */ static int mdoc_sp_pre(MDOC_ARGS) { struct roffsu su; struct htmlpair tag; SCALE_VS_INIT(&su, 1); if (MDOC_sp == n->tok) { if (n->child) a2roffsu(n->child->string, &su, SCALE_VS); } else su.scale = 0; bufinit(h); bufcat_su(h, "height", &su); PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); /* So the div isn't empty: */ print_text(h, "\\~"); return(0); }
/* * Set up the indentation for a list item; used from pre_it(). */ static void print_width(const struct mdoc_bl *bl, const struct roff_node *child) { char buf[24]; struct roffsu su; const char *end; int numeric, remain, sz, chsz; numeric = 1; remain = 0; /* Convert the width into a number (of characters). */ if (bl->width == NULL) sz = (bl->type == LIST_hang) ? 6 : 0; else { end = a2roffsu(bl->width, &su, SCALE_MAX); if (end == NULL || *end != '\0') sz = man_strlen(bl->width); else if (SCALE_EN == su.unit) sz = su.scale; else { sz = 0; numeric = 0; } } /* XXX Rough estimation, might have multiple parts. */ if (bl->type == LIST_enum) chsz = (bl->count > 8) + 1; else if (child != NULL && child->type == ROFFT_TEXT) chsz = man_strlen(child->string); else chsz = 0; /* Maybe we are inside an enclosing list? */ mid_it(); /* * Save our own indentation, * such that child lists can use it. */ Bl_stack[Bl_stack_len++] = sz + 2; /* Set up the current list. */ if (chsz > sz && bl->type != LIST_tag) print_block(".HP", 0); else { print_block(".TP", 0); remain = sz + 2; } if (numeric) { (void)snprintf(buf, sizeof(buf), "%dn", sz + 2); print_word(buf); } else print_word(bl->width); TPremain = remain; }
/* * Calculate the scaling unit passed in a `-width' argument. This uses * either a native scaling unit (e.g., 1i, 2m) or the string length of * the value. */ static void a2width(const char *p, struct roffsu *su) { if ( ! a2roffsu(p, su, SCALE_MAX)) { su->unit = SCALE_BU; su->scale = (int)strlen(p); } }
static size_t a2height(const struct termp *p, const char *cp) { struct roffsu su; if ( ! a2roffsu(cp, &su, SCALE_VS)) SCALE_VS_INIT(&su, atoi(cp)); return(term_vspan(p, &su)); }
static int a2width(const struct termp *p, const char *cp) { struct roffsu su; if ( ! a2roffsu(cp, &su, SCALE_BU)) return(-1); return((int)term_hspan(p, &su)); }
/* * Calculate the scaling unit passed in a `-width' argument. This uses * either a native scaling unit (e.g., 1i, 2m) or the string length of * the value. */ static void a2width(const char *p, struct roffsu *su) { if (a2roffsu(p, su, SCALE_MAX) < 2) { su->unit = SCALE_EN; su->scale = html_strlen(p); } else if (su->scale < 0.0) su->scale = 0.0; }
static int a2width(const struct man_node *n, struct roffsu *su) { if (MAN_TEXT != n->type) return(0); if (a2roffsu(n->string, su, SCALE_EN)) return(1); return(0); }
static int a2width(const struct termp *p, const char *v) { struct roffsu su; if (a2roffsu(v, &su, SCALE_MAX) < 2) { SCALE_HS_INIT(&su, term_strlen(p, v)); su.scale /= term_strlen(p, "0"); } return term_hspan(p, &su) / 24; }
static size_t a2width(const struct termp *p, const char *v) { struct roffsu su; assert(v); if ( ! a2roffsu(v, &su, SCALE_MAX)) SCALE_HS_INIT(&su, term_strlen(p, v)); return(term_hspan(p, &su)); }
static size_t a2height(const struct termp *p, const char *v) { struct roffsu su; assert(v); if ( ! a2roffsu(v, &su, SCALE_VS)) SCALE_VS_INIT(&su, term_len(p, 1)); return(term_vspan(p, &su)); }
/* * Set up the indentation for a list item; used from pre_it(). */ static void print_width(const char *v, const struct mdoc_node *child, size_t defsz) { char buf[24]; struct roffsu su; size_t sz, chsz; int numeric, remain; numeric = 1; remain = 0; /* Convert v into a number (of characters). */ if (NULL == v) sz = defsz; else if (a2roffsu(v, &su, SCALE_MAX)) { if (SCALE_EN == su.unit) sz = su.scale; else { sz = 0; numeric = 0; } } else sz = strlen(v); /* XXX Rough estimation, might have multiple parts. */ chsz = (NULL != child && MDOC_TEXT == child->type) ? strlen(child->string) : 0; /* Maybe we are inside an enclosing list? */ mid_it(); /* * Save our own indentation, * such that child lists can use it. */ Bl_stack[Bl_stack_len++] = sz + 2; /* Set up the current list. */ if (defsz && chsz > sz) print_block(".HP", 0); else { print_block(".TP", 0); remain = sz + 2; } if (numeric) { (void)snprintf(buf, sizeof(buf), "%zun", sz + 2); print_word(buf); } else print_word(v); TPremain = remain; }
static int pre_sp(DECL_ARGS) { struct roffsu su; int i, len; if ((NULL == n->prev && n->parent)) { switch (n->parent->tok) { case MAN_SH: case MAN_SS: case MAN_PP: case MAN_LP: case MAN_P: return 0; default: break; } } if (n->tok == MAN_br) len = 0; else if (n->child == NULL) len = 1; else { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } if (len == 0) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); /* * Handle an explicit break request in the same way * as an overflowing line. */ if (p->flags & TERMP_BRIND) { p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); } return 0; }
static int pre_PD(DECL_ARGS) { struct roffsu su; n = n->child; if (n == NULL) { mt->pardist = 1; return 0; } assert(n->type == ROFFT_TEXT); if (a2roffsu(n->string, &su, SCALE_VS)) mt->pardist = term_vspan(p, &su); return 0; }
static void print_offs(const char *v, int keywords) { char buf[24]; struct roffsu su; const char *end; int sz; print_line(".RS", MMAN_Bk_susp); /* Convert v into a number (of characters). */ if (NULL == v || '\0' == *v || (keywords && !strcmp(v, "left"))) sz = 0; else if (keywords && !strcmp(v, "indent")) sz = 6; else if (keywords && !strcmp(v, "indent-two")) sz = 12; else { end = a2roffsu(v, &su, SCALE_EN); if (end == NULL || *end != '\0') sz = man_strlen(v); else if (SCALE_EN == su.unit) sz = su.scale; else { /* * XXX * If we are inside an enclosing list, * there is no easy way to add the two * indentations because they are provided * in terms of different units. */ print_word(v); outflags |= MMAN_nl; return; } } /* * We are inside an enclosing list. * Add the two indentations. */ if (Bl_stack_len) sz += Bl_stack[Bl_stack_len - 1]; (void)snprintf(buf, sizeof(buf), "%dn", sz); print_word(buf); outflags |= MMAN_nl; }
/* * Calculate the scaling unit passed in an `-offset' argument. This * uses either a native scaling unit (e.g., 1i, 2m), one of a set of * predefined strings (indent, etc.), or the string length of the value. */ static void a2offs(const char *p, struct roffsu *su) { /* FIXME: "right"? */ if (0 == strcmp(p, "left")) SCALE_HS_INIT(su, 0); else if (0 == strcmp(p, "indent")) SCALE_HS_INIT(su, INDENT); else if (0 == strcmp(p, "indent-two")) SCALE_HS_INIT(su, INDENT * 2); else if ( ! a2roffsu(p, su, SCALE_MAX)) { su->unit = SCALE_BU; su->scale = (int)strlen(p); } }
static size_t a2offs(const struct termp *p, const char *v) { struct roffsu su; if ('\0' == *v) return(0); else if (0 == strcmp(v, "left")) return(0); else if (0 == strcmp(v, "indent")) return(term_len(p, p->defindent + 1)); else if (0 == strcmp(v, "indent-two")) return(term_len(p, (p->defindent + 1) * 2)); else if ( ! a2roffsu(v, &su, SCALE_MAX)) SCALE_HS_INIT(&su, term_strlen(p, v)); return(term_hspan(p, &su)); }
static int pre_sp(DECL_ARGS) { struct roffsu su; int i, len; if ((NULL == n->prev && n->parent)) { switch (n->parent->tok) { case MAN_SH: /* FALLTHROUGH */ case MAN_SS: /* FALLTHROUGH */ case MAN_PP: /* FALLTHROUGH */ case MAN_LP: /* FALLTHROUGH */ case MAN_P: /* FALLTHROUGH */ return(0); default: break; } } if (n->tok == MAN_br) len = 0; else if (n->child == NULL) len = 1; else { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } if (len == 0) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); return(0); }
static int pre_in(DECL_ARGS) { struct roffsu su; const char *cp; size_t v; int less; term_newln(p); if (NULL == n->child) { p->offset = mt->offset; return 0; } cp = n->child->string; less = 0; if ('-' == *cp) less = -1; else if ('+' == *cp) less = 1; else cp--; if ( ! a2roffsu(++cp, &su, SCALE_EN)) return 0; v = (term_hspan(p, &su) + 11) / 24; if (less < 0) p->offset -= p->offset > v ? v : p->offset; else if (less > 0) p->offset += v; else p->offset = v; if (p->offset > SHRT_MAX) p->offset = term_len(p, p->defindent); return 0; }
static void roff_term_pre_po(ROFF_TERM_ARGS) { struct roffsu su; static int po, polast; int ponew; if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EM) != NULL) { ponew = term_hen(p, &su); if (*n->child->string == '+' || *n->child->string == '-') ponew += po; } else ponew = polast; polast = po; po = ponew; ponew = po - polast + (int)p->tcol->offset; p->tcol->offset = ponew > 0 ? ponew : 0; }
static void roff_term_pre_sp(ROFF_TERM_ARGS) { struct roffsu su; int len; if (n->child != NULL) { if (a2roffsu(n->child->string, &su, SCALE_VS) == NULL) su.scale = 1.0; len = term_vspan(p, &su); } else len = 1; if (len < 0) p->skipvsp -= len; else while (len--) term_vspace(p); roff_term_pre_br(p, n); }
static void roff_term_pre_ti(ROFF_TERM_ARGS) { struct roffsu su; const char *cp; int len, sign; roff_term_pre_br(p, n); if (n->child == NULL) return; cp = n->child->string; if (*cp == '+') { sign = 1; cp++; } else if (*cp == '-') { sign = -1; cp++; } else sign = 0; if (a2roffsu(cp, &su, SCALE_EM) == NULL) return; len = term_hen(p, &su); if (sign == 0) { p->ti = len - p->tcol->offset; p->tcol->offset = len; } else if (sign == 1) { p->ti = len; p->tcol->offset += len; } else if ((size_t)len < p->tcol->offset) { p->ti = -len; p->tcol->offset -= len; } else { p->ti = -p->tcol->offset; p->tcol->offset = 0; } }
static int pre_HP(DECL_ARGS) { struct roffsu su; const struct roff_node *nn; int len; switch (n->type) { case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); return 1; case ROFFT_BODY: break; default: return 0; } if ( ! (MANT_LITERAL & mt->fl)) { p->flags |= TERMP_NOBREAK | TERMP_BRIND; p->trailspace = 2; } /* Calculate offset. */ if ((nn = n->parent->head->child) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) len = term_len(p, p->defindent); mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; p->offset = mt->offset; p->rmargin = mt->offset + len; return 1; }
static int pre_TP(DECL_ARGS) { struct roffsu su; struct roff_node *nn; int len, savelit; switch (n->type) { case ROFFT_HEAD: p->flags |= TERMP_NOBREAK | TERMP_BRTRSP; p->trailspace = 1; break; case ROFFT_BODY: p->flags |= TERMP_NOSPACE; break; case ROFFT_BLOCK: print_bvspace(p, n, mt->pardist); /* FALLTHROUGH */ default: return 1; } /* Calculate offset. */ if ((nn = n->parent->head->child) != NULL && nn->string != NULL && ! (MAN_LINE & nn->flags) && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su) / 24; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; else if (len > SHRT_MAX) len = term_len(p, p->defindent); mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; switch (n->type) { case ROFFT_HEAD: p->offset = mt->offset; p->rmargin = mt->offset + len; savelit = MANT_LITERAL & mt->fl; mt->fl &= ~MANT_LITERAL; /* Don't print same-line elements. */ nn = n->child; while (NULL != nn && 0 == (MAN_LINE & nn->flags)) nn = nn->next; while (NULL != nn) { print_man_node(p, mt, nn, meta); nn = nn->next; } if (savelit) mt->fl |= MANT_LITERAL; return 0; case ROFFT_BODY: p->offset = mt->offset + len; p->rmargin = p->maxrmargin; p->trailspace = 0; p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP); break; default: break; } return 1; }