version 1.46, 2015/02/25 14:37:17 |
version 1.62, 2015/03/05 09:36:41 |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <time.h> |
#include <unistd.h> |
|
|
#include "extern.h" |
#include "extern.h" |
|
|
Line 42 static void doaccent(struct texi *, enum texicmd, size |
|
Line 42 static void doaccent(struct texi *, enum texicmd, size |
|
static void doblock(struct texi *, enum texicmd, size_t *); |
static void doblock(struct texi *, enum texicmd, size_t *); |
static void dobracket(struct texi *, enum texicmd, size_t *); |
static void dobracket(struct texi *, enum texicmd, size_t *); |
static void dobye(struct texi *, enum texicmd, size_t *); |
static void dobye(struct texi *, enum texicmd, size_t *); |
|
static void docopying(struct texi *, enum texicmd, size_t *); |
static void dodefindex(struct texi *, enum texicmd, size_t *); |
static void dodefindex(struct texi *, enum texicmd, size_t *); |
static void dodefn(struct texi *, enum texicmd, size_t *); |
static void dodefn(struct texi *, enum texicmd, size_t *); |
static void dodisplay(struct texi *, enum texicmd, size_t *); |
static void dodisplay(struct texi *, enum texicmd, size_t *); |
Line 54 static void doignbracket(struct texi *, enum texicmd, |
|
Line 55 static void doignbracket(struct texi *, enum texicmd, |
|
static void doignline(struct texi *, enum texicmd, size_t *); |
static void doignline(struct texi *, enum texicmd, size_t *); |
static void doinline(struct texi *, enum texicmd, size_t *); |
static void doinline(struct texi *, enum texicmd, size_t *); |
static void doinclude(struct texi *, enum texicmd, size_t *); |
static void doinclude(struct texi *, enum texicmd, size_t *); |
|
static void doinsertcopying(struct texi *, enum texicmd, size_t *); |
static void doitem(struct texi *, enum texicmd, size_t *); |
static void doitem(struct texi *, enum texicmd, size_t *); |
static void doitemize(struct texi *, enum texicmd, size_t *); |
static void doitemize(struct texi *, enum texicmd, size_t *); |
static void dolink(struct texi *, enum texicmd, size_t *); |
static void dolink(struct texi *, enum texicmd, size_t *); |
Line 94 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 96 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
{ dosymbol, "*", 1 }, /* TEXICMD_ASTERISK */ |
{ dosymbol, "*", 1 }, /* TEXICMD_ASTERISK */ |
{ dosymbol, "@", 1 }, /* TEXICMD_AT */ |
{ dosymbol, "@", 1 }, /* TEXICMD_AT */ |
{ doignline, "author", 6 }, /* TEXICMD_AUTHOR */ |
{ doignline, "author", 6 }, /* TEXICMD_AUTHOR */ |
{ doinline, "b", 1 }, /* TEXICMD_BOLD */ |
{ doinline, "b", 1 }, /* TEXICMD_B */ |
|
{ dosymbol, "\\", 1 }, /* TEXICMD_BACKSLASH */ |
{ dosymbol, "!", 1 }, /* TEXICMD_BANG */ |
{ dosymbol, "!", 1 }, /* TEXICMD_BANG */ |
{ dosymbol, "bullet", 6 }, /* TEXICMD_BULLET */ |
{ dosymbol, "bullet", 6 }, /* TEXICMD_BULLET */ |
{ dobye, "bye", 3 }, /* TEXICMD_BYE */ |
{ dobye, "bye", 3 }, /* TEXICMD_BYE */ |
Line 114 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 117 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
{ doignline, "c", 1 }, /* TEXICMD_COMMENT */ |
{ doignline, "c", 1 }, /* TEXICMD_COMMENT */ |
{ doignline, "comment", 7 }, /* TEXICMD_COMMENT_LONG */ |
{ doignline, "comment", 7 }, /* TEXICMD_COMMENT_LONG */ |
{ doignline, "contents", 8 }, /* TEXICMD_CONTENTS */ |
{ doignline, "contents", 8 }, /* TEXICMD_CONTENTS */ |
{ doignblock, "copying", 7 }, /* TEXICMD_COPYING */ |
{ docopying, "copying", 7 }, /* TEXICMD_COPYING */ |
{ dosymbol, "copyright", 9 }, /* TEXICMD_COPYRIGHT */ |
{ dosymbol, "copyright", 9 }, /* TEXICMD_COPYRIGHT */ |
{ dodefindex, "defcodeindex", 12 }, /* TEXICMD_DEFCODEINDEX */ |
{ dodefindex, "defcodeindex", 12 }, /* TEXICMD_DEFCODEINDEX */ |
{ dodefn, "deffn", 5 }, /* TEXICMD_DEFFN */ |
{ dodefn, "deffn", 5 }, /* TEXICMD_DEFFN */ |
Line 213 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 216 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
{ dodisplay, "indentblock", 11 }, /* TEXICMD_INDENTBLOCK */ |
{ dodisplay, "indentblock", 11 }, /* TEXICMD_INDENTBLOCK */ |
{ dolink, "indicateurl", 11 }, /* TEXICMD_INDICATEURL */ |
{ dolink, "indicateurl", 11 }, /* TEXICMD_INDICATEURL */ |
{ dolink, "inforef", 7 }, /* TEXICMD_INFOREF */ |
{ dolink, "inforef", 7 }, /* TEXICMD_INFOREF */ |
{ doignline, "insertcopying", 13 }, /* TEXICMD_INSERTCOPYING */ |
{ doinsertcopying, "insertcopying", 13 }, /* TEXICMD_INSERTCOPYING */ |
{ doitem, "item", 4 }, /* TEXICMD_ITEM */ |
{ doitem, "item", 4 }, /* TEXICMD_ITEM */ |
{ doitemize, "itemize", 7 }, /* TEXICMD_ITEMIZE */ |
{ doitemize, "itemize", 7 }, /* TEXICMD_ITEMIZE */ |
{ doitem, "itemx", 5 }, /* TEXICMD_ITEMX */ |
{ doitem, "itemx", 5 }, /* TEXICMD_ITEMX */ |
Line 268 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 271 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
{ doaccent, "ringaccent", 10 }, /* TEXICMD_RINGACCENT */ |
{ doaccent, "ringaccent", 10 }, /* TEXICMD_RINGACCENT */ |
{ doinline, "samp", 4 }, /* TEXICMD_SAMP */ |
{ doinline, "samp", 4 }, /* TEXICMD_SAMP */ |
{ doinline, "sansserif", 9 }, /* TEXICMD_SANSSERIF */ |
{ doinline, "sansserif", 9 }, /* TEXICMD_SANSSERIF */ |
{ dobracket, "sc", 2 }, /* TEXICMD_SC */ |
{ doinline, "sc", 2 }, /* TEXICMD_SC */ |
{ dosection, "section", 7 }, /* TEXICMD_SECTION */ |
{ dosection, "section", 7 }, /* TEXICMD_SECTION */ |
{ dovalue, "set", 3 }, /* TEXICMD_SET */ |
{ dovalue, "set", 3 }, /* TEXICMD_SET */ |
{ doignline, "setchapternewpage", 17 }, /* TEXICMD_SETCHAPNEWPAGE */ |
{ doignline, "setchapternewpage", 17 }, /* TEXICMD_SETCHAPNEWPAGE */ |
Line 295 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 298 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
{ dosubsubsection, "subsubsection", 13 }, /* TEXICMD_SUBSUBSECTION */ |
{ dosubsubsection, "subsubsection", 13 }, /* TEXICMD_SUBSUBSECTION */ |
{ doignline, "subtitle", 8 }, /* TEXICMD_SUBTITLE */ |
{ doignline, "subtitle", 8 }, /* TEXICMD_SUBTITLE */ |
{ doignline, "summarycontents", 15 }, /* TEXICMD_SUMMARYCONTENTS */ |
{ doignline, "summarycontents", 15 }, /* TEXICMD_SUMMARYCONTENTS */ |
{ doignline, "synindex", 8 }, /* TEXICMD_SYNINDEX */ |
{ dodefindex, "synindex", 8 }, /* TEXICMD_SYNINDEX */ |
{ doignline, "syncodeindex", 12 }, /* TEXICMD_SYNCODEINDEX */ |
{ dodefindex, "syncodeindex", 12 }, /* TEXICMD_SYNCODEINDEX */ |
{ doinline, "t", 1 }, /* TEXICMD_T */ |
{ doinline, "t", 1 }, /* TEXICMD_T */ |
{ dotab, "tab", 3 }, /* TEXICMD_TAB */ |
{ dotab, "tab", 3 }, /* TEXICMD_TAB */ |
{ dosymbol, "\t", 1 }, /* TEXICMD_TABSYM */ |
{ dosymbol, "\t", 1 }, /* TEXICMD_TABSYM */ |
Line 341 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
Line 344 static const struct texitok __texitoks[TEXICMD__MAX] = |
|
|
|
const struct texitok *const texitoks = __texitoks; |
const struct texitok *const texitoks = __texitoks; |
|
|
|
/* |
|
* Texinfo has lots of indexes. |
|
* You can add new ones in a variety of ways. |
|
* We maintain an array of all of these index names (usually a few |
|
* letters) and pass unknown commands through the array list. |
|
*/ |
static void |
static void |
dodefindex(struct texi *p, enum texicmd cmd, size_t *pos) |
dodefindex(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
Line 349 dodefindex(struct texi *p, enum texicmd cmd, size_t *p |
|
Line 358 dodefindex(struct texi *p, enum texicmd cmd, size_t *p |
|
|
|
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
advance(p, pos); |
advance(p, pos); |
|
|
start = end = *pos; |
start = end = *pos; |
while (end < BUFSZ(p) && ! ismspace(BUF(p)[end])) |
while (end < BUFSZ(p) && ! ismspace(BUF(p)[end])) |
end++; |
end++; |
Line 357 dodefindex(struct texi *p, enum texicmd cmd, size_t *p |
|
Line 365 dodefindex(struct texi *p, enum texicmd cmd, size_t *p |
|
if (start == end) { |
if (start == end) { |
advanceeoln(p, pos, 1); |
advanceeoln(p, pos, 1); |
return; |
return; |
} else if (NULL == (cp = malloc(end - start + 1))) |
} |
|
|
|
if (NULL == (cp = malloc(end - start + 1))) |
texiabort(p, NULL); |
texiabort(p, NULL); |
|
|
memcpy(cp, &BUF(p)[start], end - start); |
memcpy(cp, &BUF(p)[start], end - start); |
cp[end - start] = '\0'; |
cp[end - start] = '\0'; |
|
|
|
/* FIXME: use reallocarray(). */ |
p->indexs = realloc(p->indexs, |
p->indexs = realloc(p->indexs, |
sizeof(char *) * (p->indexsz + 1)); |
sizeof(char *) * (p->indexsz + 1)); |
|
|
if (NULL == p->indexs) |
if (NULL == p->indexs) |
texiabort(p, NULL); |
texiabort(p, NULL); |
p->indexs[p->indexsz++] = cp; |
p->indexs[p->indexsz++] = cp; |
|
|
|
advanceeoln(p, pos, 1); |
} |
} |
|
|
static void |
static void |
Line 431 dodefn(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 442 dodefn(struct texi *p, enum texicmd cmd, size_t *pos) |
|
break; |
break; |
} |
} |
|
|
texiputchars(p, ":\n"); |
texiputchar(p, ':'); |
|
texiputchar(p, '\n'); |
|
|
switch (cmd) { |
switch (cmd) { |
case (TEXICMD_DEFMAC): |
case (TEXICMD_DEFMAC): |
Line 496 dodefn(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 508 dodefn(struct texi *p, enum texicmd cmd, size_t *pos) |
|
abort(); |
abort(); |
} |
} |
|
|
texivspace(p); |
if (NULL == blk) |
if (NULL != blk) |
return; |
parseto(p, pos, blk); |
|
|
/* |
|
* All "block" definitions have their block bodies indented |
|
* unless they have the "x" form of the command following. |
|
* E.g., |
|
* @deffn some function |
|
* @deffnx another |
|
* An explanation. |
|
* @end deffn |
|
* With this loop, we delay opening the indented block until we |
|
* skipped past conformant macros. |
|
*/ |
|
for (;;) { |
|
switch (peekcmd(p, *pos)) { |
|
case (TEXICMD_DEFFNX): |
|
case (TEXICMD_DEFMACX): |
|
case (TEXICMD_DEFTPX): |
|
case (TEXICMD_DEFTYPEFNX): |
|
case (TEXICMD_DEFTYPEFUNX): |
|
case (TEXICMD_DEFTYPEMETHODX): |
|
case (TEXICMD_DEFTYPEVARX): |
|
case (TEXICMD_DEFTYPEVRX): |
|
case (TEXICMD_DEFUNX): |
|
case (TEXICMD_DEFVARX): |
|
case (TEXICMD_DEFVRX): |
|
texivspace(p); |
|
parseeoln(p, pos); |
|
continue; |
|
default: |
|
break; |
|
} |
|
break; |
|
} |
|
teximacro(p, "Bd -filled -offset indent"); |
|
parseto(p, pos, blk); |
|
teximacro(p, "Ed"); |
|
p->seenvs = 1; |
} |
} |
|
|
static void |
static void |
Line 612 doignblock(struct texi *p, enum texicmd cmd, size_t *p |
|
Line 660 doignblock(struct texi *p, enum texicmd cmd, size_t *p |
|
* Thus, we keep track of scopes for matching "end" blocks. |
* Thus, we keep track of scopes for matching "end" blocks. |
*/ |
*/ |
while (stack > 0 && *pos < BUFSZ(p)) { |
while (stack > 0 && *pos < BUFSZ(p)) { |
if (stack > 10) |
if (stack > 64) |
abort(); |
texierr(p, "run-away nested stack?"); |
endt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, esz); |
endt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, esz); |
startt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, start, ssz); |
startt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, start, ssz); |
if (NULL == endt) { |
if (NULL == endt) { |
Line 688 doinline(struct texi *p, enum texicmd cmd, size_t *pos |
|
Line 736 doinline(struct texi *p, enum texicmd cmd, size_t *pos |
|
} |
} |
|
|
if (NULL == macro || p->literal || TEXILIST_TABLE == p->list) { |
if (NULL == macro || p->literal || TEXILIST_TABLE == p->list) { |
parsebracket(p, pos); |
if (TEXICMD_SC == cmd) |
|
p->uppercase++; |
|
parsebracket(p, pos, 0); |
|
if (TEXICMD_SC == cmd) |
|
p->uppercase--; |
return; |
return; |
} |
} |
|
|
|
/* |
|
* If we haven't seen any whitespace, then we don't want the |
|
* subsequent macro to insert any whitespace. |
|
*/ |
|
if (p->outmacro && 0 == p->seenws) { |
|
teximacroopen(p, "Ns"); |
|
teximacroclose(p); |
|
} |
|
|
teximacroopen(p, macro); |
teximacroopen(p, macro); |
p->seenws = 0; |
p->seenws = 0; |
parsebracket(p, pos); |
if (TEXICMD_SC == cmd) |
|
p->uppercase++; |
|
parsebracket(p, pos, 0); |
|
if (TEXICMD_SC == cmd) |
|
p->uppercase--; |
texipunctuate(p, pos); |
texipunctuate(p, pos); |
teximacroclose(p); |
teximacroclose(p); |
} |
} |
Line 726 doverb(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 791 doverb(struct texi *p, enum texicmd cmd, size_t *pos) |
|
break; |
break; |
advance(p, pos); |
advance(p, pos); |
} |
} |
if (*pos == BUFSZ(p) - 1) |
if (*pos >= BUFSZ(p) - 1) |
return; |
return; |
texiputbuf(p, start, *pos); |
texiputbuf(p, start, *pos); |
|
|
Line 738 doverb(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 803 doverb(struct texi *p, enum texicmd cmd, size_t *pos) |
|
} |
} |
|
|
static void |
static void |
|
doinsertcopying(struct texi *p, enum texicmd cmd, size_t *pos) |
|
{ |
|
|
|
advanceeoln(p, pos, 0); |
|
if (NULL == p->copying) |
|
return; |
|
texisplice(p, p->copying, p->copyingsz, *pos); |
|
} |
|
|
|
static void |
|
docopying(struct texi *p, enum texicmd cmd, size_t *pos) |
|
{ |
|
const char *end, *term; |
|
size_t endsz, endpos; |
|
|
|
/* We retain our starting (but not ending) newlines. */ |
|
end = "\n@end copying\n"; |
|
endsz = strlen(end); |
|
advanceeoln(p, pos, 0); |
|
if (*pos == BUFSZ(p)) { |
|
texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); |
|
return; |
|
} |
|
|
|
term = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, endsz); |
|
if (NULL == term) { |
|
texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); |
|
endpos = BUFSZ(p); |
|
} else |
|
endpos = *pos + (size_t)(term - &BUF(p)[*pos]); |
|
|
|
assert(endpos <= BUFSZ(p)); |
|
assert('\n' == BUF(p)[*pos]); |
|
advance(p, pos); |
|
|
|
p->copying = malloc(endpos - *pos + 1); |
|
p->copyingsz = endpos - *pos; |
|
memcpy(p->copying, &BUF(p)[*pos], p->copyingsz); |
|
p->copying[endpos - *pos] = '\0'; |
|
|
|
while (*pos < endpos) |
|
advance(p, pos); |
|
if (*pos < BUFSZ(p)) |
|
advanceto(p, pos, endpos + endsz); |
|
} |
|
|
|
static void |
doverbatim(struct texi *p, enum texicmd cmd, size_t *pos) |
doverbatim(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
const char *end, *term; |
const char *end, *term; |
Line 748 doverbatim(struct texi *p, enum texicmd cmd, size_t *p |
|
Line 860 doverbatim(struct texi *p, enum texicmd cmd, size_t *p |
|
endsz = strlen(end); |
endsz = strlen(end); |
advanceeoln(p, pos, 0); |
advanceeoln(p, pos, 0); |
if (*pos == BUFSZ(p)) { |
if (*pos == BUFSZ(p)) { |
texiwarn(p, "unexpected end of file"); |
texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); |
return; |
return; |
} |
} |
|
|
term = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, endsz); |
term = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, endsz); |
if (NULL == term) { |
if (NULL == term) { |
texiwarn(p, "unterminated verbatim block"); |
texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); |
endpos = BUFSZ(p); |
endpos = BUFSZ(p); |
} else |
} else |
endpos = *pos + (size_t)(term - &BUF(p)[*pos]); |
endpos = *pos + (size_t)(term - &BUF(p)[*pos]); |
Line 768 doverbatim(struct texi *p, enum texicmd cmd, size_t *p |
|
Line 880 doverbatim(struct texi *p, enum texicmd cmd, size_t *p |
|
advance(p, pos); |
advance(p, pos); |
} |
} |
teximacro(p, "Ed"); |
teximacro(p, "Ed"); |
|
p->seenvs = 1; |
if (*pos < BUFSZ(p)) |
if (*pos < BUFSZ(p)) |
advanceto(p, pos, endpos + endsz); |
advanceto(p, pos, endpos + endsz); |
} |
} |
|
|
dobracket(struct texi *p, enum texicmd cmd, size_t *pos) |
dobracket(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
|
|
parsebracket(p, pos); |
parsebracket(p, pos, 0); |
} |
} |
|
|
static void |
static void |
dodisplay(struct texi *p, enum texicmd cmd, size_t *pos) |
dodisplay(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
|
|
|
advanceeoln(p, pos, 1); |
|
|
switch (cmd) { |
switch (cmd) { |
case (TEXICMD_FORMAT): |
case (TEXICMD_FORMAT): |
case (TEXICMD_SMALLFORMAT): |
case (TEXICMD_SMALLFORMAT): |
Line 915 dodisplay(struct texi *p, enum texicmd cmd, size_t *po |
|
Line 1030 dodisplay(struct texi *p, enum texicmd cmd, size_t *po |
|
break; |
break; |
} |
} |
|
|
p->seenvs = 1; |
|
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
|
parseto(p, pos, texitoks[cmd].tok); |
parseto(p, pos, texitoks[cmd].tok); |
teximacro(p, "Ed"); |
teximacro(p, "Ed"); |
|
p->seenvs = 1; |
} |
} |
|
|
static void |
static void |
doexample(struct texi *p, enum texicmd cmd, size_t *pos) |
doexample(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
|
|
teximacro(p, "Bd -literal -offset indent"); |
|
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
advanceeoln(p, pos, 1); |
|
|
|
teximacro(p, "Bd -literal -offset indent"); |
p->literal++; |
p->literal++; |
parseto(p, pos, texitoks[cmd].tok); |
parseto(p, pos, texitoks[cmd].tok); |
p->literal--; |
p->literal--; |
teximacro(p, "Ed"); |
teximacro(p, "Ed"); |
|
p->seenvs = 1; |
} |
} |
|
|
static void |
static void |
Line 946 dobye(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 1060 dobye(struct texi *p, enum texicmd cmd, size_t *pos) |
|
static void |
static void |
dotitle(struct texi *p, enum texicmd cmd, size_t *pos) |
dotitle(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
size_t start, end; |
size_t start; |
|
|
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
advance(p, pos); |
advance(p, pos); |
start = end = *pos; |
|
while (end < BUFSZ(p) && '\n' != BUF(p)[end]) |
/* We want to suck down the entire line, inclusive \n. */ |
end++; |
start = *pos; |
advanceeoln(p, pos, 1); |
while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos]) { |
|
if ('@' == BUF(p)[*pos]) |
|
advance(p, pos); |
|
advance(p, pos); |
|
} |
|
if (*pos < BUFSZ(p)) |
|
advance(p, pos); |
|
|
|
/* Copy this into a buffer. */ |
free(p->subtitle); |
free(p->subtitle); |
p->subtitle = malloc(end - start + 1); |
if (NULL == (p->subtitle = malloc(*pos - start + 1))) |
if (NULL == p->subtitle) |
|
texiabort(p, NULL); |
texiabort(p, NULL); |
memcpy(p->subtitle, &BUF(p)[start], end - start); |
memcpy(p->subtitle, &BUF(p)[start], *pos - start); |
p->subtitle[end - start] = '\0'; |
p->subtitle[*pos - start] = '\0'; |
} |
} |
|
|
static void |
static void |
Line 988 doaccent(struct texi *p, enum texicmd cmd, size_t *pos |
|
Line 1109 doaccent(struct texi *p, enum texicmd cmd, size_t *pos |
|
if ('{' == BUF(p)[*pos]) { |
if ('{' == BUF(p)[*pos]) { |
brace = 1; |
brace = 1; |
advance(p, pos); |
advance(p, pos); |
} else if (isalpha(texitoks[cmd].tok[0])) |
} else if (isalpha((unsigned char)texitoks[cmd].tok[0])) |
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
advance(p, pos); |
advance(p, pos); |
|
|
Line 1152 dosymbol(struct texi *p, enum texicmd cmd, size_t *pos |
|
Line 1273 dosymbol(struct texi *p, enum texicmd cmd, size_t *pos |
|
case (TEXICMD_AT): |
case (TEXICMD_AT): |
texiputchar(p, '@'); |
texiputchar(p, '@'); |
break; |
break; |
|
case (TEXICMD_BACKSLASH): |
|
texiputchar(p, '\\'); |
|
break; |
case (TEXICMD_BANG): |
case (TEXICMD_BANG): |
texiputchar(p, '!'); |
texiputchar(p, '!'); |
break; |
break; |
Line 1310 dosymbol(struct texi *p, enum texicmd cmd, size_t *pos |
|
Line 1434 dosymbol(struct texi *p, enum texicmd cmd, size_t *pos |
|
} |
} |
|
|
/* Alphabetic commands have braces we ignore. */ |
/* Alphabetic commands have braces we ignore. */ |
if (isalpha(texitoks[cmd].tok[0])) |
if (isalpha((unsigned char)texitoks[cmd].tok[0])) |
doignbracket(p, cmd, pos); |
doignbracket(p, cmd, pos); |
} |
} |
|
|
Line 1326 doquotation(struct texi *p, enum texicmd cmd, size_t * |
|
Line 1450 doquotation(struct texi *p, enum texicmd cmd, size_t * |
|
static void |
static void |
domath(struct texi *p, enum texicmd cmd, size_t *pos) |
domath(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
size_t nest, start; |
|
|
|
/* |
parsebracket(p, pos, 1); |
* Math handling is different from everything else. |
|
* We don't allow any subcomponents, and we ignore the rules in |
|
* terms of @-commands. |
|
* This departs from GNU's rules, but whatever. |
|
*/ |
|
while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) |
|
advance(p, pos); |
|
if (*pos == BUFSZ(p) || '{' != BUF(p)[*pos]) |
|
return; |
|
advance(p, pos); |
|
if (p->seenws && p->outcol && 0 == p->literal) |
|
texiputchar(p, ' '); |
|
p->seenws = 0; |
|
for (nest = 1, start = *pos; *pos < BUFSZ(p) && nest > 0; ) { |
|
if ('{' == BUF(p)[*pos]) |
|
nest++; |
|
else if ('}' == BUF(p)[*pos]) |
|
if (0 == --nest) |
|
continue; |
|
advance(p, pos); |
|
} |
|
if (*pos == BUFSZ(p)) |
|
return; |
|
assert('}' == BUF(p)[*pos]); |
|
texiputbuf(p, start, *pos); |
|
advance(p, pos); |
|
} |
} |
|
|
static void |
static void |
Line 1400 dovalue(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 1497 dovalue(struct texi *p, enum texicmd cmd, size_t *pos) |
|
texiputchar(p, ' '); |
texiputchar(p, ' '); |
p->seenws = 0; |
p->seenws = 0; |
if (NULL != (cp = valueblookup(p, pos))) |
if (NULL != (cp = valueblookup(p, pos))) |
texisplice(p, cp, strlen(cp), pos); |
texisplice(p, cp, strlen(cp), *pos); |
else |
else |
texiputchars(p, "{No value}"); |
texiputchars(p, "{No value}"); |
} else if (TEXICMD_IFCLEAR == cmd) { |
} else if (TEXICMD_IFCLEAR == cmd) { |
Line 1542 dosection(struct texi *p, enum texicmd cmd, size_t *po |
|
Line 1639 dosection(struct texi *p, enum texicmd cmd, size_t *po |
|
int sec; |
int sec; |
|
|
switch (cmd) { |
switch (cmd) { |
|
case (TEXICMD_TOP): |
|
sec = 0; |
|
break; |
case (TEXICMD_APPENDIX): |
case (TEXICMD_APPENDIX): |
case (TEXICMD_CHAPTER): |
case (TEXICMD_CHAPTER): |
case (TEXICMD_TOP): |
|
case (TEXICMD_UNNUMBERED): |
case (TEXICMD_UNNUMBERED): |
sec = sectioner(p, 0); |
sec = sectioner(p, 0); |
break; |
break; |
Line 1563 dosection(struct texi *p, enum texicmd cmd, size_t *po |
|
Line 1662 dosection(struct texi *p, enum texicmd cmd, size_t *po |
|
else if (p->literal) |
else if (p->literal) |
texierr(p, "\"%s\" in a literal scope!?", sects[sec]); |
texierr(p, "\"%s\" in a literal scope!?", sects[sec]); |
|
|
|
if (0 == sec && NULL != p->chapters) { |
|
teximdocclose(p, 0); |
|
teximdocopen(p, pos); |
|
} |
|
|
teximacroopen(p, sects[sec]); |
teximacroopen(p, sects[sec]); |
parseeoln(p, pos); |
parseeoln(p, pos); |
teximacroclose(p); |
teximacroclose(p); |
p->seenvs = 1; |
|
} |
} |
|
|
static void |
static void |
dosp(struct texi *p, enum texicmd cmd, size_t *pos) |
|
{ |
|
|
|
if (p->literal) |
|
texiputchar(p, '\n'); |
|
else |
|
texivspace(p); |
|
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
|
} |
|
|
|
static void |
|
dotop(struct texi *p, enum texicmd cmd, size_t *pos) |
dotop(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
const char *cp; |
|
time_t t; |
|
char date[32]; |
|
|
|
if (--p->ign) |
if (--p->ign) |
texierr(p, "@top command while ignoring"); |
texierr(p, "@top command while ignoring"); |
|
|
/* |
if (NULL == p->chapters) |
* Here we print our standard mdoc(7) prologue. |
teximdocopen(p, pos); |
* We use the title set with @settitle for the `Nd' description |
dosection(p, cmd, pos); |
* and the source document filename (the first one as invoked on |
} |
* the command line) for the title. |
|
* The date is set to the current date. |
|
*/ |
|
t = time(NULL); |
|
strftime(date, sizeof(date), "%F", localtime(&t)); |
|
|
|
teximacroopen(p, "Dd"); |
static void |
texiputchars(p, date); |
dosp(struct texi *p, enum texicmd cmd, size_t *pos) |
teximacroclose(p); |
{ |
teximacroopen(p, "Dt"); |
|
for (cp = p->title; '\0' != *cp; cp++) |
advanceeoln(p, pos, 1); |
texiputchar(p, toupper(*cp)); |
if (p->literal) |
texiputchars(p, " 7"); |
texiputchar(p, '\n'); |
teximacroclose(p); |
|
teximacro(p, "Os"); |
|
teximacro(p, "Sh NAME"); |
|
teximacroopen(p, "Nm"); |
|
for (cp = p->title; '\0' != *cp; cp++) |
|
texiputchar(p, *cp); |
|
teximacroclose(p); |
|
teximacroopen(p, "Nd"); |
|
if (NULL != p->subtitle) |
|
for (cp = p->subtitle; '\0' != *cp; cp++) |
|
texiputchar(p, *cp); |
|
else |
else |
texiputchars(p, "Unknown description"); |
texivspace(p); |
teximacroclose(p); |
|
p->seenvs = 1; |
|
dosection(p, cmd, pos); |
|
} |
} |
|
|
static void |
static void |
Line 1654 doitem(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 1723 doitem(struct texi *p, enum texicmd cmd, size_t *pos) |
|
} |
} |
|
|
/* Trick so we don't start with Pp. */ |
/* Trick so we don't start with Pp. */ |
p->seenvs = 1; |
|
parseeoln(p, pos); |
parseeoln(p, pos); |
|
|
if (TEXILIST_ITEM == p->list) |
if (TEXILIST_ITEM == p->list) |
Line 1695 domultitable(struct texi *p, enum texicmd cmd, size_t |
|
Line 1763 domultitable(struct texi *p, enum texicmd cmd, size_t |
|
|
|
/* Make sure we don't print anything when scanning. */ |
/* Make sure we don't print anything when scanning. */ |
p->ign++; |
p->ign++; |
if ('@' == BUF(p)[*pos]) { |
if (*pos < BUFSZ(p) && '@' == BUF(p)[*pos]) { |
/* |
/* |
* Look for @columnfractions. |
* Look for @columnfractions. |
* We ignore these, but we do use the number of |
* We ignore these, but we do use the number of |
Line 1747 dotable(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 1815 dotable(struct texi *p, enum texicmd cmd, size_t *pos) |
|
{ |
{ |
enum texilist sv = p->list; |
enum texilist sv = p->list; |
|
|
|
advanceeoln(p, pos, 1); |
|
|
p->list = TEXILIST_ITEM; |
p->list = TEXILIST_ITEM; |
teximacro(p, "Bl -tag -width Ds"); |
teximacro(p, "Bl -tag -width Ds"); |
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
|
p->seenvs = 1; |
|
parseto(p, pos, texitoks[cmd].tok); |
parseto(p, pos, texitoks[cmd].tok); |
teximacro(p, "El"); |
teximacro(p, "El"); |
|
p->seenvs = 1; |
p->list = sv; |
p->list = sv; |
} |
} |
|
|
Line 1768 doend(struct texi *p, enum texicmd cmd, size_t *pos) |
|
Line 1836 doend(struct texi *p, enum texicmd cmd, size_t *pos) |
|
while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos]) |
while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos]) |
advance(p, pos); |
advance(p, pos); |
|
|
texiwarn(p, "unexpected \"end\": %.*s", (int)(*pos - start), &BUF(p)[start]); |
texiwarn(p, "unexpected \"end\": %.*s", |
|
(int)(*pos - start), &BUF(p)[start]); |
advanceeoln(p, pos, 1); |
advanceeoln(p, pos, 1); |
} |
} |
|
|
Line 1777 doenumerate(struct texi *p, enum texicmd cmd, size_t * |
|
Line 1846 doenumerate(struct texi *p, enum texicmd cmd, size_t * |
|
{ |
{ |
enum texilist sv = p->list; |
enum texilist sv = p->list; |
|
|
|
advanceeoln(p, pos, 1); |
|
|
p->list = TEXILIST_NOITEM; |
p->list = TEXILIST_NOITEM; |
teximacro(p, "Bl -enum"); |
teximacro(p, "Bl -enum"); |
p->seenvs = 1; |
parseto(p, pos, texitoks[cmd].tok); |
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
|
parseto(p, pos, "enumerate"); |
|
teximacro(p, "El"); |
teximacro(p, "El"); |
|
p->seenvs = 1; |
p->list = sv; |
p->list = sv; |
} |
} |
|
|
Line 1792 doitemize(struct texi *p, enum texicmd cmd, size_t *po |
|
Line 1861 doitemize(struct texi *p, enum texicmd cmd, size_t *po |
|
{ |
{ |
enum texilist sv = p->list; |
enum texilist sv = p->list; |
|
|
|
advanceeoln(p, pos, 1); |
|
|
p->list = TEXILIST_NOITEM; |
p->list = TEXILIST_NOITEM; |
teximacro(p, "Bl -bullet"); |
teximacro(p, "Bl -bullet"); |
p->seenvs = 1; |
parseto(p, pos, texitoks[cmd].tok); |
/* FIXME: ignore and parseeoln. */ |
|
advanceeoln(p, pos, 1); |
|
parseto(p, pos, "itemize"); |
|
teximacro(p, "El"); |
teximacro(p, "El"); |
|
p->seenvs = 1; |
p->list = sv; |
p->list = sv; |
} |
} |
|
|
Line 1807 doignbracket(struct texi *p, enum texicmd cmd, size_t |
|
Line 1876 doignbracket(struct texi *p, enum texicmd cmd, size_t |
|
{ |
{ |
|
|
p->ign++; |
p->ign++; |
parsebracket(p, pos); |
parsebracket(p, pos, 0); |
p->ign--; |
p->ign--; |
} |
} |
|
|
|
|
doignline(struct texi *p, enum texicmd cmd, size_t *pos) |
doignline(struct texi *p, enum texicmd cmd, size_t *pos) |
{ |
{ |
|
|
/* FIXME: ignore and parseeoln. */ |
advanceeoln(p, pos, 1); |
advanceeoln(p, pos, 1); |
|
} |
} |
|
|
/* |
/* |
Line 1874 main(int argc, char *argv[]) |
|
Line 1942 main(int argc, char *argv[]) |
|
|
|
memset(&texi, 0, sizeof(struct texi)); |
memset(&texi, 0, sizeof(struct texi)); |
texi.ign = 1; |
texi.ign = 1; |
|
texi.outfile = stdout; |
Idir = NULL; |
Idir = NULL; |
|
|
while (-1 != (c = getopt(argc, argv, "I:"))) |
while (-1 != (c = getopt(argc, argv, "C:I:"))) |
switch (c) { |
switch (c) { |
|
case ('C'): |
|
texi.chapters = optarg; |
|
break; |
case ('I'): |
case ('I'): |
Idir = optarg; |
Idir = optarg; |
break; |
break; |
Line 1911 main(int argc, char *argv[]) |
|
Line 1983 main(int argc, char *argv[]) |
|
} |
} |
|
|
texiexit(&texi); |
texiexit(&texi); |
return(EXIT_FAILURE); |
exit(EXIT_SUCCESS); |
usage: |
usage: |
fprintf(stderr, "usage: %s [-Idirs] [file]\n", progname); |
fprintf(stderr, "usage: %s [-Cdir] [-Idirs] [file]\n", progname); |
return(EXIT_FAILURE); |
return(EXIT_FAILURE); |
} |
} |