From ba9c1487d811dccd55655fee8ca9a96856fa69f9 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 1 Apr 2004 17:22:56 +0000 Subject: [PATCH] Arrange a mechanism whereby each backend can be passed a filename from its command-line option (`--text=foo.txt') and automatically convert it into one or more notional \cfg directives. In the HTML case this mechanism enables single-file mode as well as setting the filename. git-svn-id: svn://svn.tartarus.org/sgt/halibut@4018 cda61777-01e9-0310-a592-d414129be87e --- bk_man.c | 28 ++++++++++++++++++++++++++++ bk_text.c | 28 ++++++++++++++++++++++++++++ bk_whlp.c | 28 ++++++++++++++++++++++++++++ bk_xhtml.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- halibut.h | 6 ++++++ main.c | 26 +++++++++++++++++++------- ustring.c | 30 ++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 8 deletions(-) diff --git a/bk_man.c b/bk_man.c index 276855e..a773b60 100644 --- a/bk_man.c +++ b/bk_man.c @@ -62,6 +62,34 @@ static void man_conf_cleanup(manconfig cf) sfree(cf.filename); } +paragraph *man_config_filename(char *filename) +{ + paragraph *p; + wchar_t *ufilename, *up; + int len; + + p = mknew(paragraph); + memset(p, 0, sizeof(*p)); + p->type = para_Config; + p->next = NULL; + p->fpos.filename = ""; + p->fpos.line = p->fpos.col = -1; + + ufilename = ufroma_dup(filename); + len = ustrlen(ufilename) + 2 + lenof(L"man-filename"); + p->keyword = mknewa(wchar_t, len); + up = p->keyword; + ustrcpy(up, L"man-filename"); + up = uadv(up); + ustrcpy(up, ufilename); + up = uadv(up); + *up = L'\0'; + assert(up - p->keyword < len); + sfree(ufilename); + + return p; +} + #define QUOTE_INITCTRL 1 /* quote initial . and ' on a line */ #define QUOTE_QUOTES 2 /* quote double quotes by doubling them */ diff --git a/bk_text.c b/bk_text.c index a0ebf82..fdb1055 100644 --- a/bk_text.c +++ b/bk_text.c @@ -180,6 +180,34 @@ static textconfig text_configure(paragraph *source) { return ret; } +paragraph *text_config_filename(char *filename) +{ + paragraph *p; + wchar_t *ufilename, *up; + int len; + + p = mknew(paragraph); + memset(p, 0, sizeof(*p)); + p->type = para_Config; + p->next = NULL; + p->fpos.filename = ""; + p->fpos.line = p->fpos.col = -1; + + ufilename = ufroma_dup(filename); + len = ustrlen(ufilename) + 2 + lenof(L"text-filename"); + p->keyword = mknewa(wchar_t, len); + up = p->keyword; + ustrcpy(up, L"text-filename"); + up = uadv(up); + ustrcpy(up, ufilename); + up = uadv(up); + *up = L'\0'; + assert(up - p->keyword < len); + sfree(ufilename); + + return p; +} + void text_backend(paragraph *sourceform, keywordlist *keywords, indexdata *idx) { paragraph *p; diff --git a/bk_whlp.c b/bk_whlp.c index 6eee4d4..9575673 100644 --- a/bk_whlp.c +++ b/bk_whlp.c @@ -43,6 +43,34 @@ static void whlp_navmenu(struct bk_whlp_state *state, paragraph *p); static void whlp_contents_write(struct bk_whlp_state *state, int level, char *text, WHLP_TOPIC topic); +paragraph *whlp_config_filename(char *filename) +{ + paragraph *p; + wchar_t *ufilename, *up; + int len; + + p = mknew(paragraph); + memset(p, 0, sizeof(*p)); + p->type = para_Config; + p->next = NULL; + p->fpos.filename = ""; + p->fpos.line = p->fpos.col = -1; + + ufilename = ufroma_dup(filename); + len = ustrlen(ufilename) + 2 + lenof(L"winhelp-filename"); + p->keyword = mknewa(wchar_t, len); + up = p->keyword; + ustrcpy(up, L"winhelp-filename"); + up = uadv(up); + ustrcpy(up, ufilename); + up = uadv(up); + *up = L'\0'; + assert(up - p->keyword < len); + sfree(ufilename); + + return p; +} + void whlp_backend(paragraph *sourceform, keywordlist *keywords, indexdata *idx) { WHLP h; diff --git a/bk_xhtml.c b/bk_xhtml.c index 7614778..56e783d 100644 --- a/bk_xhtml.c +++ b/bk_xhtml.c @@ -39,7 +39,7 @@ * formatting directive, %% is a literal %). Formatting directives * are: * - * - %n is the section number, minus whitespace (`Chapter1.2'). + * - %n is the section type-plus-number, minus whitespace (`Chapter1.2'). * - %b is the section number on its own (`1.2'). * - %k is the section's _internal_ keyword. * - %N is the section's visible title in the output, again minus @@ -285,6 +285,57 @@ static xhtmlconfig xhtml_configure(paragraph *source) return ret; } +paragraph *xhtml_config_filename(char *filename) +{ + /* + * If the user passes in a single filename as a parameter to + * the `--html' command-line option, then we should assume it + * to imply _two_ config directives: + * \cfg{xhtml-single-filename}{whatever} and + * \cfg{xhtml-leaf-level}{0}; the rationale being that the user + * wants their output _in that file_. + */ + + paragraph *p[2]; + int i, len; + wchar_t *ufilename, *up; + + for (i = 0; i < 2; i++) { + p[i] = mknew(paragraph); + memset(p[i], 0, sizeof(*p[i])); + p[i]->type = para_Config; + p[i]->next = NULL; + p[i]->fpos.filename = ""; + p[i]->fpos.line = p[i]->fpos.col = -1; + } + + ufilename = ufroma_dup(filename); + len = ustrlen(ufilename) + 2 + lenof(L"xhtml-single-filename"); + p[0]->keyword = mknewa(wchar_t, len); + up = p[0]->keyword; + ustrcpy(up, L"xhtml-single-filename"); + up = uadv(up); + ustrcpy(up, ufilename); + up = uadv(up); + *up = L'\0'; + assert(up - p[0]->keyword < len); + sfree(ufilename); + + len = lenof(L"xhtml-leaf-level") + lenof(L"0") + 1; + p[1]->keyword = mknewa(wchar_t, len); + up = p[1]->keyword; + ustrcpy(up, L"xhtml-leaf-level"); + up = uadv(up); + ustrcpy(up, L"0"); + up = uadv(up); + *up = L'\0'; + assert(up - p[1]->keyword < len); + + p[0]->next = p[1]; + + return p[0]; +} + static xhtmlsection *xhtml_new_section(xhtmlsection *last) { xhtmlsection *ret = mknew(xhtmlsection); diff --git a/halibut.h b/halibut.h index c4f4721..6ecf3b3 100644 --- a/halibut.h +++ b/halibut.h @@ -248,7 +248,9 @@ char *dupstr(char *s); */ wchar_t *ustrdup(wchar_t *s); char *ustrtoa(wchar_t *s, char *outbuf, int size); +wchar_t *ustrfroma(char *s, wchar_t *outbuf, int size); char *utoa_dup(wchar_t *s); +wchar_t *ufroma_dup(char *s); int ustrlen(wchar_t *s); wchar_t *uadv(wchar_t *s); wchar_t *ustrcpy(wchar_t *dest, wchar_t *source); @@ -413,20 +415,24 @@ struct userstyle_Tag { * bk_text.c */ void text_backend(paragraph *, keywordlist *, indexdata *); +paragraph *text_config_filename(char *filename); /* * bk_xhtml.c */ void xhtml_backend(paragraph *, keywordlist *, indexdata *); +paragraph *xhtml_config_filename(char *filename); /* * bk_whlp.c */ void whlp_backend(paragraph *, keywordlist *, indexdata *); +paragraph *whlp_config_filename(char *filename); /* * bk_man.c */ void man_backend(paragraph *, keywordlist *, indexdata *); +paragraph *man_config_filename(char *filename); #endif diff --git a/main.c b/main.c index 3d72d05..b509928 100644 --- a/main.c +++ b/main.c @@ -14,15 +14,16 @@ static void dbg_prtkws(keywordlist *kws); static const struct backend { char *name; void (*func)(paragraph *, keywordlist *, indexdata *); + paragraph *(*filename)(char *filename); int bitfield; } backends[] = { - {"text", text_backend, 0x0001}, - {"xhtml", xhtml_backend, 0x0002}, - {"html", xhtml_backend, 0x0002}, - {"hlp", whlp_backend, 0x0004}, - {"whlp", whlp_backend, 0x0004}, - {"winhelp", whlp_backend, 0x0004}, - {"man", man_backend, 0x0008}, + {"text", text_backend, text_config_filename, 0x0001}, + {"xhtml", xhtml_backend, xhtml_config_filename, 0x0002}, + {"html", xhtml_backend, xhtml_config_filename, 0x0002}, + {"hlp", whlp_backend, whlp_config_filename, 0x0004}, + {"whlp", whlp_backend, whlp_config_filename, 0x0004}, + {"winhelp", whlp_backend, whlp_config_filename, 0x0004}, + {"man", man_backend, man_config_filename, 0x0008}, }; int main(int argc, char **argv) { @@ -83,6 +84,17 @@ int main(int argc, char **argv) { for (k = 0; k < (int)lenof(backends); k++) if (!strcmp(opt+1, backends[k].name)) { backendbits |= backends[k].bitfield; + if (val) { + paragraph *p = backends[k].filename(val); + assert(p); + if (cfg_tail) + cfg_tail->next = p; + else + cfg = p; + while (p->next) + p = p->next; + cfg_tail = p; + } break; } if (k < (int)lenof(backends)) { diff --git a/ustring.c b/ustring.c index a64d155..c4af519 100644 --- a/ustring.c +++ b/ustring.c @@ -33,6 +33,21 @@ char *ustrtoa(wchar_t *s, char *outbuf, int size) { return outbuf; } +wchar_t *ustrfroma(char *s, wchar_t *outbuf, int size) { + wchar_t *p; + if (!s) { + *outbuf = L'\0'; + return outbuf; + } + for (p = outbuf; *s && p < outbuf+size; p++,s++) + *p = *s; + if (p < outbuf+size) + *p = '\0'; + else + outbuf[size-1] = '\0'; + return outbuf; +} + char *utoa_dup(wchar_t *s) { int len; char *buf = NULL; @@ -48,6 +63,21 @@ char *utoa_dup(wchar_t *s) { return buf; } +wchar_t *ufroma_dup(char *s) { + int len; + wchar_t *buf = NULL; + + len = strlen(s) + 1; + do { + buf = resize(buf, len); + ustrfroma(s, buf, len); + len = (3 * len) / 2 + 1; /* this guarantees a strict increase */ + } while (ustrlen(buf) >= len-1); + + buf = resize(buf, ustrlen(buf)+1); + return buf; +} + int ustrlen(wchar_t *s) { int len = 0; while (*s++) len++; -- 2.11.0