Add a \quote{...} directive, working like <blockquote> in HTML.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 25 Mar 2004 18:32:05 +0000 (18:32 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 25 Mar 2004 18:32:05 +0000 (18:32 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/halibut@3978 cda61777-01e9-0310-a592-d414129be87e

bk_man.c
bk_text.c
bk_whlp.c
bk_xhtml.c
error.c
halibut.h
input.c

index 64e9648..c464e84 100644 (file)
--- a/bk_man.c
+++ b/bk_man.c
@@ -222,9 +222,11 @@ void man_backend(paragraph *sourceform, keywordlist *keywords,
        break;
 
       case para_LcontPush:
+      case para_QuotePush:
        fprintf(fp, ".RS\n");
        break;
       case para_LcontPop:
+      case para_QuotePop:
        fprintf(fp, ".RE\n");
        break;
     }
index 989cdbf..139e1d6 100644 (file)
--- a/bk_text.c
+++ b/bk_text.c
@@ -226,12 +226,20 @@ void text_backend(paragraph *sourceform, keywordlist *keywords,
     /* Do the main document */
     for (p = sourceform; p; p = p->next) switch (p->type) {
 
+      case para_QuotePush:
+       nesting += 2;
+       break;
+      case para_QuotePop:
+       nesting -= 2;
+       assert(nesting >= 0);
+       break;
+
       case para_LcontPush:
-       nesting++;
+       nesting += nestindent;
        break;
       case para_LcontPop:
-       assert(nesting > 0);
-       nesting--;
+       nesting -= nestindent;
+       assert(nesting >= 0);
        break;
 
        /*
@@ -266,8 +274,7 @@ void text_backend(paragraph *sourceform, keywordlist *keywords,
        break;
 
       case para_Rule:
-       text_rule(fp, conf.indent + nestindent*nesting,
-                 conf.width - nestindent*nesting);
+       text_rule(fp, conf.indent + nesting, conf.width - nesting);
        break;
 
       case para_Normal:
@@ -309,8 +316,8 @@ void text_backend(paragraph *sourceform, keywordlist *keywords,
            body = p->words;
        }
        text_para(fp, prefix, prefixextra, body,
-                 conf.indent + nestindent*nesting + indentb, indenta,
-                 conf.width - nestindent*nesting - indentb - indenta);
+                 conf.indent + nesting + indentb, indenta,
+                 conf.width - nesting - indentb - indenta);
        if (wp) {
            wp->next = NULL;
            free_word_list(body);
@@ -319,8 +326,8 @@ void text_backend(paragraph *sourceform, keywordlist *keywords,
 
       case para_Code:
        text_codepara(fp, p->words,
-                     conf.indent + nestindent*nesting + conf.indent_code,
-                     conf.width - nestindent*nesting - 2 * conf.indent_code);
+                     conf.indent + nesting + conf.indent_code,
+                     conf.width - nesting - 2 * conf.indent_code);
        break;
     }
 
index 85b51eb..91b07c1 100644 (file)
--- a/bk_whlp.c
+++ b/bk_whlp.c
@@ -241,9 +241,11 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
        break;
 
       case para_LcontPush:
+      case para_QuotePush:
        nesting++;
        break;
       case para_LcontPop:
+      case para_QuotePop:
        assert(nesting > 0);
        nesting--;
        break;
index 3024664..449eb4e 100644 (file)
@@ -1142,6 +1142,12 @@ static void xhtml_do_paras(FILE *fp, paragraph *p)
            goto closeofflist;         /* ick */
        }
        break;
+      case para_QuotePush:
+       fprintf(fp, "<blockquote>\n");
+       break;
+      case para_QuotePop:
+       fprintf(fp, "</blockquote>\n");
+       break;
 
       case para_Bullet:
       case para_NumberedList:
diff --git a/error.c b/error.c
index e9c681a..bf16504 100644 (file)
--- a/error.c
+++ b/error.c
@@ -194,9 +194,11 @@ static void do_error(int code, va_list ap) {
        sprintf(error, "\\lcont is only expected after a list item");
        flags = FILEPOS;
        break;
-      case err_sectmarkerinlcont:
+      case err_sectmarkerinblock:
        fpos = *va_arg(ap, filepos *);
-       sprintf(error, "section headings are not supported within \\lcont");
+       sp = va_arg(ap, char *);
+       sprintf(error, "section headings are not supported within \\%.100s",
+               sp);
        flags = FILEPOS;
        break; 
       case err_whatever:
index 1312cd4..c771459 100644 (file)
--- a/halibut.h
+++ b/halibut.h
@@ -112,6 +112,8 @@ enum {
     para_Config,                      /* configuration directive */
     para_LcontPush,                   /* begin continuation of list item */
     para_LcontPop,                    /* end continuation of list item */
+    para_QuotePush,                   /* begin block quote */
+    para_QuotePop,                    /* end block quote */
     para_NotParaType                  /* placeholder value */
 };
 
@@ -213,7 +215,7 @@ enum {
     err_winhelp_ctxclash,             /* WinHelp context ID hash clash */
     err_multikw,                      /* keyword clash in sections */
     err_misplacedlcont,                       /* \lcont not after a list item */
-    err_sectmarkerinlcont,            /* section marker appeared in \lcont */
+    err_sectmarkerinblock,            /* section marker appeared in block */
     err_whatever                       /* random error of another type */
 };
 
diff --git a/input.c b/input.c
index 0535495..db862dd 100644 (file)
--- a/input.c
+++ b/input.c
@@ -192,6 +192,7 @@ enum {
     c_nocite,                         /* bibliography trickery */
     c_preamble,                               /* document preamble text */
     c_q,                              /* quote marks */
+    c_quote,                          /* block-quoted paragraphs */
     c_rule,                           /* horizontal rule */
     c_title,                          /* document title */
     c_u,                              /* aux field is char code */
@@ -260,6 +261,7 @@ static void match_kw(token *tok) {
        {"nocite", c_nocite},          /* bibliography trickery */
        {"preamble", c_preamble},      /* document preamble text */
        {"q", c_q},                    /* quote marks */
+       {"quote", c_quote},            /* block-quoted paragraphs */
        {"rule", c_rule},              /* horizontal rule */
        {"title", c_title},            /* document title */
        {"versionid", c_versionid},    /* document RCS id */
@@ -527,8 +529,8 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) {
     } *sitem;
     stack parsestk;
     struct crossparaitem {
-       int type;                      /* currently c_lcont or -1 */
-       int seen_lcont;
+       int type;                      /* currently c_lcont, c_quote or -1 */
+       int seen_lcont, seen_quote;
     };
     stack crossparastk;
     word *indexword, *uword, *iword;
@@ -616,8 +618,9 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) {
         * finish them.
         */
        if (t.type == tok_cmd &&
-           t.cmd == c_lcont) {
+           (t.cmd == c_lcont || t.cmd == c_quote)) {
            struct crossparaitem *sitem, *stop;
+           int cmd = t.cmd;
 
            /*
             * Expect, and swallow, an open brace.
@@ -628,31 +631,54 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) {
                continue;
            }
 
-           /*
-            * \lcont causes a continuation of a list item into
-            * multiple paragraphs (which may in turn contain
-            * nested lists, code paras etc). Hence, the previous
-            * paragraph must be of a list type.
-            */
-           sitem = mknew(struct crossparaitem);
-           stop = (struct crossparaitem *)stk_top(crossparastk);
-           if (prev_para_type == para_Bullet ||
-               prev_para_type == para_NumberedList ||
-               prev_para_type == para_Description) {
-               sitem->type = c_lcont;
-               sitem->seen_lcont = 1;
-               par.type = para_LcontPush;
-               prev_para_type = par.type;
-               addpara(par, ret);
+           if (cmd == c_lcont) {
+               /*
+                * \lcont causes a continuation of a list item into
+                * multiple paragraphs (which may in turn contain
+                * nested lists, code paras etc). Hence, the previous
+                * paragraph must be of a list type.
+                */
+               sitem = mknew(struct crossparaitem);
+               stop = (struct crossparaitem *)stk_top(crossparastk);
+               if (stop)
+                   *sitem = *stop;
+               else
+                   sitem->seen_quote = sitem->seen_lcont = 0;
+
+               if (prev_para_type == para_Bullet ||
+                   prev_para_type == para_NumberedList ||
+                   prev_para_type == para_Description) {
+                   sitem->type = c_lcont;
+                   sitem->seen_lcont = 1;
+                   par.type = para_LcontPush;
+                   prev_para_type = par.type;
+                   addpara(par, ret);
+               } else {
+                   /*
+                    * Push a null item on the cross-para stack so that
+                    * when we see the corresponding closing brace we
+                    * don't give a cascade error.
+                    */
+                   sitem->type = -1;
+                   error(err_misplacedlcont, &t.pos);
+               }
            } else {
                /*
-                * Push a null item on the cross-para stack so that
-                * when we see the corresponding closing brace we
-                * don't give a cascade error.
+                * \quote causes a group of paragraphs to be
+                * block-quoted (typically they will be indented a
+                * bit).
                 */
-               sitem->type = -1;
-               sitem->seen_lcont = (stop ? stop->seen_lcont : 0);
-               error(err_misplacedlcont, &t.pos);
+               sitem = mknew(struct crossparaitem);
+               stop = (struct crossparaitem *)stk_top(crossparastk);
+               if (stop)
+                   *sitem = *stop;
+               else
+                   sitem->seen_quote = sitem->seen_lcont = 0;
+               sitem->type = c_quote;
+               sitem->seen_quote = 1;
+               par.type = para_QuotePush;
+               prev_para_type = par.type;
+               addpara(par, ret);
            }
            stk_push(crossparastk, sitem);
            continue;
@@ -667,6 +693,11 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) {
                    prev_para_type = par.type;
                    addpara(par, ret);
                    break;
+                 case c_quote:
+                   par.type = para_QuotePop;
+                   prev_para_type = par.type;
+                   addpara(par, ret);
+                   break;
                }
                sfree(sitem);
            }
@@ -747,8 +778,10 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) {
                par.type == para_Appendix ||
                par.type == para_UnnumberedChapter) {
                struct crossparaitem *sitem = stk_top(crossparastk);
-               if (sitem && sitem->seen_lcont) {
-                   error(err_sectmarkerinlcont, &t.pos);
+               if (sitem && (sitem->seen_lcont || sitem->seen_quote)) {
+                   error(err_sectmarkerinblock,
+                         &t.pos,
+                         (sitem->seen_lcont ? "lcont" : "quote"));
                }
            }