1. James Tocknell
  2. shinypress

Commits

Peter Ward  committed 31fb8f0

Added lyrics doctest.

  • Participants
  • Parent commits 072f563
  • Branches default

Comments (0)

Files changed (4)

File setup.py

View file
  • Ignore whitespace
     author_email='peteraward@gmail.com',
     requires=['jinja2'],
     packages=['shinypress'],
+    test_suite='test_shinypress.suite',
     entry_points={
         'console_scripts': [
             'shinypress-merge = shinypress.merge',

File shinypress/__init__.py

View file
  • Ignore whitespace
-from shinypress.handlers import text, lyrics, pdf, images, hacks
-
-handlers = dict(
-    text=text.render,
-    title=text.title,
-    lyrics=lyrics.render,
-    pdf=pdf.render,
-    images=images.render,
-
-    background=hacks.background,
-)
-

File shinypress/lyrics/__init__.py

View file
  • Ignore whitespace
 from .. import mime_utils
 
 class LyricsConverter(object):
+    """
+    A converter for a simple markup for song lyrics.
+
+    The first paragraph is interpreted as information about the song.
+    The first line is the song title, and the second line has the authors.
+    Remainder lines are in a "Key: Value" format, where the keys can be
+    anything, and are case-insensitive.
+
+    This is followed by paragraphs, where each paragraph is a verse.
+
+    >>> source = '''\\
+    ... My Song Title
+    ... Author One, Author Two
+    ... Copyleft: Foobar Lawyers
+    ...
+    ... This is verse one.
+    ... And a continuation of the same verse!
+    ...
+    ... Verse 2:
+    ... This verse is labelled.
+    ... The label won't show.
+    ...
+    ... (verse 2)
+    ...
+    ... Verse 3:
+    ... And the verse can be repeated::
+    ... If it has a colon on the first line,
+    ... it must be doubled to escape it
+    ... '''
+
+    The lyrics can be loaded using the from_file class method.
+    Then, the lyrics can be queried for their information.
+
+    >>> from StringIO import StringIO
+    >>> lyrics = LyricsConverter.from_file(StringIO(source), 'text/plain')
+    >>> lyrics.info['title']
+    'My Song Title'
+    >>> lyrics.info['authors']
+    'Author One, Author Two'
+    >>> lyrics.info['copyleft']
+    'Foobar Lawyers'
+    >>> len(lyrics.verses)
+    4
+    >>> lyrics.verses[1] == lyrics.verses[2]
+    True
+    >>> 'verse is labelled' in lyrics.verses[1]
+    True
+    >>> 'Verse 2' in lyrics.verses[1]
+    False
+
+    The lyrics can be changed and written out to a variety of output types.
+    For instance, if we change the song name, the source output should be almost
+    the same as the original data.
+    The differences are that the info keys will be shown in title case, and
+    verse labels will be removed.
+    TODO: fix this so that verse labels are retained.
+
+    >>> lyrics.title = 'Your Song Title'
+    >>> output = StringIO()
+    >>> lyrics.save(output, 'text/plain')
+    >>> new_source = output.getvalue()
+    >>> print new_source
+    Your Song Title
+    Author One, Author Two
+    Copyleft: Foobar Lawyers
+    <BLANKLINE>
+    This is verse one.
+    And a continuation of the same verse!
+    <BLANKLINE>
+    This verse is labelled.
+    The label won't show.
+    <BLANKLINE>
+    This verse is labelled.
+    The label won't show.
+    <BLANKLINE>
+    And the verse can be repeated::
+    If it has a colon on the first line,
+    it must be doubled to escape it
+    <BLANKLINE>
+    """
+
     input_mimetypes = [
         'text/plain',
     ]
 
     output_mimetypes = [
+        'text/plain',
         'text/html',
         'text/x-tex',
     ]
 
+    def __init__(self, info, verses):
+        self.info = dict(info)
+        self.verses = list(verses)
+
+    def get_title(self):
+        return self.info['title']
+    def set_title(self, new_title):
+        self.info['title'] = new_title
+    title = property(get_title, set_title)
+
+    def get_authors(self):
+        return self.info['authors']
+    def set_authors(self, new_authors):
+        self.info['authors'] = new_authors
+    authors = property(get_authors, set_authors)
+
+    def save_source(self, output):
+        print >> output, self.title
+        print >> output, self.authors
+        for key, value in self.info.items():
+            if key not in ('title', 'authors'):
+                print >> output, '%s: %s' % (key.title(), value)
+        print >> output
+
+        print >> output, '\n\n'.join(self.verses)
+
     def save(self, file, mime):
         assert mime_utils.any_matches(mime, self.output_mimetypes)
 
+        if mime == 'text/plain':
+            self.save_source(file)
+        elif mime == 'text/html':
+            self.save_html(file)
+        elif mime == 'text/x-tex':
+            raise NotImplementedError
+        else:
+            # only reached if you've changed output_mimetypes
+            # without changing this if statement
+            raise ValueError, 'should not be reached'
+
     @classmethod
     def from_file(cls, file, mime):
         assert mime_utils.any_matches(mime, cls.input_mimetypes)
+        info, verses = parse_lyrics(file)
+        return cls(info, verses)
 
-        info, verses = parse_lyrics(file)

File test_shinypress.py

View file
  • Ignore whitespace
+import doctest
+import unittest
+
+def suite():
+    from shinypress import lyrics
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite(lyrics))
+    return suite