Skip to content
This repository was archived by the owner on Mar 26, 2022. It is now read-only.

Commit ab211d7

Browse files
authored
Merge pull request #87 from rtfd/spec-0.27
Update commonmark spec to 0.27
2 parents cb8f9e4 + 972020d commit ab211d7

File tree

4 files changed

+135
-72
lines changed

4 files changed

+135
-72
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.7.3
2+
- The CommonMark spec has been updated to 0.27.
3+
14
## 0.7.2 (2016-08-10)
25
- Removed outdated files from distributed packages, reported by @hyperknot
36

CommonMark/blocks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
reATXHeadingMarker = re.compile(r'^#{1,6}(?:[ \t]+|$)')
4848
reCodeFence = re.compile(r'^`{3,}(?!.*`)|^~{3,}(?!.*~)')
4949
reClosingCodeFence = re.compile(r'^(?:`{3,}|~{3,})(?= *$)')
50-
reSetextHeadingLine = re.compile(r'^(?:=+|-+) *$')
50+
reSetextHeadingLine = re.compile(r'^(?:=+|-+)[ \t]*$')
5151
reLineEnding = re.compile(r'\r\n|\n|\r')
5252

5353

CommonMark/inlines.py

+40-20
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
# Some regexps used in inline parser:
2121

2222
ESCAPED_CHAR = '\\\\' + common.ESCAPABLE
23-
REG_CHAR = '[^\\\\()\\x00-\\x20]'
24-
IN_PARENS_NOSP = '\\((' + REG_CHAR + '|' + ESCAPED_CHAR + '|\\\\)*\\)'
2523

2624
rePunctuation = re.compile(
2725
r'^[\u2000-\u206F\u2E00-\u2E7F\\' + "'" + '!"#\$%&\(\)'
@@ -36,9 +34,6 @@
3634
reLinkDestinationBraces = re.compile(
3735
'^(?:[<](?:[^ <>\\t\\n\\\\\\x00]' + '|' + ESCAPED_CHAR + '|' +
3836
'\\\\)*[>])')
39-
reLinkDestination = re.compile(
40-
'^(?:' + REG_CHAR + '+|' + ESCAPED_CHAR + '|\\\\|' +
41-
IN_PARENS_NOSP + ')*')
4237

4338
reEscapable = re.compile('^' + common.ESCAPABLE)
4439
reEntityHere = re.compile('^' + common.ENTITY, re.IGNORECASE)
@@ -54,8 +49,9 @@
5449
r'^<[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*>',
5550
re.IGNORECASE)
5651
reSpnl = re.compile(r'^ *(?:\n *)?')
57-
reWhitespaceChar = re.compile(r'^\s')
58-
reWhitespace = re.compile(r'\s+')
52+
reWhitespaceChar = re.compile(r'^^[ \t\n\x0b\x0c\x0d]')
53+
reWhitespace = re.compile(r'[ \t\n\x0b\x0c\x0d]+')
54+
reUnicodeWhitespaceChar = re.compile(r'^\s')
5955
reFinalSpace = re.compile(r' *$')
6056
reInitialSpace = re.compile(r'^ *')
6157
reSpaceAtEndOfLine = re.compile(r'^ *(?:\n|$)')
@@ -262,10 +258,10 @@ def scanDelims(self, c):
262258
c_after = '\n'
263259

264260
# Python 2 doesn't recognize '\xa0' as whitespace
265-
after_is_whitespace = re.match(reWhitespaceChar, c_after) or \
261+
after_is_whitespace = re.match(reUnicodeWhitespaceChar, c_after) or \
266262
c_after == '\xa0'
267263
after_is_punctuation = re.match(rePunctuation, c_after)
268-
before_is_whitespace = re.match(reWhitespaceChar, c_before) or \
264+
before_is_whitespace = re.match(reUnicodeWhitespaceChar, c_before) or \
269265
c_before == '\xa0'
270266
before_is_punctuation = re.match(rePunctuation, c_before)
271267

@@ -318,6 +314,7 @@ def handleDelim(self, cc, block):
318314
self.delimiters = {
319315
'cc': cc,
320316
'numdelims': numdelims,
317+
'origdelims': numdelims,
321318
'node': node,
322319
'previous': self.delimiters,
323320
'next': None,
@@ -372,8 +369,8 @@ def processEmphasis(self, stack_bottom):
372369
opener != openers_bottom[closercc]):
373370
odd_match = (closer.get('can_open') or
374371
opener.get('can_close')) and \
375-
(opener.get('numdelims') +
376-
closer.get('numdelims')) % 3 == 0
372+
(opener.get('origdelims') +
373+
closer.get('origdelims')) % 3 == 0
377374
if opener.get('cc') == closercc and \
378375
opener.get('can_open') and \
379376
not odd_match:
@@ -487,11 +484,31 @@ def parseLinkDestination(self):
487484
"""
488485
res = self.match(reLinkDestinationBraces)
489486
if res is None:
490-
res = self.match(reLinkDestination)
491-
if res is None:
492-
return None
493-
else:
494-
return normalize_uri(unescape_string(res))
487+
# TODO handrolled parser; res should be None or the string
488+
savepos = self.pos
489+
openparens = 0
490+
c = self.peek()
491+
while c is not None:
492+
if c == '\\':
493+
self.pos += 1
494+
if self.peek() is not None:
495+
self.pos += 1
496+
elif c == '(':
497+
self.pos += 1
498+
openparens += 1
499+
elif c == ')':
500+
if openparens < 1:
501+
break
502+
else:
503+
self.pos += 1
504+
openparens -= 1
505+
elif re.match(reWhitespaceChar, c):
506+
break
507+
else:
508+
self.pos += 1
509+
c = self.peek()
510+
res = self.subject[savepos:self.pos]
511+
return normalize_uri(unescape_string(res))
495512
else:
496513
# chop off surrounding <..>:
497514
return normalize_uri(unescape_string(res[1:-1]))
@@ -575,22 +592,25 @@ def parseCloseBracket(self, block):
575592

576593
# Check to see if we have a link/image
577594

595+
savepos = self.pos
596+
578597
# Inline link?
579598
if self.peek() == '(':
580599
self.pos += 1
581600
self.spnl()
582601
dest = self.parseLinkDestination()
583-
if dest is not None and \
584-
self.spnl():
602+
if dest is not None and self.spnl():
585603
# make sure there's a space before the title
586604
if re.match(reWhitespaceChar, self.subject[self.pos-1]):
587605
title = self.parseLinkTitle()
588606
if self.spnl() and self.peek() == ')':
589607
self.pos += 1
590608
matched = True
591-
else:
609+
else:
610+
self.pos = savepos
611+
612+
if not matched:
592613
# Next, see if there's a link label
593-
savepos = self.pos
594614
beforelabel = self.pos
595615
n = self.parseLinkLabel()
596616
if n > 2:

0 commit comments

Comments
 (0)