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

Side by Side Diff: third_party/markdown/extensions/codehilite.py

Issue 93743005: Support markdown template for html editor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix path without dir 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 """
2 CodeHilite Extension for Python-Markdown
3 ========================================
4
5 Adds code/syntax highlighting to standard Python-Markdown code blocks.
6
7 Copyright 2006-2008 [Waylan Limberg](http://achinghead.com/).
8
9 Project website: <http://packages.python.org/Markdown/extensions/code_hilite.htm l>
10 Contact: markdown@freewisdom.org
11
12 License: BSD (see ../LICENSE.md for details)
13
14 Dependencies:
15 * [Python 2.3+](http://python.org/)
16 * [Markdown 2.0+](http://packages.python.org/Markdown/)
17 * [Pygments](http://pygments.org/)
18
19 """
20
21 from __future__ import absolute_import
22 from __future__ import unicode_literals
23 from . import Extension
24 from ..treeprocessors import Treeprocessor
25 import warnings
26 try:
27 from pygments import highlight
28 from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer
29 from pygments.formatters import HtmlFormatter
30 pygments = True
31 except ImportError:
32 pygments = False
33
34 # ------------------ The Main CodeHilite Class ----------------------
35 class CodeHilite(object):
36 """
37 Determine language of source code, and pass it into the pygments hilighter.
38
39 Basic Usage:
40 >>> code = CodeHilite(src = 'some text')
41 >>> html = code.hilite()
42
43 * src: Source string or any object with a .readline attribute.
44
45 * linenums: (Boolean) Set line numbering to 'on' (True), 'off' (False) or 'a uto'(None).
46 Set to 'auto' by default.
47
48 * guess_lang: (Boolean) Turn language auto-detection 'on' or 'off' (on by de fault).
49
50 * css_class: Set class name of wrapper div ('codehilite' by default).
51
52 Low Level Usage:
53 >>> code = CodeHilite()
54 >>> code.src = 'some text' # String or anything with a .readline attr.
55 >>> code.linenos = True # True or False; Turns line numbering on or of.
56 >>> html = code.hilite()
57
58 """
59
60 def __init__(self, src=None, linenums=None, guess_lang=True,
61 css_class="codehilite", lang=None, style='default',
62 noclasses=False, tab_length=4):
63 self.src = src
64 self.lang = lang
65 self.linenums = linenums
66 self.guess_lang = guess_lang
67 self.css_class = css_class
68 self.style = style
69 self.noclasses = noclasses
70 self.tab_length = tab_length
71
72 def hilite(self):
73 """
74 Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with
75 optional line numbers. The output should then be styled with css to
76 your liking. No styles are applied by default - only styling hooks
77 (i.e.: <span class="k">).
78
79 returns : A string of html.
80
81 """
82
83 self.src = self.src.strip('\n')
84
85 if self.lang is None:
86 self._getLang()
87
88 if pygments:
89 try:
90 lexer = get_lexer_by_name(self.lang)
91 except ValueError:
92 try:
93 if self.guess_lang:
94 lexer = guess_lexer(self.src)
95 else:
96 lexer = TextLexer()
97 except ValueError:
98 lexer = TextLexer()
99 formatter = HtmlFormatter(linenos=self.linenums,
100 cssclass=self.css_class,
101 style=self.style,
102 noclasses=self.noclasses)
103 return highlight(self.src, lexer, formatter)
104 else:
105 # just escape and build markup usable by JS highlighting libs
106 txt = self.src.replace('&', '&amp;')
107 txt = txt.replace('<', '&lt;')
108 txt = txt.replace('>', '&gt;')
109 txt = txt.replace('"', '&quot;')
110 classes = []
111 if self.lang:
112 classes.append('language-%s' % self.lang)
113 if self.linenums:
114 classes.append('linenums')
115 class_str = ''
116 if classes:
117 class_str = ' class="%s"' % ' '.join(classes)
118 return '<pre class="%s"><code%s>%s</code></pre>\n'% \
119 (self.css_class, class_str, txt)
120
121 def _getLang(self):
122 """
123 Determines language of a code block from shebang line and whether said
124 line should be removed or left in place. If the sheband line contains a
125 path (even a single /) then it is assumed to be a real shebang line and
126 left alone. However, if no path is given (e.i.: #!python or :::python)
127 then it is assumed to be a mock shebang for language identifitation of a
128 code fragment and removed from the code block prior to processing for
129 code highlighting. When a mock shebang (e.i: #!python) is found, line
130 numbering is turned on. When colons are found in place of a shebang
131 (e.i.: :::python), line numbering is left in the current state - off
132 by default.
133
134 """
135
136 import re
137
138 #split text into lines
139 lines = self.src.split("\n")
140 #pull first line to examine
141 fl = lines.pop(0)
142
143 c = re.compile(r'''
144 (?:(?:^::+)|(?P<shebang>^[#]!)) # Shebang or 2 or more colons.
145 (?P<path>(?:/\w+)*[/ ])? # Zero or 1 path
146 (?P<lang>[\w+-]*) # The language
147 ''', re.VERBOSE)
148 # search first line for shebang
149 m = c.search(fl)
150 if m:
151 # we have a match
152 try:
153 self.lang = m.group('lang').lower()
154 except IndexError:
155 self.lang = None
156 if m.group('path'):
157 # path exists - restore first line
158 lines.insert(0, fl)
159 if self.linenums is None and m.group('shebang'):
160 # Overridable and Shebang exists - use line numbers
161 self.linenums = True
162 else:
163 # No match
164 lines.insert(0, fl)
165
166 self.src = "\n".join(lines).strip("\n")
167
168
169
170 # ------------------ The Markdown Extension -------------------------------
171 class HiliteTreeprocessor(Treeprocessor):
172 """ Hilight source code in code blocks. """
173
174 def run(self, root):
175 """ Find code blocks and store in htmlStash. """
176 blocks = root.getiterator('pre')
177 for block in blocks:
178 children = block.getchildren()
179 if len(children) == 1 and children[0].tag == 'code':
180 code = CodeHilite(children[0].text,
181 linenums=self.config['linenums'],
182 guess_lang=self.config['guess_lang'],
183 css_class=self.config['css_class'],
184 style=self.config['pygments_style'],
185 noclasses=self.config['noclasses'],
186 tab_length=self.markdown.tab_length)
187 placeholder = self.markdown.htmlStash.store(code.hilite(),
188 safe=True)
189 # Clear codeblock in etree instance
190 block.clear()
191 # Change to p element which will later
192 # be removed when inserting raw html
193 block.tag = 'p'
194 block.text = placeholder
195
196
197 class CodeHiliteExtension(Extension):
198 """ Add source code hilighting to markdown codeblocks. """
199
200 def __init__(self, configs):
201 # define default configs
202 self.config = {
203 'linenums': [None, "Use lines numbers. True=yes, False=no, None=auto "],
204 'force_linenos' : [False, "Depreciated! Use 'linenums' instead. Forc e line numbers - Default: False"],
205 'guess_lang' : [True, "Automatic language detection - Default: True" ],
206 'css_class' : ["codehilite",
207 "Set class name for wrapper <div> - Default: codehili te"],
208 'pygments_style' : ['default', 'Pygments HTML Formatter Style (Color scheme) - Default: default'],
209 'noclasses': [False, 'Use inline styles instead of CSS classes - Def ault false']
210 }
211
212 # Override defaults with user settings
213 for key, value in configs:
214 # convert strings to booleans
215 if value == 'True': value = True
216 if value == 'False': value = False
217 if value == 'None': value = None
218
219 if key == 'force_linenos':
220 warnings.warn('The "force_linenos" config setting'
221 ' to the CodeHilite extension is deprecrecated.'
222 ' Use "linenums" instead.', PendingDeprecationWarning)
223 if value:
224 # Carry 'force_linenos' over to new 'linenos'.
225 self.setConfig('linenums', True)
226
227 self.setConfig(key, value)
228
229 def extendMarkdown(self, md, md_globals):
230 """ Add HilitePostprocessor to Markdown instance. """
231 hiliter = HiliteTreeprocessor(md)
232 hiliter.config = self.getConfigs()
233 md.treeprocessors.add("hilite", hiliter, "<inline")
234
235 md.registerExtension(self)
236
237
238 def makeExtension(configs={}):
239 return CodeHiliteExtension(configs=configs)
240
OLDNEW
« 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