+ if (NULL == mdoc->meta.title)
+ mdoc->meta.title = xstrdup("untitled");
+ return(1);
+}
+
+
+static int
+post_os(struct mdoc *mdoc)
+{
+ char buf[64];
+
+ assert(MDOC_ELEM == mdoc->last->type);
+ assert(MDOC_Os == mdoc->last->tok);
+ assert(NULL == mdoc->meta.os);
+
+ if ( ! xstrlcats(buf, mdoc->last->child, 64))
+ return(mdoc_err(mdoc, "macro parameters too long"));
+
+ mdoc->meta.os = xstrdup(buf[0] ? buf : "local");
+ mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
+ return(1);
+}
+
+
+static int
+post_dd(struct mdoc *mdoc)
+{
+ char date[64];
+ size_t sz;
+ char *p;
+ struct mdoc_node *n;
+
+ assert(MDOC_ELEM == mdoc->last->type);
+ assert(MDOC_Dd == mdoc->last->tok);
+
+ n = mdoc->last->child;
+ assert(0 == mdoc->meta.date);
+ date[0] = 0;
+
+ sz = 64;
+
+ for ( ; 0 == mdoc->meta.date && n; n = n->next) {
+ assert(MDOC_TEXT == n->type);
+ p = n->data.text.string;
+
+ if (xstrcmp(p, "$Mdocdate: January 19 2009 $")) {
+ mdoc->meta.date = time(NULL);
+ continue;
+ } else if (xstrcmp(p, "$")) {
+ mdoc->meta.date = mdoc_atotime(date);
+ continue;
+ } else if (xstrcmp(p, "$Mdocdate:"))
+ continue;
+
+ if ( ! xstrlcat(date, n->data.text.string, sz))
+ return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
+ if (n->next && ! xstrlcat(date, " ", sz))
+ return(mdoc_nerr(mdoc, n, "invalid parameter syntax"));
+ }
+
+ if (mdoc->meta.date && NULL == n)
+ return(1);
+ else if (n)
+ return(mdoc_err(mdoc, "invalid parameter syntax"));
+ if ((mdoc->meta.date = mdoc_atotime(date)))
+ return(1);
+ return(mdoc_err(mdoc, "invalid parameter syntax"));
+}
+
+
+int
+mdoc_action_post(struct mdoc *mdoc)
+{
+
+ if (MDOC_ACTED & mdoc->last->flags)
+ return(1);
+ mdoc->last->flags |= MDOC_ACTED;
+
+ if (MDOC_TEXT == mdoc->last->type)
+ return(1);
+ if (MDOC_ROOT == mdoc->last->type)
+ return(1);
+ if (NULL == mdoc_actions[mdoc->last->tok].post)
+ return(1);
+ return((*mdoc_actions[mdoc->last->tok].post)(mdoc));
+}