summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-03-21 13:09:29 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-03-21 13:09:29 +0000
commitd4084afea5b60ca8b2d5f4e09e97c52c8330a55f (patch)
treeb902c7b99b4008cf2a68fbed3ae2e04775161b24
parent86bb8c0e30ab857dae5be0086e8c7cd444afd2af (diff)
downloadmandoc-d4084afea5b60ca8b2d5f4e09e97c52c8330a55f.tar.gz
`Em' accepts empty tokens.
Punctuation fully fixed (per-reserved-word). Sm enabled.
-rw-r--r--mandoc.143
-rw-r--r--mdoc.h2
-rw-r--r--private.h1
-rw-r--r--term.c47
-rw-r--r--terminal.c163
-rw-r--r--validate.c2
6 files changed, 186 insertions, 72 deletions
diff --git a/mandoc.1 b/mandoc.1
index d6a44002..4b4d8740 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -88,6 +88,45 @@ were provided.
.Pp
.Ex -std mandoc
.\" SUB-SECTION
+.Ss Reserved Words
+The reserved words described in
+.Xr mdoc 7
+are handled according to the following rules:
+.Bl -enum -offset XXX
+.It
+Opening delimiters
+.Po
+.Sq \&( ,
+.Sq \&[ ,
+and
+.Sq \&{
+.Pc are not followed by whitespace.
+.It
+Closing delimiters
+.Po
+.Sq \&. ,
+.Sq \&, ,
+.Sq \&; ,
+.Sq \&: ,
+.Sq \&? ,
+.Sq \&! ,
+.Sq \&) ,
+.Sq \&]
+and
+.Sq \&}
+.Pc are not preceeded by whitespace.
+.El
+.\" PARAGRAPH
+.Pp
+Note that reserved words may occur in streams of text, so the following:
+.Bd -literal -offset XXXX
+this self is not that of the waking , empirically real man
+.Ed
+.\" PARAGRAPH
+.Pp
+\&...correctly adjusts the comma spacing to
+.Qq this self is not that of the waking , empirically real man .
+.\" SUB-SECTION
.Ss Output Formats
The
.Nm
@@ -160,10 +199,6 @@ displays types are synonyms, as are \-filled and \-ragged.
The
.Sq \&Xo/Xc
pair isn't supported.
-.It
-The
-.Sq \&Sm
-macro has no effect, yet.
.El
.Pp
Other macros still aren't supported by virtue of nobody complaining
diff --git a/mdoc.h b/mdoc.h
index 7bcaa8e9..1c184e88 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -322,8 +322,6 @@ const char *mdoc_a2att(const char *);
const char *mdoc_a2lib(const char *);
const char *mdoc_a2st(const char *);
-int mdoc_isdelim(const char *);
-
__END_DECLS
#endif /*!MDOC_H*/
diff --git a/private.h b/private.h
index f28a3ef5..304862ad 100644
--- a/private.h
+++ b/private.h
@@ -117,6 +117,7 @@ void *mdoc_tokhash_alloc(void);
int mdoc_tokhash_find(const void *, const char *);
void mdoc_tokhash_free(void *);
int mdoc_iscdelim(char);
+int mdoc_isdelim(const char *);
size_t mdoc_isescape(const char *);
enum mdoc_sec mdoc_atosec(const char *);
time_t mdoc_atotime(const char *);
diff --git a/term.c b/term.c
index 09af2f9f..ad783444 100644
--- a/term.c
+++ b/term.c
@@ -55,7 +55,7 @@
#define TTYPE_DIAG 18
#define TTYPE_LINK_ANCHOR 19
#define TTYPE_LINK_TEXT 20
-#define TTYPE_REF_TITLE 21
+#define TTYPE_REF_JOURNAL 21
#define TTYPE_NMAX 22
/*
@@ -88,7 +88,7 @@ const int ttypes[TTYPE_NMAX] = {
TERMP_BOLD, /* TTYPE_DIAG */
TERMP_UNDER, /* TTYPE_LINK_ANCHOR */
TERMP_BOLD, /* TTYPE_LINK_TEXT */
- TERMP_UNDER /* TTYPE_REF_TITLE */
+ TERMP_UNDER /* TTYPE_REF_JOURNAL */
};
static int arg_hasattr(int, const struct mdoc_node *);
@@ -118,6 +118,7 @@ static void name##_post(DECL_ARGS)
DECL_PRE(name); \
DECL_POST(name);
+DECL_PREPOST(termp__t);
DECL_PREPOST(termp_aq);
DECL_PREPOST(termp_bd);
DECL_PREPOST(termp_bq);
@@ -140,7 +141,7 @@ DECL_PREPOST(termp_ss);
DECL_PREPOST(termp_sq);
DECL_PREPOST(termp_vt);
-DECL_PRE(termp__t);
+DECL_PRE(termp__j);
DECL_PRE(termp_ap);
DECL_PRE(termp_ar);
DECL_PRE(termp_at);
@@ -227,12 +228,12 @@ const struct termact __termacts[MDOC_MAX] = {
{ NULL, termp____post }, /* %B */
{ NULL, termp____post }, /* %D */
{ NULL, termp____post }, /* %I */
- { NULL, termp____post }, /* %J */
+ { termp__j_pre, termp____post }, /* %J */
{ NULL, termp____post }, /* %N */
{ NULL, termp____post }, /* %O */
{ NULL, termp____post }, /* %P */
{ NULL, termp____post }, /* %R */
- { termp__t_pre, termp____post }, /* %T */
+ { termp__t_pre, termp__t_post }, /* %T */
{ NULL, termp____post }, /* %V */
{ NULL, NULL }, /* Ac */
{ termp_aq_pre, termp_aq_post }, /* Ao */
@@ -1803,16 +1804,14 @@ static int
termp_sm_pre(DECL_ARGS)
{
-#if notyet
- assert(node->child);
- if (0 == strcmp("off", node->child->data.text.string)) {
+ if (NULL == node->child || MDOC_TEXT != node->child->type)
+ errx(1, "expected boolean line argument");
+
+ if (0 == strcmp("on", node->child->string)) {
p->flags &= ~TERMP_NONOSPACE;
p->flags &= ~TERMP_NOSPACE;
- } else {
+ } else
p->flags |= TERMP_NONOSPACE;
- p->flags |= TERMP_NOSPACE;
- }
-#endif
return(0);
}
@@ -1832,16 +1831,38 @@ termp_ap_pre(DECL_ARGS)
/* ARGSUSED */
static int
+termp__j_pre(DECL_ARGS)
+{
+
+ TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_REF_JOURNAL]);
+ return(1);
+}
+
+
+/* ARGSUSED */
+static int
termp__t_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_REF_TITLE]);
+ term_word(p, "\"");
+ p->flags |= TERMP_NOSPACE;
return(1);
}
/* ARGSUSED */
static void
+termp__t_post(DECL_ARGS)
+{
+
+ p->flags |= TERMP_NOSPACE;
+ term_word(p, "\"");
+ termp____post(p, pair, meta, node);
+}
+
+
+/* ARGSUSED */
+static void
termp____post(DECL_ARGS)
{
diff --git a/terminal.c b/terminal.c
index 770fc80c..ab596b03 100644
--- a/terminal.c
+++ b/terminal.c
@@ -29,23 +29,25 @@ extern size_t strlcpy(char *, const char *, size_t);
extern size_t strlcat(char *, const char *, size_t);
#endif
-static struct termp *termp_alloc(enum termenc);
-static void termp_free(struct termp *);
-static void termp_body(struct termp *, struct termpair *,
+static struct termp *term_alloc(enum termenc);
+static void term_free(struct termp *);
+static void term_body(struct termp *, struct termpair *,
const struct mdoc_meta *,
const struct mdoc_node *);
-static void termp_head(struct termp *,
+static void term_head(struct termp *,
const struct mdoc_meta *);
-static void termp_foot(struct termp *,
+static void term_foot(struct termp *,
const struct mdoc_meta *);
-static void termp_pword(struct termp *, const char *, int);
-static void termp_pescape(struct termp *,
+static void term_pword(struct termp *, const char *, int);
+static void term_pescape(struct termp *,
const char *, int *, int);
-static void termp_nescape(struct termp *,
+static void term_nescape(struct termp *,
const char *, size_t);
-static void termp_chara(struct termp *, char);
-static void termp_stringa(struct termp *,
+static void term_chara(struct termp *, char);
+static void term_stringa(struct termp *,
const char *, size_t);
+static int term_isopendelim(const char *, size_t);
+static int term_isclosedelim(const char *, size_t);
static void sanity(const struct mdoc_node *); /* XXX */
@@ -53,7 +55,7 @@ void *
latin1_alloc(void)
{
- return(termp_alloc(TERMENC_LATIN1));
+ return(term_alloc(TERMENC_LATIN1));
}
@@ -61,7 +63,7 @@ void *
utf8_alloc(void)
{
- return(termp_alloc(TERMENC_UTF8));
+ return(term_alloc(TERMENC_UTF8));
}
@@ -69,7 +71,7 @@ void *
ascii_alloc(void)
{
- return(termp_alloc(TERMENC_ASCII));
+ return(term_alloc(TERMENC_ASCII));
}
@@ -83,9 +85,9 @@ terminal_run(void *arg, const struct mdoc *mdoc)
if (NULL == p->symtab)
p->symtab = term_ascii2htab();
- termp_head(p, mdoc_meta(mdoc));
- termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc));
- termp_foot(p, mdoc_meta(mdoc));
+ term_head(p, mdoc_meta(mdoc));
+ term_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc));
+ term_foot(p, mdoc_meta(mdoc));
return(1);
}
@@ -95,12 +97,12 @@ void
terminal_free(void *arg)
{
- termp_free((struct termp *)arg);
+ term_free((struct termp *)arg);
}
static void
-termp_free(struct termp *p)
+term_free(struct termp *p)
{
if (p->buf)
@@ -113,7 +115,7 @@ termp_free(struct termp *p)
static struct termp *
-termp_alloc(enum termenc enc)
+term_alloc(enum termenc enc)
{
struct termp *p;
@@ -126,6 +128,62 @@ termp_alloc(enum termenc enc)
}
+static int
+term_isclosedelim(const char *p, size_t len)
+{
+
+ if (1 != len)
+ return(0);
+
+ switch (*p) {
+ case('.'):
+ /* FALLTHROUGH */
+ case(','):
+ /* FALLTHROUGH */
+ case(';'):
+ /* FALLTHROUGH */
+ case(':'):
+ /* FALLTHROUGH */
+ case('?'):
+ /* FALLTHROUGH */
+ case('!'):
+ /* FALLTHROUGH */
+ case(')'):
+ /* FALLTHROUGH */
+ case(']'):
+ /* FALLTHROUGH */
+ case('}'):
+ return(1);
+ default:
+ break;
+ }
+
+ return(0);
+}
+
+
+static int
+term_isopendelim(const char *p, size_t len)
+{
+
+ if (1 != len)
+ return(0);
+
+ switch (*p) {
+ case('('):
+ /* FALLTHROUGH */
+ case('['):
+ /* FALLTHROUGH */
+ case('{'):
+ return(1);
+ default:
+ break;
+ }
+
+ return(0);
+}
+
+
/*
* Flush a line of text. A "line" is loosely defined as being something
* that should be followed by a newline, regardless of whether it's
@@ -327,16 +385,10 @@ term_word(struct termp *p, const char *word)
len = (int)strlen(word);
if (p->flags & TERMP_LITERAL) {
- termp_pword(p, word, len);
+ term_pword(p, word, len);
return;
}
- if (mdoc_isdelim(word)) {
- if ( ! (p->flags & TERMP_IGNDELIM))
- p->flags |= TERMP_NOSPACE;
- p->flags &= ~TERMP_IGNDELIM;
- }
-
/* LINTED */
for (j = i = 0; i < len; i++) {
if (' ' != word[i]) {
@@ -353,25 +405,25 @@ term_word(struct termp *p, const char *word)
if (0 == j)
continue;
assert(i >= j);
- termp_pword(p, &word[i - j], j);
+ term_pword(p, &word[i - j], j);
j = 0;
}
if (j > 0) {
assert(i >= j);
- termp_pword(p, &word[i - j], j);
+ term_pword(p, &word[i - j], j);
}
}
static void
-termp_body(struct termp *p, struct termpair *ppair,
+term_body(struct termp *p, struct termpair *ppair,
const struct mdoc_meta *meta,
const struct mdoc_node *node)
{
term_node(p, ppair, meta, node);
if (node->next)
- termp_body(p, ppair, meta, node->next);
+ term_body(p, ppair, meta, node->next);
}
@@ -415,7 +467,7 @@ term_node(struct termp *p, struct termpair *ppair,
p->flags |= pair.flag;
if (dochild && node->child)
- termp_body(p, &pair, meta, node->child);
+ term_body(p, &pair, meta, node->child);
if (TERMPAIR_FLAG & pair.type)
p->flags &= ~pair.flag;
@@ -429,7 +481,7 @@ term_node(struct termp *p, struct termpair *ppair,
static void
-termp_foot(struct termp *p, const struct mdoc_meta *meta)
+term_foot(struct termp *p, const struct mdoc_meta *meta)
{
struct tm *tm;
char *buf, *os;
@@ -480,7 +532,7 @@ termp_foot(struct termp *p, const struct mdoc_meta *meta)
static void
-termp_head(struct termp *p, const struct mdoc_meta *meta)
+term_head(struct termp *p, const struct mdoc_meta *meta)
{
char *buf, *title;
@@ -554,14 +606,14 @@ termp_head(struct termp *p, const struct mdoc_meta *meta)
* output buffer by way of the symbol table.
*/
static void
-termp_nescape(struct termp *p, const char *word, size_t len)
+term_nescape(struct termp *p, const char *word, size_t len)
{
const char *rhs;
size_t sz;
if (NULL == (rhs = term_a2ascii(p->symtab, word, len, &sz)))
return;
- termp_stringa(p, rhs, sz);
+ term_stringa(p, rhs, sz);
}
@@ -571,7 +623,7 @@ termp_nescape(struct termp *p, const char *word, size_t len)
* the escape sequence (we assert upon badly-formed escape sequences).
*/
static void
-termp_pescape(struct termp *p, const char *word, int *i, int len)
+term_pescape(struct termp *p, const char *word, int *i, int len)
{
int j;
@@ -583,7 +635,7 @@ termp_pescape(struct termp *p, const char *word, int *i, int len)
if (*i + 1 >= len)
return;
- termp_nescape(p, &word[*i], 2);
+ term_nescape(p, &word[*i], 2);
(*i)++;
return;
@@ -598,18 +650,18 @@ termp_pescape(struct termp *p, const char *word, int *i, int len)
if (*i + 1 >= len)
return;
- termp_nescape(p, &word[*i], 2);
+ term_nescape(p, &word[*i], 2);
(*i)++;
return;
case ('['):
break;
default:
- termp_nescape(p, &word[*i], 1);
+ term_nescape(p, &word[*i], 1);
return;
}
} else if ('[' != word[*i]) {
- termp_nescape(p, &word[*i], 1);
+ term_nescape(p, &word[*i], 1);
return;
}
@@ -620,7 +672,7 @@ termp_pescape(struct termp *p, const char *word, int *i, int len)
if (0 == word[*i])
return;
- termp_nescape(p, &word[*i - j], (size_t)j);
+ term_nescape(p, &word[*i - j], (size_t)j);
}
@@ -630,12 +682,16 @@ termp_pescape(struct termp *p, const char *word, int *i, int len)
* handles word styling.
*/
static void
-termp_pword(struct termp *p, const char *word, int len)
+term_pword(struct termp *p, const char *word, int len)
{
int i;
+ if (term_isclosedelim(word, len))
+ if ( ! (TERMP_IGNDELIM & p->flags))
+ p->flags |= TERMP_NOSPACE;
+
if ( ! (TERMP_NOSPACE & p->flags))
- termp_chara(p, ' ');
+ term_chara(p, ' ');
if ( ! (p->flags & TERMP_NONOSPACE))
p->flags &= ~TERMP_NOSPACE;
@@ -647,33 +703,36 @@ termp_pword(struct termp *p, const char *word, int len)
for (i = 0; i < len; i++) {
if ('\\' == word[i]) {
- termp_pescape(p, word, &i, len);
+ term_pescape(p, word, &i, len);
continue;
}
if (TERMP_STYLE & p->flags) {
if (TERMP_BOLD & p->flags) {
- termp_chara(p, word[i]);
- termp_chara(p, 8);
+ term_chara(p, word[i]);
+ term_chara(p, 8);
}
if (TERMP_UNDER & p->flags) {
- termp_chara(p, '_');
- termp_chara(p, 8);
+ term_chara(p, '_');
+ term_chara(p, 8);
}
}
- termp_chara(p, word[i]);
+ term_chara(p, word[i]);
}
+
+ if (term_isopendelim(word, len))
+ p->flags |= TERMP_NOSPACE;
}
/*
- * Like termp_chara() but for arbitrary-length buffers. Resize the
+ * Like term_chara() but for arbitrary-length buffers. Resize the
* buffer by a factor of two (if the buffer is less than that) or the
* buffer's size.
*/
static void
-termp_stringa(struct termp *p, const char *c, size_t sz)
+term_stringa(struct termp *p, const char *c, size_t sz)
{
size_t s;
@@ -702,7 +761,7 @@ termp_stringa(struct termp *p, const char *c, size_t sz)
* size.
*/
static void
-termp_chara(struct termp *p, char c)
+term_chara(struct termp *p, char c)
{
size_t s;
diff --git a/validate.c b/validate.c
index 65785042..074d6042 100644
--- a/validate.c
+++ b/validate.c
@@ -265,7 +265,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, posts_wline }, /* Dq */
{ NULL, NULL }, /* Ec */
{ NULL, NULL }, /* Ef */
- { NULL, posts_text }, /* Em */
+ { NULL, NULL }, /* Em */
{ NULL, NULL }, /* Eo */
{ NULL, NULL }, /* Fx */
{ NULL, posts_text }, /* Ms */