Mercurial > jouvence
changeset 22:142a53d6e558
Add support for notes.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 04 Jan 2017 23:03:33 -0800 |
parents | 94d094a0bdb7 |
children | 36424a1081ff |
files | README.rst jouvence/console.py jouvence/html.py jouvence/renderer.py jouvence/resources/html_header.html tests/test_renderer.py |
diffstat | 6 files changed, 88 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/README.rst Wed Jan 04 21:07:26 2017 -0800 +++ b/README.rst Wed Jan 04 23:03:33 2017 -0800 @@ -59,8 +59,8 @@ are not implemented yet: * Dual dialogue -* Notes * Boneyards * Sections and synopses +* Proper Unicode support (although Fountain's spec greatly assumes English screenplays, sadly).
--- a/jouvence/console.py Wed Jan 04 21:07:26 2017 -0800 +++ b/jouvence/console.py Wed Jan 04 23:03:33 2017 -0800 @@ -91,3 +91,9 @@ def make_underline(self, text): return self._writeStyled(colorama.Style.BRIGHT, text) + + def make_note(self, text): + out = colorama.Style.DIM + colorama.Fore.MAGENTA + out += ' [[ ' + text + ' ]] ' + out += colorama.Style.RESET_ALL + return out
--- a/jouvence/html.py Wed Jan 04 21:07:26 2017 -0800 +++ b/jouvence/html.py Wed Jan 04 23:03:33 2017 -0800 @@ -45,9 +45,17 @@ } out.write(_res('html_header.html') % data) out.write('<div class="jouvence-doc">\n') + out.write('<div class="jouvence-main">\n') def write_footer(self, doc, out): - out.write('</div>\n') + out.write('</div>\n') # End `jouvence-main` + + out.write('<div class="jouvence-notes">\n') + self._render_footnotes(out) + out.write('</div>\n') # End `jouvence-notes` + + out.write('</div>\n') # End `jouvence-doc` + if self.standalone: out.write(_res('html_footer.html')) @@ -95,8 +103,21 @@ def write_pagebreak(self, out): out.write('<hr/>\n') + def _render_footnotes(self, out): + for i, n in enumerate(self.text_renderer.notes): + note_id = i + 1 + out.write( + '<div class="jouvence-note" id="jouvence-note-%d">' % + note_id) + text = '<sup>%d</sup> %s' % (note_id, n) + _elem(out, 'p', None, _br(text)) + out.write('</div>\n') + class HtmlTextRenderer(BaseTextRenderer): + def __init__(self): + self.notes = [] + def render_text(self, text): return super().render_text(escape(text)) @@ -108,3 +129,12 @@ def make_underline(self, text): return '<u>%s</u>' % text + + def make_note(self, text): + note_id = len(self.notes) + 1 + out = '<sup id="jouvence-note-ref-%d">' % note_id + out += '<a rel="footnote" href="#jouvence-note-%d">' % note_id + out += str(note_id) + out += '</a></sup>' + self.notes.append(text) + return out
--- a/jouvence/renderer.py Wed Jan 04 21:07:26 2017 -0800 +++ b/jouvence/renderer.py Wed Jan 04 23:03:33 2017 -0800 @@ -94,6 +94,8 @@ RE_UNDERLINE = re.compile( r"(?P<before>^|\s)(?P<esc>\\)?_(?P<text>.*[^\s])_(?=[^a-zA-Z0-9]|$)") +RE_NOTE = re.compile(r"\[\[(?P<text>.+?)\]\]", re.DOTALL) + class BaseTextRenderer: def render_text(self, text): @@ -101,6 +103,7 @@ 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) + text = RE_NOTE.sub(self._do_make_note, text) return text @@ -125,6 +128,9 @@ m.group('before') + self.make_underline(m.group('text'))) + def _do_make_note(self, m): + return self.make_note(m.group('text')) + def make_italics(self, text): raise NotImplementedError() @@ -134,6 +140,9 @@ def make_underline(self, text): raise NotImplementedError() + def make_note(self, text): + raise NotImplementedError() + class NullTextRenderer(BaseTextRenderer): def make_bold(self, text): @@ -144,3 +153,6 @@ def make_underline(self, text): return text + + def make_note(self, text): + return text
--- a/jouvence/resources/html_header.html Wed Jan 04 21:07:26 2017 -0800 +++ b/jouvence/resources/html_header.html Wed Jan 04 23:03:33 2017 -0800 @@ -17,8 +17,14 @@ } .jouvence-doc { background-color: #fff; + box-shadow: #111 0px 0.5em 2em; + } + .jouvence-notes { + background-color: #593; + color: #fff; + } + .jouvence-main, .jouvence-notes { padding: 2em; - box-shadow: #111 0px 0.5em 2em; } p.footer { text-align: center;
--- a/tests/test_renderer.py Wed Jan 04 21:07:26 2017 -0800 +++ b/tests/test_renderer.py Wed Jan 04 23:03:33 2017 -0800 @@ -12,6 +12,9 @@ def make_underline(self, text): return 'U:' + text + ':U' + def make_note(self, text): + return 'N:' + text + ':N' + @pytest.mark.parametrize('intext, expected', [ ("_Underline_", "U:Underline:U"), @@ -62,3 +65,31 @@ r = TestTextRenderer() out = r.render_text(intext) assert out == expected + + +def test_note(): + r = TestTextRenderer() + out = r.render_text( + "This is JACK[[Do we have a better name?]]. He likes movies.") + expected = "This is JACKN:Do we have a better name?:N. He likes movies." + assert out == expected + + +def test_note_with_line_break(): + r = TestTextRenderer() + out = r.render_text( + "This is JACK[[Do we have a better name?\n" + "I think we did]]. He likes movies.") + expected = ("This is JACKN:Do we have a better name?\n" + "I think we did:N. He likes movies.") + assert out == expected + + +def test_note_multiple(): + r = TestTextRenderer() + out = r.render_text( + "This is JACK[[Do we have a better name?]]. " + "He likes movies[[or plays?]].") + expected = ("This is JACKN:Do we have a better name?:N. " + "He likes moviesN:or plays?:N.") + assert out == expected