Frontends#

Text in, validated IR out. Two syntaxes, one IR – which is what lets a comic script and a YAML document compile identically without anything downstream knowing there is more than one.

scenet.frontends.yaml_front#

.. py:module:: scenet.frontends.yaml_front

The YAML surface syntax: text in, validated IR out.

This is one frontend among several planned – a comic-script frontend will target the same IR. Keeping parsing separate from the IR is what makes that possible without touching anything downstream.

.. py:function:: parse_relation(text)

module:

scenet.frontends.yaml_front

Parse subject predicate object into a relation.

Written as a sentence rather than a mapping because staging is read far more often than it is written, and alice left_of bob is legible at a glance in a way that a three-key mapping is not.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\~scenet.ir.Relation``

.. py:function:: parse_panel(text, *, source=None)

module:

scenet.frontends.yaml_front

Parse panel source into validated IR.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\~scenet.ir.PanelIR``

.. py:function:: load_panel(path)

module:

scenet.frontends.yaml_front

Read and validate a single-panel document from disk.

type path:
sphinx_autodoc_typehints_type:

\:py\:class\:\~pathlib.Path``

param path:

A *.panel.yaml file.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\~scenet.ir.PanelIR``

returns:

The validated scene graph. No coordinates yet – that is the solver’s job.

raises OSError:

The file cannot be read.

raises PanelSyntaxError:

The document is malformed or invalid. The path is included in the message.

.. py:function:: parse_scene(text, *, source=None)

module:

scenet.frontends.yaml_front

Parse a multi-panel document, resolving over inheritance.

A document with a top-level panels: mapping holds a sequence; anything else is treated as a single panel named “panel”, so the two forms share one entry point and a single-panel file needs no ceremony.

Panel order follows declaration order, which is reading order.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`~scenet.ir.PanelIR`]`

.. py:function:: load_scene(path)

module:

scenet.frontends.yaml_front

Read and validate a multi-panel document from disk.

type path:
sphinx_autodoc_typehints_type:

\:py\:class\:\~pathlib.Path``

param path:

A *.scene.yaml file. A single-panel document also works and comes back as one entry named panel.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`~scenet.ir.PanelIR`]`

returns:

Panel name to scene graph, in declaration order – which is reading order.

raises OSError:

The file cannot be read.

raises PanelSyntaxError:

A panel is malformed or invalid.

raises CompositionError:

An over: chain is unresolvable or cyclic.

scenet.frontends.script_front#

.. py:module:: scenet.frontends.script_front

A frontend for comic script, the format writers already use.

Checked before building this: Fountain has no native panel, caption or SFX support, and there is no standardised comic script format at all. But the informal industry convention is stable across publishers – PANEL 1, a prose description, a character cue in capitals, the dialogue beneath it – so that is what this parses.

The honest limitation. A prose description like “Alice and Bob face each other on a rainy street corner” cannot be compiled. Turning that into staging needs natural language understanding, and guessing would produce panels that are confidently wrong – far worse than refusing. So descriptions are preserved but not interpreted, and anything the compiler must know is declared explicitly: cast and staging in a front-matter block, per-panel settings as @ directives.

   ---
   cast:
     ALICE: {reference: alice, at: left_third}
     BOB:   {reference: bob,   at: right_third}
   staging:
     - ALICE left_of BOB
   ---

   PANEL 1
   @shot: full_shot
   Alice and Bob face each other on a rainy street corner.

   ALICE
   You forgot your umbrella!

   BOB (whisper)
   I know.

.. py:function:: parse_script(text, *, source=None)

module:

scenet.frontends.script_front

Parse comic script into one validated panel per PANEL heading.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`~scenet.ir.PanelIR`]`

.. py:function:: load_script(path)

module:

scenet.frontends.script_front

Read and validate a comic script from disk.

type path:
sphinx_autodoc_typehints_type:

\:py\:class\:\~pathlib.Path``

param path:

A *.script file in the comic-script format writers already use.

rtype:
sphinx_autodoc_typehints_type:

\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`~scenet.ir.PanelIR`]`

returns:

Panel name to scene graph, in the order the panels appear.

raises OSError:

The file cannot be read.

raises ScriptSyntaxError:

The script cannot be parsed – dialogue before the first PANEL heading, or no PANEL headings at all.