@@ -1,5 +1,7 @@
1{-# LANGUAGE NoImplicitPrelude #-}
1{-# LANGUAGE NoImplicitPrelude #-}
2{-# LANGUAGE Arrows #-}
2{-# LANGUAGE Arrows #-}
3+{-# LANGUAGE DeriveFoldable #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE PatternGuards #-}
5{-# LANGUAGE PatternGuards #-}
4{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE TupleSections #-}
7{-# LANGUAGE TupleSections #-}
@@ -26,21 +28,26 @@ import Control.Applicative hiding (liftA, liftA2, liftA3)
26import Control.Arrow
28import Control.Arrow
28import qualified Data.ByteString.Lazy as B
30import qualified Data.ByteString.Lazy as B
31+import Data.Foldable (fold)
29−import Data.List (find, intercalate)
32+import Data.List (find, intercalate, stripPrefix)
30import qualified Data.Map as M
33import qualified Data.Map as M
31import Data.Maybe
34import Data.Maybe
35+import Data.Semigroup (First(..), Option(..))
37+import Text.TeXMath (readMathML, writeTeX)
33import qualified Text.XML.Light as XML
38import qualified Text.XML.Light as XML
35import Text.Pandoc.Builder
40import Text.Pandoc.Builder
36import Text.Pandoc.MediaBag (MediaBag, insertMedia)
41import Text.Pandoc.MediaBag (MediaBag, insertMedia)
37import Text.Pandoc.Shared
42import Text.Pandoc.Shared
38import Text.Pandoc.Extensions (extensionsFromList, Extension(..))
43import Text.Pandoc.Extensions (extensionsFromList, Extension(..))
44+import qualified Text.Pandoc.UTF8 as UTF8
40import Text.Pandoc.Readers.Odt.Base
46import Text.Pandoc.Readers.Odt.Base
41import Text.Pandoc.Readers.Odt.Namespaces
47import Text.Pandoc.Readers.Odt.Namespaces
42import Text.Pandoc.Readers.Odt.StyleReader
48import Text.Pandoc.Readers.Odt.StyleReader
50+import Text.Pandoc.Readers.Odt.Arrows.State (foldS)
44import Text.Pandoc.Readers.Odt.Arrows.Utils
51import Text.Pandoc.Readers.Odt.Arrows.Utils
45import Text.Pandoc.Readers.Odt.Generic.Fallible
52import Text.Pandoc.Readers.Odt.Generic.Fallible
46import Text.Pandoc.Readers.Odt.Generic.Utils
53import Text.Pandoc.Readers.Odt.Generic.Utils
@@ -498,6 +505,13 @@ type InlineMatcher = ElementMatcher Inlines
498type BlockMatcher = ElementMatcher Blocks
505type BlockMatcher = ElementMatcher Blocks
508+newtype FirstMatch a = FirstMatch (Option (First a))
509+ deriving (Foldable, Monoid, Semigroup)
511+firstMatch :: a -> FirstMatch a
512+firstMatch = FirstMatch . Option . Just . First
502matchingElement :: (Monoid e)
516matchingElement :: (Monoid e)
503 => Namespace -> ElementName
517 => Namespace -> ElementName
@@ -598,7 +612,7 @@ read_paragraph = matchingElement NsText "p"
598 , read_reference_start
612 , read_reference_start
599 , read_bookmark_ref
613 , read_bookmark_ref
600 , read_reference_ref
614 , read_reference_ref
601− , read_maybe_nested_img_frame
615+ , read_frame
602 , read_text_seq
616 , read_text_seq
603 ] read_plain_text
617 ] read_plain_text
@@ -624,7 +638,7 @@ read_header = matchingElement NsText "h"
624 , read_reference_start
638 , read_reference_start
625 , read_bookmark_ref
639 , read_bookmark_ref
626 , read_reference_ref
640 , read_reference_ref
627− , read_maybe_nested_img_frame
641+ , read_frame
628 ] read_plain_text
642 ] read_plain_text
629 ) -< blocks
643 ) -< blocks
630 anchor <- getHeaderAnchor -< children
644 anchor <- getHeaderAnchor -< children
@@ -737,32 +751,43 @@ read_table_cell = matchingElement NsTable "table-cell"
739----------------------
753----------------------
740−-- Images
754+-- Frames
741----------------------
755----------------------
744−read_maybe_nested_img_frame :: InlineMatcher
758+read_frame :: InlineMatcher
745−read_maybe_nested_img_frame = matchingElement NsDraw "frame"
759+read_frame = matchingElement NsDraw "frame"
746− $ proc blocks -> do
760+ $ filterChildrenName' NsDraw (`elem` ["image", "object", "text-box"])
747− img <- (findChild' NsDraw "image") -< ()
761+ >>> foldS read_frame_child
748− case img of
762+ >>> arr fold
749− Just _ -> read_frame -< blocks
763+
764+read_frame_child :: OdtReaderSafe XML.Element (FirstMatch Inlines)
766+ proc child -> case elName child of
767+ "image" -> read_frame_img -< child
768+ "object" -> read_frame_mathml -< child
750− Nothing -> matchChildContent' [ read_frame_text_box ] -< blocks
769+ "text-box" -> read_frame_text_box -< child
751−
770+ _ -> returnV mempty -< ()
752−read_frame :: OdtReaderSafe Inlines Inlines
772+read_frame_img :: OdtReaderSafe XML.Element (FirstMatch Inlines)
753−read_frame =
773+read_frame_img =
754− proc blocks -> do
774+ proc img -> do
775+ src <- executeIn (findAttr' NsXLink "href") -< img
777+ "" -> returnV mempty -< ()
755− let exts = extensionsFromList [Ext_auto_identifiers]
779+ let exts = extensionsFromList [Ext_auto_identifiers]
780+ resource <- lookupResource -< src'
781+ _ <- updateMediaWithResource -< resource
756− w <- ( findAttr' NsSVG "width" ) -< ()
782+ w <- findAttr' NsSVG "width" -< ()
757− h <- ( findAttr' NsSVG "height" ) -< ()
783+ h <- findAttr' NsSVG "height" -< ()
758− titleNodes <- ( matchChildContent' [ read_frame_title ] ) -< blocks
784+ titleNodes <- matchChildContent' [ read_frame_title ] -< ()
759− src <- matchChildContent' [ read_image_src ] -< blocks
760− resource <- lookupResource -< src
761− _ <- updateMediaWithResource -< resource
762− alt <- (matchChildContent [] read_plain_text) -< blocks
785+ alt <- matchChildContent [] read_plain_text -< ()
763− arr (uncurry4 imageWith ) -<
786+ arr (firstMatch . uncurry4 imageWith) -<
764− (image_attributes w h, src,
765− inlineListToIdentifier exts (toList titleNodes), alt)
787+ (image_attributes w h, src', inlineListToIdentifier exts (toList titleNodes), alt)
789+read_frame_title :: InlineMatcher
790+read_frame_title = matchingElement NsSVG "title" (matchChildContent [] read_plain_text)
767image_attributes :: Maybe String -> Maybe String -> Attr
792image_attributes :: Maybe String -> Maybe String -> Attr
768image_attributes x y =
793image_attributes x y =
@@ -772,28 +797,29 @@ image_attributes x y =
772 dim name (Just v) = [(name, v)]
797 dim name (Just v) = [(name, v)]
773 dim _ Nothing = []
798 dim _ Nothing = []
775−read_image_src :: (Namespace, ElementName, OdtReader Anchor Anchor)
800+read_frame_mathml :: OdtReaderSafe XML.Element (FirstMatch Inlines)
776−read_image_src = matchingElement NsDraw "image"
801+read_frame_mathml =
777− $ proc _ -> do
802+ proc obj -> do
778− imgSrc <- findAttr NsXLink "href" -< ()
803+ src <- executeIn (findAttr' NsXLink "href") -< obj
779− case imgSrc of
804+ case fold src of
780− Right src -> returnV src -<< ()
805+ "" -> returnV mempty -< ()
807+ let path = fromMaybe src' (stripPrefix "./" src') ++ "/content.xml"
808+ (_, mathml) <- lookupResource -< path
809+ case readMathML (UTF8.toString $ B.toStrict mathml) of
781− Left _ -> returnV "" -< ()
810+ Left _ -> returnV mempty -< ()
782−
811+ Right exps -> arr (firstMatch . displayMath . writeTeX) -< exps
783−read_frame_title :: InlineMatcher
812+
784−read_frame_title = matchingElement NsSVG "title" (matchChildContent [] read_plain_text)
786−read_frame_text_box :: InlineMatcher
813+read_frame_text_box :: OdtReaderSafe XML.Element (FirstMatch Inlines)
787−read_frame_text_box = matchingElement NsDraw "text-box"
814+read_frame_text_box = proc box -> do
789− paragraphs <- (matchChildContent' [ read_paragraph ]) -< blocks
815+ paragraphs <- executeIn (matchChildContent' [ read_paragraph ]) -< box
790− arr read_img_with_caption -< toList paragraphs
816+ arr read_img_with_caption -< toList paragraphs
792−read_img_with_caption :: [Block] -> Inlines
818+read_img_with_caption :: [Block] -> FirstMatch Inlines
793read_img_with_caption (Para [Image attr alt (src,title)] : _) =
819read_img_with_caption (Para [Image attr alt (src,title)] : _) =
794− singleton (Image attr alt (src, 'f':'i':'g':':':title)) -- no text, default caption
820+ firstMatch $ singleton (Image attr alt (src, 'f':'i':'g':':':title)) -- no text, default caption
795read_img_with_caption (Para (Image attr _ (src,title) : txt) : _) =
821read_img_with_caption (Para (Image attr _ (src,title) : txt) : _) =
796− singleton (Image attr txt (src, 'f':'i':'g':':':title) ) -- override caption with the text that follows
822+ firstMatch $ singleton (Image attr txt (src, 'f':'i':'g':':':title) ) -- override caption with the text that follows
797read_img_with_caption ( Para (_ : xs) : ys) =
823read_img_with_caption ( Para (_ : xs) : ys) =
798 read_img_with_caption (Para xs : ys)
824 read_img_with_caption (Para xs : ys)
799read_img_with_caption _ =
825read_img_with_caption _ =
@@ -901,8 +927,8 @@ post_process' (Table _ a w h r : Div ("", ["caption"], _) [Para inlines] : xs) =
901post_process' bs = bs
927post_process' bs = bs
903read_body :: OdtReader _x (Pandoc, MediaBag)
929read_body :: OdtReader _x (Pandoc, MediaBag)
904−read_body = executeIn NsOffice "body"
930+read_body = executeInSub NsOffice "body"
905− $ executeIn NsOffice "text"
931+ $ executeInSub NsOffice "text"
906 $ liftAsSuccess
932 $ liftAsSuccess
907 $ proc inlines -> do
933 $ proc inlines -> do
908 txt <- read_text -< inlines
934 txt <- read_text -< inlines