]>
Commit | Line | Data |
---|---|---|
c12bc4de RD |
1 | ############################################################################## |
2 | # | |
3 | # Zope Public License (ZPL) Version 1.0 | |
4 | # ------------------------------------- | |
5 | # | |
6 | # Copyright (c) Digital Creations. All rights reserved. | |
7 | # | |
8 | # This license has been certified as Open Source(tm). | |
9 | # | |
10 | # Redistribution and use in source and binary forms, with or without | |
11 | # modification, are permitted provided that the following conditions are | |
12 | # met: | |
13 | # | |
14 | # 1. Redistributions in source code must retain the above copyright | |
15 | # notice, this list of conditions, and the following disclaimer. | |
16 | # | |
17 | # 2. Redistributions in binary form must reproduce the above copyright | |
18 | # notice, this list of conditions, and the following disclaimer in | |
19 | # the documentation and/or other materials provided with the | |
20 | # distribution. | |
21 | # | |
22 | # 3. Digital Creations requests that attribution be given to Zope | |
23 | # in any manner possible. Zope includes a "Powered by Zope" | |
24 | # button that is installed by default. While it is not a license | |
25 | # violation to remove this button, it is requested that the | |
26 | # attribution remain. A significant investment has been put | |
27 | # into Zope, and this effort will continue if the Zope community | |
28 | # continues to grow. This is one way to assure that growth. | |
29 | # | |
30 | # 4. All advertising materials and documentation mentioning | |
31 | # features derived from or use of this software must display | |
32 | # the following acknowledgement: | |
33 | # | |
34 | # "This product includes software developed by Digital Creations | |
35 | # for use in the Z Object Publishing Environment | |
36 | # (http://www.zope.org/)." | |
37 | # | |
38 | # In the event that the product being advertised includes an | |
39 | # intact Zope distribution (with copyright and license included) | |
40 | # then this clause is waived. | |
41 | # | |
42 | # 5. Names associated with Zope or Digital Creations must not be used to | |
43 | # endorse or promote products derived from this software without | |
44 | # prior written permission from Digital Creations. | |
45 | # | |
46 | # 6. Modified redistributions of any form whatsoever must retain | |
47 | # the following acknowledgment: | |
48 | # | |
49 | # "This product includes software developed by Digital Creations | |
50 | # for use in the Z Object Publishing Environment | |
51 | # (http://www.zope.org/)." | |
52 | # | |
53 | # Intact (re-)distributions of any official Zope release do not | |
54 | # require an external acknowledgement. | |
55 | # | |
56 | # 7. Modifications are encouraged but must be packaged separately as | |
57 | # patches to official Zope releases. Distributions that do not | |
58 | # clearly separate the patches from the original work must be clearly | |
59 | # labeled as unofficial distributions. Modifications which do not | |
60 | # carry the name Zope may be packaged in any form, as long as they | |
61 | # conform to all of the clauses above. | |
62 | # | |
63 | # | |
64 | # Disclaimer | |
65 | # | |
66 | # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY | |
67 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
68 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
69 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS | |
70 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
71 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
72 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
73 | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
74 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
75 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
76 | # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
77 | # SUCH DAMAGE. | |
78 | # | |
79 | # | |
80 | # This software consists of contributions made by Digital Creations and | |
81 | # many individuals on behalf of Digital Creations. Specific | |
82 | # attributions are listed in the accompanying credits file. | |
83 | # | |
84 | ############################################################################## | |
85 | ||
86 | import string | |
87 | from string import join, split, find, lstrip | |
88 | ||
89 | class DocBookClass: | |
90 | ||
91 | element_types={ | |
92 | '#text': '_text', | |
93 | 'StructuredTextDocument': 'document', | |
94 | 'StructuredTextParagraph': 'paragraph', | |
95 | 'StructuredTextExample': 'example', | |
96 | 'StructuredTextBullet': 'bullet', | |
97 | 'StructuredTextNumbered': 'numbered', | |
98 | 'StructuredTextDescription': 'description', | |
99 | 'StructuredTextDescriptionTitle': 'descriptionTitle', | |
100 | 'StructuredTextDescriptionBody': 'descriptionBody', | |
101 | 'StructuredTextSection': 'section', | |
102 | 'StructuredTextSectionTitle': 'sectionTitle', | |
103 | 'StructuredTextLiteral': 'literal', | |
104 | 'StructuredTextEmphasis': 'emphasis', | |
105 | 'StructuredTextStrong': 'strong', | |
106 | 'StructuredTextLink': 'link', | |
107 | 'StructuredTextXref': 'xref', | |
108 | } | |
109 | ||
110 | def dispatch(self, doc, level, output): | |
111 | getattr(self, self.element_types[doc.getNodeName()])(doc, level, output) | |
112 | ||
113 | def __call__(self, doc, level=1): | |
114 | r=[] | |
115 | self.dispatch(doc, level-1, r.append) | |
116 | return join(r,'') | |
117 | ||
118 | def _text(self, doc, level, output): | |
119 | if doc.getNodeName() == 'StructuredTextLiteral': | |
120 | output(doc.getNodeValue()) | |
121 | else: | |
122 | output(lstrip(doc.getNodeValue())) | |
123 | ||
124 | def document(self, doc, level, output): | |
125 | output('<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">\n') | |
126 | output('<book>\n') | |
127 | children=doc.getChildNodes() | |
128 | if (children and | |
129 | children[0].getNodeName() == 'StructuredTextSection'): | |
130 | output('<title>%s</title>' % children[0].getChildNodes()[0].getNodeValue()) | |
131 | for c in children: | |
132 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
133 | output('</book>\n') | |
134 | ||
135 | def section(self, doc, level, output): | |
136 | output('\n<sect%s>\n' % (level + 1)) | |
137 | children=doc.getChildNodes() | |
138 | for c in children: | |
139 | getattr(self, self.element_types[c.getNodeName()])(c, level+1, output) | |
140 | output('\n</sect%s>\n' % (level + 1)) | |
141 | ||
142 | def sectionTitle(self, doc, level, output): | |
143 | output('<title>') | |
144 | for c in doc.getChildNodes(): | |
145 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
146 | output('</title>\n') | |
147 | ||
148 | def description(self, doc, level, output): | |
149 | p=doc.getPreviousSibling() | |
150 | if p is None or p.getNodeName() is not doc.getNodeName(): | |
151 | output('<variablelist>\n') | |
152 | for c in doc.getChildNodes(): | |
153 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
154 | n=doc.getNextSibling() | |
155 | if n is None or n.getNodeName() is not doc.getNodeName(): | |
156 | output('</variablelist>\n') | |
157 | ||
158 | def descriptionTitle(self, doc, level, output): | |
159 | output('<varlistentry><term>\n') | |
160 | for c in doc.getChildNodes(): | |
161 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
162 | output('</term>\n') | |
163 | ||
164 | def descriptionBody(self, doc, level, output): | |
165 | output('<listitem><para>\n') | |
166 | for c in doc.getChildNodes(): | |
167 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
168 | output('</para></listitem>\n') | |
169 | output('</varlistentry>\n') | |
170 | ||
171 | def bullet(self, doc, level, output): | |
172 | p=doc.getPreviousSibling() | |
173 | if p is None or p.getNodeName() is not doc.getNodeName(): | |
174 | output('<itemizedlist>\n') | |
175 | output('<listitem><para>\n') | |
176 | ||
177 | for c in doc.getChildNodes(): | |
178 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
179 | n=doc.getNextSibling() | |
180 | output('</para></listitem>\n') | |
181 | if n is None or n.getNodeName() is not doc.getNodeName(): | |
182 | output('</itemizedlist>\n') | |
183 | ||
184 | def numbered(self, doc, level, output): | |
185 | p=doc.getPreviousSibling() | |
186 | if p is None or p.getNodeName() is not doc.getNodeName(): | |
187 | output('<orderedlist>\n') | |
188 | output('<listitem><para>\n') | |
189 | for c in doc.getChildNodes(): | |
190 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
191 | n=doc.getNextSibling() | |
192 | output('</para></listitem>\n') | |
193 | if n is None or n.getNodeName() is not doc.getNodeName(): | |
194 | output('</orderedlist>\n') | |
195 | ||
196 | def example(self, doc, level, output): | |
197 | i=0 | |
198 | for c in doc.getChildNodes(): | |
199 | if i==0: | |
200 | output('<programlisting>\n<![CDATA[\n') | |
201 | ## | |
202 | ## eek. A ']]>' in your body will break this... | |
203 | ## | |
204 | output(prestrip(c.getNodeValue())) | |
205 | output('\n]]></programlisting>\n') | |
206 | else: | |
207 | getattr(self, self.element_types[c.getNodeName()])( | |
208 | c, level, output) | |
209 | ||
210 | def paragraph(self, doc, level, output): | |
211 | ||
212 | output('<para>\n\n') | |
213 | for c in doc.getChildNodes(): | |
214 | getattr(self, self.element_types[c.getNodeName()])( | |
215 | c, level, output) | |
216 | output('</para>\n\n') | |
217 | ||
218 | def link(self, doc, level, output): | |
219 | # output('<link linkend="%s">' % doc.href) | |
220 | for c in doc.getChildNodes(): | |
221 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
222 | # output('</link>') | |
223 | ||
224 | def emphasis(self, doc, level, output): | |
225 | output('<emphasis>') | |
226 | for c in doc.getChildNodes(): | |
227 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
228 | output('</emphasis> ') | |
229 | ||
230 | def literal(self, doc, level, output): | |
231 | output('<literal>') | |
232 | for c in doc.getChildNodes(): | |
233 | output(c.getNodeValue()) | |
234 | output('</literal>') | |
235 | ||
236 | def strong(self, doc, level, output): | |
237 | output('<emphasis>') | |
238 | for c in doc.getChildNodes(): | |
239 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
240 | output('</emphasis>') | |
241 | ||
242 | def xref(self, doc, level, output): | |
243 | output('<xref linkend="%s">' % doc.getNodeValue()) | |
244 | ||
245 | def prestrip(v): | |
246 | v=string.replace(v, '\r\n', '\n') | |
247 | v=string.replace(v, '\r', '\n') | |
248 | v=string.replace(v, '\t', ' ') | |
249 | lines=string.split(v, '\n') | |
250 | indent=len(lines[0]) | |
251 | for line in lines: | |
252 | if not len(line): continue | |
253 | i=len(line)-len(string.lstrip(line)) | |
254 | if i < indent: | |
255 | indent=i | |
256 | nlines=[] | |
257 | for line in lines: | |
258 | nlines.append(line[indent:]) | |
259 | return string.join(nlines, '\r\n') | |
260 | ||
261 | ||
262 | class DocBookChapter(DocBookClass): | |
263 | ||
264 | def document(self, doc, level, output): | |
265 | output('<chapter>\n') | |
266 | children=doc.getChildNodes() | |
267 | if (children and | |
268 | children[0].getNodeName() == 'StructuredTextSection'): | |
269 | output('<title>%s</title>' % children[0].getChildNodes()[0].getNodeValue()) | |
270 | for c in children[0].getChildNodes()[1:]: | |
271 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
272 | output('</chapter>\n') | |
273 | ||
274 | ets = DocBookClass.element_types | |
275 | ets.update({'StructuredTextImage': 'image'}) | |
276 | ||
277 | class DocBookChapterWithFigures(DocBookChapter): | |
278 | ||
279 | element_types = ets | |
280 | ||
281 | def image(self, doc, level, output): | |
282 | if hasattr(doc, 'key'): | |
283 | output('<figure id="%s"><title>%s</title>\n' % (doc.key, doc.getNodeValue()) ) | |
284 | else: | |
285 | output('<figure><title>%s</title>\n' % doc.getNodeValue()) | |
286 | ## for c in doc.getChildNodes(): | |
287 | ## getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
288 | output('<graphic fileref="%s"></graphic>\n</figure>\n' % doc.href) | |
289 | ||
290 | class DocBookArticle(DocBookClass): | |
291 | ||
292 | def document(self, doc, level, output): | |
293 | output('<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">\n') | |
294 | output('<article>\n') | |
295 | children=doc.getChildNodes() | |
296 | if (children and | |
297 | children[0].getNodeName() == 'StructuredTextSection'): | |
298 | output('<artheader>\n<title>%s</title>\n</artheader>\n' % | |
299 | children[0].getChildNodes()[0].getNodeValue()) | |
300 | for c in children: | |
301 | getattr(self, self.element_types[c.getNodeName()])(c, level, output) | |
302 | output('</article>\n') | |
303 | ||
304 | ||
305 | class DocBookBook: | |
306 | ||
307 | def __init__(self, title=''): | |
308 | self.title = title | |
309 | self.chapters = [] | |
310 | ||
311 | def addChapter(self, chapter): | |
312 | self.chapters.append(chapter) | |
313 | ||
314 | def read(self): | |
315 | out = '<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">\n<book>\n' | |
316 | out = out + '<title>%s</title>\n' % self.title | |
317 | for chapter in self.chapters: | |
318 | out = out + chapter + '\n</book>\n' | |
319 | ||
320 | return out | |
321 | ||
322 | def __str__(self): | |
323 | return self.read() | |
324 | ||
325 |