📄 markdown.py
字号:
i += 1 # added on 2006.02.25 else : i += 1 # Add the dom elements for item in items : li = self.doc.createElement("li") ul.appendChild(li) self._processSection(li, item, inList + 1, looseList = looseList) # Process the remaining part of the section self._processSection(parent_elem, lines[i:], inList) def _linesUntil(self, lines, condition) : """ A utility function to break a list of lines upon the first line that satisfied a condition. The condition argument should be a predicate function. """ i = -1 for line in lines : i += 1 if condition(line) : break else : i += 1 return lines[:i], lines[i:] def _processQuote(self, parent_elem, lines, inList) : """Given a list of document lines starting with a quote finds the end of the quote, unindents it and recursively processes the body of the quote and the remainder of the text file. @param parent_elem: DOM element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None """ dequoted = [] i = 0 for line in lines : m = RE.regExp['quoted'].match(line) if m : dequoted.append(m.group(1)) i += 1 else : break else : i += 1 blockquote = self.doc.createElement('blockquote') parent_elem.appendChild(blockquote) self._processSection(blockquote, dequoted, inList) self._processSection(parent_elem, lines[i:], inList) def _processCodeBlock(self, parent_elem, lines, inList) : """Given a list of document lines starting with a code block finds the end of the block, puts it into the dom verbatim wrapped in ("<pre><code>") and recursively processes the the remainder of the text file. @param parent_elem: DOM element to which the content will be added @param lines: a list of lines @param inList: a level @returns: None""" detabbed, theRest = self.blockGuru.detectTabbed(lines) pre = self.doc.createElement('pre') code = self.doc.createElement('code') parent_elem.appendChild(pre) pre.appendChild(code) text = "\n".join(detabbed).rstrip()+"\n" #text = text.replace("&", "&") code.appendChild(self.doc.createTextNode(text)) self._processSection(parent_elem, theRest, inList) def _handleInlineWrapper2 (self, line) : parts = [line] #if not(line): # return [self.doc.createTextNode(' ')] for pattern in self.inlinePatterns : #print #print self.inlinePatterns.index(pattern) i = 0 #print parts while i < len(parts) : x = parts[i] #print i if isinstance(x, (str, unicode)) : result = self._applyPattern(x, pattern) #print result #print result #print parts, i if result : i -= 1 parts.remove(x) for y in result : parts.insert(i+1,y) i += 1 for i in range(len(parts)) : x = parts[i] if isinstance(x, (str, unicode)) : parts[i] = self.doc.createTextNode(x) return parts def _handleInlineWrapper (self, line) : # A wrapper around _handleInline to avoid recursion parts = [line] i = 0 while i < len(parts) : x = parts[i] if isinstance(x, (str, unicode)) : parts.remove(x) result = self._handleInline(x) for y in result : parts.insert(i,y) else : i += 1 return parts def _handleInline(self, line): """Transform a Markdown line with inline elements to an XHTML fragment. This function uses auxiliary objects called inline patterns. See notes on inline patterns above. @param item: A block of Markdown text @return: A list of NanoDom nodes """ if not(line): return [self.doc.createTextNode(' ')] for pattern in self.inlinePatterns : list = self._applyPattern( line, pattern) if list: return list return [self.doc.createTextNode(line)] def _applyPattern(self, line, pattern) : """ Given a pattern name, this function checks if the line fits the pattern, creates the necessary elements, and returns back a list consisting of NanoDom elements and/or strings. @param line: the text to be processed @param pattern: the pattern to be checked @returns: the appropriate newly created NanoDom element if the pattern matches, None otherwise. """ # match the line to pattern's pre-compiled reg exp. # if no match, move on. m = pattern.getCompiledRegExp().match(line) if not m : return None # if we got a match let the pattern make us a NanoDom node # if it doesn't, move on node = pattern.handleMatch(m, self.doc) if node : # Those are in the reverse order! return ( m.groups()[-1], # the string to the left node, # the new node m.group(1)) # the string to the right of the match else : return None def __str__(self, source = None): """Return the document in XHTML format. @returns: A serialized XHTML body.""" #try : if source : self.source = source doc = self._transform() xml = doc.toxml() #finally: # doc.unlink() # Let's stick in all the raw html pieces for i in range(self.htmlStash.html_counter) : html = self.htmlStash.rawHtmlBlocks[i] if self.safeMode : html = "[HTML_REMOVED]" xml = xml.replace("<p>%s\n</p>" % (HTML_PLACEHOLDER % i), html + "\n") xml = xml.replace(HTML_PLACEHOLDER % i, html) # And return everything but the top level tag if self.stripTopLevelTags : xml = xml.strip()[23:-7] + "\n" for pp in self.textPostprocessors : xml = pp.run(xml) return self.docType + xml toString = __str__ def __unicode__(self): """Return the document in XHTML format as a Unicode object. """ return str(self)#.decode(self.encoding) toUnicode = __unicode__# ====================================================================def markdownFromFile(input = None, output = None, extensions = [], encoding = None, message_threshold = CRITICAL, safe = False) : global MESSAGE_THRESHOLD MESSAGE_THRESHOLD = message_threshold message(VERBOSE, "input file: %s" % input) if not encoding : encoding = "utf-8" input_file = codecs.open(input, mode="r", encoding="utf-8") text = input_file.read() input_file.close() new_text = markdown(text, extensions, encoding, safe_mode = safe) if output : output_file = codecs.open(output, "w", encoding=encoding) output_file.write(new_text) output_file.close() else : sys.stdout.write(new_text.encode(encoding))def markdown(text, extensions = [], encoding = None, safe_mode = False) : message(VERBOSE, "in markdown.markdown(), received text:\n%s" % text) extension_names = [] extension_configs = {} for ext in extensions : pos = ext.find("(") if pos == -1 : extension_names.append(ext) else : name = ext[:pos] extension_names.append(name) pairs = [x.split("=") for x in ext[pos+1:-1].split(",")] configs = [(x.strip(), y.strip()) for (x, y) in pairs] extension_configs[name] = configs #print configs md = Markdown(text, extensions=extension_names, extension_configs=extension_configs, safe_mode = safe_mode) return md.toString() class Extension : def __init__(self, configs = {}) : self.config = configs def getConfig(self, key) : if self.config.has_key(key) : #print self.config[key][0] return self.config[key][0] else : return "" def getConfigInfo(self) : return [(key, self.config[key][1]) for key in self.config.keys()] def setConfig(self, key, value) : self.config[key][0] = valueOPTPARSE_WARNING = """Python 2.3 or higher required for advanced command line options.For lower versions of Python use: %s INPUT_FILE > OUTPUT_FILE """ % EXECUTABLE_NAME_FOR_USAGEdef parse_options() : try : optparse = __import__("optparse") except : if len(sys.argv) == 2 : return {'input' : sys.argv[1], 'output' : None, 'message_threshold' : CRITICAL, 'safe' : False, 'extensions' : [], 'encoding' : None } else : print OPTPARSE_WARNING return None parser = optparse.OptionParser(usage="%prog INPUTFILE [options]") parser.add_option("-f", "--file", dest="filename", help="write output to OUTPUT_FILE", metavar="OUTPUT_FILE") parser.add_option("-e", "--encoding", dest="encoding", help="encoding for input and output files",) parser.add_option("-q", "--quiet", default = CRITICAL, action="store_const", const=NONE, dest="verbose", help="suppress all messages") parser.add_option("-v", "--verbose", action="store_const", const=INFO, dest="verbose", help="print info messages") parser.add_option("-s", "--safe", action="store_const", const=True, dest="safe", help="same mode (strip user's HTML tag)") parser.add_option("--noisy", action="store_const", const=VERBOSE, dest="verbose", help="print debug messages") parser.add_option("-x", "--extension", action="append", dest="extensions", help = "load extension EXTENSION", metavar="EXTENSION") (options, args) = parser.parse_args() if not len(args) == 1 : parser.print_help() return None else : input_file = args[0] if not options.extensions : options.extensions = [] return {'input' : input_file, 'output' : options.filename, 'message_threshold' : options.verbose, 'safe' : options.safe, 'extensions' : options.extensions, 'encoding' : options.encoding }if __name__ == '__main__': """ Run Markdown from the command line. """ options = parse_options() #if os.access(inFile, os.R_OK): if not options : sys.exit(0) markdownFromFile(**options)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -