diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,41 @@
-Version 0.10.0.2 released 1 Nov 2012
+Version 0.10.1 released 31 Dec 2012
+
+*   Fixed duplicate dropExtension on categoryPage.  (atsuo yamada)
+    This created problems with categories containing periods.
+
+*   Fixed duplicate unescaping of HTML entities. (atsuo yamada)
+
+*   Supply $revision$ at _diff if "Changes from beginning to..."
+    (atsuo yamada)
+
+*   MathJax rendering is now working in edit preview mode
+    (Dmitry Gerasimov).
+
+*   Upgrade directory package dependency to 1.2, and
+    fix compilation issue with GHC 7.6.1 (Bin Jin).
+
+*   Allow metadata keys to include digits, _, -.  Closes #328.
+
+*   Don't read config for --help or --version (Ben Millwood).
+    Also involves a refactor of options into those that make the program
+    quit immediately, and those that just alter the configuration.
+
+*   Updated to use filestore 0.6 (new diff API).
+    Thanks to markwright for partial patch.
+
+*   Include format metadata in default installed pages.
+    This allows them to continue working when the user changes the
+    default page format.  Closes #329.
+
+*   Added explicit path to Gitit User's Guide in default front page.
+
+*   Fix Gitit User's Guide link on front page.
+    Previously it was broken due to "smart punctuation."
+
+*   Fixed validation messages.  Switched from using lookRead "messages"
+    to using looks "message" for messages.  Closes #294.
+
+Version 0.10.0.2 released 02 Nov 2012
 
 *   Raised version bounds for dependencies.
 
diff --git a/Network/Gitit/Cache.hs b/Network/Gitit/Cache.hs
--- a/Network/Gitit/Cache.hs
+++ b/Network/Gitit/Cache.hs
@@ -27,7 +27,7 @@
 import qualified Data.ByteString as B (ByteString, readFile, writeFile)
 import System.FilePath
 import System.Directory (doesFileExist, removeFile, createDirectoryIfMissing, getModificationTime)
-import System.Time (ClockTime)
+import Data.Time.Clock (UTCTime)
 import Network.Gitit.State
 import Network.Gitit.Types
 import Control.Monad
@@ -53,7 +53,7 @@
     exists <- doesFileExist pdfname
     when exists $ removeFile pdfname
 
-lookupCache :: String -> GititServerPart (Maybe (ClockTime, B.ByteString))
+lookupCache :: String -> GititServerPart (Maybe (UTCTime, B.ByteString))
 lookupCache file = do
   cfg <- getConfig
   let target = encodeString $ cacheDir cfg </> file
diff --git a/Network/Gitit/Framework.hs b/Network/Gitit/Framework.hs
--- a/Network/Gitit/Framework.hs
+++ b/Network/Gitit/Framework.hs
@@ -322,21 +322,21 @@
     mzero
 
 -- | Runs a server monad in a local context after setting
--- the "messages" request header.
+-- the "message" request header.
 withMessages :: ServerMonad m => [String] -> m a -> m a
 withMessages messages handler = do
   req <- askRq
-  let inps = filter (\(n,_) -> n /= "messages") $ rqInputsQuery req
-  let newInp = ("messages", Input {
+  let inps = filter (\(n,_) -> n /= "message") $ rqInputsQuery req
+  let newInp msg = ("message", Input {
                               inputValue = Right
-                                         $ LazyUTF8.fromString $ show messages
+                                         $ LazyUTF8.fromString msg
                             , inputFilename = Nothing
                             , inputContentType = ContentType {
                                     ctType = "text"
                                   , ctSubtype = "plain"
                                   , ctParameters = [] }
                             })
-  localRq (\rq -> rq{ rqInputsQuery = newInp : inps }) handler
+  localRq (\rq -> rq{ rqInputsQuery = map newInp messages ++ inps }) handler
 
 -- | Returns a filestore object derived from the
 -- repository path and filestore type specified in configuration.
diff --git a/Network/Gitit/Handlers.hs b/Network/Gitit/Handlers.hs
--- a/Network/Gitit/Handlers.hs
+++ b/Network/Gitit/Handlers.hs
@@ -64,7 +64,6 @@
         exportPage, showHighlightedSource, preview, applyPreCommitPlugins)
 import Network.Gitit.Page (readCategories)
 import Control.Exception (throwIO, catch, try)
-import System.Time
 import System.FilePath
 import Prelude hiding (catch)
 import Network.Gitit.State
@@ -78,7 +77,7 @@
 import qualified Data.ByteString.Lazy as B
 import qualified Data.ByteString as S
 import Network.HTTP (urlEncodeVars)
-import Data.Time (getCurrentTime, addUTCTime)
+import Data.Time.Clock
 import Data.FileStore
 import System.Log.Logger (logM, Priority(..))
 
@@ -117,9 +116,9 @@
   if null pages
      then error "No pages found!"
      else do
-       TOD _ picosecs <- liftIO getClockTime
+       secs <- liftIO (fmap utctDayTime getCurrentTime)
        let newPage = pages !!
-                     ((fromIntegral picosecs `div` 1000000) `mod` length pages)
+                     (truncate (secs * 1000000) `mod` length pages)
        seeOther (base' ++ urlForPage newPage) $ toResponse $
          p << "Redirecting to a random page"
 
@@ -460,7 +459,7 @@
        Left e         -> liftIO $ throwIO e
        Right htmlDiff -> formattedPage defaultPageLayout{
                                           pgPageName = page,
-                                          pgRevision = from',
+                                          pgRevision = from' `mplus` to,
                                           pgMessages = pMessages params,
                                           pgTabs = DiffTab :
                                                    pgTabs defaultPageLayout,
@@ -472,9 +471,9 @@
         -> IO Html
 getDiff fs file from to = do
   rawDiff <- diff fs file from to
-  let diffLineToHtml (B, xs) = thespan << unlines xs
-      diffLineToHtml (F, xs) = thespan ! [theclass "deleted"] << unlines xs
-      diffLineToHtml (S, xs) = thespan ! [theclass "added"]   << unlines xs
+  let diffLineToHtml (Both xs _) = thespan << unlines xs
+      diffLineToHtml (First xs) = thespan ! [theclass "deleted"] << unlines xs
+      diffLineToHtml (Second xs) = thespan ! [theclass "added"]  << unlines xs
   return $ h2 ! [theclass "revision"] <<
              ("Changes from " ++ fromMaybe "beginning" from ++
               " to " ++ fromMaybe "current" to) +++
@@ -541,6 +540,7 @@
   let pgScripts'' = case mathMethod cfg of
        JsMathScript -> "jsMath/easy/load.js" : pgScripts'
        MathML       -> "MathMLinHTML.js" : pgScripts'
+       MathJax url  -> url : pgScripts'
        _            -> pgScripts'
   formattedPage defaultPageLayout{
                   pgPageName = page,
@@ -704,7 +704,7 @@
              forM pages $ \f -> do
                categories <- liftIO $ readCategories $ repoPath </> f
                return $ if category `elem` categories
-                           then Just $ dropExtension f
+                           then Just f
                            else Nothing
   base' <- getWikiBase
   let toMatchListItem file = li <<
@@ -768,9 +768,8 @@
   let file = (path' `orIfNull` "_site") <.> "feed"
   let mbPath = if null path' then Nothing else Just path'
   -- first, check for a cached version that is recent enough
-  now <- liftIO $ getClockTime
-  let isRecentEnough t = normalizeTimeDiff (diffClockTimes now t) <
-                         normalizeTimeDiff (noTimeDiff{tdMin = fromIntegral $ feedRefreshTime cfg})
+  now <- liftIO $ getCurrentTime
+  let isRecentEnough t = truncate (diffUTCTime now t) < 60 * feedRefreshTime cfg
   mbCached <- lookupCache file
   case mbCached of
        Just (modtime, contents) | isRecentEnough modtime -> do
diff --git a/Network/Gitit/Initialize.hs b/Network/Gitit/Initialize.hs
--- a/Network/Gitit/Initialize.hs
+++ b/Network/Gitit/Initialize.hs
@@ -142,11 +142,16 @@
     let helpcontents = helpcontentsInitial ++ "\n\n" ++ helpcontentsMarkup
     usersguidepath <- getDataFileName "README.markdown"
     usersguidecontents <- liftM converter $ readFileUTF8 usersguidepath
+    -- include header in case user changes default format:
+    let header = "---\nformat: markdown\n...\n\n"
     -- add front page, help page, and user's guide
     let auth = Author "Gitit" ""
-    createIfMissing fs (frontPage conf <.> "page") auth "Default front page" welcomecontents
-    createIfMissing fs "Help.page" auth "Default help page" helpcontents
-    createIfMissing fs "Gitit User's Guide.page" auth "User's guide (README)" usersguidecontents
+    createIfMissing fs (frontPage conf <.> "page") auth "Default front page"
+      $ header ++ welcomecontents
+    createIfMissing fs "Help.page" auth "Default help page"
+      $ header ++ helpcontents
+    createIfMissing fs "Gitit User’s Guide.page" auth "User’s guide (README)"
+      $ header ++ usersguidecontents
 
 createIfMissing :: FileStore -> FilePath -> Author -> Description -> String -> IO ()
 createIfMissing fs p a comm cont = do
diff --git a/Network/Gitit/Page.hs b/Network/Gitit/Page.hs
--- a/Network/Gitit/Page.hs
+++ b/Network/Gitit/Page.hs
@@ -88,7 +88,9 @@
 
 pMetadataLine :: GenParser Char st (String, String)
 pMetadataLine = try $ do
-  ident <- many1 letter
+  first <- letter
+  rest <- many (letter <|> digit <|> oneOf "-_")
+  let ident = first:rest
   skipMany (oneOf " \t")
   _ <- char ':'
   rawval <- many $ noneOf "\n\r"
diff --git a/Network/Gitit/Types.hs b/Network/Gitit/Types.hs
--- a/Network/Gitit/Types.hs
+++ b/Network/Gitit/Types.hs
@@ -300,7 +300,7 @@
 
 instance FromData Params where
      fromData = do
-         let look' = liftM fromEntities . look
+         let look' = look
          un <- look' "username"       `mplus` return ""
          pw <- look' "password"       `mplus` return ""
          p2 <- look' "password2"      `mplus` return ""
@@ -316,7 +316,7 @@
          pa <- look' "patterns"       `mplus` return ""
          gt <- look' "gotopage"       `mplus` return ""
          ft <- look' "filetodelete"   `mplus` return ""
-         me <- lookRead "messages"   `mplus` return []
+         me <- looks "message"
          fm <- liftM Just (look' "from") `mplus` return Nothing
          to <- liftM Just (look' "to")   `mplus` return Nothing
          et <- liftM (Just . filter (/='\r')) (look' "editedText")
diff --git a/data/FrontPage.page b/data/FrontPage.page
--- a/data/FrontPage.page
+++ b/data/FrontPage.page
@@ -8,5 +8,5 @@
 
 Help is always available through the "Help" link in the sidebar.
 More details on installing and configurating gitit are available
-in the [Gitit User's Guide]().
+in the [Gitit User’s Guide]().
 
diff --git a/data/static/js/preview.js b/data/static/js/preview.js
--- a/data/static/js/preview.js
+++ b/data/static/js/preview.js
@@ -10,6 +10,12 @@
         if (typeof(convert) == 'function') { convert(); }
         // Process any mathematics if we're using jsMath
         if (typeof(jsMath) == 'object')    { jsMath.ProcessBeforeShowing(); }
+        // Process any mathematics if we're using MathJax
+        if (typeof(window.MathJax) == 'object') {
+          // http://docs.mathjax.org/en/latest/typeset.html
+          var math = document.getElementById("MathExample");
+          MathJax.Hub.Queue(["Typeset",MathJax.Hub,math]);
+        }
       },
       "html");
 
diff --git a/gitit.cabal b/gitit.cabal
--- a/gitit.cabal
+++ b/gitit.cabal
@@ -1,5 +1,5 @@
 name:                gitit
-version:             0.10.0.2
+version:             0.10.1
 Cabal-version:       >= 1.6
 build-type:          Simple
 synopsis:            Wiki using happstack, git or darcs, and pandoc.
@@ -138,7 +138,7 @@
                      pandoc-types >= 1.9.0.2 && < 1.10,
                      process,
                      filepath,
-                     directory,
+                     directory >= 1.2,
                      mtl,
                      cgi,
                      old-time,
@@ -154,7 +154,7 @@
                      old-locale >= 1,
                      time >= 1.1 && < 1.5,
                      recaptcha >= 0.1,
-                     filestore >= 0.5 && < 0.6,
+                     filestore >= 0.6 && < 0.7,
                      zlib >= 0.5 && < 0.6,
                      url >= 2.1 && < 2.2,
                      happstack-server >= 7.0 && < 7.2,
diff --git a/gitit.hs b/gitit.hs
--- a/gitit.hs
+++ b/gitit.hs
@@ -24,6 +24,7 @@
 import Network.Gitit.Util (readFileUTF8)
 import System.Directory
 import Data.Maybe (isNothing)
+import Control.Monad.Error()
 import Control.Monad.Reader
 import System.Log.Logger (Priority(..), setLevel, setHandlers,
         getLogger, saveGlobalLogger)
@@ -44,7 +45,19 @@
 main = do
 
   -- parse options to get config file
-  opts <- getArgs >>= parseArgs
+  args <- getArgs >>= parseArgs
+
+  -- sequence in Either monad gets first Left or all Rights
+  opts <- case sequence args of
+    Left Help -> putErr ExitSuccess =<< usageMessage
+    Left Version -> do
+        progname <- getProgName
+        putErr ExitSuccess (progname ++ " version " ++
+            showVersion version ++ compileInfo ++ copyrightMessage)
+    Left PrintDefaultConfig -> getDataFileName "data/default.conf" >>=
+        readFileUTF8 >>= B.putStrLn . fromString >> exitWith ExitSuccess
+    Right xs -> return xs
+
   defaultConfig <- getDefaultConfig
   conf <- foldM handleFlag defaultConfig opts
   -- check for external programs that are needed
@@ -91,31 +104,35 @@
                                , dir "_reloadTemplates" reloadTemplates
                                ]
 
-data Opt
+data ExitOpt
     = Help
-    | ConfigFile FilePath
-    | Port Int
-	| Listen String
-    | Debug
     | Version
     | PrintDefaultConfig
+
+data ConfigOpt
+    = ConfigFile FilePath
+    | Port Int
+    | Listen String
+    | Debug
     deriving (Eq)
 
+type Opt = Either ExitOpt ConfigOpt
+
 flags :: [OptDescr Opt]
 flags =
-   [ Option ['h'] ["help"] (NoArg Help)
+   [ Option ['h'] ["help"] (NoArg (Left Help))
         "Print this help message"
-   , Option ['v'] ["version"] (NoArg Version)
+   , Option ['v'] ["version"] (NoArg (Left Version))
         "Print version information"
-   , Option ['p'] ["port"] (ReqArg (Port . read) "PORT")
+   , Option ['p'] ["port"] (ReqArg (Right . Port . read) "PORT")
         "Specify port"
-   , Option ['l'] ["listen"] (ReqArg (Listen . checkListen) "INTERFACE")
+   , Option ['l'] ["listen"] (ReqArg (Right . Listen . checkListen) "INTERFACE")
         "Specify IP address to listen on"
-   , Option [] ["print-default-config"] (NoArg PrintDefaultConfig)
+   , Option [] ["print-default-config"] (NoArg (Left PrintDefaultConfig))
         "Print default configuration"
-   , Option [] ["debug"] (NoArg Debug)
+   , Option [] ["debug"] (NoArg (Right Debug))
         "Print debugging information on each request"
-   , Option ['f'] ["config-file"] (ReqArg ConfigFile "FILE")
+   , Option ['f'] ["config-file"] (ReqArg (Right . ConfigFile) "FILE")
         "Specify configuration file"
    ]
 
@@ -124,20 +141,24 @@
               | isIPv4address l = l
               | otherwise       = error "Gitit.checkListen: Not a valid interface name"
 
-getListenOrDefault :: [Opt] -> String
+getListenOrDefault :: [ConfigOpt] -> String
 getListenOrDefault [] = "0.0.0.0"
 getListenOrDefault ((Listen l):_) = l
 getListenOrDefault (_:os) = getListenOrDefault os
 
 parseArgs :: [String] -> IO [Opt]
 parseArgs argv = do
-  progname <- getProgName
   case getOpt Permute flags argv of
     (opts,_,[])  -> return opts
-    (_,_,errs)   -> putErr (ExitFailure 1) (concat errs ++ usageInfo (usageHeader progname) flags)
+    (_,_,errs)   -> putErr (ExitFailure 1) . (concat errs ++) =<< usageMessage
 
-usageHeader :: String -> String
-usageHeader progname = "Usage:  " ++ progname ++ " [opts...]"
+usageMessage :: IO String
+usageMessage = do
+  progname <- getProgName
+  confLoc <- getDataFileName "data/default.conf"
+  return $ usageInfo ("Usage:  " ++ progname ++ " [opts...]") flags
+    ++ "\nDefault configuration file path:\n  " ++ confLoc
+    ++ "\nSet the `gitit_datadir' environment variable to change this."
 
 copyrightMessage :: String
 copyrightMessage = "\nCopyright (C) 2008 John MacFarlane\n" ++
@@ -152,13 +173,9 @@
   " -plugins"
 #endif
 
-handleFlag :: Config -> Opt -> IO Config
-handleFlag conf opt = do
-  progname <- getProgName
+handleFlag :: Config -> ConfigOpt -> IO Config
+handleFlag conf opt =
   case opt of
-    Help               -> putErr ExitSuccess (usageInfo (usageHeader progname) flags)
-    Version            -> putErr ExitSuccess (progname ++ " version " ++ showVersion version ++ compileInfo ++ copyrightMessage)
-    PrintDefaultConfig -> getDataFileName "data/default.conf" >>= readFileUTF8 >>= B.putStrLn . fromString >> exitWith ExitSuccess
     Debug              -> return conf{ debugMode = True }
     Port p             -> return conf{ portNumber = p }
     ConfigFile fname   -> getConfigFromFile fname
