]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Wiki/Engine.hs
Implemented the outline command
[Rakka.git] / Rakka / Wiki / Engine.hs
index 65009751dde7694c12a52fd4b678f5e5d20261ea..ffaab2f4edf28a9a41b19be39b223be3999d4e8f 100644 (file)
@@ -1,13 +1,14 @@
 module Rakka.Wiki.Engine
     ( formatPage
+    , formatSubPage
     )
     where
 
 import           Control.Arrow
 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
@@ -27,30 +28,47 @@ formatPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
            -> a Page XmlTree
 formatPage env
     = proc page
-    -> do tree <- case pageType page of
-                    MIMEType "text" "x-rakka" _
-                        -> do let source = decodeLazy UTF8 (pageContent page)
-                              formatWikiPage env -< (Just page, source)
-          attachXHtmlNs -< tree
-
-
-formatWikiPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
-                  Environment
-               -> a (Maybe Page, String) XmlTree
-formatWikiPage env
-    = proc (page, source)
     -> do BaseURI baseURI <- getSysConfA (envSysConf env) (BaseURI undefined) -< ()
           interpTable     <- getInterpTableA env -< ()
+          wiki            <- wikifyPage env -< (interpTable, page)
+          xs              <- interpretCommandsA env -< (interpTable, (pageName page, (Just wiki, wiki)))
+          formatWikiBlocks -< (baseURI, xs)
 
-          let parser = wikiPage (tableToFunc interpTable)
 
-          case parse parser "" source of
-            Left  err
-                -> formatParseError -< err
-
-            Right blocks
-                -> do xs <- interpretCommandsA env -< (interpTable, (page, blocks))
-                      formatWikiBlocks -< (baseURI, xs)
+formatSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+                 Environment
+              -> a (PageName, (Maybe Page, Page)) XmlTree
+formatSubPage env
+    = proc (mainPageName, (mainPage, subPage))
+    -> do BaseURI baseURI <- getSysConfA (envSysConf env) (BaseURI undefined) -< ()
+          interpTable     <- getInterpTableA env -< ()
+          mainWiki        <- case mainPage of
+                               Just page
+                                   -> do wiki <- wikifyPage env -< (interpTable, page)
+                                         returnA -< Just wiki
+                               Nothing
+                                   -> returnA -< Nothing
+          subWiki        <- wikifyPage env -< (interpTable, subPage)
+          xs             <- interpretCommandsA env -< (interpTable, (mainPageName, (mainWiki, subWiki)))
+          formatWikiBlocks -< (baseURI, xs)
+
+
+wikifyPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+                 Environment
+              -> a (InterpTable, Page) WikiPage
+wikifyPage env
+    = proc (interpTable, page)
+    -> case pageType page of
+         MIMEType "text" "x-rakka" _
+             -> do let source = decodeLazy UTF8 (pageContent page)
+                       parser = wikiPage (tableToFunc interpTable)
+
+                   case parse parser "" source of
+                     Left  err
+                         -> wikifyParseError -< err
+
+                     Right xs
+                         -> returnA -< xs
     where
       tableToFunc :: InterpTable -> String -> Maybe CommandType
       tableToFunc table name
@@ -59,67 +77,59 @@ formatWikiPage env
 
 interpretCommandsA :: ArrowIO a =>
                       Environment
-                   -> a (InterpTable, (Maybe Page, WikiPage)) WikiPage
-interpretCommandsA = arrIO3 . interpretCommands
+                   -> a (InterpTable, (PageName, (Maybe WikiPage, WikiPage))) WikiPage
+interpretCommandsA = arrIO4 . interpretCommands
 
 
-interpretCommands :: Environment -> InterpTable -> Maybe Page -> WikiPage -> IO WikiPage
-interpretCommands _   _     _    []     = return []
-interpretCommands env table page blocks = mapM interpBlock blocks
+interpretCommands :: Environment -> InterpTable -> PageName -> Maybe WikiPage -> WikiPage -> IO WikiPage
+interpretCommands _   _     _    _        []         = return []
+interpretCommands env table name mainTree targetTree
+    = everywhereM' (mkM interpBlockCmd) targetTree
+      >>=
+      everywhereM' (mkM interpInlineCmd)
     where
-      interpBlock :: BlockElement -> IO BlockElement
-      interpBlock (List           list) = interpList list >>= return . List
-      interpBlock (DefinitionList defs) = mapM interpDefinition defs >>= return . DefinitionList
-      interpBlock (Preformatted   xs  ) = mapM interpInline xs >>= return . Preformatted
-      interpBlock (Paragraph      xs  ) = mapM interpInline xs >>= return . Paragraph
-      interpBlock others                = return others
-
-      interpList :: ListElement -> IO ListElement
-      interpList list = do items <- mapM interpListItem (listItems list)
-                           return $ list { listItems = items }
-
-      interpListItem :: ListItem -> IO ListItem
-      interpListItem []                  = return []
-      interpListItem ((Left  nested):xs) = do x  <- interpList nested >>= return . Left
-                                              xs <- interpListItem xs
-                                              return (x:xs)
-      interpListItem ((Right inline):xs) = do x  <- interpInline inline >>= return . Right
-                                              xs <- interpListItem xs
-                                              return (x:xs)
-
-      interpDefinition :: Definition -> IO Definition
-      interpDefinition def = do term <- mapM interpInline (defTerm def)
-                                desc <- mapM interpInline (defDesc def)
-                                return $ def { defTerm = term, defDesc = desc }
-
-      interpInline :: InlineElement -> IO InlineElement
-      interpInline (Italic    xs ) = mapM interpInline xs >>= return . Italic
-      interpInline (Bold      xs ) = mapM interpInline xs >>= return . Bold
-      interpInline (InlineCmd cmd) = interpInlineCmd cmd
-      interpInline others          = return others
-
-      interpInlineCmd :: InlineCommand -> IO InlineElement
-      interpInlineCmd cmd
+      ctx :: InterpreterContext
+      ctx = InterpreterContext {
+              ctxPageName   = name
+            , ctxMainTree   = mainTree
+            , ctxTargetTree = targetTree
+            , 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 cmd page (envStorage env) (envSysConf env)
-                     >>=
-                     interpInline
+                  -> iciInterpret interp ctx cmd
 
 
-formatParseError :: ArrowXml a => a ParseError XmlTree
-formatParseError 
-    = proc err -> (eelem "pre" += txt (show err)) -<< ()
+-- Perform monadic transformation in top-down order.
+everywhereM' :: Monad m => GenericM m -> GenericM m
+everywhereM' f x = f x >>= gmapM (everywhereM' f)
 
 
-attachXHtmlNs :: ArrowXml a => a XmlTree XmlTree
-attachXHtmlNs = processBottomUp (changeQName attach')
-    where
-      attach' :: QName -> QName
-      attach' qn = qn {
-                     namePrefix   = "xhtml"
-                   , namespaceUri = "http://www.w3.org/1999/xhtml"
-                   }
+wikifyParseError :: ArrowXml a => a ParseError WikiPage
+wikifyParseError 
+    = proc err -> returnA -< [Preformatted [Text (show err)]]