module Rakka.Page ( PageName , Page(..) , LanguageTag , LanguageName , encodePageName , decodePageName , mkPageURI , mkPageFragmentURI , mkObjectURI , mkAuxiliaryURI , mkRakkaURI ) where import Data.ByteString.Base (LazyByteString) import qualified Data.ByteString.Char8 as C8 import Data.Encoding import Data.Encoding.UTF8 import Data.Map (Map) import Network.HTTP.Lucu import Network.URI import Subversion.Types import System.FilePath import System.Time type PageName = String type LanguageTag = String -- See RFC 3066: http://www.ietf.org/rfc/rfc3066.txt type LanguageName = String -- i.e. "日本語" data Page = Redirection { redirName :: !PageName , redirDest :: !PageName , redirRevision :: !(Maybe RevNum) , redirLastMod :: !CalendarTime } | Entity { pageName :: !PageName , pageType :: !MIMEType , pageLanguage :: !(Maybe LanguageTag) , pageIsTheme :: !Bool -- text/css 以外では無意味 , pageIsFeed :: !Bool -- text/x-rakka 以外では無意味 , pageIsLocked :: !Bool , pageIsBoring :: !Bool , pageIsBinary :: !Bool , pageRevision :: !RevNum , pageLastMod :: !CalendarTime , pageSummary :: !(Maybe String) , pageOtherLang :: !(Map LanguageTag PageName) , pageContent :: !LazyByteString } -- UTF-8 に encode してから 0x20 - 0x7E の範圍を除いて URI escape する。 encodePageName :: PageName -> FilePath encodePageName = escapeURIString isSafe . C8.unpack . encode UTF8 where isSafe :: Char -> Bool isSafe c | c == '/' = True | isReserved c = False | c >= ' ' && c <= '~' = True | otherwise = False -- URI unescape して UTF-8 から decode する。 decodePageName :: FilePath -> PageName decodePageName = decode UTF8 . C8.pack . unEscapeString mkPageURI :: URI -> PageName -> URI mkPageURI baseURI name = baseURI { uriPath = foldl combine "/" [uriPath baseURI, encodePageName name ++ ".html"] } mkPageFragmentURI :: URI -> PageName -> String -> URI mkPageFragmentURI baseURI name fragment = baseURI { uriPath = foldl combine "/" [uriPath baseURI, encodePageName name ++ ".html"] , uriFragment = ('#':fragment) } mkObjectURI :: URI -> PageName -> URI mkObjectURI baseURI name = mkAuxiliaryURI baseURI ["object"] name mkAuxiliaryURI :: URI -> [String] -> PageName -> URI mkAuxiliaryURI baseURI basePath name = baseURI { uriPath = foldl combine "/" ([uriPath baseURI] ++ basePath ++ [encodePageName name]) } mkRakkaURI :: PageName -> URI mkRakkaURI name = URI { uriScheme = "rakka:" , uriAuthority = Nothing , uriPath = encodePageName name , uriQuery = "" , uriFragment = "" }