allura
修訂 | f49a7af095a5ef5355b0bccd5329b11f0a667fd9 (tree) |
---|---|
時間 | 2012-05-04 19:17:37 |
作者 | bolkimen <bolkimen@yaho...> |
Commiter | bolkimen |
ticket:47 add tests and change code
@@ -542,7 +542,7 @@ def paging_sanitizer(limit, page, total_count, zero_based_pages=True): | ||
542 | 542 | page = min(max(int(page), (0 if zero_based_pages else 1)), max_page) |
543 | 543 | return limit, page |
544 | 544 | |
545 | -def render_any_markup(name, text): | |
545 | +def render_any_markup(name, text, code_mode=False): | |
546 | 546 | """ |
547 | 547 | renders any markup format using the pypeline |
548 | 548 | Returns jinja-safe text |
@@ -551,6 +551,15 @@ def render_any_markup(name, text): | ||
551 | 551 | text = '<p><em>Empty File</em></p>' |
552 | 552 | else: |
553 | 553 | text = pylons.g.pypeline_markup.render(name, text) |
554 | - if not pylons.g.pypeline_markup.can_render(name): | |
555 | - text = '<pre>%s</pre>' % text | |
554 | + if not pylons.g.pypeline_markup.can_render(name) or True: | |
555 | + if code_mode: | |
556 | + markup_text = '<div class="codehilite"><pre>' | |
557 | + line_num = 1 | |
558 | + for line in text.splitlines(): | |
559 | + markup_text = markup_text + '<div id="l%s" class="code_block"><span class="lineno">%s</span> %s</div>' % (line_num, line_num, line) | |
560 | + line_num += 1 | |
561 | + markup_text = markup_text + '</pre></div>' | |
562 | + text = markup_text | |
563 | + else: | |
564 | + text = '<pre>%s</pre>' % text | |
556 | 565 | return Markup(text) |
@@ -407,7 +407,6 @@ class LineAnchorCodeHtmlFormatter(HtmlFormatter): | ||
407 | 407 | num = self.linenostart |
408 | 408 | yield 0, ('<pre' + (style and ' style="%s"' % style) + '>') |
409 | 409 | for tup in inner: |
410 | - yield (tup[0], '<a class="linelink" href="#codeline_%s">'\ | |
411 | - '<div id="codeline_%s" class="code_block">%s</div></a>' % (num, num, tup[1])) | |
410 | + yield (tup[0], '<div id="l%s" class="code_block">%s</div>' % (num, tup[1])) | |
412 | 411 | num += 1 |
413 | 412 | yield 0, '</pre>' |
@@ -64,7 +64,6 @@ | ||
64 | 64 | |
65 | 65 | .codehilite pre { margin:0; } |
66 | 66 | .codehilite div { margin:0; padding: 0; } |
67 | -.codehilite a.linelink { text-decoration: none; } | |
68 | -.codehilite a.linelink .code_block { width:100%; } | |
69 | -.codehilite a.linelink .code_block:hover { background-color: #ffff99; } | |
67 | +.codehilite .code_block { width:100%; } | |
68 | +.codehilite .code_block:hover { background-color: #ffff99; } | |
70 | 69 | .codehilite .lineno { background-color: #ebebeb; display:inline-block; padding:0 .5em; border-width: 0 1px 0 0; border-style: solid; border-color: #ddd; } |
@@ -22,17 +22,18 @@ | ||
22 | 22 | {{ super() }} |
23 | 23 | <script type="text/javascript">(function() { |
24 | 24 | var hash = window.location.hash.substring(1); |
25 | - if (hash != '' && hash.substring(0, 9) == 'codeline_') { | |
25 | + if (hash != '' && hash.substring(0, 1) == 'l' && !isNaN(hash.substring(1))) { | |
26 | 26 | $('#' + hash).css('background-color', '#ffff99'); |
27 | 27 | } |
28 | 28 | |
29 | 29 | $('.code_block').each(function(index, element) { |
30 | 30 | $(element).bind('click', function() { |
31 | 31 | var hash = window.location.hash.substring(1); |
32 | - if (hash != '' && hash.substring(0, 9) == 'codeline_') { | |
32 | + if (hash != '' && hash.substring(0, 1) == 'l' && !isNaN(hash.substring(1))) { | |
33 | 33 | $('#' + hash).css('background-color', 'transparent'); |
34 | 34 | } |
35 | 35 | $(element).css('background-color', '#ffff99'); |
36 | + window.location.href = '#' + $(element).attr('id'); | |
36 | 37 | }); |
37 | 38 | }); |
38 | 39 | }()); |
@@ -68,7 +69,7 @@ | ||
68 | 69 | <div class="clip grid-19"> |
69 | 70 | <h3><span class="ico-l"><b data-icon="{{g.icons['table'].char}}" class="ico {{g.icons['table'].css}}"></b> {{h.really_unicode(blob.name)}}</span></h3> |
70 | 71 | {% if blob.has_pypeline_view %} |
71 | - {{h.render_any_markup(blob.name, blob.text)}} | |
72 | + {{h.render_any_markup(blob.name, blob.text, True)}} | |
72 | 73 | {% else %} |
73 | 74 | {{g.highlight(blob.text, filename=blob.name)}} |
74 | 75 | {% endif %} |
@@ -5,6 +5,10 @@ import unittest | ||
5 | 5 | import pylons |
6 | 6 | from webob import Request |
7 | 7 | |
8 | +from pygments import highlight | |
9 | +from pygments.lexers import PythonLexer, get_lexer_for_filename | |
10 | +from pygments.formatters import HtmlFormatter | |
11 | + | |
8 | 12 | from ming.orm import state |
9 | 13 | from alluratest.controller import setup_unit_test |
10 | 14 |
@@ -115,3 +119,16 @@ class TestCaseInsensitiveDict(unittest.TestCase): | ||
115 | 119 | assert d == dict(foo=1, bar=2) |
116 | 120 | assert d != dict(Foo=1, bar=2) |
117 | 121 | assert d == utils.CaseInsensitiveDict(Foo=1, bar=2) |
122 | + | |
123 | +class TestLineAnchorCodeHtmlFormatter(unittest.TestCase): | |
124 | + def test_render(self): | |
125 | + code = '#!/usr/bin/env python\n'\ | |
126 | + 'print "Hello, world!"' | |
127 | + | |
128 | + formatter = utils.LineAnchorCodeHtmlFormatter(cssclass='codehilite', | |
129 | + linenos='inline') | |
130 | + lexer = get_lexer_for_filename("some.py", encoding='chardet') | |
131 | + hl_code = highlight(code, lexer, formatter) | |
132 | + assert '<div class="codehilite">' in hl_code | |
133 | + assert '<div id="l1" class="code_block">' in hl_code | |
134 | + assert '<span class="lineno">1</span>' in hl_code |
@@ -149,6 +149,8 @@ class TestRootController(TestController): | ||
149 | 149 | assert 'README' in resp.html.find('h2',{'class':'dark title'}).contents[2] |
150 | 150 | content = str(resp.html.find('div',{'class':'clip grid-19'})) |
151 | 151 | assert 'This is readme' in content, content |
152 | + assert '<div id="l1" class="code_block">' in resp | |
153 | + assert 'var hash = window.location.hash.substring(1);' in resp | |
152 | 154 | |
153 | 155 | def test_invalid_file(self): |
154 | 156 | ci = self._get_ci() |
@@ -126,6 +126,8 @@ class TestRootController(TestController): | ||
126 | 126 | assert 'README' in resp.html.find('h2',{'class':'dark title'}).contents[2] |
127 | 127 | content = str(resp.html.find('div',{'class':'clip grid-19'})) |
128 | 128 | assert 'This is readme' in content, content |
129 | + assert '<div id="l1" class="code_block">' in resp | |
130 | + assert 'var hash = window.location.hash.substring(1);' in resp | |
129 | 131 | |
130 | 132 | def test_invalid_file(self): |
131 | 133 | ci = self._get_ci() |
@@ -76,6 +76,8 @@ class TestRootController(TestController): | ||
76 | 76 | assert 'README' in resp.html.find('h2',{'class':'dark title'}).contents[2] |
77 | 77 | content = str(resp.html.find('div',{'class':'clip grid-19'})) |
78 | 78 | assert 'This is readme' in content, content |
79 | + assert '<div id="l1" class="code_block">' in resp | |
80 | + assert 'var hash = window.location.hash.substring(1);' in resp | |
79 | 81 | |
80 | 82 | def test_invalid_file(self): |
81 | 83 | resp = self.app.get('/src/1/tree/READMEz', status=404) |