Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: third_party/twisted_8_1/twisted/lore/tree.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5 import re, os, cStringIO, time, cgi, string, urlparse
6 from twisted import copyright
7 from twisted.python import htmlizer, text
8 from twisted.web import microdom, domhelpers
9 import process, latex, indexer, numberer, htmlbook
10 from twisted.python.util import InsensitiveDict
11
12 # relative links to html files
13 def fixLinks(document, ext):
14 """
15 Rewrite links to XHTML lore input documents so they point to lore XHTML
16 output documents.
17
18 Any node with an C{href} attribute which does not contain a value starting
19 with C{http}, C{https}, C{ftp}, or C{mailto} and which does not have a
20 C{class} attribute of C{absolute} or which contains C{listing} and which
21 does point to an URL ending with C{html} will have that attribute value
22 rewritten so that the filename extension is C{ext} instead of C{html}.
23
24 @type document: A DOM Node or Document
25 @param document: The input document which contains all of the content to be
26 presented.
27
28 @type ext: C{str}
29 @param ext: The extension to use when selecting an output file name. This
30 replaces the extension of the input file name.
31
32 @return: C{None}
33 """
34 supported_schemes=['http', 'https', 'ftp', 'mailto']
35 for node in domhelpers.findElementsWithAttribute(document, 'href'):
36 href = node.getAttribute("href")
37 if urlparse.urlparse(href)[0] in supported_schemes:
38 continue
39 if node.getAttribute("class", "") == "absolute":
40 continue
41 if node.getAttribute("class", "").find('listing') != -1:
42 continue
43
44 # This is a relative link, so it should be munged.
45 if href.endswith('html') or href[:href.rfind('#')].endswith('html'):
46 fname, fext = os.path.splitext(href)
47 if '#' in fext:
48 fext = ext+'#'+fext.split('#', 1)[1]
49 else:
50 fext = ext
51 node.setAttribute("href", fname + fext)
52
53
54
55 def addMtime(document, fullpath):
56 """
57 Set the last modified time of the given document.
58
59 @type document: A DOM Node or Document
60 @param document: The output template which defines the presentation of the
61 last modified time.
62
63 @type fullpath: C{str}
64 @param fullpath: The file name from which to take the last modified time.
65
66 @return: C{None}
67 """
68 for node in domhelpers.findElementsWithAttribute(document, "class","mtime"):
69 node.appendChild(microdom.Text(time.ctime(os.path.getmtime(fullpath))))
70
71
72
73 def _getAPI(node):
74 """
75 Retrieve the fully qualified Python name represented by the given node.
76
77 The name is represented by one or two aspects of the node: the value of the
78 node's first child forms the end of the name. If the node has a C{base}
79 attribute, that attribute's value is prepended to the node's value, with
80 C{.} separating the two parts.
81
82 @rtype: C{str}
83 @return: The fully qualified Python name.
84 """
85 base = ""
86 if node.hasAttribute("base"):
87 base = node.getAttribute("base") + "."
88 return base+node.childNodes[0].nodeValue
89
90
91
92 def fixAPI(document, url):
93 """
94 Replace API references with links to API documentation.
95
96 @type document: A DOM Node or Document
97 @param document: The input document which contains all of the content to be
98 presented.
99
100 @type url: C{str}
101 @param url: A string which will be interpolated with the fully qualified
102 Python name of any API reference encountered in the input document, the
103 result of which will be used as a link to API documentation for that name
104 in the output document.
105
106 @return: C{None}
107 """
108 # API references
109 for node in domhelpers.findElementsWithAttribute(document, "class", "API"):
110 fullname = _getAPI(node)
111 node2 = microdom.Element('a', {'href': url%fullname, 'title': fullname})
112 node2.childNodes = node.childNodes
113 node.childNodes = [node2]
114 node.removeAttribute('base')
115
116
117
118 def fontifyPython(document):
119 """
120 Syntax color any node in the given document which contains a Python source
121 listing.
122
123 @type document: A DOM Node or Document
124 @param document: The input document which contains all of the content to be
125 presented.
126
127 @return: C{None}
128 """
129 def matcher(node):
130 return (node.nodeName == 'pre' and node.hasAttribute('class') and
131 node.getAttribute('class') == 'python')
132 for node in domhelpers.findElements(document, matcher):
133 fontifyPythonNode(node)
134
135
136
137 def fontifyPythonNode(node):
138 """
139 Syntax color the given node containing Python source code.
140
141 @return: C{None}
142 """
143 oldio = cStringIO.StringIO()
144 latex.getLatexText(node, oldio.write,
145 entities={'lt': '<', 'gt': '>', 'amp': '&'})
146 oldio = cStringIO.StringIO(oldio.getvalue().strip()+'\n')
147 newio = cStringIO.StringIO()
148 htmlizer.filter(oldio, newio, writer=htmlizer.SmallerHTMLWriter)
149 newio.seek(0)
150 newel = microdom.parse(newio).documentElement
151 newel.setAttribute("class", "python")
152 node.parentNode.replaceChild(newel, node)
153
154
155
156 def addPyListings(document, dir):
157 """
158 Insert Python source listings into the given document from files in the
159 given directory based on C{py-listing} nodes.
160
161 Any node in C{document} with a C{class} attribute set to C{py-listing} will
162 have source lines taken from the file named in that node's C{href}
163 attribute (searched for in C{dir}) inserted in place of that node.
164
165 If a node has a C{skipLines} attribute, its value will be parsed as an
166 integer and that many lines will be skipped at the beginning of the source
167 file.
168
169 @type document: A DOM Node or Document
170 @param document: The document within which to make listing replacements.
171
172 @type dir: C{str}
173 @param dir: The directory in which to find source files containing the
174 referenced Python listings.
175
176 @return: C{None}
177 """
178 for node in domhelpers.findElementsWithAttribute(document, "class",
179 "py-listing"):
180 filename = node.getAttribute("href")
181 outfile = cStringIO.StringIO()
182 lines = map(string.rstrip, open(os.path.join(dir, filename)).readlines() )
183 data = '\n'.join(lines[int(node.getAttribute('skipLines', 0)):])
184 data = cStringIO.StringIO(text.removeLeadingTrailingBlanks(data))
185 htmlizer.filter(data, outfile, writer=htmlizer.SmallerHTMLWriter)
186 val = outfile.getvalue()
187 _replaceWithListing(node, val, filename, "py-listing")
188
189
190
191 def _replaceWithListing(node, val, filename, class_):
192 captionTitle = domhelpers.getNodeText(node)
193 if captionTitle == os.path.basename(filename):
194 captionTitle = 'Source listing'
195 text = ('<div class="%s">%s<div class="caption">%s - '
196 '<a href="%s"><span class="filename">%s</span></a></div></div>' %
197 (class_, val, captionTitle, filename, filename))
198 newnode = microdom.parseString(text).documentElement
199 node.parentNode.replaceChild(newnode, node)
200
201
202
203 def addHTMLListings(document, dir):
204 """
205 Insert HTML source listings into the given document from files in the given
206 directory based on C{html-listing} nodes.
207
208 Any node in C{document} with a C{class} attribute set to C{html-listing}
209 will have source lines taken from the file named in that node's C{href}
210 attribute (searched for in C{dir}) inserted in place of that node.
211
212 @type document: A DOM Node or Document
213 @param document: The document within which to make listing replacements.
214
215 @type dir: C{str}
216 @param dir: The directory in which to find source files containing the
217 referenced HTML listings.
218
219 @return: C{None}
220 """
221 for node in domhelpers.findElementsWithAttribute(document, "class",
222 "html-listing"):
223 filename = node.getAttribute("href")
224 val = ('<pre class="htmlsource">\n%s</pre>' %
225 cgi.escape(open(os.path.join(dir, filename)).read()))
226 _replaceWithListing(node, val, filename, "html-listing")
227
228
229
230 def addPlainListings(document, dir):
231 """
232 Insert text listings into the given document from files in the given
233 directory based on C{listing} nodes.
234
235 Any node in C{document} with a C{class} attribute set to C{listing} will
236 have source lines taken from the file named in that node's C{href}
237 attribute (searched for in C{dir}) inserted in place of that node.
238
239 @type document: A DOM Node or Document
240 @param document: The document within which to make listing replacements.
241
242 @type dir: C{str}
243 @param dir: The directory in which to find source files containing the
244 referenced text listings.
245
246 @return: C{None}
247 """
248 for node in domhelpers.findElementsWithAttribute(document, "class",
249 "listing"):
250 filename = node.getAttribute("href")
251 val = ('<pre>\n%s</pre>' %
252 cgi.escape(open(os.path.join(dir, filename)).read()))
253 _replaceWithListing(node, val, filename, "listing")
254
255
256
257 def getHeaders(document):
258 """
259 Return all H2 and H3 nodes in the given document.
260
261 @type document: A DOM Node or Document
262
263 @rtype: C{list}
264 """
265 return domhelpers.findElements(
266 document,
267 lambda n, m=re.compile('h[23]$').match: m(n.nodeName))
268
269
270
271 def generateToC(document):
272 """
273 Create a table of contents for the given document.
274
275 @type document: A DOM Node or Document
276
277 @rtype: A DOM Node
278 @return: a Node containing a table of contents based on the headers of the
279 given document.
280 """
281 toc, level, id = '\n<ol>\n', 0, 0
282 for element in getHeaders(document):
283 elementLevel = int(element.tagName[1])-2
284 toc += (level-elementLevel)*'</ul>\n'
285 toc += (elementLevel-level)*'<ul>'
286 toc += '<li><a href="#auto%d">' % id
287 toc += domhelpers.getNodeText(element)
288 toc += '</a></li>\n'
289 level = elementLevel
290 anchor = microdom.parseString('<a name="auto%d" />' % id).documentElemen t
291 element.childNodes.append(anchor)
292 id += 1
293 toc += '</ul>\n' * level
294 toc += '</ol>\n'
295 return microdom.parseString(toc).documentElement
296
297
298
299 def putInToC(document, toc):
300 """
301 Insert the given table of contents into the given document.
302
303 The node with C{class} attribute set to C{toc} has its children replaced
304 with C{toc}.
305
306 @type document: A DOM Node or Document
307 @type toc: A DOM Node
308 """
309 tocOrig = domhelpers.findElementsWithAttribute(document, 'class', 'toc')
310 if tocOrig:
311 tocOrig= tocOrig[0]
312 tocOrig.childNodes = [toc]
313
314
315
316 def removeH1(document):
317 """
318 Replace all C{h1} nodes in the given document with empty C{span} nodes.
319
320 C{h1} nodes mark up document sections and the output template is given an
321 opportunity to present this information in a different way.
322
323 @type document: A DOM Node or Document
324 @param document: The input document which contains all of the content to be
325 presented.
326
327 @return: C{None}
328 """
329 h1 = domhelpers.findNodesNamed(document, 'h1')
330 empty = microdom.Element('span')
331 for node in h1:
332 node.parentNode.replaceChild(empty, node)
333
334
335
336 def footnotes(document):
337 """
338 Find footnotes in the given document, move them to the end of the body, and
339 generate links to them.
340
341 A footnote is any node with a C{class} attribute set to C{footnote}.
342 Footnote links are generated as superscript. Footnotes are collected in a
343 C{ol} node at the end of the document.
344
345 @type document: A DOM Node or Document
346 @param document: The input document which contains all of the content to be
347 presented.
348
349 @return: C{None}
350 """
351 footnotes = domhelpers.findElementsWithAttribute(document, "class",
352 "footnote")
353 if not footnotes:
354 return
355 footnoteElement = microdom.Element('ol')
356 id = 1
357 for footnote in footnotes:
358 href = microdom.parseString('<a href="#footnote-%(id)d">'
359 '<super>%(id)d</super></a>'
360 % vars()).documentElement
361 text = ' '.join(domhelpers.getNodeText(footnote).split())
362 href.setAttribute('title', text)
363 target = microdom.Element('a', attributes={'name': 'footnote-%d' % id})
364 target.childNodes = [footnote]
365 footnoteContent = microdom.Element('li')
366 footnoteContent.childNodes = [target]
367 footnoteElement.childNodes.append(footnoteContent)
368 footnote.parentNode.replaceChild(href, footnote)
369 id += 1
370 body = domhelpers.findNodesNamed(document, "body")[0]
371 header = microdom.parseString('<h2>Footnotes</h2>').documentElement
372 body.childNodes.append(header)
373 body.childNodes.append(footnoteElement)
374
375
376
377 def notes(document):
378 """
379 Find notes in the given document and mark them up as such.
380
381 A note is any node with a C{class} attribute set to C{note}.
382
383 (I think this is a very stupid feature. When I found it I actually
384 exclaimed out loud. -exarkun)
385
386 @type document: A DOM Node or Document
387 @param document: The input document which contains all of the content to be
388 presented.
389
390 @return: C{None}
391 """
392 notes = domhelpers.findElementsWithAttribute(document, "class", "note")
393 notePrefix = microdom.parseString('<strong>Note: </strong>').documentElement
394 for note in notes:
395 note.childNodes.insert(0, notePrefix)
396
397
398
399 def compareMarkPos(a, b):
400 """
401 Perform in every way identically to L{cmp} for valid inputs.
402
403 XXX - replace this with L{cmp}
404 """
405 linecmp = cmp(a[0], b[0])
406 if linecmp:
407 return linecmp
408 return cmp(a[1], b[1])
409
410
411
412 def comparePosition(firstElement, secondElement):
413 """
414 Compare the two elements given by their position in the document or
415 documents they were parsed from.
416
417 @type firstElement: C{twisted.web.microdom.Element}
418 @type secondElement: C{twisted.web.microdom.Element}
419
420 @return: C{-1}, C{0}, or C{1}, with the same meanings as the return value
421 of L{cmp}.
422 """
423 return compareMarkPos(firstElement._markpos, secondElement._markpos)
424
425
426
427 def findNodeJustBefore(target, nodes):
428 """
429 Find the node in C{nodes} which appeared immediately before C{target} in
430 the input document.
431
432 @type target: L{twisted.web.microdom.Element}
433 @type nodes: C{list} of L{twisted.web.microdom.Element}
434 @return: An element from C{nodes}
435 """
436 result = None
437 for node in nodes:
438 if comparePosition(target, node) < 0:
439 return result
440 result = node
441 return result
442
443
444
445 def getFirstAncestorWithSectionHeader(entry):
446 """
447 Visit the ancestors of C{entry} until one with at least one C{h2} child
448 node is found, then return all of that node's C{h2} child nodes.
449
450 @type entry: A DOM Node
451 @param entry: The node from which to begin traversal. This node itself is
452 excluded from consideration.
453
454 @rtype: C{list} of DOM Nodes
455 @return: All C{h2} nodes of the ultimately selected parent node.
456 """
457 for a in domhelpers.getParents(entry)[1:]:
458 headers = domhelpers.findNodesNamed(a, "h2")
459 if len(headers) > 0:
460 return headers
461 return []
462
463
464
465 def getSectionNumber(header):
466 """
467 Retrieve the section number of the given node.
468
469 @type header: A DOM Node or L{None}
470 @param header: The section from which to extract a number. The section
471 number is the value of this node's first child.
472
473 @return: C{None} or a C{str} giving the section number.
474 """
475 if not header:
476 return None
477 return header.childNodes[0].value.strip()
478
479
480
481 def getSectionReference(entry):
482 """
483 Find the section number which contains the given node.
484
485 This function looks at the given node's ancestry until it finds a node
486 which defines a section, then returns that section's number.
487
488 @type entry: A DOM Node
489 @param entry: The node for which to determine the section.
490
491 @rtype: C{str}
492 @return: The section number, as returned by C{getSectionNumber} of the
493 first ancestor of C{entry} which defines a section, as determined by
494 L{getFirstAncestorWithSectionHeader}.
495 """
496 headers = getFirstAncestorWithSectionHeader(entry)
497 myHeader = findNodeJustBefore(entry, headers)
498 return getSectionNumber(myHeader)
499
500
501
502 def index(document, filename, chapterReference):
503 """
504 Extract index entries from the given document and store them for later use
505 and insert named anchors so that the index can link back to those entries.
506
507 Any node with a C{class} attribute set to C{index} is considered an index
508 entry.
509
510 @type document: A DOM Node or Document
511 @param document: The input document which contains all of the content to be
512 presented.
513
514 @type filename: C{str}
515 @param filename: A link to the output for the given document which will be
516 included in the index to link to any index entry found here.
517
518 @type chapterReference: ???
519 @param chapterReference: ???
520
521 @return: C{None}
522 """
523 entries = domhelpers.findElementsWithAttribute(document, "class", "index")
524 if not entries:
525 return
526 i = 0;
527 for entry in entries:
528 i += 1
529 anchor = 'index%02d' % i
530 if chapterReference:
531 ref = getSectionReference(entry) or chapterReference
532 else:
533 ref = 'link'
534 indexer.addEntry(filename, anchor, entry.attributes['value'], ref)
535 # does nodeName even affect anything?
536 entry.nodeName = entry.tagName = entry.endTagName = 'a'
537 entry.attributes = InsensitiveDict({'name': anchor})
538
539
540
541 def setIndexLink(template, indexFilename):
542 """
543 Insert a link to an index document.
544
545 Any node with a C{class} attribute set to C{index-link} will have its tag
546 name changed to C{a} and its C{href} attribute set to C{indexFilename}.
547
548 @type template: A DOM Node or Document
549 @param template: The output template which defines the presentation of the
550 version information.
551
552 @type indexFilename: C{str}
553 @param indexFilename: The address of the index document to which to link.
554 If any C{False} value, this function will remove all index-link nodes.
555
556 @return: C{None}
557 """
558 indexLinks = domhelpers.findElementsWithAttribute(template,
559 "class",
560 "index-link")
561 for link in indexLinks:
562 if indexFilename is None:
563 link.parentNode.removeChild(link)
564 else:
565 link.nodeName = link.tagName = link.endTagName = 'a'
566 link.attributes = InsensitiveDict({'href': indexFilename})
567
568
569
570 def numberDocument(document, chapterNumber):
571 """
572 Number the sections of the given document.
573
574 A dot-separated chapter, section number is added to the beginning of each
575 section, as defined by C{h2} nodes.
576
577 @type document: A DOM Node or Document
578 @param document: The input document which contains all of the content to be
579 presented.
580
581 @type chapterNumber: C{int}
582 @param chapterNumber: The chapter number of this content in an overall
583 document.
584
585 @return: C{None}
586 """
587 i = 1
588 for node in domhelpers.findNodesNamed(document, "h2"):
589 node.childNodes = [microdom.Text("%s.%d " % (chapterNumber, i))] + node. childNodes
590 i += 1
591
592
593
594 def fixRelativeLinks(document, linkrel):
595 """
596 Replace relative links in C{str} and C{href} attributes with links relative
597 to C{linkrel}.
598
599 @type document: A DOM Node or Document
600 @param document: The output template.
601
602 @type linkrel: C{str}
603 @param linkrel: An prefix to apply to all relative links in C{src} or
604 C{href} attributes in the input document when generating the output
605 document.
606 """
607 for attr in 'src', 'href':
608 for node in domhelpers.findElementsWithAttribute(document, attr):
609 href = node.getAttribute(attr)
610 if not href.startswith('http') and not href.startswith('/'):
611 node.setAttribute(attr, linkrel+node.getAttribute(attr))
612
613
614
615 def setTitle(template, title, chapterNumber):
616 """
617 Add title and chapter number information to the template document.
618
619 The title is added to the end of the first C{title} tag and the end of the
620 first tag with a C{class} attribute set to C{title}. If specified, the
621 chapter is inserted before the title.
622
623 @type template: A DOM Node or Document
624 @param template: The output template which defines the presentation of the
625 version information.
626
627 @type title: C{list} of DOM Nodes
628 @param title: Nodes from the input document defining its title.
629
630 @type chapterNumber: C{int}
631 @param chapterNumber: The chapter number of this content in an overall
632 document. If not applicable, any C{False} value will result in this
633 information being omitted.
634
635 @return: C{None}
636 """
637 for nodeList in (domhelpers.findNodesNamed(template, "title"),
638 domhelpers.findElementsWithAttribute(template, "class",
639 'title')):
640 if nodeList:
641 if numberer.getNumberSections() and chapterNumber:
642 nodeList[0].childNodes.append(microdom.Text('%s. ' % chapterNumb er))
643 nodeList[0].childNodes.extend(title)
644
645
646
647 def setAuthors(template, authors):
648 """
649 Add author information to the template document.
650
651 Names and contact information for authors are added to each node with a
652 C{class} attribute set to C{authors} and to the template head as C{link}
653 nodes.
654
655 @type template: A DOM Node or Document
656 @param template: The output template which defines the presentation of the
657 version information.
658
659 @type authors: C{list} of two-tuples of C{str}
660 @param authors: List of names and contact information for the authors of
661 the input document.
662
663 @return: C{None}
664 """
665 # First, similarly to setTitle, insert text into an <div class="authors">
666 text = ''
667 for name, href in authors:
668 # FIXME: Do proper quoting/escaping (is it ok to use
669 # xml.sax.saxutils.{escape,quoteattr}?)
670 anchor = '<a href="%s">%s</a>' % (href, name)
671 if (name, href) == authors[-1]:
672 if len(authors) == 1:
673 text = anchor
674 else:
675 text += 'and ' + anchor
676 else:
677 text += anchor + ','
678
679 childNodes = microdom.parseString('<span>' + text +'</span>').childNodes
680
681 for node in domhelpers.findElementsWithAttribute(template,
682 "class", 'authors'):
683 node.childNodes.extend(childNodes)
684
685 # Second, add appropriate <link rel="author" ...> tags to the <head>.
686 head = domhelpers.findNodesNamed(template, 'head')[0]
687 authors = [microdom.parseString('<link rel="author" href="%s" title="%s"/>'
688 % (href, name)).childNodes[0]
689 for name, href in authors]
690 head.childNodes.extend(authors)
691
692
693
694 def setVersion(template, version):
695 """
696 Add a version indicator to the given template.
697
698 @type template: A DOM Node or Document
699 @param template: The output template which defines the presentation of the
700 version information.
701
702 @type version: C{str}
703 @param version: The version string to add to the template.
704
705 @return: C{None}
706 """
707 for node in domhelpers.findElementsWithAttribute(template, "class",
708 "version"):
709 node.appendChild(microdom.Text(version))
710
711
712
713 def getOutputFileName(originalFileName, outputExtension, index=None):
714 """
715 Return a filename which is the same as C{originalFileName} except for the
716 extension, which is replaced with C{outputExtension}.
717
718 For example, if C{originalFileName} is C{'/foo/bar.baz'} and
719 C{outputExtension} is C{'quux'}, the return value will be
720 C{'/foo/bar.quux'}.
721
722 @type originalFileName: C{str}
723 @type outputExtension: C{stR}
724 @param index: ignored, never passed.
725 @rtype: C{str}
726 """
727 return os.path.splitext(originalFileName)[0]+outputExtension
728
729
730
731 def munge(document, template, linkrel, dir, fullpath, ext, url, config, outfileG enerator=getOutputFileName):
732 """
733 Mutate C{template} until it resembles C{document}.
734
735 @type document: A DOM Node or Document
736 @param document: The input document which contains all of the content to be
737 presented.
738
739 @type template: A DOM Node or Document
740 @param template: The template document which defines the desired
741 presentation format of the content.
742
743 @type linkrel: C{str}
744 @param linkrel: An prefix to apply to all relative links in C{src} or
745 C{href} attributes in the input document when generating the output
746 document.
747
748 @type dir: C{str}
749 @param dir: The directory in which to search for source listing files.
750
751 @type fullpath: C{str}
752 @param fullpath: The file name which contained the input document.
753
754 @type ext: C{str}
755 @param ext: The extension to use when selecting an output file name. This
756 replaces the extension of the input file name.
757
758 @type url: C{str}
759 @param url: A string which will be interpolated with the fully qualified
760 Python name of any API reference encountered in the input document, the
761 result of which will be used as a link to API documentation for that name
762 in the output document.
763
764 @type config: C{dict}
765 @param config: Further specification of the desired form of the output.
766 Valid keys in this dictionary::
767
768 noapi: If present and set to a True value, links to API documentation
769 will not be generated.
770
771 version: A string which will be included in the output to indicate the
772 version of this documentation.
773
774 @type outfileGenerator: Callable of C{str}, C{str} returning C{str}
775 @param outfileGenerator: Output filename factory. This is invoked with the
776 intput filename and C{ext} and the output document is serialized to the
777 file with the name returned.
778
779 @return: C{None}
780 """
781 fixRelativeLinks(template, linkrel)
782 addMtime(template, fullpath)
783 removeH1(document)
784 if not config.get('noapi', False):
785 fixAPI(document, url)
786 fontifyPython(document)
787 fixLinks(document, ext)
788 addPyListings(document, dir)
789 addHTMLListings(document, dir)
790 addPlainListings(document, dir)
791 putInToC(template, generateToC(document))
792 footnotes(document)
793 notes(document)
794
795 setIndexLink(template, indexer.getIndexFilename())
796 setVersion(template, config.get('version', ''))
797
798 # Insert the document into the template
799 chapterNumber = htmlbook.getNumber(fullpath)
800 title = domhelpers.findNodesNamed(document, 'title')[0].childNodes
801 setTitle(template, title, chapterNumber)
802 if numberer.getNumberSections() and chapterNumber:
803 numberDocument(document, chapterNumber)
804 index(document, outfileGenerator(os.path.split(fullpath)[1], ext),
805 htmlbook.getReference(fullpath))
806
807 authors = domhelpers.findNodesNamed(document, 'link')
808 authors = [(node.getAttribute('title',''), node.getAttribute('href', ''))
809 for node in authors if node.getAttribute('rel', '') == 'author']
810 setAuthors(template, authors)
811
812 body = domhelpers.findNodesNamed(document, "body")[0]
813 tmplbody = domhelpers.findElementsWithAttribute(template, "class",
814 "body")[0]
815 tmplbody.childNodes = body.childNodes
816 tmplbody.setAttribute("class", "content")
817
818
819 def parseFileAndReport(filename):
820 """
821 Parse and return the contents of the given lore XHTML document.
822
823 @type filename: C{str}
824 @param filename: The name of a file containing a lore XHTML document to
825 load.
826
827 @raise process.ProcessingFailure: When the contents of the specified file
828 cannot be parsed.
829
830 @rtype: A DOM Document
831 @return: The document contained in C{filename}.
832 """
833 try:
834 return microdom.parse(open(filename))
835 except microdom.MismatchedTags, e:
836 raise process.ProcessingFailure(
837 "%s:%s: begin mismatched tags <%s>/</%s>" %
838 (e.begLine, e.begCol, e.got, e.expect),
839 "%s:%s: end mismatched tags <%s>/</%s>" %
840 (e.endLine, e.endCol, e.got, e.expect))
841 except microdom.ParseError, e:
842 raise process.ProcessingFailure("%s:%s:%s" % (e.line, e.col, e.message))
843 except IOError, e:
844 raise process.ProcessingFailure(e.strerror + ", filename was '" + filena me + "'")
845
846 def makeSureDirectoryExists(filename):
847 filename = os.path.abspath(filename)
848 dirname = os.path.dirname(filename)
849 if (not os.path.exists(dirname)):
850 os.makedirs(dirname)
851
852 def doFile(filename, linkrel, ext, url, templ, options={}, outfileGenerator=getO utputFileName):
853 """
854 Process the input document at C{filename} and write an output document.
855
856 @type filename: C{str}
857 @param filename: The path to the input file which will be processed.
858
859 @type linkrel: C{str}
860 @param linkrel: An prefix to apply to all relative links in C{src} or
861 C{href} attributes in the input document when generating the output
862 document.
863
864 @type ext: C{str}
865 @param ext: The extension to use when selecting an output file name. This
866 replaces the extension of the input file name.
867
868 @type url: C{str}
869 @param url: A string which will be interpolated with the fully qualified
870 Python name of any API reference encountered in the input document, the
871 result of which will be used as a link to API documentation for that name
872 in the output document.
873
874 @type templ: A DOM Node or Document
875 @param templ: The template on which the output document will be based.
876 This is mutated and then serialized to the output file.
877
878 @type options: C{dict}
879 @param options: Further specification of the desired form of the output.
880 Valid keys in this dictionary::
881
882 noapi: If present and set to a True value, links to API documentation
883 will not be generated.
884
885 version: A string which will be included in the output to indicate the
886 version of this documentation.
887
888 @type outfileGenerator: Callable of C{str}, C{str} returning C{str}
889 @param outfileGenerator: Output filename factory. This is invoked with the
890 intput filename and C{ext} and the output document is serialized to the
891 file with the name returned.
892
893 @return: C{None}
894 """
895 doc = parseFileAndReport(filename)
896 clonedNode = templ.cloneNode(1)
897 munge(doc, clonedNode, linkrel, os.path.dirname(filename), filename, ext,
898 url, options, outfileGenerator)
899 newFilename = outfileGenerator(filename, ext)
900 makeSureDirectoryExists(newFilename)
901 clonedNode.writexml(open(newFilename, 'wb'))
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/lore/topfiles/setup.py ('k') | third_party/twisted_8_1/twisted/mail/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698