Changeset 113
- Timestamp:
- 04/07/07 15:14:04 (2 years ago)
- Files:
-
- trunk/src/shakespeare/format.py (modified) (1 diff)
- trunk/src/shakespeare/format_test.py (modified) (1 diff)
- trunk/src/shakespeare/template/view_annotate.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/shakespeare/format.py
Revision 99 Revision 113 1 """ 1 """ 2 Format texts in a variety of ways 2 Format texts in a variety of ways 3 """ 3 """ 4 4 5 def format_text(fileobj, format): 5 def format_text(fileobj, format): 6 """Format a provided text in a variety of ways. 6 """Format a provided text in a variety of ways. 7 7 8 @format: the name specifying the format to use 8 @format: the name specifying the format to use 9 """ 9 """ 10 formatter = None 10 formatter = None 11 if format == 'plain': 11 if format == 'plain': 12 formatter = TextFormatterPlain(fileobj) 12 formatter = TextFormatterPlain(fileobj) 13 elif format == 'lineno': 13 elif format == 'lineno': 14 formatter = TextFormatterLineno(fileobj) 14 formatter = TextFormatterLineno(fileobj) 15 elif format == 'annotate': 15 elif format == 'annotate': 16 formatter = TextFormatterAnnotate(fileobj) 16 formatter = TextFormatterAnnotate(fileobj) 17 else: 17 else: 18 raise ValueError('Unknown format: %s' % format) 18 raise ValueError('Unknown format: %s' % format) 19 return formatter.format() 19 return formatter.format() 20 20 21 21 22 class TextFormatter(object): 22 class TextFormatter(object): 23 """Abstract base class for formatters. 23 """Abstract base class for formatters. 24 """ 24 """ 25 25 26 def __init__(self, file=None): 26 def __init__(self, file=None): 27 """ 27 """ 28 @file: file-like object containing a text in plain txt with utf-8 28 @file: file-like object containing a text in plain txt with utf-8 29 encoding 29 encoding 30 """ 30 """ 31 self.file = file 31 self.file = file 32 32 33 def format(self): 33 def format(self): 34 """Format the supplied text. 34 """Format the supplied text. 35 35 36 The returned string will be in unicode format with utf-8 encoding 36 The returned string will be in unicode format with utf-8 encoding 37 """ 37 """ 38 raise NotImplementedError() 38 raise NotImplementedError() 39 39 40 def escape_chars(self, text): 40 def escape_chars(self, text): 41 return text.replace('&', '&').replace('<', '<') 41 return text.replace('&', '&').replace('<', '<') 42 42 43 class TextFormatterPlain(TextFormatter): 43 class TextFormatterPlain(TextFormatter): 44 """Format the text as plain text (in an html <pre> tag). 44 """Format the text as plain text (in an html <pre> tag). 45 """ 45 """ 46 46 47 def format(self): 47 def format(self): 48 out = unicode(self.file.read(), 'utf-8') 48 out = unicode(self.file.read(), 'utf-8') 49 out = self.escape_chars(out) 49 out = self.escape_chars(out) 50 out = \ 50 out = \ 51 u''' 51 u''' 52 <pre> 52 <pre> 53 %s 53 %s 54 </pre>''' % out 54 </pre>''' % out 55 return out 55 return out 56 56 57 class TextFormatterLineno(TextFormatter): 57 class TextFormatterLineno(TextFormatter): 58 """Format the text to have line numbers. 58 """Format the text to have line numbers. 59 """ 59 """ 60 60 61 def format(self): 61 def format(self): 62 result = '' 62 result = '' 63 count = 0 63 count = 0 64 for line in self.file.readlines(): 64 for line in self.file.readlines(): 65 tlineno = unicode(count).ljust(4) # assume line no < 10000 65 tlineno = unicode(count).ljust(4) # assume line no < 10000 66 tline = unicode(line, 'utf-8').rstrip() 66 tline = unicode(line, 'utf-8').rstrip() 67 tline = self.escape_chars(tline) 67 tline = self.escape_chars(tline) 68 result += u'<pre id="%s">%s %s</pre>\n' % (count, tlineno, tline) 68 result += u'<pre id="%s">%s %s</pre>\n' % (count, tlineno, tline) 69 count += 1 69 count += 1 70 return result 70 return result 71 71 72 72 73 class TextFormatterAnnotate(TextFormatter): 73 class TextFormatterAnnotate(TextFormatter): 74 """Format the text in a manner suitable for marginalia annotation. 74 """Format the text in a manner suitable for marginalia annotation. 75 """ 75 """ 76 entry_template = u''' 76 entry_template = u''' 77 <div id="%(id)s" class="hentry"> 77 <div id="%(id)s" class="hentry"> 78 <h3 class="entry-title">%(title)s</h3> 78 <h3 class="entry-title">%(title)s</h3> 79 <div class="entry-content"> 79 <div class="entry-content"> 80 %(content)s 80 %(content)s 81 </div><!-- /entry-content --> 81 </div><!-- /entry-content --> 82 <p class="metadata"> 83 <a rel="bookmark" href="%(page_url)s#%(id)s">#</a> 84 <span class="author">%(author)s</span> 85 </p> 82 <div class="notes"> 86 <div class="notes"> 83 <button class="createAnnotation" onclick="createAnnotation(' m1',true)" title="Click here to create an annotation">></button>87 <button class="createAnnotation" onclick="createAnnotation('%(id)s',true)" title="Click here to create an annotation">></button> 84 <ol> 88 <ol> 85 <li></li> 89 <li></li> 86 </ol> 90 </ol> 87 </div><!-- /notes --> 91 </div><!-- /notes --> 88 </div><!-- /hentry --> 92 </div><!-- /hentry --> 89 ''' 93 ''' 90 94 91 def format(self): 95 def format(self): 92 line_numberer = TextFormatterLineno(self.file) 96 line_numberer = TextFormatterLineno(self.file) 93 text_with_linenos = line_numberer.format() 97 text_with_linenos = line_numberer.format() 94 # todo chunking 98 # todo chunking 95 values = { 99 values = { 96 'content' : text_with_linenos, 100 'content' : text_with_linenos, 97 'title' : 'Test Stuff', 101 'title' : 'Test Stuff', 98 'id' : 'm2', 102 'id' : 'm2', 103 'page_url' : 'http://localhost:8080/', 104 'author' : 'Nemo', 99 } 105 } 100 result = self.entry_template % values 106 result = self.entry_template % values 101 return result 107 return result 102 108 trunk/src/shakespeare/format_test.py
Revision 99 Revision 113 1 import StringIO 1 import StringIO 2 import shakespeare.format 2 import shakespeare.format 3 3 4 4 5 starttext = unicode('''Blah \xc3\xa6 5 starttext = unicode('''Blah \xc3\xa6 6 blah & blah''', 'utf-8') 6 blah & blah''', 'utf-8') 7 7 8 sometext = starttext.replace('&', '&') 8 sometext = starttext.replace('&', '&') 9 9 10 class TestTextFormatter: 10 class TestTextFormatter: 11 formatter = shakespeare.format.TextFormatter() 11 formatter = shakespeare.format.TextFormatter() 12 12 13 def test_escape_chars(self): 13 def test_escape_chars(self): 14 out = self.formatter.escape_chars(starttext) 14 out = self.formatter.escape_chars(starttext) 15 assert out == sometext 15 assert out == sometext 16 16 17 17 18 class TestTextFormatterPlain: 18 class TestTextFormatterPlain: 19 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 19 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 20 formatter = shakespeare.format.TextFormatterPlain(fileobj) 20 formatter = shakespeare.format.TextFormatterPlain(fileobj) 21 exp = u''' 21 exp = u''' 22 <pre> 22 <pre> 23 %s 23 %s 24 </pre>''' % sometext 24 </pre>''' % sometext 25 25 26 def test_format(self): 26 def test_format(self): 27 out = self.formatter.format() 27 out = self.formatter.format() 28 assert out == self.exp 28 assert out == self.exp 29 29 30 30 31 class TestTextFormatterLineno: 31 class TestTextFormatterLineno: 32 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 32 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 33 formatter = shakespeare.format.TextFormatterLineno(fileobj) 33 formatter = shakespeare.format.TextFormatterLineno(fileobj) 34 exp = u'''<pre id="0">0 Blah \xe6</pre> 34 exp = u'''<pre id="0">0 Blah \xe6</pre> 35 <pre id="1">1 blah & blah</pre> 35 <pre id="1">1 blah & blah</pre> 36 ''' 36 ''' 37 37 38 def test_format(self): 38 def test_format(self): 39 out = self.formatter.format() 39 out = self.formatter.format() 40 assert out == self.exp 40 assert out == self.exp 41 41 42 def test_text_format():43 formatlist = [ ('plain', TestTextFormatterPlain),44 ('lineno', TestTextFormatterLineno),45 ('annotate', TestTextFormatterAnnotate),46 ]47 for item in formatlist:48 fileobj = StringIO.StringIO(starttext.encode('utf-8'))49 tout = shakespeare.format.format_text(fileobj, item[0])50 assert tout == item[1].exp51 42 52 class TestTextFormatterAnnotate: 43 class TestTextFormatterAnnotate: 53 44 54 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 45 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 55 formatter = shakespeare.format.TextFormatterAnnotate(fileobj) 46 formatter = shakespeare.format.TextFormatterAnnotate(fileobj) 56 exp = u''' 47 exp = u''' 57 <div id="m2" class="hentry"> 48 <div id="m2" class="hentry"> 58 <h3 class="entry-title">Test Stuff</h3> 49 <h3 class="entry-title">Test Stuff</h3> 59 <div class="entry-content"> 50 <div class="entry-content"> 60 <pre id="0">0 Blah \xe6</pre> 51 <pre id="0">0 Blah \xe6</pre> 61 <pre id="1">1 blah & blah</pre> 52 <pre id="1">1 blah & blah</pre> 62 53 63 </div><!-- /entry-content --> 54 </div><!-- /entry-content --> 55 <p class="metadata"> 56 <a rel="bookmark" href="http://localhost:8080/#m2">#</a> 57 <span class="author">Nemo</span> 58 </p> 64 <div class="notes"> 59 <div class="notes"> 65 <button class="createAnnotation" onclick="createAnnotation('m 1',true)" title="Click here to create an annotation">></button>60 <button class="createAnnotation" onclick="createAnnotation('m2',true)" title="Click here to create an annotation">></button> 66 <ol> 61 <ol> 67 <li></li> 62 <li></li> 68 </ol> 63 </ol> 69 </div><!-- /notes --> 64 </div><!-- /notes --> 70 </div><!-- /hentry --> 65 </div><!-- /hentry --> 71 ''' 66 ''' 72 67 73 def test_format(self): 68 def test_format(self): 74 out = self.formatter.format() 69 out = self.formatter.format() 75 print '"%s"' % out.encode('utf-8') 70 print '"%s"' % out.encode('utf-8') 76 print '"%s"' % self.exp.encode('utf-8') 71 print '"%s"' % self.exp.encode('utf-8') 77 assert out == self.exp 72 assert out == self.exp 78 73 79 def test_valid_xml(self): 74 def test_valid_xml(self): 80 import genshi 75 import genshi 81 outxml = genshi.XML(self.exp) 76 outxml = genshi.XML(self.exp) 82 77 78 79 def test_text_format(): 80 formatlist = [ ('plain', TestTextFormatterPlain), 81 ('lineno', TestTextFormatterLineno), 82 ('annotate', TestTextFormatterAnnotate), 83 ] 84 for item in formatlist: 85 fileobj = StringIO.StringIO(starttext.encode('utf-8')) 86 tout = shakespeare.format.format_text(fileobj, item[0]) 87 assert tout == item[1].exp 88 trunk/src/shakespeare/template/view_annotate.html
Revision 99 Revision 113 1 <html xmlns:py="http://genshi.edgewall.org/" 1 <html xmlns:py="http://genshi.edgewall.org/" 2 xmlns:xi="http://www.w3.org/2001/XInclude"> 2 xmlns:xi="http://www.w3.org/2001/XInclude"> 3 3 4 <py:def function="page_title">View Works - Annotate</py:def> 4 <py:def function="page_title">View Works - Annotate</py:def> 5 <head> 5 <head> 6 <py:def function="page_specific_css"> 6 <py:def function="page_specific_css"> 7 ${marginalia_media} 7 ${marginalia_media} 8 <style type="text/css" py:def="page_specific_css"> 8 <style type="text/css" py:def="page_specific_css"> 9 body 9 body 10 { 10 { 11 margin: 0; 11 margin: 0; 12 padding: 0; 12 padding: 0; 13 } 13 } 14 14 15 div.frame 15 div.frame 16 { 16 { 17 height: 90%; 17 height: 90%; 18 overflow: auto; 18 overflow: auto; 19 float: left; 19 float: left; 20 padding: 1em; 20 padding: 1em; 21 } 21 } 22 22 23 div.singleview 23 div.singleview 24 { 24 { 25 padding: 2em; 25 padding: 2em; 26 padding-left: 10%; 26 padding-left: 10%; 27 padding-right: 10%; 27 padding-right: 10%; 28 } 28 } 29 29 30 /* ensure we take up the whole width */ 30 /* ensure we take up the whole width */ 31 div.multiview 31 div.multiview 32 { 32 { 33 width: 100%; 33 width: 100%; 34 height: 90%; 34 height: 90%; 35 } 35 } 36 </style> 36 </style> 37 </py:def> 37 </py:def> 38 </head> 38 </head> 39 39 40 <div py:match="content"> 40 <div py:match="content"> 41 <div id="annotation-controls"> 42 <form> 43 <input type="button" onclick='showAllAnnotations( "http://localhost:8080/#*")' value="Show Annotations" /><br /> 44 <input type="button" onclick='hideAllAnnotations( "http://localhost:8080/#*")' value="Hide Annotations" /><br /> 45 </form> 46 </div> 41 <div py:if="len(texts) == 1" class="singleview"> 47 <div py:if="len(texts) == 1" class="singleview"> 42 ${texts[0]} 48 ${texts[0]} 43 </div> 49 </div> 44 <div class="multiview" py:if="len(texts) > 1" > 50 <div class="multiview" py:if="len(texts) > 1" > 45 <div py:for="text in texts" class="frame" 51 <div py:for="text in texts" class="frame" 46 style="width: ${frame_width}%;" > 52 style="width: ${frame_width}%;" > 47 ${text} 53 ${text} 48 </div> 54 </div> 49 </div> 55 </div> 50 </div> 56 </div> 51 57 52 <xi:include href="layout.html" /> 58 <xi:include href="layout.html" /> 53 </html> 59 </html>
