Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: third_party/markdown/extensions/codehilite.py

Issue 133433002: Docserver: Support markdown for HTML content. Request thirdparty submission review. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: change the version of app & cron.yaml Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/markdown/extensions/attr_list.py ('k') | third_party/markdown/extensions/def_list.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/markdown/extensions/codehilite.py
diff --git a/third_party/markdown/extensions/codehilite.py b/third_party/markdown/extensions/codehilite.py
new file mode 100644
index 0000000000000000000000000000000000000000..53c04c92d567bcbd548ce2cbbf5897434988315f
--- /dev/null
+++ b/third_party/markdown/extensions/codehilite.py
@@ -0,0 +1,272 @@
+# markdown is released under the BSD license
+# Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
+# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+# Copyright 2004 Manfred Stienstra (the original version)
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the <organization> nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+
+"""
+CodeHilite Extension for Python-Markdown
+========================================
+
+Adds code/syntax highlighting to standard Python-Markdown code blocks.
+
+Copyright 2006-2008 [Waylan Limberg](http://achinghead.com/).
+
+Project website: <http://packages.python.org/Markdown/extensions/code_hilite.html>
+Contact: markdown@freewisdom.org
+
+License: BSD (see ../LICENSE.md for details)
+
+Dependencies:
+* [Python 2.3+](http://python.org/)
+* [Markdown 2.0+](http://packages.python.org/Markdown/)
+* [Pygments](http://pygments.org/)
+
+"""
+
+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, TextLexer
+ from pygments.formatters import HtmlFormatter
+ pygments = True
+except ImportError:
+ pygments = False
+
+# ------------------ The Main CodeHilite Class ----------------------
+class CodeHilite(object):
+ """
+ Determine language of source code, and pass it into the pygments hilighter.
+
+ Basic Usage:
+ >>> code = CodeHilite(src = 'some text')
+ >>> html = code.hilite()
+
+ * 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.
+
+ * guess_lang: (Boolean) Turn language auto-detection 'on' or 'off' (on by default).
+
+ * css_class: Set class name of wrapper div ('codehilite' by default).
+
+ 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.
+ >>> 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):
+ self.src = src
+ self.lang = lang
+ self.linenums = linenums
+ self.guess_lang = guess_lang
+ self.css_class = css_class
+ self.style = style
+ self.noclasses = noclasses
+ self.tab_length = tab_length
+
+ def hilite(self):
+ """
+ Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with
+ optional line numbers. The output should then be styled with css to
+ your liking. No styles are applied by default - only styling hooks
+ (i.e.: <span class="k">).
+
+ returns : A string of html.
+
+ """
+
+ self.src = self.src.strip('\n')
+
+ if self.lang is None:
+ self._getLang()
+
+ if pygments:
+ try:
+ lexer = get_lexer_by_name(self.lang)
+ except ValueError:
+ try:
+ if self.guess_lang:
+ lexer = guess_lexer(self.src)
+ else:
+ lexer = TextLexer()
+ except ValueError:
+ lexer = TextLexer()
+ formatter = HtmlFormatter(linenos=self.linenums,
+ cssclass=self.css_class,
+ style=self.style,
+ noclasses=self.noclasses)
+ return highlight(self.src, lexer, formatter)
+ else:
+ # just escape and build markup usable by JS highlighting libs
+ txt = self.src.replace('&', '&amp;')
+ txt = txt.replace('<', '&lt;')
+ txt = txt.replace('>', '&gt;')
+ txt = txt.replace('"', '&quot;')
+ classes = []
+ if self.lang:
+ classes.append('language-%s' % self.lang)
+ if self.linenums:
+ 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)
+
+ def _getLang(self):
+ """
+ Determines language of a code block from shebang line and whether said
+ 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
+ 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
+ by default.
+
+ """
+
+ import re
+
+ #split text into lines
+ lines = self.src.split("\n")
+ #pull first line to examine
+ fl = lines.pop(0)
+
+ c = re.compile(r'''
+ (?:(?:^::+)|(?P<shebang>^[#]!)) # Shebang or 2 or more colons.
+ (?P<path>(?:/\w+)*[/ ])? # Zero or 1 path
+ (?P<lang>[\w+-]*) # The language
+ ''', re.VERBOSE)
+ # search first line for shebang
+ m = c.search(fl)
+ if m:
+ # we have a match
+ try:
+ self.lang = m.group('lang').lower()
+ except IndexError:
+ self.lang = None
+ if m.group('path'):
+ # path exists - restore first line
+ lines.insert(0, fl)
+ if self.linenums is None and m.group('shebang'):
+ # Overridable and Shebang exists - use line numbers
+ self.linenums = True
+ else:
+ # No match
+ lines.insert(0, fl)
+
+ self.src = "\n".join(lines).strip("\n")
+
+
+
+# ------------------ The Markdown Extension -------------------------------
+class HiliteTreeprocessor(Treeprocessor):
+ """ Hilight source code in code blocks. """
+
+ def run(self, root):
+ """ Find code blocks and store in htmlStash. """
+ blocks = root.getiterator('pre')
+ 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)
+ placeholder = self.markdown.htmlStash.store(code.hilite(),
+ safe=True)
+ # Clear codeblock in etree instance
+ block.clear()
+ # Change to p element which will later
+ # be removed when inserting raw html
+ block.tag = 'p'
+ block.text = placeholder
+
+
+class CodeHiliteExtension(Extension):
+ """ Add source code hilighting to markdown codeblocks. """
+
+ def __init__(self, configs):
+ # 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']
+ }
+
+ # Override defaults with user settings
+ for key, value in configs:
+ # convert strings to booleans
+ if value == 'True': value = True
+ if value == 'False': value = False
+ if value == 'None': value = None
+
+ if key == 'force_linenos':
+ warnings.warn('The "force_linenos" config setting'
+ ' to the CodeHilite extension is deprecrecated.'
+ ' Use "linenums" instead.', PendingDeprecationWarning)
+ if value:
+ # Carry 'force_linenos' over to new 'linenos'.
+ self.setConfig('linenums', True)
+
+ self.setConfig(key, value)
+
+ def extendMarkdown(self, md, md_globals):
+ """ Add HilitePostprocessor to Markdown instance. """
+ hiliter = HiliteTreeprocessor(md)
+ hiliter.config = self.getConfigs()
+ md.treeprocessors.add("hilite", hiliter, "<inline")
+
+ md.registerExtension(self)
+
+
+def makeExtension(configs={}):
+ return CodeHiliteExtension(configs=configs)
+
« no previous file with comments | « third_party/markdown/extensions/attr_list.py ('k') | third_party/markdown/extensions/def_list.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698