]>
git.proxmox.com Git - mirror_ovs.git/blob - python/build/nroff.py
1 # Copyright (c) 2010, 2011, 2012, 2015 Nicira, Inc.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
18 from ovs
.db
import error
21 def text_to_nroff(s
, font
=r
'\fR'):
25 # In Roman type, let -- in XML be \- in nroff. That gives us a way to
26 # write minus signs, which is important in some places in manpages.
28 # Bold in nroff usually represents literal text, where there's no
29 # distinction between hyphens and minus sign. The convention in nroff
30 # appears to be to use a minus sign in such cases, so we follow that
33 # Finally, we always output - as a minus sign when it is followed by a
36 if c
== '--' and font
== r
'\fR':
38 if c
!= '-' or font
in (r
'\fB', r
'\fL'):
39 return c
.replace('-', r
'\-')
50 # groff(7) says that . can be escaped by \. but in practice groff
51 # still gives an error with \. at the beginning of a line.
54 raise error
.Error("bad escape")
56 # Escape - \ " ' . as needed by nroff.
57 s
= re
.sub('(-[0-9]|--|[-"\'\\\\.])', escape
, s
)
61 def escape_nroff_literal(s
, font
=r
'\fB'):
62 return font
+ r
'%s\fR' % text_to_nroff(s
, font
)
65 def inline_xml_to_nroff(node
, font
, to_upper
=False, newline
='\n'):
66 if node
.nodeType
== node
.TEXT_NODE
:
68 s
= text_to_nroff(node
.data
.upper(), font
)
70 s
= text_to_nroff(node
.data
, font
)
71 return s
.replace('\n', newline
)
72 elif node
.nodeType
== node
.ELEMENT_NODE
:
73 if node
.tagName
in ['code', 'em', 'option', 'env', 'b']:
75 for child
in node
.childNodes
:
76 s
+= inline_xml_to_nroff(child
, r
'\fB', to_upper
, newline
)
78 elif node
.tagName
== 'ref':
80 if node
.hasAttribute('column'):
81 s
+= node
.attributes
['column'].nodeValue
82 if node
.hasAttribute('key'):
83 s
+= ':' + node
.attributes
['key'].nodeValue
84 elif node
.hasAttribute('table'):
85 s
+= node
.attributes
['table'].nodeValue
86 elif node
.hasAttribute('group'):
87 s
+= node
.attributes
['group'].nodeValue
88 elif node
.hasAttribute('db'):
89 s
+= node
.attributes
['db'].nodeValue
91 raise error
.Error("'ref' lacks required attributes: %s"
92 % node
.attributes
.keys())
94 elif node
.tagName
in ['var', 'dfn', 'i']:
96 for child
in node
.childNodes
:
97 s
+= inline_xml_to_nroff(child
, r
'\fI', to_upper
, newline
)
100 raise error
.Error("element <%s> unknown or invalid here"
102 elif node
.nodeType
== node
.COMMENT_NODE
:
105 raise error
.Error("unknown node %s in inline xml" % node
)
108 def pre_to_nroff(nodes
, para
, font
):
109 # This puts 'font' at the beginning of each line so that leading and
110 # trailing whitespace stripping later doesn't removed leading spaces
111 # from preformatted text.
112 s
= para
+ '\n.nf\n' + font
114 s
+= inline_xml_to_nroff(node
, font
, False, '\n.br\n' + font
)
120 sys
.stderr
.write('%s\n' % msg
)
124 def diagram_header_to_nroff(header_node
):
127 for node
in header_node
.childNodes
:
128 if node
.nodeType
== node
.ELEMENT_NODE
and node
.tagName
== 'bits':
129 name
= node
.attributes
['name'].nodeValue
130 width
= node
.attributes
['width'].nodeValue
131 above
= node
.getAttribute('above')
132 below
= node
.getAttribute('below')
133 fill
= node
.getAttribute('fill')
134 header_fields
+= [{"name": name
,
141 elif node
.nodeType
== node
.COMMENT_NODE
:
143 elif node
.nodeType
== node
.TEXT_NODE
and node
.data
.isspace():
146 fatal("unknown node %s in diagram <header> element" % node
)
149 for f
in header_fields
:
150 pic_s
+= " %s: box \"%s\" width %s" % (f
['tag'], f
['name'],
152 if f
['fill'] == 'yes':
155 for f
in header_fields
:
156 pic_s
+= " \"%s\" at %s.n above\n" % (f
['above'], f
['tag'])
157 pic_s
+= " \"%s\" at %s.s below\n" % (f
['below'], f
['tag'])
158 name
= header_node
.getAttribute('name')
163 pic_s
+= "line <->%s \"%s\" above " % (visible
, name
)
164 pic_s
+= "from %s.nw + (0,textht) " % header_fields
[0]['tag']
165 pic_s
+= "to %s.ne + (0,textht)\n" % header_fields
[-1]['tag']
168 for f
in header_fields
:
169 text_s
+= """.IP \\(bu
170 %s bits""" % (f
['above'])
172 text_s
+= ": %s" % f
['name']
174 text_s
+= " (%s)" % f
['below']
179 def diagram_to_nroff(nodes
, para
):
184 if node
.nodeType
== node
.ELEMENT_NODE
and node
.tagName
== 'header':
188 pic_header
, text_header
= diagram_header_to_nroff(node
)
189 pic_s
+= "[\n" + pic_header
+ "]\n"
190 text_s
+= text_header
192 elif node
.nodeType
== node
.ELEMENT_NODE
and node
.tagName
== 'nospace':
194 elif node
.nodeType
== node
.ELEMENT_NODE
and node
.tagName
== 'dots':
196 pic_s
+= '". . ." ljust\n'
198 elif node
.nodeType
== node
.COMMENT_NODE
:
200 elif node
.nodeType
== node
.TEXT_NODE
and node
.data
.isspace():
203 fatal("unknown node %s in diagram <header> element" % node
)
205 .\\" check if in troff mode (TTY)
214 .\\" check if in nroff mode:
222 def block_xml_to_nroff(nodes
, para
='.PP'):
225 if node
.nodeType
== node
.TEXT_NODE
:
226 s
+= text_to_nroff(node
.data
)
228 elif node
.nodeType
== node
.ELEMENT_NODE
:
229 if node
.tagName
in ['ul', 'ol']:
234 for li_node
in node
.childNodes
:
235 if (li_node
.nodeType
== node
.ELEMENT_NODE
236 and li_node
.tagName
== 'li'):
238 if node
.tagName
== 'ul':
241 s
+= ".IP %d. .25in\n" % i
242 s
+= block_xml_to_nroff(li_node
.childNodes
, ".IP")
243 elif li_node
.nodeType
== node
.COMMENT_NODE
:
245 elif (li_node
.nodeType
!= node
.TEXT_NODE
246 or not li_node
.data
.isspace()):
247 raise error
.Error("<%s> element may only have "
248 "<li> children" % node
.tagName
)
250 elif node
.tagName
== 'dl':
255 for li_node
in node
.childNodes
:
256 if (li_node
.nodeType
== node
.ELEMENT_NODE
257 and li_node
.tagName
== 'dt'):
263 elif (li_node
.nodeType
== node
.ELEMENT_NODE
264 and li_node
.tagName
== 'dd'):
268 elif li_node
.nodeType
== node
.COMMENT_NODE
:
270 elif (li_node
.nodeType
!= node
.TEXT_NODE
271 or not li_node
.data
.isspace()):
272 raise error
.Error("<dl> element may only have "
273 "<dt> and <dd> children")
274 s
+= block_xml_to_nroff(li_node
.childNodes
, ".IP")
276 elif node
.tagName
== 'p':
278 if not s
.endswith("\n"):
281 s
+= block_xml_to_nroff(node
.childNodes
, para
)
282 elif node
.tagName
in ('h1', 'h2', 'h3'):
284 if not s
.endswith("\n"):
286 nroffTag
= {'h1': 'SH', 'h2': 'SS', 'h3': 'ST'}[node
.tagName
]
287 s
+= '.%s "' % nroffTag
288 for child_node
in node
.childNodes
:
289 s
+= inline_xml_to_nroff(child_node
, r
'\fR',
290 to_upper
=(nroffTag
== 'SH'))
292 elif node
.tagName
== 'pre':
293 fixed
= node
.getAttribute('fixed')
298 s
+= pre_to_nroff(node
.childNodes
, para
, font
)
299 elif node
.tagName
== 'diagram':
300 s
+= diagram_to_nroff(node
.childNodes
, para
)
302 s
+= inline_xml_to_nroff(node
, r
'\fR')
303 elif node
.nodeType
== node
.COMMENT_NODE
:
306 raise error
.Error("unknown node %s in block xml" % node
)
307 if s
!= "" and not s
.endswith('\n'):