Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: sitescripts/web/converters.py

Issue 17817001: Simple CMS as Anwiki replacement (Closed)
Left Patch Set: Various improvements Created Oct. 24, 2013, 11:42 a.m.
Right Patch Set: Fixed MIME type Created Nov. 4, 2013, 4:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « sitescripts/web/bin/test_server.py ('k') | sitescripts/web/sources.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This file is part of the Adblock Plus web scripts, 3 # This file is part of the Adblock Plus web scripts,
4 # Copyright (C) 2006-2013 Eyeo GmbH 4 # Copyright (C) 2006-2013 Eyeo GmbH
5 # 5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify 6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as 7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation. 8 # published by the Free Software Foundation.
9 # 9 #
10 # Adblock Plus is distributed in the hope that it will be useful, 10 # Adblock Plus is distributed in the hope that it will be useful,
(...skipping 25 matching lines...) Expand all
36 "'": "'", 36 "'": "'",
37 } 37 }
38 38
39 class Converter: 39 class Converter:
40 def __init__(self, params, key="pagedata"): 40 def __init__(self, params, key="pagedata"):
41 self._params = params 41 self._params = params
42 self._key = key 42 self._key = key
43 43
44 # Read in any parameters specified at the beginning of the file 44 # Read in any parameters specified at the beginning of the file
45 lines = params[key].splitlines(True) 45 lines = params[key].splitlines(True)
46 while len(lines) and re.search(r"^\s*[\w\-]+\s*=", lines[0]): 46 while lines and re.search(r"^\s*[\w\-]+\s*=", lines[0]):
47 name, value = lines.pop(0).split("=", 1) 47 name, value = lines.pop(0).split("=", 1)
48 params[name.strip()] = value.strip() 48 params[name.strip()] = value.strip()
49 params[key] = "".join(lines) 49 params[key] = "".join(lines)
50 50
51 def insert_localized_strings(self, text, escapes): 51 def localize_string(self, name, localedata, escapes, links=[]):
52 def escape(s): 52 def escape(s):
53 return re.sub(r".", 53 return re.sub(r".",
54 lambda match: escapes.get(match.group(0), match.group(0)), 54 lambda match: escapes.get(match.group(0), match.group(0)),
55 s, flags=re.S) 55 s, flags=re.S)
56 56 def re_escape(s):
57 return re.escape(escape(s))
58
59 try:
60 result = localedata[name].strip()
61 except KeyError:
62 raise Exception("Lookup failed for string %s used on page %s" % (name, sel f._params["page"]))
63
64 # Insert links
65 result = escape(result)
66 while links:
67 result = re.sub(
68 r"%s([^<>]*?)%s" % (re_escape("<a>"), re_escape("</a>")),
69 r'<a href="%s">\1</a>' % links.pop(0),
70 result, 1, flags=re.S
71 )
72
73 # <strong> and <em> tags are allowed
74 result = re.sub(
75 r"%s([^<>]*?)%s" % (re_escape("<strong>"), re_escape("</strong>")),
76 r"<strong>\1</strong>",
77 result, flags=re.S
78 )
79 result = re.sub(
80 r"%s([^<>]*?)%s" % (re_escape("<em>"), re_escape("</em>")),
81 r"<em>\1</em>",
82 result, flags=re.S
83 )
84 return result
85
86 def insert_localized_strings(self, text, escapes):
57 def lookup_string(match): 87 def lookup_string(match):
58 name, links = match.groups() 88 name, links = match.groups()
59 try:
60 result = self._params["localedata"][name].strip()
61 except KeyError:
62 raise Exception("Lookup failed for string %s used on page %s" % (name, s elf._params["page"]))
63
64 result = escape(result)
65 if links: 89 if links:
66 links = map(unicode.strip, links.strip("()").split(",")) 90 links = map(unicode.strip, links.strip("()").split(","))
67 while len(links): 91 else:
68 result = re.sub( 92 links = []
69 r"%s(.*?)%s" % (escape("<a>"), escape("</a>")), 93 return self.localize_string(name, self._params["localedata"], escapes, lin ks)
70 r'<a href="%s">\1</a>' % links.pop(0),
71 result, 1, flags=re.S
72 )
73 return result
74 94
75 return re.sub( 95 return re.sub(
76 r"\$([\w\-]+)(\([^()$]+\))?\$", 96 r"\$([\w\-]+)(\([^()$]+\))?\$",
77 lookup_string, 97 lookup_string,
78 text 98 text
79 ) 99 )
80 100
81 def process_links(self, text): 101 def process_links(self, text):
82 def process_link(match): 102 def process_link(match):
83 pre, attr, url, post = match.groups() 103 pre, attr, url, post = match.groups()
84 url = jinja2.Markup(url).unescape() 104 url = jinja2.Markup(url).unescape()
85 105
86 locale, new_url = self._params["source"].resolve_link(url, self._params["l ocale"]) 106 locale, new_url = self._params["source"].resolve_link(url, self._params["l ocale"])
87 if new_url != None: 107 if new_url != None:
88 url = new_url 108 url = new_url
89 if attr == "href": 109 if attr == "href":
90 post += ' hreflang="%s"' % jinja2.Markup.escape(locale) 110 post += ' hreflang="%s"' % jinja2.Markup.escape(locale)
91 111
92 return "".join((pre, jinja2.Markup.escape(url), post)) 112 return "".join((pre, jinja2.Markup.escape(url), post))
93 113
94 text = re.sub(r"(<a [^<>]*\b(href)=\")([^<>\"]+)(\")", process_link, text) 114 text = re.sub(r"(<a\s[^<>]*\b(href)=\")([^<>\"]+)(\")", process_link, text)
95 text = re.sub(r"(<img [^<>]*\b(src)=\")([^<>\"]+)(\")", process_link, text) 115 text = re.sub(r"(<img\s[^<>]*\b(src)=\")([^<>\"]+)(\")", process_link, text)
96 return text 116 return text
117
118 def resolve_includes(self, text):
119 def resolve_include(match):
120 global converters
121 name = match.group(1)
122 for format, converter_class in converters.iteritems():
123 if self._params["source"].has_include(name, format):
124 self._params["includedata"] = self._params["source"].read_include(name , format)
125 converter = converter_class(self._params, key="includedata")
126 return converter()
127 raise Exception("Failed to resolve include %s in page %s" % (name, self._p arams["page"]))
128
129 return re.sub(r'<\?\s*include\s+([^\s<>"]+)\s*\?>', resolve_include, text)
97 130
98 def __call__(self): 131 def __call__(self):
99 result = self.get_html(self._params[self._key]) 132 result = self.get_html(self._params[self._key])
133 result = self.resolve_includes(result)
100 if self._key == "pagedata": 134 if self._key == "pagedata":
101 head = [] 135 head = []
102 def add_to_head(match): 136 def add_to_head(match):
103 head.append(match.group(1)) 137 head.append(match.group(1))
104 return "" 138 return ""
105 body = re.sub(r"<head>(.*?)</head>", add_to_head, result, flags=re.S) 139 body = re.sub(r"<head>(.*?)</head>", add_to_head, result, flags=re.S)
106 return "".join(head), body 140 return "".join(head), body
107 else: 141 else:
108 return result 142 return result
109 143
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 "translate": self.translate, 176 "translate": self.translate,
143 "linkify": self.linkify, 177 "linkify": self.linkify,
144 "toclist": self.toclist, 178 "toclist": self.toclist,
145 } 179 }
146 self._env = get_custom_template_environment(filters) 180 self._env = get_custom_template_environment(filters)
147 181
148 def get_html(self, source): 182 def get_html(self, source):
149 template = self._env.from_string(source) 183 template = self._env.from_string(source)
150 return template.render(self._params) 184 return template.render(self._params)
151 185
152 def translate(self, name, page=None): 186 def translate(self, name, page=None, links=[]):
153 if page == None: 187 if page == None:
154 localedata = self._params["localedata"] 188 localedata = self._params["localedata"]
155 else: 189 else:
156 localedata = self._params["source"].read_locale(self._params["locale"], pa ge) 190 localedata = self._params["source"].read_locale(self._params["locale"], pa ge)
157 191 return jinja2.Markup(self.localize_string(name, localedata, html_escapes, li nks=links))
158 try:
159 return localedata[name]
160 except KeyError:
161 raise Exception("Lookup failed for string %s used on page %s" % (name, sel f._params["page"]))
162 192
163 def linkify(self, page, locale=None): 193 def linkify(self, page, locale=None):
164 if locale == None: 194 if locale == None:
165 locale = self._params["locale"] 195 locale = self._params["locale"]
166 196
167 locale, url = self._params["source"].resolve_link(page, locale) 197 locale, url = self._params["source"].resolve_link(page, locale)
168 return jinja2.Markup('<a href="%s" hreflang="%s">' % ( 198 return jinja2.Markup('<a href="%s" hreflang="%s">' % (
169 jinja2.Markup.escape(url), 199 jinja2.Markup.escape(url),
170 jinja2.Markup.escape(locale) 200 jinja2.Markup.escape(locale)
171 )) 201 ))
172 202
173 def toclist(self, content): 203 def toclist(self, content):
174 flat = [] 204 flat = []
175 for match in re.finditer(r'<h(\d) [^<>]*\bid="([^<>"]+)"[^<>]*>(.*?)</h\1>', content, re.S): 205 for match in re.finditer(r'<h(\d)\s[^<>]*\bid="([^<>"]+)"[^<>]*>(.*?)</h\1>' , content, re.S):
176 flat.append({ 206 flat.append({
177 "level": int(match.group(1)), 207 "level": int(match.group(1)),
178 "anchor": jinja2.Markup(match.group(2)).unescape(), 208 "anchor": jinja2.Markup(match.group(2)).unescape(),
179 "title": jinja2.Markup(match.group(3)).unescape(), 209 "title": jinja2.Markup(match.group(3)).unescape(),
180 "subitems": [], 210 "subitems": [],
181 }) 211 })
182 212
183 structured = [] 213 structured = []
184 stack = [{"level": 0, "subitems": structured}] 214 stack = [{"level": 0, "subitems": structured}]
185 for item in flat: 215 for item in flat:
186 while stack[-1]["level"] >= item["level"]: 216 while stack[-1]["level"] >= item["level"]:
187 stack.pop() 217 stack.pop()
188 stack[-1]["subitems"].append(item) 218 stack[-1]["subitems"].append(item)
189 stack.append(item) 219 stack.append(item)
190 return structured 220 return structured
191 221
192 converters = { 222 converters = {
193 "raw": RawConverter, 223 "raw": RawConverter,
194 "md": MarkdownConverter, 224 "md": MarkdownConverter,
195 "tmpl": TemplateConverter, 225 "tmpl": TemplateConverter,
196 } 226 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld