version 1.1, 2014/04/02 10:06:14 |
version 1.6, 2019/04/12 16:40:53 |
|
|
|
|
Here's a quick note on how to add new DocBook elements. |
Here's a quick note on how to add new DocBook elements. |
|
|
First, look up the element in the DocBook reference. For element <foo>, this is usually: |
First, look up the element in the DocBook reference. |
|
For element <foo>, this is usually: |
|
|
http://docbook.org/tdg51/en/html/foo.html |
https://tdg.docbook.org/tdg/5.1/foo.html |
|
|
Add the alpha-ordered node (NODE_FOO) to extern.h. |
Some elements are no longer defined in DocBook 5. |
|
For these, you will have to look at 4.5 documentation instead: |
|
|
Next, add rules.c isparent() rule. This is the hard part. First, |
https://tdg.docbook.org/tdg/4.5/foo.html |
create a top-level switch statement for NODE_FOO. Create a white-list |
|
of switch cases beneath that corresponding to each "These elements |
|
contain foo": |
|
|
|
switch (parent) { |
|
case (NODE_BAR): |
|
case (NODE_BAZ): |
|
return(1); |
|
default: |
|
break; |
|
} |
|
return(0); |
|
|
|
Next, go through the "The following elements occur in foo" and add a |
Add one "struct alias" initializer to the aliases[] array in the |
"case (NODE_FOO)" to each of those elements' switches. |
file parse.c *or* one "struct nodeprop" initializer to the properties[] |
|
array in the file node.c, but not both. The first struct member is |
|
the name of the element as it appears in DocBook documents. |
|
There are several special cases: |
|
|
Now the hard work is finished! |
* If docbook2mdoc(1) never needs to produce any output for the |
|
element nor from any children it may have, specify NODE_DELETE. |
|
If, in addition, finding the element in an input document implies |
|
that the output from the document will likely be incomplete or |
|
otherwise significantly unsatisfactory, use NODE_DELETE_WARN |
|
instead. |
|
|
Next, add the name and whether it admits text to docbook2mdoc.c's |
* If docbook2mdoc(1) can treat the element as transparent, that |
"nodes" structure array. |
is, if removing the element and inserting its content in its |
|
place would not change the desired formatting, specify NODE_IGNORE. |
|
This does not exclude that in DocBook itself, syntactic requirements |
|
or semantic significance may be attached to the element. |
|
|
Finally, modify print_pnode() with your new entry. Use similar nodes as |
* If docbook2mdoc(1) can handle the element in exactly the same way |
a reference. (NOTE: if it's an inline like, say, NODE_EMPHASIS, then |
as another node that is already handled, reuse the "enum nodeid" |
remember to add the node to the postfix switch statement!) |
constant for the node that is already handled. This only requires |
|
identitical handling by docbook2mdoc(1), even when syntax or |
|
semantics differ in DocBook itself. For example: |
|
{ "chapter", NODE_SECTION }, |
|
{ "part", NODE_SECTION }, |
|
{ "refsect1", NODE_SECTION }, |
|
{ "refsect2", NODE_SECTION }, |
|
/* ... */ |
|
{ "section", NODE_SECTION }, |
|
|
|
* Otherwise - that is, when the formatter needs to make at least |
|
one explicit formatting decision based on the presence, absence, |
|
or content of the element - add an enum constant for the new |
|
node to the declaration of "enum nodeid" in the file node.h. |
|
Use properties[] in node.c and preserve the alphabetic ordering. |
|
Add such a constant if only if the code will use it at least at |
|
one place. |
|
|
|
|
|
In the latter case, implement formatting in the file docbook2mdoc.c. |
|
Decide how the new node needs to be handled in the first, bigger |
|
switch statement of the function pnode_print(). Typical cases |
|
include: |
|
|
|
* Nodes to be represented by in-line macros that are parsed and |
|
callable often get away with merely opening a macro scope |
|
with macro_open(), letting the subsequent loop take care of |
|
any children. |
|
|
|
* Nodes to be represented by one single stand-alone macro sometimes |
|
get away with calling macro_line(), or macro_nodeline() if an |
|
argument is required. |
|
|
|
* Nodes with complex formatting requirements call their own, |
|
dedicated pnode_print*() formatting functions. |
|
These functions are ordered roughly as follows: |
|
1. paragraphs |
|
2. sections |
|
3. functions and mathematics |
|
4. semantic markup for command line utilities |
|
5. various semantic markup |
|
6. structural markup like lists and tables |
|
Such functions often contain their own loops over children and |
|
remove the children with pnode_unlinksub() at the end. But in |
|
some cases, it is alternatively possible to let the common loop |
|
in the middle of pnode_print() handle the children. |
|
|
|
|
|
Always keep the distinction between the two main ways to handle |
|
children in mind: by default and by the common loop in the middle |
|
of pnode_print(), children are formatted recursively with pnode_print(), |
|
potentially resulting in complex, nested formatting. By contrast, |
|
children can be reduced to just one string containing their their |
|
bare text content, ignoring any further markup that may be contained |
|
inside, by calling macro_addnode(), macro_nodeline(), or print_textnode(). |