Mercurial > jouvence
changeset 3:6019eee799bf
Add base classes for rendering.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 03 Jan 2017 09:05:48 -0800 |
parents | 59fe8cb6190d |
children | 9053902c750e |
files | fontaine/renderer.py tests/test_renderer.py |
diffstat | 2 files changed, 132 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/fontaine/renderer.py Tue Jan 03 09:05:28 2017 -0800 +++ b/fontaine/renderer.py Tue Jan 03 09:05:48 2017 -0800 @@ -1,4 +1,102 @@ import re +from fontaine.document import ( + TYPE_ACTION, TYPE_CENTEREDACTION, TYPE_CHARACTER, TYPE_DIALOG, + TYPE_PARENTHETICAL, TYPE_TRANSITION, TYPE_LYRICS, TYPE_PAGEBREAK) + + +class BaseDocumentRenderer: + def __init__(self, text_renderer=None): + self.text_renderer = text_renderer + if not text_renderer: + self.text_renderer = NullTextRenderer() + + self._para_rdrs = { + TYPE_ACTION: self.write_action, + TYPE_CENTEREDACTION: self.write_centeredaction, + TYPE_CHARACTER: self.write_character, + TYPE_DIALOG: self.write_dialog, + TYPE_PARENTHETICAL: self.write_parenthetical, + TYPE_TRANSITION: self.write_transition, + TYPE_LYRICS: self.write_lyrics, + TYPE_PAGEBREAK: self.write_pagebreak, + } + + def _tr(self, text): + return self.text_renderer.render_text(text) + + def render_doc(self, doc): + self.write_header(doc) + self.render_title_page(doc.title_values) + for s in doc.scenes: + self.render_scene(s) + self.write_footer(doc) + + def render_title_page(self, values): + # Render known metadata. + title = values.get('title') + credit = values.get('credit') + author = values.get('author') or values.get('authors') + source = values.get('source') + center_text = '\n\n'.join([ + i for i in [title, credit, author, source] + if i is not None]) + self.write_title_heading(self._tr(center_text)) + + ddate = values.get('date') or values.get('draft date') + contact = values.get('contact') + bottom_text = '\n\n'.join([ + i for i in [ddate, contact] + if i is not None]) + self.write_title_footer(self._tr(bottom_text)) + + def render_scene(self, scene): + if scene.header is not None: + self.write_scene_heading(scene.header) + for p in scene.paragraphs: + rdr_func = self._para_rdrs[p.type] + if p.type != TYPE_PAGEBREAK: + rdr_func(self._tr(p.text)) + else: + rdr_func() + + def write_header(self, doc): + pass + + def write_footer(self, doc): + pass + + def write_title_heading(self, text): + raise NotImplementedError() + + def write_title_footer(self, text): + raise NotImplementedError() + + def write_scene_heading(self, text): + raise NotImplementedError() + + def write_action(self, text): + raise NotImplementedError() + + def write_centeredaction(self, text): + raise NotImplementedError() + + def write_character(self, text): + raise NotImplementedError() + + def write_dialog(self, text): + raise NotImplementedError() + + def write_parenthetical(self, text): + raise NotImplementedError() + + def write_transition(self, text): + raise NotImplementedError() + + def write_lyrics(self, text): + raise NotImplementedError() + + def write_pagebreak(self): + raise NotImplementedError() RE_ITALICS = re.compile( @@ -9,41 +107,52 @@ r"(?P<before>^|\s)(?P<esc>\\)?_(?P<text>.*[^\s])_(?=[^a-zA-Z0-9]|$)") -class BaseRenderer: +class BaseTextRenderer: def render_text(self, text): # Replace bold stuff to catch double asterisks. - text = RE_BOLD.sub(self._do_write_bold, text) - text = RE_ITALICS.sub(self._do_write_italics, text) - text = RE_UNDERLINE.sub(self._do_write_underline, text) + text = RE_BOLD.sub(self._do_make_bold, text) + text = RE_ITALICS.sub(self._do_make_italics, text) + text = RE_UNDERLINE.sub(self._do_make_underline, text) return text - def _do_write_italics(self, m): + def _do_make_italics(self, m): if m.group('esc'): return m.group('before') + '*' + m.group('text') + '*' return ( m.group('before') + - self.write_italics(m.group('text'))) + self.make_italics(m.group('text'))) - def _do_write_bold(self, m): + def _do_make_bold(self, m): if m.group('esc'): return m.group('before') + '**' + m.group('text') + '**' return ( m.group('before') + - self.write_bold(m.group('text'))) + self.make_bold(m.group('text'))) - def _do_write_underline(self, m): + def _do_make_underline(self, m): if m.group('esc'): return m.group('before') + '_' + m.group('text') + '_' return ( m.group('before') + - self.write_underline(m.group('text'))) + self.make_underline(m.group('text'))) + + def make_italics(self, text): + raise NotImplementedError() - def write_italics(self, text): + def make_bold(self, text): + raise NotImplementedError() + + def make_underline(self, text): raise NotImplementedError() - def write_bold(self, text): - raise NotImplementedError() + +class NullTextRenderer(BaseTextRenderer): + def make_bold(self, text): + return text - def write_underline(self, text): - raise NotImplementedError() + def make_italics(self, text): + return text + + def make_underline(self, text): + return text
--- a/tests/test_renderer.py Tue Jan 03 09:05:28 2017 -0800 +++ b/tests/test_renderer.py Tue Jan 03 09:05:48 2017 -0800 @@ -1,15 +1,15 @@ import pytest -from fontaine.renderer import BaseRenderer +from fontaine.renderer import BaseTextRenderer -class TestRenderer(BaseRenderer): - def write_bold(self, text): +class TestTextRenderer(BaseTextRenderer): + def make_bold(self, text): return 'B:' + text + ':B' - def write_italics(self, text): + def make_italics(self, text): return 'I:' + text + ':I' - def write_underline(self, text): + def make_underline(self, text): return 'U:' + text + ':U' @@ -25,7 +25,7 @@ ("This is an \_escaped_ one.", "This is an _escaped_ one.") ]) def test_underline(intext, expected): - r = TestRenderer() + r = TestTextRenderer() out = r.render_text(intext) assert out == expected @@ -42,7 +42,7 @@ ("This is some \*escaped* one.", "This is some *escaped* one.") ]) def test_italics(intext, expected): - r = TestRenderer() + r = TestTextRenderer() out = r.render_text(intext) assert out == expected @@ -59,6 +59,6 @@ ("This is some \**escaped** one.", "This is some **escaped** one.") ]) def test_bold(intext, expected): - r = TestRenderer() + r = TestTextRenderer() out = r.render_text(intext) assert out == expected