| 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: |
|---|