removed obsolete issues (many of them fixed with AE)
[docutils.git] / sandbox / oliverr / ht / writer / hthtml.py
blobd45f316f69f0423a32b02a0c6b9bcee9326f017b
1 # Author: Ollie Rutherfurd
2 # Contact: oliver@rutherfurd.net
3 # Revision: $Revision$
4 # Date: $Date$
5 # Copyright: This module has been placed in the public domain.
7 """
8 Simple .ht (HyperText Template) document tree Writer.
10 .ht tmeplate files are essentially normal HTML, with
11 an option set of RFC 2822-like headers at the top of
12 the file. There must be at least one blank line between
13 the last header and the start of the body HTML.
15 See http://ht2html.sf.net/ for more information on
16 .ht files and ht2html..
17 """
19 __docformat__ = 'reStructuredText'
21 import os
22 from docutils import nodes
23 from docutils import writers
24 from docutils.writers.html4css1 import HTMLTranslator
27 class Writer(writers.Writer):
29 supported = ('ht',)
30 """Formats this writer supports."""
32 settings_spec = (
33 '.ht template-Specific Options',
34 None,
35 (('Specify base section (i.e. if 3, a top-level section '
36 'would be written as H3, 2nd level H4, etc...). Default is 3.',
37 ['--base-section'],
38 {'choices': ['1','2','3','4'],
39 'default': '3',
40 'metavar': '<NUMBER>'}),
41 ('Specify a stylesheet URL, used verbatim. Default is '
42 '"default.css".',
43 ['--stylesheet'],
44 {'default': 'default.css', 'metavar': '<URL>'}),
45 ('Specify a stylesheet file, relative to the current working '
46 'directory. The path is adjusted relative to the output HTML '
47 'file. Overrides --stylesheet.',
48 ['--stylesheet-path'],
49 {'metavar': '<file>'}),
50 ('Format for footnote references: one of "superscript" or '
51 '"brackets". Default is "superscript".',
52 ['--footnote-references'],
53 {'choices': ['superscript', 'brackets'], 'default': 'superscript',
54 'metavar': '<FORMAT>'}),
55 ('Remove extra vertical whitespace between items of bullet lists '
56 'and enumerated lists, when list items are "simple" (i.e., all '
57 'items each contain one paragraph and/or one "simple" sublist '
58 'only). Default: enabled.',
59 ['--compact-lists'],
60 {'default': 1, 'action': 'store_true'}),
61 ('Disable compact simple bullet and enumerated lists.',
62 ['--no-compact-lists'],
63 {'dest': 'compact_lists', 'action': 'store_false'}),
64 ('Omit the XML declaration. Use with caution.',
65 ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1,
66 'action': 'store_false'}),))
68 relative_path_settings = ('stylesheet_path',)
70 output = None
72 def __init__(self):
73 writers.Writer.__init__(self)
74 self.translator_class = HTTranslator
76 def translate(self):
77 visitor = self.translator_class(self.document)
78 self.document.walkabout(visitor)
79 self.output = visitor.astext()
80 self.stylesheet = visitor.stylesheet
81 self.body = visitor.body
84 class HTTranslator(HTMLTranslator):
86 def __init__(self, document):
88 # I don't believe we can embed any style content
89 # the header, so always link to the stylesheet.
90 document.settings.embed_stylesheet = 0
91 document.settings.base_section = int(document.settings.base_section)
93 HTMLTranslator.__init__(self, document)
94 # ht2html likes having a title, so add a default one
95 self.headers = {'title': 'None'}
96 stylesheet = self.get_stylesheet_reference(os.getcwd())
97 if stylesheet:
98 self.headers['stylesheet']= stylesheet
99 # using first author found for .ht 'Author' header
100 self.has_author = 0
102 def astext(self):
103 headers = ''.join(['%s: %s\n' % (k,v) \
104 for (k,v) in self.headers.items()])
105 # kludge! want footer, but not '</body></html>'
106 body = self.body_pre_docinfo + self.docinfo + self.body + \
107 self.body_suffix[:-1]
109 return ''.join([headers + '\n'] + body)
111 def visit_author(self, node):
112 if not self.headers.has_key('author'):
113 self.headers['author'] = self.encode(node.astext())
114 HTMLTranslator.visit_author(self, node)
116 def visit_contact(self, node):
117 if not self.headers.has_key('author-email'):
118 self.headers['author-email'] = self.encode(node.astext())
119 HTMLTranslator.visit_contact(self, node)
121 def visit_title(self, node):
122 """Only 6 section levels are supported by HTML."""
123 if isinstance(node.parent, nodes.topic):
124 HTMLTranslator.visit_title(self, node)
125 elif self.section_level == 0:
126 HTMLTranslator.visit_title(self, node)
127 # document title
128 title = node.astext()
129 self.headers['title'] = self.encode(title)
130 else:
131 # offset section level to account for ``base_section``.
132 self.section_level += (self.settings.base_section - 1)
133 HTMLTranslator.visit_title(self, node)
134 self.section_level -= (self.settings.base_section - 1)
137 # :indentSize=4:lineSeparator=\n:noTabs=true:tabSize=4: