neuron-0.6.0.0: src/lib/Neuron/Zettelkasten/Zettel/Parser.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Neuron.Zettelkasten.Zettel.Parser where
import Control.Monad.Writer
import Data.Some
import qualified Data.Text as T
import Neuron.Reader.Type
import Neuron.Zettelkasten.ID
import Neuron.Zettelkasten.Query.Error
import Neuron.Zettelkasten.Query.Parser (queryFromURILink)
import Neuron.Zettelkasten.Zettel
import qualified Neuron.Zettelkasten.Zettel.Meta as Meta
import Reflex.Dom.Pandoc.URILink (queryURILinks)
import Relude
import Text.Pandoc.Definition (Pandoc)
import Text.Pandoc.Util
parseZettel ::
ZettelFormat ->
ZettelReader ->
FilePath ->
ZettelID ->
Text ->
ZettelC
parseZettel format zreader fn zid s = do
case zreader fn s of
Left parseErr ->
Left $ Zettel zid format fn "Unknown" False [] Nothing [] parseErr s
Right (meta, doc) ->
let (title, titleInBody) = case Meta.title =<< meta of
Just tit -> (tit, False)
Nothing -> fromMaybe ("Untitled", False) $ do
((,True) . plainify . snd <$> getH1 doc)
<|> ((,False) . takeInitial . plainify <$> getFirstParagraphText doc)
tags = fromMaybe [] $ Meta.tags =<< meta
day = case zid of
-- We ignore the "data" meta field on legacy Date IDs, which encode the
-- creation date in the ID.
ZettelDateID v _ -> Just v
ZettelCustomID _ -> Meta.date =<< meta
(queries, errors) = runWriter $ extractQueries doc
in Right $ Zettel zid format fn title titleInBody tags day queries errors doc
where
-- Extract all (valid) queries from the Pandoc document
extractQueries :: MonadWriter [QueryParseError] m => Pandoc -> m [Some ZettelQuery]
extractQueries doc =
fmap catMaybes $ forM (queryURILinks doc) $ \ul ->
case queryFromURILink ul of
Left e -> do
tell [e]
pure Nothing
Right v ->
pure v
takeInitial =
(<> " ...") . T.take 18
-- | Like `parseZettel` but operates on multiple files.
parseZettels ::
[((ZettelFormat, ZettelReader), [(ZettelID, FilePath, Text)])] ->
[ZettelC]
parseZettels filesPerFormat =
flip concatMap filesPerFormat $ \((format, zreader), files) ->
flip fmap files $ \(zid, path, s) ->
parseZettel format zreader path zid s