1 | # Author: Ollie Rutherfurd |
---|
2 | # Contact: oliver@rutherfurd.net |
---|
3 | # Revision: $Revision: 2884 $ |
---|
4 | # Date: $Date: 2004-12-08 20:49:05 +0100 (Wed, 08 Dec 2004) $ |
---|
5 | # Copyright: This module has been placed in the public domain. |
---|
6 | |
---|
7 | """ |
---|
8 | Simple .ht (HyperText Template) document tree Writer. |
---|
9 | |
---|
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. |
---|
14 | |
---|
15 | See http://ht2html.sf.net/ for more information on |
---|
16 | .ht files and ht2html.. |
---|
17 | """ |
---|
18 | |
---|
19 | __docformat__ = 'reStructuredText' |
---|
20 | |
---|
21 | import os |
---|
22 | from docutils import nodes |
---|
23 | from docutils import writers |
---|
24 | from docutils import frontend |
---|
25 | from docutils.writers.html4css1 import HTMLTranslator, utils |
---|
26 | |
---|
27 | |
---|
28 | class Writer(writers.Writer): |
---|
29 | |
---|
30 | supported = ('htmlfrag',) |
---|
31 | """Formats this writer supports.""" |
---|
32 | |
---|
33 | settings_spec = ( |
---|
34 | 'HTML-Specific Options', |
---|
35 | None, |
---|
36 | (('Specify a stylesheet URL, used verbatim. Default is ' |
---|
37 | '"default.css". Overrides --stylesheet-path.', |
---|
38 | ['--stylesheet'], |
---|
39 | {'default': 'default.css', 'metavar': '<URL>', |
---|
40 | 'overrides': 'stylesheet_path'}), |
---|
41 | ('Specify a stylesheet file, relative to the current working ' |
---|
42 | 'directory. The path is adjusted relative to the output HTML ' |
---|
43 | 'file. Overrides --stylesheet.', |
---|
44 | ['--stylesheet-path'], |
---|
45 | {'metavar': '<file>', 'overrides': 'stylesheet'}), |
---|
46 | ('Link to the stylesheet in the output HTML file. This is the ' |
---|
47 | 'default.', |
---|
48 | ['--link-stylesheet'], |
---|
49 | {'dest': 'embed_stylesheet', 'action': 'store_false', |
---|
50 | 'validator': frontend.validate_boolean}), |
---|
51 | ('Embed the stylesheet in the output HTML file. The stylesheet ' |
---|
52 | 'file must be accessible during processing (--stylesheet-path is ' |
---|
53 | 'recommended). Default: link the stylesheet, do not embed it.', |
---|
54 | ['--embed-stylesheet'], |
---|
55 | {'action': 'store_true', 'validator': frontend.validate_boolean}), |
---|
56 | ('Specify the initial header level. Default is 1 for "<h1>". ' |
---|
57 | 'Does not affect document title & subtitle (see --no-doc-title).', |
---|
58 | ['--initial-header-level'], |
---|
59 | {'choices': '1 2 3 4 5 6'.split(), 'default': '3', |
---|
60 | 'metavar': '<level>'}), |
---|
61 | ('Specify the maximum width (in characters) for one-column field ' |
---|
62 | 'names. Longer field names will span an entire row of the table ' |
---|
63 | 'used to render the field list. Default is 14 characters. ' |
---|
64 | 'Use 0 for "no limit".', |
---|
65 | ['--field-name-limit'], |
---|
66 | {'default': 14, 'metavar': '<level>', |
---|
67 | 'validator': frontend.validate_nonnegative_int}), |
---|
68 | ('Specify the maximum width (in characters) for options in option ' |
---|
69 | 'lists. Longer options will span an entire row of the table used ' |
---|
70 | 'to render the option list. Default is 14 characters. ' |
---|
71 | 'Use 0 for "no limit".', |
---|
72 | ['--option-limit'], |
---|
73 | {'default': 14, 'metavar': '<level>', |
---|
74 | 'validator': frontend.validate_nonnegative_int}), |
---|
75 | ('Format for footnote references: one of "superscript" or ' |
---|
76 | '"brackets". Default is "brackets".', |
---|
77 | ['--footnote-references'], |
---|
78 | {'choices': ['superscript', 'brackets'], 'default': 'brackets', |
---|
79 | 'metavar': '<format>', |
---|
80 | 'overrides': 'trim_footnote_reference_space'}), |
---|
81 | ('Format for block quote attributions: one of "dash" (em-dash ' |
---|
82 | 'prefix), "parentheses"/"parens", or "none". Default is "dash".', |
---|
83 | ['--attribution'], |
---|
84 | {'choices': ['dash', 'parentheses', 'parens', 'none'], |
---|
85 | 'default': 'dash', 'metavar': '<format>'}), |
---|
86 | ('Remove extra vertical whitespace between items of bullet lists ' |
---|
87 | 'and enumerated lists, when list items are "simple" (i.e., all ' |
---|
88 | 'items each contain one paragraph and/or one "simple" sublist ' |
---|
89 | 'only). Default: enabled.', |
---|
90 | ['--compact-lists'], |
---|
91 | {'default': 1, 'action': 'store_true', |
---|
92 | 'validator': frontend.validate_boolean}), |
---|
93 | ('Disable compact simple bullet and enumerated lists.', |
---|
94 | ['--no-compact-lists'], |
---|
95 | {'dest': 'compact_lists', 'action': 'store_false'}), |
---|
96 | ('Omit the XML declaration. Use with caution.', |
---|
97 | ['--no-xml-declaration'], |
---|
98 | {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', |
---|
99 | 'validator': frontend.validate_boolean}), |
---|
100 | ('Scramble email addresses to confuse harvesters. ' |
---|
101 | 'For example, "abc@example.org" will become ' |
---|
102 | '``<a href="mailto:%61%62%63%40...">abc at example dot org</a>``.', |
---|
103 | ['--cloak-email-addresses'], |
---|
104 | {'action': 'store_true', 'validator': frontend.validate_boolean}),)) |
---|
105 | |
---|
106 | |
---|
107 | relative_path_settings = ('stylesheet_path',) |
---|
108 | |
---|
109 | output = None |
---|
110 | |
---|
111 | def __init__(self): |
---|
112 | writers.Writer.__init__(self) |
---|
113 | self.translator_class = HTMLFragTranslator |
---|
114 | |
---|
115 | def translate(self): |
---|
116 | visitor = self.translator_class(self.document) |
---|
117 | self.document.walkabout(visitor) |
---|
118 | self.output = visitor.astext() |
---|
119 | self.stylesheet = visitor.stylesheet |
---|
120 | self.body = visitor.body |
---|
121 | |
---|
122 | |
---|
123 | class HTMLFragTranslator(HTMLTranslator): |
---|
124 | |
---|
125 | def __init__(self, document): |
---|
126 | # I don't believe we can embed any style content |
---|
127 | # the header, so always link to the stylesheet. |
---|
128 | document.settings.embed_stylesheet = 0 |
---|
129 | HTMLTranslator.__init__(self, document) |
---|
130 | |
---|
131 | def astext(self): |
---|
132 | # kludge! want footer, but not '</body></html>' |
---|
133 | body = self.body_pre_docinfo + self.docinfo + self.body + \ |
---|
134 | self.body_suffix[:-1] |
---|
135 | return ''.join(body) |
---|
136 | |
---|
137 | # :indentSize=4:lineSeparator=\n:noTabs=true:tabSize=4: |
---|