]> gitweb @ CieloNegro.org - Rakka.git/commitdiff
The big change
authorpho <pho@cielonegro.org>
Tue, 30 Oct 2007 10:26:56 +0000 (19:26 +0900)
committerpho <pho@cielonegro.org>
Tue, 30 Oct 2007 10:26:56 +0000 (19:26 +0900)
darcs-hash:20071030102656-62b54-449bda8a45c3e3ac65751704a133ea60a16cc4d0.gz

13 files changed:
Main.hs
Rakka.cabal
Rakka/Environment.hs
Rakka/Page.hs
Rakka/Resource/PageEntity.hs [new file with mode: 0644]
Rakka/Resource/Render.hs [deleted file]
Rakka/Wiki.hs
Rakka/Wiki/Engine.hs
Rakka/Wiki/Formatter.hs
Rakka/Wiki/Interpreter.hs
Rakka/Wiki/Interpreter/Base.hs
Rakka/Wiki/Interpreter/Outline.hs
schemas/rakka-page-1.0.rng

diff --git a/Main.hs b/Main.hs
index 8027c7ec0978a4caf2aec2cae6ed90cd2c2e3f59..6621f58a11439ae334923349a75819ff8e042b64 100644 (file)
--- a/Main.hs
+++ b/Main.hs
@@ -7,8 +7,8 @@ import           Network.HTTP.Lucu
 import           Rakka.Environment
 import           Rakka.Resource.Index
 import           Rakka.Resource.JavaScript
+import           Rakka.Resource.PageEntity
 import           Rakka.Resource.Object
-import           Rakka.Resource.Render
 import           Rakka.Storage
 import           Subversion
 import           System.Console.GetOpt
@@ -128,7 +128,7 @@ main = withSubversion $
           rebuildIndexIfRequested env opts
 
           infoM logger ("Listening to " ++ show portNum ++ "/tcp...")
-          runHttpd (envLucuConf env) (resTree env) [fallbackRender env]
+          runHttpd (envLucuConf env) (resTree env) [fallbackPageEntity env]
 
           
 resTree :: Environment -> ResTree
index 737352f1925b3d3f81dd6db1802bf92fcbab9b4c..47c87a16c34aa6d609887ad648eb790f6bbe8daf 100644 (file)
@@ -51,7 +51,7 @@ Other-Modules:
     Rakka.Resource.Index
     Rakka.Resource.JavaScript
     Rakka.Resource.Object
-    Rakka.Resource.Render
+    Rakka.Resource.PageEntity
     Rakka.Storage
     Rakka.Storage.DefaultPage
     Rakka.Storage.Types
index 321ba7ed07bac0a8ba53304ac1a798f8c84c1901..d40294ae44c27f224908291509c3f735478c40e6 100644 (file)
@@ -5,9 +5,12 @@ module Rakka.Environment
     )
     where
 
+import           Control.Arrow
+import           Control.Arrow.ArrowList
 import qualified Data.Map as M
 import           Network
 import qualified Network.HTTP.Lucu.Config as LC
+import           Rakka.Page
 import           Rakka.Storage
 import           Rakka.SystemConfig
 import           Rakka.Wiki.Engine
@@ -22,6 +25,8 @@ import           System.Directory
 import           System.FilePath
 import           System.IO
 import           System.Log.Logger
+import           Text.HyperEstraier
+import           Text.XML.HXT.Arrow.XmlIOStateArrow
 
 
 logger = "Rakka.Environment"
@@ -53,7 +58,7 @@ setupEnv lsdir portNum
                             do noticeM logger ("Creating a subversion repository on " ++ reposPath)
                                createRepository reposPath [] []
          sysConf     <- mkSystemConfig lucuConf repos
-         storage     <- mkStorage lsdir repos (makeDraft interpTable)
+         storage     <- mkStorage lsdir repos (makeDraft' interpTable)
 
          return $ Environment {
                       envLocalStateDir = lsdir
@@ -63,6 +68,18 @@ setupEnv lsdir portNum
                     , envStorage       = storage
                     , envInterpTable   = interpTable
                     }
+    where
+      makeDraft' :: InterpTable -> Page -> IO Document
+      makeDraft' interpTable page
+          = do [doc] <- runX ( setErrorMsgHandler False fail
+                               >>>
+                               constA page
+                               >>>
+                               xmlizePage
+                               >>>
+                               makeDraft interpTable
+                             )
+               return doc
 
 
 mkInterpTable :: InterpTable
index ec6ce8008209b498afb4064d9560f26e2df4d85c..9d84cf28df7f0285c2788842773063998c638a5b 100644 (file)
@@ -8,6 +8,7 @@ module Rakka.Page
     , decodePageName
 
     , pageFileName'
+    , defaultFileName
 
     , mkPageURI
     , mkPageFragmentURI
@@ -89,14 +90,15 @@ encodeFragment = escapeURIString isSafeChar . C8.unpack . encode UTF8
 
 
 pageFileName' :: Page -> String
-pageFileName' page = fromMaybe (defaultFileName page) (pageFileName page)
+pageFileName' page
+    = fromMaybe (defaultFileName (pageType page) (pageName page)) (pageFileName page)
 
 
-defaultFileName :: Page -> String
-defaultFileName page
-    = let baseName = takeFileName (pageName page)
+defaultFileName :: MIMEType -> PageName -> String
+defaultFileName pType pName
+    = let baseName = takeFileName pName
       in 
-        case pageType page of
+        case pType of
           MIMEType "text" "x-rakka" _ -> baseName <.> "rakka"
           MIMEType "text" "css"     _ -> baseName <.> "css"
           _                           -> baseName
diff --git a/Rakka/Resource/PageEntity.hs b/Rakka/Resource/PageEntity.hs
new file mode 100644 (file)
index 0000000..3c00612
--- /dev/null
@@ -0,0 +1,271 @@
+module Rakka.Resource.PageEntity
+    ( fallbackPageEntity
+    )
+    where
+
+import           Control.Arrow
+import           Control.Arrow.ArrowIO
+import           Control.Arrow.ArrowIf
+import           Control.Arrow.ArrowList
+import           Data.Char
+import           Data.Maybe
+import           Network.HTTP.Lucu
+import           Network.HTTP.Lucu.Utils
+import           Network.URI
+import           Rakka.Environment
+import           Rakka.Page
+import           Rakka.Resource
+import           Rakka.Storage
+import           Rakka.SystemConfig
+import           Rakka.Wiki.Engine
+import           System.FilePath
+import           System.Time
+import           Text.XML.HXT.Arrow.XmlArrow
+import           Text.XML.HXT.Arrow.XmlNodeSet
+import           Text.XML.HXT.DOM.TypeDefs
+
+
+fallbackPageEntity :: Environment -> [String] -> IO (Maybe ResourceDef)
+fallbackPageEntity env path
+    | null path                  = return Nothing
+    | null $ head path           = return Nothing
+    | isLower $ head $ head path = return Nothing -- 先頭の文字が小文字であってはならない
+    | otherwise
+        = return $ Just $ ResourceDef {
+            resUsesNativeThread = False
+          , resIsGreedy         = True
+          , resGet              = Just $ handleGet env (toPageName path)
+          , resHead             = Nothing
+          , resPost             = Nothing
+          , resPut              = Nothing
+          , resDelete           = Nothing
+          }
+    where
+      toPageName :: [String] -> PageName
+      toPageName = decodePageName . dropExtension . joinWith "/"
+
+
+handleGet :: Environment -> PageName -> Resource ()
+handleGet env name
+    = runIdempotentA $ proc ()
+    -> do pageM <- getPageA (envStorage env) -< (name, Nothing)
+          case pageM of
+            Nothing
+                -> handlePageNotFound env -< name
+
+            Just redir@(Redirection _ _ _ _)
+                -> handleRedirect env -< redir
+
+            Just entity@(Entity _ _ _ _ _ _ _ _ _ _ _ _ _ _)
+                -> handleGetEntity env -< entity
+
+{-
+  HTTP/1.1 302 Found
+  Location: http://example.org/Destination?from=Source
+-}
+handleRedirect :: (ArrowXml a, ArrowIO a) => Environment -> a Page (Resource ())
+handleRedirect env
+    = proc redir
+    -> do BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
+          returnA -< redirect Found (mkPageURI baseURI $ redirName redir) -- FIXME
+
+
+handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ())
+handleGetEntity env
+    = proc page
+    -> do tree <- xmlizePage -< page
+          returnA -< do let lastMod = toClockTime $ pageLastMod page
+                              
+                        -- text/x-rakka の場合は、内容が動的に生成され
+                        -- てゐる可能性があるので、ETag も
+                        -- Last-Modified も返す事が出來ない。
+                        case pageType page of
+                          MIMEType "text" "x-rakka" _
+                              -> return ()
+                          _   -> case pageRevision page of
+                                   0   -> foundTimeStamp lastMod -- 0 はデフォルトページ
+                                   rev -> foundEntity (strongETag $ show rev) lastMod
+
+                        outputXmlPage tree (entityToXHTML env)
+
+
+entityToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
+entityToXHTML env
+    = proc page
+    -> do SiteName   siteName   <- getSysConfA (envSysConf env) -< ()
+          BaseURI    baseURI    <- getSysConfA (envSysConf env) -< ()
+          StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
+
+          pageName <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page
+
+          let cssHref   = [uriToString id (mkObjectURI baseURI styleSheet) ""]
+              scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI </> "js" }) ""]
+
+          pageTitle    <- listA (readSubPage env) -< (pageName, Just page, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (pageName, Just page, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (pageName, Just page, "SideBar/Right")
+          pageBody     <- listA (makeMainXHTML (envStorage env) (envSysConf env) (envInterpTable env)) -< page
+
+          ( eelem "/"
+            += ( eelem "html"
+                 += sattr "xmlns" "http://www.w3.org/1999/xhtml"
+                 += ( getXPathTreesInDoc "/page/@lang"
+                      `guards`
+                      qattr (QN "xml" "lang" "")
+                                ( getXPathTreesInDoc "/page/@lang/text()" )
+                    )
+                 += ( eelem "head"
+                      += ( eelem "title"
+                           += txt siteName
+                           += txt " - "
+                           += getXPathTreesInDoc "/page/@name/text()"
+                         )
+                      += ( constL cssHref
+                           >>>
+                           eelem "link"
+                           += sattr "rel"  "stylesheet"
+                           += sattr "type" "text/css"
+                           += attr "href" (arr id >>> mkText)
+                         )
+                      += ( constL scriptSrc
+                           >>>
+                           eelem "script"
+                           += sattr "type" "text/javascript"
+                           += attr "src" (arr id >>> mkText)
+                         )
+                    )
+                 += ( eelem "body"
+                      += ( eelem "div"
+                           += sattr "class" "header"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "center"
+                           += ( eelem "div"
+                                += sattr "class" "title"
+                                += constL pageTitle
+                              )
+                           += ( eelem "div"
+                                += sattr "class" "body"
+                                += constL pageBody
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "footer"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "left sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL leftSideBar
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "right sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL rightSideBar
+                              )
+                         )
+                    )
+               ) ) -<< page
+
+
+readSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+               Environment
+            -> a (PageName, Maybe XmlTree, PageName) XmlTree
+readSubPage env
+    = proc (mainPageName, mainPage, subPageName) ->
+      do subPage  <- getPageA (envStorage env) >>> arr fromJust >>> xmlizePage -< (subPageName, Nothing)
+         subXHTML <- makeSubXHTML (envStorage env) (envSysConf env) (envInterpTable env)
+                     -< (mainPageName, mainPage, subPage)
+         returnA -< subXHTML
+
+
+{-
+  <pageNotFound name="Foo/Bar" />
+-}
+handlePageNotFound :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a PageName (Resource ())
+handlePageNotFound env
+    = proc name
+    -> do tree <- ( eelem "/"
+                    += ( eelem "pageNotFound"
+                         += attr "name" (arr id >>> mkText)
+                       )
+                  ) -< name
+          returnA -< do setStatus NotFound
+                        outputXmlPage tree (notFoundToXHTML env)
+
+
+notFoundToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
+notFoundToXHTML env
+    = proc pageNotFound
+    -> do SiteName   siteName   <- getSysConfA (envSysConf env) -< ()
+          BaseURI    baseURI    <- getSysConfA (envSysConf env) -< ()
+          StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
+
+          pageName <- (getXPathTreesInDoc "/pageNotFound/@name/text()" >>> getText) -< pageNotFound
+
+          let cssHref   = [uriToString id (mkObjectURI baseURI styleSheet) ""]
+              scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI </> "js" }) ""]
+
+          pageTitle    <- listA (readSubPage env) -< (pageName, Nothing, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (pageName, Nothing, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (pageName, Nothing, "SideBar/Right")
+
+          ( eelem "/"
+            += ( eelem "html"
+                 += sattr "xmlns" "http://www.w3.org/1999/xhtml"
+                 += ( eelem "head"
+                      += ( eelem "title"
+                           += txt siteName
+                           += txt " - "
+                           += getXPathTreesInDoc "/pageNotFound/@name/text()"
+                         )
+                      += ( constL cssHref
+                           >>>
+                           eelem "link"
+                           += sattr "rel"  "stylesheet"
+                           += sattr "type" "text/css"
+                           += attr "href" (arr id >>> mkText)
+                         )
+                      += ( constL scriptSrc
+                           >>>
+                           eelem "script"
+                           += sattr "type" "text/javascript"
+                           += attr "src" (arr id >>> mkText)
+                         )
+                    )
+                 += ( eelem "body"
+                      += ( eelem "div"
+                           += sattr "class" "header"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "center"
+                           += ( eelem "div"
+                                += sattr "class" "title"
+                                += constL pageTitle
+                              )
+                           += ( eelem "div"
+                                += sattr "class" "body"
+                                += txt "404 Not Found (FIXME)" -- FIXME
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "footer"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "left sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL leftSideBar
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "right sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL rightSideBar
+                              )
+                         )
+                    )
+               ) ) -<< pageNotFound
diff --git a/Rakka/Resource/Render.hs b/Rakka/Resource/Render.hs
deleted file mode 100644 (file)
index bcfd17f..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-module Rakka.Resource.Render
-    ( fallbackRender
-    )
-    where
-
-import           Control.Arrow
-import           Control.Arrow.ArrowIO
-import           Control.Arrow.ArrowIf
-import           Data.Char
-import           Network.HTTP.Lucu
-import           Network.HTTP.Lucu.Utils
-import           Rakka.Environment
-import           Rakka.Page
-import           Rakka.Resource
-import           Rakka.Storage
-import           Rakka.SystemConfig
-import           Rakka.Wiki.Engine
-import           System.FilePath
-import           System.Time
-import           Text.XML.HXT.Arrow.Namespace
-import           Text.XML.HXT.Arrow.XmlArrow
-import           Text.XML.HXT.Arrow.XmlNodeSet
-import           Text.XML.HXT.DOM.TypeDefs
-
-
-fallbackRender :: Environment -> [String] -> IO (Maybe ResourceDef)
-fallbackRender env path
-    | null path                  = return Nothing
-    | null $ head path           = return Nothing
-    | isLower $ head $ head path = return Nothing -- 先頭の文字が小文字であってはならない
-    | otherwise
-        = return $ Just $ ResourceDef {
-            resUsesNativeThread = False
-          , resIsGreedy         = True
-          , resGet              = Just $ handleGet env (toPageName path)
-          , resHead             = Nothing
-          , resPost             = Nothing
-          , resPut              = Nothing
-          , resDelete           = Nothing
-          }
-    where
-      toPageName :: [String] -> PageName
-      toPageName = decodePageName . dropExtension . joinWith "/"
-
-
-handleGet :: Environment -> PageName -> Resource ()
-handleGet env name
-    = runIdempotentA $ proc ()
-    -> do pageM <- getPageA (envStorage env) -< (name, Nothing)
-          case pageM of
-            Nothing
-                -> handlePageNotFound env -< name
-
-            Just redir@(Redirection _ _ _ _)
-                -> handleRedirect env -< redir
-
-            Just entity@(Entity _ _ _ _ _ _ _ _ _ _ _ _ _ _)
-                -> handleGetEntity env -< entity
-
-{-
-  HTTP/1.1 302 Found
-  Location: http://example.org/Destination?from=Source
--}
-handleRedirect :: (ArrowXml a, ArrowIO a) => Environment -> a Page (Resource ())
-handleRedirect env
-    = proc redir
-    -> do BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
-          returnA -< redirect Found (mkPageURI baseURI $ redirName redir) -- FIXME
-
-
-{-
-  <page site="CieloNegro"
-        baseURI="http://example.org"
-        name="Foo/Bar"
-        type="text/x-rakka"
-        lang="ja"            -- 存在しない場合もある
-        fileName="bar.rakka" -- 存在しない場合もある
-        isTheme="no"         -- text/css の場合のみ存在
-        isFeed="no"          -- text/x-rakka の場合のみ存在
-        isLocked="no"
-        isBinary="no"
-        revision="112">      -- デフォルトでない場合のみ存在
-        lastModified="2000-01-01T00:00:00">
-
-    <styleSheets>
-      <styleSheet src="http://example.org/object/StyleSheet/Default" />
-    </styleSheets>
-
-    <scripts>
-      <script src="http://example.org/js" />
-    </scripts>
-
-    <summary>
-        blah blah...
-    </summary> -- 存在しない場合もある
-
-    <otherLang> -- 存在しない場合もある
-      <link lang="ja" page="Bar/Baz" />
-    </otherLang>
-
-    <pageTitle>
-      blah blah...
-    </pageTitle>
-
-    <sideBar>
-      <left>
-        blah blah...
-      </left>
-      <right>
-        blah blah...
-      </right>
-    </sideBar>
-
-    <body>
-      blah blah...
-    </body>
-
-    <source><!-- isBinary="no" の場合にのみ存在 -->
-      blah blah...
-    </source>
-  </page>
--}
-handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ())
-handleGetEntity env
-    = proc page
-    -> do tree <- formatEntirePage (envStorage env) (envSysConf env) (envInterpTable env) -< page
-          returnA -< do let lastMod = toClockTime $ pageLastMod page
-                              
-                        -- text/x-rakka の場合は、内容が動的に生成され
-                        -- てゐる可能性があるので、ETag も
-                        -- Last-Modified も返す事が出來ない。
-                        case pageType page of
-                          MIMEType "text" "x-rakka" _
-                              -> return ()
-                          _   -> case pageRevision page of
-                                   0   -> foundTimeStamp lastMod -- 0 はデフォルトページ
-                                   rev -> foundEntity (strongETag $ show rev) lastMod
-
-                        outputXmlPage tree entityToXHTML
-
-
-entityToXHTML :: ArrowXml a => a XmlTree XmlTree
-entityToXHTML
-    = eelem "/"
-      += ( eelem "html"
-           += sattr "xmlns" "http://www.w3.org/1999/xhtml"
-           += ( getXPathTreesInDoc "/page/@lang"
-                `guards`
-                qattr (QN "xml" "lang" "")
-                          ( getXPathTreesInDoc "/page/@lang/text()" )
-              )
-           += ( eelem "head"
-                += ( eelem "title"
-                     += getXPathTreesInDoc "/page/@site/text()"
-                     += txt " - "
-                     += getXPathTreesInDoc "/page/@name/text()"
-                   )
-                += ( getXPathTreesInDoc "/page/styleSheets/styleSheet"
-                     >>>
-                     eelem "link"
-                     += sattr "rel"  "stylesheet"
-                     += sattr "type" "text/css"
-                     += attr "href"
-                            ( getXPathTrees "/styleSheet/@src/text()" )
-                   )
-                += ( getXPathTreesInDoc "/page/scripts/script"
-                     >>>
-                     eelem "script"
-                     += sattr "type" "text/javascript"
-                     += attr "src"
-                            ( getXPathTrees "/script/@src/text()" )
-                   )
-              )
-           += ( eelem "body"
-                += ( eelem "div"
-                     += sattr "class" "header"
-                   )
-                += ( eelem "div"
-                     += sattr "class" "center"
-                     += ( eelem "div"
-                          += sattr "class" "title"
-                          += getXPathTreesInDoc "/page/pageTitle/*"
-                        )
-                     += ( eelem "div"
-                          += sattr "class" "body"
-                          += getXPathTreesInDoc "/page/body/*"
-                        )
-                   )
-                += ( eelem "div"
-                     += sattr "class" "footer"
-                   )
-                += ( eelem "div"
-                     += sattr "class" "left sideBar"
-                     += ( eelem "div"
-                          += sattr "class" "content"
-                          += getXPathTreesInDoc "/page/sideBar/left/*"
-                        )
-                   )
-                += ( eelem "div"
-                     += sattr "class" "right sideBar"
-                     += ( eelem "div"
-                          += sattr "class" "content"
-                          += getXPathTreesInDoc "/page/sideBar/right/*"
-                        )
-                   )
-              )
-           >>>
-           uniqueNamespacesFromDeclAndQNames
-         )
-
-
-{-
-  <pageNotFound site="CieloNegro"
-                baseURI="http://example.org"
-                name="Foo/Bar">
-
-    <styleSheets>
-      <styleSheet src="http://example.org/object/StyleSheet/Default" />
-    </styleSheets>
-
-    <scripts>
-      <script src="http://example.org/js" />
-    </scripts>
-
-    <pageTitle>
-      blah blah...
-    </pageTitle>
-
-    <sideBar>
-      <left>
-        blah blah...
-      </left>
-      <right>
-        blah blah...
-      </right>
-    </sideBar>
-  </pageNotFound>
--}
-handlePageNotFound :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a PageName (Resource ())
-handlePageNotFound env
-    = proc name
-    -> do tree <- formatUnexistentPage (envStorage env) (envSysConf env) (envInterpTable env) -< name
-          returnA -< do setStatus NotFound
-                        outputXmlPage tree notFoundToXHTML
-
-
-notFoundToXHTML :: ArrowXml a => a XmlTree XmlTree
-notFoundToXHTML
-    = eelem "/"
-      += ( eelem "html"
-           += sattr "xmlns" "http://www.w3.org/1999/xhtml"
-           += ( eelem "head"
-                += ( eelem "title"
-                     += getXPathTreesInDoc "/pageNotFound/@site/text()"
-                     += txt " - "
-                     += getXPathTreesInDoc "/pageNotFound/@name/text()"
-                   )
-                += ( getXPathTreesInDoc "/pageNotFound/styleSheets/styleSheet"
-                     >>>
-                     eelem "link"
-                     += sattr "rel"  "stylesheet"
-                     += sattr "type" "text/css"
-                     += attr "href"
-                            ( getXPathTrees "/styleSheet/@src/text()" )
-                   )
-                += ( getXPathTreesInDoc "/pageNotFound/scripts/script"
-                     >>>
-                     eelem "script"
-                     += sattr "type" "text/javascript"
-                     += attr "src"
-                            ( getXPathTrees "/script/@src/text()" )
-                   )
-              )
-           += ( eelem "body"
-                += ( eelem "div"
-                     += sattr "class" "header"
-                   )
-                += ( eelem "div"
-                     += sattr "class" "center"
-                     += ( eelem "div"
-                          += sattr "class" "title"
-                          += getXPathTreesInDoc "/pageNotFound/pageTitle/*"
-                        )
-                     += ( eelem "div"
-                          += sattr "class" "body"
-                          += txt "404 Not Found (FIXME)" -- FIXME
-                        )
-                   )
-                += ( eelem "div"
-                     += sattr "class" "footer"
-                   )
-                += ( eelem "div"
-                     += sattr "class" "left sideBar"
-                     += ( eelem "div"
-                          += sattr "class" "content"
-                          += getXPathTreesInDoc "/pageNotFound/sideBar/left/*"
-                        )
-                   )
-                += ( eelem "div"
-                     += sattr "class" "right sideBar"
-                     += ( eelem "div"
-                          += sattr "class" "content"
-                          += getXPathTreesInDoc "/pageNotFound/sideBar/right/*"
-                        )
-                   )
-              )
-           >>>
-           uniqueNamespacesFromDeclAndQNames
-         )
index 5dfb462bba6a33d0559c195b5a5cb37147ab06df..af50afbc7adef90939cdba3376cad8bca3de214b 100644 (file)
@@ -74,7 +74,7 @@ data InlineElement
     | LineBreak ![Attribute]
     | Span ![Attribute] ![InlineElement]
     | Image {
-        imgSource :: !PageName
+        imgSource :: !(PageName)
       , imgAlt    :: !(Maybe String)
       }
     | Anchor ![Attribute] ![InlineElement]
index 07eaff4a594ed5c5ff112f1550997e533bffe6df..1f24e37332b96f1f6f093d75546ed73ce385edc2 100644 (file)
@@ -1,14 +1,17 @@
 module Rakka.Wiki.Engine
     ( InterpTable
-    , formatEntirePage
-    , formatUnexistentPage
+    , xmlizePage
+    , makeMainXHTML
+    , makeSubXHTML
     , makeDraft
     )
     where
 
+import qualified Codec.Binary.Base64 as B64
 import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowList
+import qualified Data.ByteString.Lazy as L
 import           Data.Encoding
 import           Data.Encoding.UTF8
 import           Data.Generics
@@ -27,287 +30,206 @@ import           Rakka.Wiki.Formatter
 import           Rakka.Wiki.Interpreter
 import           Text.HyperEstraier hiding (getText)
 import           Text.ParserCombinators.Parsec
-import           Text.XML.HXT.Arrow.Namespace
 import           Text.XML.HXT.Arrow.XmlArrow
+import           Text.XML.HXT.Arrow.XmlNodeSet
 import           Text.XML.HXT.DOM.TypeDefs
 
 
 type InterpTable = Map String Interpreter
 
 
-formatEntirePage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
-                    Storage
-                 -> SystemConfig
-                 -> InterpTable
-                 -> a Page XmlTree
-formatEntirePage sto sysConf interpTable
+{-
+  <page name="Foo/Bar"
+        type="text/x-rakka"
+        lang="ja"            -- 存在しない場合もある
+        fileName="bar.rakka" -- 存在しない場合もある
+        isTheme="no"         -- text/css の場合のみ存在
+        isFeed="no"          -- text/x-rakka の場合のみ存在
+        isLocked="no"
+        isBinary="no"
+        revision="112">      -- デフォルトでない場合のみ存在
+        lastModified="2000-01-01T00:00:00">
+
+    <summary>
+        blah blah...
+    </summary> -- 存在しない場合もある
+
+    <otherLang> -- 存在しない場合もある
+      <link lang="ja" page="Bar/Baz" />
+    </otherLang>
+
+    <!-- 何れか一方のみ -->
+    <textData>
+      blah blah...
+    </textData>
+    <binaryData>
+      SKJaHKS8JK/DH8KS43JDK2aKKaSFLLS...
+    </binaryData>
+  </page>
+-}
+xmlizePage :: (ArrowXml a, ArrowChoice a) => a Page XmlTree
+xmlizePage 
     = proc page
-    -> do SiteName   siteName <- getSysConfA sysConf -< ()
-          BaseURI    baseURI  <- getSysConfA sysConf -< ()
-          StyleSheet cssName  <- getSysConfA sysConf -< ()
-
-          Just pageTitle    <- getPageA sto -< ("PageTitle"    , Nothing)
-          Just leftSideBar  <- getPageA sto -< ("SideBar/Left" , Nothing)
-          Just rightSideBar <- getPageA sto -< ("SideBar/Right", Nothing)
-
-          tree <- ( eelem "/"
-                    += ( eelem "page"
-                         += sattr "site"       siteName
-                         += sattr "baseURI"    (uriToString id baseURI "")
-                         += sattr "name"       (pageName page)
-                         += sattr "type"       (show $ pageType page)
-                         += ( case pageLanguage page of
-                                Just x -> sattr "lang" x
-                                _      -> none
-                            )
-                         += ( case pageFileName page of
-                                Just x -> sattr "fileName" x
-                                _      -> none
-                            )
-                         += ( case pageType page of
-                                MIMEType "text" "css" _
-                                    -> sattr "isTheme" (yesOrNo $ pageIsTheme page)
-                                _   -> none
-                            )
-                         += ( case pageType page of
-                                MIMEType "text" "x-rakka" _
-                                    -> sattr "isFeed" (yesOrNo $ pageIsFeed page)
-                                _   -> none
-                            )
-                         += sattr "isLocked" (yesOrNo $ pageIsLocked page)
-                         += sattr "isBoring" (yesOrNo $ pageIsBoring page)
-                         += sattr "isBinary" (yesOrNo $ pageIsBinary page)
-                         += sattr "revision" (show $ pageRevision page)
-                         += sattr "lastModified" (formatW3CDateTime $ pageLastMod page)
-
-                         += ( eelem "styleSheets"
-                              += ( eelem "styleSheet"
-                                   += sattr "src" (uriToString id (mkObjectURI baseURI cssName) "")
-                                 )
-                            )
-
-                         += ( eelem "scripts"
-                              += ( eelem "script"
-                                   += sattr "src" (uriToString id (baseURI { uriPath = "/js" }) "")
-                                 )
-                            )
-
-                         += ( case pageSummary page of
-                                Nothing -> none
-                                Just s  -> eelem "summary" += txt s
-                            )
-
-                         += ( if M.null (pageOtherLang page) then
-                                  none
-                              else
-                                  selem "otherLang"
-                                            [ eelem "link"
-                                              += sattr "lang" lang
-                                              += sattr "page" page
-                                                  | (lang, page) <- M.toList (pageOtherLang page) ]
-                            )
-                         += ( eelem "pageTitle"
-                              += ( (constA (pageName page) &&& constA (Just page) &&& constA pageTitle)
-                                   >>>
-                                   formatSubPage sto sysConf interpTable
-                                 )
-                            )
-                         += ( eelem "sideBar"
-                              += ( eelem "left"
-                                   += ( (constA (pageName page) &&& constA (Just page) &&& constA leftSideBar)
-                                        >>>
-                                        formatSubPage sto sysConf interpTable
-                                      )
-                                 )
-                              += ( eelem "right"
-                                   += ( (constA (pageName page) &&& constA (Just page) &&& constA rightSideBar)
-                                        >>>
-                                        formatSubPage sto sysConf interpTable
-                                      )
-                                 )
-                            )
-                         += ( eelem "body"
-                              += (constA page >>> formatMainPage sto sysConf interpTable)
-                            )
-                         += (constA page >>> formatSource)
-                         >>>
-                         uniqueNamespacesFromDeclAndQNames
-                       )
-                  ) -<< ()
-          returnA -< tree
-
-
-formatSource :: (ArrowXml a, ArrowChoice a) => a Page XmlTree
-formatSource = proc page
-             -> if pageIsBinary page then
-                    none -< ()
-                else
-                    let source = decodeLazy UTF8 (pageContent page)
-                    in
-                      ( eelem "source" += mkText ) -< source
-
-
-formatUnexistentPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
-                        Storage
-                     -> SystemConfig
-                     -> InterpTable
-                     -> a PageName XmlTree
-formatUnexistentPage sto sysConf interpTable
-    = proc name
-    -> do SiteName   siteName <- getSysConfA sysConf -< ()
-          BaseURI    baseURI  <- getSysConfA sysConf -< ()
-          StyleSheet cssName  <- getSysConfA sysConf -< ()
-
-          Just pageTitle    <- getPageA sto -< ("PageTitle"    , Nothing)
-          Just leftSideBar  <- getPageA sto -< ("SideBar/Left" , Nothing)
-          Just rightSideBar <- getPageA sto -< ("SideBar/Right", Nothing)
-
-          tree <- ( eelem "/"
-                    += ( eelem "pageNotFound"
-                         += sattr "site"    siteName
-                         += sattr "baseURI" (uriToString id baseURI "")
-                         += sattr "name"    name
-
-                         += ( eelem "styleSheets"
-                              += ( eelem "styleSheet"
-                                   += sattr "src" (uriToString id (mkObjectURI baseURI cssName) "")
-                                 )
-                            )
-
-                         += ( eelem "scripts"
-                              += ( eelem "script"
-                                   += sattr "src" (uriToString id (baseURI { uriPath = "/js" }) "")
-                                 )
-                            )
-                         
-                         += ( eelem "pageTitle"
-                              += ( (constA name &&& constA Nothing &&& constA pageTitle)
-                                   >>>
-                                   formatSubPage sto sysConf interpTable
-                                 )
-                            )
-                         += ( eelem "sideBar"
-                              += ( eelem "left"
-                                   += ( (constA name &&& constA Nothing &&& constA leftSideBar)
-                                        >>>
-                                        formatSubPage sto sysConf interpTable
-                                      )
-                                 )
-                              += ( eelem "right"
-                                   += ( (constA name &&& constA Nothing &&& constA rightSideBar)
-                                        >>>
-                                        formatSubPage sto sysConf interpTable
-                                      )
-                                 )
-                            )
-                         >>>
-                         uniqueNamespacesFromDeclAndQNames
-                       )
-                  ) -<< ()
-          returnA -< tree
-
-
-formatMainPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
-                  Storage
-               -> SystemConfig
-               -> InterpTable
-               -> a Page XmlTree
-formatMainPage sto sysConf interpTable
-    = proc page
-    -> do BaseURI baseURI <- getSysConfA sysConf -< ()
-          wiki            <- arr2 wikifyPage -< (interpTable, page)
-          xs              <- interpretCommandsA sto sysConf interpTable
-                             -< (pageName page, Just (page, wiki), wiki)
-          formatWikiBlocks -< (baseURI, xs)
+    -> (eelem "/"
+        += ( eelem "page"
+             += sattr "name" (pageName page)
+             += sattr "type" (show $ pageType page)
+             += ( case pageLanguage page of
+                    Just x  -> sattr "lang" x
+                    Nothing -> none
+                )
+             += ( case pageFileName page of
+                    Just x  -> sattr "fileName" x
+                    Nothing -> none
+                )
+             += ( case pageType page of
+                    MIMEType "text" "css" _
+                        -> sattr "isTheme" (yesOrNo $ pageIsTheme page)
+                    MIMEType "text" "x-rakka" _
+                        -> sattr "isFeed"  (yesOrNo $ pageIsFeed page)
+                    _
+                        -> none
+                )
+             += sattr "isLocked" (yesOrNo $ pageIsLocked page)
+             += sattr "isBoring" (yesOrNo $ pageIsBoring page)
+             += sattr "isBinary" (yesOrNo $ pageIsBinary page)
+             += sattr "revision" (show $ pageRevision page)
+             += sattr "lastModified" (formatW3CDateTime $ pageLastMod page)
+             += ( case pageSummary page of
+                    Just s  -> eelem "summary" += txt s
+                    Nothing -> none
+                )
+             += ( if M.null (pageOtherLang page) then
+                      none
+                  else
+                      selem "otherLang"
+                                [ eelem "link"
+                                  += sattr "lang" lang
+                                  += sattr "page" page
+                                      | (lang, page) <- M.toList (pageOtherLang page) ]
+                )
+             += ( if pageIsBinary page then
+                      ( eelem "binaryData"
+                        += txt (B64.encode $ L.unpack $ pageContent page)
+                      )
+                  else
+                      ( eelem "textData"
+                        += txt (decodeLazy UTF8 $ pageContent page)
+                      )
+                )
+           )
+       ) -<< ()
+
+
+wikifyPage :: (ArrowXml a, ArrowChoice a) => InterpTable -> a XmlTree WikiPage
+wikifyPage interpTable
+    = proc tree
+    -> do pName      <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
+          pType      <- getXPathTreesInDoc "/page/@type/text()" >>> getText >>> arr read -< tree
+          pIsBinary  <- getXPathTreesInDoc "/page/@isBinary/text()" >>> getText -< tree
+          pFileName  <- maybeA (getXPathTreesInDoc "/page/fileName/text()"   >>> getText) -< tree
+          textData   <- maybeA (getXPathTreesInDoc "/page/textData/text()"   >>> getText) -< tree
+
+          case pType of
+            MIMEType "text" "x-rakka" _
+                -> case parse (wikiPage cmdTypeOf) "" (fromJust textData) of
+                     Left err -> wikifyParseError -< err
+                     Right xs -> returnA -< xs
+
+            MIMEType "image" _ _
+                -> returnA -< [ Paragraph [Image pName Nothing] ]
+
+            _   -> if pIsBinary == "yes" then
+                       returnA -< [ Paragraph [ ObjectLink {
+                                                  objLinkPage = pName
+                                                , objLinkText = Just $ fromMaybe (defaultFileName pType pName) pFileName
+                                                }
+                                              ]
+                                  ]
+                   else
+                       -- pre
+                       returnA -< [ Preformatted [Text $ fromJust textData] ]
+    where
+      cmdTypeOf :: String -> Maybe CommandType
+      cmdTypeOf name
+          = fmap commandType (M.lookup name interpTable)
+
+      binToURI :: MIMEType -> String -> URI
+      binToURI pType base64Data
+          = nullURI {
+              uriScheme = "data:"
+            , uriPath   = show pType ++ ";base64," ++ (stripWhiteSpace base64Data)
+            }
+
+      stripWhiteSpace :: String -> String
+      stripWhiteSpace []     = []
+      stripWhiteSpace (x:xs)
+          | x `elem` " \t\n" = stripWhiteSpace xs
+          | otherwise        = x : stripWhiteSpace xs
 
 
-formatSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+makeMainXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
                  Storage
               -> SystemConfig
               -> InterpTable
-              -> a (PageName, (Maybe Page, Page)) XmlTree
-formatSubPage sto sysConf interpTable
-    = proc (mainPageName, (mainPage, subPage))
+              -> a XmlTree XmlTree
+makeMainXHTML sto sysConf interpTable
+    = proc tree
+    -> do BaseURI baseURI <- getSysConfA sysConf -< ()
+          wiki            <- wikifyPage interpTable -< tree
+          pName           <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
+          interpreted     <- interpretCommands sto sysConf interpTable
+                             -< (pName, Just (tree, wiki), wiki)
+          formatWikiBlocks -< (baseURI, interpreted)
+
+
+makeSubXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+                Storage
+             -> SystemConfig
+             -> InterpTable
+             -> a (PageName, Maybe XmlTree, XmlTree) XmlTree
+makeSubXHTML sto sysConf interpTable
+    = proc (mainPageName, mainPage, subPage)
     -> do BaseURI baseURI <- getSysConfA sysConf -< ()
           mainWiki        <- case mainPage of
                                Just page
-                                   -> do wiki <- arr2 wikifyPage -< (interpTable, page)
+                                   -> do wiki <- wikifyPage interpTable -< page
                                          returnA -< Just (page, wiki)
                                Nothing
                                    -> returnA -< Nothing
-          subWiki        <- arr2 wikifyPage -< (interpTable, subPage)
-          xs             <- interpretCommandsA sto sysConf interpTable
-                            -< (mainPageName, mainWiki, subWiki)
-          formatWikiBlocks -< (baseURI, xs)
-
-
-wikifyPage :: InterpTable -> Page -> WikiPage
-wikifyPage interpTable page
-    = case pageType page of
-        MIMEType "text" "x-rakka" _
-            -> let source = decodeLazy UTF8 (pageContent page)
-                   parser = wikiPage tableToFunc
-               in
-                 case parse parser "" source of
-                   Left err -> wikifyParseError err
-                   Right xs -> xs
-
-        MIMEType "image" _ _
-            -> [ Paragraph [ Image (pageName page) Nothing ] ]
-
-        _   -> if pageIsBinary page then
-                   -- object へのリンクのみ
-                   [ Paragraph [ ObjectLink (pageName page) (Just $ pageFileName' page) ] ]
-               else
-                   -- pre
-                   let text = decodeLazy UTF8 (pageContent page)
-                   in
-                     [ Preformatted [ Text text ] ]
-    where
-      tableToFunc :: String -> Maybe CommandType
-      tableToFunc name
-          = fmap commandType (M.lookup name interpTable)
-
+          subWiki         <- wikifyPage interpTable -< subPage
+          interpreted     <- interpretCommands sto sysConf interpTable
+                             -< (mainPageName, mainWiki, subWiki)
+          formatWikiBlocks -< (baseURI, interpreted)
 
-interpretCommandsA :: (ArrowIO a, ArrowApply a) =>
-                      Storage
-                   -> SystemConfig
-                   -> InterpTable
-                   -> a (PageName, Maybe (Page, WikiPage), WikiPage) WikiPage
-interpretCommandsA sto sysConf interpTable
-    = proc (name, mainPageAndTree, targetTree)
-    -> arrIO0 (interpretCommands sto sysConf interpTable name mainPageAndTree targetTree) 
-       -<< ()
 
-
-interpretCommands :: Storage
+interpretCommands :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
+                     Storage
                   -> SystemConfig
                   -> InterpTable
-                  -> PageName
-                  -> Maybe (Page, WikiPage)
-                  -> WikiPage
-                  -> IO WikiPage
-interpretCommands sto sysConf interpTable name mainPageAndTree targetTree
-    = everywhereM' (mkM interpBlockCmd) targetTree
-      >>=
-      everywhereM' (mkM interpInlineCmd)
+                  -> a (PageName, Maybe (XmlTree, WikiPage), WikiPage) WikiPage
+interpretCommands sto sysConf interpTable
+    = proc (name, mainPageAndWiki, targetWiki)
+    -> let ctx = InterpreterContext {
+                   ctxPageName   = name
+                 , ctxMainPage   = fmap fst mainPageAndWiki
+                 , ctxMainWiki   = fmap snd mainPageAndWiki
+                 , ctxTargetWiki = targetWiki
+                 , ctxStorage    = sto
+                 , ctxSysConf    = sysConf
+                 }
+       in
+         ( arrIO (everywhereM' (mkM $ interpBlockCmd ctx))
+           >>>
+           arrIO (everywhereM' (mkM $ interpInlineCmd ctx))
+         ) -<< targetWiki
     where
-      ctx :: InterpreterContext
-      ctx = InterpreterContext {
-              ctxPageName   = name
-            , ctxMainPage   = fmap fst mainPageAndTree
-            , ctxMainTree   = fmap snd mainPageAndTree
-            , ctxTargetTree = targetTree
-            , ctxStorage    = sto
-            , ctxSysConf    = sysConf
-            }
-
-      interpBlockCmd :: BlockElement -> IO BlockElement
-      interpBlockCmd (BlockCmd cmd) = interpBlockCmd' cmd
-      interpBlockCmd others         = return others
+      interpBlockCmd :: InterpreterContext -> BlockElement -> IO BlockElement
+      interpBlockCmd ctx (BlockCmd cmd) = interpBlockCmd' ctx cmd
+      interpBlockCmd _   others         = return others
 
-      interpBlockCmd' :: BlockCommand -> IO BlockElement
-      interpBlockCmd' cmd
+      interpBlockCmd' :: InterpreterContext -> BlockCommand -> IO BlockElement
+      interpBlockCmd' ctx cmd
           = case M.lookup (bCmdName cmd) interpTable of
               Nothing
                   -> fail ("no such interpreter: " ++ bCmdName cmd)
@@ -316,12 +238,12 @@ interpretCommands sto sysConf interpTable name mainPageAndTree targetTree
                   -> bciInterpret interp ctx cmd
 
 
-      interpInlineCmd :: InlineElement -> IO InlineElement
-      interpInlineCmd (InlineCmd cmd) = interpInlineCmd' cmd
-      interpInlineCmd others          = return others
+      interpInlineCmd :: InterpreterContext -> InlineElement -> IO InlineElement
+      interpInlineCmd ctx (InlineCmd cmd) = interpInlineCmd' ctx cmd
+      interpInlineCmd _   others          = return others
 
-      interpInlineCmd' :: InlineCommand -> IO InlineElement
-      interpInlineCmd' cmd
+      interpInlineCmd' :: InterpreterContext -> InlineCommand -> IO InlineElement
+      interpInlineCmd' ctx cmd
           = case M.lookup (iCmdName cmd) interpTable of
               Nothing
                   -> fail ("no such interpreter: " ++ iCmdName cmd)
@@ -330,45 +252,67 @@ interpretCommands sto sysConf interpTable name mainPageAndTree targetTree
                   -> iciInterpret interp ctx cmd
 
 
-makeDraft :: InterpTable -> Page -> IO Document
-makeDraft interpTable page
-    = do doc <- newDocument
-
-         setURI       doc                  $ Just $ mkRakkaURI $ pageName page
-         setAttribute doc "@title"         $ Just $ pageName page
-         setAttribute doc "@lang"          $ pageLanguage page
-         setAttribute doc "@type"          $ Just $ show $ pageType page
-         setAttribute doc "@mdate"         $ Just $ formatW3CDateTime $ pageLastMod page
-         setAttribute doc "rakka:fileName" $ pageFileName page
-         setAttribute doc "rakka:isLocked" $ Just $ yesOrNo $ pageIsLocked page
-         setAttribute doc "rakka:isBoring" $ Just $ yesOrNo $ pageIsBoring page
-         setAttribute doc "rakka:isBinary" $ Just $ yesOrNo $ pageIsBinary page
-         setAttribute doc "rakka:revision" $ Just $ show $ pageRevision page
-         setAttribute doc "rakka:summary"  $ pageSummary page
-
-         addHiddenText doc (pageName page)
-
-         case pageType page of
-            MIMEType "text" "css" _
-                -> setAttribute doc "rakka:isTheme" $ Just $ yesOrNo $ pageIsTheme page
-            MIMEType "text" "x-rakka" _
-                -> setAttribute doc "rakka:isFeed"  $ Just $ yesOrNo $ pageIsFeed page
-            _   -> return ()
-
-         case pageSummary page of
-           Nothing -> return ()
-           Just s  -> addHiddenText doc s
+makeDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => InterpTable -> a XmlTree Document
+makeDraft interpTable
+    = proc tree ->
+      do doc <- arrIO0 newDocument -< ()
+         
+         pName     <- getXPathTreesInDoc "/page/@name/text()"         >>> getText -< tree
+         pType     <- getXPathTreesInDoc "/page/@type/text()"         >>> getText -< tree
+         pLastMod  <- getXPathTreesInDoc "/page/@lastModified/text()" >>> getText -< tree
+         pIsLocked <- getXPathTreesInDoc "/page/@isLocked/text()"     >>> getText -< tree
+         pIsBoring <- getXPathTreesInDoc "/page/@isBoring/text()"     >>> getText -< tree
+         pIsBinary <- getXPathTreesInDoc "/page/@isBinary/text()"     >>> getText -< tree
+         pRevision <- getXPathTreesInDoc "/page/@revision/text()"     >>> getText -< tree
+         pLang     <- maybeA (getXPathTreesInDoc "/page/@lang/text()"     >>> getText) -< tree
+         pFileName <- maybeA (getXPathTreesInDoc "/page/@fileName/text()" >>> getText) -< tree
+         pIsTheme  <- maybeA (getXPathTreesInDoc "/page/@isTheme/text()"  >>> getText) -< tree
+         pIsFeed   <- maybeA (getXPathTreesInDoc "/page/@isFeed/text()"   >>> getText) -< tree
+         pSummary  <- maybeA (getXPathTreesInDoc "/page/summary/text()"   >>> getText) -< tree
+
+         arrIO2 setURI                               -< (doc, Just $ mkRakkaURI pName)
+         arrIO2 (flip setAttribute "@title"        ) -< (doc, Just pName)
+         arrIO2 (flip setAttribute "@type"         ) -< (doc, Just pType)
+         arrIO2 (flip setAttribute "@mdate"        ) -< (doc, Just pLastMod)
+         arrIO2 (flip setAttribute "@lang"         ) -< (doc, pLang)
+         arrIO2 (flip setAttribute "rakka:fileName") -< (doc, pFileName)
+         arrIO2 (flip setAttribute "rakka:isLocked") -< (doc, Just pIsLocked)
+         arrIO2 (flip setAttribute "rakka:isBoring") -< (doc, Just pIsBoring)
+         arrIO2 (flip setAttribute "rakka:isBinary") -< (doc, Just pIsBinary)
+         arrIO2 (flip setAttribute "rakka:revision") -< (doc, Just pRevision)
+         arrIO2 (flip setAttribute "rakka:summary" ) -< (doc, pSummary)
+
+         arrIO2 addHiddenText -< (doc, pName)
+
+         case pSummary of
+           Just s  -> arrIO2 addHiddenText -< (doc, s)
+           Nothing -> returnA -< ()
 
          -- otherLang はリンク先ページ名を hidden text で入れる。
-         sequence_ [ addHiddenText doc x
-                         | (_, x) <- M.toList (pageOtherLang page) ]
-
-         -- wikify して興味のある部分を addText する。
-         let wikiPage = wikifyPage interpTable page
-         everywhereM' (mkM (addBlockText  doc)) wikiPage
-         everywhereM' (mkM (addInlineText doc)) wikiPage
-
-         return doc
+         otherLangs <- listA (getXPathTreesInDoc "/page/otherLang/link/@page/text()" >>> getText) -< tree
+         listA ( (arr fst &&& arrL snd)
+                 >>>
+                 arrIO2 addHiddenText
+                 >>>
+                 none
+               ) -< (doc, otherLangs)
+
+         case read pType of
+           MIMEType "text" "css" _
+               -> arrIO2 (flip setAttribute "rakka:isTheme") -< (doc, pIsTheme)
+           
+           MIMEType "text" "x-rakka" _
+               -- wikify して興味のある部分を addText する。
+               -> do arrIO2 (flip setAttribute "rakka:isFeed") -< (doc, pIsFeed)
+                     wikiPage <- wikifyPage interpTable -< tree
+                     arrIO0 (everywhereM' (mkM (addBlockText  doc)) wikiPage) -<< ()
+                     arrIO0 (everywhereM' (mkM (addInlineText doc)) wikiPage) -<< ()
+                     returnA -< ()
+
+           MIMEType _ _ _
+               -> returnA -< ()
+
+         returnA -< doc
     where
       addBlockText :: Document -> BlockElement -> IO BlockElement
       addBlockText doc b
@@ -403,13 +347,12 @@ makeDraft interpTable page
                  _   -> return ()
                return i
 
-
 -- Perform monadic transformation in top-down order.
 everywhereM' :: Monad m => GenericM m -> GenericM m
 everywhereM' f x = f x >>= gmapM (everywhereM' f)
 
 
-wikifyParseError :: ParseError -> WikiPage
-wikifyParseError err
-    = [Div [("class", "error")]
-               [ Block (Preformatted [Text (show err)]) ]]
+wikifyParseError :: Arrow a => a ParseError WikiPage
+wikifyParseError = proc err
+                 -> returnA -< [Div [("class", "error")]
+                                [ Block (Preformatted [Text (show err)]) ]]
index 983673bf9614867a619f211e136a7b5980ce6d54..969c228a756ad93d269ff8d69d219466ece5bd99 100644 (file)
@@ -5,7 +5,6 @@ module Rakka.Wiki.Formatter
 
 import           Control.Arrow
 import           Control.Arrow.ArrowList
-import           Control.Arrow.ArrowTree
 import           Data.Char
 import           Data.List
 import           Data.Maybe
@@ -21,7 +20,7 @@ formatWikiBlocks
     = proc (baseURI, blocks)
     -> do block   <- arrL id     -< blocks
           tree    <- formatBlock -< (baseURI, block)
-          attachXHtmlNs -< tree
+          returnA -< tree
 
 
 formatElement :: (ArrowXml a, ArrowChoice a) => a (URI, Element) XmlTree
@@ -241,8 +240,8 @@ formatPageLink
 
 
 formatImage :: (ArrowXml a) => a (URI, InlineElement) XmlTree
-formatImage = proc (baseURI, Image name alt)
-            -> let uri  = mkObjectURI baseURI name
+formatImage = proc (baseURI, Image src alt)
+            -> let uri  = mkObjectURI baseURI src
                    href = uriToString id uri ""
                in
                  ( eelem "img"
@@ -267,13 +266,3 @@ mkAnchor :: (ArrowXml a) => a (String, String) XmlTree
 mkAnchor = eelem "a"
            += attr "href" (arr fst >>> mkText)
            += (arr snd >>> mkText)
-
-
-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"
-                   }
index ad951f80a668beabf59cfea1f8f2d9796a763407..9c40816e47519aedf6ac27a7731f7e8b20dee4f6 100644 (file)
@@ -11,6 +11,7 @@ import           Rakka.Page
 import           Rakka.Storage
 import           Rakka.SystemConfig
 import           Rakka.Wiki
+import           Text.XML.HXT.DOM.TypeDefs
 
 
 data Interpreter
@@ -27,9 +28,9 @@ data Interpreter
 data InterpreterContext
     = InterpreterContext {
         ctxPageName   :: !PageName
-      , ctxMainPage   :: !(Maybe Page)
-      , ctxMainTree   :: !(Maybe WikiPage)
-      , ctxTargetTree :: !WikiPage
+      , ctxMainPage   :: !(Maybe XmlTree)
+      , ctxMainWiki   :: !(Maybe WikiPage)
+      , ctxTargetWiki :: !WikiPage
       , ctxStorage    :: !Storage
       , ctxSysConf    :: !SystemConfig
       }
index 38578c0e590b53d4deb396a7a5da66476dbc84ef..9a02ae255668be349716a141300996bbe74aba1c 100644 (file)
@@ -3,6 +3,8 @@ module Rakka.Wiki.Interpreter.Base
     )
     where
 
+import           Control.Arrow
+import           Control.Arrow.ListArrow
 import           Data.Map (Map)
 import qualified Data.Map as M
 import           Data.Maybe
@@ -11,6 +13,8 @@ import           Rakka.Page
 import           Rakka.SystemConfig
 import           Rakka.Wiki
 import           Rakka.Wiki.Interpreter
+import           Text.XML.HXT.Arrow.XmlArrow
+import           Text.XML.HXT.Arrow.XmlNodeSet
 
 
 interpreters :: [Interpreter]
@@ -62,14 +66,21 @@ otherLangsInterp
         bciName      = "inOtherLanguages"
       , bciInterpret
           = \ ctx _ ->
-            case fmap pageOtherLang (ctxMainPage ctx) of
-              Nothing
-                -> return EmptyBlock
-
-              Just linkTable
-                  -> do Languages langTable <- getSysConf (ctxSysConf ctx)
-                        let merged = mergeTables langTable (M.toList linkTable)
-                        return $ mkLangList merged
+            let linkTable = case ctxMainPage ctx of
+                              Just page -> runLA ( getXPathTreesInDoc "/page/otherLang/link"
+                                                   >>>
+                                                   ( getAttrValue0 "lang"
+                                                     &&&
+                                                     getAttrValue0 "page"
+                                                   )
+                                                 ) page
+                              Nothing   -> []
+            in
+              case linkTable of
+                [] -> return EmptyBlock
+                xs -> do Languages langTable <- getSysConf (ctxSysConf ctx)
+                         let merged = mergeTables langTable linkTable
+                         return $ mkLangList merged
       }
     where
       mergeTables :: Map LanguageTag LanguageName
index eb8c9d4db095b3b1d2e8e14edcabf9a65b7c8664..16ed0c5f7999ad52670df7398ca10e41f8a7b647 100644 (file)
@@ -17,7 +17,7 @@ outlineInterp = BlockCommandInterpreter {
                   bciName      = "outline"
                 , bciInterpret
                     = \ ctx _ ->
-                      case ctxMainTree ctx of
+                      case ctxMainWiki ctx of
                         Just tree -> return $ Div [("class", "outline")] [Block $ mkOutline tree]
                         Nothing   -> return EmptyBlock
                 }
index ecd61b78d4f84bf033601f324082083609279190..3fefe6ca38bff6a5fa7971f4405bf07b4fbae2d1 100644 (file)
         </attribute>
       </optional>
 
-      <optional>
-        <attribute name="filename">
-          <text />
-        </attribute>
-      </optional>
-
       <optional>
         <!-- text/css でなければ無視される -->
         <attribute name="isTheme">