Arrange a mechanism whereby each backend can be passed a filename
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 1 Apr 2004 17:22:56 +0000 (17:22 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 1 Apr 2004 17:22:56 +0000 (17:22 +0000)
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
bk_text.c
bk_whlp.c
bk_xhtml.c
halibut.h
main.c
ustring.c

index 276855e..a773b60 100644 (file)
--- 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 = "<command line>";
+    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 */
 
index a0ebf82..fdb1055 100644 (file)
--- 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 = "<command line>";
+    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;
index 6eee4d4..9575673 100644 (file)
--- 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 = "<command line>";
+    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;
index 7614778..56e783d 100644 (file)
@@ -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 = "<command line>";
+       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);
index c4f4721..6ecf3b3 100644 (file)
--- 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 (file)
--- 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)) {
index a64d155..c4af519 100644 (file)
--- 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++;