JSON Schema Reference¶
FountainDocument.to_dict() and FountainDocument.to_json() share one documented shape.
This page pins that shape as a versioned contract: the top-level document, the element dictionary, the formatting-span dictionary, and the nested dual-dialogue metadata.
For task-focused examples, see Export a Screenplay to JSON.
Top-Level Shape¶
to_dict() returns a dictionary with three keys:
>>> from fountain.document import FountainDocument
>>> FountainDocument([]).to_dict().keys()
dict_keys(['schema_version', 'metadata', 'elements'])
schema_versionAn integer identifying the shape of this document. The current value is
1, exposed as the module constantfountain.document.JSON_SCHEMA_VERSION. A future release that changes the shape below in a breaking way bumps this number.metadataA dictionary of title page fields (
title,author,draft_date, and so on), the same dictionary asdocument.metadata.elementsA list of element dictionaries, one per
FountainElementindocument.elements, in document order.
Element Shape¶
Every element in the document, whether top-level or nested inside another element’s metadata, serializes to the same five keys:
>>> from fountain.parser import FountainParser
>>> document = FountainParser().parse("INT. KITCHEN - DAY\n\nJOHN\nHello.")
>>> document.to_dict()["elements"][0].keys()
dict_keys(['type', 'text', 'formatting', 'line_number', 'metadata'])
typeThe element’s
ElementTypevalue as a string, for example"scene_heading"or"dialogue".textThe element’s clean text content, with Fountain markup removed.
formattingA list of formatting-span dictionaries; see Formatting-Span Shape below.
line_numberThe 1-based source line number the element started on.
metadataA dictionary of element-specific attributes. Most elements carry an empty or small metadata dictionary (
scene_number,extension,forced, and similar flags). DUAL_DIALOGUE elements nest other elements here; see Dual-Dialogue Metadata below.
Formatting-Span Shape¶
Each entry in an element’s formatting list describes one inline emphasis span:
>>> from fountain.parser import FountainParser
>>> document = FountainParser().parse("JOHN\nThis is **bold** text.")
>>> document.to_dict()["elements"][1]["formatting"][0]
{'start': 8, 'end': 12, 'format_type': 'bold'}
startThe zero-based character offset where the span begins, inclusive.
endThe zero-based character offset where the span ends, exclusive.
format_typeOne of
"bold","italic", or"underline".
Dual-Dialogue Metadata¶
A DUAL_DIALOGUE element’s metadata nests the two character/dialogue blocks it pairs, using the same element shape as everywhere else:
>>> from fountain.parser import FountainParser
>>> document = FountainParser().parse("BRICK\nHi.\n\nSTEEL^\nHello.")
>>> dual = [element for element in document.to_dict()["elements"] if element["type"] == "dual_dialogue"][0]
>>> sorted(dual["metadata"].keys())
['left_character', 'left_dialogue', 'right_character', 'right_dialogue']
>>> dual["metadata"]["left_character"]["type"]
'character'
>>> dual["metadata"]["left_character"]["text"]
'BRICK'
>>> isinstance(dual["metadata"]["left_dialogue"], list)
True
>>> dual["metadata"]["left_dialogue"][0]["type"]
'dialogue'
left_characterandright_characterElement dictionaries for the two CHARACTER cues, each with the same five keys documented in Element Shape.
left_dialogueandright_dialogueLists of element dictionaries for the DIALOGUE (and PARENTHETICAL) elements spoken under each character.
Because nested elements share the exact shape of top-level elements, code that walks document.to_dict()["elements"] can recurse into metadata["left_character"] or metadata["left_dialogue"] without a special case.