3
# Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at:
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
3
17
from datetime import date
8
21
import xml.dom.minidom
11
24
from ovs.db import error
12
25
import ovs.db.schema
27
from build.nroff import *
14
29
argv0 = sys.argv[0]
16
def textToNroff(s, font=r'\fR'):
20
if c != '-' or font == r'\fB':
31
raise error.Error("bad escape")
33
# Escape - \ " ' as needed by nroff.
34
s = re.sub('(-[0-9]|[-"\'\\\\])', escape, s)
39
def escapeNroffLiteral(s):
40
return r'\fB%s\fR' % textToNroff(s, r'\fB')
42
def inlineXmlToNroff(node, font):
43
if node.nodeType == node.TEXT_NODE:
44
return textToNroff(node.data, font)
45
elif node.nodeType == node.ELEMENT_NODE:
46
if node.tagName in ['code', 'em', 'option']:
48
for child in node.childNodes:
49
s += inlineXmlToNroff(child, r'\fB')
51
elif node.tagName == 'ref':
53
if node.hasAttribute('column'):
54
s += node.attributes['column'].nodeValue
55
if node.hasAttribute('key'):
56
s += ':' + node.attributes['key'].nodeValue
57
elif node.hasAttribute('table'):
58
s += node.attributes['table'].nodeValue
59
elif node.hasAttribute('group'):
60
s += node.attributes['group'].nodeValue
62
raise error.Error("'ref' lacks required attributes: %s" % node.attributes.keys())
64
elif node.tagName == 'var':
66
for child in node.childNodes:
67
s += inlineXmlToNroff(child, r'\fI')
70
raise error.Error("element <%s> unknown or invalid here" % node.tagName)
72
raise error.Error("unknown node %s in inline xml" % node)
74
def blockXmlToNroff(nodes, para='.PP'):
77
if node.nodeType == node.TEXT_NODE:
78
s += textToNroff(node.data)
80
elif node.nodeType == node.ELEMENT_NODE:
81
if node.tagName in ['ul', 'ol']:
86
for liNode in node.childNodes:
87
if (liNode.nodeType == node.ELEMENT_NODE
88
and liNode.tagName == 'li'):
90
if node.tagName == 'ul':
93
s += ".IP %d. .25in\n" % i
94
s += blockXmlToNroff(liNode.childNodes, ".IP")
95
elif (liNode.nodeType != node.TEXT_NODE
96
or not liNode.data.isspace()):
97
raise error.Error("<%s> element may only have <li> children" % node.tagName)
99
elif node.tagName == 'dl':
104
for liNode in node.childNodes:
105
if (liNode.nodeType == node.ELEMENT_NODE
106
and liNode.tagName == 'dt'):
112
elif (liNode.nodeType == node.ELEMENT_NODE
113
and liNode.tagName == 'dd'):
117
elif (liNode.nodeType != node.TEXT_NODE
118
or not liNode.data.isspace()):
119
raise error.Error("<dl> element may only have <dt> and <dd> children")
120
s += blockXmlToNroff(liNode.childNodes, ".IP")
122
elif node.tagName == 'p':
124
if not s.endswith("\n"):
127
s += blockXmlToNroff(node.childNodes, para)
128
elif node.tagName in ('h1', 'h2', 'h3'):
130
if not s.endswith("\n"):
132
nroffTag = {'h1': 'SH', 'h2': 'SS', 'h3': 'ST'}[node.tagName]
133
s += ".%s " % nroffTag
134
for child_node in node.childNodes:
135
s += inlineXmlToNroff(child_node, r'\fR')
138
s += inlineXmlToNroff(node, r'\fR')
140
raise error.Error("unknown node %s in block xml" % node)
141
if s != "" and not s.endswith('\n'):
145
31
def typeAndConstraintsToNroff(column):
146
32
type = column.type.toEnglish(escapeNroffLiteral)
147
33
constraints = column.type.constraintsToEnglish(escapeNroffLiteral,
219
106
summary += [('column', nameNroff, typeNroff)]
220
107
elif node.tagName == 'group':
221
108
title = node.attributes["title"].nodeValue
222
subSummary, subIntro, subBody = columnGroupToNroff(table, node)
109
subSummary, subIntro, subBody = columnGroupToNroff(
110
table, node, documented_columns)
223
111
summary += [('group', title, subSummary)]
224
112
body += '.ST "%s:"\n' % textToNroff(title)
225
113
body += subIntro + subBody
242
130
tableName = tableXml.attributes['name'].nodeValue
243
131
table = schema.tables[tableName]
133
documented_columns = set()
248
summary, intro, body = columnGroupToNroff(table, tableXml)
137
summary, intro, body = columnGroupToNroff(table, tableXml,
250
140
s += '.SS "Summary:\n'
251
141
s += tableSummaryToNroff(summary)
252
142
s += '.SS "Details:\n'
145
schema_columns = set(table.columns.keys())
146
undocumented_columns = schema_columns - documented_columns
147
for column in undocumented_columns:
148
raise error.Error("table %s has undocumented column %s"
149
% (tableName, column))
256
def docsToNroff(schemaFile, xmlFile, erFile, title=None, version=None):
153
def docsToNroff(schemaFile, xmlFile, erFile, version=None):
257
154
schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schemaFile))
258
155
doc = xml.dom.minidom.parse(xmlFile).documentElement