summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bk_text.c77
-rw-r--r--buttress.h32
-rw-r--r--input.c39
-rw-r--r--inputs/test.but10
-rw-r--r--misc.c6
5 files changed, 115 insertions, 49 deletions
diff --git a/bk_text.c b/bk_text.c
index 2f32b47..b7bdac7 100644
--- a/bk_text.c
+++ b/bk_text.c
@@ -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 */
diff --git a/buttress.h b/buttress.h
index 09969a3..f4e4533 100644
--- a/buttress.h
+++ b/buttress.h
@@ -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
diff --git a/input.c b/input.c
index 2e0b583..a312155 100644
--- a/input.c
+++ b/input.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}.
diff --git a/misc.c b/misc.c
index 97caf8d..c808670 100644
--- a/misc.c
+++ b/misc.c
@@ -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;
}