]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Wiki/Engine.hs
wrote many
[Rakka.git] / Rakka / Wiki / Engine.hs
index 5aa5db4ac90e5d81a13ac28eedd086e90a585766..aa897e841e01b6429d9dd9fd1d5d81ebedb9f532 100644 (file)
@@ -1,5 +1,6 @@
 module Rakka.Wiki.Engine
     ( formatPage
+    , formatSubPage
     )
     where
 
@@ -8,12 +9,16 @@ import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowTree
 import           Data.Encoding
 import           Data.Encoding.UTF8
+import           Data.Generics
+import qualified Data.Map as M
 import           Network.HTTP.Lucu
 import           Rakka.Environment
 import           Rakka.Page
 import           Rakka.SystemConfig
+import           Rakka.Wiki
 import           Rakka.Wiki.Parser
 import           Rakka.Wiki.Formatter
+import           Rakka.Wiki.Interpreter
 import           Text.ParserCombinators.Parsec
 import           Text.XML.HXT.Arrow.XmlArrow
 import           Text.XML.HXT.DOM.TypeDefs
@@ -26,23 +31,97 @@ formatPage env
     = proc page
     -> do tree <- case pageType page of
                     MIMEType "text" "x-rakka" _
-                        -> formatWikiPage env -< page
+                        -> do let source = decodeLazy UTF8 (pageContent page)
+                              formatWikiPage env -< (pageName page, source)
+          attachXHtmlNs -< tree
+
+
+formatSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+                 Environment
+              -> a (PageName, Page) XmlTree
+formatSubPage env
+    = proc (mainPageName, subPage)
+    -> do tree <- case pageType subPage of
+                    MIMEType "text" "x-rakka" _
+                        -> do let source = decodeLazy UTF8 (pageContent subPage)
+                              formatWikiPage env -< (mainPageName, source)
           attachXHtmlNs -< tree
 
 
 formatWikiPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
                   Environment
-               -> a Page XmlTree
+               -> a (PageName, String) XmlTree
 formatWikiPage env
-    = proc page
-    -> do let source = decodeLazy UTF8 (pageContent page)
-          case parse wikiPage "" source of
+    = proc (name, source)
+    -> do BaseURI baseURI <- getSysConfA (envSysConf env) (BaseURI undefined) -< ()
+          interpTable     <- getInterpTableA env -< ()
+
+          let parser = wikiPage (tableToFunc interpTable)
+
+          case parse parser "" source of
             Left  err
                 -> formatParseError -< err
 
-            Right elems
-                -> do BaseURI baseURI <- getSysConfA (envSysConf env) (BaseURI undefined) -< ()
-                      formatWikiElements -< (baseURI, elems)
+            Right blocks
+                -> do xs <- interpretCommandsA env -< (interpTable, (name, blocks))
+                      formatWikiBlocks -< (baseURI, xs)
+    where
+      tableToFunc :: InterpTable -> String -> Maybe CommandType
+      tableToFunc table name
+          = fmap commandType (M.lookup name table)
+
+
+interpretCommandsA :: ArrowIO a =>
+                      Environment
+                   -> a (InterpTable, (PageName, WikiPage)) WikiPage
+interpretCommandsA = arrIO3 . interpretCommands
+
+
+interpretCommands :: Environment -> InterpTable -> PageName -> WikiPage -> IO WikiPage
+interpretCommands _   _     _    []     = return []
+interpretCommands env table name blocks = everywhereM' (mkM interpBlockCmd) blocks
+                                          >>=
+                                          everywhereM' (mkM interpInlineCmd)
+    where
+      ctx :: InterpreterContext
+      ctx = InterpreterContext {
+              ctxPageName = name
+            , ctxTree     = blocks
+            , ctxStorage  = envStorage env
+            , ctxSysConf  = envSysConf env
+            }
+
+      interpBlockCmd :: BlockElement -> IO BlockElement
+      interpBlockCmd (BlockCmd cmd) = interpBlockCmd' cmd
+      interpBlockCmd others         = return others
+
+      interpBlockCmd' :: BlockCommand -> IO BlockElement
+      interpBlockCmd' cmd
+          = case M.lookup (bCmdName cmd) table of
+              Nothing
+                  -> fail ("no such interpreter: " ++ bCmdName cmd)
+
+              Just interp
+                  -> bciInterpret interp ctx cmd
+
+
+      interpInlineCmd :: InlineElement -> IO InlineElement
+      interpInlineCmd (InlineCmd cmd) = interpInlineCmd' cmd
+      interpInlineCmd others          = return others
+
+      interpInlineCmd' :: InlineCommand -> IO InlineElement
+      interpInlineCmd' cmd
+          = case M.lookup (iCmdName cmd) table of
+              Nothing
+                  -> fail ("no such interpreter: " ++ iCmdName cmd)
+
+              Just interp
+                  -> iciInterpret interp ctx cmd
+
+
+-- Perform monadic transformation in top-down order.
+everywhereM' :: Monad m => GenericM m -> GenericM m
+everywhereM' f x = f x >>= gmapM (everywhereM' f)
 
 
 formatParseError :: ArrowXml a => a ParseError XmlTree