git.iko.soy/typeable/pandoc
on master help sign in
OMath: Finish initial cleanup.
2f7a627Jesse Rosenthal
src/Text/Pandoc/Readers/Docx/OMath.hs+50−522
@@ -30,14 +30,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30Types and functions for conversion of OMML into TeXMath.
30Types and functions for conversion of OMML into TeXMath.
31-}
31-}
32
32
33−module Text.Pandoc.Readers.Docx.OMath ( elemToExps
33+module Text.Pandoc.Readers.Docx.OMath (readOMML
34 ) where
34 ) where
35
35
36import Text.XML.Light
36import Text.XML.Light
37import Data.Maybe (mapMaybe, fromMaybe)
37import Data.Maybe (mapMaybe, fromMaybe)
38import Data.List (intersperse)
38import Data.List (intersperse)
39import qualified Text.TeXMath.Types as TM
39import qualified Text.TeXMath.Types as TM
40−import Control.Applicative ((<$>))
40+
41+readOMML :: Element -> Maybe [TM.Exp]
42+readOMML element | isElem "m" "oMath" element =
43+ Just $ concat $ mapMaybe (elemToExps') (elChildren element)
44+readOMML _ = Nothing
45+
41
46
42isElem :: String -> String -> Element -> Bool
47isElem :: String -> String -> Element -> Bool
43isElem prefix name element =
48isElem prefix name element =
@@ -53,56 +58,11 @@ hasElemName prefix name qn =
53 qName qn == name &&
58 qName qn == name &&
54 qp == prefix
59 qp == prefix
55
60
56−data OMath = OMath [OMathElem]
57− deriving Show
58−
59−data OMathElem = Accent AccentStyle Base
60− | Bar BarStyle Base
61− | Box Base
62− | BorderBox Base
63− | Delimiter DelimStyle [Base]
64− | EquationArray [Base]
65− | Fraction [OMathElem] [OMathElem]
66− | Function [OMathElem] Base
67− | Group GroupStyle Base
68− | LowerLimit Base [OMathElem]
69− | UpperLimit Base [OMathElem]
70− | Matrix [[Base]]
71− | NAry NAryStyle [OMathElem] [OMathElem] Base
72− | Phantom Base
73− | Radical [OMathElem] Base
74− | PreSubSuper [OMathElem] [OMathElem] Base
75− | Sub Base [OMathElem]
76− | SubSuper Base [OMathElem] [OMathElem]
77− | Super Base [OMathElem]
78− | OMathRun OMathRunStyle [OMathRunElem]
79− deriving Show
80−
81data OMathRunElem = TextRun String
61data OMathRunElem = TextRun String
82 | LnBrk
62 | LnBrk
83 | Tab
63 | Tab
84 deriving Show
64 deriving Show
85
65
86−data Base = Base [OMathElem]
87− deriving Show
88−
89−data TopBottom = Top | Bottom
90− deriving Show
91−
92−data AccentStyle = AccentStyle { accentChar :: Maybe Char }
93− deriving Show
94−
95−data BarStyle = BarStyle { barPos :: TopBottom}
96− deriving Show
97−
98−data NAryStyle = NAryStyle { nAryChar :: Maybe Char
99− , nAryLimLoc :: LimLoc}
100− deriving Show
101−
102−data OMathRunStyle = OMathRunStyle { oMathLit :: Bool
103− , oMathRunTextStyle :: OMathRunTextStyle }
104− deriving Show
105−
106data OMathRunTextStyle = NoStyle
66data OMathRunTextStyle = NoStyle
107 | Normal
67 | Normal
108 | Styled { oMathScript :: Maybe OMathTextScript
68 | Styled { oMathScript :: Maybe OMathTextScript
@@ -123,71 +83,29 @@ data OMathTextStyle = OPlain
123 | OBoldItalic
83 | OBoldItalic
124 deriving (Show, Eq)
84 deriving (Show, Eq)
125
85
126−defaultNAryStyle :: NAryStyle
86+elemToBase :: Element -> Maybe TM.Exp
127−defaultNAryStyle = NAryStyle { nAryChar = Nothing -- integral, in practice
87+elemToBase element | isElem "m" "e" element = do
128− , nAryLimLoc = SubSup }
88+ bs <- elemToBases element
129−
89+ return $ case bs of
130−data LimLoc = SubSup | UnderOver deriving Show
90+ (e : []) -> e
131−
91+ exps -> TM.EGrouped exps
132−data DelimStyle = DelimStyle { delimBegChar :: Maybe Char
92+elemToBase _ = Nothing
133− , delimSepChar :: Maybe Char
134− , delimEndChar :: Maybe Char}
135− deriving Show
136−
137−defaultDelimStyle :: DelimStyle
138−defaultDelimStyle = DelimStyle { delimBegChar = Nothing
139− , delimSepChar = Nothing
140− , delimEndChar = Nothing }
141−
142−data GroupStyle = GroupStyle { groupChr :: Maybe Char
143− , groupPos :: Maybe TopBottom }
144− deriving Show
145−
146−defaultGroupStyle :: GroupStyle
147−defaultGroupStyle = GroupStyle {groupChr = Nothing, groupPos = Nothing}
148
93
149−elemToMath :: Element -> Maybe OMath
94+elemToBases :: Element -> Maybe [TM.Exp]
150−elemToMath element | isElem "m" "oMath" element =
95+elemToBases element | isElem "m" "e" element =
151− Just $ OMath $ mapMaybe (elemToMathElem) (elChildren element)
96+ return $ concat $ mapMaybe elemToExps' (elChildren element)
152−elemToMath _ = Nothing
97+elemToBases _ = Nothing
153
98
154−elemToBase :: Element -> Maybe Base
155−elemToBase element | isElem "m" "e" element =
156− Just $ Base $ mapMaybe (elemToMathElem) (elChildren element)
157−elemToBase _ = Nothing
158
99
159-- TODO: The right way to do this is to use the ampersand to break the
100-- TODO: The right way to do this is to use the ampersand to break the
160-- text lines into multiple columns. That's tricky, though, and this
101-- text lines into multiple columns. That's tricky, though, and this
161-- will get us most of the way for the time being.
102-- will get us most of the way for the time being.
162−filterAmpersand :: OMathElem -> OMathElem
103+filterAmpersand :: TM.Exp -> TM.Exp
163−filterAmpersand (OMathRun mrPr elems) =
104+filterAmpersand (TM.EIdentifier s) = TM.EIdentifier (filter ('&' /=) s)
164− let f (TextRun s) = TextRun $ filter ('&' /=) s
105+filterAmpersand (TM.EText tt s) = TM.EText tt (filter ('&' /=) s)
165− f re = re
106+filterAmpersand (TM.EStyled tt exps) = TM.EStyled tt (map filterAmpersand exps)
166− in
107+filterAmpersand (TM.EGrouped exps) = TM.EGrouped (map filterAmpersand exps)
167− OMathRun mrPr (map f elems)
108+filterAmpersand e = e
168−filterAmpersand e = e
169−
170−elemToBaseNoAmpersand :: Element -> Maybe Base
171−elemToBaseNoAmpersand element | isElem "m" "e" element =
172− return $ Base $
173− mapMaybe
174− (\e -> (elemToMathElem e >>= (return . filterAmpersand)))
175− (elChildren element)
176−elemToBaseNoAmpersand _ = Nothing
177−
178−elemToOMathRunStyle :: Element -> OMathRunStyle
179−elemToOMathRunStyle element =
180− let lit =
181− case
182− filterChildName (hasElemName"m" "lit") element >>=
183− findAttrBy (hasElemName"m" "val")
184− of
185− Just "on" -> True
186− _ -> False
187− in
188− OMathRunStyle { oMathLit = lit
189− , oMathRunTextStyle = (elemToOMathRunTextStyle element)
190− }
191
109
192elemToOMathRunTextStyle :: Element -> OMathRunTextStyle
110elemToOMathRunTextStyle :: Element -> OMathRunTextStyle
193elemToOMathRunTextStyle element
111elemToOMathRunTextStyle element
@@ -198,7 +116,7 @@ elemToOMathRunTextStyle element
198 let scr =
116 let scr =
199 case
117 case
200 filterChildName (hasElemName"m" "scr") mrPr >>=
118 filterChildName (hasElemName"m" "scr") mrPr >>=
201− findAttrBy (hasElemName"m" "val")
119+ findAttrBy (hasElemName"m" "val")
202 of
120 of
203 Just "roman" -> Just ORoman
121 Just "roman" -> Just ORoman
204 Just "script" -> Just OScript
122 Just "script" -> Just OScript
@@ -222,183 +140,10 @@ elemToOMathRunTextStyle element
222 Styled { oMathScript = scr, oMathStyle = sty }
140 Styled { oMathScript = scr, oMathStyle = sty }
223 | otherwise = NoStyle
141 | otherwise = NoStyle
224
142
225−
226−
227−elemToNAryStyle :: Element -> NAryStyle
228−elemToNAryStyle element
229− | Just narypr <- filterChildName (hasElemName"m" "naryPr") element =
230− let
231− chr = filterChildName (hasElemName"m" "chr") narypr >>=
232− findAttrBy (hasElemName"m" "val") >>=
233− Just . head
234− limLoc = filterChildName (hasElemName"m" "limLoc") narypr >>=
235− findAttrBy (hasElemName"m" "val")
236− limLoc' = case limLoc of
237− Just "undOver" -> UnderOver
238− Just "subSup" -> SubSup
239− _ -> SubSup
240− in
241− NAryStyle { nAryChar = chr, nAryLimLoc = limLoc'}
242−elemToNAryStyle _ = defaultNAryStyle
243−
244−elemToDelimStyle :: Element -> DelimStyle
245−elemToDelimStyle element
246− | Just dPr <- filterChildName (hasElemName"m" "dPr") element =
247− let begChr = filterChildName (hasElemName"m" "begChr") dPr >>=
248− findAttrBy (hasElemName"m" "val") >>=
249− (\c -> if null c then (Just ' ') else (Just $ head c))
250− sepChr = filterChildName (hasElemName"m" "sepChr") dPr >>=
251− findAttrBy (hasElemName"m" "val") >>=
252− (\c -> if null c then (Just ' ') else (Just $ head c))
253− endChr = filterChildName (hasElemName"m" "endChr") dPr >>=
254− findAttrBy (hasElemName"m" "val") >>=
255− (\c -> if null c then (Just ' ') else (Just $ head c))
256− in
257− DelimStyle { delimBegChar = begChr
258− , delimSepChar = sepChr
259− , delimEndChar = endChr}
260−elemToDelimStyle _ = defaultDelimStyle
261−
262−elemToGroupStyle :: Element -> GroupStyle
263−elemToGroupStyle element
264− | Just gPr <- filterChildName (hasElemName"m" "groupChrPr") element =
265− let chr = filterChildName (hasElemName"m" "chr") gPr >>=
266− findAttrBy (hasElemName"m" "val") >>=
267− Just . head
268− pos = filterChildName (hasElemName"m" "pos") gPr >>=
269− findAttrBy (hasElemName"m" "val") >>=
270− (\s -> Just $ if s == "top" then Top else Bottom)
271− in
272− GroupStyle { groupChr = chr, groupPos = pos }
273−elemToGroupStyle _ = defaultGroupStyle
274−
275−elemToMathElem :: Element -> Maybe OMathElem
276−elemToMathElem element | isElem "m" "acc" element = do
277− let accChar =
278− filterChildName (hasElemName"m" "accPr") element >>=
279− filterChildName (hasElemName"m" "chr") >>=
280− findAttrBy (hasElemName"m" "val") >>=
281− Just . head
282− accPr = AccentStyle { accentChar = accChar}
283− base <- filterChildName (hasElemName"m" "e") element >>=
284− elemToBase
285− return $ Accent accPr base
286−elemToMathElem element | isElem "m" "bar" element = do
287− barPr <- filterChildName (hasElemName"m" "barPr") element >>=
288− filterChildName (hasElemName"m" "pos") >>=
289− findAttrBy (hasElemName"m" "val") >>=
290− (\s ->
291− Just $ BarStyle {
292− barPos = (if s == "bot" then Bottom else Top)
293− })
294− base <- filterChildName (hasElemName"m" "e") element >>=
295− elemToBase
296− return $ Bar barPr base
297−elemToMathElem element | isElem "m" "box" element =
298− filterChildName (hasElemName"m" "e") element >>=
299− elemToBase >>=
300− (\b -> return $ Box b)
301−elemToMathElem element | isElem "m" "borderBox" element =
302− filterChildName (hasElemName"m" "e") element >>=
303− elemToBase >>=
304− (\b -> return $ BorderBox b)
305−elemToMathElem element | isElem "m" "d" element =
306− let style = elemToDelimStyle element
307− in
308− return $ Delimiter style $ mapMaybe (elemToBase) (elChildren element)
309−elemToMathElem element | isElem "m" "eqArr" element =
310− return $ EquationArray $ mapMaybe (elemToBaseNoAmpersand) (elChildren element)
311−elemToMathElem element | isElem "m" "f" element = do
312− num <- filterChildName (hasElemName"m" "num") element
313− den <- filterChildName (hasElemName"m" "den") element
314− let numElems = mapMaybe (elemToMathElem) (elChildren num)
315− denElems = mapMaybe (elemToMathElem) (elChildren den)
316− return $ Fraction numElems denElems
317−elemToMathElem element | isElem "m" "func" element = do
318− fName <- filterChildName (hasElemName"m" "fName") element
319− base <- filterChildName (hasElemName"m" "e") element >>=
320− elemToBase
321− let fnElems = mapMaybe (elemToMathElem) (elChildren fName)
322− return $ Function fnElems base
323−elemToMathElem element | isElem "m" "groupChr" element =
324− let style = elemToGroupStyle element
325− in
326− filterChildName (hasElemName"m" "e") element >>=
327− elemToBase >>=
328− (\b -> return $ Group style b)
329−elemToMathElem element | isElem "m" "limLow" element = do
330− base <- filterChildName (hasElemName"m" "e") element
331− >>= elemToBase
332− lim <- filterChildName (hasElemName"m" "lim") element
333− let limElems = mapMaybe (elemToMathElem) (elChildren lim)
334− return $ LowerLimit base limElems
335−elemToMathElem element | isElem "m" "limUpp" element = do
336− base <- filterChildName (hasElemName"m" "e") element
337− >>= elemToBase
338− lim <- filterChildName (hasElemName"m" "lim") element
339− let limElems = mapMaybe (elemToMathElem) (elChildren lim)
340− return $ UpperLimit base limElems
341−elemToMathElem element | isElem "m" "m" element = do
342− let rows = filterChildrenName (hasElemName"m" "mr") element
343− let bases = mapMaybe (\mr -> mapM (elemToBase) (elChildren mr)) rows
344− return $ Matrix bases
345−elemToMathElem element | isElem "m" "nary" element = do
346− let style = elemToNAryStyle element
347− sub <- filterChildName (hasElemName"m" "sub") element >>=
348− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
349− sup <- filterChildName (hasElemName"m" "sup") element >>=
350− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
351− base <- filterChildName (hasElemName"m" "e") element >>=
352− elemToBase
353− return $ NAry style sub sup base
354−elemToMathElem element | isElem "m" "rad" element = do
355− deg <- filterChildName (hasElemName"m" "deg") element >>=
356− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
357− base <- filterChildName (hasElemName"m" "e") element >>=
358− elemToBase
359− return $ Radical deg base
360−elemToMathElem element | isElem "m" "phant" element = do
361− base <- filterChildName (hasElemName"m" "e") element >>=
362− elemToBase
363− return $ Phantom base
364−elemToMathElem element | isElem "m" "sPre" element = do
365− sub <- filterChildName (hasElemName"m" "sub") element >>=
366− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
367− sup <- filterChildName (hasElemName"m" "sup") element >>=
368− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
369− base <- filterChildName (hasElemName"m" "e") element >>=
370− elemToBase
371− return $ PreSubSuper sub sup base
372−elemToMathElem element | isElem "m" "sSub" element = do
373− base <- filterChildName (hasElemName"m" "e") element >>=
374− elemToBase
375− sub <- filterChildName (hasElemName"m" "sub") element >>=
376− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
377− return $ Sub base sub
378−elemToMathElem element | isElem "m" "sSubSup" element = do
379− base <- filterChildName (hasElemName"m" "e") element >>=
380− elemToBase
381− sub <- filterChildName (hasElemName"m" "sub") element >>=
382− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
383− sup <- filterChildName (hasElemName"m" "sup") element >>=
384− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
385− return $ SubSuper base sub sup
386−elemToMathElem element | isElem "m" "sSup" element = do
387− base <- filterChildName (hasElemName"m" "e") element >>=
388− elemToBase
389− sup <- filterChildName (hasElemName"m" "sup") element >>=
390− (\e -> return $ mapMaybe (elemToMathElem) (elChildren e))
391− return $ Super base sup
392−elemToMathElem element | isElem "m" "r" element = do
393− let mrPr = elemToOMathRunStyle element
394− mrElems <- elemToOMathRunElems element
395− return $ OMathRun mrPr mrElems
396−elemToMathElem _ = Nothing
397−
398elemToOMathRunElem :: Element -> Maybe OMathRunElem
143elemToOMathRunElem :: Element -> Maybe OMathRunElem
399elemToOMathRunElem element
144elemToOMathRunElem element
400 | isElem "w" "t" element
145 | isElem "w" "t" element
401− || isElem "m" "t" element
146+ || isElem "m" "t" element
402 || isElem "w" "delText" element = Just $ TextRun $ strContent element
147 || isElem "w" "delText" element = Just $ TextRun $ strContent element
403 | isElem "w" "br" element = Just LnBrk
148 | isElem "w" "br" element = Just LnBrk
404 | isElem "w" "tab" element = Just Tab
149 | isElem "w" "tab" element = Just Tab
@@ -421,149 +166,10 @@ oMathRunElemToString (Tab) = ['\t']
421oMathRunElemsToString :: [OMathRunElem] -> String
166oMathRunElemsToString :: [OMathRunElem] -> String
422oMathRunElemsToString = concatMap oMathRunElemToString
167oMathRunElemsToString = concatMap oMathRunElemToString
423
168
424−oMathElemToString :: OMathElem -> String
425−oMathElemToString (OMathRun _ oMathRunElems) =
426− oMathRunElemsToString oMathRunElems
427−oMathElemToString _ = ""
428−
429−
430−oMathToExps :: OMath -> [TM.Exp]
431−oMathToExps (OMath oMathElems) = concatMap oMathElemToExps oMathElems
432−
433−oMathElemToExps :: OMathElem -> [TM.Exp]
434−oMathElemToExps (Accent style base) =
435− let baseExp = baseToExp base
436− chr = case accentChar style of
437− Just c -> c
438− Nothing -> '\180' -- default to acute.
439− in
440− [TM.EOver False baseExp (TM.ESymbol TM.Accent [chr])]
441−oMathElemToExps(Bar style base) =
442− let baseExp = baseToExp base
443− in
444− case barPos style of
445− Top -> [TM.EOver False baseExp (TM.ESymbol TM.Accent "\175")]
446− Bottom -> [TM.EUnder False baseExp (TM.ESymbol TM.Accent "\818")]
447−oMathElemToExps (Box base) = [baseToExp base]
448−oMathElemToExps (BorderBox base) =
449− -- TODO: This should be "\\boxed" somehow
450− [baseToExp base]
451−oMathElemToExps (Delimiter dPr bases) =
452− let baseExps = map baseToExp bases
453− inDelimExps = map Right baseExps
454− beg = fromMaybe '(' (delimBegChar dPr)
455− end = fromMaybe ')' (delimEndChar dPr)
456− sep = fromMaybe '|' (delimSepChar dPr)
457− exps = intersperse (Left [sep]) inDelimExps
458− in
459− [TM.EDelimited [beg] [end] exps]
460−oMathElemToExps (EquationArray bases) =
461− let baseExps = map (\b -> [baseToExp' b]) bases
462− in
463− [TM.EArray [] baseExps]
464−oMathElemToExps (Fraction num denom) =
465− let numExp = TM.EGrouped $ concatMap oMathElemToExps num
466− denExp = TM.EGrouped $ concatMap oMathElemToExps denom
467− in
468− [TM.EFraction TM.NormalFrac numExp denExp]
469−oMathElemToExps (Function fname base) =
470− -- We need a string for the fname, but omml gives it to us as a
471− -- series of oMath elems. We're going to filter out the oMathRuns,
472− -- which should work for us most of the time.
473− let fnameString = concatMap oMathElemToString fname
474− baseExp = baseToExp base
475− in
476− [TM.EMathOperator fnameString, baseExp]
477−oMathElemToExps (Group style base)
478− | Just Top <- groupPos style =
479− let baseExp = baseToExp base
480− chr = case groupChr style of
481− Just c -> c
482− Nothing -> '\65079' -- default to overbrace
483− in
484− [TM.EOver False baseExp (TM.ESymbol TM.Accent [chr])]
485− | otherwise =
486− let baseExp = baseToExp base
487− chr = case groupChr style of
488− Just c -> c
489− Nothing -> '\65080' -- default to underbrace
490− in
491− [TM.EUnder False baseExp (TM.ESymbol TM.Accent [chr])]
492−oMathElemToExps (LowerLimit base limElems) = do
493− let baseExp = baseToExp base
494− lim = TM.EGrouped $ concatMap oMathElemToExps limElems
495− in
496− [TM.EUnder True lim baseExp]
497−oMathElemToExps (UpperLimit base limElems) =
498− let baseExp = baseToExp base
499− lim = TM.EGrouped $ concatMap oMathElemToExps limElems
500− in
501− [TM.EOver True lim baseExp]
502−oMathElemToExps (Matrix bases) =
503− let rows = map (map baseToExp') bases
504− in
505− [TM.EArray [TM.AlignCenter] rows]
506−oMathElemToExps (NAry style sub sup base) =
507− let
508− subExps = concatMap oMathElemToExps sub
509− supExps = concatMap oMathElemToExps sup
510− baseExp = baseToExp base
511− opChar = case nAryChar style of
512− Just c -> c
513− -- default to integral
514− Nothing -> '\8747'
515− in [ TM.ESubsup
516− (TM.ESymbol TM.Op [opChar])
517− (TM.EGrouped subExps)
518− (TM.EGrouped supExps)
519− , baseExp]
520−oMathElemToExps (Phantom base) =
521− [TM.EPhantom $ baseToExp base]
522−oMathElemToExps (Radical degree base) =
523− let degExps = concatMap oMathElemToExps degree
524− baseExp = baseToExp base
525− in
526− case degExps of
527− [] -> [TM.ESqrt baseExp]
528− ds -> [TM.ERoot (TM.EGrouped ds) baseExp]
529−oMathElemToExps (PreSubSuper sub sup base) =
530− let subExps = concatMap oMathElemToExps sub
531− supExps = concatMap oMathElemToExps sup
532− baseExp = baseToExp base
533− in [ TM.ESubsup
534− (TM.EIdentifier "") (TM.EGrouped subExps) (TM.EGrouped supExps)
535− , baseExp]
536−oMathElemToExps (Sub base sub) =
537− let baseExp = baseToExp base
538− subExps = concatMap oMathElemToExps sub
539− in
540− [TM.ESub baseExp (TM.EGrouped subExps)]
541−oMathElemToExps (SubSuper base sub sup) =
542− let baseExp = baseToExp base
543− subExps = concatMap oMathElemToExps sub
544− supExps = concatMap oMathElemToExps sup
545− in
546− [TM.ESubsup baseExp (TM.EGrouped subExps) (TM.EGrouped supExps)]
547−oMathElemToExps (Super base sup) =
548− let baseExp = baseToExp base
549− supExps = concatMap oMathElemToExps sup
550− in
551− [TM.ESuper baseExp (TM.EGrouped supExps)]
552−oMathElemToExps (OMathRun sty elems)
553− | NoStyle <- oMathRunTextStyle sty =
554− [TM.EIdentifier $ oMathRunElemsToString elems]
555− | Nothing <- oMathRunStyleToTextType sty =
556− [TM.EIdentifier $ oMathRunElemsToString elems]
557− | Just textType <- oMathRunStyleToTextType sty =
558− if oMathLit sty
559− then [TM.EText textType (oMathRunElemsToString elems)]
560− else [TM.EStyled textType [TM.EIdentifier $ oMathRunElemsToString elems]]
561−oMathElemToExps (OMathRun _ _) = []
562−
563oMathRunTextStyleToTextType :: OMathRunTextStyle -> Maybe TM.TextType
169oMathRunTextStyleToTextType :: OMathRunTextStyle -> Maybe TM.TextType
564oMathRunTextStyleToTextType (Normal) = Just $ TM.TextNormal
170oMathRunTextStyleToTextType (Normal) = Just $ TM.TextNormal
565oMathRunTextStyleToTextType (NoStyle) = Nothing
171oMathRunTextStyleToTextType (NoStyle) = Nothing
566−oMathRunTextStyleToTextType (Styled scr sty)
172+oMathRunTextStyleToTextType (Styled scr sty)
567 | Just OBold <- sty
173 | Just OBold <- sty
568 , Just OSansSerif <- scr =
174 , Just OSansSerif <- scr =
569 Just $ TM.TextSansSerifBold
175 Just $ TM.TextSansSerifBold
@@ -598,70 +204,6 @@ oMathRunTextStyleToTextType (Styled scr sty)
598 | otherwise = Nothing
204 | otherwise = Nothing
599
205
600
206
601−oMathRunStyleToTextType :: OMathRunStyle -> Maybe TM.TextType
602−oMathRunStyleToTextType mrPr
603− | Normal <- oMathRunTextStyle mrPr =
604− Just $ TM.TextNormal
605− | Styled scr sty <- oMathRunTextStyle mrPr
606− ,Just OBold <- sty
607− , Just OSansSerif <- scr =
608− Just $ TM.TextSansSerifBold
609− | Styled scr sty <- oMathRunTextStyle mrPr
610− , Just OBoldItalic <- sty
611− , Just OSansSerif <- scr =
612− Just $ TM.TextSansSerifBoldItalic
613− | Styled scr sty <- oMathRunTextStyle mrPr
614− , Just OBold <- sty
615− , Just OScript <- scr =
616− Just $ TM.TextBoldScript
617− | Styled scr sty <- oMathRunTextStyle mrPr
618− , Just OBold <- sty
619− , Just OFraktur <- scr =
620− Just $ TM.TextBoldFraktur
621− | Styled scr sty <- oMathRunTextStyle mrPr
622− , Just OItalic <- sty
623− , Just OSansSerif <- scr =
624− Just $ TM.TextSansSerifItalic
625− | Styled _ sty <- oMathRunTextStyle mrPr
626− , Just OBold <- sty =
627− Just $ TM.TextBold
628− | Styled _ sty <- oMathRunTextStyle mrPr
629− , Just OItalic <- sty =
630− Just $ TM.TextItalic
631− | Styled scr _ <- oMathRunTextStyle mrPr
632− , Just OMonospace <- scr =
633− Just $ TM.TextMonospace
634− | Styled scr _ <- oMathRunTextStyle mrPr
635− , Just OSansSerif <- scr =
636− Just $ TM.TextSansSerif
637− | Styled scr _ <- oMathRunTextStyle mrPr
638− , Just ODoubleStruck <- scr =
639− Just $ TM.TextDoubleStruck
640− | Styled scr _ <- oMathRunTextStyle mrPr
641− , Just OScript <- scr =
642− Just $ TM.TextDoubleStruck
643− | Styled scr _ <- oMathRunTextStyle mrPr
644− , Just OFraktur <- scr =
645− Just $ TM.TextFraktur
646− | Styled _ sty <- oMathRunTextStyle mrPr
647− , Just OBoldItalic <- sty =
648− Just $ TM.TextBoldItalic
649− | otherwise = Nothing
650−
651−baseToExp :: Base -> TM.Exp
652−baseToExp b = case baseToExp' b of
653− (e : []) -> e
654− exps -> TM.EGrouped exps
655−
656−-- an ungrouped version of baseToExp
657−baseToExp' :: Base -> [TM.Exp]
658−baseToExp' (Base mathElems) =
659− concatMap oMathElemToExps mathElems
660−
661−elemToExps :: Element -> Maybe [TM.Exp]
662−elemToExps element = oMathToExps <$> (elemToMath element)
663−
664−
665elemToExps' :: Element -> Maybe [TM.Exp]
207elemToExps' :: Element -> Maybe [TM.Exp]
666elemToExps' element | isElem "m" "acc" element = do
208elemToExps' element | isElem "m" "acc" element = do
667 let chr = filterChildName (hasElemName "m" "accPr") element >>=
209 let chr = filterChildName (hasElemName "m" "accPr") element >>=
@@ -672,35 +214,31 @@ elemToExps' element | isElem "m" "acc" element = do
672 Just c -> c
214 Just c -> c
673 Nothing -> '\180' -- default to acute.
215 Nothing -> '\180' -- default to acute.
674 baseExp <- filterChildName (hasElemName "m" "e") element >>=
216 baseExp <- filterChildName (hasElemName "m" "e") element >>=
675− elemToBase >>=
217+ elemToBase
676− (return . baseToExp)
677 return $ [TM.EOver False baseExp (TM.ESymbol TM.Accent [chr'])]
218 return $ [TM.EOver False baseExp (TM.ESymbol TM.Accent [chr'])]
678elemToExps' element | isElem "m" "bar" element = do
219elemToExps' element | isElem "m" "bar" element = do
679 pos <- filterChildName (hasElemName "m" "barPr") element >>=
220 pos <- filterChildName (hasElemName "m" "barPr") element >>=
680 filterChildName (hasElemName "m" "pos") >>=
221 filterChildName (hasElemName "m" "pos") >>=
681− findAttrBy (hasElemName "m" "val")
222+ findAttrBy (hasElemName "m" "val")
682 baseExp <- filterChildName (hasElemName "m" "e") element >>=
223 baseExp <- filterChildName (hasElemName "m" "e") element >>=
683− elemToBase >>=
224+ elemToBase
684− (return . baseToExp)
685 case pos of
225 case pos of
686 "top" -> Just [TM.EOver False baseExp (TM.ESymbol TM.Accent "\175")]
226 "top" -> Just [TM.EOver False baseExp (TM.ESymbol TM.Accent "\175")]
687 "bot" -> Just [TM.EUnder False baseExp (TM.ESymbol TM.Accent "\818")]
227 "bot" -> Just [TM.EUnder False baseExp (TM.ESymbol TM.Accent "\818")]
688 _ -> Nothing
228 _ -> Nothing
689elemToExps' element | isElem "m" "box" element = do
229elemToExps' element | isElem "m" "box" element = do
690 baseExp <- filterChildName (hasElemName "m" "e") element >>=
230 baseExp <- filterChildName (hasElemName "m" "e") element >>=
691− elemToBase >>=
231+ elemToBase
692− (return . baseToExp)
693 return [baseExp]
232 return [baseExp]
694elemToExps' element | isElem "m" "borderBox" element = do
233elemToExps' element | isElem "m" "borderBox" element = do
695 -- TODO: This needs to be "\\boxed" somehow.
234 -- TODO: This needs to be "\\boxed" somehow.
696 baseExp <- filterChildName (hasElemName "m" "e") element >>=
235 baseExp <- filterChildName (hasElemName "m" "e") element >>=
697− elemToBase >>=
236+ elemToBase
698− (return . baseToExp)
699 return [baseExp]
237 return [baseExp]
700−elemToExps' element | isElem "m" "d" element =
238+elemToExps' element | isElem "m" "d" element =
701 let baseExps = mapMaybe
239 let baseExps = mapMaybe
702− (\e -> (elemToBase e >>= (return . baseToExp)))
240+ elemToBase
703− (elChildren element)
241+ (elChildren element)
704 inDelimExps = map Right baseExps
242 inDelimExps = map Right baseExps
705 dPr = filterChildName (hasElemName "m" "dPr") element
243 dPr = filterChildName (hasElemName "m" "dPr") element
706 begChr = dPr >>=
244 begChr = dPr >>=
@@ -722,10 +260,10 @@ elemToExps' element | isElem "m" "d" element =
722 in
260 in
723 Just [TM.EDelimited [beg] [end] exps]
261 Just [TM.EDelimited [beg] [end] exps]
724elemToExps' element | isElem "m" "eqArr" element =
262elemToExps' element | isElem "m" "eqArr" element =
725− let bases = mapMaybe (elemToBaseNoAmpersand) (elChildren element)
263+ let expLst = mapMaybe elemToBases (elChildren element)
726− baseExps = map (\b -> [baseToExp' b]) bases
264+ expLst' = map (\es -> [map filterAmpersand es]) expLst
727 in
265 in
728− return [TM.EArray [] baseExps]
266+ return [TM.EArray [] expLst']
729elemToExps' element | isElem "m" "f" element = do
267elemToExps' element | isElem "m" "f" element = do
730 num <- filterChildName (hasElemName "m" "num") element
268 num <- filterChildName (hasElemName "m" "num") element
731 den <- filterChildName (hasElemName "m" "den") element
269 den <- filterChildName (hasElemName "m" "den") element
@@ -735,8 +273,7 @@ elemToExps' element | isElem "m" "f" element = do
735elemToExps' element | isElem "m" "func" element = do
273elemToExps' element | isElem "m" "func" element = do
736 fName <- filterChildName (hasElemName "m" "fName") element
274 fName <- filterChildName (hasElemName "m" "fName") element
737 baseExp <- filterChildName (hasElemName "m" "e") element >>=
275 baseExp <- filterChildName (hasElemName "m" "e") element >>=
738− elemToBase >>=
276+ elemToBase
739− (return . baseToExp)
740 -- We need a string for the fname, but omml gives it to us as a
277 -- We need a string for the fname, but omml gives it to us as a
741 -- series of oMath elems. We're going to filter out the oMathRuns,
278 -- series of oMath elems. We're going to filter out the oMathRuns,
742 -- which should work for us most of the time.
279 -- which should work for us most of the time.
@@ -752,8 +289,7 @@ elemToExps' element | isElem "m" "groupChr" element = do
752 filterChildName (hasElemName "m" "pos") >>=
289 filterChildName (hasElemName "m" "pos") >>=
753 findAttrBy (hasElemName "m" "val")
290 findAttrBy (hasElemName "m" "val")
754 baseExp <- filterChildName (hasElemName "m" "e") element >>=
291 baseExp <- filterChildName (hasElemName "m" "e") element >>=
755− elemToBase >>=
292+ elemToBase
756− (return . baseToExp)
757 case pos of
293 case pos of
758 Just "top" ->
294 Just "top" ->
759 let chr' = case chr of
295 let chr' = case chr of
@@ -771,7 +307,6 @@ elemToExps' element | isElem "m" "groupChr" element = do
771elemToExps' element | isElem "m" "limLow" element = do
307elemToExps' element | isElem "m" "limLow" element = do
772 baseExp <- filterChildName (hasElemName "m" "e") element
308 baseExp <- filterChildName (hasElemName "m" "e") element
773 >>= elemToBase
309 >>= elemToBase
774− >>= (return . baseToExp)
775 limExp <- filterChildName (hasElemName "m" "lim") element
310 limExp <- filterChildName (hasElemName "m" "lim") element
776 >>= (\e -> Just $ concat $ mapMaybe (elemToExps') (elChildren e))
311 >>= (\e -> Just $ concat $ mapMaybe (elemToExps') (elChildren e))
777 >>= (return . TM.EGrouped)
312 >>= (return . TM.EGrouped)
@@ -779,16 +314,15 @@ elemToExps' element | isElem "m" "limLow" element = do
779elemToExps' element | isElem "m" "limUpp" element = do
314elemToExps' element | isElem "m" "limUpp" element = do
780 baseExp <- filterChildName (hasElemName "m" "e") element
315 baseExp <- filterChildName (hasElemName "m" "e") element
781 >>= elemToBase
316 >>= elemToBase
782− >>= (return . baseToExp)
783 limExp <- filterChildName (hasElemName "m" "lim") element
317 limExp <- filterChildName (hasElemName "m" "lim") element
784 >>= (\e -> Just $ concat $ mapMaybe (elemToExps') (elChildren e))
318 >>= (\e -> Just $ concat $ mapMaybe (elemToExps') (elChildren e))
785 >>= (return . TM.EGrouped)
319 >>= (return . TM.EGrouped)
786 return [TM.EOver True limExp baseExp]
320 return [TM.EOver True limExp baseExp]
787−elemToExps' element | isElem "m" "m" element =
321+elemToExps' element | isElem "m" "m" element =
788 let rows = filterChildrenName (hasElemName "m" "mr") element
322 let rows = filterChildrenName (hasElemName "m" "mr") element
789 rowExps = map
323 rowExps = map
790 (\mr -> mapMaybe
324 (\mr -> mapMaybe
791− (\e -> (elemToBase e >>= return . baseToExp'))
325+ elemToBases
792 (elChildren mr))
326 (elChildren mr))
793 rows
327 rows
794 in
328 in
@@ -809,8 +343,7 @@ elemToExps' element | isElem "m" "nary" element = do
809 supExps <- filterChildName (hasElemName "m" "sup") element >>=
343 supExps <- filterChildName (hasElemName "m" "sup") element >>=
810 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
344 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
811 baseExp <- filterChildName (hasElemName "m" "e") element >>=
345 baseExp <- filterChildName (hasElemName "m" "e") element >>=
812− elemToBase >>=
346+ elemToBase
813− (return . baseToExp)
814 case limLoc of
347 case limLoc of
815 Just "undOvr" -> return [TM.EUnderover True
348 Just "undOvr" -> return [TM.EUnderover True
816 (TM.ESymbol TM.Op [opChr])
349 (TM.ESymbol TM.Op [opChr])
@@ -825,15 +358,13 @@ elemToExps' element | isElem "m" "nary" element = do
825
358
826elemToExps' element | isElem "m" "phant" element = do
359elemToExps' element | isElem "m" "phant" element = do
827 baseExp <- filterChildName (hasElemName "m" "e") element >>=
360 baseExp <- filterChildName (hasElemName "m" "e") element >>=
828− elemToBase >>=
361+ elemToBase
829− (return . baseToExp)
830 return [TM.EPhantom baseExp]
362 return [TM.EPhantom baseExp]
831elemToExps' element | isElem "m" "rad" element = do
363elemToExps' element | isElem "m" "rad" element = do
832 degExps <- filterChildName (hasElemName "m" "deg") element >>=
364 degExps <- filterChildName (hasElemName "m" "deg") element >>=
833 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
365 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
834 baseExp <- filterChildName (hasElemName "m" "e") element >>=
366 baseExp <- filterChildName (hasElemName "m" "e") element >>=
835− elemToBase >>=
367+ elemToBase
836− (return . baseToExp)
837 return $ case degExps of
368 return $ case degExps of
838 [] -> [TM.ESqrt baseExp]
369 [] -> [TM.ESqrt baseExp]
839 ds -> [TM.ERoot (TM.EGrouped ds) baseExp]
370 ds -> [TM.ERoot (TM.EGrouped ds) baseExp]
@@ -843,8 +374,7 @@ elemToExps' element | isElem "m" "sPre" element = do
843 supExps <- filterChildName (hasElemName "m" "sup") element >>=
374 supExps <- filterChildName (hasElemName "m" "sup") element >>=
844 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
375 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
845 baseExp <- filterChildName (hasElemName "m" "e") element >>=
376 baseExp <- filterChildName (hasElemName "m" "e") element >>=
846− elemToBase >>=
377+ elemToBase
847− (return . baseToExp)
848 return [TM.ESubsup
378 return [TM.ESubsup
849 (TM.EIdentifier "")
379 (TM.EIdentifier "")
850 (TM.EGrouped subExps)
380 (TM.EGrouped subExps)
@@ -852,15 +382,13 @@ elemToExps' element | isElem "m" "sPre" element = do
852 , baseExp]
382 , baseExp]
853elemToExps' element | isElem "m" "sSub" element = do
383elemToExps' element | isElem "m" "sSub" element = do
854 baseExp <- filterChildName (hasElemName "m" "e") element >>=
384 baseExp <- filterChildName (hasElemName "m" "e") element >>=
855− elemToBase >>=
385+ elemToBase
856− (return . baseToExp)
857 subExps <- filterChildName (hasElemName "m" "sub") element >>=
386 subExps <- filterChildName (hasElemName "m" "sub") element >>=
858 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
387 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
859 return [TM.ESub baseExp (TM.EGrouped subExps)]
388 return [TM.ESub baseExp (TM.EGrouped subExps)]
860elemToExps' element | isElem "m" "sSubSup" element = do
389elemToExps' element | isElem "m" "sSubSup" element = do
861 baseExp <- filterChildName (hasElemName "m" "e") element >>=
390 baseExp <- filterChildName (hasElemName "m" "e") element >>=
862− elemToBase >>=
391+ elemToBase
863− (return . baseToExp)
864 subExps <- filterChildName (hasElemName "m" "sub") element >>=
392 subExps <- filterChildName (hasElemName "m" "sub") element >>=
865 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
393 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
866 supExps <- filterChildName (hasElemName "m" "sup") element >>=
394 supExps <- filterChildName (hasElemName "m" "sup") element >>=
@@ -868,8 +396,7 @@ elemToExps' element | isElem "m" "sSubSup" element = do
868 return [TM.ESubsup baseExp (TM.EGrouped subExps) (TM.EGrouped supExps)]
396 return [TM.ESubsup baseExp (TM.EGrouped subExps) (TM.EGrouped supExps)]
869elemToExps' element | isElem "m" "sSup" element = do
397elemToExps' element | isElem "m" "sSup" element = do
870 baseExp <- filterChildName (hasElemName "m" "e") element >>=
398 baseExp <- filterChildName (hasElemName "m" "e") element >>=
871− elemToBase >>=
399+ elemToBase
872− (return . baseToExp)
873 supExps <- filterChildName (hasElemName "m" "sup") element >>=
400 supExps <- filterChildName (hasElemName "m" "sup") element >>=
874 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
401 (\e -> return $ concat $ mapMaybe (elemToExps') (elChildren e))
875 return [TM.ESuper baseExp (TM.EGrouped supExps)]
402 return [TM.ESuper baseExp (TM.EGrouped supExps)]
@@ -890,6 +417,7 @@ elemToExps' element | isElem "m" "r" element = do
890 [TM.EStyled textType [TM.EIdentifier $ oMathRunElemsToString mrElems]]
417 [TM.EStyled textType [TM.EIdentifier $ oMathRunElemsToString mrElems]]
891elemToExps' _ = Nothing
418elemToExps' _ = Nothing
892
419
420+
893expToString :: TM.Exp -> String
421expToString :: TM.Exp -> String
894expToString (TM.ENumber s) = s
422expToString (TM.ENumber s) = s
895expToString (TM.EIdentifier s) = s
423expToString (TM.EIdentifier s) = s
src/Text/Pandoc/Readers/Docx/Parse.hs+4−14
@@ -61,7 +61,7 @@ import qualified Text.Pandoc.UTF8 as UTF8
61import Control.Monad.Reader
61import Control.Monad.Reader
62import qualified Data.Map as M
62import qualified Data.Map as M
63import Text.Pandoc.Compat.Except
63import Text.Pandoc.Compat.Except
64−import Text.Pandoc.Readers.Docx.OMath (elemToExps)
64+import Text.Pandoc.Readers.Docx.OMath (readOMML)
65import Text.TeXMath (Exp)
65import Text.TeXMath (Exp)
66
66
67data ReaderEnv = ReaderEnv { envNotes :: Notes
67data ReaderEnv = ReaderEnv { envNotes :: Notes
@@ -475,7 +475,7 @@ elemToBodyPart ns element
475 | isElem ns "w" "p" element
475 | isElem ns "w" "p" element
476 , (c:_) <- findChildren (elemName ns "m" "oMathPara") element =
476 , (c:_) <- findChildren (elemName ns "m" "oMathPara") element =
477 do
477 do
478− expsLst <- mapD (\e -> (maybeToD $ elemToExps e)) (elChildren c)
478+ expsLst <- mapD (\e -> (maybeToD $ readOMML e)) (elChildren c)
479 return $ OMathPara expsLst
479 return $ OMathPara expsLst
480elemToBodyPart ns element
480elemToBodyPart ns element
481 | isElem ns "w" "p" element
481 | isElem ns "w" "p" element
@@ -574,8 +574,8 @@ elemToParPart ns element
574 Just target -> ExternalHyperLink target runs
574 Just target -> ExternalHyperLink target runs
575 Nothing -> ExternalHyperLink "" runs
575 Nothing -> ExternalHyperLink "" runs
576elemToParPart ns element
576elemToParPart ns element
577− | isElem ns "m" "oMath" element =
577+ | isElem ns "m" "oMath" element =
578− (maybeToD $ elemToExps element) >>= (return . PlainOMath)
578+ (maybeToD $ readOMML element) >>= (return . PlainOMath)
579elemToParPart _ _ = throwError WrongElem
579elemToParPart _ _ = throwError WrongElem
580
580
581lookupFootnote :: String -> Notes -> Maybe Element
581lookupFootnote :: String -> Notes -> Maybe Element
@@ -677,13 +677,3 @@ elemToRunElems ns element
677 || isElem ns "m" "r" element =
677 || isElem ns "m" "r" element =
678 mapD (elemToRunElem ns) (elChildren element)
678 mapD (elemToRunElem ns) (elChildren element)
679elemToRunElems _ _ = throwError WrongElem
679elemToRunElems _ _ = throwError WrongElem
680−
681−
682−
683−
684−
685−
686−
687−
688−
689−