From 28df3d00a6f3ae1889c25bd960e5feccde9a3d78 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar Date: Thu, 30 Apr 2020 10:41:00 -0400 Subject: [PATCH] Support for "data" meta field Ref #151 --- guide/2011505.md | 21 ++++++++++++++++++++- src/Neuron/Zettelkasten/ID.hs | 7 ------- src/Neuron/Zettelkasten/Query/View.hs | 2 +- src/Neuron/Zettelkasten/Zettel.hs | 12 ++++++++++-- src/Neuron/Zettelkasten/Zettel/Meta.hs | 5 ++++- test/Neuron/Zettelkasten/ZettelSpec.hs | 12 +++++++----- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/guide/2011505.md b/guide/2011505.md index 78bb5c26e..4cc7cd452 100644 --- a/guide/2011505.md +++ b/guide/2011505.md @@ -2,7 +2,11 @@ title: Zettel metadata --- -You zettels can contain custom metadata. Neuron supports "tags" as builtin. For example: +Every zettel must contain a "title" field in its metadata. Option metadata include "tags" and "date". + +## Tags + +You can attach one or more tags to your zettels: ```markdown --- @@ -13,3 +17,18 @@ tags: ``` Tags can also be nested using a "tag/subtag" syntax, to allow a more fine-grained organization of your Zettelkasten, especially when using advanced queries as shown in [2011506](zcf://linking-to-multiple-zettels). + +## Date + +If you are using custom ID, the creation date of the zettels can be specified in the "date" metadata field: + +```markdown +--- +title: Ate steak for birthday +date: 2020-04-07 +tags: + - journal +--- +``` + +The creation date can be made to display in a zquery result by using the `linkTheme=withDate` argument (see [2011506](zcf://linking-to-multiple-zettels)). diff --git a/src/Neuron/Zettelkasten/ID.hs b/src/Neuron/Zettelkasten/ID.hs index 3e5de4887..5f2df6154 100644 --- a/src/Neuron/Zettelkasten/ID.hs +++ b/src/Neuron/Zettelkasten/ID.hs @@ -8,7 +8,6 @@ module Neuron.Zettelkasten.ID ( ZettelID (..), InvalidID (..), - zettelIDDay, zettelIDText, parseZettelID, parseZettelID', @@ -77,12 +76,6 @@ formatDay day = zettelIDSourceFileName :: ZettelID -> FilePath zettelIDSourceFileName zid = toString $ zettelIDText zid <> ".md" -zettelIDDay :: ZettelID -> Maybe Day -zettelIDDay = \case - ZettelCustomID _ -> Nothing - ZettelDateID day _ -> - Just day - zettelPath :: ZettelID -> Action FilePath zettelPath zid = do notesDir <- Rib.ribInputDir diff --git a/src/Neuron/Zettelkasten/Query/View.hs b/src/Neuron/Zettelkasten/Query/View.hs index 6859fd5a7..fba8369a2 100644 --- a/src/Neuron/Zettelkasten/Query/View.hs +++ b/src/Neuron/Zettelkasten/Query/View.hs @@ -69,7 +69,7 @@ renderZettelLink LinkView {..} Zettel {..} = do let zurl = Rib.routeUrlRel $ Route_Zettel zettelID mextra = if linkViewShowDate - then case zettelIDDay zettelID of + then case zettelDay of Just day -> Just $ toHtml $ show @Text day Nothing -> diff --git a/src/Neuron/Zettelkasten/Zettel.hs b/src/Neuron/Zettelkasten/Zettel.hs index 3d5d7a9d6..b920b6fa1 100644 --- a/src/Neuron/Zettelkasten/Zettel.hs +++ b/src/Neuron/Zettelkasten/Zettel.hs @@ -10,6 +10,7 @@ module Neuron.Zettelkasten.Zettel where import Data.Aeson import Data.Graph.Labelled (Vertex (..)) import Data.TagTree (Tag) +import Data.Time.Calendar import Development.Shake (Action) import Neuron.Zettelkasten.ID import qualified Neuron.Zettelkasten.Zettel.Meta as Meta @@ -22,6 +23,7 @@ data Zettel = Zettel { zettelID :: ZettelID, zettelTitle :: Text, zettelTags :: [Tag], + zettelDay :: Maybe Day, zettelContent :: MMark } @@ -46,7 +48,8 @@ zettelJson :: KeyValue a => Zettel -> [a] zettelJson Zettel {..} = [ "id" .= toJSON zettelID, "title" .= zettelTitle, - "tags" .= zettelTags + "tags" .= zettelTags, + "day" .= zettelDay ] -- | Load a zettel from a file. @@ -59,4 +62,9 @@ mkZettelFromPath path = do meta = Meta.getMeta doc title = maybe (toText $ "No title for " <> path) Meta.title meta tags = fromMaybe [] $ Meta.tags =<< meta - pure $ Zettel zid title tags doc + 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 + pure $ Zettel zid title tags day doc diff --git a/src/Neuron/Zettelkasten/Zettel/Meta.hs b/src/Neuron/Zettelkasten/Zettel/Meta.hs index 1f070ce7b..d4940f723 100644 --- a/src/Neuron/Zettelkasten/Zettel/Meta.hs +++ b/src/Neuron/Zettelkasten/Zettel/Meta.hs @@ -11,13 +11,16 @@ where import Data.Aeson import Data.TagTree (Tag) +import Data.Time.Calendar import Relude import Text.MMark (MMark, projectYaml) -- | YAML metadata in a zettel markdown file data Meta = Meta { title :: Text, - tags :: Maybe [Tag] + tags :: Maybe [Tag], + -- | Creation day + date :: Maybe Day } deriving (Eq, Show, Generic, FromJSON) diff --git a/test/Neuron/Zettelkasten/ZettelSpec.hs b/test/Neuron/Zettelkasten/ZettelSpec.hs index ce7954364..c8c97d399 100644 --- a/test/Neuron/Zettelkasten/ZettelSpec.hs +++ b/test/Neuron/Zettelkasten/ZettelSpec.hs @@ -21,7 +21,8 @@ spec = do describe "sortZettelsReverseChronological" $ do let mkDay = fromGregorian 2020 3 dummyContent = either error id $ parsePure "" "Dummy" - mkZettel day idx = Zettel (ZettelDateID (mkDay day) idx) "Some title" [Tag "science", Tag "journal/class"] dummyContent + mkZettel day idx = + Zettel (ZettelDateID (mkDay day) idx) "Some title" [Tag "science", Tag "journal/class"] Nothing dummyContent it "sorts correctly" $ do let zs = [mkZettel 3 2, mkZettel 5 1] sortZettelsReverseChronological zs @@ -32,14 +33,15 @@ spec = do `shouldBe` [mkZettel 7 4, mkZettel 7 2] describe "Zettel JSON" $ do let day = fromGregorian 2020 3 19 - zid = ZettelDateID day 1 + zid = ZettelCustomID "Foo-Bar" dummyContent = either error id $ parsePure "" "Dummy" - zettel = Zettel zid "Some title" [Tag "science", Tag "journal/class"] dummyContent + zettel = Zettel zid "Some title" [Tag "science", Tag "journal/class"] (Just day) dummyContent it "Produces expected json" $ do -- "{\"id\":\"2011401\",\"title\":\"Some title\",\"tags\":[\"science\"]}" object (zettelJson zettel) `shouldBe` object - [ "id" .= ("2011401" :: Text), + [ "id" .= ("Foo-Bar" :: Text), "title" .= ("Some title" :: Text), - "tags" .= (["science", "journal/class"] :: [Text]) + "tags" .= (["science", "journal/class"] :: [Text]), + "day" .= day ]