diff options
-rw-r--r-- | markdown/__init__.py | 141 | ||||
-rw-r--r-- | markdown/blockparser.py | 9 | ||||
-rw-r--r-- | markdown/blockprocessors.py | 58 | ||||
-rw-r--r-- | markdown/etree_loader.py | 2 | ||||
-rw-r--r-- | markdown/extensions/abbr.py | 5 | ||||
-rw-r--r-- | markdown/extensions/def_list.py | 5 | ||||
-rw-r--r-- | markdown/extensions/fenced_code.py | 3 | ||||
-rw-r--r-- | markdown/extensions/footnotes.py | 5 | ||||
-rw-r--r-- | markdown/extensions/headerid.py | 5 | ||||
-rw-r--r-- | markdown/extensions/meta.py | 3 | ||||
-rw-r--r-- | markdown/extensions/rss.py | 2 | ||||
-rw-r--r-- | markdown/extensions/tables.py | 2 | ||||
-rw-r--r-- | markdown/extensions/toc.py | 2 | ||||
-rw-r--r-- | markdown/extensions/wikilinks.py | 2 | ||||
-rw-r--r-- | markdown/html4.py | 12 | ||||
-rw-r--r-- | markdown/inlinepatterns.py | 42 | ||||
-rw-r--r-- | markdown/postprocessors.py | 13 | ||||
-rw-r--r-- | markdown/preprocessors.py | 17 | ||||
-rw-r--r-- | markdown/treeprocessors.py | 32 |
19 files changed, 138 insertions, 222 deletions
diff --git a/markdown/__init__.py b/markdown/__init__.py index 26314f6..5743c9b 100644 --- a/markdown/__init__.py +++ b/markdown/__init__.py @@ -44,99 +44,6 @@ version_info = (2,0,3, "Final") import re import codecs -import sys -import warnings -import logging -from logging import DEBUG, INFO, WARN, ERROR, CRITICAL - - -""" -CONSTANTS -============================================================================= -""" - -""" -Constants you might want to modify ------------------------------------------------------------------------------ -""" - -# default logging level for command-line use -COMMAND_LINE_LOGGING_LEVEL = CRITICAL -TAB_LENGTH = 4 # expand tabs to this many spaces -ENABLE_ATTRIBUTES = True # @id = xyz -> <... id="xyz"> -SMART_EMPHASIS = True # this_or_that does not become this<i>or</i>that -DEFAULT_OUTPUT_FORMAT = 'xhtml1' # xhtml or html4 output -HTML_REMOVED_TEXT = "[HTML_REMOVED]" # text used instead of HTML in safe mode -BLOCK_LEVEL_ELEMENTS = re.compile("p|div|h[1-6]|blockquote|pre|table|dl|ol|ul" - "|script|noscript|form|fieldset|iframe|math" - "|ins|del|hr|hr/|style|li|dt|dd|thead|tbody" - "|tr|th|td") -DOC_TAG = "div" # Element used to wrap document - later removed - -# Placeholders -STX = u'\u0002' # Use STX ("Start of text") for start-of-placeholder -ETX = u'\u0003' # Use ETX ("End of text") for end-of-placeholder -INLINE_PLACEHOLDER_PREFIX = STX+"klzzwxh:" -INLINE_PLACEHOLDER = INLINE_PLACEHOLDER_PREFIX + "%s" + ETX -AMP_SUBSTITUTE = STX+"amp"+ETX - - -""" -Constants you probably do not need to change ------------------------------------------------------------------------------ -""" - -RTL_BIDI_RANGES = ( (u'\u0590', u'\u07FF'), - # Hebrew (0590-05FF), Arabic (0600-06FF), - # Syriac (0700-074F), Arabic supplement (0750-077F), - # Thaana (0780-07BF), Nko (07C0-07FF). - (u'\u2D30', u'\u2D7F'), # Tifinagh - ) - - -""" -AUXILIARY GLOBAL FUNCTIONS -============================================================================= -""" - - -def message(level, text): - """ A wrapper method for logging debug messages. """ - logger = logging.getLogger('MARKDOWN') - if logger.handlers: - # The logger is configured - logger.log(level, text) - if level > WARN: - sys.exit(0) - elif level > WARN: - raise MarkdownException, text - else: - warnings.warn(text, MarkdownWarning) - - -def isBlockLevel(tag): - """Check if the tag is a block level HTML tag.""" - return BLOCK_LEVEL_ELEMENTS.match(tag) - -""" -MISC AUXILIARY CLASSES -============================================================================= -""" - -class AtomicString(unicode): - """A string which should not be further processed.""" - pass - - -class MarkdownException(Exception): - """ A Markdown Exception. """ - pass - - -class MarkdownWarning(Warning): - """ A Markdown Warning. """ - pass - """ OVERALL DESIGN @@ -157,21 +64,16 @@ Markdown processing takes place in four steps: Those steps are put together by the Markdown() class. """ - +import misc +import misc_logging import preprocessors import blockprocessors import treeprocessors import inlinepatterns import postprocessors import blockparser -import etree_loader import odict -# Extensions should use "markdown.etree" instead of "etree" (or do `from -# markdown import etree`). Do not import it by yourself. - -etree = etree_loader.importETree() - # Adds the ability to output html4 import html4 @@ -183,7 +85,7 @@ class Markdown: extensions=[], extension_configs={}, safe_mode = False, - output_format=DEFAULT_OUTPUT_FORMAT): + output_format=misc.DEFAULT_OUTPUT_FORMAT): """ Creates a new Markdown instance. @@ -302,8 +204,8 @@ class Markdown: self.output_formats = { 'html' : html4.to_html_string, 'html4' : html4.to_html_string, - 'xhtml' : etree.tostring, - 'xhtml1': etree.tostring, + 'xhtml' : misc.etree.tostring, + 'xhtml1': misc.etree.tostring, } self.references = {} @@ -331,9 +233,10 @@ class Markdown: try: ext.extendMarkdown(self, globals()) except NotImplementedError, e: - message(ERROR, e) + misc_logging.message(misc_logging.ERROR, e) else: - message(ERROR, 'Extension "%s.%s" must be of type: "markdown.Extension".' \ + misc_logging.message(misc_logging.ERROR, + 'Extension "%s.%s" must be of type: "markdown.Extension".' \ % (ext.__class__.__module__, ext.__class__.__name__)) def registerExtension(self, extension): @@ -356,7 +259,8 @@ class Markdown: try: self.serializer = self.output_formats[format.lower()] except KeyError: - message(CRITICAL, 'Invalid Output Format: "%s". Use one of %s.' \ + misc_logging.message(misc_logging.CRITICAL, + 'Invalid Output Format: "%s". Use one of %s.' \ % (format, self.output_formats.keys())) def convert(self, source): @@ -375,13 +279,14 @@ class Markdown: try: source = unicode(source) except UnicodeDecodeError: - message(CRITICAL, 'UnicodeDecodeError: Markdown only accepts unicode or ascii input.') + misc_logging.message(misc_logging.CRITICAL, + 'UnicodeDecodeError: Markdown only accepts unicode or ascii input.') return u"" - source = source.replace(STX, "").replace(ETX, "") + source = source.replace(misc.STX, "").replace(misc.ETX, "") source = source.replace("\r\n", "\n").replace("\r", "\n") + "\n\n" source = re.sub(r'\n\s+\n', '\n\n', source) - source = source.expandtabs(TAB_LENGTH) + source = source.expandtabs(misc.TAB_LENGTH) # Split into lines and run the line preprocessors. self.lines = source.split("\n") @@ -401,16 +306,16 @@ class Markdown: output, length = codecs.utf_8_decode(self.serializer(root, encoding="utf-8")) if self.stripTopLevelTags: try: - start = output.index('<%s>'%DOC_TAG)+len(DOC_TAG)+2 - end = output.rindex('</%s>'%DOC_TAG) + start = output.index('<%s>'%misc.DOC_TAG)+len(misc.DOC_TAG)+2 + end = output.rindex('</%s>'%misc.DOC_TAG) output = output[start:end].strip() except ValueError: - if output.strip().endswith('<%s />'%DOC_TAG): + if output.strip().endswith('<%s />'%misc.DOC_TAG): # We have an empty document output = '' else: # We have a serious problem - message(CRITICAL, 'Failed to strip top level tags.') + misc_logging.message(misc_logging.CRITICAL, 'Failed to strip top level tags.') # Run the text post-processors for pp in self.postprocessors.values(): @@ -453,7 +358,7 @@ class Markdown: html = self.convert(text) # Write to file or stdout - if isinstance(output, basestring): + if isinstance(output, (str, unicode)): output_file = codecs.open(output, "w", encoding=encoding) output_file.write(html) output_file.close() @@ -538,7 +443,7 @@ def load_extension(ext_name, configs = []): try: # Old style (mdx.<extension>) module = __import__(module_name_old_style) except ImportError: - message(WARN, "Failed loading extension '%s' from '%s' or '%s'" + misc_logging.message(misc_logging.WARN, "Failed loading extension '%s' from '%s' or '%s'" % (ext_name, module_name_new_style, module_name_old_style)) # Return None so we don't try to initiate none-existant extension return None @@ -548,7 +453,7 @@ def load_extension(ext_name, configs = []): try: return module.makeExtension(configs.items()) except AttributeError, e: - message(CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e)) + misc_logging.message(misc_logging.CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e)) def load_extensions(ext_names): @@ -572,7 +477,7 @@ markdownFromFile(). def markdown(text, extensions = [], safe_mode = False, - output_format = DEFAULT_OUTPUT_FORMAT): + output_format = misc.DEFAULT_OUTPUT_FORMAT): """Convert a markdown string to HTML and return HTML as a unicode string. This is a shortcut function for `Markdown` class to cover the most @@ -607,7 +512,7 @@ def markdownFromFile(input = None, extensions = [], encoding = None, safe_mode = False, - output_format = DEFAULT_OUTPUT_FORMAT): + output_format = misc.DEFAULT_OUTPUT_FORMAT): """Read markdown code from a file and write it to a file or a stream.""" md = Markdown(extensions=load_extensions(extensions), safe_mode=safe_mode, diff --git a/markdown/blockparser.py b/markdown/blockparser.py index e18b338..915d6c0 100644 --- a/markdown/blockparser.py +++ b/markdown/blockparser.py @@ -1,5 +1,6 @@ -import markdown +import misc +import odict class State(list): """ Track the current and nested state of the parser. @@ -42,7 +43,7 @@ class BlockParser: """ def __init__(self): - self.blockprocessors = markdown.odict.OrderedDict() + self.blockprocessors = odict.OrderedDict() self.state = State() def parseDocument(self, lines): @@ -56,9 +57,9 @@ class BlockParser: """ # Create a ElementTree from the lines - self.root = markdown.etree.Element(markdown.DOC_TAG) + self.root = misc.etree.Element(misc.DOC_TAG) self.parseChunk(self.root, '\n'.join(lines)) - return markdown.etree.ElementTree(self.root) + return misc.etree.ElementTree(self.root) def parseChunk(self, parent, text): """ Parse a chunk of markdown text and attach to given etree node. diff --git a/markdown/blockprocessors.py b/markdown/blockprocessors.py index 42693c6..3aeef34 100644 --- a/markdown/blockprocessors.py +++ b/markdown/blockprocessors.py @@ -13,8 +13,8 @@ as they need to alter how markdown blocks are parsed. """ import re -import markdown -from markdown import CRITICAL, message +import misc +from misc_logging import CRITICAL, message class BlockProcessor: """ Base class for block processors. @@ -42,8 +42,8 @@ class BlockProcessor: newtext = [] lines = text.split('\n') for line in lines: - if line.startswith(' '*markdown.TAB_LENGTH): - newtext.append(line[markdown.TAB_LENGTH:]) + if line.startswith(' '*misc.TAB_LENGTH): + newtext.append(line[misc.TAB_LENGTH:]) elif not line.strip(): newtext.append('') else: @@ -54,8 +54,8 @@ class BlockProcessor: """ Remove a tab from front of lines but allowing dedented lines. """ lines = text.split('\n') for i in range(len(lines)): - if lines[i].startswith(' '*markdown.TAB_LENGTH*level): - lines[i] = lines[i][markdown.TAB_LENGTH*level:] + if lines[i].startswith(' '*misc.TAB_LENGTH*level): + lines[i] = lines[i][misc.TAB_LENGTH*level:] return '\n'.join(lines) def test(self, parent, block): @@ -114,12 +114,12 @@ class ListIndentProcessor(BlockProcessor): """ - INDENT_RE = re.compile(r'^(([ ]{%s})+)'% markdown.TAB_LENGTH) + INDENT_RE = re.compile(r'^(([ ]{%s})+)'% misc.TAB_LENGTH) ITEM_TYPES = ['li'] LIST_TYPES = ['ul', 'ol'] def test(self, parent, block): - return block.startswith(' '*markdown.TAB_LENGTH) and \ + return block.startswith(' '*misc.TAB_LENGTH) and \ not self.parser.state.isstate('detabbed') and \ (parent.tag in self.ITEM_TYPES or \ (len(parent) and parent[-1] and \ @@ -154,7 +154,7 @@ class ListIndentProcessor(BlockProcessor): # If the parent li has text, that text needs to be moved to a p # The p must be 'inserted' at beginning of list in the event # that other children already exist i.e.; a nested sublist. - p = markdown.etree.Element('p') + p = misc.etree.Element('p') p.text = sibling[-1].text sibling[-1].text = '' sibling[-1].insert(0, p) @@ -162,10 +162,10 @@ class ListIndentProcessor(BlockProcessor): else: self.create_item(sibling, block) self.parser.state.reset() - + def create_item(self, parent, block): """ Create a new li and parse the block with it as the parent. """ - li = markdown.etree.SubElement(parent, 'li') + li = misc.etree.SubElement(parent, 'li') self.parser.parseBlocks(li, [block]) def get_level(self, parent, block): @@ -173,7 +173,7 @@ class ListIndentProcessor(BlockProcessor): # Get indent level m = self.INDENT_RE.match(block) if m: - indent_level = len(m.group(1))/markdown.TAB_LENGTH + indent_level = len(m.group(1))/misc.TAB_LENGTH else: indent_level = 0 if self.parser.state.isstate('list'): @@ -200,7 +200,7 @@ class CodeBlockProcessor(BlockProcessor): """ Process code blocks. """ def test(self, parent, block): - return block.startswith(' '*markdown.TAB_LENGTH) + return block.startswith(' '*misc.TAB_LENGTH) def run(self, parent, blocks): sibling = self.lastChild(parent) @@ -213,13 +213,13 @@ class CodeBlockProcessor(BlockProcessor): # linebreaks removed from the split into a list. code = sibling[0] block, theRest = self.detab(block) - code.text = markdown.AtomicString('%s\n%s\n' % (code.text, block.rstrip())) + code.text = misc.AtomicString('%s\n%s\n' % (code.text, block.rstrip())) else: # This is a new codeblock. Create the elements and insert text. - pre = markdown.etree.SubElement(parent, 'pre') - code = markdown.etree.SubElement(pre, 'code') + pre = misc.etree.SubElement(parent, 'pre') + code = misc.etree.SubElement(pre, 'code') block, theRest = self.detab(block) - code.text = markdown.AtomicString('%s\n' % block.rstrip()) + code.text = misc.AtomicString('%s\n' % block.rstrip()) if theRest: # This block contained unindented line(s) after the first indented # line. Insert these lines as the first block of the master blocks @@ -250,7 +250,7 @@ class BlockQuoteProcessor(BlockProcessor): quote = sibling else: # This is a new blockquote. Create a new parent element. - quote = markdown.etree.SubElement(parent, 'blockquote') + quote = misc.etree.SubElement(parent, 'blockquote') # Recursively parse block with blockquote as parent. # change parser state so blockquotes embedded in lists use p tags self.parser.state.set('blockquote') @@ -295,13 +295,13 @@ class OListProcessor(BlockProcessor): # since it's possible there are other children for this sibling, # we can't just SubElement the p, we need to insert it as the # first item - p = markdown.etree.Element('p') + p = misc.etree.Element('p') p.text = lst[-1].text lst[-1].text = '' lst[-1].insert(0, p) # parse first block differently as it gets wrapped in a p. - li = markdown.etree.SubElement(lst, 'li') + li = misc.etree.SubElement(lst, 'li') self.parser.state.set('looselist') firstitem = items.pop(0) self.parser.parseBlocks(li, [firstitem]) @@ -315,17 +315,17 @@ class OListProcessor(BlockProcessor): lst = parent else: # This is a new list so create parent with appropriate tag. - lst = markdown.etree.SubElement(parent, self.TAG) + lst = misc.etree.SubElement(parent, self.TAG) self.parser.state.set('list') # Loop through items in block, recursively parsing each with the # appropriate parent. for item in items: - if item.startswith(' '*markdown.TAB_LENGTH): + if item.startswith(' '*misc.TAB_LENGTH): # Item is indented. Parse with last item as parent self.parser.parseBlocks(lst[-1], [item]) else: # New item. Create li and parse with it as parent - li = markdown.etree.SubElement(lst, 'li') + li = misc.etree.SubElement(lst, 'li') self.parser.parseBlocks(li, [item]) self.parser.state.reset() @@ -339,7 +339,7 @@ class OListProcessor(BlockProcessor): items.append(m.group(3)) elif self.INDENT_RE.match(line): # This is an indented (possibly nested) item. - if items[-1].startswith(' '*markdown.TAB_LENGTH): + if items[-1].startswith(' '*misc.TAB_LENGTH): # Previous item was indented. Append to that item. items[-1] = '%s\n%s' % (items[-1], line) else: @@ -378,7 +378,7 @@ class HashHeaderProcessor(BlockProcessor): # recursively parse this lines as a block. self.parser.parseBlocks(parent, [before]) # Create header using named groups from RE - h = markdown.etree.SubElement(parent, 'h%d' % len(m.group('level'))) + h = misc.etree.SubElement(parent, 'h%d' % len(m.group('level'))) h.text = m.group('header').strip() if after: # Insert remaining lines as first block for future parsing. @@ -404,7 +404,7 @@ class SetextHeaderProcessor(BlockProcessor): level = 1 else: level = 2 - h = markdown.etree.SubElement(parent, 'h%d' % level) + h = misc.etree.SubElement(parent, 'h%d' % level) h.text = lines[0].strip() if len(lines) > 2: # Block contains additional lines. Add to master blocks for later. @@ -437,7 +437,7 @@ class HRProcessor(BlockProcessor): # Recursively parse lines before hr so they get parsed first. self.parser.parseBlocks(parent, ['\n'.join(prelines)]) # create hr - hr = markdown.etree.SubElement(parent, 'hr') + hr = misc.etree.SubElement(parent, 'hr') # check for lines in block after hr. lines = lines[len(prelines)+1:] if len(lines): @@ -465,7 +465,7 @@ class EmptyBlockProcessor(BlockProcessor): if sibling and sibling.tag == 'pre' and sibling[0] and \ sibling[0].tag == 'code': # Last block is a codeblock. Append to preserve whitespace. - sibling[0].text = markdown.AtomicString('%s/n/n/n' % sibling[0].text ) + sibling[0].text = misc.AtomicString('%s/n/n/n' % sibling[0].text ) class ParagraphProcessor(BlockProcessor): @@ -486,5 +486,5 @@ class ParagraphProcessor(BlockProcessor): parent.text = block.lstrip() else: # Create a regular paragraph - p = markdown.etree.SubElement(parent, 'p') + p = misc.etree.SubElement(parent, 'p') p.text = block.lstrip() diff --git a/markdown/etree_loader.py b/markdown/etree_loader.py index e2599b2..8abb1aa 100644 --- a/markdown/etree_loader.py +++ b/markdown/etree_loader.py @@ -1,5 +1,5 @@ -from markdown import message, CRITICAL +from misc_logging import message, CRITICAL import sys ## Import diff --git a/markdown/extensions/abbr.py b/markdown/extensions/abbr.py index 783220e..e2443a7 100644 --- a/markdown/extensions/abbr.py +++ b/markdown/extensions/abbr.py @@ -23,8 +23,9 @@ Copyright 2007-2008 ''' -import markdown, re -from markdown import etree +import re +import markdown +from markdown.misc import etree # Global Vars ABBR_REF_RE = re.compile(r'[*]\[(?P<abbr>[^\]]*)\][ ]?:\s*(?P<title>.*)') diff --git a/markdown/extensions/def_list.py b/markdown/extensions/def_list.py index 7a8d9e7..d16196e 100644 --- a/markdown/extensions/def_list.py +++ b/markdown/extensions/def_list.py @@ -19,8 +19,9 @@ Copyright 2008 - [Waylan Limberg](http://achinghead.com) """ -import markdown, re -from markdown import etree +import re +import markdown +from markdown.misc import etree class DefListProcessor(markdown.blockprocessors.BlockProcessor): diff --git a/markdown/extensions/fenced_code.py b/markdown/extensions/fenced_code.py index 23dc7b5..4bcb5be 100644 --- a/markdown/extensions/fenced_code.py +++ b/markdown/extensions/fenced_code.py @@ -61,7 +61,8 @@ Dependencies: """ -import markdown, re +import re +import markdown from markdown.extensions.codehilite import CodeHilite, CodeHiliteExtension # Global vars diff --git a/markdown/extensions/footnotes.py b/markdown/extensions/footnotes.py index e1a9cda..a3d540f 100644 --- a/markdown/extensions/footnotes.py +++ b/markdown/extensions/footnotes.py @@ -23,8 +23,9 @@ Example: """ -import re, markdown -from markdown import etree +import re +import markdown +from markdown.misc import etree FN_BACKLINK_TEXT = "zz1337820767766393qq" NBSP_PLACEHOLDER = "qq3936677670287331zz" diff --git a/markdown/extensions/headerid.py b/markdown/extensions/headerid.py index 6806818..de6bcf1 100644 --- a/markdown/extensions/headerid.py +++ b/markdown/extensions/headerid.py @@ -66,7 +66,8 @@ Dependencies: """ import markdown -from markdown import CRITICAL, etree, message +from markdown.misc import etree +from markdown.misc_logging import CRITICAL, message import re from string import ascii_lowercase, digits, punctuation @@ -108,7 +109,7 @@ class HeaderIdProcessor(markdown.blockprocessors.BlockProcessor): level = len(m.group('level')) + start_level if level > 6: level = 6 - h = markdown.etree.SubElement(parent, 'h%d' % level) + h = etree.SubElement(parent, 'h%d' % level) h.text = m.group('header').strip() if m.group('id'): h.set('id', self._unique_id(m.group('id'))) diff --git a/markdown/extensions/meta.py b/markdown/extensions/meta.py index 1b555b2..e0c2414 100644 --- a/markdown/extensions/meta.py +++ b/markdown/extensions/meta.py @@ -39,8 +39,9 @@ Contact: markdown@freewisdom.org License: BSD (see ../docs/LICENSE for details) """ +import re -import markdown, re +import markdown # Global Vars META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)') diff --git a/markdown/extensions/rss.py b/markdown/extensions/rss.py index 1274da2..64f7be1 100644 --- a/markdown/extensions/rss.py +++ b/markdown/extensions/rss.py @@ -1,5 +1,5 @@ import markdown -from markdown import etree +from markdown.misc import etree DEFAULT_URL = "http://www.freewisdom.org/projects/python-markdown/" DEFAULT_CREATOR = "Yuri Takhteyev" diff --git a/markdown/extensions/tables.py b/markdown/extensions/tables.py index 1d3c920..009f161 100644 --- a/markdown/extensions/tables.py +++ b/markdown/extensions/tables.py @@ -15,7 +15,7 @@ A simple example: Copyright 2009 - [Waylan Limberg](http://achinghead.com) """ import markdown -from markdown import etree +from markdown.misc import etree class TableProcessor(markdown.blockprocessors.BlockProcessor): diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index fd2a86a..46798f5 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -9,7 +9,7 @@ Dependencies: """ import markdown -from markdown import etree +from markdown.misc import etree import re class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): diff --git a/markdown/extensions/wikilinks.py b/markdown/extensions/wikilinks.py index df44e1c..2da207f 100644 --- a/markdown/extensions/wikilinks.py +++ b/markdown/extensions/wikilinks.py @@ -121,7 +121,7 @@ class WikiLinks(markdown.inlinepatterns.Pattern): base_url, end_url, html_class = self._getMeta() label = m.group(2).strip() url = self.config['build_url'][0](label, base_url, end_url) - a = markdown.etree.Element('a') + a = markdown.misc.etree.Element('a') a.text = label a.set('href', url) if html_class: diff --git a/markdown/html4.py b/markdown/html4.py index 08f241d..e47cb78 100644 --- a/markdown/html4.py +++ b/markdown/html4.py @@ -37,12 +37,12 @@ # -------------------------------------------------------------------- -import markdown -ElementTree = markdown.etree.ElementTree -QName = markdown.etree.QName -Comment = markdown.etree.Comment -PI = markdown.etree.PI -ProcessingInstruction = markdown.etree.ProcessingInstruction +import misc +ElementTree = misc.etree.ElementTree +QName = misc.etree.QName +Comment = misc.etree.Comment +PI = misc.etree.PI +ProcessingInstruction = misc.etree.ProcessingInstruction HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", "img", "input", "isindex", "link", "meta" "param") diff --git a/markdown/inlinepatterns.py b/markdown/inlinepatterns.py index 917a9d3..c277395 100644 --- a/markdown/inlinepatterns.py +++ b/markdown/inlinepatterns.py @@ -41,7 +41,7 @@ So, we apply the expressions in the following order: * finally we apply strong and emphasis """ -import markdown +import misc import re from urlparse import urlparse, urlunparse import sys @@ -68,7 +68,7 @@ EMPHASIS_RE = r'(\*)([^\*]+)\2' # *emphasis* STRONG_RE = r'(\*{2}|_{2})(.+?)\2' # **strong** STRONG_EM_RE = r'(\*{3}|_{3})(.+?)\2' # ***strong*** -if markdown.SMART_EMPHASIS: +if misc.SMART_EMPHASIS: EMPHASIS_2_RE = r'(?<!\w)(_)(\S.+?)\2(?!\w)' # _emphasis_ else: EMPHASIS_2_RE = r'(_)(.+?)\2' # _emphasis_ @@ -159,7 +159,7 @@ class SimpleTextPattern (Pattern): """ Return a simple text of group(2) of a Pattern. """ def handleMatch(self, m): text = m.group(2) - if text == markdown.INLINE_PLACEHOLDER_PREFIX: + if text == misc.INLINE_PLACEHOLDER_PREFIX: return None return text @@ -174,7 +174,7 @@ class SimpleTagPattern (Pattern): self.tag = tag def handleMatch(self, m): - el = markdown.etree.Element(self.tag) + el = misc.etree.Element(self.tag) el.text = m.group(3) return el @@ -182,7 +182,7 @@ class SimpleTagPattern (Pattern): class SubstituteTagPattern (SimpleTagPattern): """ Return a eLement of type `tag` with no children. """ def handleMatch (self, m): - return markdown.etree.Element(self.tag) + return misc.etree.Element(self.tag) class BacktickPattern (Pattern): @@ -192,8 +192,8 @@ class BacktickPattern (Pattern): self.tag = "code" def handleMatch(self, m): - el = markdown.etree.Element(self.tag) - el.text = markdown.AtomicString(m.group(3).strip()) + el = misc.etree.Element(self.tag) + el.text = misc.AtomicString(m.group(3).strip()) return el @@ -205,8 +205,8 @@ class DoubleTagPattern (SimpleTagPattern): """ def handleMatch(self, m): tag1, tag2 = self.tag.split(",") - el1 = markdown.etree.Element(tag1) - el2 = markdown.etree.SubElement(el1, tag2) + el1 = misc.etree.Element(tag1) + el2 = misc.etree.SubElement(el1, tag2) el2.text = m.group(3) return el1 @@ -223,7 +223,7 @@ class HtmlPattern (Pattern): class LinkPattern (Pattern): """ Return a link element from the given match. """ def handleMatch(self, m): - el = markdown.etree.Element("a") + el = misc.etree.Element("a") el.text = m.group(2) title = m.group(11) href = m.group(9) @@ -275,7 +275,7 @@ class LinkPattern (Pattern): class ImagePattern(LinkPattern): """ Return a img element from the given match. """ def handleMatch(self, m): - el = markdown.etree.Element("img") + el = misc.etree.Element("img") src_parts = m.group(9).split() if src_parts: src = src_parts[0] @@ -287,7 +287,7 @@ class ImagePattern(LinkPattern): if len(src_parts) > 1: el.set('title', dequote(" ".join(src_parts[1:]))) - if markdown.ENABLE_ATTRIBUTES: + if misc.ENABLE_ATTRIBUTES: truealt = handleAttributes(m.group(2), el) else: truealt = m.group(2) @@ -313,7 +313,7 @@ class ReferencePattern(LinkPattern): return self.makeTag(href, title, text) def makeTag(self, href, title, text): - el = markdown.etree.Element('a') + el = misc.etree.Element('a') el.set('href', self.sanitize_url(href)) if title: @@ -326,7 +326,7 @@ class ReferencePattern(LinkPattern): class ImageReferencePattern (ReferencePattern): """ Match to a stored reference and return img element. """ def makeTag(self, href, title, text): - el = markdown.etree.Element("img") + el = misc.etree.Element("img") el.set("src", self.sanitize_url(href)) if title: el.set("title", title) @@ -337,9 +337,9 @@ class ImageReferencePattern (ReferencePattern): class AutolinkPattern (Pattern): """ Return a link Element given an autolink (`<http://example/com>`). """ def handleMatch(self, m): - el = markdown.etree.Element("a") + el = misc.etree.Element("a") el.set('href', m.group(2)) - el.text = markdown.AtomicString(m.group(2)) + el.text = misc.AtomicString(m.group(2)) return el class AutomailPattern (Pattern): @@ -347,7 +347,7 @@ class AutomailPattern (Pattern): Return a mailto link Element given an automail link (`<foo@example.com>`). """ def handleMatch(self, m): - el = markdown.etree.Element('a') + el = misc.etree.Element('a') email = m.group(2) if email.startswith("mailto:"): email = email[len("mailto:"):] @@ -356,15 +356,15 @@ class AutomailPattern (Pattern): """Return entity definition by code, or the code if not defined.""" entity = htmlentitydefs.codepoint2name.get(code) if entity: - return "%s%s;" % (markdown.AMP_SUBSTITUTE, entity) + return "%s%s;" % (misc.AMP_SUBSTITUTE, entity) else: - return "%s#%d;" % (markdown.AMP_SUBSTITUTE, code) + return "%s#%d;" % (misc.AMP_SUBSTITUTE, code) letters = [codepoint2name(ord(letter)) for letter in email] - el.text = markdown.AtomicString(''.join(letters)) + el.text = misc.AtomicString(''.join(letters)) mailto = "mailto:" + email - mailto = "".join([markdown.AMP_SUBSTITUTE + '#%d;' % + mailto = "".join([misc.AMP_SUBSTITUTE + '#%d;' % ord(letter) for letter in mailto]) el.set('href', mailto) return el diff --git a/markdown/postprocessors.py b/markdown/postprocessors.py index e5c2e06..ceb897f 100644 --- a/markdown/postprocessors.py +++ b/markdown/postprocessors.py @@ -9,7 +9,8 @@ processing. """ -import markdown +import misc +import preprocessors class Processor: def __init__(self, markdown_instance=None): @@ -51,19 +52,19 @@ class RawHtmlPostprocessor(Postprocessor): elif str(self.markdown.safeMode).lower() == 'remove': html = '' else: - html = markdown.HTML_REMOVED_TEXT + html = misc.HTML_REMOVED_TEXT if safe or not self.markdown.safeMode: text = text.replace("<p>%s</p>" % - (markdown.preprocessors.HTML_PLACEHOLDER % i), + (preprocessors.HTML_PLACEHOLDER % i), html + "\n") - text = text.replace(markdown.preprocessors.HTML_PLACEHOLDER % i, + text = text.replace(preprocessors.HTML_PLACEHOLDER % i, html) return text def unescape(self, html): """ Unescape any markdown escaped text within inline html. """ for k, v in self.markdown.treeprocessors['inline'].stashed_nodes.items(): - ph = markdown.INLINE_PLACEHOLDER % k + ph = misc.INLINE_PLACEHOLDER % k html = html.replace(ph, '\%s' % v) return html @@ -81,5 +82,5 @@ class AndSubstitutePostprocessor(Postprocessor): pass def run(self, text): - text = text.replace(markdown.AMP_SUBSTITUTE, "&") + text = text.replace(misc.AMP_SUBSTITUTE, "&") return text diff --git a/markdown/preprocessors.py b/markdown/preprocessors.py index 3fabcf2..248e940 100644 --- a/markdown/preprocessors.py +++ b/markdown/preprocessors.py @@ -8,10 +8,11 @@ complicated. """ import re -import markdown -HTML_PLACEHOLDER_PREFIX = markdown.STX+"wzxhzdk:" -HTML_PLACEHOLDER = HTML_PLACEHOLDER_PREFIX + "%d" + markdown.ETX +import misc + +HTML_PLACEHOLDER_PREFIX = misc.STX+"wzxhzdk:" +HTML_PLACEHOLDER = HTML_PLACEHOLDER_PREFIX + "%d" + misc.ETX class Processor: def __init__(self, markdown_instance=None): @@ -146,7 +147,7 @@ class HtmlBlockPreprocessor(Preprocessor): left_tag = '' right_tag = '' in_tag = False # flag - + while text: block = text[0] if block.startswith("\n"): @@ -172,11 +173,11 @@ class HtmlBlockPreprocessor(Preprocessor): # keep checking conditions below and maybe just append if data_index < len(block) \ - and markdown.isBlockLevel(left_tag): + and misc.isBlockLevel(left_tag): text.insert(0, block[data_index:]) block = block[:data_index] - if not (markdown.isBlockLevel(left_tag) \ + if not (misc.isBlockLevel(left_tag) \ or block[1] in ["!", "?", "@", "%"]): new_blocks.append(block) continue @@ -184,7 +185,7 @@ class HtmlBlockPreprocessor(Preprocessor): if self._is_oneliner(left_tag): new_blocks.append(block.strip()) continue - + if block.rstrip().endswith(">") \ and self._equal_tags(left_tag, right_tag): if self.markdown_in_raw and 'markdown' in attrs.keys(): @@ -204,7 +205,7 @@ class HtmlBlockPreprocessor(Preprocessor): else: # if is block level tag and is not complete - if markdown.isBlockLevel(left_tag) or left_tag == "--" \ + if misc.isBlockLevel(left_tag) or left_tag == "--" \ and not block.rstrip().endswith(">"): items.append(block.strip()) in_tag = True diff --git a/markdown/treeprocessors.py b/markdown/treeprocessors.py index 97073f4..79c3999 100644 --- a/markdown/treeprocessors.py +++ b/markdown/treeprocessors.py @@ -1,6 +1,8 @@ -import markdown import re +import inlinepatterns +import misc + def isString(s): """ Check if it's string """ return isinstance(s, unicode) or isinstance(s, str) @@ -37,17 +39,17 @@ class InlineProcessor(Treeprocessor): """ def __init__ (self, md): - self.__placeholder_prefix = markdown.INLINE_PLACEHOLDER_PREFIX - self.__placeholder_suffix = markdown.ETX + self.__placeholder_prefix = misc.INLINE_PLACEHOLDER_PREFIX + self.__placeholder_suffix = misc.ETX self.__placeholder_length = 4 + len(self.__placeholder_prefix) \ + len(self.__placeholder_suffix) - self.__placeholder_re = re.compile(markdown.INLINE_PLACEHOLDER % r'([0-9]{4})') + self.__placeholder_re = re.compile(misc.INLINE_PLACEHOLDER % r'([0-9]{4})') self.markdown = md def __makePlaceholder(self, type): """ Generate a placeholder """ id = "%04d" % len(self.stashed_nodes) - hash = markdown.INLINE_PLACEHOLDER % id + hash = misc.INLINE_PLACEHOLDER % id return hash, id def __findPlaceholder(self, data, index): @@ -87,7 +89,7 @@ class InlineProcessor(Treeprocessor): Returns: String with placeholders. """ - if not isinstance(data, markdown.AtomicString): + if not isinstance(data, misc.AtomicString): startIndex = 0 while patternIndex < len(self.markdown.inlinePatterns): data, matched, startIndex = self.__applyPattern( @@ -222,7 +224,7 @@ class InlineProcessor(Treeprocessor): return data, True, len(leftData) + match.span(len(match.groups()))[0] if not isString(node): - if not isinstance(node.text, markdown.AtomicString): + if not isinstance(node.text, misc.AtomicString): # We need to process current node too for child in [node] + node.getchildren(): if not isString(node): @@ -264,7 +266,7 @@ class InlineProcessor(Treeprocessor): currElement = stack.pop() insertQueue = [] for child in currElement.getchildren(): - if child.text and not isinstance(child.text, markdown.AtomicString): + if child.text and not isinstance(child.text, misc.AtomicString): text = child.text child.text = None lst = self.__processPlaceholders(self.__handleInline( @@ -275,22 +277,22 @@ class InlineProcessor(Treeprocessor): if child.getchildren(): stack.append(child) - if markdown.ENABLE_ATTRIBUTES: + if misc.ENABLE_ATTRIBUTES: for element, lst in insertQueue: if element.text: element.text = \ - markdown.inlinepatterns.handleAttributes(element.text, + inlinepatterns.handleAttributes(element.text, element) i = 0 for newChild in lst: # Processing attributes if newChild.tail: newChild.tail = \ - markdown.inlinepatterns.handleAttributes(newChild.tail, + inlinepatterns.handleAttributes(newChild.tail, element) if newChild.text: newChild.text = \ - markdown.inlinepatterns.handleAttributes(newChild.text, + inlinepatterns.handleAttributes(newChild.text, newChild) element.insert(i, newChild) i += 1 @@ -304,12 +306,12 @@ class PrettifyTreeprocessor(Treeprocessor): """ Recursively add linebreaks to ElementTree children. """ i = "\n" - if markdown.isBlockLevel(elem.tag) and elem.tag not in ['code', 'pre']: + if misc.isBlockLevel(elem.tag) and elem.tag not in ['code', 'pre']: if (not elem.text or not elem.text.strip()) \ - and len(elem) and markdown.isBlockLevel(elem[0].tag): + and len(elem) and misc.isBlockLevel(elem[0].tag): elem.text = i for e in elem: - if markdown.isBlockLevel(e.tag): + if misc.isBlockLevel(e.tag): self._prettifyETree(e) if not elem.tail or not elem.tail.strip(): elem.tail = i |