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