=================================================================== RCS file: /cvs/texi2mdoc/main.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -p -r1.22 -r1.23 --- texi2mdoc/main.c 2015/02/19 16:44:26 1.22 +++ texi2mdoc/main.c 2015/02/19 20:55:56 1.23 @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.22 2015/02/19 16:44:26 kristaps Exp $ */ +/* $Id: main.c,v 1.23 2015/02/19 20:55:56 kristaps Exp $ */ /* * Copyright (c) 2015 Kristaps Dzonsons * @@ -43,6 +43,7 @@ enum texicmd { TEXICMD_APPENDIX, TEXICMD_APPENDIXSEC, TEXICMD_APPENDIXSUBSEC, + TEXICMD_APPENDIXSUBSUBSEC, TEXICMD_ASTERISK, TEXICMD_AT, TEXICMD_AUTHOR, @@ -136,6 +137,7 @@ enum texicmd { TEXICMD_KEY, TEXICMD_KINDEX, TEXICMD_LATEX, + TEXICMD_LOWERSECTIONS, TEXICMD_MATH, TEXICMD_MENU, TEXICMD_MULTITABLE, @@ -151,6 +153,7 @@ enum texicmd { TEXICMD_PARINDENT, TEXICMD_PRINTINDEX, TEXICMD_R, + TEXICMD_RAISESECTIONS, TEXICMD_REF, TEXICMD_RESULT, TEXICMD_SAMP, @@ -174,6 +177,7 @@ enum texicmd { TEXICMD_STRONG, TEXICMD_SUBHEADING, TEXICMD_SUBSECTION, + TEXICMD_SUBSUBSECTION, TEXICMD_SUBTITLE, TEXICMD_SYNCODEINDEX, TEXICMD_T, @@ -191,6 +195,7 @@ enum texicmd { TEXICMD_UNNUMBERED, TEXICMD_UNNUMBEREDSEC, TEXICMD_UNNUMBEREDSUBSEC, + TEXICMD_UNNUMBEREDSUBSUBSEC, TEXICMD_UREF, TEXICMD_URL, TEXICMD_VAR, @@ -203,6 +208,14 @@ enum texicmd { TEXICMD__MAX }; +#define SECTSZ 4 +static const char *const sects[SECTSZ] = { + "Sh", + "Ss", + "Em", + "No", +}; + /* * The file currently being parsed. * This keeps track of our location within that file. @@ -251,6 +264,7 @@ struct texi { size_t dirsz; /* number of texi directories */ char *title; /* title of document */ char *subtitle; /* subtitle of document */ + int secoffs; /* see sectioner() */ /* * The following control what we output to the screen. * The complexity is required to accomodate for mdoc(7). @@ -291,9 +305,11 @@ static void domultitable(struct texi *, enum texicmd, static void doquotation(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dotable(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dotop(struct texi *, enum texicmd, const char *, size_t, size_t *); +static void dosecoffs(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dosection(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dosp(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dosubsection(struct texi *, enum texicmd, const char *, size_t, size_t *); +static void dosubsubsection(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dosymbol(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dotab(struct texi *, enum texicmd, const char *, size_t, size_t *); static void dotitle(struct texi *, enum texicmd, const char *, size_t, size_t *); @@ -308,6 +324,7 @@ static const struct texitok texitoks[TEXICMD__MAX] = { { dosection, "appendix", 8 }, /* TEXICMD_APPENDIX */ { dosection, "appendixsec", 11 }, /* TEXICMD_APPENDIXSEC */ { dosubsection, "appendixsubsec", 14 }, /* TEXICMD_APPENDIXSUBSEC */ + { dosubsubsection, "appendixsubsubsec", 17 }, /* TEXICMD_APPENDIXSUBSUBSEC */ { dosymbol, "*", 1 }, /* TEXICMD_ASTERISK */ { dosymbol, "@", 1 }, /* TEXICMD_AT */ { doignline, "author", 6 }, /* TEXICMD_AUTHOR */ @@ -401,6 +418,7 @@ static const struct texitok texitoks[TEXICMD__MAX] = { { dobracket, "key", 3 }, /* TEXICMD_KEY */ { doignline, "kindex", 6 }, /* TEXICMD_KINDEX */ { dosymbol, "LaTeX", 5 }, /* TEXICMD_LATEX */ + { dosecoffs, "lowersections", 13 }, /* TEXICMD_LOWERSECTIONS */ { domath, "math", 4 }, /* TEXICMD_MATH */ { doignblock, "menu", 4 }, /* TEXICMD_MENU */ { domultitable, "multitable", 10 }, /* TEXICMD_MULTITABLE */ @@ -416,6 +434,7 @@ static const struct texitok texitoks[TEXICMD__MAX] = { { doignline, "paragraphindent", 14 }, /* TEXICMD_PARINDENT */ { doignline, "printindex", 10 }, /* TEXICMD_PRINTINDEX */ { doinline, "r", 1 }, /* TEXICMD_R */ + { dosecoffs, "raisesections", 13 }, /* TEXICMD_RAISESECTIONS */ { dobracket, "ref", 3 }, /* TEXICMD_REF */ { dosymbol, "result", 6 }, /* TEXICMD_RESULT */ { doinline, "samp", 4 }, /* TEXICMD_SAMP */ @@ -439,6 +458,7 @@ static const struct texitok texitoks[TEXICMD__MAX] = { { doinline, "strong", 6 }, /* TEXICMD_STRONG */ { dosubsection, "subheading", 10 }, /* TEXICMD_SUBHEADING */ { dosubsection, "subsection", 10 }, /* TEXICMD_SUBSECTION */ + { dosubsubsection, "subsubsection", 13 }, /* TEXICMD_SUBSUBSECTION */ { doignline, "subtitle", 8 }, /* TEXICMD_SUBTITLE */ { doignline, "syncodeindex", 12 }, /* TEXICMD_SYNCODEINDEX */ { doinline, "t", 1 }, /* TEXICMD_T */ @@ -456,6 +476,7 @@ static const struct texitok texitoks[TEXICMD__MAX] = { { dosection, "unnumbered", 10 }, /* TEXICMD_UNNUMBERED */ { dosection, "unnumberedsec", 13 }, /* TEXICMD_UNNUMBEREDSEC */ { dosubsection, "unnumberedsubsec", 16 }, /* TEXICMD_UNNUMBEREDSUBSEC */ + { dosubsubsection, "unnumberedsubsubsec", 19 }, /* TEXICMD_UNNUMBEREDSUBSUBSEC */ { dolink, "uref", 4 }, /* TEXICMD_UREF */ { dolink, "url", 3 }, /* TEXICMD_URL */ { doinline, "var", 3 }, /* TEXICMD_VAR */ @@ -1801,53 +1822,103 @@ doignargn(struct texi *p, enum texicmd cmd, p->ign--; } +/* + * Sections can be made subsections and so on by way of the + * @raiseections and @lowersections commands. + * Perform this check here and return the actual section number adjusted + * to the raise level. + */ +static int +sectioner(struct texi *p, int sec) +{ + + if ((sec -= p->secoffs) < 0) { + texiwarn(p, "section below minimum, clamping"); + return(0); + } else if (sec >= SECTSZ) { + texiwarn(p, "section above maximum, clamping"); + return(SECTSZ - 1); + } + return(sec); +} + static void +dosubsubsection(struct texi *p, enum texicmd cmd, + const char *buf, size_t sz, size_t *pos) +{ + int sec; + + sec = sectioner(p, 3); + + /* We don't have a subsubsubsection, so make one up. */ + texivspace(p); + teximacroopen(p, sects[sec]); + parseeoln(p, buf, sz, pos); + teximacroclose(p); + texivspace(p); +} + +static void dosubsection(struct texi *p, enum texicmd cmd, const char *buf, size_t sz, size_t *pos) { + int sec; + sec = sectioner(p, 2); + if (p->outmacro) - texierr(p, "\"Em\" in open line scope!?"); + texierr(p, "\"%s\" in open line scope!?", sects[sec]); else if (p->literal) - texierr(p, "\"Em\" in a literal scope!?"); + texierr(p, "\"%s\" in a literal scope!?", sects[sec]); /* We don't have a subsubsection, so make one up. */ texivspace(p); - teximacroopen(p, "Em"); + teximacroopen(p, sects[sec]); parseeoln(p, buf, sz, pos); teximacroclose(p); texivspace(p); } static void +dosecoffs(struct texi *p, enum texicmd cmd, + const char *buf, size_t sz, size_t *pos) +{ + + if (TEXICMD_RAISESECTIONS == cmd) + p->secoffs++; + else + p->secoffs--; +} + +static void dosection(struct texi *p, enum texicmd cmd, - const char *buf, size_t sz, size_t *pos) + const char *buf, size_t sz, size_t *pos) { - const char *blk; + int sec; switch (cmd) { case (TEXICMD_APPENDIX): case (TEXICMD_CHAPTER): case (TEXICMD_TOP): case (TEXICMD_UNNUMBERED): - blk = "Sh"; + sec = sectioner(p, 0); break; case (TEXICMD_APPENDIXSEC): case (TEXICMD_HEADING): case (TEXICMD_SECTION): case (TEXICMD_UNNUMBEREDSEC): - blk = "Ss"; + sec = sectioner(p, 1); break; default: abort(); } if (p->outmacro) - texierr(p, "%s in open line scope!?", blk); + texierr(p, "\"%s\" in open line scope!?", sects[sec]); else if (p->literal) - texierr(p, "%s in a literal scope!?", blk); + texierr(p, "\"%s\" in a literal scope!?", sects[sec]); - teximacroopen(p, blk); + teximacroopen(p, sects[sec]); parseeoln(p, buf, sz, pos); teximacroclose(p); p->seenvs = 1;