diff options
| -rw-r--r-- | bk_text.c | 77 | ||||
| -rw-r--r-- | buttress.h | 32 | ||||
| -rw-r--r-- | input.c | 39 | ||||
| -rw-r--r-- | inputs/test.but | 10 | ||||
| -rw-r--r-- | misc.c | 6 |
5 files changed, 115 insertions, 49 deletions
@@ -4,6 +4,7 @@ #include <stdio.h> #include <stdlib.h> +#include <assert.h> #include "buttress.h" typedef enum { LEFT, CENTRE } alignment; @@ -267,41 +268,43 @@ static void text_rdaddwc(rdstringc *rs, word *text, word *end) { case word_Emph: case word_Code: case word_WeakCode: - if (text->type == word_Emph && - (text->aux == attr_First || text->aux == attr_Only)) - rdaddc(rs, '_'); /* FIXME: configurability */ - else if (text->type == word_Code && - (text->aux == attr_First || text->aux == attr_Only)) - rdaddc(rs, '`'); /* FIXME: configurability */ - if (text_convert(text->text, &c)) - rdaddsc(rs, c); - else - text_rdaddwc(rs, text->alt, NULL); - sfree(c); - if (text->type == word_Emph && - (text->aux == attr_Last || text->aux == attr_Only)) - rdaddc(rs, '_'); /* FIXME: configurability */ - else if (text->type == word_Code && - (text->aux == attr_Last || text->aux == attr_Only)) - rdaddc(rs, '\''); /* FIXME: configurability */ - break; - case word_WhiteSpace: case word_EmphSpace: case word_CodeSpace: case word_WkCodeSpace: - if (text->type == word_EmphSpace && - (text->aux == attr_First || text->aux == attr_Only)) + case word_Quote: + case word_EmphQuote: + case word_CodeQuote: + case word_WkCodeQuote: + assert(text->type != word_CodeQuote && + text->type != word_WkCodeQuote); + if (towordstyle(text->type) == word_Emph && + (attraux(text->aux) == attr_First || + attraux(text->aux) == attr_Only)) rdaddc(rs, '_'); /* FIXME: configurability */ - else if (text->type == word_CodeSpace && - (text->aux == attr_First || text->aux == attr_Only)) + else if (towordstyle(text->type) == word_Code && + (attraux(text->aux) == attr_First || + attraux(text->aux) == attr_Only)) rdaddc(rs, '`'); /* FIXME: configurability */ - rdaddc(rs, ' '); - if (text->type == word_EmphSpace && - (text->aux == attr_Last || text->aux == attr_Only)) + if (removeattr(text->type) == word_Normal) { + if (text_convert(text->text, &c)) + rdaddsc(rs, c); + else + text_rdaddwc(rs, text->alt, NULL); + sfree(c); + } else if (removeattr(text->type) == word_WhiteSpace) { + rdaddc(rs, ' '); + } else if (removeattr(text->type) == word_Quote) { + rdaddc(rs, quoteaux(text->aux) == quote_Open ? '`' : '\''); + /* FIXME: configurability */ + } + if (towordstyle(text->type) == word_Emph && + (attraux(text->aux) == attr_Last || + attraux(text->aux) == attr_Only)) rdaddc(rs, '_'); /* FIXME: configurability */ - else if (text->type == word_CodeSpace && - (text->aux == attr_Last || text->aux == attr_Only)) + else if (towordstyle(text->type) == word_Code && + (attraux(text->aux) == attr_Last || + attraux(text->aux) == attr_Only)) rdaddc(rs, '\''); /* FIXME: configurability */ break; } @@ -334,8 +337,8 @@ static int text_width(word *text) { case word_WeakCode: return (((text->type == word_Emph || text->type == word_Code) - ? (text->aux == attr_Only ? 2 : - text->aux == attr_Always ? 0 : 1) + ? (attraux(text->aux) == attr_Only ? 2 : + attraux(text->aux) == attr_Always ? 0 : 1) : 0) + (text_convert(text->text, NULL) ? ustrlen(text->text) : @@ -345,10 +348,16 @@ static int text_width(word *text) { case word_EmphSpace: case word_CodeSpace: case word_WkCodeSpace: - return (((text->type == word_EmphSpace || - text->type == word_CodeSpace) - ? (text->aux == attr_Only ? 2 : - text->aux == attr_Always ? 0 : 1) + case word_Quote: + case word_EmphQuote: + case word_CodeQuote: + case word_WkCodeQuote: + assert(text->type != word_CodeQuote && + text->type != word_WkCodeQuote); + return (((towordstyle(text->type) == word_Emph || + towordstyle(text->type) == word_Code) + ? (attraux(text->aux) == attr_Only ? 2 : + attraux(text->aux) == attr_Always ? 0 : 1) : 0) + 1); } return 0; /* should never happen */ @@ -121,7 +121,12 @@ enum { word_WhiteSpace, /* text is NULL or ignorable */ word_EmphSpace, /* WhiteSpace when emphasised */ word_CodeSpace, /* WhiteSpace when code */ - word_WkCodeSpace, /* WhiteSpace when weak code */ + word_WkCodeSpace, /* WhiteSpace when weak code */ + /* ... and must be in the same order as these quote types ... */ + word_Quote, /* text is NULL or ignorable */ + word_EmphQuote, /* Quote when emphasised */ + word_CodeQuote, /* (can't happen) */ + word_WkCodeQuote, /* (can't happen) */ /* END ORDERING CONSTRAINT */ word_internal_endattrs, word_UpperXref, /* \K */ @@ -133,15 +138,28 @@ enum { }; /* aux values for attributed words */ enum { - attr_Only, /* a lone word with the attribute */ - attr_First, /* the first of a series */ - attr_Last, /* the last of a series */ - attr_Always /* any other part of a series */ + attr_Only = 0x0000, /* a lone word with the attribute */ + attr_First = 0x0001, /* the first of a series */ + attr_Last = 0x0002, /* the last of a series */ + attr_Always = 0x0003, /* any other part of a series */ + attr_mask = 0x0003, +}; +/* aux values for quote-type words */ +enum { + quote_Open = 0x0010, + quote_Close = 0x0020, + quote_mask = 0x0030, }; #define isattr(x) ( ( (x) > word_Normal && (x) < word_WhiteSpace ) || \ ( (x) > word_WhiteSpace && (x) < word_internal_endattrs ) ) -#define sameattr(x,y) ( (x)-(y) == 0 || (x)-(y) == 4 || (x)-(y) == -4 ) -#define tospacestyle(x) ( (x) + 4 ) +#define sameattr(x,y) ( (((x)-(y)) & 3) == 0 ) +#define towordstyle(x) ( word_Normal + ((x) & 3) ) +#define tospacestyle(x) ( word_WhiteSpace + ((x) & 3) ) +#define toquotestyle(x) ( word_Quote + ((x) & 3) ) +#define removeattr(x) ( word_Normal + ((x) &~ 3) ) + +#define attraux(x) ( (x) & attr_mask ) +#define quoteaux(x) ( (x) & quote_mask ) /* * error.c @@ -187,6 +187,7 @@ enum { c_n, /* numbered list */ c_nocite, /* bibliography trickery */ c_preamble, /* document preamble text */ + c_q, /* quote marks */ c_rule, /* horizontal rule */ c_title, /* document title */ c_u, /* aux field is char code */ @@ -249,6 +250,7 @@ static void match_kw(token *tok) { {"n", c_n}, /* numbered list */ {"nocite", c_nocite}, /* bibliography trickery */ {"preamble", c_preamble}, /* document preamble text */ + {"q", c_q}, /* quote marks */ {"rule", c_rule}, /* horizontal rule */ {"title", c_title}, /* document title */ {"versionid", c_versionid}, /* document RCS id */ @@ -504,6 +506,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) { stack_style = 2, /* \e, \c, \cw */ stack_idx = 4, /* \I, \i, \ii */ stack_hyper = 8, /* \W */ + stack_quote = 16, /* \q */ } type; word **whptr; /* to restore from \u alternatives */ word **idximplicit; /* to restore from \u alternatives */ @@ -807,6 +810,20 @@ static void read_file(paragraph ***ret, input *in, index *idx) { if (indexing) addword(wd, &idximplicit); } + if (sitem->type & stack_quote) { + wd.text = NULL; + wd.type = toquotestyle(style); + wd.alt = NULL; + wd.aux = quote_Close; + wd.fpos = t.pos; + wd.breaks = FALSE; + if (!indexing || index_visible) + addword(wd, &whptr); + if (indexing) { + rdadd(&indexstr, L'"'); + addword(wd, &idximplicit); + } + } } sfree(sitem); break; @@ -846,6 +863,28 @@ static void read_file(paragraph ***ret, input *in, index *idx) { } } break; + case c_q: + dtor(t), t = get_token(in); + if (t.type != tok_lbrace) { + error(err_explbr, &t.pos); + } else { + wd.text = NULL; + wd.type = toquotestyle(style); + wd.alt = NULL; + wd.aux = quote_Open; + wd.fpos = t.pos; + wd.breaks = FALSE; + if (!indexing || index_visible) + addword(wd, &whptr); + if (indexing) { + rdadd(&indexstr, L'"'); + addword(wd, &idximplicit); + } + sitem = mknew(struct stack_item); + sitem->type = stack_quote; + stk_push(parsestk, sitem); + } + break; case c_K: case c_k: case c_W: diff --git a/inputs/test.but b/inputs/test.but index 81fb19d..57844ab 100644 --- a/inputs/test.but +++ b/inputs/test.but @@ -7,13 +7,13 @@ date \date{%Y.%m.%d} (default format is \date). \copyright Copyright 1999 Simon \#{second comment}Tatham. All rights reserved. -\define{coopt} co\u00F6{-o}pt - \define{metacoopt} [this is a nested, multi-line macro, talking about \coopt a bit] -\versionid $Id: test.but,v 1.9 1999/10/24 17:14:16 simon Exp $ +\define{coopt} co\u00F6{-o}pt + +\versionid $Id: test.but,v 1.10 1999/11/07 16:14:23 simon Exp $ \C{ch\\ap} First chapter title @@ -56,7 +56,7 @@ This is a numbered list: \n{keyword} Aah. -\n Eek. `Aah' is point \k{keyword}. +\n Eek. \q{Aah} is point \k{keyword}. A-paragraph-full-of-hyphens-to-test-the-idea-that-word-wrapping-can-happen-somewhere-in-all-this-hyphenatory-nonsense. @@ -73,7 +73,7 @@ characters, to be precise. And their code equivalents, \c{\\}, \S{subhead} First subheading So here's a \I{subheading}\I{subsection}subsection. Just -incidentally, `this' is in quotes. \ii{Those} quotes had better work +incidentally, \q{this} is in quotes. \ii{Those} quotes had better work in all formats. We'll try for some Unicode here: \i{Schr\u00F6{oe}dinger}. @@ -143,9 +143,9 @@ void mark_attr_ends(paragraph *sourceform) { sameattr(wp->type, w->type)); int after = (w->next && isattr(w->next->type) && sameattr(w->next->type, w->type)); - w->aux = (before ? - (after ? attr_Always : attr_Last) : - (after ? attr_First : attr_Only)); + w->aux |= (before ? + (after ? attr_Always : attr_Last) : + (after ? attr_First : attr_Only)); } wp = w; } |