Obsoleted the `\preamble' command. Preamble text is now taken to be
[sgt/halibut] / bk_whlp.c
index a8cb99e..1d5dbc6 100644 (file)
--- a/bk_whlp.c
+++ b/bk_whlp.c
@@ -28,6 +28,8 @@ enum {
     FONT_NORMAL,
     FONT_EMPH,
     FONT_CODE,
+    FONT_ITAL_CODE,
+    FONT_BOLD_CODE,
     FONT_TITLE,
     FONT_TITLE_EMPH,
     FONT_TITLE_CODE,
@@ -35,7 +37,8 @@ enum {
 };
 
 static void whlp_rdaddwc(rdstringc *rs, word *text);
-static int whlp_convert(wchar_t *s, char **result, int hard_spaces);
+static int whlp_convert(wchar_t *s, int maxlen,
+                       char **result, int hard_spaces);
 static void whlp_mkparagraph(struct bk_whlp_state *state,
                             int font, word *text, int subsidiary);
 static void whlp_navmenu(struct bk_whlp_state *state, paragraph *p);
@@ -50,7 +53,9 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
     struct bk_whlp_state state;
     WHLP_TOPIC contents_topic;
     int i;
+    int nesting;
     indexentry *ie;
+    int done_contents_topic;
 
     filename = "output.hlp";          /* FIXME: configurability */
     cntname = "output.cnt";           /* corresponding contents file */
@@ -72,6 +77,10 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
                     WHLP_FONT_ITALIC, 0, 0, 0);
     whlp_create_font(h, "Courier New", WHLP_FONTFAM_FIXED, 24,
                     0, 0, 0, 0);
+    whlp_create_font(h, "Courier New", WHLP_FONTFAM_FIXED, 24,
+                    WHLP_FONT_ITALIC, 0, 0, 0);
+    whlp_create_font(h, "Courier New", WHLP_FONTFAM_FIXED, 24,
+                    WHLP_FONT_BOLD, 0, 0, 0);
     whlp_create_font(h, "Arial", WHLP_FONTFAM_SERIF, 30,
                     WHLP_FONT_BOLD, 0, 0, 0);
     whlp_create_font(h, "Arial", WHLP_FONTFAM_SERIF, 30,
@@ -90,7 +99,7 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
        if (p->type == para_Config && p->parent) {
            if (!ustricmp(p->keyword, L"winhelp-topic")) {
                char *topicname;
-               whlp_convert(uadv(p->keyword), &topicname, 0);
+               whlp_convert(uadv(p->keyword), 0, &topicname, 0);
                /* Store the topic name in the private_data field of the
                 * containing section. */
                p->parent->private_data = topicname;
@@ -136,8 +145,7 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
     whlp_prepare(h);
 
     /* ------------------------------------------------------------------
-     * Do the contents page, containing title, preamble and
-     * copyright.
+     * Begin the contents page.
      */
 
     whlp_begin_topic(h, contents_topic, "Contents", "DB(\"btn_up\")", NULL);
@@ -165,57 +173,13 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
        /* FIXME: configurability in that string */
     }
 
-    /*
-     * Next comes the preamble, which just goes into the ordinary
-     * scrolling region.
-     */
-    for (p = sourceform; p; p = p->next) {
-       if (p->type == para_Preamble) {
-           whlp_para_attr(h, WHLP_PARA_SPACEBELOW, 12);
-           whlp_begin_para(h, WHLP_PARA_SCROLL);
-           whlp_mkparagraph(&state, FONT_NORMAL, p->words, FALSE);
-           whlp_end_para(h);
-       }
-    }
-
-    /*
-     * The copyright goes to two places, again: into the contents
-     * page and also into the system section.
-     */
-    {
-       rdstringc rs = {0, 0, NULL};
-       for (p = sourceform; p; p = p->next) {
-           if (p->type == para_Copyright) {
-               whlp_para_attr(h, WHLP_PARA_SPACEBELOW, 12);
-               whlp_begin_para(h, WHLP_PARA_SCROLL);
-               whlp_mkparagraph(&state, FONT_NORMAL, p->words, FALSE);
-               whlp_end_para(h);
-               whlp_rdaddwc(&rs, p->words);
-           }
-       }
-       if (rs.text) {
-           whlp_copyright(h, rs.text);
-           sfree(rs.text);
-       }
-    }
-
-    /*
-     * Now do the primary navigation menu.
-     */
-    for (p = sourceform; p; p = p->next) {
-       if (p->type == para_Chapter ||
-           p->type == para_Appendix ||
-           p->type == para_UnnumberedChapter)
-           whlp_navmenu(&state, p);
-    }
-
-    state.curr_topic = contents_topic;
     lastsect = NULL;
 
     /* ------------------------------------------------------------------
      * Now we've done the contents page, we're ready to go through
      * and do the main manual text. Ooh.
      */
+    nesting = 0;
     for (p = sourceform; p; p = p->next) switch (p->type) {
        /*
         * Things we ignore because we've already processed them or
@@ -226,11 +190,20 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
       case para_Biblio:                       /* only touch BiblioCited */
       case para_VersionID:
       case para_Copyright:
-      case para_Preamble:
       case para_NoCite:
       case para_Title:
        break;
 
+      case para_LcontPush:
+      case para_QuotePush:
+       nesting++;
+       break;
+      case para_LcontPop:
+      case para_QuotePop:
+       assert(nesting > 0);
+       nesting--;
+       break;
+
        /*
         * Chapter and section titles: start a new Help topic.
         */
@@ -239,6 +212,53 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
       case para_UnnumberedChapter:
       case para_Heading:
       case para_Subsect:
+
+       if (!done_contents_topic) {
+           paragraph *p;
+
+           /*
+            * If this is the first section title we've seen, then
+            * we're currently still in the contents topic. We
+            * should therefore finish up the contents page by
+            * writing the copyright notice and a nav menu.
+            */
+
+           /*
+            * The copyright goes to two places, again: into the
+            * contents page and also into the system section.
+            */
+           {
+               rdstringc rs = {0, 0, NULL};
+               for (p = sourceform; p; p = p->next) {
+                   if (p->type == para_Copyright) {
+                       whlp_para_attr(h, WHLP_PARA_SPACEBELOW, 12);
+                       whlp_begin_para(h, WHLP_PARA_SCROLL);
+                       whlp_mkparagraph(&state, FONT_NORMAL, p->words, FALSE);
+                       whlp_end_para(h);
+                       whlp_rdaddwc(&rs, p->words);
+                   }
+               }
+               if (rs.text) {
+                   whlp_copyright(h, rs.text);
+                   sfree(rs.text);
+               }
+           }
+
+           /*
+            * Now do the primary navigation menu.
+            */
+           for (p = sourceform; p; p = p->next) {
+               if (p->type == para_Chapter ||
+                   p->type == para_Appendix ||
+                   p->type == para_UnnumberedChapter)
+                   whlp_navmenu(&state, p);
+           }
+
+           state.curr_topic = contents_topic;
+
+           done_contents_topic = TRUE;
+       }
+
        if (lastsect && lastsect->child) {
            paragraph *q;
            /*
@@ -343,12 +363,14 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
        break;
 
       case para_Normal:
+      case para_DescribedThing:
+      case para_Description:
       case para_BiblioCited:
       case para_Bullet:
       case para_NumberedList:
        whlp_para_attr(h, WHLP_PARA_SPACEBELOW, 12);
        if (p->type == para_Bullet || p->type == para_NumberedList) {
-           whlp_para_attr(h, WHLP_PARA_LEFTINDENT, 72);
+           whlp_para_attr(h, WHLP_PARA_LEFTINDENT, 72*nesting + 72);
            whlp_para_attr(h, WHLP_PARA_FIRSTLINEINDENT, -36);
            whlp_set_tabstop(h, 72, WHLP_ALIGN_LEFT);
            whlp_begin_para(h, WHLP_PARA_SCROLL);
@@ -361,6 +383,8 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
            }
            whlp_tab(h);
        } else {
+           whlp_para_attr(h, WHLP_PARA_LEFTINDENT,
+                          72*nesting + (p->type==para_Description ? 72 : 0));
            whlp_begin_para(h, WHLP_PARA_SCROLL);
        }
 
@@ -382,13 +406,41 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
         */
        {
            word *w;
+           wchar_t *t, *e;
            char *c;
-           for (w = p->words; w; w = w->next) {
+
+           for (w = p->words; w; w = w->next) if (w->type == word_WeakCode) {
+               t = w->text;
+               if (w->next && w->next->type == word_Emph) {
+                   w = w->next;
+                   e = w->text;
+               } else
+                   e = NULL;
+
                if (!w->next)
                    whlp_para_attr(h, WHLP_PARA_SPACEBELOW, 12);
+
+               whlp_para_attr(h, WHLP_PARA_LEFTINDENT, 72*nesting);
                whlp_begin_para(h, WHLP_PARA_SCROLL);
+               while (e && *e && *t) {
+                   int n;
+                   int ec = *e;
+
+                   for (n = 0; t[n] && e[n] && e[n] == ec; n++);
+                   if (ec == 'i')
+                       whlp_set_font(h, FONT_ITAL_CODE);
+                   else if (ec == 'b')
+                       whlp_set_font(h, FONT_BOLD_CODE);
+                   else
+                       whlp_set_font(h, FONT_CODE);
+                   whlp_convert(t, n, &c, FALSE);
+                   whlp_text(h, c);
+                   sfree(c);
+                   t += n;
+                   e += n;
+               }
                whlp_set_font(h, FONT_CODE);
-               whlp_convert(w->text, &c, FALSE);
+               whlp_convert(t, 0, &c, FALSE);
                whlp_text(h, c);
                sfree(c);
                whlp_end_para(h);
@@ -479,22 +531,25 @@ static void whlp_mkparagraph(struct bk_whlp_state *state,
       case word_LowerXref:
        if (subsidiary) break;         /* disabled in subsidiary bits */
         kwl = kw_lookup(state->keywords, text->text);
-       assert(xref_target == NULL);
-       if (kwl->para->type == para_NumberedList) {
-           break;                     /* don't xref to numbered list items */
-       } else if (kwl->para->type == para_BiblioCited) {
-           /*
-            * An xref to a bibliography item jumps to the section
-            * containing it.
-            */
-           if (kwl->para->parent)
-               xref_target = kwl->para->parent;
-           else
-               break;
-       } else {
-           xref_target = kwl->para;
-       }
-       whlp_start_hyperlink(state->h, (WHLP_TOPIC)xref_target->private_data);
+        assert(xref_target == NULL);
+        if (kwl) {
+            if (kwl->para->type == para_NumberedList) {
+                break;                /* don't xref to numbered list items */
+            } else if (kwl->para->type == para_BiblioCited) {
+                /*
+                 * An xref to a bibliography item jumps to the section
+                 * containing it.
+                 */
+                if (kwl->para->parent)
+                    xref_target = kwl->para->parent;
+                else
+                    break;
+            } else {
+                xref_target = kwl->para;
+            }
+            whlp_start_hyperlink(state->h,
+                                 (WHLP_TOPIC)xref_target->private_data);
+        }
        break;
 
       case word_XrefEnd:
@@ -528,7 +583,7 @@ static void whlp_mkparagraph(struct bk_whlp_state *state,
            whlp_set_font(state->h, newfont);
        }
        if (removeattr(text->type) == word_Normal) {
-           if (whlp_convert(text->text, &c, TRUE))
+           if (whlp_convert(text->text, 0, &c, TRUE))
                whlp_text(state->h, c);
            else
                whlp_mkparagraph(state, deffont, text->alt, FALSE);
@@ -571,7 +626,7 @@ static void whlp_rdaddwc(rdstringc *rs, word *text) {
        assert(text->type != word_CodeQuote &&
               text->type != word_WkCodeQuote);
        if (removeattr(text->type) == word_Normal) {
-           if (whlp_convert(text->text, &c, FALSE))
+           if (whlp_convert(text->text, 0, &c, FALSE))
                rdaddsc(rs, c);
            else
                whlp_rdaddwc(rs, text->alt);
@@ -597,7 +652,8 @@ static void whlp_rdaddwc(rdstringc *rs, word *text) {
  * characters are OK but `result' is non-NULL, a result _will_
  * still be generated!
  */
-static int whlp_convert(wchar_t *s, char **result, int hard_spaces) {
+static int whlp_convert(wchar_t *s, int maxlen,
+                       char **result, int hard_spaces) {
     /*
      * FIXME. Currently this is ISO8859-1 only.
      */
@@ -606,7 +662,10 @@ static int whlp_convert(wchar_t *s, char **result, int hard_spaces) {
     char *p = NULL;
     int plen = 0, psize = 0;
 
-    for (; *s; s++) {
+    if (maxlen <= 0)
+       maxlen = -1;
+
+    for (; *s && maxlen != 0; s++, maxlen--) {
        wchar_t c = *s;
        char outc;