Permalink
Browse files

Added math config option, native mathml support.

Default is now for math to be converted into MathML
by texmath and served using MathMLinHTML.js.  This
isn't completely portable, so jsMath and raw options
are also provided.
  • Loading branch information...
1 parent c038db8 commit 18ff13461822fa5a3fba7ce5033f36d995dc45f6 @jgm committed Aug 22, 2009
Showing with 131 additions and 18 deletions.
  1. +5 −1 Network/Gitit/Config.hs
  2. +29 −4 Network/Gitit/ContentTransformer.hs
  3. +5 −2 Network/Gitit/Types.hs
  4. +12 −0 data/default.conf
  5. +76 −0 data/static/js/MathMLinHTML.js
  6. +2 −1 gitit.cabal
  7. +2 −10 gitit.hs
@@ -118,6 +118,7 @@ extractConfig cp = do
cfRepositoryType <- get cp "DEFAULT" "repository-type"
cfRepositoryPath <- get cp "DEFAULT" "repository-path"
cfDefaultPageType <- get cp "DEFAULT" "default-page-type"
+ cfMathMethod <- get cp "DEFAULT" "math"
cfShowLHSBirdTracks <- get cp "DEFAULT" "show-lhs-bird-tracks"
cfAuthenticationMethod <- get cp "DEFAULT" "authentication-method"
cfUserFile <- get cp "DEFAULT" "user-file"
@@ -168,6 +169,10 @@ extractConfig cp = do
repositoryPath = cfRepositoryPath
, repositoryType = repotype'
, defaultPageType = pt
+ , mathMethod = case map toLower cfMathMethod of
+ "jsmath" -> JsMathScript
+ "mathml" -> MathML
+ _ -> RawTeX
, defaultLHS = lhs
, showLHSBirdTracks = cfShowLHSBirdTracks
, withUser = case authMethod of
@@ -207,7 +212,6 @@ extractConfig cp = do
, useCache = cfUseCache
, cacheDir = cfCacheDir
, mimeMap = mimeMap'
- , jsMath = False
, mailCommand = cfMailCommand
, resetPasswordMessage = fromQuotedMultiline cfResetPasswordMessage
, markupHelp = markupHelpText
@@ -93,6 +93,8 @@ import Network.HTTP (urlEncodeVars)
import Network.URI (isAllowedInURI, escapeURIString)
import qualified Data.ByteString as S (concat)
import qualified Data.ByteString.Lazy as L (toChunks, fromChunks)
+import Text.XML.Light
+import Text.TeXMath
--
-- ContentTransformer runners
@@ -391,8 +393,13 @@ applyTransform inp transform = do
-- | Applies all the page transform plugins to a Pandoc document.
applyPageTransforms :: Pandoc -> ContentTransformer Pandoc
-applyPageTransforms c = liftM (wikiLinksTransform : ) getPageTransforms >>=
- foldM applyTransform c
+applyPageTransforms c = do
+ xforms <- getPageTransforms
+ cfg <- lift getConfig
+ let xforms' = case mathMethod cfg of
+ MathML -> mathMLTransform : xforms
+ _ -> xforms
+ foldM applyTransform c (wikiLinksTransform : xforms')
-- | Applies all the pre-parse transform plugins to a Page object.
applyPreParseTransforms :: Page -> ContentTransformer Page
@@ -434,11 +441,17 @@ addPageTitleToPandoc title' (Pandoc _ blocks) = do
then Pandoc (Meta [] [] []) blocks
else Pandoc (Meta [Str title'] [] []) blocks
--- | Adds javascript links for jsMath support.
+-- | Adds javascript links for math support.
addMathSupport :: a -> ContentTransformer a
addMathSupport c = do
conf <- lift getConfig
- updateLayout $ \l -> addScripts l ["jsMath/easy/load.js" | jsMath conf]
+ updateLayout $ \l ->
+ case mathMethod conf of
+ JsMathScript -> addScripts l ["jsMath/easy/load.js"]
+ -- eventually this should be added dynamically only
+ -- on pages with math:
+ MathML -> addScripts l ["MathMLinHTML.js"]
+ RawTeX -> l
return c
-- | Adds javascripts to page layout.
@@ -505,6 +518,18 @@ convertWikiLinks (Link ref ("", "")) =
Link ref (inlinesToURL ref, "Go to wiki page")
convertWikiLinks x = x
+mathMLTransform :: Pandoc -> PluginM Pandoc
+mathMLTransform = return . processWith convertTeXMathToMathML
+
+-- | Convert math to MathML.
+convertTeXMathToMathML :: Inline -> Inline
+convertTeXMathToMathML (Math t x) =
+ case texMathToMathML t' x of
+ Left _ -> Math t x
+ Right v -> HtmlInline $ ppElement v
+ where t' = if t == DisplayMath then DisplayBlock else DisplayInline
+convertTeXMathToMathML x = x
+
-- | Derives a URL from a list of Pandoc Inline elements.
inlinesToURL :: [Inline] -> String
inlinesToURL = escapeURIString isAllowedInURI  . encodeString . inlinesToString
@@ -44,6 +44,9 @@ data PageType = Markdown | RST | LaTeX | HTML
data FileStoreType = Git | Darcs deriving Show
+data MathMethod = MathML | JsMathScript | RawTeX
+ deriving (Read, Show, Eq)
+
-- | Data structure for information read from config file.
data Config = Config {
-- | Path of repository containing filestore
@@ -52,6 +55,8 @@ data Config = Config {
repositoryType :: FileStoreType,
-- | Default page markup type for this wiki
defaultPageType :: PageType,
+ -- | How to handle LaTeX math in pages?
+ mathMethod :: MathMethod,
-- | Treat as literate haskell by default?
defaultLHS :: Bool,
-- | Show Haskell code with bird tracks
@@ -106,8 +111,6 @@ data Config = Config {
cacheDir :: FilePath,
-- | Map associating mime types with file extensions
mimeMap :: M.Map String String,
- -- | Are jsMath files present?
- jsMath :: Bool,
-- | Command to send notification emails
mailCommand :: String,
-- | Text of password reset email
View
@@ -44,6 +44,18 @@ default-page-type: Markdown
# rendered correctly if RST is selected. The same goes for LaTeX and
# HTML.
+math: MathML
+# specifies how LaTeX math is to be displayed. Possible values
+# are MathML, raw, and jsMath. If mathml is selected, gitit will
+# convert LaTeX math to MathML and link in a script, MathMLinHTML.js,
+# that allows the MathML to be seen in Gecko browsers, IE +
+# mathplayer, and Opera. In other browsers you may get a jumble
+# of characters. If raw is selected, the LaTeX math will be displayed
+# as raw LaTeX math. If jsMath is selected, gitit will link to
+# the script /js/jsMath/easy/load.js, and will assume that jsMath
+# has been installed into the js/jsMath directory. This is the most
+# portable solution.
+
show-lhs-bird-tracks: no
# specifies whether to show Haskell code blocks in "bird style",
# with "> " at the beginning of each line.
@@ -0,0 +1,76 @@
+/*
+March 19, 2004 MathHTML (c) Peter Jipsen http://www.chapman.edu/~jipsen
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+(at http://www.gnu.org/copyleft/gpl.html) for more details.
+*/
+
+function convertMath(node) {// for Gecko
+ if (node.nodeType==1) {
+ var newnode =
+ document.createElementNS("http://www.w3.org/1998/Math/MathML",
+ node.nodeName.toLowerCase());
+ for(var i=0; i < node.attributes.length; i++)
+ newnode.setAttribute(node.attributes[i].nodeName,
+ node.attributes[i].nodeValue);
+ for (var i=0; i<node.childNodes.length; i++) {
+ var st = node.childNodes[i].nodeValue;
+ if (st==null || st.slice(0,1)!=" " && st.slice(0,1)!="\n")
+ newnode.appendChild(convertMath(node.childNodes[i]));
+ }
+ return newnode;
+ }
+ else return node;
+}
+
+function convert() {
+ var mmlnode = document.getElementsByTagName("math");
+ var st,str,node,newnode;
+ for (var i=0; i<mmlnode.length; i++)
+ if (document.createElementNS!=null)
+ mmlnode[i].parentNode.replaceChild(convertMath(mmlnode[i]),mmlnode[i]);
+ else { // convert for IE
+ str = "";
+ node = mmlnode[i];
+ while (node.nodeName!="/MATH") {
+ st = node.nodeName.toLowerCase();
+ if (st=="#text") str += node.nodeValue;
+ else {
+ str += (st.slice(0,1)=="/" ? "</m:"+st.slice(1) : "<m:"+st);
+ if (st.slice(0,1)!="/")
+ for(var j=0; j < node.attributes.length; j++)
+ if (node.attributes[j].nodeValue!="italic" &&
+ node.attributes[j].nodeValue!="" &&
+ node.attributes[j].nodeValue!="inherit" &&
+ node.attributes[j].nodeValue!=undefined)
+ str += " "+node.attributes[j].nodeName+"="+
+ "\""+node.attributes[j].nodeValue+"\"";
+ str += ">";
+ }
+ node = node.nextSibling;
+ node.parentNode.removeChild(node.previousSibling);
+ }
+ str += "</m:math>";
+ newnode = document.createElement("span");
+ node.parentNode.replaceChild(newnode,node);
+ newnode.innerHTML = str;
+ }
+}
+
+if (document.createElementNS==null) {
+ document.write("<object id=\"mathplayer\"\
+ classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");
+ document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");
+}
+if(typeof window.addEventListener != 'undefined'){
+ window.addEventListener('load', convert, false);
+}
+if(typeof window.attachEvent != 'undefined') {
+ window.attachEvent('onload', convert);
+}
View
@@ -58,6 +58,7 @@ data-files: data/static/css/screen.css, data/static/css/print.css,
data/static/js/uploadForm.js, data/static/js/jquery-ui.packed.js,
data/static/js/jquery.hotkeys-0.7.9.min.js,
data/static/js/preview.js, data/static/js/search.js,
+ data/static/js/MathMLinHTML.js,
data/post-update, data/FrontPage.page, data/Help.page,
data/markup.Markdown, data/markup.RST,
data/markup.HTML, data/markup.LaTeX,
@@ -115,7 +116,7 @@ Executable gitit
datetime, zlib, url, happstack-server >= 0.3.3 && < 0.4,
happstack-util >= 0.3.2 && < 0.4, xml >= 1.3.4,
hslogger >= 1 && < 1.1, ConfigFile >= 1, feed >= 0.3.6,
- cautious-file >= 0.1.5 && < 0.2
+ cautious-file >= 0.1.5 && < 0.2, texmath
if impl(ghc >= 6.10)
build-depends: base >= 4, syb
if flag(plugins)
View
@@ -23,11 +23,10 @@ import Network.Gitit.Server
import Network.Gitit.Initialize (createStaticIfMissing, createRepoIfMissing)
import Prelude hiding (writeFile, readFile, catch)
import System.Directory
-import System.FilePath ((</>))
import Network.Gitit.Config (getConfigFromOpts)
import Data.Maybe (isNothing)
import Control.Monad.Reader
-import System.Log.Logger (logM, Priority(..), setLevel, setHandlers,
+import System.Log.Logger (Priority(..), setLevel, setHandlers,
getLogger, saveGlobalLogger)
import System.Log.Handler.Simple (fileHandler)
import Data.Char (toLower)
@@ -54,14 +53,7 @@ main = do
saveGlobalLogger $ setLevel level $ setHandlers [logFileHandler] serverLogger
saveGlobalLogger $ setLevel level $ setHandlers [logFileHandler] gititLogger
- jsMathExists <- liftIO $ doesFileExist $
- staticDir conf </> "js" </> "jsMath" </> "easy" </> "load.js"
- logM "gitit" NOTICE $
- if jsMathExists
- then "Found jsMath scripts -- using jsMath"
- else "Did not find jsMath scripts -- not using jsMath"
-
- let conf' = conf{jsMath = jsMathExists, logLevel = level}
+ let conf' = conf{logLevel = level}
-- setup the page repository, template, and static files, if they don't exist
createRepoIfMissing conf'

0 comments on commit 18ff134

Please sign in to comment.