Mercurial > jouvence
changeset 31:9ae14e9615e6
docs: Add Sphynx documentation and code docstrings.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 15 Jan 2017 22:41:49 -0800 |
parents | ff71a3e7fab0 |
children | 86eaab47f03b |
files | .hgignore README.rst dev-requirements.txt docs/Makefile docs/api.rst docs/conf.py docs/index.rst docs/make.bat jouvence/__init__.py jouvence/cli.py jouvence/console.py jouvence/document.py jouvence/html.py jouvence/parser.py jouvence/renderer.py |
diffstat | 15 files changed, 577 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Jan 12 09:18:36 2017 -0800 +++ b/.hgignore Sun Jan 15 22:41:49 2017 -0800 @@ -10,3 +10,5 @@ dist Jouvence.egg-info jouvence/version.py + +docs/_build
--- a/README.rst Thu Jan 12 09:18:36 2017 -0800 +++ b/README.rst Sun Jan 15 22:41:49 2017 -0800 @@ -56,7 +56,7 @@ =========== Jouvence doesn't support the complete Fountain syntax yet. The following things -are not implemented yet: +are not implemented: * Dual dialogue * Proper Unicode support (although Fountain's spec greatly assumes English screenplays, sadly).
--- a/dev-requirements.txt Thu Jan 12 09:18:36 2017 -0800 +++ b/dev-requirements.txt Sun Jan 15 22:41:49 2017 -0800 @@ -1,3 +1,5 @@ py==1.4.32 pytest==3.0.5 PyYAML==3.12 +Sphinx==1.5.1 +sphinx-autobuild==0.6.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/Makefile Sun Jan 15 22:41:49 2017 -0800 @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = Jouvence +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/api.rst Sun Jan 15 22:41:49 2017 -0800 @@ -0,0 +1,166 @@ + +API +=== + +.. module:: jouvence + :synopsis: Jouvence API + +The Jouvence API is fairly simple, and includes: + + * A Fountain parser that returns a screenplay object. + * Several renderers, for formatting a screenplay object into something + you can display on screen or elsewhere. + * A screenplay object that you can manipulate for custom rendering, + analysis, and more. + + +Parser +------ + +.. automodule:: jouvence.parser + :synopsis: The Jouvence parser + :members: + + +Document +-------- + +.. module:: jouvence.document + :synopsis: The Jouvence document object model + + +.. autoclass:: JouvenceDocument + :members: + + .. attribute:: title_values + + The title page key/values dictionary. + + .. attribute:: scenes + + The list of scenes in the screenplay. + + Most screenplays start with some "free text" before the first scene. + In this case, the first scene would have no header, and would contain + this text. + + +.. autoclass:: JouvenceScene + :members: + + .. attribute:: header + + The header text of the scene, _e.g._ "EXT. JAMES' HOUSE - DAY". + + .. attribute:: paragraphs + + The list of paragraphs in the scene. Each paragraph is an instance + of :class:`~jouvence.document.JouvenceSceneElement`. + + .. method:: addAction(text) + + Adds an action (paragraph with ``TYPE_ACTION`` type). + + .. method:: addCenteredAction(text) + + Adds a centered action (paragraph with ``TYPE_CENTEREDACTION`` type). + + .. method:: addCharacter(text) + + Adds a character line (paragraph with ``TYPE_CHARACTER`` type). + + .. method:: addDialog(text) + + Adds a dialog line (paragraph with ``TYPE_DIALOG`` type). + + .. method:: addParenthetical(text) + + Adds a parenthetical (paragraph with ``TYPE_PARENTHETICAL`` type). + + .. method:: addTransition(text) + + Adds a transition (paragraph with ``TYPE_TRANSITION`` type). + + .. method:: addLyrics(text) + + Adds some lyrics (paragraph with ``TYPE_LYRICS`` type). + + .. method:: addSynopsis(text) + + Adds a synopsis (paragraph with ``TYPE_SYNOPSIS`` type). + + +.. autoclass:: JouvenceSceneElement + :members: + + .. attribute:: type + + The type of this element. Could be any of: + + * ``TYPE_ACTION`` + * ``TYPE_CENTEREDACTION`` + * ``TYPE_CHARACTER`` + * ``TYPE_DIALOG`` + * ``TYPE_PARENTHETICAL`` + * ``TYPE_TRANSITION`` + * ``TYPE_LYRICS`` + * ``TYPE_PAGEBREAK`` + * ``TYPE_SECTION`` + * ``TYPE_SYNOPSIS`` + + .. attribute:: text + + The text for this paragraph. + + +.. autoclass:: JouvenceSceneSection + :members: + + Screenplay sections have their own class because they have a ``depth`` + attribute in addition to a type and text. + + .. attribute:: depth + + The depth, or level, of the section. + + +Renderers +--------- + +.. module:: jouvence.renderer + +.. autoclass:: BaseDocumentRenderer + :members: + + .. attribute:: force_title_page + + By default, if there are no title page values in a screenplay, no + title page will be produced. Set ``force_title_page`` to ``True`` + to force rendering a title page with default/placeholder values. + + .. attribute:: text_renderer + + The :class:`~BaseTextRenderer` instance that this document renderer + is using to handle text. + +.. autoclass:: BaseTextRenderer + :members: + + +.. automodule:: jouvence.html + :members: get_css + +.. autoclass:: HtmlDocumentRenderer + :members: + +.. autoclass:: HtmlTextRenderer + :members: + + +.. automodule:: jouvence.console + +.. autoclass:: ConsoleDocumentRenderer + :members: + +.. autoclass:: ConsoleTextRenderer + :members:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/conf.py Sun Jan 15 22:41:49 2017 -0800 @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Jouvence documentation build configuration file, created by +# sphinx-quickstart on Sun Jan 15 18:04:24 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import sys +sys.path.append(os.path.dirname(os.path.dirname(__file__))) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.coverage'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Jouvence' +copyright = '2017, BOLT80' +author = 'Ludovic Chabant' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.3.1' +# The full version, including alpha/beta/rc tags. +release = '0.3.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Jouvencedoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Jouvence.tex', 'Jouvence Documentation', + 'Ludovic Chabant', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'jouvence', 'Jouvence Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Jouvence', 'Jouvence Documentation', + author, 'Jouvence', 'One line description of project.', + 'Miscellaneous'), +]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/index.rst Sun Jan 15 22:41:49 2017 -0800 @@ -0,0 +1,79 @@ + +######## +JOUVENCE +######## + + +`Fountain`_ is a plain text markup language for screenwriting. Jouvence +is a Python package for parsing and rendering Fountain documents. + +Jouvence supports: + +* Most of the Fountain specification (see limitations below). +* Rendering to HTML and terminals. + +.. _fountain: http://fountain.io/ + + +Installation +============ + +As with many Python packages, it's recommended that you use `virtualenv`_, +but since Jouvence doesn't have many dependencies, you should be fine. + +You can install Jouvence the usual way:: + + pip install jouvence + +If you want to test that it works, you can feed it a Fountain screenplay and +see if it prints it nicely in your terminal:: + + jouvence <path-to-fountain-file> + +You should then see the Fountain file rendered with colored and indented +styles. + +.. _virtualenv: https://virtualenv.pypa.io/en/stable/ + + +Usage +===== + +The Jouvence API goes pretty much like this:: + + from jouvence.parser import JouvenceParser + from jouvence.html import HtmlDocumentRenderer + + parser = JouvenceParser() + document = parser.parse(path_to_file) + renderer = HtmlDocumentRenderer() + with open(path_to_output, 'w') as fp: + renderer.render_doc(document, fp) + + + +Limitations +=========== + +Jouvence doesn't support the complete Fountain syntax yet. The following things +are not implemented: + +* Dual dialogue +* Proper Unicode support (although Fountain's spec greatly assumes English screenplays, sadly). + + + +Documentation +============= + +.. toctree:: + :maxdepth: 2 + + api + + +If you can't find what you're looking for, have a look here: + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/make.bat Sun Jan 15 22:41:49 2017 -0800 @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=Jouvence + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd
--- a/jouvence/__init__.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/__init__.py Sun Jan 15 22:41:49 2017 -0800 @@ -1,4 +1,27 @@ +# -*- coding: utf-8 -*- +""" + JOUVENCE + ======== + + `Fountain`_ is a plain text markup language for screenwriting. Jouvence + is a Python package for parsing and rendering Fountain documents. + + Jouvence supports: + + * Most of the Fountain specification (see limitations below). + * Rendering to HTML and terminals. + + .. _fountain: http://fountain.io/ + + :copyright: (c) 2017, BOLT80. + :license: Apache2. See LICENSE file for details. +""" + +__docformat__ = 'restructuredtext en' + try: from .version import version except ImportError: version = '<unknown>' + +__version__ = version
--- a/jouvence/cli.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/cli.py Sun Jan 15 22:41:49 2017 -0800 @@ -3,6 +3,11 @@ def main(): + """The Jouvence CLI utility. + + It lets the user print a screenplay to the terminal (with syntax + highlighting), or save a screenplay into a nicely formatted HTML page. + """ parser = argparse.ArgumentParser( description='Jouvence command line utility') parser.add_argument('script')
--- a/jouvence/console.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/console.py Sun Jan 15 22:41:49 2017 -0800 @@ -1,3 +1,6 @@ +"""The ``jouvence.console`` module contains utilities for rendering +a Foutain screenplay in a terminal. +""" import os import colorama from .renderer import BaseDocumentRenderer, BaseTextRenderer @@ -15,6 +18,9 @@ class ConsoleDocumentRenderer(BaseDocumentRenderer): + """A document renderer that prints a screenplay into a terminal with + some nice syntax highlighting. + """ def __init__(self, width=80): super().__init__(ConsoleTextRenderer()) self.width = width @@ -87,6 +93,7 @@ class ConsoleTextRenderer(BaseTextRenderer): + """A text renderer for producing ANSI colouring.""" def _writeStyled(self, style, text): return style + text + colorama.Style.NORMAL
--- a/jouvence/document.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/document.py Sun Jan 15 22:41:49 2017 -0800 @@ -2,11 +2,20 @@ class JouvenceDocument: + """Represents a Fountain screenplay in a structured way. + + A screenplay contains: + + * A title page (optional) with a key/value dictionary of settings. + * A list of scenes. + * Each scene contains a list of paragraphs of various types. + """ def __init__(self): self.title_values = {} self.scenes = [] def addScene(self, header=None): + """Adds a scene with the specified header.""" s = JouvenceScene() if header: s.header = header @@ -14,6 +23,13 @@ return s def lastScene(self, auto_create=True): + """Gets the last scene in the screenplay. + + `auto_create` + If ``True``, and the screenplay has no scenes, create + a scene with an empty header text. Otherwise, return + ``None``. + """ try: return self.scenes[-1] except IndexError: @@ -23,6 +39,10 @@ return None def lastParagraph(self): + """Gets the last paragraph of the last scene in the screenplay. + + If there's no scene in the screenplay, return ``None``. + """ s = self.lastScene(False) if s: return s.lastParagraph() @@ -30,6 +50,7 @@ class JouvenceScene: + """A scene in a screenplay.""" def __init__(self): self.header = None self.paragraphs = [] @@ -57,9 +78,11 @@ raise AttributeError def addPageBreak(self): + """Adds a page break (paragraph with ``TYPE_PAGEBREAK`` type).""" self.paragraphs.append(JouvenceSceneElement(TYPE_PAGEBREAK, None)) def addSection(self, depth, text): + """Adds a section (a :class:`~JouvenceSceneSection` instance).""" self.paragraphs.append(JouvenceSceneSection(depth, text)) def lastParagraph(self): @@ -70,6 +93,9 @@ class JouvenceSceneElement: + """An element of a screenplay scene, _e.g._ an action, a dialogue + line, a parenthetical, etc. + """ def __init__(self, el_type, text): self.type = el_type self.text = text
--- a/jouvence/html.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/html.py Sun Jan 15 22:41:49 2017 -0800 @@ -1,3 +1,7 @@ +"""The ``jouvence.html`` module contains utilities for turning a +Fountain screenplay into a web page, along with other web-related +features. +""" import os.path from markupsafe import escape from .renderer import BaseDocumentRenderer, BaseTextRenderer @@ -27,15 +31,32 @@ def get_css(): + """Gets the default CSS screenplay theme that Jouvence uses.""" return _res('html_styles.css') class HtmlDocumentRenderer(BaseDocumentRenderer): + """A document renderer that formats a screenplay into a web page. + """ def __init__(self, standalone=True): + """Creates a new HTML renderer. + + `standalone` + If ``True`` (the default), it will render a complete HTML + page, with CSS styling. If ``False``, it will just produce + the markup for the screenplay itself. The calling + application is responsible for producing the rest of the + HTML page, along with CSS code, to render the screenplay + properly. + """ super().__init__(HtmlTextRenderer()) self.standalone = standalone def get_css(self): + """Gets the default CSS screenplay theme that Jouvence uses. + + This is the same as :func:`~jouvence.html.get_css`. + """ return _res('html_styles.css') def write_header(self, doc, out): @@ -126,6 +147,7 @@ class HtmlTextRenderer(BaseTextRenderer): + """A text renderer for producing HTML markup.""" def __init__(self): self.notes = []
--- a/jouvence/parser.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/parser.py Sun Jan 15 22:41:49 2017 -0800 @@ -645,10 +645,17 @@ class JouvenceParser: + """ Parses a Fountain document and returns a + :class:`~jouvence.document.JouvenceDocument` instance. + """ def __init__(self): pass def parse(self, filein): + """Parses a file or stream. This must either be a Python file object, + or the path to file on disk. Returns a + :class:`~jouvence.document.JouvenceDocument` instance. + """ if isinstance(filein, str): with open(filein, 'r') as fp: return self._doParse(fp) @@ -656,6 +663,9 @@ return self._doParse(fp) def parseString(self, text): + """Parses a string. Returns a + :class:`~jouvence.document.JouvenceDocument` instance. + """ import io with io.StringIO(text) as fp: return self._doParse(fp)
--- a/jouvence/renderer.py Thu Jan 12 09:18:36 2017 -0800 +++ b/jouvence/renderer.py Sun Jan 15 22:41:49 2017 -0800 @@ -6,7 +6,18 @@ class BaseDocumentRenderer: + """The base class for document renderers. + + Document renderers are given a document to transform into whatever + format they're responsible for. + """ def __init__(self, text_renderer=None): + """Initializes the document renderer. + + `text_renderer` + The :class:`~BaseTextRenderer` instance to use for + formatting text. + """ self.force_title_page = False self.text_renderer = text_renderer if not text_renderer: @@ -29,6 +40,13 @@ return self.text_renderer.render_text(text) def render_doc(self, doc, out): + """Renders the given document (``doc``) into the given buffer + (``out``). + + The output buffer must be a file-like object, like the return + value of the ``open()`` built-in function, or an instance of + ``io.StringIO``, among others. + """ self.write_header(doc, out) self.render_title_page(doc.title_values, out) for s in doc.scenes: @@ -113,7 +131,11 @@ class BaseTextRenderer: + """A class responsible for rendering text, including such things as + italics, bold, or underline. + """ def render_text(self, text): + """Processes the given text, and returns the formatted data.""" # Replace bold stuff to catch double asterisks. text = RE_BOLD.sub(self._do_make_bold, text) text = RE_ITALICS.sub(self._do_make_italics, text)