ondim-0.1.0.0
Safe HaskellNone
LanguageGHC2021

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 -> Ondim s [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 monad state, and they can also be organized into more nested Namespaces. See Ondim.State for more information on how to manipulate the state.

The state also store templates, which are essentialy values of type OndimNode t => t 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:

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

Monad

data Ondim s a Source #

Instances

Instances details
MonadIO (Ondim RealWorld) Source # 
Instance details

Defined in Ondim.Internal.Basic

Methods

liftIO :: IO a -> Ondim RealWorld a #

Applicative (Ondim s) Source # 
Instance details

Defined in Ondim.Internal.Basic

Methods

pure :: a -> Ondim s a #

(<*>) :: Ondim s (a -> b) -> Ondim s a -> Ondim s b #

liftA2 :: (a -> b -> c) -> Ondim s a -> Ondim s b -> Ondim s c #

(*>) :: Ondim s a -> Ondim s b -> Ondim s b #

(<*) :: Ondim s a -> Ondim s b -> Ondim s a #

Functor (Ondim s) Source # 
Instance details

Defined in Ondim.Internal.Basic

Methods

fmap :: (a -> b) -> Ondim s a -> Ondim s b #

(<$) :: a -> Ondim s b -> Ondim s a #

Monad (Ondim s) Source # 
Instance details

Defined in Ondim.Internal.Basic

Methods

(>>=) :: Ondim s a -> (a -> Ondim s b) -> Ondim s b #

(>>) :: Ondim s a -> Ondim s b -> Ondim s b #

return :: a -> Ondim s a #

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.

liftST :: ST s a -> Ondim s a Source #

Nodes

class (Typeable t, Expansible t) => OndimNode t Source #

Instances

Instances details
OndimNode Attribute Source # 
Instance details

Defined in Ondim.Internal.Class

OndimNode LByteString Source # 
Instance details

Defined in Ondim.Internal.Class

OndimNode Text Source # 
Instance details

Defined in Ondim.Internal.Class

(OndimNode a, Expansible (t a), Foldable t, Typeable t) => OndimNode (t a) Source # 
Instance details

Defined in Ondim.Internal.Class

Methods

identify :: t a -> Maybe Text Source #

attributes :: t a -> Ondim s [Attribute] Source #

children :: t a -> [t a] Source #

castFrom :: OndimNode a0 => Maybe (a0 -> [t a]) Source #

renderNode :: Maybe (t a -> LByteString) Source #

nodeAsText :: Maybe (t a -> Text) Source #

identify :: OndimNode t => t -> Maybe Text Source #

Returns the name of the node as defined by the OndimNode instance.

ondimCast :: (OndimNode a, OndimNode b) => Maybe (a -> [b]) Source #

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 Expansion s t = t -> Ondim s [t] Source #

An expansion.

type PolyExpansion s = forall a. OndimNode a => Expansion s a Source #

An expansion that is polymorphic on the type.

State transformations

Get specific expansions

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.

Auxiliary

type Attribute = (Text, Text) Source #

Alias for attributes