|
1 # $Id: html.py 4667 2006-07-12 21:40:56Z wiemann $ |
|
2 # Author: David Goodger <goodger@python.org> |
|
3 # Copyright: This module has been placed in the public domain. |
|
4 |
|
5 """ |
|
6 Directives for typically HTML-specific constructs. |
|
7 """ |
|
8 |
|
9 __docformat__ = 'reStructuredText' |
|
10 |
|
11 import sys |
|
12 from docutils import nodes, utils |
|
13 from docutils.parsers.rst import Directive |
|
14 from docutils.parsers.rst import states |
|
15 from docutils.transforms import components |
|
16 |
|
17 |
|
18 class MetaBody(states.SpecializedBody): |
|
19 |
|
20 class meta(nodes.Special, nodes.PreBibliographic, nodes.Element): |
|
21 """HTML-specific "meta" element.""" |
|
22 pass |
|
23 |
|
24 def field_marker(self, match, context, next_state): |
|
25 """Meta element.""" |
|
26 node, blank_finish = self.parsemeta(match) |
|
27 self.parent += node |
|
28 return [], next_state, [] |
|
29 |
|
30 def parsemeta(self, match): |
|
31 name = self.parse_field_marker(match) |
|
32 indented, indent, line_offset, blank_finish = \ |
|
33 self.state_machine.get_first_known_indented(match.end()) |
|
34 node = self.meta() |
|
35 pending = nodes.pending(components.Filter, |
|
36 {'component': 'writer', |
|
37 'format': 'html', |
|
38 'nodes': [node]}) |
|
39 node['content'] = ' '.join(indented) |
|
40 if not indented: |
|
41 line = self.state_machine.line |
|
42 msg = self.reporter.info( |
|
43 'No content for meta tag "%s".' % name, |
|
44 nodes.literal_block(line, line), |
|
45 line=self.state_machine.abs_line_number()) |
|
46 return msg, blank_finish |
|
47 tokens = name.split() |
|
48 try: |
|
49 attname, val = utils.extract_name_value(tokens[0])[0] |
|
50 node[attname.lower()] = val |
|
51 except utils.NameValueError: |
|
52 node['name'] = tokens[0] |
|
53 for token in tokens[1:]: |
|
54 try: |
|
55 attname, val = utils.extract_name_value(token)[0] |
|
56 node[attname.lower()] = val |
|
57 except utils.NameValueError, detail: |
|
58 line = self.state_machine.line |
|
59 msg = self.reporter.error( |
|
60 'Error parsing meta tag attribute "%s": %s.' |
|
61 % (token, detail), nodes.literal_block(line, line), |
|
62 line=self.state_machine.abs_line_number()) |
|
63 return msg, blank_finish |
|
64 self.document.note_pending(pending) |
|
65 return pending, blank_finish |
|
66 |
|
67 |
|
68 class Meta(Directive): |
|
69 |
|
70 has_content = True |
|
71 |
|
72 SMkwargs = {'state_classes': (MetaBody,)} |
|
73 |
|
74 def run(self): |
|
75 self.assert_has_content() |
|
76 node = nodes.Element() |
|
77 new_line_offset, blank_finish = self.state.nested_list_parse( |
|
78 self.content, self.content_offset, node, |
|
79 initial_state='MetaBody', blank_finish=1, |
|
80 state_machine_kwargs=self.SMkwargs) |
|
81 if (new_line_offset - self.content_offset) != len(self.content): |
|
82 # incomplete parse of block? |
|
83 error = self.state_machine.reporter.error( |
|
84 'Invalid meta directive.', |
|
85 nodes.literal_block(self.block_text, self.block_text), |
|
86 line=self.lineno) |
|
87 node += error |
|
88 return node.children |