The places of the elements: which element can hold which child
The DSL accepts an element in more places than these rules give, because
the macros of the outer entities stay in scope in each nested block. See
"The definitions of the elements" in docs/architecture.md.
Expresso.PlacementTransformer calls slide/1 for each slide, and it refuses
an element in a wrong place. docs/reference/placement.md gives the rules.
A transformer adds children to two elements, and these children are in their
place: the Expresso.Element.Lines of a code element and the
Expresso.Element.TocEntry of a toc. Expresso.Overlay.Check reports a
pause inside an element, so this module accepts a pause in each place.
Summary
Functions
Return the children that an element holds under a key, as a list of modules
Give an error for the first child of an element in a wrong place, at each depth
Give an error for the first element of a slide in a wrong place
Functions
Return the children that an element holds under a key, as a list of modules
iex> Expresso.Element.Columns in Expresso.Placement.children(Expresso.Element.TextBox, :elements)
true
iex> Expresso.Placement.children(Expresso.Element.Callout, :elements) |> Enum.member?(Expresso.Element.Callout)
false
Give an error for the first child of an element in a wrong place, at each depth
Expresso.Element.Chart calls this function for each frame, because the
transform of the chart reads the flows of a frame before
Expresso.PlacementTransformer runs.
iex> alias Expresso.Builder
iex> {:error, message} = Expresso.Placement.element(%Expresso.Element.Frame{flows: [Builder.node("b")]})
iex> message
"a node is inside a frame, and a frame holds flow"
@spec slide(Expresso.Slide.t()) :: :ok | {:error, String.t()}
Give an error for the first element of a slide in a wrong place
iex> alias Expresso.Builder
iex> Expresso.Placement.slide(Builder.slide("s", elements: [Builder.callout(:tip)]))
:ok
iex> slide = Builder.slide("s", elements: [Builder.callout(:tip, elements: [Builder.callout(:note)])])
iex> {:error, message} = Expresso.Placement.slide(slide)
iex> message =~ "a callout is inside a callout"
true