aboutsummaryrefslogtreecommitdiffstats
path: root/markdown/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'markdown/extensions')
-rw-r--r--markdown/extensions/__init__.py33
-rw-r--r--markdown/extensions/abbr.py26
-rw-r--r--markdown/extensions/admonition.py14
-rw-r--r--markdown/extensions/attr_list.py30
-rw-r--r--markdown/extensions/codehilite.py77
-rw-r--r--markdown/extensions/def_list.py14
-rw-r--r--markdown/extensions/extra.py6
-rw-r--r--markdown/extensions/fenced_code.py34
-rw-r--r--markdown/extensions/footnotes.py102
-rw-r--r--markdown/extensions/headerid.py28
-rw-r--r--markdown/extensions/meta.py16
-rw-r--r--markdown/extensions/nl2br.py6
-rw-r--r--markdown/extensions/sane_lists.py9
-rw-r--r--markdown/extensions/smart_strong.py12
-rw-r--r--markdown/extensions/smarty.py76
-rw-r--r--markdown/extensions/tables.py14
-rw-r--r--markdown/extensions/toc.py93
-rw-r--r--markdown/extensions/wikilinks.py31
18 files changed, 346 insertions, 275 deletions
diff --git a/markdown/extensions/__init__.py b/markdown/extensions/__init__.py
index 03b2a4c..a823fef 100644
--- a/markdown/extensions/__init__.py
+++ b/markdown/extensions/__init__.py
@@ -7,9 +7,10 @@ from __future__ import unicode_literals
from ..util import parseBoolValue
import warnings
+
class Extension(object):
""" Base class for extensions to subclass. """
-
+
# Default config -- to be overriden by a subclass
# Must be of the following format:
# {
@@ -18,7 +19,7 @@ class Extension(object):
# Note that Extension.setConfig will raise a KeyError
# if a default is not set here.
config = {}
-
+
def __init__(self, *args, **kwargs):
""" Initiate Extension and set up configs. """
@@ -26,23 +27,26 @@ class Extension(object):
# (there only ever used to be one so we use arg[0])
if len(args):
self.setConfigs(args[0])
- warnings.warn('Extension classes accepting positional args is pending Deprecation. '
- 'Each setting should be passed into the Class as a keyword. Positional '
- 'args will be deprecated in version 2.6 and raise an error in version '
- '2.7. See the Release Notes for Python-Markdown version 2.5 for more info.',
+ warnings.warn('Extension classes accepting positional args is '
+ 'pending Deprecation. Each setting should be '
+ 'passed into the Class as a keyword. Positional '
+ 'args will be deprecated in version 2.6 and raise '
+ 'an error in version 2.7. See the Release Notes for '
+ 'Python-Markdown version 2.5 for more info.',
PendingDeprecationWarning)
# check for configs kwarg for backward compat.
if 'configs' in kwargs.keys():
self.setConfigs(kwargs.pop('configs', {}))
- warnings.warn('Extension classes accepting a dict on the single keyword "config" is '
- 'pending Deprecation. Each setting should be passed into the Class as '
- 'a keyword directly. The "config" keyword will be deprecated in version '
- '2.6 and raise an error in version 2.7. See the Release Notes for '
+ warnings.warn('Extension classes accepting a dict on the single '
+ 'keyword "config" is pending Deprecation. Each '
+ 'setting should be passed into the Class as a '
+ 'keyword directly. The "config" keyword will be '
+ 'deprecated in version 2.6 and raise an error in '
+ 'version 2.7. See the Release Notes for '
'Python-Markdown version 2.5 for more info.',
PendingDeprecationWarning)
# finally, use kwargs
self.setConfigs(kwargs)
-
def getConfig(self, key, default=''):
""" Return a setting for the given key or an empty string. """
@@ -88,6 +92,7 @@ class Extension(object):
* md_globals: Global variables in the markdown module namespace.
"""
- raise NotImplementedError('Extension "%s.%s" must define an "extendMarkdown"' \
- 'method.' % (self.__class__.__module__, self.__class__.__name__))
-
+ raise NotImplementedError(
+ 'Extension "%s.%s" must define an "extendMarkdown"'
+ 'method.' % (self.__class__.__module__, self.__class__.__name__)
+ )
diff --git a/markdown/extensions/abbr.py b/markdown/extensions/abbr.py
index 58dd0aa..353d126 100644
--- a/markdown/extensions/abbr.py
+++ b/markdown/extensions/abbr.py
@@ -4,7 +4,7 @@ Abbreviation Extension for Python-Markdown
This extension adds abbreviation handling to Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/abbreviations.html>
+See <https://pythonhosted.org/Markdown/extensions/abbreviations.html>
for documentation.
Oringinal code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/) and
@@ -12,7 +12,7 @@ Oringinal code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/) and
All changes Copyright 2008-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
'''
@@ -27,14 +27,15 @@ import re
# Global Vars
ABBR_REF_RE = re.compile(r'[*]\[(?P<abbr>[^\]]*)\][ ]?:\s*(?P<title>.*)')
+
class AbbrExtension(Extension):
""" Abbreviation Extension for Python-Markdown. """
def extendMarkdown(self, md, md_globals):
""" Insert AbbrPreprocessor before ReferencePreprocessor. """
md.preprocessors.add('abbr', AbbrPreprocessor(md), '<reference')
-
-
+
+
class AbbrPreprocessor(Preprocessor):
""" Abbreviation Preprocessor - parse text for abbr references. """
@@ -42,7 +43,7 @@ class AbbrPreprocessor(Preprocessor):
'''
Find and remove all Abbreviation references from the text.
Each reference is set as a new AbbrPattern in the markdown instance.
-
+
'''
new_text = []
for line in lines:
@@ -50,19 +51,19 @@ class AbbrPreprocessor(Preprocessor):
if m:
abbr = m.group('abbr').strip()
title = m.group('title').strip()
- self.markdown.inlinePatterns['abbr-%s'%abbr] = \
+ self.markdown.inlinePatterns['abbr-%s' % abbr] = \
AbbrPattern(self._generate_pattern(abbr), title)
else:
new_text.append(line)
return new_text
-
+
def _generate_pattern(self, text):
'''
- Given a string, returns an regex pattern to match that string.
-
- 'HTML' -> r'(?P<abbr>[H][T][M][L])'
-
- Note: we force each char as a literal match (in brackets) as we don't
+ Given a string, returns an regex pattern to match that string.
+
+ 'HTML' -> r'(?P<abbr>[H][T][M][L])'
+
+ Note: we force each char as a literal match (in brackets) as we don't
know what they will be beforehand.
'''
@@ -85,5 +86,6 @@ class AbbrPattern(Pattern):
abbr.set('title', self.title)
return abbr
+
def makeExtension(*args, **kwargs):
return AbbrExtension(*args, **kwargs)
diff --git a/markdown/extensions/admonition.py b/markdown/extensions/admonition.py
index 189f2c2..8fe3aee 100644
--- a/markdown/extensions/admonition.py
+++ b/markdown/extensions/admonition.py
@@ -4,16 +4,16 @@ Admonition extension for Python-Markdown
Adds rST-style admonitions. Inspired by [rST][] feature with the same name.
-[rST]: http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions
+[rST]: http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions # flake8: noqa
-See <https://pythonhosted.org/Markdown/extensions/admonition.html>
+See <https://pythonhosted.org/Markdown/extensions/admonition.html>
for documentation.
Original code Copyright [Tiago Serafim](http://www.tiagoserafim.com/).
All changes Copyright The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -46,8 +46,8 @@ class AdmonitionProcessor(BlockProcessor):
def test(self, parent, block):
sibling = self.lastChild(parent)
return self.RE.search(block) or \
- (block.startswith(' ' * self.tab_length) and sibling and \
- sibling.get('class', '').find(self.CLASSNAME) != -1)
+ (block.startswith(' ' * self.tab_length) and sibling and
+ sibling.get('class', '').find(self.CLASSNAME) != -1)
def run(self, parent, blocks):
sibling = self.lastChild(parent)
@@ -82,7 +82,8 @@ class AdmonitionProcessor(BlockProcessor):
klass, title = match.group(1).lower(), match.group(2)
if title is None:
# no title was provided, use the capitalized classname as title
- # e.g.: `!!! note` will render `<p class="admonition-title">Note</p>`
+ # e.g.: `!!! note` will render
+ # `<p class="admonition-title">Note</p>`
title = klass.capitalize()
elif title == '':
# an explicit blank title should not be rendered
@@ -93,4 +94,3 @@ class AdmonitionProcessor(BlockProcessor):
def makeExtension(*args, **kwargs):
return AdmonitionExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/attr_list.py b/markdown/extensions/attr_list.py
index 59da3b4..395259a 100644
--- a/markdown/extensions/attr_list.py
+++ b/markdown/extensions/attr_list.py
@@ -2,18 +2,18 @@
Attribute List Extension for Python-Markdown
============================================
-Adds attribute list syntax. Inspired by
+Adds attribute list syntax. Inspired by
[maruku](http://maruku.rubyforge.org/proposal.html#attribute_lists)'s
feature of the same name.
-See <https://pythonhosted.org/Markdown/extensions/attr_list.html>
+See <https://pythonhosted.org/Markdown/extensions/attr_list.html>
for documentation.
Original code Copyright 2011 [Waylan Limberg](http://achinghead.com/).
All changes Copyright 2011-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -26,21 +26,25 @@ import re
try:
Scanner = re.Scanner
-except AttributeError: #pragma: no cover
+except AttributeError: # pragma: no cover
# must be on Python 2.4
from sre import Scanner
+
def _handle_double_quote(s, t):
k, v = t.split('=')
return k, v.strip('"')
+
def _handle_single_quote(s, t):
k, v = t.split('=')
return k, v.strip("'")
-def _handle_key_value(s, t):
+
+def _handle_key_value(s, t):
return t.split('=')
+
def _handle_word(s, t):
if t.startswith('.'):
return '.', t[1:]
@@ -56,22 +60,26 @@ _scanner = Scanner([
(r' ', None)
])
+
def get_attrs(str):
""" Parse attribute list and return a list of attribute tuples. """
return _scanner.scan(str)[0]
+
def isheader(elem):
return elem.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
+
class AttrListTreeprocessor(Treeprocessor):
-
+
BASE_RE = r'\{\:?([^\}]*)\}'
HEADER_RE = re.compile(r'[ ]+%s[ ]*$' % BASE_RE)
BLOCK_RE = re.compile(r'\n[ ]*%s[ ]*$' % BASE_RE)
INLINE_RE = re.compile(r'^%s' % BASE_RE)
- NAME_RE = re.compile(r'[^A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff\u0370-\u037d'
- r'\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef'
- r'\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd'
+ NAME_RE = re.compile(r'[^A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff'
+ r'\u0370-\u037d\u037f-\u1fff\u200c-\u200d'
+ r'\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff'
+ r'\uf900-\ufdcf\ufdf0-\ufffd'
r'\:\-\.0-9\u00b7\u0300-\u036f\u203f-\u2040]+')
def run(self, doc):
@@ -160,7 +168,9 @@ class AttrListTreeprocessor(Treeprocessor):
class AttrListExtension(Extension):
def extendMarkdown(self, md, md_globals):
- md.treeprocessors.add('attr_list', AttrListTreeprocessor(md), '>prettify')
+ md.treeprocessors.add(
+ 'attr_list', AttrListTreeprocessor(md), '>prettify'
+ )
def makeExtension(*args, **kwargs):
diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py
index 0c3df7e..211db21 100644
--- a/markdown/extensions/codehilite.py
+++ b/markdown/extensions/codehilite.py
@@ -4,7 +4,7 @@ CodeHilite Extension for Python-Markdown
Adds code/syntax highlighting to standard Python-Markdown code blocks.
-See <https://pythonhosted.org/Markdown/extensions/code_hilite.html>
+See <https://pythonhosted.org/Markdown/extensions/code_hilite.html>
for documentation.
Original code Copyright 2006-2008 [Waylan Limberg](http://achinghead.com/).
@@ -19,7 +19,7 @@ from __future__ import absolute_import
from __future__ import unicode_literals
from . import Extension
from ..treeprocessors import Treeprocessor
-import warnings
+
try:
from pygments import highlight
from pygments.lexers import get_lexer_by_name, guess_lexer
@@ -47,7 +47,7 @@ def parse_hl_lines(expr):
# ------------------ The Main CodeHilite Class ----------------------
class CodeHilite(object):
"""
- Determine language of source code, and pass it into the pygments hilighter.
+ Determine language of source code, and pass it into pygments hilighter.
Basic Usage:
>>> code = CodeHilite(src = 'some text')
@@ -55,10 +55,11 @@ class CodeHilite(object):
* src: Source string or any object with a .readline attribute.
- * linenums: (Boolean) Set line numbering to 'on' (True), 'off' (False) or 'auto'(None).
- Set to 'auto' by default.
+ * linenums: (Boolean) Set line numbering to 'on' (True),
+ 'off' (False) or 'auto'(None). Set to 'auto' by default.
- * guess_lang: (Boolean) Turn language auto-detection 'on' or 'off' (on by default).
+ * guess_lang: (Boolean) Turn language auto-detection
+ 'on' or 'off' (on by default).
* css_class: Set class name of wrapper div ('codehilite' by default).
@@ -67,14 +68,14 @@ class CodeHilite(object):
Low Level Usage:
>>> code = CodeHilite()
>>> code.src = 'some text' # String or anything with a .readline attr.
- >>> code.linenos = True # True or False; Turns line numbering on or of.
+ >>> code.linenos = True # Turns line numbering on or of.
>>> html = code.hilite()
"""
def __init__(self, src=None, linenums=None, guess_lang=True,
- css_class="codehilite", lang=None, style='default',
- noclasses=False, tab_length=4, hl_lines=None):
+ css_class="codehilite", lang=None, style='default',
+ noclasses=False, tab_length=4, hl_lines=None):
self.src = src
self.lang = lang
self.linenums = linenums
@@ -132,9 +133,9 @@ class CodeHilite(object):
classes.append('linenums')
class_str = ''
if classes:
- class_str = ' class="%s"' % ' '.join(classes)
- return '<pre class="%s"><code%s>%s</code></pre>\n'% \
- (self.css_class, class_str, txt)
+ class_str = ' class="%s"' % ' '.join(classes)
+ return '<pre class="%s"><code%s>%s</code></pre>\n' % \
+ (self.css_class, class_str, txt)
def _parseHeader(self):
"""
@@ -142,8 +143,8 @@ class CodeHilite(object):
line should be removed or left in place. If the sheband line contains a
path (even a single /) then it is assumed to be a real shebang line and
left alone. However, if no path is given (e.i.: #!python or :::python)
- then it is assumed to be a mock shebang for language identifitation of a
- code fragment and removed from the code block prior to processing for
+ then it is assumed to be a mock shebang for language identifitation of
+ a code fragment and removed from the code block prior to processing for
code highlighting. When a mock shebang (e.i: #!python) is found, line
numbering is turned on. When colons are found in place of a shebang
(e.i.: :::python), line numbering is left in the current state - off
@@ -156,9 +157,9 @@ class CodeHilite(object):
import re
- #split text into lines
+ # split text into lines
lines = self.src.split("\n")
- #pull first line to examine
+ # pull first line to examine
fl = lines.pop(0)
c = re.compile(r'''
@@ -192,8 +193,9 @@ class CodeHilite(object):
self.src = "\n".join(lines).strip("\n")
-
# ------------------ The Markdown Extension -------------------------------
+
+
class HiliteTreeprocessor(Treeprocessor):
""" Hilight source code in code blocks. """
@@ -203,13 +205,15 @@ class HiliteTreeprocessor(Treeprocessor):
for block in blocks:
children = block.getchildren()
if len(children) == 1 and children[0].tag == 'code':
- code = CodeHilite(children[0].text,
- linenums=self.config['linenums'],
- guess_lang=self.config['guess_lang'],
- css_class=self.config['css_class'],
- style=self.config['pygments_style'],
- noclasses=self.config['noclasses'],
- tab_length=self.markdown.tab_length)
+ code = CodeHilite(
+ children[0].text,
+ linenums=self.config['linenums'],
+ guess_lang=self.config['guess_lang'],
+ css_class=self.config['css_class'],
+ style=self.config['pygments_style'],
+ noclasses=self.config['noclasses'],
+ tab_length=self.markdown.tab_length
+ )
placeholder = self.markdown.htmlStash.store(code.hilite(),
safe=True)
# Clear codeblock in etree instance
@@ -226,13 +230,22 @@ class CodeHiliteExtension(Extension):
def __init__(self, *args, **kwargs):
# define default configs
self.config = {
- 'linenums': [None, "Use lines numbers. True=yes, False=no, None=auto"],
- 'force_linenos' : [False, "Depreciated! Use 'linenums' instead. Force line numbers - Default: False"],
- 'guess_lang' : [True, "Automatic language detection - Default: True"],
- 'css_class' : ["codehilite",
- "Set class name for wrapper <div> - Default: codehilite"],
- 'pygments_style' : ['default', 'Pygments HTML Formatter Style (Colorscheme) - Default: default'],
- 'noclasses': [False, 'Use inline styles instead of CSS classes - Default false']
+ 'linenums': [None,
+ "Use lines numbers. True=yes, False=no, None=auto"],
+ 'force_linenos': [False,
+ "Depreciated! Use 'linenums' instead. Force "
+ "line numbers - Default: False"],
+ 'guess_lang': [True,
+ "Automatic language detection - Default: True"],
+ 'css_class': ["codehilite",
+ "Set class name for wrapper <div> - "
+ "Default: codehilite"],
+ 'pygments_style': ['default',
+ 'Pygments HTML Formatter Style '
+ '(Colorscheme) - Default: default'],
+ 'noclasses': [False,
+ 'Use inline styles instead of CSS classes - '
+ 'Default false']
}
super(CodeHiliteExtension, self).__init__(*args, **kwargs)
@@ -247,4 +260,4 @@ class CodeHiliteExtension(Extension):
def makeExtension(*args, **kwargs):
- return CodeHiliteExtension(*args, **kwargs)
+ return CodeHiliteExtension(*args, **kwargs)
diff --git a/markdown/extensions/def_list.py b/markdown/extensions/def_list.py
index 22e2491..118b739 100644
--- a/markdown/extensions/def_list.py
+++ b/markdown/extensions/def_list.py
@@ -4,14 +4,14 @@ Definition List Extension for Python-Markdown
Adds parsing of Definition Lists to Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/definition_lists.html>
+See <https://pythonhosted.org/Markdown/extensions/definition_lists.html>
for documentation.
Original code Copyright 2008 [Waylan Limberg](http://achinghead.com)
All changes Copyright 2008-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -36,7 +36,8 @@ class DefListProcessor(BlockProcessor):
raw_block = blocks.pop(0)
m = self.RE.search(raw_block)
- terms = [l.strip() for l in raw_block[:m.start()].split('\n') if l.strip()]
+ terms = [l.strip() for l in
+ raw_block[:m.start()].split('\n') if l.strip()]
block = raw_block[m.end():]
no_indent = self.NO_INDENT_RE.match(block)
if no_indent:
@@ -49,7 +50,7 @@ class DefListProcessor(BlockProcessor):
d = m.group(2)
sibling = self.lastChild(parent)
if not terms and sibling is None:
- # This is not a definition item. Most likely a paragraph that
+ # This is not a definition item. Most likely a paragraph that
# starts with a colon at the begining of a document or list.
blocks.insert(0, raw_block)
return False
@@ -84,6 +85,7 @@ class DefListProcessor(BlockProcessor):
if theRest:
blocks.insert(0, theRest)
+
class DefListIndentProcessor(ListIndentProcessor):
""" Process indented children of definition list items. """
@@ -94,7 +96,6 @@ class DefListIndentProcessor(ListIndentProcessor):
""" Create a new dd and parse the block with it as the parent. """
dd = etree.SubElement(parent, 'dd')
self.parser.parseBlocks(dd, [block])
-
class DefListExtension(Extension):
@@ -105,11 +106,10 @@ class DefListExtension(Extension):
md.parser.blockprocessors.add('defindent',
DefListIndentProcessor(md.parser),
'>indent')
- md.parser.blockprocessors.add('deflist',
+ md.parser.blockprocessors.add('deflist',
DefListProcessor(md.parser),
'>ulist')
def makeExtension(*args, **kwargs):
return DefListExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/extra.py b/markdown/extensions/extra.py
index 4044a87..de5db03 100644
--- a/markdown/extensions/extra.py
+++ b/markdown/extensions/extra.py
@@ -20,12 +20,12 @@ under a differant name. You could also edit the `extensions` global
variable defined below, but be aware that such changes may be lost
when you upgrade to any future version of Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/extra.html>
+See <https://pythonhosted.org/Markdown/extensions/extra.html>
for documentation.
Copyright The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -51,7 +51,7 @@ class ExtraExtension(Extension):
""" Add various extensions to Markdown class."""
def __init__(self, *args, **kwargs):
- """ config is just a dumb holder which gets passed to actual ext later. """
+ """ config is a dumb holder which gets passed to actual ext later. """
self.config = kwargs.pop('configs', {})
self.config.update(kwargs)
diff --git a/markdown/extensions/fenced_code.py b/markdown/extensions/fenced_code.py
index 2aacca6..4af8891 100644
--- a/markdown/extensions/fenced_code.py
+++ b/markdown/extensions/fenced_code.py
@@ -4,7 +4,7 @@ Fenced Code Extension for Python Markdown
This extension adds Fenced Code Blocks to Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/fenced_code_blocks.html>
+See <https://pythonhosted.org/Markdown/extensions/fenced_code_blocks.html>
for documentation.
Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
@@ -12,7 +12,7 @@ Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
All changes Copyright 2008-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
from __future__ import absolute_import
@@ -30,8 +30,8 @@ class FencedCodeExtension(Extension):
md.registerExtension(self)
md.preprocessors.add('fenced_code_block',
- FencedBlockPreprocessor(md),
- ">normalize_whitespace")
+ FencedBlockPreprocessor(md),
+ ">normalize_whitespace")
class FencedBlockPreprocessor(Preprocessor):
@@ -75,21 +75,26 @@ class FencedBlockPreprocessor(Preprocessor):
# If config is not empty, then the codehighlite extension
# is enabled, so we call it to highlight the code
if self.codehilite_conf:
- highliter = CodeHilite(m.group('code'),
- linenums=self.codehilite_conf['linenums'][0],
- guess_lang=self.codehilite_conf['guess_lang'][0],
- css_class=self.codehilite_conf['css_class'][0],
- style=self.codehilite_conf['pygments_style'][0],
- lang=(m.group('lang') or None),
- noclasses=self.codehilite_conf['noclasses'][0],
- hl_lines=parse_hl_lines(m.group('hl_lines')))
+ highliter = CodeHilite(
+ m.group('code'),
+ linenums=self.codehilite_conf['linenums'][0],
+ guess_lang=self.codehilite_conf['guess_lang'][0],
+ css_class=self.codehilite_conf['css_class'][0],
+ style=self.codehilite_conf['pygments_style'][0],
+ lang=(m.group('lang') or None),
+ noclasses=self.codehilite_conf['noclasses'][0],
+ hl_lines=parse_hl_lines(m.group('hl_lines'))
+ )
code = highliter.hilite()
else:
- code = self.CODE_WRAP % (lang, self._escape(m.group('code')))
+ code = self.CODE_WRAP % (lang,
+ self._escape(m.group('code')))
placeholder = self.markdown.htmlStash.store(code, safe=True)
- text = '%s\n%s\n%s'% (text[:m.start()], placeholder, text[m.end():])
+ text = '%s\n%s\n%s' % (text[:m.start()],
+ placeholder,
+ text[m.end():])
else:
break
return text.split("\n")
@@ -105,4 +110,3 @@ class FencedBlockPreprocessor(Preprocessor):
def makeExtension(*args, **kwargs):
return FencedCodeExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/footnotes.py b/markdown/extensions/footnotes.py
index a59de97..4779f0c 100644
--- a/markdown/extensions/footnotes.py
+++ b/markdown/extensions/footnotes.py
@@ -4,12 +4,12 @@ Footnotes Extension for Python-Markdown
Adds footnote handling to Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/footnotes.html>
+See <https://pythonhosted.org/Markdown/extensions/footnotes.html>
for documentation.
Copyright The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -25,30 +25,32 @@ from ..odict import OrderedDict
import re
FN_BACKLINK_TEXT = "zz1337820767766393qq"
-NBSP_PLACEHOLDER = "qq3936677670287331zz"
+NBSP_PLACEHOLDER = "qq3936677670287331zz"
DEF_RE = re.compile(r'[ ]{0,3}\[\^([^\]]*)\]:\s*(.*)')
TABBED_RE = re.compile(r'((\t)|( ))(.*)')
+
class FootnoteExtension(Extension):
""" Footnote Extension. """
- def __init__ (self, *args, **kwargs):
+ def __init__(self, *args, **kwargs):
""" Setup configs. """
self.config = {
'PLACE_MARKER':
- ["///Footnotes Go Here///",
- "The text string that marks where the footnotes go"],
+ ["///Footnotes Go Here///",
+ "The text string that marks where the footnotes go"],
'UNIQUE_IDS':
- [False,
- "Avoid name collisions across "
- "multiple calls to reset()."],
+ [False,
+ "Avoid name collisions across "
+ "multiple calls to reset()."],
"BACKLINK_TEXT":
- ["&#8617;",
- "The text string that links from the footnote to the reader's place."]
+ ["&#8617;",
+ "The text string that links from the footnote "
+ "to the reader's place."]
}
super(FootnoteExtension, self).__init__(*args, **kwargs)
-
+
# In multiple invocations, emit links that don't get tangled.
self.unique_prefix = 0
@@ -60,23 +62,27 @@ class FootnoteExtension(Extension):
self.parser = md.parser
self.md = md
# Insert a preprocessor before ReferencePreprocessor
- md.preprocessors.add("footnote", FootnotePreprocessor(self),
- "<reference")
+ md.preprocessors.add(
+ "footnote", FootnotePreprocessor(self), "<reference"
+ )
# Insert an inline pattern before ImageReferencePattern
- FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah
- md.inlinePatterns.add("footnote", FootnotePattern(FOOTNOTE_RE, self),
- "<reference")
+ FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah
+ md.inlinePatterns.add(
+ "footnote", FootnotePattern(FOOTNOTE_RE, self), "<reference"
+ )
# Insert a tree-processor that would actually add the footnote div
- # This must be before all other treeprocessors (i.e., inline and
+ # This must be before all other treeprocessors (i.e., inline and
# codehilite) so they can run on the the contents of the div.
- md.treeprocessors.add("footnote", FootnoteTreeprocessor(self),
- "_begin")
+ md.treeprocessors.add(
+ "footnote", FootnoteTreeprocessor(self), "_begin"
+ )
# Insert a postprocessor after amp_substitute oricessor
- md.postprocessors.add("footnote", FootnotePostprocessor(self),
- ">amp_substitute")
+ md.postprocessors.add(
+ "footnote", FootnotePostprocessor(self), ">amp_substitute"
+ )
def reset(self):
- """ Clear the footnotes on reset, and prepare for a distinct document. """
+ """ Clear footnotes on reset, and prepare for distinct document. """
self.footnotes = OrderedDict()
self.unique_prefix += 1
@@ -92,7 +98,7 @@ class FootnoteExtension(Extension):
return child, element, False
finder(child)
return None
-
+
res = finder(root)
return res
@@ -115,7 +121,8 @@ class FootnoteExtension(Extension):
def makeFootnoteRefId(self, id):
""" Return footnote back-link id. """
if self.getConfig("UNIQUE_IDS"):
- return 'fnref%s%d-%s' % (self.get_separator(), self.unique_prefix, id)
+ return 'fnref%s%d-%s' % (self.get_separator(),
+ self.unique_prefix, id)
else:
return 'fnref%s%s' % (self.get_separator(), id)
@@ -137,10 +144,13 @@ class FootnoteExtension(Extension):
backlink = etree.Element("a")
backlink.set("href", "#" + self.makeFootnoteRefId(id))
if self.md.output_format not in ['html5', 'xhtml5']:
- backlink.set("rev", "footnote") # Invalid in HTML5
+ backlink.set("rev", "footnote") # Invalid in HTML5
backlink.set("class", "footnote-backref")
- backlink.set("title", "Jump back to footnote %d in the text" % \
- (self.footnotes.index(id)+1))
+ backlink.set(
+ "title",
+ "Jump back to footnote %d in the text" %
+ (self.footnotes.index(id)+1)
+ )
backlink.text = FN_BACKLINK_TEXT
if li.getchildren():
@@ -157,7 +167,7 @@ class FootnoteExtension(Extension):
class FootnotePreprocessor(Preprocessor):
""" Find all footnote references and store for later use. """
- def __init__ (self, footnotes):
+ def __init__(self, footnotes):
self.footnotes = footnotes
def run(self, lines):
@@ -178,7 +188,7 @@ class FootnotePreprocessor(Preprocessor):
if m:
fn, _i = self.detectTabbed(lines[i+1:])
fn.insert(0, m.group(2))
- i += _i-1 # skip past footnote
+ i += _i-1 # skip past footnote
self.footnotes.setFootnote(m.group(1), "\n".join(fn))
else:
newlines.append(lines[i])
@@ -199,16 +209,16 @@ class FootnotePreprocessor(Preprocessor):
"""
items = []
- blank_line = False # have we encountered a blank line yet?
- i = 0 # to keep track of where we are
+ blank_line = False # have we encountered a blank line yet?
+ i = 0 # to keep track of where we are
def detab(line):
match = TABBED_RE.match(line)
if match:
- return match.group(4)
+ return match.group(4)
for line in lines:
- if line.strip(): # Non-blank line
+ if line.strip(): # Non-blank line
detabbed_line = detab(line)
if detabbed_line:
items.append(detabbed_line)
@@ -222,23 +232,24 @@ class FootnotePreprocessor(Preprocessor):
else:
return items, i+1
- else: # Blank line: _maybe_ we are done.
+ else: # Blank line: _maybe_ we are done.
blank_line = True
- i += 1 # advance
+ i += 1 # advance
# Find the next non-blank line
for j in range(i, len(lines)):
if lines[j].strip():
- next_line = lines[j]; break
+ next_line = lines[j]
+ break
else:
- break # There is no more text; we are done.
+ break # There is no more text; we are done.
# Check if the next non-blank line is tabbed
- if detab(next_line): # Yes, more work to do.
+ if detab(next_line): # Yes, more work to do.
items.append("")
continue
else:
- break # No, we are done.
+ break # No, we are done.
else:
i += 1
@@ -260,7 +271,7 @@ class FootnotePattern(Pattern):
sup.set('id', self.footnotes.makeFootnoteRefId(id))
a.set('href', '#' + self.footnotes.makeFootnoteId(id))
if self.footnotes.md.output_format not in ['html5', 'xhtml5']:
- a.set('rel', 'footnote') # invalid in HTML5
+ a.set('rel', 'footnote') # invalid in HTML5
a.set('class', 'footnote-ref')
a.text = text_type(self.footnotes.footnotes.index(id) + 1)
return sup
@@ -271,7 +282,7 @@ class FootnotePattern(Pattern):
class FootnoteTreeprocessor(Treeprocessor):
""" Build and append footnote div to end of document. """
- def __init__ (self, footnotes):
+ def __init__(self, footnotes):
self.footnotes = footnotes
def run(self, root):
@@ -290,16 +301,19 @@ class FootnoteTreeprocessor(Treeprocessor):
else:
root.append(footnotesDiv)
+
class FootnotePostprocessor(Postprocessor):
""" Replace placeholders with html entities. """
def __init__(self, footnotes):
self.footnotes = footnotes
def run(self, text):
- text = text.replace(FN_BACKLINK_TEXT, self.footnotes.getConfig("BACKLINK_TEXT"))
+ text = text.replace(
+ FN_BACKLINK_TEXT, self.footnotes.getConfig("BACKLINK_TEXT")
+ )
return text.replace(NBSP_PLACEHOLDER, "&#160;")
+
def makeExtension(*args, **kwargs):
""" Return an instance of the FootnoteExtension """
return FootnoteExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/headerid.py b/markdown/extensions/headerid.py
index f7b7805..c9f2a21 100644
--- a/markdown/extensions/headerid.py
+++ b/markdown/extensions/headerid.py
@@ -4,14 +4,14 @@ HeaderID Extension for Python-Markdown
Auto-generate id attributes for HTML headers.
-See <https://pythonhosted.org/Markdown/extensions/header_id.html>
+See <https://pythonhosted.org/Markdown/extensions/header_id.html>
for documentation.
Original code Copyright 2007-2011 [Waylan Limberg](http://achinghead.com/).
All changes Copyright 2011-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -41,18 +41,18 @@ def unique(id, ids):
while id in ids or not id:
m = IDCOUNT_RE.match(id)
if m:
- id = '%s_%d'% (m.group(1), int(m.group(2))+1)
+ id = '%s_%d' % (m.group(1), int(m.group(2))+1)
else:
- id = '%s_%d'% (id, 1)
+ id = '%s_%d' % (id, 1)
ids.add(id)
return id
def itertext(elem):
- """ Loop through all children and return text only.
-
+ """ Loop through all children and return text only.
+
Reimplements method of same name added to ElementTree in Python 2.7
-
+
"""
if elem.text:
yield elem.text
@@ -103,7 +103,6 @@ class HeaderIdTreeprocessor(Treeprocessor):
level = 6
elem.tag = 'h%d' % level
-
def _get_meta(self):
""" Return meta data suported by this ext as a tuple """
level = int(self.config['level']) - 1
@@ -111,7 +110,7 @@ class HeaderIdTreeprocessor(Treeprocessor):
if hasattr(self.md, 'Meta'):
if 'header_level' in self.md.Meta:
level = int(self.md.Meta['header_level'][0]) - 1
- if 'header_forceid' in self.md.Meta:
+ if 'header_forceid' in self.md.Meta:
force = parseBoolValue(self.md.Meta['header_forceid'][0])
return level, force
@@ -120,11 +119,11 @@ class HeaderIdExtension(Extension):
def __init__(self, *args, **kwargs):
# set defaults
self.config = {
- 'level' : ['1', 'Base level for headers.'],
- 'forceid' : ['True', 'Force all headers to have an id.'],
- 'separator' : ['-', 'Word separator.'],
- 'slugify' : [slugify, 'Callable to generate anchors'],
- }
+ 'level': ['1', 'Base level for headers.'],
+ 'forceid': ['True', 'Force all headers to have an id.'],
+ 'separator': ['-', 'Word separator.'],
+ 'slugify': [slugify, 'Callable to generate anchors']
+ }
super(HeaderIdExtension, self).__init__(*args, **kwargs)
@@ -146,4 +145,3 @@ class HeaderIdExtension(Extension):
def makeExtension(*args, **kwargs):
return HeaderIdExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/meta.py b/markdown/extensions/meta.py
index bcc25a0..a733a8a 100644
--- a/markdown/extensions/meta.py
+++ b/markdown/extensions/meta.py
@@ -4,14 +4,14 @@ Meta Data Extension for Python-Markdown
This extension adds Meta Data handling to markdown.
-See <https://pythonhosted.org/Markdown/extensions/meta_data.html>
+See <https://pythonhosted.org/Markdown/extensions/meta_data.html>
for documentation.
Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
All changes Copyright 2008-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -25,13 +25,16 @@ import re
META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
+
class MetaExtension (Extension):
""" Meta-Data extension for Python-Markdown. """
def extendMarkdown(self, md, md_globals):
""" Add MetaPreprocessor to Markdown instance. """
- md.preprocessors.add("meta", MetaPreprocessor(md), ">normalize_whitespace")
+ md.preprocessors.add(
+ "meta", MetaPreprocessor(md), ">normalize_whitespace"
+ )
class MetaPreprocessor(Preprocessor):
@@ -44,7 +47,7 @@ class MetaPreprocessor(Preprocessor):
while lines:
line = lines.pop(0)
if line.strip() == '':
- break # blank line - done
+ break # blank line - done
m1 = META_RE.match(line)
if m1:
key = m1.group('key').lower().strip()
@@ -60,11 +63,10 @@ class MetaPreprocessor(Preprocessor):
meta[key].append(m2.group('value').strip())
else:
lines.insert(0, line)
- break # no meta data - done
+ break # no meta data - done
self.markdown.Meta = meta
return lines
-
+
def makeExtension(*args, **kwargs):
return MetaExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/nl2br.py b/markdown/extensions/nl2br.py
index 062a7e6..8acd60c 100644
--- a/markdown/extensions/nl2br.py
+++ b/markdown/extensions/nl2br.py
@@ -5,14 +5,14 @@ NL2BR Extension
A Python-Markdown extension to treat newlines as hard breaks; like
GitHub-flavored Markdown does.
-See <https://pythonhosted.org/Markdown/extensions/nl2br.html>
+See <https://pythonhosted.org/Markdown/extensions/nl2br.html>
for documentation.
Oringinal code Copyright 2011 [Brian Neal](http://deathofagremmie.com/)
All changes Copyright 2011-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -23,6 +23,7 @@ from ..inlinepatterns import SubstituteTagPattern
BR_RE = r'\n'
+
class Nl2BrExtension(Extension):
def extendMarkdown(self, md, md_globals):
@@ -32,4 +33,3 @@ class Nl2BrExtension(Extension):
def makeExtension(*args, **kwargs):
return Nl2BrExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/sane_lists.py b/markdown/extensions/sane_lists.py
index 9eb3a11..213c8a6 100644
--- a/markdown/extensions/sane_lists.py
+++ b/markdown/extensions/sane_lists.py
@@ -4,14 +4,14 @@ Sane List Extension for Python-Markdown
Modify the behavior of Lists in Python-Markdown to act in a sane manor.
-See <https://pythonhosted.org/Markdown/extensions/sane_lists.html>
+See <https://pythonhosted.org/Markdown/extensions/sane_lists.html>
for documentation.
Original code Copyright 2011 [Waylan Limberg](http://achinghead.com)
All changes Copyright 2011-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -23,13 +23,13 @@ import re
class SaneOListProcessor(OListProcessor):
-
+
CHILD_RE = re.compile(r'^[ ]{0,3}((\d+\.))[ ]+(.*)')
SIBLING_TAGS = ['ol']
class SaneUListProcessor(UListProcessor):
-
+
CHILD_RE = re.compile(r'^[ ]{0,3}(([*+-]))[ ]+(.*)')
SIBLING_TAGS = ['ul']
@@ -45,4 +45,3 @@ class SaneListExtension(Extension):
def makeExtension(*args, **kwargs):
return SaneListExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/smart_strong.py b/markdown/extensions/smart_strong.py
index 331dae8..58570bb 100644
--- a/markdown/extensions/smart_strong.py
+++ b/markdown/extensions/smart_strong.py
@@ -4,14 +4,14 @@ Smart_Strong Extension for Python-Markdown
This extention adds smarter handling of double underscores within words.
-See <https://pythonhosted.org/Markdown/extensions/smart_strong.html>
+See <https://pythonhosted.org/Markdown/extensions/smart_strong.html>
for documentation.
Original code Copyright 2011 [Waylan Limberg](http://achinghead.com)
All changes Copyright 2011-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
'''
@@ -23,13 +23,19 @@ from ..inlinepatterns import SimpleTagPattern
SMART_STRONG_RE = r'(?<!\w)(_{2})(?!_)(.+?)(?<!_)\2(?!\w)'
STRONG_RE = r'(\*{2})(.+?)\2'
+
class SmartEmphasisExtension(Extension):
""" Add smart_emphasis extension to Markdown class."""
def extendMarkdown(self, md, md_globals):
""" Modify inline patterns. """
md.inlinePatterns['strong'] = SimpleTagPattern(STRONG_RE, 'strong')
- md.inlinePatterns.add('strong2', SimpleTagPattern(SMART_STRONG_RE, 'strong'), '>emphasis2')
+ md.inlinePatterns.add(
+ 'strong2',
+ SimpleTagPattern(SMART_STRONG_RE, 'strong'),
+ '>emphasis2'
+ )
+
def makeExtension(*args, **kwargs):
return SmartEmphasisExtension(*args, **kwargs)
diff --git a/markdown/extensions/smarty.py b/markdown/extensions/smarty.py
index 00c330f..3d79061 100644
--- a/markdown/extensions/smarty.py
+++ b/markdown/extensions/smarty.py
@@ -3,17 +3,17 @@
Smarty extension for Python-Markdown
====================================
-Adds conversion of ASCII dashes, quotes and ellipses to their HTML
+Adds conversion of ASCII dashes, quotes and ellipses to their HTML
entity equivalents.
-See <https://pythonhosted.org/Markdown/extensions/smarty.html>
+See <https://pythonhosted.org/Markdown/extensions/smarty.html>
for documentation.
Author: 2013, Dmitry Shachnev <mitya57@gmail.com>
All changes Copyright 2013-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
SmartyPants license:
@@ -32,7 +32,7 @@ SmartyPants license:
the documentation and/or other materials provided with the
distribution.
- * Neither the name "SmartyPants" nor the names of its contributors
+ * Neither the name "SmartyPants" nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
@@ -86,7 +86,7 @@ from . import Extension
from ..inlinepatterns import HtmlPattern
from ..odict import OrderedDict
from ..treeprocessors import InlineProcessor
-from ..util import parseBoolValue
+
# Constants for quote education.
punctClass = r"""[!"#\$\%'()*+,-.\/:;<=>?\@\[\\\]\^_`{|}~]"""
@@ -94,14 +94,14 @@ endOfWordClass = r"[\s.,;:!?)]"
closeClass = "[^\ \t\r\n\[\{\(\-\u0002\u0003]"
openingQuotesBase = (
- '(\s' # a whitespace char
- '|&nbsp;' # or a non-breaking space entity
- '|--' # or dashes
- '|–|—' # or unicode
- '|&[mn]dash;' # or named dash entities
- '|&#8211;|&#8212;' # or decimal entities
- ')'
-)
+ '(\s' # a whitespace char
+ '|&nbsp;' # or a non-breaking space entity
+ '|--' # or dashes
+ '|–|—' # or unicode
+ '|&[mn]dash;' # or named dash entities
+ '|&#8211;|&#8212;' # or decimal entities
+ ')'
+)
substitutions = {
'mdash': '&mdash;',
@@ -137,13 +137,14 @@ closingDoubleQuotesRegex2 = '(?<=%s)"' % closeClass
openingSingleQuotesRegex = r"%s'(?=\w)" % openingQuotesBase
# Single closing quotes:
-closingSingleQuotesRegex = r"(?<=%s)'(?!\s|s\b|\d)" % closeClass
+closingSingleQuotesRegex = r"(?<=%s)'(?!\s|s\b|\d)" % closeClass
closingSingleQuotesRegex2 = r"(?<=%s)'(\s|s\b)" % closeClass
# All remaining quotes should be opening ones
remainingSingleQuotesRegex = "'"
remainingDoubleQuotesRegex = '"'
+
class SubstituteTextPattern(HtmlPattern):
def __init__(self, pattern, replace, markdown_instance):
""" Replaces matches with some text. """
@@ -160,6 +161,7 @@ class SubstituteTextPattern(HtmlPattern):
result += self.markdown.htmlStash.store(part, safe=True)
return result
+
class SmartyExtension(Extension):
def __init__(self, *args, **kwargs):
self.config = {
@@ -167,7 +169,7 @@ class SmartyExtension(Extension):
'smart_angled_quotes': [False, 'Educate angled quotes'],
'smart_dashes': [True, 'Educate dashes'],
'smart_ellipses': [True, 'Educate ellipses'],
- 'substitutions' : [{}, 'Overwrite default substitutions'],
+ 'substitutions': [{}, 'Overwrite default substitutions'],
}
super(SmartyExtension, self).__init__(*args, **kwargs)
self.substitutions = dict(substitutions)
@@ -182,31 +184,40 @@ class SmartyExtension(Extension):
self.inlinePatterns.add(name, pattern, after)
def educateDashes(self, md):
- emDashesPattern = SubstituteTextPattern(r'(?<!-)---(?!-)',
- (self.substitutions['mdash'],), md)
- enDashesPattern = SubstituteTextPattern(r'(?<!-)--(?!-)',
- (self.substitutions['ndash'],), md)
+ emDashesPattern = SubstituteTextPattern(
+ r'(?<!-)---(?!-)', (self.substitutions['mdash'],), md
+ )
+ enDashesPattern = SubstituteTextPattern(
+ r'(?<!-)--(?!-)', (self.substitutions['ndash'],), md
+ )
self.inlinePatterns.add('smarty-em-dashes', emDashesPattern, '_begin')
- self.inlinePatterns.add('smarty-en-dashes', enDashesPattern,
- '>smarty-em-dashes')
+ self.inlinePatterns.add(
+ 'smarty-en-dashes', enDashesPattern, '>smarty-em-dashes'
+ )
def educateEllipses(self, md):
- ellipsesPattern = SubstituteTextPattern(r'(?<!\.)\.{3}(?!\.)',
- (self.substitutions['ellipsis'],), md)
+ ellipsesPattern = SubstituteTextPattern(
+ r'(?<!\.)\.{3}(?!\.)', (self.substitutions['ellipsis'],), md
+ )
self.inlinePatterns.add('smarty-ellipses', ellipsesPattern, '_begin')
def educateAngledQuotes(self, md):
- leftAngledQuotePattern = SubstituteTextPattern(r'\<\<',
- (self.substitutions['left-angle-quote'],), md)
- rightAngledQuotePattern = SubstituteTextPattern(r'\>\>',
- (self.substitutions['right-angle-quote'],), md)
- self.inlinePatterns.add('smarty-left-angle-quotes',
- leftAngledQuotePattern, '_begin')
- self.inlinePatterns.add('smarty-right-angle-quotes',
- rightAngledQuotePattern, '>smarty-left-angle-quotes')
+ leftAngledQuotePattern = SubstituteTextPattern(
+ r'\<\<', (self.substitutions['left-angle-quote'],), md
+ )
+ rightAngledQuotePattern = SubstituteTextPattern(
+ r'\>\>', (self.substitutions['right-angle-quote'],), md
+ )
+ self.inlinePatterns.add(
+ 'smarty-left-angle-quotes', leftAngledQuotePattern, '_begin'
+ )
+ self.inlinePatterns.add(
+ 'smarty-right-angle-quotes',
+ rightAngledQuotePattern,
+ '>smarty-left-angle-quotes'
+ )
def educateQuotes(self, md):
- configs = self.getConfigs()
lsquo = self.substitutions['left-single-quote']
rsquo = self.substitutions['right-single-quote']
ldquo = self.substitutions['left-double-quote']
@@ -243,5 +254,6 @@ class SmartyExtension(Extension):
md.treeprocessors.add('smarty', inlineProcessor, '_end')
md.ESCAPED_CHARS.extend(['"', "'"])
+
def makeExtension(*args, **kwargs):
return SmartyExtension(*args, **kwargs)
diff --git a/markdown/extensions/tables.py b/markdown/extensions/tables.py
index 57507e9..cbf711a 100644
--- a/markdown/extensions/tables.py
+++ b/markdown/extensions/tables.py
@@ -4,7 +4,7 @@ Tables Extension for Python-Markdown
Added parsing of tables to Python-Markdown.
-See <https://pythonhosted.org/Markdown/extensions/tables.html>
+See <https://pythonhosted.org/Markdown/extensions/tables.html>
for documentation.
Original code Copyright 2009 [Waylan Limberg](http://achinghead.com)
@@ -21,13 +21,14 @@ from . import Extension
from ..blockprocessors import BlockProcessor
from ..util import etree
+
class TableProcessor(BlockProcessor):
""" Process Tables. """
def test(self, parent, block):
rows = block.split('\n')
- return (len(rows) > 2 and '|' in rows[0] and
- '|' in rows[1] and '-' in rows[1] and
+ return (len(rows) > 2 and '|' in rows[0] and
+ '|' in rows[1] and '-' in rows[1] and
rows[1].strip()[0] in ['|', ':', '-'])
def run(self, parent, blocks):
@@ -66,13 +67,13 @@ class TableProcessor(BlockProcessor):
if parent.tag == 'thead':
tag = 'th'
cells = self._split_row(row, border)
- # We use align here rather than cells to ensure every row
+ # We use align here rather than cells to ensure every row
# contains the same number of columns.
for i, a in enumerate(align):
c = etree.SubElement(tr, tag)
try:
c.text = cells[i].strip()
- except IndexError: #pragma: no cover
+ except IndexError: # pragma: no cover
c.text = ""
if a:
c.set('align', a)
@@ -92,11 +93,10 @@ class TableExtension(Extension):
def extendMarkdown(self, md, md_globals):
""" Add an instance of TableProcessor to BlockParser. """
- md.parser.blockprocessors.add('table',
+ md.parser.blockprocessors.add('table',
TableProcessor(md.parser),
'<hashheader')
def makeExtension(*args, **kwargs):
return TableExtension(*args, **kwargs)
-
diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py
index f7fb675..99542ed 100644
--- a/markdown/extensions/toc.py
+++ b/markdown/extensions/toc.py
@@ -2,14 +2,14 @@
Table of Contents Extension for Python-Markdown
===============================================
-See <https://pythonhosted.org/Markdown/extensions/toc.html>
+See <https://pythonhosted.org/Markdown/extensions/toc.html>
for documentation.
Oringinal code Copyright 2008 [Jack Miller](http://codezen.org)
All changes Copyright 2008-2014 The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
"""
@@ -68,9 +68,11 @@ def order_toc_list(toc_list):
# Note current level as last
levels.append(current_level)
- # Level is the same, so append to the current parent (if available)
+ # Level is the same, so append to
+ # the current parent (if available)
if current_level == levels[-1]:
- (parents[-1]['children'] if parents else ordered_list).append(t)
+ (parents[-1]['children'] if parents
+ else ordered_list).append(t)
# Current level is > last item's level,
# So make last item a parent and append current as child
@@ -84,14 +86,14 @@ def order_toc_list(toc_list):
class TocTreeprocessor(Treeprocessor):
-
+
# Iterator wrapper to get parent and child all at once
def iterparent(self, root):
for parent in root.getiterator():
for child in parent:
yield parent, child
-
- def add_anchor(self, c, elem_id): #@ReservedAssignment
+
+ def add_anchor(self, c, elem_id): # @ReservedAssignment
anchor = etree.Element("a")
anchor.text = c.text
anchor.attrib["href"] = "#" + elem_id
@@ -105,12 +107,13 @@ class TocTreeprocessor(Treeprocessor):
def add_permalink(self, c, elem_id):
permalink = etree.Element("a")
permalink.text = ("%spara;" % AMP_SUBSTITUTE
- if self.use_permalinks is True else self.use_permalinks)
+ if self.use_permalinks is True
+ else self.use_permalinks)
permalink.attrib["href"] = "#" + elem_id
permalink.attrib["class"] = "headerlink"
permalink.attrib["title"] = "Permanent link"
c.append(permalink)
-
+
def build_toc_etree(self, div, toc_list):
# Add title to the div
if self.config["title"]:
@@ -129,20 +132,20 @@ class TocTreeprocessor(Treeprocessor):
if item['children']:
build_etree_ul(item['children'], li)
return ul
-
+
return build_etree_ul(toc_list, div)
-
+
def run(self, doc):
div = etree.Element("div")
div.attrib["class"] = "toc"
header_rgx = re.compile("[Hh][123456]")
-
+
self.use_anchors = parseBoolValue(self.config["anchorlink"])
self.use_permalinks = parseBoolValue(self.config["permalink"], False)
if self.use_permalinks is None:
self.use_permalinks = self.config["permalink"]
-
+
# Get a list of id attributes
used_ids = set()
for c in doc.getiterator():
@@ -160,7 +163,7 @@ class TocTreeprocessor(Treeprocessor):
# validation by putting a <div> inside of a <p>
# we actually replace the <p> in its entirety.
# We do not allow the marker inside a header as that
- # would causes an enless loop of placing a new TOC
+ # would causes an enless loop of placing a new TOC
# inside previously generated TOC.
if c.text and c.text.strip() == self.config["marker"] and \
not header_rgx.match(c.tag) and c.tag not in ['pre', 'code']:
@@ -169,32 +172,34 @@ class TocTreeprocessor(Treeprocessor):
p[i] = div
break
marker_found = True
-
+
if header_rgx.match(c.tag):
-
- # Do not override pre-existing ids
- if not "id" in c.attrib:
+
+ # Do not override pre-existing ids
+ if "id" not in c.attrib:
elem_id = stashedHTML2text(text, self.markdown)
- elem_id = unique(self.config["slugify"](elem_id, '-'), used_ids)
+ elem_id = unique(self.config["slugify"](elem_id, '-'),
+ used_ids)
c.attrib["id"] = elem_id
else:
elem_id = c.attrib["id"]
tag_level = int(c.tag[-1])
-
+
toc_list.append({'level': tag_level,
- 'id': elem_id,
- 'name': text})
+ 'id': elem_id,
+ 'name': text})
if self.use_anchors:
self.add_anchor(c, elem_id)
if self.use_permalinks:
self.add_permalink(c, elem_id)
-
+
toc_list_nested = order_toc_list(toc_list)
self.build_toc_etree(div, toc_list_nested)
prettify = self.markdown.treeprocessors.get('prettify')
- if prettify: prettify.run(div)
+ if prettify:
+ prettify.run(div)
if not marker_found:
# serialize and attach to markdown instance.
toc = self.markdown.serializer(div)
@@ -204,26 +209,26 @@ class TocTreeprocessor(Treeprocessor):
class TocExtension(Extension):
-
+
TreeProcessorClass = TocTreeprocessor
-
+
def __init__(self, *args, **kwargs):
- self.config = {
- "marker" : ["[TOC]",
- "Text to find and replace with Table of Contents - "
- "Defaults to \"[TOC]\""],
- "slugify" : [slugify,
- "Function to generate anchors based on header text - "
- "Defaults to the headerid ext's slugify function."],
- "title" : ["",
- "Title to insert into TOC <div> - "
- "Defaults to an empty string"],
- "anchorlink" : [0,
- "1 if header should be a self link - "
- "Defaults to 0"],
- "permalink" : [0,
- "1 or link text if a Sphinx-style permalink should be added - "
- "Defaults to 0"]
+ self.config = {
+ "marker": ["[TOC]",
+ "Text to find and replace with Table of Contents - "
+ "Defaults to \"[TOC]\""],
+ "slugify": [slugify,
+ "Function to generate anchors based on header text - "
+ "Defaults to the headerid ext's slugify function."],
+ "title": ["",
+ "Title to insert into TOC <div> - "
+ "Defaults to an empty string"],
+ "anchorlink": [0,
+ "1 if header should be a self link - "
+ "Defaults to 0"],
+ "permalink": [0,
+ "1 or link text if a Sphinx-style permalink should "
+ "be added - Defaults to 0"]
}
super(TocExtension, self).__init__(*args, **kwargs)
@@ -232,8 +237,8 @@ class TocExtension(Extension):
tocext = self.TreeProcessorClass(md)
tocext.config = self.getConfigs()
# Headerid ext is set to '>prettify'. With this set to '_end',
- # it should always come after headerid ext (and honor ids assinged
- # by the header id extension) if both are used. Same goes for
+ # it should always come after headerid ext (and honor ids assinged
+ # by the header id extension) if both are used. Same goes for
# attr_list extension. This must come last because we don't want
# to redefine ids after toc is created. But we do want toc prettified.
md.treeprocessors.add("toc", tocext, "_end")
diff --git a/markdown/extensions/wikilinks.py b/markdown/extensions/wikilinks.py
index 64377cf..94e1b67 100644
--- a/markdown/extensions/wikilinks.py
+++ b/markdown/extensions/wikilinks.py
@@ -4,14 +4,14 @@ WikiLinks Extension for Python-Markdown
Converts [[WikiLinks]] to relative links.
-See <https://pythonhosted.org/Markdown/extensions/wikilinks.html>
+See <https://pythonhosted.org/Markdown/extensions/wikilinks.html>
for documentation.
Original code Copyright [Waylan Limberg](http://achinghead.com/).
All changes Copyright The Python Markdown Project
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
+License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
'''
@@ -22,27 +22,28 @@ from ..inlinepatterns import Pattern
from ..util import etree
import re
+
def build_url(label, base, end):
""" Build a url from the label, a base, and an end. """
clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label)
- return '%s%s%s'% (base, clean_label, end)
+ return '%s%s%s' % (base, clean_label, end)
class WikiLinkExtension(Extension):
- def __init__ (self, *args, **kwargs):
+ def __init__(self, *args, **kwargs):
self.config = {
- 'base_url' : ['/', 'String to append to beginning or URL.'],
- 'end_url' : ['/', 'String to append to end of URL.'],
- 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'],
- 'build_url' : [build_url, 'Callable formats URL from label.'],
+ 'base_url': ['/', 'String to append to beginning or URL.'],
+ 'end_url': ['/', 'String to append to end of URL.'],
+ 'html_class': ['wikilink', 'CSS hook. Leave blank for none.'],
+ 'build_url': [build_url, 'Callable formats URL from label.'],
}
-
+
super(WikiLinkExtension, self).__init__(*args, **kwargs)
-
+
def extendMarkdown(self, md, md_globals):
self.md = md
-
+
# append to end of inline patterns
WIKILINK_RE = r'\[\[([\w0-9_ -]+)\]\]'
wikilinkPattern = WikiLinks(WIKILINK_RE, self.getConfigs())
@@ -54,14 +55,14 @@ class WikiLinks(Pattern):
def __init__(self, pattern, config):
super(WikiLinks, self).__init__(pattern)
self.config = config
-
+
def handleMatch(self, m):
if m.group(2).strip():
base_url, end_url, html_class = self._getMeta()
label = m.group(2).strip()
url = self.config['build_url'](label, base_url, end_url)
a = etree.Element('a')
- a.text = label
+ a.text = label
a.set('href', url)
if html_class:
a.set('class', html_class)
@@ -82,7 +83,7 @@ class WikiLinks(Pattern):
if 'wiki_html_class' in self.md.Meta:
html_class = self.md.Meta['wiki_html_class'][0]
return base_url, end_url, html_class
-
-def makeExtension(*args, **kwargs) :
+
+def makeExtension(*args, **kwargs):
return WikiLinkExtension(*args, **kwargs)