1 module Rakka.Wiki.Engine
7 import Control.Arrow.ArrowIO
8 import Control.Arrow.ArrowTree
10 import Data.Encoding.UTF8
12 import qualified Data.Map as M
13 import Network.HTTP.Lucu
14 import Rakka.Environment
16 import Rakka.SystemConfig
18 import Rakka.Wiki.Parser
19 import Rakka.Wiki.Formatter
20 import Rakka.Wiki.Interpreter
21 import Text.ParserCombinators.Parsec
22 import Text.XML.HXT.Arrow.XmlArrow
23 import Text.XML.HXT.DOM.TypeDefs
26 formatPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
31 -> do tree <- case pageType page of
32 MIMEType "text" "x-rakka" _
33 -> do let source = decodeLazy UTF8 (pageContent page)
34 formatWikiPage env -< (Just page, source)
38 formatWikiPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
40 -> a (Maybe Page, String) XmlTree
43 -> do BaseURI baseURI <- getSysConfA (envSysConf env) (BaseURI undefined) -< ()
44 interpTable <- getInterpTableA env -< ()
46 let parser = wikiPage (tableToFunc interpTable)
48 case parse parser "" source of
50 -> formatParseError -< err
53 -> do xs <- interpretCommandsA env -< (interpTable, (page, blocks))
54 formatWikiBlocks -< (baseURI, xs)
56 tableToFunc :: InterpTable -> String -> Maybe CommandType
57 tableToFunc table name
58 = fmap commandType (M.lookup name table)
61 interpretCommandsA :: ArrowIO a =>
63 -> a (InterpTable, (Maybe Page, WikiPage)) WikiPage
64 interpretCommandsA = arrIO3 . interpretCommands
67 interpretCommands :: Environment -> InterpTable -> Maybe Page -> WikiPage -> IO WikiPage
68 interpretCommands _ _ _ [] = return []
69 interpretCommands env table page blocks = everywhereM' (mkM interpBlockCmd) blocks
71 everywhereM' (mkM interpInlineCmd)
73 ctx :: InterpreterContext
74 ctx = InterpreterContext {
77 , ctxStorage = envStorage env
78 , ctxSysConf = envSysConf env
81 interpBlockCmd :: BlockElement -> IO BlockElement
82 interpBlockCmd (BlockCmd cmd) = interpBlockCmd' cmd
83 interpBlockCmd others = return others
85 interpBlockCmd' :: BlockCommand -> IO BlockElement
87 = case M.lookup (bCmdName cmd) table of
89 -> fail ("no such interpreter: " ++ bCmdName cmd)
92 -> bciInterpret interp ctx cmd
95 interpInlineCmd :: InlineElement -> IO InlineElement
96 interpInlineCmd (InlineCmd cmd) = interpInlineCmd' cmd
97 interpInlineCmd others = return others
99 interpInlineCmd' :: InlineCommand -> IO InlineElement
101 = case M.lookup (iCmdName cmd) table of
103 -> fail ("no such interpreter: " ++ iCmdName cmd)
106 -> iciInterpret interp ctx cmd
109 -- Perform monadic transformation in top-down order.
110 everywhereM' :: Monad m => GenericM m -> GenericM m
111 everywhereM' f x = f x >>= gmapM (everywhereM' f)
114 formatParseError :: ArrowXml a => a ParseError XmlTree
116 = proc err -> (eelem "pre" += txt (show err)) -<< ()
119 attachXHtmlNs :: ArrowXml a => a XmlTree XmlTree
120 attachXHtmlNs = processBottomUp (changeQName attach')
122 attach' :: QName -> QName
125 , namespaceUri = "http://www.w3.org/1999/xhtml"