{-# LANGUAGE OverloadedRecordDot #-} module Zettel.Render where import Control.Monad as M (when) import Data.Default (def) import qualified Data.Map.Strict as Map import qualified Data.Text as T import Paths_org_zk (getDataFileName) import Text.Pandoc.App (applyFilters) import Text.Pandoc.Builder (HasMeta (..), ToMetaValue (..)) import Text.Pandoc.Class (runIOorExplode) import Text.Pandoc.Definition (Block (..), Inline (..)) import Text.Pandoc.Extensions (Extension (..), disableExtension, enableExtension) import Text.Pandoc.Filter (Environment (..), Filter (..)) import Text.Pandoc.Options (CiteMethod (..), ReaderOptions (..), WriterOptions (..), getDefaultExtensions, multimarkdownExtensions) import Text.Pandoc.Scripting (noEngine) import Text.Pandoc.Templates (WithDefaultPartials (..), compileTemplate) import Text.Pandoc.Walk (query, walk) import Text.Pandoc.Writers (writeMarkdown) import Zettel.Types zettelIdToLink :: ZettelId -> Inline zettelIdToLink ident = Link mempty [Str $ "#" <> unZettelId ident] ("/" <> unZettelId ident, "") renderZettelLinks :: [ZettelId] -> Block renderZettelLinks = BulletList . map (\ident -> [Para [zettelIdToLink ident]]) toInlines :: Text -> [Inline] toInlines t = intersperse Space . map Str $ T.words t renderTitleLinks :: Int -> Text -> [ZettelId] -> [Block] renderTitleLinks level title ids = [Header level mempty (toInlines title), renderZettelLinks ids] newtype MB = MB {unMB :: Bool} deriving (Show, Eq) instance Semigroup MB where MB a <> MB b = MB $ a || b instance Monoid MB where mempty = MB False checkCitation :: Inline -> MB checkCitation Cite {} = MB True checkCitation _ = MB False renderZettel :: ZettelId -> Zettel -> IO Text renderZettel _ zettel = do templateFile <- getDataFileName "data/markdown.template" template <- decodeUtf8 <$> readFileBS templateFile Right templ <- runIOorExplode . runWithDefaultPartials $ compileTemplate "" template let writeOpts = ( def { writerTemplate = Just templ, writerExtensions = multimarkdownExtensions, writerReferenceLinks = True } ) runIOorExplode $ if unMB $ query checkCitation zettel.zettelBody then let pandoc = setMeta "csl" ("/Users/ymherklotz/Dropbox/zk/assets/ieee.csl" :: FilePath) $ setMeta "bibliography" (["/Users/ymherklotz/bibliography/references.bib"] :: [FilePath]) zettel.zettelBody in applyFilters noEngine ( Environment def {readerExtensions = getDefaultExtensions "org"} writeOpts { writerExtensions = disableExtension Ext_citations writeOpts.writerExtensions } ) [CiteprocFilter] ["org"] pandoc >>= writeMarkdown writeOpts else writeMarkdown writeOpts zettel.zettelBody renderZettelFile :: FilePath -> ZettelId -> Zettel -> IO () renderZettelFile dir ident zettel = do t <- renderZettel ident zettel writeFileText (dir <> "/" <> toString (unZettelId ident <> ".md")) t renderZettelGraphFile :: FilePath -> ZettelGraph -> IO () renderZettelGraphFile fp zg = forM_ (Map.assocs (unZettelGraph zg)) $ uncurry (renderZettelFile fp)