Blame src/Text/Pandoc/Readers/Odt.hs

Packit Service d2f85f
{-# LANGUAGE PatternGuards #-}
Packit Service d2f85f
Packit Service d2f85f
{-
Packit Service d2f85f
Copyright (C) 2015 Martin Linnemann <theCodingMarlin@googlemail.com>
Packit Service d2f85f
Packit Service d2f85f
This program is free software; you can redistribute it and/or modify
Packit Service d2f85f
it under the terms of the GNU General Public License as published by
Packit Service d2f85f
the Free Software Foundation; either version 2 of the License, or
Packit Service d2f85f
(at your option) any later version.
Packit Service d2f85f
Packit Service d2f85f
This program is distributed in the hope that it will be useful,
Packit Service d2f85f
but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d2f85f
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d2f85f
GNU General Public License for more details.
Packit Service d2f85f
Packit Service d2f85f
You should have received a copy of the GNU General Public License
Packit Service d2f85f
along with this program; if not, write to the Free Software
Packit Service d2f85f
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service d2f85f
-}
Packit Service d2f85f
Packit Service d2f85f
{- |
Packit Service d2f85f
   Module      : Text.Pandoc.Reader.Odt
Packit Service d2f85f
   Copyright   : Copyright (C) 2015 Martin Linnemann
Packit Service d2f85f
   License     : GNU GPL, version 2 or above
Packit Service d2f85f
Packit Service d2f85f
   Maintainer  : Martin Linnemann <theCodingMarlin@googlemail.com>
Packit Service d2f85f
   Stability   : alpha
Packit Service d2f85f
   Portability : portable
Packit Service d2f85f
Packit Service d2f85f
Entry point to the odt reader.
Packit Service d2f85f
-}
Packit Service d2f85f
Packit Service d2f85f
module Text.Pandoc.Readers.Odt ( readOdt ) where
Packit Service d2f85f
Packit Service d2f85f
import Codec.Archive.Zip
Packit Service d2f85f
import qualified Text.XML.Light as XML
Packit Service d2f85f
Packit Service d2f85f
import qualified Data.ByteString.Lazy as B
Packit Service d2f85f
Packit Service d2f85f
import System.FilePath
Packit Service d2f85f
Packit Service d2f85f
import Control.Monad.Except (throwError)
Packit Service d2f85f
Packit Service d2f85f
import Text.Pandoc.Class (PandocMonad)
Packit Service d2f85f
import qualified Text.Pandoc.Class as P
Packit Service d2f85f
import Text.Pandoc.Definition
Packit Service d2f85f
import Text.Pandoc.Error
Packit Service d2f85f
import Text.Pandoc.MediaBag
Packit Service d2f85f
import Text.Pandoc.Options
Packit Service d2f85f
import qualified Text.Pandoc.UTF8 as UTF8
Packit Service d2f85f
Packit Service d2f85f
import Text.Pandoc.Readers.Odt.ContentReader
Packit Service d2f85f
import Text.Pandoc.Readers.Odt.StyleReader
Packit Service d2f85f
Packit Service d2f85f
import Text.Pandoc.Readers.Odt.Generic.Fallible
Packit Service d2f85f
import Text.Pandoc.Readers.Odt.Generic.XMLConverter
Packit Service d2f85f
import Text.Pandoc.Shared (filteredFilesFromArchive)
Packit Service d2f85f
Packit Service d2f85f
readOdt :: PandocMonad m
Packit Service d2f85f
        => ReaderOptions
Packit Service d2f85f
        -> B.ByteString
Packit Service d2f85f
        -> m Pandoc
Packit Service d2f85f
readOdt opts bytes = case readOdt' opts bytes of
Packit Service d2f85f
  Right (doc, mb) -> do
Packit Service d2f85f
    P.setMediaBag mb
Packit Service d2f85f
    return doc
Packit Service d2f85f
  Left e -> throwError e
Packit Service d2f85f
Packit Service d2f85f
--
Packit Service d2f85f
readOdt' :: ReaderOptions
Packit Service d2f85f
         -> B.ByteString
Packit Service d2f85f
         -> Either PandocError (Pandoc, MediaBag)
Packit Service d2f85f
readOdt' _ bytes = bytesToOdt bytes-- of
Packit Service d2f85f
--                    Right (pandoc, mediaBag) -> Right (pandoc , mediaBag)
Packit Service d2f85f
--                    Left  err                -> Left err
Packit Service d2f85f
Packit Service d2f85f
--
Packit Service d2f85f
bytesToOdt :: B.ByteString -> Either PandocError (Pandoc, MediaBag)
Packit Service d2f85f
bytesToOdt bytes = case toArchiveOrFail bytes of
Packit Service d2f85f
  Right archive -> archiveToOdt archive
Packit Service d2f85f
  Left _        -> Left $ PandocParseError "Couldn't parse odt file."
Packit Service d2f85f
Packit Service d2f85f
--
Packit Service d2f85f
archiveToOdt :: Archive -> Either PandocError (Pandoc, MediaBag)
Packit Service d2f85f
archiveToOdt archive
Packit Service d2f85f
  | Just contentEntry      <- findEntryByPath "content.xml" archive
Packit Service d2f85f
  , Just stylesEntry       <- findEntryByPath "styles.xml"  archive
Packit Service d2f85f
  , Just contentElem       <- entryToXmlElem contentEntry
Packit Service d2f85f
  , Just stylesElem        <- entryToXmlElem stylesEntry
Packit Service d2f85f
  , Right styles           <- chooseMax (readStylesAt stylesElem )
Packit Service d2f85f
                                        (readStylesAt contentElem)
Packit Service d2f85f
  , media                  <- filteredFilesFromArchive archive filePathIsOdtMedia
Packit Service d2f85f
  , startState             <- readerState styles media
Packit Service d2f85f
  , Right pandocWithMedia  <- runConverter' read_body
Packit Service d2f85f
                                            startState
Packit Service d2f85f
                                            contentElem
Packit Service d2f85f
Packit Service d2f85f
  = Right pandocWithMedia
Packit Service d2f85f
Packit Service d2f85f
  | otherwise
Packit Service d2f85f
    -- Not very detailed, but I don't think more information would be helpful
Packit Service d2f85f
  = Left $ PandocParseError "Couldn't parse odt file."
Packit Service d2f85f
    where
Packit Service d2f85f
      filePathIsOdtMedia :: FilePath -> Bool
Packit Service d2f85f
      filePathIsOdtMedia fp =
Packit Service d2f85f
        let (dir, _) = splitFileName fp
Packit Service d2f85f
        in
Packit Service d2f85f
         (dir == "Pictures/")
Packit Service d2f85f
Packit Service d2f85f
Packit Service d2f85f
--
Packit Service d2f85f
entryToXmlElem :: Entry -> Maybe XML.Element
Packit Service d2f85f
entryToXmlElem = XML.parseXMLDoc . UTF8.toStringLazy . fromEntry