def registerExtensions(self, extensions, configs): """ Register extensions with this instance of Markdown. Keyword aurguments: * extensions: A list of extensions, which can either be strings or objects. See the docstring on Markdown. * configs: A dictionary mapping module names to config options. """ for ext in extensions: if isinstance(ext, basestring): ext = load_extension(ext, configs.get(ext, [])) if isinstance(ext, Extension): try: ext.extendMarkdown(self, globals()) except NotImplementedError, e: message(ERROR, e) else: message( ERROR, 'Extension "%s.%s" must be of type: "markdown.Extension".' % (ext.__class__.__module__, ext.__class__.__name__), )
def set_output_format(self, format): """ Set the output format for the class instance. """ try: self.serializer = self.output_formats[format.lower()] except KeyError: message(CRITICAL, 'Invalid Output Format: "%s". Use one of %s.' \ % (format, self.output_formats.keys()))
def build_extension(self, ext_name, configs=[]): """Build extension by name, then return the module. The extension name may contain arguments as part of the string in the following format: "extname(key1=value1,key2=value2)" """ # Parse extensions config params (ignore the order) configs = dict(configs) pos = ext_name.find("(") # find the first "(" if pos > 0: ext_args = ext_name[pos + 1:-1] ext_name = ext_name[:pos] pairs = [x.split("=") for x in ext_args.split(",")] configs.update([(x.strip(), y.strip()) for (x, y) in pairs]) # Setup the module names ext_module = 'markdown.extensions' module_name_new_style = '.'.join([ext_module, ext_name]) module_name_old_style = '_'.join(['mdx', ext_name]) # Try loading the extention first from one place, then another try: # New style (markdown.extensons.<extension>) module = __import__(module_name_new_style, {}, {}, [ext_module]) except ImportError: try: # Old style (mdx_<extension>) module = __import__(module_name_old_style) except ImportError: message( 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 # If the module is loaded successfully, we expect it to define a # function called makeExtension() try: return module.makeExtension(configs.items()) except AttributeError, e: message(CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e))
def run(self, parent, blocks): block = blocks.pop(0) m = self.RE.search(block) if m: before = block[:m.start()] # All lines before header after = block[m.end():] # All lines after header if before: # As the header was not the first line of the block and the # lines before the header must be parsed first, # recursively parse this lines as a block. self.parser.parseBlocks(parent, [before]) # Create header using named groups from RE h = util.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. blocks.insert(0, after) else: # This should never happen, but just in case... message(CRITICAL, "We've got a problem header!")
def importETree(): """Import the best implementation of ElementTree, return a module object.""" etree_in_c = None try: # Is it Python 2.5+ with C implemenation of ElementTree installed? import xml.etree.cElementTree as etree_in_c from xml.etree.ElementTree import Comment except ImportError: try: # Is it Python 2.5+ with Python implementation of ElementTree? import xml.etree.ElementTree as etree except ImportError: try: # An earlier version of Python with cElementTree installed? import cElementTree as etree_in_c from elementtree.ElementTree import Comment except ImportError: try: # An earlier version of Python with Python ElementTree? import elementtree.ElementTree as etree except ImportError: message(CRITICAL, "Failed to import ElementTree") sys.exit(1) if etree_in_c: if etree_in_c.VERSION < "1.0": message(CRITICAL, "cElementTree version 1.0 or higher is required.") sys.exit(1) # Third party serializers (including ours) test with non-c Comment etree_in_c.test_comment = Comment return etree_in_c elif etree.VERSION < "1.1": message(CRITICAL, "ElementTree version 1.1 or higher is required") sys.exit(1) else: return etree
def importETree(): """Import the best implementation of ElementTree, return a module object.""" etree_in_c = None try: # Is it Python 2.5+ with C implemenation of ElementTree installed? import xml.etree.cElementTree as etree_in_c except ImportError: try: # Is it Python 2.5+ with Python implementation of ElementTree? import xml.etree.ElementTree as etree except ImportError: try: # An earlier version of Python with cElementTree installed? import cElementTree as etree_in_c except ImportError: try: # An earlier version of Python with Python ElementTree? import elementtree.ElementTree as etree except ImportError: message(CRITICAL, "Failed to import ElementTree") sys.exit(1) if etree_in_c and etree_in_c.VERSION < "1.0": message(CRITICAL, "For cElementTree version 1.0 or higher is required.") sys.exit(1) elif etree_in_c : return etree_in_c elif etree.VERSION < "1.1": message(CRITICAL, "For ElementTree version 1.1 or higher is required") sys.exit(1) else : return etree
def build_extension(self, ext_name, configs = []): """Build extension by name, then return the module. The extension name may contain arguments as part of the string in the following format: "extname(key1=value1,key2=value2)" """ # Parse extensions config params (ignore the order) configs = dict(configs) pos = ext_name.find("(") # find the first "(" if pos > 0: ext_args = ext_name[pos+1:-1] ext_name = ext_name[:pos] pairs = [x.split("=") for x in ext_args.split(",")] configs.update([(x.strip(), y.strip()) for (x, y) in pairs]) # Setup the module names ext_module = 'markdown.extensions' module_name_new_style = '.'.join([ext_module, ext_name]) module_name_old_style = '_'.join(['mdx', ext_name]) # Try loading the extention first from one place, then another try: # New style (markdown.extensons.<extension>) module = __import__(module_name_new_style, {}, {}, [ext_module]) except ImportError: try: # Old style (mdx_<extension>) module = __import__(module_name_old_style) except ImportError: message(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 # If the module is loaded successfully, we expect it to define a # function called makeExtension() try: return module.makeExtension(configs.items()) except AttributeError, e: message(CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e))
def importETree(): """Import the best implementation of ElementTree, return a module object.""" etree_in_c = None try: # Is it Python 2.5+ with C implemenation of ElementTree installed? import xml.etree.cElementTree as etree_in_c except ImportError: try: # Is it Python 2.5+ with Python implementation of ElementTree? import xml.etree.ElementTree as etree except ImportError: try: # An earlier version of Python with cElementTree installed? import cElementTree as etree_in_c except ImportError: try: # An earlier version of Python with Python ElementTree? import elementtree.ElementTree as etree except ImportError: message(CRITICAL, "Failed to import ElementTree") sys.exit(1) if etree_in_c and etree_in_c.VERSION < "1.0": message(CRITICAL, "For cElementTree version 1.0 or higher is required.") sys.exit(1) elif etree_in_c: return etree_in_c elif etree.VERSION < "1.1": message(CRITICAL, "For ElementTree version 1.1 or higher is required") sys.exit(1) else: return etree
def registerExtensions(self, extensions, configs): """ Register extensions with this instance of Markdown. Keyword aurguments: * extensions: A list of extensions, which can either be strings or objects. See the docstring on Markdown. * configs: A dictionary mapping module names to config options. """ for ext in extensions: if isinstance(ext, basestring): ext = self.build_extension(ext, configs.get(ext, [])) if isinstance(ext, Extension): try: ext.extendMarkdown(self, globals()) except NotImplementedError, e: message(ERROR, e) else: message(ERROR, 'Extension "%s.%s" must be of type: "markdown.Extension".' \ % (ext.__class__.__module__, ext.__class__.__name__))
def convert(self, source): """ Convert markdown to serialized XHTML or HTML. Keyword arguments: * source: Source text as a Unicode string. Markdown processing takes place in five steps: 1. A bunch of "preprocessors" munge the input text. 2. BlockParser() parses the high-level structural elements of the pre-processed text into an ElementTree. 3. A bunch of "treeprocessors" are run against the ElementTree. One such treeprocessor runs InlinePatterns against the ElementTree, detecting inline markup. 4. Some post-processors are run against the text after the ElementTree has been serialized into text. 5. The output is written to a string. """ # Fixup the source text if not source.strip(): return u"" # a blank unicode string try: source = unicode(source) except UnicodeDecodeError: message( CRITICAL, 'UnicodeDecodeError: Markdown only accepts unicode or ascii input.' ) return u"" source = source.replace(util.STX, "").replace(util.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(self.tab_length) # Split into lines and run the line preprocessors. self.lines = source.split("\n") for prep in self.preprocessors.values(): self.lines = prep.run(self.lines) # Parse the high-level elements. root = self.parser.parseDocument(self.lines).getroot() # Run the tree-processors for treeprocessor in self.treeprocessors.values(): newRoot = treeprocessor.run(root) if newRoot: root = newRoot # Serialize _properly_. Strip top-level tags. output, length = codecs.utf_8_decode( self.serializer(root, encoding="utf-8")) if self.stripTopLevelTags: try: start = output.index('<%s>' % self.doc_tag) + len( self.doc_tag) + 2 end = output.rindex('</%s>' % self.doc_tag) output = output[start:end].strip() except ValueError: if output.strip().endswith('<%s />' % self.doc_tag): # We have an empty document output = '' else: # We have a serious problem message(CRITICAL, 'Failed to strip top level tags.') # Run the text post-processors for pp in self.postprocessors.values(): output = pp.run(output) return output.strip()
def convert(self, source): """ Convert markdown to serialized XHTML or HTML. Keyword arguments: * source: Source text as a Unicode string. Markdown processing takes place in five steps: 1. A bunch of "preprocessors" munge the input text. 2. BlockParser() parses the high-level structural elements of the pre-processed text into an ElementTree. 3. A bunch of "treeprocessors" are run against the ElementTree. One such treeprocessor runs InlinePatterns against the ElementTree, detecting inline markup. 4. Some post-processors are run against the text after the ElementTree has been serialized into text. 5. The output is written to a string. """ # Fixup the source text if not source.strip(): return u"" # a blank unicode string try: source = unicode(source) except UnicodeDecodeError: message(CRITICAL, 'UnicodeDecodeError: Markdown only accepts unicode or ascii input.') return u"" source = source.replace(util.STX, "").replace(util.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(self.tab_length) # Split into lines and run the line preprocessors. self.lines = source.split("\n") for prep in self.preprocessors.values(): self.lines = prep.run(self.lines) # Parse the high-level elements. root = self.parser.parseDocument(self.lines).getroot() # Run the tree-processors for treeprocessor in self.treeprocessors.values(): newRoot = treeprocessor.run(root) if newRoot: root = newRoot # Serialize _properly_. Strip top-level tags. output, length = codecs.utf_8_decode(self.serializer(root, encoding="utf-8")) if self.stripTopLevelTags: try: start = output.index('<%s>'%self.doc_tag)+len(self.doc_tag)+2 end = output.rindex('</%s>'%self.doc_tag) output = output[start:end].strip() except ValueError: if output.strip().endswith('<%s />'%self.doc_tag): # We have an empty document output = '' else: # We have a serious problem message(CRITICAL, 'Failed to strip top level tags.') # Run the text post-processors for pp in self.postprocessors.values(): output = pp.run(output) return output.strip()