Skip to content

Commit

Permalink
Merge pull request #67 from brondsem/restricted_styles
Browse files Browse the repository at this point in the history
Restore restricted mode effect on inline styles.  Fixes #65

Thanks, @brondsem ! And sorry for the delay.
  • Loading branch information
ikirudennis committed Jun 8, 2019
2 parents f833df6 + 304d074 commit eea71e3
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 36 deletions.
40 changes: 40 additions & 0 deletions tests/test_textile.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,46 @@ def test_restricted():

assert result == expect

test = "p{color:blue}. is this blue?"
result = textile.textile_restricted(test)
expect = '\t<p>is this blue?</p>'

assert result == expect

test = """\
table{border:1px solid black}.
|={color:gray}. Your caption goes here
|~.
|{position:absolute}. A footer | foo |
|-.
|_{font-size:xxlarge}. header|_=. centered header|
|~. bottom aligned|{background:red;width:200px}. asfd|"""
result = textile.textile_restricted(test, lite=False)
# styles from alignment hints like =. and ~. are ok
expect = '''\
\t<table>
\t<caption>Your caption goes here</caption>
\t
\t<tfoot>
\t\t<tr>
\t\t\t<td>A footer </td>
\t\t\t<td> foo </td>
\t\t</tr>
\t</tfoot>
\t<tbody>
\t\t<tr>
\t\t\t<th>header</th>
\t\t\t<th style="text-align:center;">centered header</th>
\t\t</tr>
\t\t<tr>
\t\t\t<td style="vertical-align:bottom;">bottom aligned</td>
\t\t\t<td>asfd</td>
\t\t</tr>
\t</tbody>
\t</table>'''

assert result == expect

def test_unicode_footnote():
html = textile.textile('текст[1]')
assert re.compile(r'^\t<p>текст<sup class="footnote" id="fnrev([a-f0-9]{32})-1"><a href="#fn\1-1">1</a></sup></p>$', re.U).search(html) is not None
Expand Down
16 changes: 8 additions & 8 deletions textile/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def fTextileList(self, match):
if ';' in pt and ':' in tl:
ls[tl] = 2

atts = pba(atts)
atts = pba(atts, restricted=self.restricted)
tabs = '\t' * len(tl)
# If start is still None, set it to '', else leave the value
# that we've already formatted.
Expand Down Expand Up @@ -961,7 +961,7 @@ def _casesdefault(c, pop, popped, url_chars, counts, pre):
text = self.span(text)
text = self.glyphs(text)
url = self.shelveURL(self.encode_url(urlunsplit(uri_parts)))
attributes = parse_attributes(atts)
attributes = parse_attributes(atts, restricted=self.restricted)
if title:
# if the title contains unicode data, it is annoying to get Python
# 2.6 and all the latter versions working properly. But shelving
Expand Down Expand Up @@ -1078,7 +1078,7 @@ def fSpan(self, match):
}

tag = qtags[tag]
atts = pba(atts)
atts = pba(atts, restricted=self.restricted)
if cite:
atts = '{0} cite="{1}"'.format(atts, cite.rstrip())

Expand Down Expand Up @@ -1131,7 +1131,7 @@ def fImage(self, match):
atts.update(height=six.text_type(size[1]))
atts.update(src=url)
if attributes:
atts.update(parse_attributes(attributes))
atts.update(parse_attributes(attributes, restricted=self.restricted))
if title:
atts.update(title=title)
if size:
Expand Down Expand Up @@ -1220,7 +1220,7 @@ def fRCList(self, match):
atts, content = m.groups()
# cleanup
content = content.strip()
atts = pba(atts)
atts = pba(atts, restricted=self.restricted)

# split the content into the term and definition
xm = re.match(r'^(.*?)[\s]*:=(.*?)[\s]*(=:|:=)?[\s]*$', content,
Expand Down Expand Up @@ -1306,7 +1306,7 @@ def fNoteLists(self, match):
o.append(li)
self.notelist_cache[index] = "\n".join(o)
result = self.notelist_cache[index]
list_atts = pba(att)
list_atts = pba(att, restricted=self.restricted)
result = '<ol{0}>\n{1}\n\t</ol>'.format(list_atts, result)
return result

Expand Down Expand Up @@ -1351,7 +1351,7 @@ def fParseNoteDefs(self, m):

# Ignores subsequent defs using the same label
if 'def' not in self.notes[label]: # pragma: no branch
self.notes[label]['def'] = {'atts': pba(att), 'content':
self.notes[label]['def'] = {'atts': pba(att, restricted=self.restricted), 'content':
self.graf(content), 'link': link}
return ''

Expand All @@ -1373,7 +1373,7 @@ def fParseNoteRefs(self, match):
processed into the notes array. So now we can resolve the link numbers
in the order we process the refs..."""
atts, label, nolink = match.groups()
atts = pba(atts)
atts = pba(atts, restricted=self.restricted)
nolink = nolink == '!'

# Assign a sequence number to this reference if there isn't one already
Expand Down
4 changes: 2 additions & 2 deletions textile/objects/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(self, textile, tag, atts, ext, cite, content):
self.cite = cite
self.content = content

self.attributes = parse_attributes(atts)
self.attributes = parse_attributes(atts, restricted=self.textile.restricted)
self.outer_tag = ''
self.inner_tag = ''
self.outer_atts = OrderedDict()
Expand Down Expand Up @@ -69,7 +69,7 @@ def process(self):
if 'id' not in self.attributes:
self.attributes.update({'id': 'fn{0}'.format(fnid)})
else:
supp_id = parse_attributes('(#fn{0})'.format(fnid))
supp_id = parse_attributes('(#fn{0})'.format(fnid), restricted=self.textile.restricted)


if '^' not in self.atts:
Expand Down
39 changes: 20 additions & 19 deletions textile/objects/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class Table(object):
def __init__(self, textile, tatts, rows, summary):
self.textile = textile
self.attributes = parse_attributes(tatts, 'table')
self.attributes = parse_attributes(tatts, 'table', restricted=self.textile.restricted)
if summary:
self.attributes.update(summary=summary.strip())
self.input = rows
Expand All @@ -44,7 +44,7 @@ def process(self):
caption_re = re.compile(captionpattern, re.S)
cmtch = caption_re.match(row)
if cmtch:
caption = Caption(**cmtch.groupdict())
caption = Caption(restricted=self.textile.restricted, **cmtch.groupdict())
self.caption = '\n{0}'.format(caption.caption)
row = cmtch.group('row').lstrip()
if row == '':
Expand All @@ -60,7 +60,7 @@ def process(self):
colgroup_atts, cols = colgroup_data, None
if '|' in colgroup_data:
colgroup_atts, cols = colgroup_data.split('|', 1)
colgrp = Colgroup(cols, colgroup_atts)
colgrp = Colgroup(cols, colgroup_atts, restricted=self.textile.restricted)
self.colgroup = colgrp.process()
if row == '':
continue
Expand All @@ -79,13 +79,13 @@ def process(self):
if rgrp:
groups.append('\n\t{0}'.format(rgrp.process()))
rgrp = grptypes[grpmatch.group('part')](grpmatch.group(
'rgrpatts'))
'rgrpatts'), restricted=self.textile.restricted)
row = grpmatch.group('row')

rmtch = re.search(r'^(?P<ratts>{0}{1}\. )(?P<row>.*)'.format(
align_re_s, cls_re_s), row.lstrip())
if rmtch:
row_atts = parse_attributes(rmtch.group('ratts'), 'tr')
row_atts = parse_attributes(rmtch.group('ratts'), 'tr', restricted=self.textile.restricted)
row = rmtch.group('row')
else:
row_atts = {}
Expand All @@ -102,7 +102,7 @@ def process(self):
cls_re_s), cell, flags=re.S)
if cmtch:
catts = cmtch.group('catts')
cell_atts = parse_attributes(catts, 'td')
cell_atts = parse_attributes(catts, 'td', restricted=self.textile.restricted)
cell = cmtch.group('cell')
else:
cell_atts = {}
Expand Down Expand Up @@ -139,8 +139,8 @@ def process(self):


class Caption(object):
def __init__(self, capts, cap, row):
self.attributes = parse_attributes(capts)
def __init__(self, capts, cap, row, restricted):
self.attributes = parse_attributes(capts, restricted=restricted)
self.caption = self.process(cap)

def process(self, cap):
Expand All @@ -149,17 +149,18 @@ def process(self, cap):


class Colgroup(object):
def __init__(self, cols, atts):
def __init__(self, cols, atts, restricted):
self.row = ''
self.attributes = atts
self.cols = cols
self.restricted = restricted

def process(self):
enc = 'unicode'
if six.PY2: # pragma: no branch
enc = 'UTF-8'

group_atts = parse_attributes(self.attributes, 'col')
group_atts = parse_attributes(self.attributes, 'col', restricted=self.restricted)
colgroup = ElementTree.Element('colgroup', attrib=group_atts)
colgroup.text = '\n\t'
if self.cols is not None:
Expand All @@ -168,7 +169,7 @@ def process(self):
# colgroup is the first item in match_cols, the remaining items are
# cols.
for idx, col in enumerate(match_cols):
col_atts = parse_attributes(col.strip(), 'col')
col_atts = parse_attributes(col.strip(), 'col', restricted=self.restricted)
ElementTree.SubElement(colgroup, 'col', col_atts)
colgrp = ElementTree.tostring(colgroup, encoding=enc)
# cleanup the extra xml declaration if it exists, (python versions
Expand Down Expand Up @@ -205,25 +206,25 @@ def process(self):


class _TableSection(object):
def __init__(self, tag, attributes):
def __init__(self, tag, attributes, restricted):
self.tag = tag
self.attributes = parse_attributes(attributes)
self.attributes = parse_attributes(attributes, restricted=restricted)
self.rows = []

def process(self):
return generate_tag(self.tag, '{0}\n\t'.format(''.join(self.rows)), self.attributes)


class Thead(_TableSection):
def __init__(self, attributes):
super(Thead, self).__init__('thead', attributes)
def __init__(self, attributes, restricted):
super(Thead, self).__init__('thead', attributes, restricted)


class Tbody(_TableSection):
def __init__(self, attributes):
super(Tbody, self).__init__('tbody', attributes)
def __init__(self, attributes, restricted):
super(Tbody, self).__init__('tbody', attributes, restricted)


class Tfoot(_TableSection):
def __init__(self, attributes):
super(Tfoot, self).__init__('tfoot', attributes)
def __init__(self, attributes, restricted):
super(Tfoot, self).__init__('tfoot', attributes, restricted)
15 changes: 8 additions & 7 deletions textile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def normalize_newlines(string):
out = re.sub(r'"$', '" ', out)
return out

def parse_attributes(block_attributes, element=None, include_id=True):
def parse_attributes(block_attributes, element=None, include_id=True, restricted=False):
vAlign = {'^': 'top', '-': 'middle', '~': 'bottom'}
hAlign = {'<': 'left', '=': 'center', '>': 'right', '<>': 'justify'}
style = []
Expand Down Expand Up @@ -136,10 +136,11 @@ def parse_attributes(block_attributes, element=None, include_id=True):
if m:
style.append("vertical-align:{0}".format(vAlign[m.group(1)]))

m = re.search(r'\{([^}]*)\}', matched)
if m:
style.extend(m.group(1).rstrip(';').split(';'))
matched = matched.replace(m.group(0), '')
if not restricted:
m = re.search(r'\{([^}]*)\}', matched)
if m:
style.extend(m.group(1).rstrip(';').split(';'))
matched = matched.replace(m.group(0), '')

m = re.search(r'\[([^\]]+)\]', matched, re.U)
if m:
Expand Down Expand Up @@ -197,9 +198,9 @@ def parse_attributes(block_attributes, element=None, include_id=True):
result['width'] = width
return result

def pba(block_attributes, element=None, include_id=True):
def pba(block_attributes, element=None, include_id=True, restricted=False):
"""Parse block attributes."""
attrs = parse_attributes(block_attributes, element, include_id)
attrs = parse_attributes(block_attributes, element, include_id, restricted)
if not attrs:
return ''
result = ' '.join(['{0}="{1}"'.format(k, v) for k, v in attrs.items()])
Expand Down

0 comments on commit eea71e3

Please sign in to comment.