[Zope-Checkins] CVS: Zope/lib/python/docutils/parsers/rst -
__init__.py:1.2.10.8 roles.py:1.1.4.5 states.py:1.2.10.8
tableparser.py:1.2.10.7
Andreas Jung
andreas at andreas-jung.com
Sun Oct 9 10:44:15 EDT 2005
Update of /cvs-repository/Zope/lib/python/docutils/parsers/rst
In directory cvs.zope.org:/tmp/cvs-serv26422/parsers/rst
Modified Files:
Tag: Zope-2_7-branch
__init__.py roles.py states.py tableparser.py
Log Message:
upgrade to docutils 0.3.9
=== Zope/lib/python/docutils/parsers/rst/__init__.py 1.2.10.7 => 1.2.10.8 ===
--- Zope/lib/python/docutils/parsers/rst/__init__.py:1.2.10.7 Fri Jan 7 08:26:03 2005
+++ Zope/lib/python/docutils/parsers/rst/__init__.py Sun Oct 9 10:43:45 2005
@@ -112,7 +112,23 @@
('Leave spaces before footnote references.',
['--leave-footnote-reference-space'],
{'action': 'store_false', 'dest': 'trim_footnote_reference_space',
- 'validator': frontend.validate_boolean}),))
+ 'validator': frontend.validate_boolean}),
+ ('Disable directives that insert the contents of external file '
+ '("include" & "raw"); replaced with a "warning" system message.',
+ ['--no-file-insertion'],
+ {'action': 'store_false', 'default': 1,
+ 'dest': 'file_insertion_enabled'}),
+ ('Enable directives that insert the contents of external file '
+ '("include" & "raw"). Enabled by default.',
+ ['--file-insertion-enabled'],
+ {'action': 'store_true', 'dest': 'file_insertion_enabled'}),
+ ('Disable the "raw" directives; replaced with a "warning" '
+ 'system message.',
+ ['--no-raw'],
+ {'action': 'store_false', 'default': 1, 'dest': 'raw_enabled'}),
+ ('Enable the "raw" directive. Enabled by default.',
+ ['--raw-enabled'],
+ {'action': 'store_true', 'dest': 'raw_enabled'}),))
config_section = 'restructuredtext parser'
config_section_dependencies = ('parsers',)
@@ -128,11 +144,10 @@
def parse(self, inputstring, document):
"""Parse `inputstring` and populate `document`, a document tree."""
self.setup_parse(inputstring, document)
- debug = document.reporter[''].debug
self.statemachine = states.RSTStateMachine(
state_classes=self.state_classes,
initial_state=self.initial_state,
- debug=debug)
+ debug=document.reporter.debug_flag)
inputlines = docutils.statemachine.string2lines(
inputstring, tab_width=document.settings.tab_width,
convert_whitespace=1)
=== Zope/lib/python/docutils/parsers/rst/roles.py 1.1.4.4 => 1.1.4.5 ===
--- Zope/lib/python/docutils/parsers/rst/roles.py:1.1.4.4 Fri Jan 7 08:26:03 2005
+++ Zope/lib/python/docutils/parsers/rst/roles.py Sun Oct 9 10:43:45 2005
@@ -174,7 +174,7 @@
if not hasattr(role_fn, 'options') or role_fn.options is None:
role_fn.options = {'class': directives.class_option}
elif not role_fn.options.has_key('class'):
- role_fn.options['class'] = directives.class_option
+ role_fn.options['class'] = directives.class_option
def register_generic_role(canonical_name, node_class):
"""For roles which simply wrap a given `node_class` around the text."""
@@ -195,6 +195,7 @@
def __call__(self, role, rawtext, text, lineno, inliner,
options={}, content=[]):
+ set_classes(options)
return [self.node_class(rawtext, utils.unescape(text), **options)], []
@@ -233,6 +234,7 @@
""""""
# Once nested inline markup is implemented, this and other methods should
# recursively call inliner.nested_parse().
+ set_classes(options)
return [nodes.inline(rawtext, utils.unescape(text), **options)], []
generic_custom_role.options = {'class': directives.class_option}
@@ -265,6 +267,7 @@
return [prb], [msg]
# Base URL mainly used by inliner.pep_reference; so this is correct:
ref = inliner.document.settings.pep_base_url + inliner.pep_url % pepnum
+ set_classes(options)
return [nodes.reference(rawtext, 'PEP ' + utils.unescape(text), refuri=ref,
**options)], []
@@ -284,6 +287,7 @@
return [prb], [msg]
# Base URL mainly used by inliner.rfc_reference, so this is correct:
ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
+ set_classes(options)
node = nodes.reference(rawtext, 'RFC ' + utils.unescape(text), refuri=ref,
**options)
return [node], []
@@ -299,10 +303,11 @@
'an associated format.' % role, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
+ set_classes(options)
node = nodes.raw(rawtext, utils.unescape(text, 1), **options)
return [node], []
-raw_role.options = {'format': directives.class_option}
+raw_role.options = {'format': directives.unchanged}
register_canonical_role('raw', raw_role)
@@ -329,3 +334,14 @@
# This should remain unimplemented, for testing purposes:
register_canonical_role('restructuredtext-unimplemented-role',
unimplemented_role)
+
+
+def set_classes(options):
+ """
+ Auxiliary function to set options['classes'] and delete
+ options['class'].
+ """
+ if options.has_key('class'):
+ assert not options.has_key('classes')
+ options['classes'] = options['class']
+ del options['class']
=== Zope/lib/python/docutils/parsers/rst/states.py 1.2.10.7 => 1.2.10.8 ===
--- Zope/lib/python/docutils/parsers/rst/states.py:1.2.10.7 Fri Jan 7 08:26:03 2005
+++ Zope/lib/python/docutils/parsers/rst/states.py Sun Oct 9 10:43:45 2005
@@ -365,7 +365,7 @@
textnodes, title_messages = self.inline_text(title, lineno)
titlenode = nodes.title(title, '', *textnodes)
name = normalize_name(titlenode.astext())
- section_node['name'] = name
+ section_node['names'].append(name)
section_node += titlenode
section_node += messages
section_node += title_messages
@@ -533,7 +533,7 @@
emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9\x00]"""
email_pattern = r"""
%(emailc)s+(?:\.%(emailc)s+)* # name
- @ # at
+ (?<!\x00)@ # at
%(emailc)s+(?:\.%(emailc)s*)* # host
%(uri_end)s # final URI char
"""
@@ -787,7 +787,7 @@
else:
if target:
reference['refuri'] = uri
- target['name'] = refname
+ target['names'].append(refname)
self.document.note_external_target(target)
self.document.note_explicit_target(target, self.parent)
node_list.append(target)
@@ -829,7 +829,7 @@
assert len(inlines) == 1
target = inlines[0]
name = normalize_name(target.astext())
- target['name'] = name
+ target['names'].append(name)
self.document.note_explicit_target(target, self.parent)
return before, inlines, remaining, sysmessages
@@ -1036,10 +1036,10 @@
pats['alphanum'] = '[a-zA-Z0-9]'
pats['alphanumplus'] = '[a-zA-Z0-9_-]'
pats['enum'] = ('(%(arabic)s|%(loweralpha)s|%(upperalpha)s|%(lowerroman)s'
- '|%(upperroman)s)' % enum.sequencepats)
+ '|%(upperroman)s|#)' % enum.sequencepats)
pats['optname'] = '%(alphanum)s%(alphanumplus)s*' % pats
# @@@ Loosen up the pattern? Allow Unicode?
- pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<%(alphanum)s[^ <>]+>)' % pats
+ pats['optarg'] = '(%(alpha)s%(alphanumplus)s*|<[^<>]+>)' % pats
pats['shortopt'] = r'(-|\+)%(alphanum)s( ?%(optarg)s)?' % pats
pats['longopt'] = r'(--|/)%(optname)s([ =]%(optarg)s)?' % pats
pats['option'] = r'(%(shortopt)s|%(longopt)s)' % pats
@@ -1182,7 +1182,10 @@
raise statemachine.TransitionCorrection('text')
enumlist = nodes.enumerated_list()
self.parent += enumlist
- enumlist['enumtype'] = sequence
+ if sequence == '#':
+ enumlist['enumtype'] = 'arabic'
+ else:
+ enumlist['enumtype'] = sequence
enumlist['prefix'] = self.enum.formatinfo[format].prefix
enumlist['suffix'] = self.enum.formatinfo[format].suffix
if ordinal != 1:
@@ -1199,7 +1202,9 @@
input_offset=self.state_machine.abs_line_offset() + 1,
node=enumlist, initial_state='EnumeratedList',
blank_finish=blank_finish,
- extra_settings={'lastordinal': ordinal, 'format': format})
+ extra_settings={'lastordinal': ordinal,
+ 'format': format,
+ 'auto': sequence == '#'})
self.goto_line(newline_offset)
if not blank_finish:
self.parent += self.unindent_warning('Enumerated list')
@@ -1232,7 +1237,9 @@
raise ParserError('enumerator format not matched')
text = groupdict[format][self.enum.formatinfo[format].start
:self.enum.formatinfo[format].end]
- if expected_sequence:
+ if text == '#':
+ sequence = '#'
+ elif expected_sequence:
try:
if self.enum.sequenceregexps[expected_sequence].match(text):
sequence = expected_sequence
@@ -1249,10 +1256,13 @@
break
else: # shouldn't happen
raise ParserError('enumerator sequence not matched')
- try:
- ordinal = self.enum.converters[sequence](text)
- except roman.InvalidRomanNumeralError:
- ordinal = None
+ if sequence == '#':
+ ordinal = 1
+ else:
+ try:
+ ordinal = self.enum.converters[sequence](text)
+ except roman.InvalidRomanNumeralError:
+ ordinal = None
return format, sequence, text, ordinal
def is_enumerated_list_item(self, ordinal, sequence, format):
@@ -1260,7 +1270,7 @@
Check validity based on the ordinal value and the second line.
Return true iff the ordinal is valid and the second line is blank,
- indented, or starts with the next enumerator.
+ indented, or starts with the next enumerator or an auto-enumerator.
"""
if ordinal is None:
return None
@@ -1273,9 +1283,11 @@
self.state_machine.previous_line()
if not next_line[:1].strip(): # blank or indented
return 1
- next_enumerator = self.make_enumerator(ordinal + 1, sequence, format)
+ next_enumerator, auto_enumerator = self.make_enumerator(
+ ordinal + 1, sequence, format)
try:
- if next_line.startswith(next_enumerator):
+ if ( next_line.startswith(next_enumerator) or
+ next_line.startswith(auto_enumerator) ):
return 1
except TypeError:
pass
@@ -1283,11 +1295,14 @@
def make_enumerator(self, ordinal, sequence, format):
"""
- Construct and return an enumerated list item marker.
+ Construct and return the next enumerated list item marker, and an
+ auto-enumerator ("#" instead of the regular enumerator).
Return ``None`` for invalid (out of range) ordinals.
- """
- if sequence == 'arabic':
+ """ #"
+ if sequence == '#':
+ enumerator = '#'
+ elif sequence == 'arabic':
enumerator = str(ordinal)
else:
if sequence.endswith('alpha'):
@@ -1310,7 +1325,10 @@
raise ParserError('unknown enumerator sequence: "%s"'
% sequence)
formatinfo = self.enum.formatinfo[format]
- return formatinfo.prefix + enumerator + formatinfo.suffix + ' '
+ next_enumerator = (formatinfo.prefix + enumerator + formatinfo.suffix
+ + ' ')
+ auto_enumerator = formatinfo.prefix + '#' + formatinfo.suffix + ' '
+ return next_enumerator, auto_enumerator
def field_marker(self, match, context, next_state):
"""Field list item."""
@@ -1415,14 +1433,20 @@
delimiter = ' '
firstopt = tokens[0].split('=')
if len(firstopt) > 1:
+ # "--opt=value" form
tokens[:1] = firstopt
delimiter = '='
elif (len(tokens[0]) > 2
and ((tokens[0].startswith('-')
and not tokens[0].startswith('--'))
or tokens[0].startswith('+'))):
+ # "-ovalue" form
tokens[:1] = [tokens[0][:2], tokens[0][2:]]
delimiter = ''
+ if len(tokens) > 1 and (tokens[1].startswith('<')
+ and tokens[-1].endswith('>')):
+ # "-o <value1 value2>" form; join all values into one token
+ tokens[1:] = [' '.join(tokens[1:])]
if 0 < len(tokens) <= 2:
option = nodes.option(optionstring)
option += nodes.option_string(tokens[0], tokens[0])
@@ -1432,7 +1456,7 @@
optlist.append(option)
else:
raise MarkupError(
- 'wrong numer of option tokens (=%s), should be 1 or 2: '
+ 'wrong number of option tokens (=%s), should be 1 or 2: '
'"%s"' % (len(tokens), optionstring),
self.state_machine.abs_line_number() + 1)
return optlist
@@ -1541,7 +1565,8 @@
table = self.build_table(tabledata, tableline)
nodelist = [table] + messages
except tableparser.TableMarkupError, detail:
- nodelist = self.malformed_table(block, str(detail)) + messages
+ nodelist = self.malformed_table(
+ block, ' '.join(detail.args)) + messages
else:
nodelist = messages
return nodelist, blank_finish
@@ -1633,13 +1658,17 @@
line=lineno)
return [error]
- def build_table(self, tabledata, tableline):
- colspecs, headrows, bodyrows = tabledata
+ def build_table(self, tabledata, tableline, stub_columns=0):
+ colwidths, headrows, bodyrows = tabledata
table = nodes.table()
- tgroup = nodes.tgroup(cols=len(colspecs))
+ tgroup = nodes.tgroup(cols=len(colwidths))
table += tgroup
- for colspec in colspecs:
- tgroup += nodes.colspec(colwidth=colspec)
+ for colwidth in colwidths:
+ colspec = nodes.colspec(colwidth=colwidth)
+ if stub_columns:
+ colspec.attributes['stub'] = 1
+ stub_columns -= 1
+ tgroup += colspec
if headrows:
thead = nodes.thead()
tgroup += thead
@@ -1727,7 +1756,7 @@
name = name[1:] # autonumber label
footnote['auto'] = 1
if name:
- footnote['name'] = name
+ footnote['names'].append(name)
self.document.note_autofootnote(footnote)
elif name == '*': # auto-symbol
name = ''
@@ -1735,7 +1764,7 @@
self.document.note_symbol_footnote(footnote)
else: # manually numbered
footnote += nodes.label('', label)
- footnote['name'] = name
+ footnote['names'].append(name)
self.document.note_footnote(footnote)
if name:
self.document.note_explicit_target(footnote, footnote)
@@ -1754,7 +1783,7 @@
citation = nodes.citation('\n'.join(indented))
citation.line = lineno
citation += nodes.label('', label)
- citation['name'] = name
+ citation['names'].append(name)
self.document.note_citation(citation)
self.document.note_explicit_target(citation, citation)
if indented:
@@ -1790,7 +1819,6 @@
target_type, data = self.parse_target(block, block_text, lineno)
if target_type == 'refname':
target = nodes.target(block_text, '', refname=normalize_name(data))
- target.indirect_reference_name = data
self.add_target(target_name, '', target, lineno)
self.document.note_indirect_target(target)
return target
@@ -1816,15 +1844,8 @@
refname = self.is_reference(reference)
if refname:
return 'refname', refname
- reference = ''.join([line.strip() for line in block])
- if reference.find(' ') == -1:
- return 'refuri', unescape(reference)
- else:
- warning = self.reporter.warning(
- 'Hyperlink target contains whitespace. Perhaps a footnote '
- 'was intended?',
- nodes.literal_block(block_text, block_text), line=lineno)
- return 'malformed', warning
+ reference = ''.join([''.join(line.split()) for line in block])
+ return 'refuri', unescape(reference)
def is_reference(self, reference):
match = self.explicit.patterns.reference.match(
@@ -1837,7 +1858,7 @@
target.line = lineno
if targetname:
name = normalize_name(unescape(targetname))
- target['name'] = name
+ target['names'].append(name)
if refuri:
uri = self.inliner.adjust_uri(refuri)
if uri:
@@ -1851,6 +1872,8 @@
else: # anonymous target
if refuri:
target['refuri'] = refuri
+ else:
+ self.document.note_internal_target(target)
target['anonymous'] = 1
self.document.note_anonymous_target(target)
@@ -1960,7 +1983,8 @@
directive_fn, option_presets))
except MarkupError, detail:
error = self.reporter.error(
- 'Error in "%s" directive:\n%s.' % (type_name, detail),
+ 'Error in "%s" directive:\n%s.' % (type_name,
+ ' '.join(detail.args)),
nodes.literal_block(block_text, block_text), line=lineno)
return [error], blank_finish
result = directive_fn(type_name, arguments, options, content, lineno,
@@ -2071,9 +2095,9 @@
except KeyError, detail:
return 0, ('unknown option: "%s"' % detail.args[0])
except (ValueError, TypeError), detail:
- return 0, ('invalid option value: %s' % detail)
+ return 0, ('invalid option value: %s' % ' '.join(detail.args))
except utils.ExtensionOptionError, detail:
- return 0, ('invalid option data: %s' % detail)
+ return 0, ('invalid option data: %s' % ' '.join(detail.args))
if blank_finish:
return 1, options
else:
@@ -2127,13 +2151,13 @@
re.compile(r"""
\.\.[ ]+ # explicit markup start
_ # target indicator
- (?![ ]) # first char. not space
+ (?![ ]|$) # first char. not space or EOL
""", re.VERBOSE)),
(substitution_def,
re.compile(r"""
\.\.[ ]+ # explicit markup start
\| # substitution indicator
- (?![ ]) # first char. not space
+ (?![ ]|$) # first char. not space or EOL
""", re.VERBOSE)),
(directive,
re.compile(r"""
@@ -2240,7 +2264,7 @@
def rfc2822(self, match, context, next_state):
"""RFC2822-style field list item."""
- fieldlist = nodes.field_list(CLASS='rfc2822')
+ fieldlist = nodes.field_list(classes=['rfc2822'])
self.parent += fieldlist
field, blank_finish = self.rfc2822_field(match)
fieldlist += field
@@ -2347,12 +2371,15 @@
"""Enumerated list item."""
format, sequence, text, ordinal = self.parse_enumerator(
match, self.parent['enumtype'])
- if (sequence != self.parent['enumtype'] or
- format != self.format or
- ordinal != (self.lastordinal + 1) or
- not self.is_enumerated_list_item(ordinal, sequence, format)):
+ if ( format != self.format
+ or (sequence != '#' and (sequence != self.parent['enumtype']
+ or self.auto
+ or ordinal != (self.lastordinal + 1)))
+ or not self.is_enumerated_list_item(ordinal, sequence, format)):
# different enumeration: new list
self.invalid_input()
+ if sequence == '#':
+ self.auto = 1
listitem, blank_finish = self.list_item(match.end())
self.parent += listitem
self.blank_finish = blank_finish
@@ -2475,7 +2502,7 @@
def embedded_directive(self, match, context, next_state):
nodelist, blank_finish = self.directive(match,
- alt=self.parent['name'])
+ alt=self.parent['names'][0])
self.parent += nodelist
if not self.state_machine.at_eof():
self.blank_finish = blank_finish
=== Zope/lib/python/docutils/parsers/rst/tableparser.py 1.2.10.6 => 1.2.10.7 ===
More information about the Zope-Checkins
mailing list