Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import re
from markdown import Extension
from markdown.blockprocessors import BlockProcessor
from markdown.util import etree
PIPE_NONE = 0
PIPE_LEFT = 1
PIPE_RIGHT = 2
class BlockQuoteProcessor(BlockProcessor):
RE = re.compile(r'(^|\n)[ ]{0,3}>[ ]?(.*)')
def test(self, parent, block):
return bool(self.RE.search(block))
def run(self, parent, blocks):
block = blocks.pop(0)
m = self.RE.search(block)
if m:
before = block[:m.start()] # Lines before blockquote
# Pass lines before blockquote in recursively for parsing forst.
self.parser.parseBlocks(parent, [before])
# Remove ``> `` from begining of each line.
block = '\n'.join(
[self.clean(line) for line in block[m.start():].split('\n')]
)
Added parsing of tables to Python-Markdown.
A simple example:
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
Copyright 2009 - [Waylan Limberg](http://achinghead.com)
"""
import markdown
from markdown import etree
class TableProcessor(markdown.blockprocessors.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
rows[1][0] in ['|', ':', '-'])
def run(self, parent, blocks):
""" Parse a table block and build table. """
block = blocks.pop(0).split('\n')
header = block[:2]
rows = block[2:]
# Get format type (bordered by pipes or not)
border = False
if header[0].startswith('|'):
self.add_inline(md, 'veoh', Veoh,
r'http://www\.veoh\.com/\S*(#watch%3D|watch/)(?P\w+)')
self.add_inline(md, 'vimeo', Vimeo,
r'http://(www.|)vimeo\.com/(?P\d+)\S*')
self.add_inline(md, 'yahoo', Yahoo,
r'http://screen\.yahoo\.com/.+/?')
self.add_inline(md, 'youtube', Youtube,
r'https?://www\.youtube\.com/watch\?\S*v=(?P\S[^&/]+)')
self.add_inline(md, 'youtube_short', Youtube,
r'https?://youtu\.be/(?P\S[^?&/]+)?')
if self.config["jsfiddle"][0]:
self.add_inline(md, 'jsfiddle', JsFiddle,
r'https?://(www.|)jsfiddle\.net/(?P[a-z0-9]+)/(?P[0-9]+)/?')
class VideoBProcessor(BlockProcessor):
def __init__(self, md, name, klass, patt, config):
self.md = md
self.name = name
self.klass = klass(config)
self.RE = re.compile(patt)
def test(self, parent, block):
return bool(self.RE.search(block))
def run(self, parent, blocks):
block = blocks.pop(0)
m = self.RE.search(block)
before = block[:m.start()]
after = block[m.end():]
# Step through children of tree to find matching indent level.
while indent_level > level:
child = self.lastChild(parent)
if (child is not None and
(child.tag in self.LIST_TYPES or child.tag in self.ITEM_TYPES)):
if child.tag in self.LIST_TYPES:
level += 1
parent = child
else:
# No more child levels. If we're short of indent_level,
# we have a code block. So we stop here.
break
return level, parent
class CodeBlockProcessor(BlockProcessor):
""" Process code blocks. """
def test(self, parent, block):
return block.startswith(' '*self.tab_length)
def run(self, parent, blocks):
sibling = self.lastChild(parent)
block = blocks.pop(0)
theRest = ''
if (sibling is not None and sibling.tag == "pre" and
len(sibling) and sibling[0].tag == "code"):
# The previous block was a code block. As blank lines do not start
# new code blocks, append this block to the previous, adding back
# linebreaks removed from the split into a list.
code = sibling[0]
block, theRest = self.detab(block)
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
Copyright 2009 - [Waylan Limberg](http://achinghead.com)
"""
from __future__ import absolute_import, unicode_literals
from markdown import Extension
from markdown.blockprocessors import BlockProcessor
from markdown.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
rows[1].strip()[0] in ['|', ':', '-'])
def run(self, parent, blocks):
""" Parse a table block and build table. """
block = blocks.pop(0).split('\n')
header = block[0].strip()
seperator = block[1].strip()
rows = block[2:]
# Get format type (bordered by pipes or not)
border = False
from markdown.blockprocessors import BlockProcessor
from markdown.util import etree
import processors.utils as utils
import re
class PanelBlockProcessor(BlockProcessor):
# p_start = re.compile('^\{panel ?(?P[^\}]*)\}')
# p_end = re.compile('\{panel end\}')
def __init__(self, ext, *args, **kwargs):
super().__init__(*args, **kwargs)
self.PANEL_TEMPLATE = ext.html_templates['panel']
self.p_start = re.compile(ext.tag_patterns['panel']['pattern_start'])
self.p_end = re.compile(ext.tag_patterns['panel']['pattern_end'])
def test(self, parent, block):
# return re.search('\{panel ?(?P[^\}]*)\}', block) is not None
return self.p_start.search(block) is not None
def run(self, parent, blocks):
# block contains the match as a substring
block = blocks.pop(0)
elemsToInspect.append(nelem)
if nelem.tag == "customlegend" :
elem.remove(nelem)
pp = util.etree.Element('p')
contentLegend = nelem.items()
for el in nelem:
pp.append(el)
elem.insert(index, pp)
Restart = True
break
index += 1
return root
class LegendProcessor(BlockProcessor):
def __init__(self, parser, md):
BlockProcessor.__init__(self, parser)
self.md = md
self.RE = re.compile(r'(^|\n)((?PFigure|Table|Code|Equation|Video|Source)[ ]{0,1})*\:[ ]{0,1}(?P.*?)(\n|$)')
def test(self, parent, block):
mLeg = self.RE.search(block)
return bool(mLeg)
def run(self, parent, blocks):
block = blocks.pop(0)
mLeg = self.RE.search(block)
before = block[:mLeg.start()]
after = block[mLeg.end():]
contentStart = block[mLeg.start():mLeg.start("txtlegend")]
# This is a new codeblock. Create the elements and insert text.
pre = markdown.etree.SubElement(parent, 'pre')
code = markdown.etree.SubElement(pre, 'code')
block, theRest = self.detab(block)
code.text = markdown.AtomicString('%s\n' % block.rstrip())
if code.text.startswith('.exec\n'):
pre.set('class', 'exec')
code.text = code.text.split(".exec\n", 1)[1]
if theRest:
# This block contained unindented line(s) after the first indented
# line. Insert these lines as the first block of the master blocks
# list for future processing.
blocks.insert(0, theRest)
class BlockQuoteProcessor(BlockProcessor):
RE = re.compile(r'(^|\n)[ ]{0,3}>[ ]?(.*)')
def test(self, parent, block):
return bool(self.RE.search(block))
def run(self, parent, blocks):
block = blocks.pop(0)
m = self.RE.search(block)
if m:
before = block[:m.start()] # Lines before blockquote
# Pass lines before blockquote in recursively for parsing forst.
self.parser.parseBlocks(parent, [before])
# Remove ``> `` from begining of each line.
block = '\n'.join([self.clean(line) for line in
block[m.start():].split('\n')])
def registered(self, processor):
if isinstance(processor, Treeprocessor):
registry = self.treeprocessors
elif isinstance(processor, (InlineProcessor, Pattern)):
registry = self.inlinePatterns
elif isinstance(processor, BlockProcessor):
registry = self.parser.blockprocessors
elif isinstance(processor, Postprocessor):
registry = self.postprocessors
elif isinstance(processor, Preprocessor):
registry = self.preprocessors
else:
raise ValueError("Unknown extension processor {}".format(name))
return registry
escapes = m.group(4)
if escapes:
return escapes.replace('\\\\', self.ESCAPED_BSLASH), m.start(0), m.end(0)
# Handle Tex
math = m.group(3)
if not math:
math = m.group(6)
if self.generic:
return inline_generic_format(math, wrap=self.wrap), m.start(0), m.end(0)
else:
return _inline_mathjax_format(math, self.preview), m.start(0), m.end(0)
class BlockArithmatexProcessor(BlockProcessor):
"""MathJax block processor to find $$MathJax$$ content."""
def __init__(self, pattern, config, md):
"""Initialize."""
# Generic setup
self.generic = config.get('generic', False)
wrap = config.get('tex_block_wrap', ['\\[', '\\]'])
self.wrap = wrap[0] + '%s' + wrap[1]
# Default setup
self.preview = config.get('preview', False)
self.match = None
self.pattern = re.compile(pattern)