summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-11-07 08:26:45 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-11-07 08:26:45 +0000
commit63d9bea608ed28cee1916112d03db7767ad915a5 (patch)
tree3e61fcdfd6934c07cf5c455047fcb6be90911af5
parentfb1465173e68568bcbfb5ca542e5bb58ae5c2866 (diff)
downloadmandoc-63d9bea608ed28cee1916112d03db7767ad915a5.tar.gz
Initial abstraction of front-end decoration events (special characters, text decorations, etc.).
-rw-r--r--out.c192
-rw-r--r--out.h12
2 files changed, 204 insertions, 0 deletions
diff --git a/out.c b/out.c
index 41904b7e..6165d240 100644
--- a/out.c
+++ b/out.c
@@ -166,3 +166,195 @@ time2a(time_t t, char *dst, size_t sz)
(void)strftime(p, sz, "%Y", &tm);
}
+
+/* Returns length of parsed string. */
+int
+a2roffdeco(enum roffdeco *d,
+ const char **word, size_t *sz)
+{
+ int j, type, sv, t, lim;
+ const char *wp;
+
+ *d = DECO_NONE;
+
+ wp = *word;
+ type = 1;
+
+ switch (*wp) {
+ case ('\0'):
+ return(0);
+
+ case ('('):
+ wp++;
+ if ('\0' == *wp)
+ return(1);
+ if ('\0' == *(wp + 1))
+ return(2);
+
+ *d = DECO_SPECIAL;
+ *sz = 2;
+ *word = wp;
+ return(3);
+
+ case ('*'):
+ wp++;
+
+ switch (*wp) {
+ case ('\0'):
+ return(1);
+
+ case ('('):
+ wp++;
+ if ('\0' == *wp)
+ return(2);
+ if ('\0' == *(wp + 1))
+ return(3);
+
+ *d = DECO_RESERVED;
+ *sz = 2;
+ *word = wp;
+ return(4);
+
+ case ('['):
+ type = 0;
+ break;
+
+ default:
+ *d = DECO_RESERVED;
+ *sz = 1;
+ *word = wp;
+ return(3);
+ }
+ break;
+
+#if 0
+ case ('s'):
+ wp++;
+
+ /* This closely follows mandoc_special(). */
+ if ('\0' == *wp)
+ return(1);
+
+ t = 0;
+ lim = 1;
+
+ if (*wp == '\'') {
+ lim = 0;
+ t = 1;
+ ++wp;
+ } else if (*wp == '[') {
+ lim = 0;
+ t = 2;
+ ++wp;
+ } else if (*wp == '(') {
+ lim = 2;
+ t = 3;
+ ++wp;
+ }
+
+ if (*wp == '+' || *wp == '-')
+ ++wp;
+
+ if (*wp == '\'') {
+ if (t) {
+ *word = wp;
+ return;
+ }
+ lim = 0;
+ t = 1;
+ ++wp;
+ } else if (*wp == '[') {
+ if (t) {
+ *word = wp;
+ return;
+ }
+ lim = 0;
+ t = 2;
+ ++wp;
+ } else if (*wp == '(') {
+ if (t) {
+ *word = wp;
+ return;
+ }
+ lim = 2;
+ t = 3;
+ ++wp;
+ }
+
+ if ( ! isdigit((u_char)*wp)) {
+ *word = --wp;
+ return;
+ }
+
+ for (j = 0; isdigit((u_char)*wp); j++) {
+ if (lim && j >= lim)
+ break;
+ ++wp;
+ }
+
+ if (t && t < 3) {
+ if (1 == t && *wp != '\'') {
+ *word = --wp;
+ return;
+ }
+ if (2 == t && *wp != ']') {
+ *word = --wp;
+ return;
+ }
+ ++wp;
+ }
+ *word = --wp;
+ return;
+#endif
+
+ case ('f'):
+ wp++;
+
+ switch (*wp) {
+ case ('\0'):
+ return(1);
+ case ('3'):
+ /* FALLTHROUGH */
+ case ('B'):
+ *d = DECO_BOLD;
+ break;
+ case ('2'):
+ /* FALLTHROUGH */
+ case ('I'):
+ *d = DECO_ITALIC;
+ break;
+ case ('P'):
+ *d = DECO_PREVIOUS;
+ break;
+ case ('1'):
+ /* FALLTHROUGH */
+ case ('R'):
+ *d = DECO_ROMAN;
+ break;
+ default:
+ break;
+ }
+
+ return(2);
+
+ case ('['):
+ break;
+
+ default:
+ *d = DECO_SPECIAL;
+ *word = wp;
+ *sz = 1;
+ return(1);
+ }
+
+ *word = ++wp;
+ for (j = 0; *wp && ']' != *wp; wp++, j++)
+ /* Loop... */ ;
+
+ if ('\0' == *wp)
+ return(j + 1);
+
+ *d = type ? DECO_SPECIAL : DECO_RESERVED;
+ *sz = j;
+ return (j + 2);
+}
diff --git a/out.h b/out.h
index 92ebbba9..822f9d12 100644
--- a/out.h
+++ b/out.h
@@ -35,6 +35,17 @@ enum roffscale {
SCALE_MAX
};
+enum roffdeco {
+ DECO_NONE,
+ DECO_SPECIAL,
+ DECO_RESERVED,
+ DECO_BOLD,
+ DECO_ITALIC,
+ DECO_ROMAN,
+ DECO_PREVIOUS,
+ DECO_MAX
+};
+
struct roffsu {
enum roffscale unit;
double scale;
@@ -54,6 +65,7 @@ struct roffsu {
int a2roffsu(const char *,
struct roffsu *, enum roffscale);
+int a2roffdeco(enum roffdeco *, const char **, size_t *);
void time2a(time_t, char *, size_t);
__END_DECLS