emanote-1.2.0.0: src/Emanote/Pandoc/Renderer/Embed.hs
module Emanote.Pandoc.Renderer.Embed where
import Commonmark.Extensions.WikiLink qualified as WL
import Data.Map.Syntax ((##))
import Emanote.Model (Model)
import Emanote.Model.Link.Rel qualified as Rel
import Emanote.Model.Link.Resolve qualified as Resolve
import Emanote.Model.Note qualified as MN
import Emanote.Model.StaticFile (CodeLanguage (..), StaticFileInfo (..), staticFileInfoTemplateName)
import Emanote.Model.StaticFile qualified as SF
import Emanote.Model.Title qualified as Tit
import Emanote.Pandoc.Link qualified as Link
import Emanote.Pandoc.Renderer (PandocBlockRenderer, PandocInlineRenderer)
import Emanote.Pandoc.Renderer.Url qualified as RenderedUrl
import Emanote.Route.ModelRoute qualified as R
import Emanote.Route.R qualified as R
import Emanote.Route.SiteRoute qualified as SF
import Emanote.Route.SiteRoute qualified as SR
import Heist qualified as H
import Heist.Extra qualified as HE
import Heist.Extra.Splices.Pandoc (pandocSplice)
import Heist.Extra.Splices.Pandoc qualified as HP
import Heist.Interpreted qualified as HI
import Optics.Operators ((^.))
import Relude
import Text.Pandoc.Definition qualified as B
embedBlockWikiLinkResolvingSplice :: PandocBlockRenderer Model R.LMLRoute
embedBlockWikiLinkResolvingSplice model _nf ctx noteRoute node = do
B.Para [inl] <- pure node
(inlRef, (_, _, otherAttrs), is, (url, tit)) <- Link.parseInlineRef inl
guard $ inlRef == Link.InlineLink
let parentR = R.withLmlRoute R.routeParent noteRoute
-- TODO: Use anchor to embed a section?
(Rel.URTWikiLink (WL.WikiLinkEmbed, wl), _mAnchor) <-
Rel.parseUnresolvedRelTarget parentR (otherAttrs <> one ("title", tit)) url
let rRel = Resolve.resolveWikiLinkMustExist model wl
RenderedUrl.renderSomeInlineRefWith Resolve.resourceSiteRoute (is, (url, tit)) rRel model ctx inl $ \case
Left (R.LMLView_Html, r) -> embedResourceRoute model ctx r
Right sf
| isJust (SF._staticFileInfo sf) ->
embedStaticFileRoute model (toText $ SF._staticFilePath sf) sf
_ -> Nothing
embedBlockRegularLinkResolvingSplice :: PandocBlockRenderer Model R.LMLRoute
embedBlockRegularLinkResolvingSplice model _nf ctx noteRoute node = do
B.Para [inl] <- pure node
(inlRef, (_, _, otherAttrs), is, (url, tit)) <- Link.parseInlineRef inl
guard $ inlRef == Link.InlineImage
let parentR = R.withLmlRoute R.routeParent noteRoute
(Rel.URTResource mr, _mAnchor) <-
Rel.parseUnresolvedRelTarget parentR (otherAttrs <> one ("title", tit)) url
let rRel = Resolve.resolveModelRoute model mr
RenderedUrl.renderSomeInlineRefWith Resolve.resourceSiteRoute (is, (url, tit)) rRel model ctx inl $
either (const Nothing) (embedStaticFileRoute model $ WL.plainify is)
embedInlineWikiLinkResolvingSplice :: PandocInlineRenderer Model R.LMLRoute
embedInlineWikiLinkResolvingSplice model _nf ctx noteRoute inl = do
(inlRef, (_, _, otherAttrs), is, (url, tit)) <- Link.parseInlineRef inl
guard $ inlRef == Link.InlineLink
let parentR = R.withLmlRoute R.routeParent noteRoute
(Rel.URTWikiLink (WL.WikiLinkEmbed, wl), _mAnchor) <- Rel.parseUnresolvedRelTarget parentR (otherAttrs <> one ("title", tit)) url
let rRel = Resolve.resolveWikiLinkMustExist model wl
RenderedUrl.renderSomeInlineRefWith Resolve.resourceSiteRoute (is, (url, tit)) rRel model ctx inl $
either (const Nothing) (embedStaticFileRoute model $ show wl)
runEmbedTemplate :: ByteString -> H.Splices (HI.Splice Identity) -> HI.Splice Identity
runEmbedTemplate name splices = do
tpl <- HE.lookupHtmlTemplateMust $ "/templates/filters/embed-" <> name
HE.runCustomTemplate tpl splices
embedResourceRoute :: Model -> HP.RenderCtx -> MN.Note -> Maybe (HI.Splice Identity)
embedResourceRoute model ctx note = do
pure . runEmbedTemplate "note" $ do
"ema:note:title" ## Tit.titleSplice ctx id (MN._noteTitle note)
"ema:note:url" ## HI.textSplice (SR.siteRouteUrl model $ SR.lmlSiteRoute (R.LMLView_Html, note ^. MN.noteRoute))
"ema:note:pandoc" ##
pandocSplice ctx (note ^. MN.noteDoc)
embedStaticFileRoute :: Model -> Text -> SF.StaticFile -> Maybe (HI.Splice Identity)
embedStaticFileRoute model altText staticFile = do
let url = SF.siteRouteUrl model $ SF.staticFileSiteRoute staticFile
staticFileInfo <- SF._staticFileInfo staticFile
pure . runEmbedTemplate (staticFileInfoTemplateName staticFileInfo) $ do
case staticFileInfo of
StaticFileInfoImage -> do
"ema:url" ## HI.textSplice url
"ema:alt" ## HI.textSplice altText
StaticFileInfoVideo ->
"ema:url" ## HI.textSplice url
StaticFileInfoAudio ->
"ema:url" ## HI.textSplice url
StaticFileInfoPDF ->
"ema:url" ## HI.textSplice url
StaticFileInfoCode (CodeLanguage language) content -> do
"ema:code:content" ## HI.textSplice content
"ema:code:language" ## HI.textSplice language
"ema:alt" ## HI.textSplice altText