-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathOrg.hs
114 lines (87 loc) · 4.39 KB
/
Org.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Org where
import Control.Applicative (empty)
import Control.Monad ((>=>))
import Data.Char (toLower)
import Data.List (intercalate)
import Data.List.Split (splitOn)
import Data.Maybe (fromJust, fromMaybe, catMaybes, isJust)
import Debug.Trace (trace)
import System.FilePath (takeExtension, replaceExtension, (</>), makeRelative, isRelative, takeDirectory)
import Hakyll (Item, Compiler, Context, Context(..), ContextField(StringField), loadSnapshot, itemBody, itemIdentifier, getResourceString, saveSnapshot, getMetadataField)
import Common (compileWithFilter, (|>), (|.))
orgCompile :: Item String -> Compiler (Item String)
orgCompile item = do
-- TODO eh, kinda copy pasted from Ipynb.hs...
let iid = show $ itemIdentifier item
let path = makeRelative "content/" iid
_ <- if path == iid then fail "Expected path relative to content/" else return () -- meh. is that really the right way?
meta <- getMetadataField (itemIdentifier item) "check_ids"
let check_ids = isJust meta
let spath = makeRelative "special/" path -- we flatten 'special hierarchy'
let wdir = "_site" </> takeDirectory spath
let args = ["--output-dir", wdir] ++ (if check_ids then ["--check-ids"] else [])
compileWithFilter "misc/compile_org.py" args item
raw_org_key = "raw_org"
meta_start = "#+"
meta_sep = ": "
type OrgMetas = [(String, String)]
type OrgBody = String
-- TODO ugh. very hacky...
orgMetadatas :: OrgBody -> OrgMetas
orgMetadatas = lines |. map tryMeta |. catMaybes
where
tryMeta :: String -> Maybe (String, String)
-- TODO catMaybe?
tryMeta line = do
-- TODO ugh. a bit ugly...
let split = splitOn meta_start line
case split of
("": rem) ->
let split2 = splitOn meta_sep $ concat rem in
case split2 of
-- we intercalate here since colons could be in title
-- TODO ugh. perhaps should have used regex instead
(fieldname: rem2) -> Just (fieldname |> map toLower, intercalate meta_sep rem2)
_ -> Nothing
_ -> Nothing
orgMetas :: Context String
orgMetas = Context $ \key _ item -> do
let idd = itemIdentifier item
let path = show idd
if takeExtension path /= ".org" then empty else do
raw_org :: Item String <- loadSnapshot idd raw_org_key
let metas = orgMetadatas $ itemBody raw_org
let meta = lookup key metas
maybe empty (StringField |. return) meta
-- TODO that's pretty horrible... maybe I need a special item type... and combine compilers?
orgCompiler = do
res <- getResourceString
_ <- saveSnapshot raw_org_key res
orgCompile res
-- TODO careful not to pick this file up when we have more org posts
-- perhaps should just move the link out of content root
-- import Text.Pandoc.Shared (stringify)
-- import Text.Pandoc.Options (def, writerVariables, writerTableOfContents)
-- import Hakyll.Web.Pandoc
-- import Text.Pandoc (readOrg, Pandoc(..), docTitle, docDate, Meta, Inline)
-- pandocMeta :: (Meta -> [Inline]) -> (Item Pandoc -> Compiler String)
-- pandocMeta extractor Item {itemBody=Pandoc meta _} = return $ stringify $ extractor meta -- TODO proper html??
-- -- TODO extract that stuff somewhere and share??
-- orgFileTags = field "filetags" (\p -> return "TODO FILETAGS")
-- orgAuthor = constField "author" "Dima" -- TODO docAuthors??
-- orgTitle = field "title" $ pandocMeta docTitle
-- orgDate = field "date" $ pandocMeta docDate
-- pandocContext :: Context Pandoc
-- pandocContext = orgFileTags <> orgAuthor <> orgTitle <> orgDate
-- -- TODO ugh. surely it can't be that ugly right?
-- data PandocX = PandocX Pandoc String
-- combineItems :: (a -> b -> c) -> Item a -> Item b -> Item c
-- combineItems f Item{itemBody=ba, itemIdentifier=ii} Item{itemBody=bb} = Item {itemBody=f ba bb, itemIdentifier=ii}
-- combineContexts :: Context Pandoc -> Context String -> Context PandocX
-- combineContexts (Context f) (Context g) = Context $ \k a Item{itemBody=PandocX pdoc rendered} -> f k a Item {itemBody=pdoc, itemIdentifier=""} <|> g k a Item {itemBody=rendered, itemIdentifier=""} -- TODO break down item ;
-- TODO readPandocWith??
-- myContext :: Context PandocX
-- myContext = combineContexts pandocContext defaultContext
-- pandoc doesn't seem to be capable of handling many org clases..
-- https://github.com/jgm/pandoc/blob/f3080c0c22470e7ecccbef86c1cd0b1339a6de9b/src/Text/Pandoc/Readers/Org/ExportSettings.hs#L61