File: [cvsweb.bsd.lv] / docbook2mdoc / node.c (download)
Revision 1.3, Wed Apr 3 11:46:09 2019 UTC (5 years, 2 months ago) by schwarze
Branch: MAIN
Changes since 1.2: +2 -1 lines
Prints tables containing only one column as .Bl -bullet -compact.
The number of columns is taken from the "cols" attribute.
No neat to treat <informaltable> separately from <table>;
the only difference is whether or not it has a title.
Treat <table> as transparent and handle <tgroup> instead.
The advantages are that <title> gets a generic handler
which also works in other contexts
and that other children of <table> are now covered as well.
|
/* $Id: node.c,v 1.3 2019/04/03 11:46:09 schwarze Exp $ */
/*
* Copyright (c) 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "node.h"
/*
* The implementation of the DocBook syntax tree.
*/
static const char *const attrkeys[ATTRKEY__MAX] = {
"choice",
"class",
"close",
"cols",
"id",
"linkend",
"open",
"rep"
};
static const char *const attrvals[ATTRVAL__MAX] = {
"monospaced",
"norepeat",
"opt",
"plain",
"repeat",
"req"
};
enum attrkey
attrkey_parse(const char *name)
{
enum attrkey key;
for (key = 0; key < ATTRKEY__MAX; key++)
if (strcmp(name, attrkeys[key]) == 0)
break;
return key;
}
enum attrval
attrval_parse(const char *name)
{
enum attrval val;
for (val = 0; val < ATTRVAL__MAX; val++)
if (strcmp(name, attrvals[val]) == 0)
break;
return val;
}
/*
* Recursively free a node (NULL is ok).
*/
static void
pnode_free(struct pnode *pn)
{
struct pnode *pch;
struct pattr *ap;
if (pn == NULL)
return;
while ((pch = TAILQ_FIRST(&pn->childq)) != NULL) {
TAILQ_REMOVE(&pn->childq, pch, child);
pnode_free(pch);
}
while ((ap = TAILQ_FIRST(&pn->attrq)) != NULL) {
TAILQ_REMOVE(&pn->attrq, ap, child);
free(ap->rawval);
free(ap);
}
free(pn->real);
free(pn);
}
/*
* Unlink a node from its parent and pnode_free() it.
*/
void
pnode_unlink(struct pnode *pn)
{
if (pn == NULL)
return;
if (pn->parent != NULL)
TAILQ_REMOVE(&pn->parent->childq, pn, child);
pnode_free(pn);
}
/*
* Unlink all children of a node and pnode_free() them.
*/
void
pnode_unlinksub(struct pnode *pn)
{
while (TAILQ_EMPTY(&pn->childq) == 0)
pnode_unlink(TAILQ_FIRST(&pn->childq));
}
/*
* Retrieve an enumeration attribute from a node.
* Return ATTRVAL__MAX if the node has no such attribute.
*/
enum attrval
pnode_getattr(struct pnode *pn, enum attrkey key)
{
struct pattr *ap;
if (pn == NULL)
return ATTRVAL__MAX;
TAILQ_FOREACH(ap, &pn->attrq, child)
if (ap->key == key)
return ap->val;
return ATTRVAL__MAX;
}
/*
* Retrieve an attribute string from a node.
* Return defval if the node has no such attribute.
*/
const char *
pnode_getattr_raw(struct pnode *pn, enum attrkey key, const char *defval)
{
struct pattr *ap;
if (pn == NULL)
return defval;
TAILQ_FOREACH(ap, &pn->attrq, child)
if (ap->key == key)
return ap->val != ATTRVAL__MAX ? attrvals[ap->val] :
ap->rawval != NULL ? ap->rawval : defval;
return defval;
}
/*
* Recursively search and return the first instance of "node".
*/
struct pnode *
pnode_findfirst(struct pnode *pn, enum nodeid node)
{
struct pnode *pch, *res;
if (pn->node == node)
return pn;
TAILQ_FOREACH(pch, &pn->childq, child)
if ((res = pnode_findfirst(pch, node)) != NULL)
return res;
return NULL;
}