Safe Haskell | None |
---|---|
Language | GHC2021 |
Ondim
Description
This module exports the main definitions and methods for working with Ondim.
Here, we shall call by a "node" any type that implements OndimNode
, which
means it is compatible with the Ondim template system. Many types can be used as
nodes at once, and in fact in a single format like HTML there are multiple types
that are regarded as nodes (the HTML document, element, node and attribute are
different types implementing the class). In other formats like Pandoc the
necessity of this approach is more evident, since there are not only the Block
and Inline
types but also metadata types and so on.
Each node may have an name, which is simply a Text
string and acessed by the
identify
class method. A node which has an name is meant to be expanded by
the template system, and this is done by applying it to an Expansion
bound to
the same name in the local state.
Another thing specified by the OndimNode
instances is how different node types
are found inside a given node type, and this information is used to recursively
expand the templates in a macro-like fashion. The main sorts of "substructures"
of a node are its children and attributes, which are acessed via the
children
and attributes
methods, repectively. Since those are part of the
class, they can be used for writing expansions that don't depend on the node
type. Those polymorphic expansions are special enough to have a type alias for
them: PolyExpansion
. The nice thing about them is that you can write
templating code only once and expand templates of any format, while still being
able to specify expansions for a given type.
So the main function in this module is probably expandNode
, which when applied
to a node runs the expansion machinery and turns the node into something else.
Expansions are just Haskell functions of type t ->
, and can be
defined inside Haskell code. The expansion's argument is the node whose name
matched the name of the expansion (the "caller"), and the expansion returns a
list of nodes that will replace it in the expansion process. Expansions are
bound to names in the Ondim
s [t]Ondim
monad state, and they can also be organized into
more nested Namespace
s. See Ondim.State for more information on how to
manipulate the state.
The state also store templates, which are essentialy values of type
and are used to store data like text and file templates.
Every template stored in the state is also seen as an expansion, the expansion
that ignores the caller argument and returns the expanded template:OndimNode
t => t
templateToExpansion tpl = const $ expandNode
tpl
This is not the true definition --- the caller node is not actually ignored,
instead it may be acessed from the template via the state in the caller
namespace. Most importantly, templates may be loaded from disk, see the module
Ondim.Loading.
For dealing with exceptions and debug data, see the module Ondim.Debug.
Synopsis
- data Ondim s a
- evalOndimWith :: OndimState s -> Ondim s a -> ST s (Either OndimException a)
- evalOndim :: Ondim s a -> ST s (Either OndimException a)
- liftST :: ST s a -> Ondim s a
- class (Typeable t, Expansible t) => OndimNode t
- identify :: OndimNode t => t -> Maybe Text
- ondimCast :: (OndimNode a, OndimNode b) => Maybe (a -> [b])
- children :: OndimNode t => t -> [t]
- expandChildren :: OndimNode t => Expansion s t
- lookupAttr :: OndimNode t => Text -> t -> Ondim s (Maybe Text)
- attributes :: OndimNode t => t -> Ondim s [Attribute]
- expandNode :: OndimNode t => t -> Ondim s [t]
- expandSubs :: Expansible t => t -> Ondim s t
- type Expansion s t = t -> Ondim s [t]
- type PolyExpansion s = forall a. OndimNode a => Expansion s a
- module Ondim.State
- getExpansion :: OndimNode t => Text -> Ondim s (Either OndimFailure (Expansion s t))
- getTemplate :: OndimNode a => Text -> Ondim s (Either OndimFailure [a])
- getNamespace :: Text -> Ondim s (Either OndimFailure (Namespace s))
- getText :: Text -> Ondim s (Either OndimFailure Text)
- callExpansion :: OndimNode t => Text -> Expansion s t
- callTemplate :: OndimNode t => Text -> Ondim s [t]
- callText :: Text -> Ondim s Text
- renderNode :: OndimNode t => Maybe (t -> LByteString)
- renderNodeOrError :: (HasCallStack, OndimNode a) => a -> Ondim s LByteString
- renderTemplateOrError :: HasCallStack => Text -> Ondim s LByteString
- type Attribute = (Text, Text)
Monad
evalOndimWith :: OndimState s -> Ondim s a -> ST s (Either OndimException a) Source #
Runs the Ondim action with a given initial state.
evalOndim :: Ondim s a -> ST s (Either OndimException a) Source #
Runs the Ondim action with empty initial state.
Nodes
class (Typeable t, Expansible t) => OndimNode t Source #
Instances
OndimNode Attribute Source # | |
OndimNode LByteString Source # | |
Defined in Ondim.Internal.Class Methods identify :: LByteString -> Maybe Text Source # attributes :: LByteString -> Ondim s [Attribute] Source # children :: LByteString -> [LByteString] Source # castFrom :: OndimNode a => Maybe (a -> [LByteString]) Source # renderNode :: Maybe (LByteString -> LByteString) Source # nodeAsText :: Maybe (LByteString -> Text) Source # | |
OndimNode Text Source # | |
Defined in Ondim.Internal.Class | |
(OndimNode a, Expansible (t a), Foldable t, Typeable t) => OndimNode (t a) Source # | |
Defined in Ondim.Internal.Class |
identify :: OndimNode t => t -> Maybe Text Source #
Returns the name of the node as defined by the OndimNode
instance.
Children and attributes
children :: OndimNode t => t -> [t] Source #
Returns the children of the node as defined by the OndimNode
instance.
expandChildren :: OndimNode t => Expansion s t Source #
Returns the children of a node after expanding them.
expandChildren
=expandNodes
.children
lookupAttr :: OndimNode t => Text -> t -> Ondim s (Maybe Text) Source #
Lookup an attribute from a node by name.
attributes :: OndimNode t => t -> Ondim s [Attribute] Source #
Returns a list of attributes of the node as defined by the OndimNode
instance.
Running templates
expandNode :: OndimNode t => t -> Ondim s [t] Source #
This function recursively expands the node and its substructures according to the expansions that are bound in the context.
More precisely, if the node name matches the name of a bound expansion, then
it feeds the node directly into the expansion. Otherwise, it runs
expandSubstructures
on the node, which essentially amounts to running
expandNode
on each substructure.
expandSubs :: Expansible t => t -> Ondim s t Source #
Expand only the substructures of a node.
Data types
type PolyExpansion s = forall a. OndimNode a => Expansion s a Source #
An expansion that is polymorphic on the type.
State transformations
module Ondim.State
Get specific expansions
getExpansion :: OndimNode t => Text -> Ondim s (Either OndimFailure (Expansion s t)) Source #
getTemplate :: OndimNode a => Text -> Ondim s (Either OndimFailure [a]) Source #
getNamespace :: Text -> Ondim s (Either OndimFailure (Namespace s)) Source #
Calling
callExpansion :: OndimNode t => Text -> Expansion s t Source #
Either applies expansion name
, or throws a failure if it does not exist.
callTemplate :: OndimNode t => Text -> Ondim s [t] Source #
Either applies template name
, or throws a failure if it does not exist.
callText :: Text -> Ondim s Text Source #
Either applies text name
, or throws a failure if it does not exist.
Rendering
renderNode :: OndimNode t => Maybe (t -> LByteString) Source #
Converts the node to a LByteString
as defined by the OndimNode
instance.
renderNodeOrError :: (HasCallStack, OndimNode a) => a -> Ondim s LByteString Source #
Render node as bytestring, if possible, or fail.
renderTemplateOrError :: HasCallStack => Text -> Ondim s LByteString Source #
Expand and then render template called name
to bytestring.