Skip to content

Instantly share code, notes, and snippets.

@chaoxu
Created June 26, 2011 02:56
Show Gist options
  • Save chaoxu/1047169 to your computer and use it in GitHub Desktop.
Save chaoxu/1047169 to your computer and use it in GitHub Desktop.
LaTeX 2 HTML, still updating
import Data.Tree
import Data.List
import Debug.Trace
import Maybe
--the last int is the amount of argument
data Label = Command String
| Constant String
| Declaration
deriving Show
--commandType =
cmdStopChar = [' ', '\\' ,'{', '}']
constStopChar = ['\\','}','{']
readCommand tex = '\\':takeWhile ((flip notElem) (cmdStopChar)) (tail tex)
readConstant = takeWhile ((flip notElem) constStopChar)
removeConstant t = drop (length (readConstant t)) t
removeCommand t = drop (length (readCommand t)) t
--returns [String]
tokenize [] = []
tokenize (x:xs)
| (x == '}') || (x == '{') = [x]:tokenize xs
| (x == '\\') = (readCommand tex):(tokenize (removeCommand tex))
| otherwise = (readConstant tex):(tokenize (removeConstant tex))
where tex = (x:xs)
--returns (Forest, remaining)
--parseNode :: [String]->(Forest Label, [String])
parseNode lex
| lex == [] = ([], [])
| head lex == "}" = ([], tail lex)
| otherwise = (headNode:tailNode, remainLex)
where (headNode, tailLex) = sequenceNode lex
(tailNode, remainLex) = (parseNode tailLex)
--return (Node, remaining)
sequenceNode (x:xs)
| head x == '\\' = (Node (Command (tail x)) [], xs)
| head x == '{' = (Node Declaration forest, remaining)
| otherwise = (Node (Constant x) [] , xs)
where lex = (x:xs)
(forest, remaining) = parseNode xs
--input Forest->Forest
commandTree ((Node (Command x) z):xs) =
--Find the maximum amount of parameters of x
--k of them are possible if and only if
(Node (Command x) ( z ++ parm)):(commandTree rest)
where (parm, rest) = commandTree' (parameterCount x) xs
commandTree (x:xs) = x:(commandTree xs)
commandTree [] = []
--commandTree' :: Int ->Forest Label->(Forest Label, Forest Label)
commandTree' count ((Node (Declaration) z):xs)
| count > 0 = ((Node (Declaration) (commandTree z)):parm, rest)
| otherwise = ([], xs)
where (parm, rest) = commandTree' (count-1) xs
commandTree' _ x = ([], x)
cmd x = Maybe.fromMaybe (\z -> "[ERROR:"++x++"]"++(compile z)++"[/ERROR]") $ (lookup x cmdList)
--compile :: Forest Label -> String
compile (x:xs) = (eval x) ++ compile (xs)
compile [] = ""
--eval :: Tree Label -> String
eval (Node (Command x) subtrees) = cmd x subtrees
eval (Node Declaration subtrees) = compile subtrees
eval (Node (Constant x) []) = x
plain ((Node (Command x) subtrees):xs) = "\\"++ x ++ (plain subtrees) ++ (plain xs)
plain ((Node (Constant x) []):xs) = x ++ (plain xs)
plain ((Node Declaration subtrees):xs) = "{" ++ (plain subtrees) ++ "}" ++ (plain xs)
plain [] = ""
latex2Html x = compile (commandTree (fst (parseNode (tokenize x))))
--List of commands--
cmdList = [("textbf",cmd_textbf),
("emph",cmd_emph),
("inlinemath",cmd_inlinemath)]
--parameterCounts :: String->Int
parameterCount x
| elem x ["frac"] = 2
| elem x ["textbf","emph", "inlinemath"] = 1
| otherwise = 0
--The commands
cmd_textbf subtrees = "<strong>"++(compile subtrees)++"</strong>"
cmd_emph subtrees = "<emph>"++(compile subtrees)++"</emph>"
cmd_inlinemath subtrees = "$"++(plain (subForest (head subtrees)))++"$"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment