module Emanote.View.TagIndex (renderTagIndex) where

import Data.List qualified as List
import Data.List.NonEmpty qualified as NE
import Data.Map.Strict qualified as Map
import Data.Map.Syntax ((##))
import Data.Tree (Forest, Tree)
import Data.Tree qualified as Tree
import Emanote.Model (Model)
import Emanote.Model qualified as M
import Emanote.Model.Note qualified as MN
import Emanote.Pandoc.Markdown.Syntax.HashTag qualified as HT
import Emanote.Pandoc.Renderer.Query qualified as PF
import Emanote.Route.SiteRoute.Class qualified as SR
import Emanote.View.Common
  ( TemplateRenderCtx (withInlineCtx),
    commonSplices,
    defaultRouteMeta,
    mkTemplateRenderCtx,
    renderModelTemplate,
  )
import Heist.Extra.Splices.List qualified as Splices
import Heist.Extra.Splices.Pandoc.Ctx (emptyRenderCtx)
import Heist.Interpreted qualified as HI
import Relude

-- An index view into the notebook indexed by the given tag path.
data TagIndex = TagIndex
  { -- | The tag path under which this index is creatd
    TagIndex -> [TagNode]
tagIndexPath :: [HT.TagNode],
    -- | User descriptive title of this index
    TagIndex -> Text
tagIndexTitle :: Text,
    -- | All notes tagged precisely with this tag path
    TagIndex -> [Note]
tagIndexNotes :: [MN.Note],
    -- | Tags immediately under this tag path.
    --
    -- If the tag path being index is "foo/bar", this will contain "foo/bar/qux".
    TagIndex -> [(NonEmpty TagNode, [Note])]
tagIndexChildren :: [(NonEmpty HT.TagNode, [MN.Note])]
  }
  deriving stock (TagIndex -> TagIndex -> Bool
(TagIndex -> TagIndex -> Bool)
-> (TagIndex -> TagIndex -> Bool) -> Eq TagIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TagIndex -> TagIndex -> Bool
$c/= :: TagIndex -> TagIndex -> Bool
== :: TagIndex -> TagIndex -> Bool
$c== :: TagIndex -> TagIndex -> Bool
Eq)

mkTagIndex :: Model -> [HT.TagNode] -> TagIndex
mkTagIndex :: Model -> [TagNode] -> TagIndex
mkTagIndex Model
model [TagNode]
tagPath' =
  let mTagPath :: Maybe (NonEmpty TagNode)
mTagPath = [TagNode] -> Maybe (NonEmpty TagNode)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [TagNode]
tagPath'
      tagMap :: Map Tag [Note]
tagMap = [(Tag, [Note])] -> Map Tag [Note]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Tag, [Note])] -> Map Tag [Note])
-> [(Tag, [Note])] -> Map Tag [Note]
forall a b. (a -> b) -> a -> b
$ Model -> [(Tag, [Note])]
forall (f :: Type -> Type). ModelT f -> [(Tag, [Note])]
M.modelTags Model
model
      tagForest :: Forest (TagNode, [Note])
tagForest = Map Tag [Note] -> Forest (TagNode, [Note])
forall a. (Eq a, Default a) => Map Tag a -> Forest (TagNode, a)
HT.tagTree Map Tag [Note]
tagMap
      childNodes :: [TagNode]
childNodes =
        [TagNode]
-> (NonEmpty TagNode -> [TagNode])
-> Maybe (NonEmpty TagNode)
-> [TagNode]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
          ((TagNode, [Note]) -> TagNode
forall a b. (a, b) -> a
fst ((TagNode, [Note]) -> TagNode)
-> (Tree (TagNode, [Note]) -> (TagNode, [Note]))
-> Tree (TagNode, [Note])
-> TagNode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree (TagNode, [Note]) -> (TagNode, [Note])
forall a. Tree a -> a
Tree.rootLabel (Tree (TagNode, [Note]) -> TagNode)
-> Forest (TagNode, [Note]) -> [TagNode]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Forest (TagNode, [Note])
tagForest)
          ((Tree (TagNode, [Note]) -> TagNode)
-> Forest (TagNode, [Note]) -> [TagNode]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((TagNode, [Note]) -> TagNode
forall a b. (a, b) -> a
fst ((TagNode, [Note]) -> TagNode)
-> (Tree (TagNode, [Note]) -> (TagNode, [Note]))
-> Tree (TagNode, [Note])
-> TagNode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree (TagNode, [Note]) -> (TagNode, [Note])
forall a. Tree a -> a
Tree.rootLabel) (Forest (TagNode, [Note]) -> [TagNode])
-> (NonEmpty TagNode -> Forest (TagNode, [Note]))
-> NonEmpty TagNode
-> [TagNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree (TagNode, [Note]) -> Forest (TagNode, [Note])
forall a. Tree a -> [Tree a]
Tree.subForest (Tree (TagNode, [Note]) -> Forest (TagNode, [Note]))
-> (NonEmpty TagNode -> Tree (TagNode, [Note]))
-> NonEmpty TagNode
-> Forest (TagNode, [Note])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty TagNode
 -> Forest (TagNode, [Note]) -> Tree (TagNode, [Note]))
-> Forest (TagNode, [Note])
-> NonEmpty TagNode
-> Tree (TagNode, [Note])
forall a b c. (a -> b -> c) -> b -> a -> c
flip NonEmpty TagNode
-> Forest (TagNode, [Note]) -> Tree (TagNode, [Note])
forall k a.
(Show k, Eq k) =>
NonEmpty k -> Forest (k, a) -> Tree (k, a)
lookupForestMust Forest (TagNode, [Note])
tagForest)
          Maybe (NonEmpty TagNode)
mTagPath
      childTags :: [(NonEmpty TagNode, [Note])]
childTags =
        [TagNode]
childNodes [TagNode]
-> (TagNode -> (NonEmpty TagNode, [Note]))
-> [(NonEmpty TagNode, [Note])]
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> \TagNode
childNode ->
          let t :: NonEmpty TagNode
t = NonEmpty TagNode -> NonEmpty TagNode
forall a. NonEmpty a -> NonEmpty a
NE.reverse (NonEmpty TagNode -> NonEmpty TagNode)
-> NonEmpty TagNode -> NonEmpty TagNode
forall a b. (a -> b) -> a -> b
$ TagNode
childNode TagNode -> [TagNode] -> NonEmpty TagNode
forall a. a -> [a] -> NonEmpty a
:| [TagNode] -> [TagNode]
forall a. [a] -> [a]
reverse [TagNode]
tagPath'
           in (NonEmpty TagNode
t, Maybe [Note] -> [Note]
forall m. Monoid m => Maybe m -> m
maybeToMonoid (Maybe [Note] -> [Note]) -> Maybe [Note] -> [Note]
forall a b. (a -> b) -> a -> b
$ Tag -> Map Tag [Note] -> Maybe [Note]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (NonEmpty TagNode -> Tag
HT.constructTag NonEmpty TagNode
t) Map Tag [Note]
tagMap)
   in case Maybe (NonEmpty TagNode)
mTagPath of
        Maybe (NonEmpty TagNode)
Nothing ->
          -- The root index displays all top-level tags (no notes)
          [TagNode]
-> Text -> [Note] -> [(NonEmpty TagNode, [Note])] -> TagIndex
TagIndex [] Text
"Tag Index" [] [(NonEmpty TagNode, [Note])]
childTags
        Just NonEmpty TagNode
tagPath ->
          let notes :: [Note]
notes =
                (TagNode, [Note]) -> [Note]
forall a b. (a, b) -> b
snd ((TagNode, [Note]) -> [Note])
-> (Tree (TagNode, [Note]) -> (TagNode, [Note]))
-> Tree (TagNode, [Note])
-> [Note]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree (TagNode, [Note]) -> (TagNode, [Note])
forall a. Tree a -> a
Tree.rootLabel (Tree (TagNode, [Note]) -> [Note])
-> Tree (TagNode, [Note]) -> [Note]
forall a b. (a -> b) -> a -> b
$ NonEmpty TagNode
-> Forest (TagNode, [Note]) -> Tree (TagNode, [Note])
forall k a.
(Show k, Eq k) =>
NonEmpty k -> Forest (k, a) -> Tree (k, a)
lookupForestMust NonEmpty TagNode
tagPath Forest (TagNode, [Note])
tagForest
              viewTitle :: Text
viewTitle = Text
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> NonEmpty TagNode -> Text
tagNodesText NonEmpty TagNode
tagPath Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" - Tag Index"
           in [TagNode]
-> Text -> [Note] -> [(NonEmpty TagNode, [Note])] -> TagIndex
TagIndex (NonEmpty TagNode -> [TagNode]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList NonEmpty TagNode
tagPath) Text
viewTitle [Note]
notes [(NonEmpty TagNode, [Note])]
childTags
  where
    lookupForestMust :: (Show k, Eq k) => NonEmpty k -> Forest (k, a) -> Tree (k, a)
    lookupForestMust :: forall k a.
(Show k, Eq k) =>
NonEmpty k -> Forest (k, a) -> Tree (k, a)
lookupForestMust NonEmpty k
path =
      Tree (k, a) -> Maybe (Tree (k, a)) -> Tree (k, a)
forall a. a -> Maybe a -> a
fromMaybe (Text -> Tree (k, a)
forall a t. (HasCallStack, IsText t) => t -> a
error (Text -> Tree (k, a)) -> Text -> Tree (k, a)
forall a b. (a -> b) -> a -> b
$ Text
"Tag not found in forest: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> NonEmpty k -> Text
forall b a. (Show a, IsString b) => a -> b
show NonEmpty k
path)
        (Maybe (Tree (k, a)) -> Tree (k, a))
-> (Forest (k, a) -> Maybe (Tree (k, a)))
-> Forest (k, a)
-> Tree (k, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
forall k a.
Eq k =>
NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
lookupForest NonEmpty k
path
    lookupForest :: Eq k => NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
    lookupForest :: forall k a.
Eq k =>
NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
lookupForest (k
k :| [k]
ks') Forest (k, a)
trees =
      case [k] -> Maybe (NonEmpty k)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [k]
ks' of
        Maybe (NonEmpty k)
Nothing ->
          (Tree (k, a) -> Bool) -> Forest (k, a) -> Maybe (Tree (k, a))
forall (t :: Type -> Type) a.
Foldable t =>
(a -> Bool) -> t a -> Maybe a
List.find (\(Tree.Node (k, a)
lbl Forest (k, a)
_) -> (k, a) -> k
forall a b. (a, b) -> a
fst (k, a)
lbl k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
k) Forest (k, a)
trees
        Just NonEmpty k
ks -> do
          Forest (k, a)
subForest <- Tree (k, a) -> Forest (k, a)
forall a. Tree a -> [Tree a]
Tree.subForest (Tree (k, a) -> Forest (k, a))
-> Maybe (Tree (k, a)) -> Maybe (Forest (k, a))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Tree (k, a) -> Bool) -> Forest (k, a) -> Maybe (Tree (k, a))
forall (t :: Type -> Type) a.
Foldable t =>
(a -> Bool) -> t a -> Maybe a
List.find (\(Tree.Node (k, a)
lbl Forest (k, a)
_) -> (k, a) -> k
forall a b. (a, b) -> a
fst (k, a)
lbl k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
k) Forest (k, a)
trees
          NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
forall k a.
Eq k =>
NonEmpty k -> Forest (k, a) -> Maybe (Tree (k, a))
lookupForest NonEmpty k
ks Forest (k, a)
subForest

renderTagIndex :: Model -> [HT.TagNode] -> LByteString
renderTagIndex :: Model -> [TagNode] -> LByteString
renderTagIndex Model
model [TagNode]
tagPath = do
  let (LMLRoute
r, Value
meta) = Model -> (LMLRoute, Value)
defaultRouteMeta Model
model
      tCtx :: TemplateRenderCtx @(Type -> Type) Identity
tCtx = Model
-> LMLRoute -> Value -> TemplateRenderCtx @(Type -> Type) Identity
mkTemplateRenderCtx Model
model LMLRoute
r Value
meta
      tagIdx :: TagIndex
tagIdx = Model -> [TagNode] -> TagIndex
mkTagIndex Model
model [TagNode]
tagPath
  Model -> TemplateName -> Splices (Splice Identity) -> LByteString
renderModelTemplate Model
model TemplateName
"templates/special/tagindex" (Splices (Splice Identity) -> LByteString)
-> Splices (Splice Identity) -> LByteString
forall a b. (a -> b) -> a -> b
$ do
    HasCallStack =>
((RenderCtx -> Splice Identity) -> Splice Identity)
-> Model -> Value -> Title -> Splices (Splice Identity)
((RenderCtx -> Splice Identity) -> Splice Identity)
-> Model -> Value -> Title -> Splices (Splice Identity)
commonSplices ((RenderCtx -> Splice Identity) -> RenderCtx -> Splice Identity
forall a b. (a -> b) -> a -> b
$ RenderCtx
emptyRenderCtx) Model
model Value
meta (Title -> Splices (Splice Identity))
-> Title -> Splices (Splice Identity)
forall a b. (a -> b) -> a -> b
$ String -> Title
forall a. IsString a => String -> a
fromString (String -> Title) -> (Text -> String) -> Text -> Title
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. ToString a => a -> String
toString (Text -> Title) -> Text -> Title
forall a b. (a -> b) -> a -> b
$ TagIndex -> Text
tagIndexTitle TagIndex
tagIdx
    Text
"ema:tag:title" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (Text
-> (NonEmpty TagNode -> Text) -> Maybe (NonEmpty TagNode) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"/" (TagNode -> Text
HT.unTagNode (TagNode -> Text)
-> (NonEmpty TagNode -> TagNode) -> NonEmpty TagNode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TagNode -> TagNode
forall (f :: Type -> Type) a. IsNonEmpty f a a "last" => f a -> a
last) (Maybe (NonEmpty TagNode) -> Text)
-> Maybe (NonEmpty TagNode) -> Text
forall a b. (a -> b) -> a -> b
$ [TagNode] -> Maybe (NonEmpty TagNode)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [TagNode]
tagPath)
    Text
"ema:tag:url" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (HasCallStack => Model -> SiteRoute -> Text
Model -> SiteRoute -> Text
SR.siteRouteUrl Model
model (SiteRoute -> Text) -> SiteRoute -> Text
forall a b. (a -> b) -> a -> b
$ [TagNode] -> SiteRoute
SR.tagIndexRoute [TagNode]
tagPath)
    let parents :: [[TagNode]]
parents = [[TagNode]]
-> (NonEmpty TagNode -> [[TagNode]])
-> Maybe (NonEmpty TagNode)
-> [[TagNode]]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ([TagNode] -> [[TagNode]]
forall a. [a] -> [[a]]
inits ([TagNode] -> [[TagNode]])
-> (NonEmpty TagNode -> [TagNode])
-> NonEmpty TagNode
-> [[TagNode]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TagNode -> [TagNode]
forall (f :: Type -> Type) a.
IsNonEmpty f a [a] "init" =>
f a -> [a]
init) (Maybe (NonEmpty TagNode) -> [[TagNode]])
-> Maybe (NonEmpty TagNode) -> [[TagNode]]
forall a b. (a -> b) -> a -> b
$ [TagNode] -> Maybe (NonEmpty TagNode)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty (TagIndex -> [TagNode]
tagIndexPath TagIndex
tagIdx)
    Text
"ema:tagcrumbs" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
##
      [[TagNode]]
-> Text
-> ([TagNode] -> Splices (Splice Identity))
-> Splice Identity
forall a.
[a] -> Text -> (a -> Splices (Splice Identity)) -> Splice Identity
Splices.listSplice [[TagNode]]
parents Text
"ema:each-crumb" (([TagNode] -> Splices (Splice Identity)) -> Splice Identity)
-> ([TagNode] -> Splices (Splice Identity)) -> Splice Identity
forall a b. (a -> b) -> a -> b
$
        \[TagNode]
crumb -> do
          let crumbTitle :: Text
crumbTitle = Text
-> (NonEmpty TagNode -> Text) -> Maybe (NonEmpty TagNode) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"/" (TagNode -> Text
HT.unTagNode (TagNode -> Text)
-> (NonEmpty TagNode -> TagNode) -> NonEmpty TagNode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TagNode -> TagNode
forall (f :: Type -> Type) a. IsNonEmpty f a a "last" => f a -> a
last) (Maybe (NonEmpty TagNode) -> Text)
-> ([TagNode] -> Maybe (NonEmpty TagNode)) -> [TagNode] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TagNode] -> Maybe (NonEmpty TagNode)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([TagNode] -> Text) -> [TagNode] -> Text
forall a b. (a -> b) -> a -> b
$ [TagNode]
crumb
              crumbUrl :: Text
crumbUrl = HasCallStack => Model -> SiteRoute -> Text
Model -> SiteRoute -> Text
SR.siteRouteUrl Model
model (SiteRoute -> Text) -> SiteRoute -> Text
forall a b. (a -> b) -> a -> b
$ [TagNode] -> SiteRoute
SR.tagIndexRoute [TagNode]
crumb
          Text
"ema:tagcrumb:title" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice Text
crumbTitle
          Text
"ema:tagcrumb:url" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice Text
crumbUrl
    Text
"ema:childTags" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
##
      [(NonEmpty TagNode, [Note])]
-> Text
-> ((NonEmpty TagNode, [Note]) -> Splices (Splice Identity))
-> Splice Identity
forall a.
[a] -> Text -> (a -> Splices (Splice Identity)) -> Splice Identity
Splices.listSplice (TagIndex -> [(NonEmpty TagNode, [Note])]
tagIndexChildren TagIndex
tagIdx) Text
"ema:each-childTag" (((NonEmpty TagNode, [Note]) -> Splices (Splice Identity))
 -> Splice Identity)
-> ((NonEmpty TagNode, [Note]) -> Splices (Splice Identity))
-> Splice Identity
forall a b. (a -> b) -> a -> b
$
        \(NonEmpty TagNode, [Note])
childTag -> do
          let childIndex :: TagIndex
childIndex = Model -> [TagNode] -> TagIndex
mkTagIndex Model
model (NonEmpty TagNode -> [TagNode]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList (NonEmpty TagNode -> [TagNode])
-> ((NonEmpty TagNode, [Note]) -> NonEmpty TagNode)
-> (NonEmpty TagNode, [Note])
-> [TagNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty TagNode, [Note]) -> NonEmpty TagNode
forall a b. (a, b) -> a
fst ((NonEmpty TagNode, [Note]) -> [TagNode])
-> (NonEmpty TagNode, [Note]) -> [TagNode]
forall a b. (a -> b) -> a -> b
$ (NonEmpty TagNode, [Note])
childTag)
          Text
"ema:childTag:title" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (NonEmpty TagNode -> Text
tagNodesText (NonEmpty TagNode -> Text) -> NonEmpty TagNode -> Text
forall a b. (a -> b) -> a -> b
$ (NonEmpty TagNode, [Note]) -> NonEmpty TagNode
forall a b. (a, b) -> a
fst (NonEmpty TagNode, [Note])
childTag)
          Text
"ema:childTag:url" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (HasCallStack => Model -> SiteRoute -> Text
Model -> SiteRoute -> Text
SR.siteRouteUrl Model
model (SiteRoute -> Text) -> SiteRoute -> Text
forall a b. (a -> b) -> a -> b
$ [TagNode] -> SiteRoute
SR.tagIndexRoute (NonEmpty TagNode -> [TagNode]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList (NonEmpty TagNode -> [TagNode]) -> NonEmpty TagNode -> [TagNode]
forall a b. (a -> b) -> a -> b
$ (NonEmpty TagNode, [Note]) -> NonEmpty TagNode
forall a b. (a, b) -> a
fst (NonEmpty TagNode, [Note])
childTag))
          Text
"ema:childTag:count-note" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (Int -> Text
forall b a. (Show a, IsString b) => a -> b
show ([Note] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length ([Note] -> Int) -> [Note] -> Int
forall a b. (a -> b) -> a -> b
$ (NonEmpty TagNode, [Note]) -> [Note]
forall a b. (a, b) -> b
snd (NonEmpty TagNode, [Note])
childTag))
          Text
"ema:childTag:count-tag" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
## Text -> Splice Identity
forall (m :: Type -> Type) (n :: Type -> Type).
Monad m =>
Text -> HeistT n m Template
HI.textSplice (Int -> Text
forall b a. (Show a, IsString b) => a -> b
show ([(NonEmpty TagNode, [Note])] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length ([(NonEmpty TagNode, [Note])] -> Int)
-> [(NonEmpty TagNode, [Note])] -> Int
forall a b. (a -> b) -> a -> b
$ TagIndex -> [(NonEmpty TagNode, [Note])]
tagIndexChildren TagIndex
childIndex))
    Text
"ema:notes" Text -> Splice Identity -> Splices (Splice Identity)
forall k v. k -> v -> MapSyntax k v
##
      [Note]
-> Text -> (Note -> Splices (Splice Identity)) -> Splice Identity
forall a.
[a] -> Text -> (a -> Splices (Splice Identity)) -> Splice Identity
Splices.listSplice (TagIndex -> [Note]
tagIndexNotes TagIndex
tagIdx) Text
"ema:each-note" ((Note -> Splices (Splice Identity)) -> Splice Identity)
-> (Note -> Splices (Splice Identity)) -> Splice Identity
forall a b. (a -> b) -> a -> b
$
        \Note
note ->
          ((RenderCtx -> Splice Identity) -> Splice Identity)
-> Model -> Note -> Splices (Splice Identity)
PF.noteSpliceMap (TemplateRenderCtx @(Type -> Type) Identity
-> (RenderCtx -> Splice Identity) -> Splice Identity
forall {k} (n :: k).
TemplateRenderCtx @k n
-> (RenderCtx -> Splice Identity) -> Splice Identity
withInlineCtx TemplateRenderCtx @(Type -> Type) Identity
tCtx) Model
model Note
note

tagNodesText :: NonEmpty HT.TagNode -> Text
tagNodesText :: NonEmpty TagNode -> Text
tagNodesText =
  Tag -> Text
HT.unTag (Tag -> Text)
-> (NonEmpty TagNode -> Tag) -> NonEmpty TagNode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TagNode -> Tag
HT.constructTag