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

Side by Side Diff: third_party/markdown/extensions/attr_list.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 Attribute List Extension for Python-Markdown
3 ============================================
4
5 Adds attribute list syntax. Inspired by
6 [maruku](http://maruku.rubyforge.org/proposal.html#attribute_lists)'s
7 feature of the same name.
8
9 Copyright 2011 [Waylan Limberg](http://achinghead.com/).
10
11 Contact: markdown@freewisdom.org
12
13 License: BSD (see ../LICENSE.md for details)
14
15 Dependencies:
16 * [Python 2.4+](http://python.org)
17 * [Markdown 2.1+](http://packages.python.org/Markdown/)
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 from ..util import isBlockLevel
26 import re
27
28 try:
29 Scanner = re.Scanner
30 except AttributeError:
31 # must be on Python 2.4
32 from sre import Scanner
33
34 def _handle_double_quote(s, t):
35 k, v = t.split('=')
36 return k, v.strip('"')
37
38 def _handle_single_quote(s, t):
39 k, v = t.split('=')
40 return k, v.strip("'")
41
42 def _handle_key_value(s, t):
43 return t.split('=')
44
45 def _handle_word(s, t):
46 if t.startswith('.'):
47 return '.', t[1:]
48 if t.startswith('#'):
49 return 'id', t[1:]
50 return t, t
51
52 _scanner = Scanner([
53 (r'[^ ]+=".*?"', _handle_double_quote),
54 (r"[^ ]+='.*?'", _handle_single_quote),
55 (r'[^ ]+=[^ ]*', _handle_key_value),
56 (r'[^ ]+', _handle_word),
57 (r' ', None)
58 ])
59
60 def get_attrs(str):
61 """ Parse attribute list and return a list of attribute tuples. """
62 return _scanner.scan(str)[0]
63
64 def isheader(elem):
65 return elem.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
66
67 class AttrListTreeprocessor(Treeprocessor):
68
69 BASE_RE = r'\{\:?([^\}]*)\}'
70 HEADER_RE = re.compile(r'[ ]*%s[ ]*$' % BASE_RE)
71 BLOCK_RE = re.compile(r'\n[ ]*%s[ ]*$' % BASE_RE)
72 INLINE_RE = re.compile(r'^%s' % BASE_RE)
73 NAME_RE = re.compile(r'[^A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff\u037 0-\u037d'
74 r'\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef'
75 r'\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd'
76 r'\:\-\.0-9\u00b7\u0300-\u036f\u203f-\u2040]+')
77
78 def run(self, doc):
79 for elem in doc.getiterator():
80 if isBlockLevel(elem.tag):
81 # Block level: check for attrs on last line of text
82 RE = self.BLOCK_RE
83 if isheader(elem):
84 # header: check for attrs at end of line
85 RE = self.HEADER_RE
86 if len(elem) and elem[-1].tail:
87 # has children. Get from tail of last child
88 m = RE.search(elem[-1].tail)
89 if m:
90 self.assign_attrs(elem, m.group(1))
91 elem[-1].tail = elem[-1].tail[:m.start()]
92 if isheader(elem):
93 # clean up trailing #s
94 elem[-1].tail = elem[-1].tail.rstrip('#').rstrip()
95 elif elem.text:
96 # no children. Get from text.
97 m = RE.search(elem.text)
98 if m:
99 self.assign_attrs(elem, m.group(1))
100 elem.text = elem.text[:m.start()]
101 if isheader(elem):
102 # clean up trailing #s
103 elem.text = elem.text.rstrip('#').rstrip()
104 else:
105 # inline: check for attrs at start of tail
106 if elem.tail:
107 m = self.INLINE_RE.match(elem.tail)
108 if m:
109 self.assign_attrs(elem, m.group(1))
110 elem.tail = elem.tail[m.end():]
111
112 def assign_attrs(self, elem, attrs):
113 """ Assign attrs to element. """
114 for k, v in get_attrs(attrs):
115 if k == '.':
116 # add to class
117 cls = elem.get('class')
118 if cls:
119 elem.set('class', '%s %s' % (cls, v))
120 else:
121 elem.set('class', v)
122 else:
123 # assign attr k with v
124 elem.set(self.sanitize_name(k), v)
125
126 def sanitize_name(self, name):
127 """
128 Sanitize name as 'an XML Name, minus the ":"'.
129 See http://www.w3.org/TR/REC-xml-names/#NT-NCName
130 """
131 return self.NAME_RE.sub('_', name)
132
133
134 class AttrListExtension(Extension):
135 def extendMarkdown(self, md, md_globals):
136 md.treeprocessors.add('attr_list', AttrListTreeprocessor(md), '>prettify ')
137
138
139 def makeExtension(configs={}):
140 return AttrListExtension(configs=configs)
OLDNEW
« no previous file with comments | « third_party/markdown/extensions/admonition.py ('k') | third_party/markdown/extensions/codehilite.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698