Python Markdown: Regexp problem in 'spantable.py' (Python Markdown 2.6.11)

As I noted in my original entry on issues with spantable.py, the version of Markdown installed using pip differs between Python 2 and Python 3: the Python 2 version is more up to date. This creates two issues when trying to use spantables in Python 2:

  1. The cell.get() method in xml.etree.elementtree doesn’t support the default keyword parameter
  2. The newer Markdown changed the way inline processors work.

I solved the first issue last week, by working around the fact the XML code in Python 2 is missing a feature. The spantables module now works with Markdown 2.6.7 in both Python 2 and Python 3, but I now have a problem in Markdown 2.6.11:

File "/home/brian/projects/python/markdown_extensions/spantables.py", line 37, in <module>
  from markdown.inlinepatterns import BacktickPattern, BACKTICK_RE
ImportError: Failed loading extension "markdown_extensions.spantables".

The BacktickPattern name is not exported from the inlinepatterns module in the newer Markdown. In addition, the pattern is 2.6.11 is more complex:

Markdown 2.6.7:  BACKTICK_RE = r'(?<!\\)(`+)(.+?)(?<!`)\2(?!`)'
Markdown 2.6.11: BACKTICK_RE = r'(?:(?<!\\)((?:\\{2})+)(?=`+)|(?<!\\)(`+)(.+?)(?<!`)\2(?!`))'

And therein seems to be the problem: although I haven’t analysed it closely, I suspect it’s possible for the new regexp to return only three fields instead of 4. So I added a check for that.

Original:

groups = match.groups()
delim = groups[1]         # the code block delimeter (ie 1 or more backticks)
row_contents = groups[2]  # the text contained inside the code block
i += match.start(4)       # jump pointer to the beginning of the rest of the text (group #4)
element = delim + row_contents + delim  # reinstert backticks
current += element

Updated:

groups = match.groups()
delim = groups[1]         # the code block delimeter (ie 1 or more backticks)
row_contents = groups[2]  # the text contained inside the code block
                          # jump pointer to the beginning of the rest of the text (group #4)
i += (match.start(4) if len(match.groups()) > 3 else 1) - 1 
element = delim + row_contents + delim  # reinstert backticks
current += element