--- a/mercurial/minirst.py Sun Oct 06 09:45:02 2019 -0400
+++ b/mercurial/minirst.py Sun Oct 06 09:48:39 2019 -0400
@@ -32,23 +32,23 @@
def section(s):
- return "%s\n%s\n\n" % (s, "\"" * encoding.colwidth(s))
+ return b"%s\n%s\n\n" % (s, b"\"" * encoding.colwidth(s))
def subsection(s):
- return "%s\n%s\n\n" % (s, '=' * encoding.colwidth(s))
+ return b"%s\n%s\n\n" % (s, b'=' * encoding.colwidth(s))
def subsubsection(s):
- return "%s\n%s\n\n" % (s, "-" * encoding.colwidth(s))
+ return b"%s\n%s\n\n" % (s, b"-" * encoding.colwidth(s))
def subsubsubsection(s):
- return "%s\n%s\n\n" % (s, "." * encoding.colwidth(s))
+ return b"%s\n%s\n\n" % (s, b"." * encoding.colwidth(s))
def subsubsubsubsection(s):
- return "%s\n%s\n\n" % (s, "'" * encoding.colwidth(s))
+ return b"%s\n%s\n\n" % (s, b"'" * encoding.colwidth(s))
def replace(text, substs):
@@ -85,12 +85,12 @@
has an 'indent' field and a 'lines' field.
"""
blocks = []
- for b in _blockre.split(text.lstrip('\n').rstrip()):
+ for b in _blockre.split(text.lstrip(b'\n').rstrip()):
lines = b.splitlines()
if lines:
indent = min((len(l) - len(l.lstrip())) for l in lines)
lines = [l[indent:] for l in lines]
- blocks.append({'indent': indent, 'lines': lines})
+ blocks.append({b'indent': indent, b'lines': lines})
return blocks
@@ -111,44 +111,44 @@
# +---------------------------+
# | indented literal block |
# +---------------------------+
- blocks[i]['type'] = 'paragraph'
- if blocks[i]['lines'][-1].endswith('::') and i + 1 < len(blocks):
- indent = blocks[i]['indent']
- adjustment = blocks[i + 1]['indent'] - indent
+ blocks[i][b'type'] = b'paragraph'
+ if blocks[i][b'lines'][-1].endswith(b'::') and i + 1 < len(blocks):
+ indent = blocks[i][b'indent']
+ adjustment = blocks[i + 1][b'indent'] - indent
- if blocks[i]['lines'] == ['::']:
+ if blocks[i][b'lines'] == [b'::']:
# Expanded form: remove block
del blocks[i]
i -= 1
- elif blocks[i]['lines'][-1].endswith(' ::'):
+ elif blocks[i][b'lines'][-1].endswith(b' ::'):
# Partially minimized form: remove space and both
# colons.
- blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-3]
+ blocks[i][b'lines'][-1] = blocks[i][b'lines'][-1][:-3]
elif (
- len(blocks[i]['lines']) == 1
- and blocks[i]['lines'][0].lstrip(' ').startswith('.. ')
- and blocks[i]['lines'][0].find(' ', 3) == -1
+ len(blocks[i][b'lines']) == 1
+ and blocks[i][b'lines'][0].lstrip(b' ').startswith(b'.. ')
+ and blocks[i][b'lines'][0].find(b' ', 3) == -1
):
# directive on its own line, not a literal block
i += 1
continue
else:
# Fully minimized form: remove just one colon.
- blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-1]
+ blocks[i][b'lines'][-1] = blocks[i][b'lines'][-1][:-1]
# List items are formatted with a hanging indent. We must
# correct for this here while we still have the original
# information on the indentation of the subsequent literal
# blocks available.
- m = _bulletre.match(blocks[i]['lines'][0])
+ m = _bulletre.match(blocks[i][b'lines'][0])
if m:
indent += m.end()
adjustment -= m.end()
# Mark the following indented blocks.
- while i + 1 < len(blocks) and blocks[i + 1]['indent'] > indent:
- blocks[i + 1]['type'] = 'literal'
- blocks[i + 1]['indent'] -= adjustment
+ while i + 1 < len(blocks) and blocks[i + 1][b'indent'] > indent:
+ blocks[i + 1][b'type'] = b'literal'
+ blocks[i + 1][b'indent'] -= adjustment
i += 1
i += 1
return blocks
@@ -169,10 +169,10 @@
# matters: definition lists has the least specific regexp and must
# come last.
listtypes = [
- ('bullet', _bulletre, True),
- ('option', _optionre, True),
- ('field', _fieldre, True),
- ('definition', _definitionre, False),
+ (b'bullet', _bulletre, True),
+ (b'option', _optionre, True),
+ (b'field', _fieldre, True),
+ (b'definition', _definitionre, False),
]
def match(lines, i, itemre, singleline):
@@ -182,18 +182,18 @@
item (but only if singleline is True).
"""
line1 = lines[i]
- line2 = i + 1 < len(lines) and lines[i + 1] or ''
+ line2 = i + 1 < len(lines) and lines[i + 1] or b''
if not itemre.match(line1):
return False
if singleline:
- return line2 == '' or line2[0:1] == ' ' or itemre.match(line2)
+ return line2 == b'' or line2[0:1] == b' ' or itemre.match(line2)
else:
- return line2.startswith(' ')
+ return line2.startswith(b' ')
i = 0
while i < len(blocks):
- if blocks[i]['type'] == 'paragraph':
- lines = blocks[i]['lines']
+ if blocks[i][b'type'] == b'paragraph':
+ lines = blocks[i][b'lines']
for type, itemre, singleline in listtypes:
if match(lines, 0, itemre, singleline):
items = []
@@ -201,12 +201,12 @@
if match(lines, j, itemre, singleline):
items.append(
{
- 'type': type,
- 'lines': [],
- 'indent': blocks[i]['indent'],
+ b'type': type,
+ b'lines': [],
+ b'indent': blocks[i][b'indent'],
}
)
- items[-1]['lines'].append(line)
+ items[-1][b'lines'].append(line)
blocks[i : i + 1] = items
break
i += 1
@@ -220,16 +220,16 @@
"""Find key for field lists."""
i = 0
while i < len(blocks):
- if blocks[i]['type'] != 'field':
+ if blocks[i][b'type'] != b'field':
i += 1
continue
j = i
- while j < len(blocks) and blocks[j]['type'] == 'field':
- m = _fieldre.match(blocks[j]['lines'][0])
+ while j < len(blocks) and blocks[j][b'type'] == b'field':
+ m = _fieldre.match(blocks[j][b'lines'][0])
key, rest = m.groups()
- blocks[j]['lines'][0] = rest
- blocks[j]['key'] = key
+ blocks[j][b'lines'][0] = rest
+ blocks[j][b'key'] = key
j += 1
i = j + 1
@@ -240,37 +240,37 @@
def updateoptionlists(blocks):
i = 0
while i < len(blocks):
- if blocks[i]['type'] != 'option':
+ if blocks[i][b'type'] != b'option':
i += 1
continue
optstrwidth = 0
j = i
- while j < len(blocks) and blocks[j]['type'] == 'option':
- m = _optionre.match(blocks[j]['lines'][0])
+ while j < len(blocks) and blocks[j][b'type'] == b'option':
+ m = _optionre.match(blocks[j][b'lines'][0])
shortoption = m.group(2)
group3 = m.group(3)
longoption = group3[2:].strip()
desc = m.group(6).strip()
longoptionarg = m.group(5).strip()
- blocks[j]['lines'][0] = desc
+ blocks[j][b'lines'][0] = desc
- noshortop = ''
+ noshortop = b''
if not shortoption:
- noshortop = ' '
+ noshortop = b' '
- opt = "%s%s" % (
- shortoption and "-%s " % shortoption or '',
- "%s--%s %s" % (noshortop, longoption, longoptionarg),
+ opt = b"%s%s" % (
+ shortoption and b"-%s " % shortoption or b'',
+ b"%s--%s %s" % (noshortop, longoption, longoptionarg),
)
opt = opt.rstrip()
- blocks[j]['optstr'] = opt
+ blocks[j][b'optstr'] = opt
optstrwidth = max(optstrwidth, encoding.colwidth(opt))
j += 1
for block in blocks[i:j]:
- block['optstrwidth'] = optstrwidth
+ block[b'optstrwidth'] = optstrwidth
i = j + 1
return blocks
@@ -291,15 +291,15 @@
# +---+ |
# | blocks |
# +-------------------------------+
- if blocks[i]['type'] == 'paragraph' and blocks[i]['lines'][
+ if blocks[i][b'type'] == b'paragraph' and blocks[i][b'lines'][
0
- ].startswith('.. container::'):
- indent = blocks[i]['indent']
- adjustment = blocks[i + 1]['indent'] - indent
- containertype = blocks[i]['lines'][0][15:]
+ ].startswith(b'.. container::'):
+ indent = blocks[i][b'indent']
+ adjustment = blocks[i + 1][b'indent'] - indent
+ containertype = blocks[i][b'lines'][0][15:]
prune = True
for c in keep:
- if c in containertype.split('.'):
+ if c in containertype.split(b'.'):
prune = False
if prune:
pruned.append(containertype)
@@ -308,11 +308,11 @@
del blocks[i]
j = i
i -= 1
- while j < len(blocks) and blocks[j]['indent'] > indent:
+ while j < len(blocks) and blocks[j][b'indent'] > indent:
if prune:
del blocks[j]
else:
- blocks[j]['indent'] -= adjustment
+ blocks[j][b'indent'] -= adjustment
j += 1
i += 1
return blocks, pruned
@@ -337,26 +337,26 @@
# x y z
# === ==== ===
if (
- block['type'] == 'paragraph'
- and len(block['lines']) > 2
- and _tablere.match(block['lines'][0])
- and block['lines'][0] == block['lines'][-1]
+ block[b'type'] == b'paragraph'
+ and len(block[b'lines']) > 2
+ and _tablere.match(block[b'lines'][0])
+ and block[b'lines'][0] == block[b'lines'][-1]
):
- block['type'] = 'table'
- block['header'] = False
- div = block['lines'][0]
+ block[b'type'] = b'table'
+ block[b'header'] = False
+ div = block[b'lines'][0]
# column markers are ASCII so we can calculate column
# position in bytes
columns = [
x
for x in pycompat.xrange(len(div))
- if div[x : x + 1] == '=' and (x == 0 or div[x - 1 : x] == ' ')
+ if div[x : x + 1] == b'=' and (x == 0 or div[x - 1 : x] == b' ')
]
rows = []
- for l in block['lines'][1:-1]:
+ for l in block[b'lines'][1:-1]:
if l == div:
- block['header'] = True
+ block[b'header'] = True
continue
row = []
# we measure columns not in bytes or characters but in
@@ -372,7 +372,7 @@
row.append(l[pos:].strip())
rows.append(row)
- block['table'] = rows
+ block[b'table'] = rows
return blocks
@@ -391,34 +391,34 @@
# | ------------- |
# +------------------------------+
if (
- block['type'] == 'paragraph'
- and len(block['lines']) == 2
- and encoding.colwidth(block['lines'][0]) == len(block['lines'][1])
- and _sectionre.match(block['lines'][1])
+ block[b'type'] == b'paragraph'
+ and len(block[b'lines']) == 2
+ and encoding.colwidth(block[b'lines'][0]) == len(block[b'lines'][1])
+ and _sectionre.match(block[b'lines'][1])
):
- block['underline'] = block['lines'][1][0:1]
- block['type'] = 'section'
- del block['lines'][1]
+ block[b'underline'] = block[b'lines'][1][0:1]
+ block[b'type'] = b'section'
+ del block[b'lines'][1]
return blocks
def inlineliterals(blocks):
- substs = [('``', '"')]
+ substs = [(b'``', b'"')]
for b in blocks:
- if b['type'] in ('paragraph', 'section'):
- b['lines'] = [replace(l, substs) for l in b['lines']]
+ if b[b'type'] in (b'paragraph', b'section'):
+ b[b'lines'] = [replace(l, substs) for l in b[b'lines']]
return blocks
def hgrole(blocks):
- substs = [(':hg:`', "'hg "), ('`', "'")]
+ substs = [(b':hg:`', b"'hg "), (b'`', b"'")]
for b in blocks:
- if b['type'] in ('paragraph', 'section'):
+ if b[b'type'] in (b'paragraph', b'section'):
# Turn :hg:`command` into "hg command". This also works
# when there is a line break in the command and relies on
# the fact that we have no stray back-quotes in the input
# (run the blocks through inlineliterals first).
- b['lines'] = [replace(l, substs) for l in b['lines']]
+ b[b'lines'] = [replace(l, substs) for l in b[b'lines']]
return blocks
@@ -430,17 +430,17 @@
"""
i = 1
while i < len(blocks):
- if blocks[i]['type'] == blocks[i - 1]['type'] and blocks[i]['type'] in (
- 'bullet',
- 'option',
- 'field',
- ):
+ if blocks[i][b'type'] == blocks[i - 1][b'type'] and blocks[i][
+ b'type'
+ ] in (b'bullet', b'option', b'field',):
i += 1
- elif not blocks[i - 1]['lines']:
+ elif not blocks[i - 1][b'lines']:
# no lines in previous block, do not separate
i += 1
else:
- blocks.insert(i, {'lines': [''], 'indent': 0, 'type': 'margin'})
+ blocks.insert(
+ i, {b'lines': [b''], b'indent': 0, b'type': b'margin'}
+ )
i += 2
return blocks
@@ -450,11 +450,11 @@
i = 0
while i < len(blocks):
b = blocks[i]
- if b['type'] == 'paragraph' and (
- b['lines'][0].startswith('.. ') or b['lines'] == ['..']
+ if b[b'type'] == b'paragraph' and (
+ b[b'lines'][0].startswith(b'.. ') or b[b'lines'] == [b'..']
):
del blocks[i]
- if i < len(blocks) and blocks[i]['type'] == 'margin':
+ if i < len(blocks) and blocks[i][b'type'] == b'margin':
del blocks[i]
else:
i += 1
@@ -469,47 +469,47 @@
admonitions = admonitions or _admonitiontitles.keys()
admonitionre = re.compile(
- br'\.\. (%s)::' % '|'.join(sorted(admonitions)), flags=re.IGNORECASE
+ br'\.\. (%s)::' % b'|'.join(sorted(admonitions)), flags=re.IGNORECASE
)
i = 0
while i < len(blocks):
- m = admonitionre.match(blocks[i]['lines'][0])
+ m = admonitionre.match(blocks[i][b'lines'][0])
if m:
- blocks[i]['type'] = 'admonition'
- admonitiontitle = blocks[i]['lines'][0][3 : m.end() - 2].lower()
+ blocks[i][b'type'] = b'admonition'
+ admonitiontitle = blocks[i][b'lines'][0][3 : m.end() - 2].lower()
- firstline = blocks[i]['lines'][0][m.end() + 1 :]
+ firstline = blocks[i][b'lines'][0][m.end() + 1 :]
if firstline:
- blocks[i]['lines'].insert(1, ' ' + firstline)
+ blocks[i][b'lines'].insert(1, b' ' + firstline)
- blocks[i]['admonitiontitle'] = admonitiontitle
- del blocks[i]['lines'][0]
+ blocks[i][b'admonitiontitle'] = admonitiontitle
+ del blocks[i][b'lines'][0]
i = i + 1
return blocks
_admonitiontitles = {
- 'attention': _('Attention:'),
- 'caution': _('Caution:'),
- 'danger': _('!Danger!'),
- 'error': _('Error:'),
- 'hint': _('Hint:'),
- 'important': _('Important:'),
- 'note': _('Note:'),
- 'tip': _('Tip:'),
- 'warning': _('Warning!'),
+ b'attention': _(b'Attention:'),
+ b'caution': _(b'Caution:'),
+ b'danger': _(b'!Danger!'),
+ b'error': _(b'Error:'),
+ b'hint': _(b'Hint:'),
+ b'important': _(b'Important:'),
+ b'note': _(b'Note:'),
+ b'tip': _(b'Tip:'),
+ b'warning': _(b'Warning!'),
}
def formatoption(block, width):
- desc = ' '.join(map(bytes.strip, block['lines']))
- colwidth = encoding.colwidth(block['optstr'])
+ desc = b' '.join(map(bytes.strip, block[b'lines']))
+ colwidth = encoding.colwidth(block[b'optstr'])
usablewidth = width - 1
- hanging = block['optstrwidth']
- initindent = '%s%s ' % (block['optstr'], ' ' * ((hanging - colwidth)))
- hangindent = ' ' * (encoding.colwidth(initindent) + 1)
- return ' %s\n' % (
+ hanging = block[b'optstrwidth']
+ initindent = b'%s%s ' % (block[b'optstr'], b' ' * ((hanging - colwidth)))
+ hangindent = b' ' * (encoding.colwidth(initindent) + 1)
+ return b' %s\n' % (
stringutil.wrap(
desc, usablewidth, initindent=initindent, hangindent=hangindent
)
@@ -520,91 +520,91 @@
"""Format a block according to width."""
if width <= 0:
width = 78
- indent = ' ' * block['indent']
- if block['type'] == 'admonition':
- admonition = _admonitiontitles[block['admonitiontitle']]
- if not block['lines']:
- return indent + admonition + '\n'
- hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
+ indent = b' ' * block[b'indent']
+ if block[b'type'] == b'admonition':
+ admonition = _admonitiontitles[block[b'admonitiontitle']]
+ if not block[b'lines']:
+ return indent + admonition + b'\n'
+ hang = len(block[b'lines'][-1]) - len(block[b'lines'][-1].lstrip())
- defindent = indent + hang * ' '
- text = ' '.join(map(bytes.strip, block['lines']))
- return '%s\n%s\n' % (
+ defindent = indent + hang * b' '
+ text = b' '.join(map(bytes.strip, block[b'lines']))
+ return b'%s\n%s\n' % (
indent + admonition,
stringutil.wrap(
text, width=width, initindent=defindent, hangindent=defindent
),
)
- if block['type'] == 'margin':
- return '\n'
- if block['type'] == 'literal':
- indent += ' '
- return indent + ('\n' + indent).join(block['lines']) + '\n'
- if block['type'] == 'section':
- underline = encoding.colwidth(block['lines'][0]) * block['underline']
- return "%s%s\n%s%s\n" % (indent, block['lines'][0], indent, underline)
- if block['type'] == 'table':
- table = block['table']
+ if block[b'type'] == b'margin':
+ return b'\n'
+ if block[b'type'] == b'literal':
+ indent += b' '
+ return indent + (b'\n' + indent).join(block[b'lines']) + b'\n'
+ if block[b'type'] == b'section':
+ underline = encoding.colwidth(block[b'lines'][0]) * block[b'underline']
+ return b"%s%s\n%s%s\n" % (indent, block[b'lines'][0], indent, underline)
+ if block[b'type'] == b'table':
+ table = block[b'table']
# compute column widths
widths = [max([encoding.colwidth(e) for e in c]) for c in zip(*table)]
- text = ''
+ text = b''
span = sum(widths) + len(widths) - 1
- indent = ' ' * block['indent']
- hang = ' ' * (len(indent) + span - widths[-1])
+ indent = b' ' * block[b'indent']
+ hang = b' ' * (len(indent) + span - widths[-1])
for row in table:
l = []
for w, v in zip(widths, row):
- pad = ' ' * (w - encoding.colwidth(v))
+ pad = b' ' * (w - encoding.colwidth(v))
l.append(v + pad)
- l = ' '.join(l)
+ l = b' '.join(l)
l = stringutil.wrap(
l, width=width, initindent=indent, hangindent=hang
)
- if not text and block['header']:
- text = l + '\n' + indent + '-' * (min(width, span)) + '\n'
+ if not text and block[b'header']:
+ text = l + b'\n' + indent + b'-' * (min(width, span)) + b'\n'
else:
- text += l + "\n"
+ text += l + b"\n"
return text
- if block['type'] == 'definition':
- term = indent + block['lines'][0]
- hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
- defindent = indent + hang * ' '
- text = ' '.join(map(bytes.strip, block['lines'][1:]))
- return '%s\n%s\n' % (
+ if block[b'type'] == b'definition':
+ term = indent + block[b'lines'][0]
+ hang = len(block[b'lines'][-1]) - len(block[b'lines'][-1].lstrip())
+ defindent = indent + hang * b' '
+ text = b' '.join(map(bytes.strip, block[b'lines'][1:]))
+ return b'%s\n%s\n' % (
term,
stringutil.wrap(
text, width=width, initindent=defindent, hangindent=defindent
),
)
subindent = indent
- if block['type'] == 'bullet':
- if block['lines'][0].startswith('| '):
+ if block[b'type'] == b'bullet':
+ if block[b'lines'][0].startswith(b'| '):
# Remove bullet for line blocks and add no extra
# indentation.
- block['lines'][0] = block['lines'][0][2:]
+ block[b'lines'][0] = block[b'lines'][0][2:]
else:
- m = _bulletre.match(block['lines'][0])
- subindent = indent + m.end() * ' '
- elif block['type'] == 'field':
- key = block['key']
- subindent = indent + _fieldwidth * ' '
+ m = _bulletre.match(block[b'lines'][0])
+ subindent = indent + m.end() * b' '
+ elif block[b'type'] == b'field':
+ key = block[b'key']
+ subindent = indent + _fieldwidth * b' '
if len(key) + 2 > _fieldwidth:
# key too large, use full line width
key = key.ljust(width)
else:
# key fits within field width
key = key.ljust(_fieldwidth)
- block['lines'][0] = key + block['lines'][0]
- elif block['type'] == 'option':
+ block[b'lines'][0] = key + block[b'lines'][0]
+ elif block[b'type'] == b'option':
return formatoption(block, width)
- text = ' '.join(map(bytes.strip, block['lines']))
+ text = b' '.join(map(bytes.strip, block[b'lines']))
return (
stringutil.wrap(
text, width=width, initindent=indent, hangindent=subindent
)
- + '\n'
+ + b'\n'
)
@@ -612,7 +612,7 @@
"""Format RST blocks as HTML"""
out = []
- headernest = ''
+ headernest = b''
listnest = []
def escape(s):
@@ -621,91 +621,91 @@
def openlist(start, level):
if not listnest or listnest[-1][0] != start:
listnest.append((start, level))
- out.append('<%s>\n' % start)
+ out.append(b'<%s>\n' % start)
- blocks = [b for b in blocks if b['type'] != 'margin']
+ blocks = [b for b in blocks if b[b'type'] != b'margin']
for pos, b in enumerate(blocks):
- btype = b['type']
- level = b['indent']
- lines = b['lines']
+ btype = b[b'type']
+ level = b[b'indent']
+ lines = b[b'lines']
- if btype == 'admonition':
- admonition = escape(_admonitiontitles[b['admonitiontitle']])
- text = escape(' '.join(map(bytes.strip, lines)))
- out.append('<p>\n<b>%s</b> %s\n</p>\n' % (admonition, text))
- elif btype == 'paragraph':
- out.append('<p>\n%s\n</p>\n' % escape('\n'.join(lines)))
- elif btype == 'margin':
+ if btype == b'admonition':
+ admonition = escape(_admonitiontitles[b[b'admonitiontitle']])
+ text = escape(b' '.join(map(bytes.strip, lines)))
+ out.append(b'<p>\n<b>%s</b> %s\n</p>\n' % (admonition, text))
+ elif btype == b'paragraph':
+ out.append(b'<p>\n%s\n</p>\n' % escape(b'\n'.join(lines)))
+ elif btype == b'margin':
pass
- elif btype == 'literal':
- out.append('<pre>\n%s\n</pre>\n' % escape('\n'.join(lines)))
- elif btype == 'section':
- i = b['underline']
+ elif btype == b'literal':
+ out.append(b'<pre>\n%s\n</pre>\n' % escape(b'\n'.join(lines)))
+ elif btype == b'section':
+ i = b[b'underline']
if i not in headernest:
headernest += i
level = headernest.index(i) + 1
- out.append('<h%d>%s</h%d>\n' % (level, escape(lines[0]), level))
- elif btype == 'table':
- table = b['table']
- out.append('<table>\n')
+ out.append(b'<h%d>%s</h%d>\n' % (level, escape(lines[0]), level))
+ elif btype == b'table':
+ table = b[b'table']
+ out.append(b'<table>\n')
for row in table:
- out.append('<tr>')
+ out.append(b'<tr>')
for v in row:
- out.append('<td>')
+ out.append(b'<td>')
out.append(escape(v))
- out.append('</td>')
- out.append('\n')
+ out.append(b'</td>')
+ out.append(b'\n')
out.pop()
- out.append('</tr>\n')
- out.append('</table>\n')
- elif btype == 'definition':
- openlist('dl', level)
+ out.append(b'</tr>\n')
+ out.append(b'</table>\n')
+ elif btype == b'definition':
+ openlist(b'dl', level)
term = escape(lines[0])
- text = escape(' '.join(map(bytes.strip, lines[1:])))
- out.append(' <dt>%s\n <dd>%s\n' % (term, text))
- elif btype == 'bullet':
- bullet, head = lines[0].split(' ', 1)
- if bullet in ('*', '-'):
- openlist('ul', level)
+ text = escape(b' '.join(map(bytes.strip, lines[1:])))
+ out.append(b' <dt>%s\n <dd>%s\n' % (term, text))
+ elif btype == b'bullet':
+ bullet, head = lines[0].split(b' ', 1)
+ if bullet in (b'*', b'-'):
+ openlist(b'ul', level)
else:
- openlist('ol', level)
- out.append(' <li> %s\n' % escape(' '.join([head] + lines[1:])))
- elif btype == 'field':
- openlist('dl', level)
- key = escape(b['key'])
- text = escape(' '.join(map(bytes.strip, lines)))
- out.append(' <dt>%s\n <dd>%s\n' % (key, text))
- elif btype == 'option':
- openlist('dl', level)
- opt = escape(b['optstr'])
- desc = escape(' '.join(map(bytes.strip, lines)))
- out.append(' <dt>%s\n <dd>%s\n' % (opt, desc))
+ openlist(b'ol', level)
+ out.append(b' <li> %s\n' % escape(b' '.join([head] + lines[1:])))
+ elif btype == b'field':
+ openlist(b'dl', level)
+ key = escape(b[b'key'])
+ text = escape(b' '.join(map(bytes.strip, lines)))
+ out.append(b' <dt>%s\n <dd>%s\n' % (key, text))
+ elif btype == b'option':
+ openlist(b'dl', level)
+ opt = escape(b[b'optstr'])
+ desc = escape(b' '.join(map(bytes.strip, lines)))
+ out.append(b' <dt>%s\n <dd>%s\n' % (opt, desc))
# close lists if indent level of next block is lower
if listnest:
start, level = listnest[-1]
if pos == len(blocks) - 1:
- out.append('</%s>\n' % start)
+ out.append(b'</%s>\n' % start)
listnest.pop()
else:
nb = blocks[pos + 1]
- ni = nb['indent']
+ ni = nb[b'indent']
if ni < level or (
ni == level
- and nb['type'] not in 'definition bullet field option'
+ and nb[b'type'] not in b'definition bullet field option'
):
- out.append('</%s>\n' % start)
+ out.append(b'</%s>\n' % start)
listnest.pop()
- return ''.join(out)
+ return b''.join(out)
def parse(text, indent=0, keep=None, admonitions=None):
"""Parse text into a list of blocks"""
blocks = findblocks(text)
for b in blocks:
- b['indent'] += indent
+ b[b'indent'] += indent
blocks = findliteralblocks(blocks)
blocks = findtables(blocks)
blocks, pruned = prunecontainers(blocks, keep or [])
@@ -722,21 +722,21 @@
def formatblocks(blocks, width):
- text = ''.join(formatblock(b, width) for b in blocks)
+ text = b''.join(formatblock(b, width) for b in blocks)
return text
def formatplain(blocks, width):
"""Format parsed blocks as plain text"""
- return ''.join(formatblock(b, width) for b in blocks)
+ return b''.join(formatblock(b, width) for b in blocks)
-def format(text, width=80, indent=0, keep=None, style='plain', section=None):
+def format(text, width=80, indent=0, keep=None, style=b'plain', section=None):
"""Parse and format the text according to width."""
blocks, pruned = parse(text, indent, keep or [])
if section:
blocks = filtersections(blocks, section)
- if style == 'html':
+ if style == b'html':
return formathtml(blocks)
else:
return formatplain(blocks, width=width)
@@ -759,7 +759,7 @@
path, nest, b = sections[i]
del parents[nest:]
parents.append(i)
- if path == section or path.endswith('.' + section):
+ if path == section or path.endswith(b'.' + section):
if lastparents != parents:
llen = len(lastparents)
plen = len(parents)
@@ -787,11 +787,11 @@
if collapse:
synthetic.reverse()
for s in synthetic:
- path = [blocks[syn]['lines'][0] for syn in s]
+ path = [blocks[syn][b'lines'][0] for syn in s]
real = s[-1] + 2
- realline = blocks[real]['lines']
- realline[0] = '"%s"' % '.'.join(path + [realline[0]]).replace(
- '"', ''
+ realline = blocks[real][b'lines']
+ realline[0] = b'"%s"' % b'.'.join(path + [realline[0]]).replace(
+ b'"', b''
)
del blocks[s[0] : real]
@@ -800,31 +800,31 @@
def _getsections(blocks):
'''return a list of (section path, nesting level, blocks) tuples'''
- nest = ""
+ nest = b""
names = ()
secs = []
def getname(b):
- if b['type'] == 'field':
- x = b['key']
+ if b[b'type'] == b'field':
+ x = b[b'key']
else:
- x = b['lines'][0]
- x = encoding.lower(x).strip('"')
- if '(' in x:
- x = x.split('(')[0]
+ x = b[b'lines'][0]
+ x = encoding.lower(x).strip(b'"')
+ if b'(' in x:
+ x = x.split(b'(')[0]
return x
for b in blocks:
- if b['type'] == 'section':
- i = b['underline']
+ if b[b'type'] == b'section':
+ i = b[b'underline']
if i not in nest:
nest += i
level = nest.index(i) + 1
nest = nest[:level]
names = names[:level] + (getname(b),)
- secs.append(('.'.join(names), level, [b]))
- elif b['type'] in ('definition', 'field'):
- i = ' '
+ secs.append((b'.'.join(names), level, [b]))
+ elif b[b'type'] in (b'definition', b'field'):
+ i = b' '
if i not in nest:
nest += i
level = nest.index(i) + 1
@@ -833,10 +833,10 @@
sec = secs[-i]
if sec[1] < level:
break
- siblings = [a for a in sec[2] if a['type'] == 'definition']
+ siblings = [a for a in sec[2] if a[b'type'] == b'definition']
if siblings:
- siblingindent = siblings[-1]['indent']
- indent = b['indent']
+ siblingindent = siblings[-1][b'indent']
+ indent = b[b'indent']
if siblingindent < indent:
level += 1
break
@@ -844,30 +844,30 @@
level = sec[1]
break
names = names[:level] + (getname(b),)
- secs.append(('.'.join(names), level, [b]))
+ secs.append((b'.'.join(names), level, [b]))
else:
if not secs:
# add an initial empty section
- secs = [('', 0, [])]
- if b['type'] != 'margin':
+ secs = [(b'', 0, [])]
+ if b[b'type'] != b'margin':
pointer = 1
- bindent = b['indent']
+ bindent = b[b'indent']
while pointer < len(secs):
section = secs[-pointer][2][0]
- if section['type'] != 'margin':
- sindent = section['indent']
- if len(section['lines']) > 1:
- sindent += len(section['lines'][1]) - len(
- section['lines'][1].lstrip(' ')
+ if section[b'type'] != b'margin':
+ sindent = section[b'indent']
+ if len(section[b'lines']) > 1:
+ sindent += len(section[b'lines'][1]) - len(
+ section[b'lines'][1].lstrip(b' ')
)
if bindent >= sindent:
break
pointer += 1
if pointer > 1:
blevel = secs[-pointer][1]
- if section['type'] != b['type']:
+ if section[b'type'] != b[b'type']:
blevel += 1
- secs.append(('', blevel, []))
+ secs.append((b'', blevel, []))
secs[-1][2].append(b)
return secs
@@ -876,20 +876,20 @@
'''Generate an RST table for the given table data as a list of lines'''
widths = [max(encoding.colwidth(e) for e in c) for c in zip(*data)]
- indent = ' ' * indent
- div = indent + ' '.join('=' * w for w in widths) + '\n'
+ indent = b' ' * indent
+ div = indent + b' '.join(b'=' * w for w in widths) + b'\n'
out = [div]
for row in data:
l = []
for w, v in zip(widths, row):
- if '\n' in v:
+ if b'\n' in v:
# only remove line breaks and indentation, long lines are
# handled by the next tool
- v = ' '.join(e.lstrip() for e in v.split('\n'))
- pad = ' ' * (w - encoding.colwidth(v))
+ v = b' '.join(e.lstrip() for e in v.split(b'\n'))
+ pad = b' ' * (w - encoding.colwidth(v))
l.append(v + pad)
- out.append(indent + ' '.join(l) + "\n")
+ out.append(indent + b' '.join(l) + b"\n")
if header and len(data) > 1:
out.insert(2, div)
out.append(div)