version 1.55, 2015/02/19 16:34:32 |
version 1.56, 2015/02/20 13:33:52 |
Line 208 outbuf_flush(struct state *st) |
|
Line 208 outbuf_flush(struct state *st) |
|
if (0 == st->outbuflen) |
if (0 == st->outbuflen) |
return; |
return; |
|
|
if (OUST_TXT == st->oust && st->wantws) |
if (OUST_NL != st->oust && st->wantws) |
putchar(' '); |
putchar(' '); |
|
|
if (OUST_MAC == st->oust && '"' == *st->outbuf) |
if (OUST_MAC == st->oust && '"' == *st->outbuf) |
|
|
'?' != buf[*start + 1] && |
'?' != buf[*start + 1] && |
'-' != buf[*start + 1]) { |
'-' != buf[*start + 1]) { |
(*start)--; |
(*start)--; |
fputs("Ar ", stdout); |
fputs("Ar", stdout); |
return; |
return; |
} |
} |
|
|
|
|
assert(i < end); |
assert(i < end); |
|
|
if ( ! (' ' == buf[i] || '>' == buf[i])) { |
if ( ! (' ' == buf[i] || '>' == buf[i])) { |
printf("Ar "); |
fputs("Ar", stdout); |
return; |
return; |
} |
} |
|
|
|
|
(end - *start == 2 || |
(end - *start == 2 || |
' ' == buf[*start + 2])) |
' ' == buf[*start + 2])) |
printf("\\&"); |
printf("\\&"); |
printf("%.*s ", (int)(i - *start), &buf[*start]); |
printf("%.*s", (int)(i - *start), &buf[*start]); |
*start = i; |
*start = i; |
|
|
if (' ' == buf[i]) { |
if (' ' == buf[i]) { |
|
|
*start = i; |
*start = i; |
goto again; |
goto again; |
} |
} |
printf("Ar "); |
fputs("Ar", stdout); |
*start = i; |
*start = i; |
} |
} |
} |
} |
Line 511 formatcode(struct state *st, const char *buf, size_t * |
|
Line 511 formatcode(struct state *st, const char *buf, size_t * |
|
size_t i, j, dsz; |
size_t i, j, dsz; |
enum fmt fmt; |
enum fmt fmt; |
unsigned char uc; |
unsigned char uc; |
|
int gotmacro, wantws; |
|
|
assert(*start + 1 < end); |
assert(*start + 1 < end); |
assert('<' == buf[*start + 1]); |
assert('<' == buf[*start + 1]); |
Line 588 formatcode(struct state *st, const char *buf, size_t * |
|
Line 589 formatcode(struct state *st, const char *buf, size_t * |
|
if (FMT__MAX != fmt && !nomacro) { |
if (FMT__MAX != fmt && !nomacro) { |
|
|
/* |
/* |
|
* Do we need spacing before the upcoming macro, |
|
* after any pending text already in the outbuf? |
|
* We may already have wantws if there was whitespace |
|
* before the code ("text B<text"), or there may be |
|
* whitespace inside our scope ("textB< text"). |
|
*/ |
|
|
|
wantws = ' ' == buf[*start] || |
|
(st->wantws && ! st->outbuflen); |
|
|
|
/* |
* If we are on a text line and there is no |
* If we are on a text line and there is no |
* whitespace before our content, we have to make |
* whitespace before our content, we have to make |
* the previous word a prefix to the macro line. |
* the previous word a prefix to the macro line. |
*/ |
*/ |
|
|
if (OUST_MAC != st->oust && ' ' != buf[*start] && |
if (OUST_MAC != st->oust && ! wantws) { |
st->outbuflen) { |
|
if (OUST_NL != st->oust) |
if (OUST_NL != st->oust) |
mdoc_newln(st); |
mdoc_newln(st); |
printf(".Pf "); |
fputs(".Pf", stdout); |
st->oust = OUST_MAC; |
st->oust = OUST_MAC; |
st->wantws = 1; |
st->wantws = wantws = 1; |
} |
} |
|
|
outbuf_flush(st); |
outbuf_flush(st); |
|
|
/* |
/* Whitespace is easier to suppress on macro lines. */ |
* Whitespace is easier to suppress on macro lines. |
|
* We may already have wantws if there was whitespace |
|
* before the code ("text B<text"), or there may be |
|
* whitespace inside our scope ("textB< text"). |
|
*/ |
|
|
|
if (OUST_MAC == st->oust && ' ' != buf[*start] && |
if (OUST_MAC == st->oust && ! wantws) |
! st->wantws) |
|
printf(" Ns"); |
printf(" Ns"); |
|
|
/* Unless we are on a macro line, start one. */ |
/* Unless we are on a macro line, start one. */ |
Line 633 formatcode(struct state *st, const char *buf, size_t * |
|
Line 638 formatcode(struct state *st, const char *buf, size_t * |
|
|
|
switch (fmt) { |
switch (fmt) { |
case (FMT_ITALIC): |
case (FMT_ITALIC): |
printf("Em "); |
fputs("Em", stdout); |
break; |
break; |
case (FMT_BOLD): |
case (FMT_BOLD): |
if (SECT_SYNOPSIS == st->sect) { |
if (SECT_SYNOPSIS == st->sect) { |
if (1 == dsz && '-' == buf[*start]) |
if (1 == dsz && '-' == buf[*start]) |
dosynopsisfl(buf, start, end); |
dosynopsisfl(buf, start, end); |
else if (0 == pos) |
else if (0 == pos) |
printf("Nm "); |
fputs("Nm", stdout); |
else |
else |
printf("Ar "); |
fputs("Ar", stdout); |
break; |
break; |
} |
} |
i = 0; |
i = 0; |
Line 652 formatcode(struct state *st, const char *buf, size_t * |
|
Line 657 formatcode(struct state *st, const char *buf, size_t * |
|
if ('=' != uc && '>' != uc) |
if ('=' != uc && '>' != uc) |
i = 0; |
i = 0; |
if (4 == i && ! strncmp(buf + *start, "NULL", 4)) { |
if (4 == i && ! strncmp(buf + *start, "NULL", 4)) { |
printf("Dv "); |
fputs("Dv", stdout); |
break; |
break; |
} |
} |
switch (i ? dict_get(buf + *start, i) : MDOC_MAX) { |
switch (i ? dict_get(buf + *start, i) : MDOC_MAX) { |
case MDOC_Fa: |
case MDOC_Fa: |
printf("Fa "); |
fputs("Fa", stdout); |
break; |
break; |
case MDOC_Vt: |
case MDOC_Vt: |
printf("Vt "); |
fputs("Vt", stdout); |
break; |
break; |
default: |
default: |
printf("Sy "); |
fputs("Sy", stdout); |
break; |
break; |
} |
} |
break; |
break; |
case (FMT_CODE): |
case (FMT_CODE): |
printf("Qo Li "); |
fputs("Qo Li", stdout); |
break; |
break; |
case (FMT_LINK): |
case (FMT_LINK): |
/* Try to link; use "No" if it's empty. */ |
/* Try to link; use "No" if it's empty. */ |
if ( ! trylink(buf, start, end, dsz)) |
if ( ! trylink(buf, start, end, dsz)) |
printf("No "); |
fputs("No", stdout); |
break; |
break; |
case (FMT_FILE): |
case (FMT_FILE): |
printf("Pa "); |
fputs("Pa", stdout); |
break; |
break; |
case (FMT_NBSP): |
case (FMT_NBSP): |
printf("No "); |
fputs("No", stdout); |
break; |
break; |
default: |
default: |
abort(); |
abort(); |
} |
} |
} else |
} else { |
outbuf_flush(st); |
outbuf_flush(st); |
|
st->wantws = 0; |
|
} |
|
|
/* |
/* |
* Process until we reach the end marker (e.g., '>') or until we |
* Process until we reach the end marker (e.g., '>') or until we |
Line 693 formatcode(struct state *st, const char *buf, size_t * |
|
Line 700 formatcode(struct state *st, const char *buf, size_t * |
|
* Don't emit any newlines: since we're on a macro line, we |
* Don't emit any newlines: since we're on a macro line, we |
* don't want to break the line. |
* don't want to break the line. |
*/ |
*/ |
|
|
|
gotmacro = 0; |
while (*start < end) { |
while (*start < end) { |
if ('>' == buf[*start] && 1 == dsz) { |
if ('>' == buf[*start] && 1 == dsz) { |
(*start)++; |
(*start)++; |
Line 716 formatcode(struct state *st, const char *buf, size_t * |
|
Line 725 formatcode(struct state *st, const char *buf, size_t * |
|
} |
} |
if (*start + 1 < end && '<' == buf[*start + 1] && |
if (*start + 1 < end && '<' == buf[*start + 1] && |
'A' <= buf[*start] && 'Z' >= buf[*start]) { |
'A' <= buf[*start] && 'Z' >= buf[*start]) { |
if ( ! formatcode(st, buf, start, end, nomacro, 1)) |
gotmacro = formatcode(st, buf, |
st->wantws = 1; |
start, end, nomacro, 1); |
continue; |
continue; |
} |
} |
|
|
/* Suppress newlines and multiple spaces. */ |
/* Suppress newlines and multiple spaces. */ |
|
|
last = buf[(*start)++]; |
last = buf[(*start)++]; |
if (' ' == last || '\n' == last) { |
if (isspace(last)) { |
putchar(' '); |
outbuf_flush(st); |
while (*start < end && ' ' == buf[*start]) |
st->wantws = 1; |
|
gotmacro = 0; |
|
while (*start < end && |
|
isspace((unsigned char)buf[*start])) |
(*start)++; |
(*start)++; |
continue; |
continue; |
} |
} |
|
|
if (OUST_MAC == st->oust && FMT__MAX != fmt) { |
if (OUST_MAC == st->oust && FMT__MAX != fmt) { |
if ( ! st->wantws) { |
if (gotmacro && ! st->wantws) { |
printf(" Ns "); |
printf(" Ns"); |
st->wantws = 1; |
st->wantws = 1; |
} |
} |
|
gotmacro = 0; |
|
|
/* |
/* |
* Escape macro-like words. |
* Escape macro-like words. |
* This matches "Xx " and "XxEOLN". |
* This matches "Xx " and "XxEOLN". |
*/ |
*/ |
|
|
if (end - *start > 0 && |
if (*start < end && ! st->outbuflen && |
isupper((unsigned char)last) && |
isupper(last) && |
islower((unsigned char)buf[*start]) && |
islower((unsigned char)buf[*start]) && |
(end - *start == 1 || |
(end - *start == 1 || |
' ' == buf[*start + 1] || |
' ' == buf[*start + 1] || |
'>' == buf[*start + 1])) |
'>' == buf[*start + 1])) |
printf("\\&"); |
outbuf_addstr(st, "\\&"); |
|
last = buf[*start - 1]; |
} |
} |
|
outbuf_addchar(st); |
|
} |
|
|
putchar(last); |
if (FMT__MAX == fmt) |
|
return(0); |
|
|
/* Protect against character escapes. */ |
outbuf_flush(st); |
|
|
if ('\\' == last) |
|
putchar('e'); |
|
} |
|
|
|
if ( ! nomacro && FMT_CODE == fmt) |
if ( ! nomacro && FMT_CODE == fmt) |
printf(" Qc "); |
fputs(" Qc", stdout); |
|
|
st->wantws = ' ' == last; |
st->wantws = ' ' == last; |
return(FMT__MAX != fmt); |
return(1); |
} |
} |
|
|
/* |
/* |
|
|
formatcodeln(struct state *st, const char *linemac, |
formatcodeln(struct state *st, const char *linemac, |
const char *buf, size_t *start, size_t end, int nomacro) |
const char *buf, size_t *start, size_t end, int nomacro) |
{ |
{ |
int gotmacro, wantws; |
int gotmacro; |
|
|
assert(OUST_NL == st->oust); |
assert(OUST_NL == st->oust); |
assert(st->wantws); |
assert(st->wantws); |
printf(".%s ", linemac); |
printf(".%s", linemac); |
st->oust = OUST_MAC; |
st->oust = OUST_MAC; |
|
|
gotmacro = 0; |
gotmacro = 0; |
while (*start < end) { |
while (*start < end) { |
wantws = ' ' == buf[*start] || '\n' == buf[*start]; |
|
if (wantws) { |
|
last = ' '; |
|
do { |
|
(*start)++; |
|
} while (*start < end && ' ' == buf[*start]); |
|
} |
|
|
|
if (*start + 1 < end && '<' == buf[*start + 1] && |
if (*start + 1 < end && '<' == buf[*start + 1] && |
'A' <= buf[*start] && 'Z' >= buf[*start]) { |
'A' <= buf[*start] && 'Z' >= buf[*start]) { |
st->wantws |= wantws; |
|
gotmacro = formatcode(st, buf, |
gotmacro = formatcode(st, buf, |
start, end, nomacro, 1); |
start, end, nomacro, 1); |
continue; |
continue; |
} |
} |
|
|
|
/* Suppress newlines and multiple spaces. */ |
|
|
|
last = buf[(*start)++]; |
|
if (isspace(last)) { |
|
outbuf_flush(st); |
|
st->wantws = 1; |
|
while (*start < end && |
|
isspace((unsigned char)buf[*start])) |
|
(*start)++; |
|
continue; |
|
} |
|
|
if (gotmacro) { |
if (gotmacro) { |
if (*start < end || st->outbuflen) { |
if (*start < end) { |
if (st->wantws || |
if (st->wantws) |
(wantws && !st->outbuflen)) |
printf(" No"); |
printf(" No "); |
|
else |
else |
printf(" Ns "); |
printf(" Ns"); |
} |
} |
|
st->wantws = 1; |
gotmacro = 0; |
gotmacro = 0; |
} |
} |
outbuf_flush(st); |
|
st->wantws = wantws; |
|
|
|
if (*start >= end) |
|
break; |
|
|
|
if (st->wantws) { |
|
putchar(' '); |
|
st->wantws = 0; |
|
} |
|
|
|
/* |
/* |
* Since we're already on a macro line, we want to make |
* Since we're already on a macro line, we want to make |
* sure that we don't inadvertently invoke a macro. |
* sure that we don't inadvertently invoke a macro. |
Line 829 formatcodeln(struct state *st, const char *linemac, |
|
Line 835 formatcodeln(struct state *st, const char *linemac, |
|
* are used in troff and we don't want to escape |
* are used in troff and we don't want to escape |
* something that needn't be escaped. |
* something that needn't be escaped. |
*/ |
*/ |
if (' ' == last && end - *start > 1 && |
if (*start < end && ! st->outbuflen && isupper(last) && |
isupper((unsigned char)buf[*start]) && |
islower((unsigned char)buf[*start]) && |
islower((unsigned char)buf[*start + 1]) && |
(end - *start == 1 || ' ' == buf[*start + 1])) { |
(end - *start == 2 || ' ' == buf[*start + 2])) |
outbuf_addstr(st, "\\&"); |
printf("\\&"); |
last = buf[*start - 1]; |
|
} |
putchar(last = buf[*start]); |
outbuf_addchar(st); |
|
|
/* Protect against character escapes. */ |
|
|
|
if ('\\' == last) |
|
putchar('e'); |
|
|
|
(*start)++; |
|
} |
} |
|
outbuf_flush(st); |
|
st->wantws = 1; |
} |
} |
|
|
/* |
/* |
Line 1529 ordinary(struct state *st, const char *buf, size_t sta |
|
Line 1530 ordinary(struct state *st, const char *buf, size_t sta |
|
st->outbuf[wend] = '\0'; |
st->outbuf[wend] = '\0'; |
mdoc_newln(st); |
mdoc_newln(st); |
if (MDOC_Fo == mtype) |
if (MDOC_Fo == mtype) |
fputs(".Fn ", stdout); |
fputs(".Fn", stdout); |
else |
else |
fputs(".Xr ", stdout); |
fputs(".Xr", stdout); |
st->oust = OUST_MAC; |
st->oust = OUST_MAC; |
} |
} |
} else { |
} else { |
Line 1540 ordinary(struct state *st, const char *buf, size_t sta |
|
Line 1541 ordinary(struct state *st, const char *buf, size_t sta |
|
savechar = st->outbuf[wend]; |
savechar = st->outbuf[wend]; |
st->outbuf[wend] = '\0'; |
st->outbuf[wend] = '\0'; |
mdoc_newln(st); |
mdoc_newln(st); |
fputs(".Dv ", stdout); |
fputs(".Dv", stdout); |
st->oust = OUST_MAC; |
st->oust = OUST_MAC; |
} else |
} else |
mtype = MDOC_Fa; |
mtype = MDOC_Fa; |
Line 1623 ordinary(struct state *st, const char *buf, size_t sta |
|
Line 1624 ordinary(struct state *st, const char *buf, size_t sta |
|
('<' != buf[start + 1] || |
('<' != buf[start + 1] || |
'A' > buf[start] || |
'A' > buf[start] || |
'Z' < buf[start])) { |
'Z' < buf[start])) { |
printf(" Ns "); |
fputs(" Ns", stdout); |
st->wantws = 1; |
st->wantws = 1; |
} |
} |
} |
} |