summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bk_text.c42
-rw-r--r--buttress.h23
-rw-r--r--input.c12
-rw-r--r--main.c2
-rw-r--r--misc.c23
5 files changed, 91 insertions, 11 deletions
diff --git a/bk_text.c b/bk_text.c
index 786c126..2b58c06 100644
--- a/bk_text.c
+++ b/bk_text.c
@@ -262,23 +262,42 @@ static void text_rdaddwc(rdstringc *rs, word *text, word *end) {
case word_Emph:
case word_Code:
case word_WeakCode:
- if (text->type == word_Emph)
+ if (text->type == word_Emph &&
+ (text->aux == attr_First || text->aux == attr_Only))
rdaddc(rs, '_'); /* FIXME: configurability */
- else if (text->type == word_Code)
+ 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)
+ if (text->type == word_Emph &&
+ (text->aux == attr_Last || text->aux == attr_Only))
rdaddc(rs, '_'); /* FIXME: configurability */
- else if (text->type == word_Code)
+ 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))
+ rdaddc(rs, '_'); /* FIXME: configurability */
+ else if (text->type == word_CodeSpace &&
+ (text->aux == attr_First || text->aux == attr_Only))
+ rdaddc(rs, '`'); /* FIXME: configurability */
rdaddc(rs, ' ');
+ if (text->type == word_EmphSpace &&
+ (text->aux == attr_Last || text->aux == attr_Only))
+ rdaddc(rs, '_'); /* FIXME: configurability */
+ else if (text->type == word_CodeSpace &&
+ (text->aux == attr_Last || text->aux == attr_Only))
+ rdaddc(rs, '\''); /* FIXME: configurability */
break;
}
}
@@ -308,13 +327,24 @@ static int text_width(word *text) {
case word_Emph:
case word_Code:
case word_WeakCode:
- return ((text->type == word_Emph || text->type == word_Code ? 2 : 0) +
+ return (((text->type == word_Emph ||
+ text->type == word_Code)
+ ? (text->aux == attr_Only ? 2 :
+ text->aux == attr_Always ? 0 : 1)
+ : 0) +
(text_convert(text->text, NULL) ?
ustrlen(text->text) :
text_width_list(text->alt)));
case word_WhiteSpace:
- return 1;
+ 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)
+ : 0) + 1);
}
return 0; /* should never happen */
}
diff --git a/buttress.h b/buttress.h
index b059322..1ce39d7 100644
--- a/buttress.h
+++ b/buttress.h
@@ -99,22 +99,41 @@ enum {
struct word_Tag {
word *next, *alt;
int type;
+ int aux;
wchar_t *text;
filepos fpos;
};
enum {
+ /* ORDERING CONSTRAINT: these normal-word types ... */
word_Normal,
word_Emph,
word_Code, /* monospaced; `quoted' in text */
word_WeakCode, /* monospaced, normal in text */
+ /* ... must be in the same order as these space types ... */
+ word_WhiteSpace, /* text is NULL or ignorable */
+ word_EmphSpace, /* WhiteSpace when emphasised */
+ word_CodeSpace, /* WhiteSpace when code */
+ word_WkCodeSpace, /* WhiteSpace when weak code */
+ /* END ORDERING CONSTRAINT */
+ word_internal_endattrs,
word_UpperXref, /* \K */
word_LowerXref, /* \k */
word_XrefEnd, /* (invisible; no text) */
word_IndexRef, /* (always an invisible one) */
- word_WhiteSpace, /* text is NULL or ignorable */
word_HyperLink, /* (invisible) */
word_HyperEnd /* (also invisible; no text) */
};
+/* 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 */
+};
+#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 )
/*
* error.c
@@ -231,6 +250,8 @@ char *rdtrimc(rdstringc *rs);
int compare_wordlists(word *a, word *b);
+void mark_attr_ends(paragraph *sourceform);
+
typedef struct tagWrappedLine wrappedline;
struct tagWrappedLine {
wrappedline *next;
diff --git a/input.c b/input.c
index 32eca3b..97d732e 100644
--- a/input.c
+++ b/input.c
@@ -417,7 +417,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
paragraph par;
word wd, **whptr, **idximplicit;
wchar_t utext[2], *wdtext;
- int style;
+ int style, spcstyle;
int already;
int iswhite, seenwhite;
int type;
@@ -618,6 +618,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
*/
parsestk = stk_new();
style = word_Normal;
+ spcstyle = word_WhiteSpace;
indexing = FALSE;
seenwhite = TRUE;
while (t.type != tok_eop && t.type != tok_eof) {
@@ -630,7 +631,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
if (whptr == &par.words)
break; /* strip whitespace at start of para */
wd.text = NULL;
- wd.type = word_WhiteSpace;
+ wd.type = spcstyle;
wd.alt = NULL;
wd.fpos = t.pos;
if (indexing)
@@ -672,8 +673,10 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
whptr = sitem->whptr;
idximplicit = sitem->idximplicit;
}
- if (sitem->type & stack_style)
+ if (sitem->type & stack_style) {
style = word_Normal;
+ spcstyle = word_WhiteSpace;
+ }
if (sitem->type & stack_idx) {
indexword->text = ustrdup(indexstr.text);
if (index_downcase)
@@ -810,6 +813,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
style = (t.cmd == c_c ? word_Code :
t.cmd == c_cw ? word_WeakCode :
word_Emph);
+ spcstyle = tospacestyle(style);
sitem->type |= stack_style;
}
dtor(t), t = get_token(in);
@@ -842,6 +846,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
style = (type == c_c ? word_Code :
type == c_cw ? word_WeakCode :
word_Emph);
+ spcstyle = tospacestyle(style);
sitem = mknew(struct stack_item);
sitem->type = stack_style;
stk_push(parsestk, sitem);
@@ -874,6 +879,7 @@ static void read_file(paragraph ***ret, input *in, index *idx) {
style = (t.cmd == c_c ? word_Code :
t.cmd == c_cw ? word_WeakCode :
word_Emph);
+ spcstyle = tospacestyle(style);
sitem->type |= stack_style;
}
dtor(t), t = get_token(in);
diff --git a/main.c b/main.c
index 34ce7d4..2827f0e 100644
--- a/main.c
+++ b/main.c
@@ -188,6 +188,8 @@ int main(int argc, char **argv) {
if (!sourceform)
exit(EXIT_FAILURE);
+ mark_attr_ends(sourceform);
+
sfree(infiles);
keywords = get_keywords(sourceform);
diff --git a/misc.c b/misc.c
index 3d512c6..e68ed42 100644
--- a/misc.c
+++ b/misc.c
@@ -132,6 +132,26 @@ int compare_wordlists(word *a, word *b) {
return 0;
}
+void mark_attr_ends(paragraph *sourceform) {
+ paragraph *p;
+ word *w, *wp;
+ for (p = sourceform; p; p = p->next) {
+ wp = NULL;
+ for (w = p->words; w; w = w->next) {
+ if (isattr(w->type)) {
+ int before = (wp && isattr(wp->type) &&
+ 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));
+ }
+ wp = w;
+ }
+ }
+}
+
wrappedline *wrap_para(word *text, int width, int subsequentwidth,
int (*widthfn)(word *)) {
wrappedline *head = NULL, **ptr = &head;
@@ -151,7 +171,8 @@ wrappedline *wrap_para(word *text, int width, int subsequentwidth,
thiswidth = lastgood = 0;
while (text) {
thiswidth += widthfn(text);
- if (text->next && text->next->type == word_WhiteSpace) {
+ if (text->next && (text->next->type == word_WhiteSpace ||
+ text->next->type == word_EmphSpace)) {
if (thiswidth > width)
break;
spc = text->next;