{-
Copyright (C) 2008-2010 John MacFarlane <jgm@berkeley.edu>
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 for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-}{- |
Module : Text.Pandoc.Writers.ODT
Copyright : Copyright (C) 2008-2010 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
Stability : alpha
Portability : portable
Conversion of 'Pandoc' documents to ODT.
-}moduleText.Pandoc.Writers.ODT(writeODT)whereimportData.IORefimportData.List(isPrefixOf)importSystem.FilePath((</>),takeExtension)importqualifiedData.ByteString.LazyasBimportData.ByteString.Lazy.UTF8(fromString)importCodec.Archive.ZipimportData.Time.Clock.POSIXimportPaths_pandoc(getDataFileName)importText.Pandoc.Shared(WriterOptions(..))importText.Pandoc.ImageSize(readImageSize,sizeInPoints)importText.Pandoc.MIME(getMimeType)importText.Pandoc.DefinitionimportText.Pandoc.GenericimportText.Pandoc.Writers.OpenDocument(writeOpenDocument)importSystem.DirectoryimportControl.Monad(liftM)importNetwork.URI(unEscapeString)importText.Pandoc.XMLimportText.Pandoc.Pretty-- | Produce an ODT file from a Pandoc document.writeODT::MaybeFilePath-- ^ Path specified by --reference-odt->WriterOptions-- ^ Writer options->Pandoc-- ^ Document to convert->IOB.ByteStringwriteODTmbRefOdtoptsdoc=doletdatadir=writerUserDataDiroptsrefArchive<-liftMtoArchive$casembRefOdtofJustf->B.readFilefNothing->doletdefaultODT=getDataFileName"reference.odt">>=B.readFilecasedatadirofNothing->defaultODTJustd->doexists<-doesFileExist(d</>"reference.odt")ifexiststhenB.readFile(d</>"reference.odt")elsedefaultODT-- handle picturespicEntriesRef<-newIORef([]::[Entry])letsourceDir=writerSourceDirectoryoptsdoc'<-bottomUpM(transformPicsourceDirpicEntriesRef)docletnewContents=writeOpenDocumentopts{writerWrapText=False}doc'epochtime<-floor`fmap`getPOSIXTimeletcontentEntry=toEntry"content.xml"epochtime$fromStringnewContentspicEntries<-readIORefpicEntriesRefletarchive=foldraddEntryToArchiverefArchive$contentEntry:picEntries-- construct META-INF/manifest.xml based on archivelettoFileEntryfp=casegetMimeTypefpofNothing->emptyJustm->selfClosingTag"manifest:file-entry"[("manifest:media-type",m),("manifest:full-path",fp)]letfiles=[ent|ent<-filesInArchivearchive,not("META-INF"`isPrefixOf`ent)]letmanifestEntry=toEntry"META-INF/manifest.xml"epochtime$fromString$show$text"<?xml version=\"1.0\" encoding=\"utf-8\"?>"$$(inTagsTrue"manifest:manifest"[("xmlns:manifest","urn:oasis:names:tc:opendocument:xmlns:manifest:1.0")]$(selfClosingTag"manifest:file-entry"[("manifest:media-type","application/vnd.oasis.opendocument.text"),("manifest:version","1.2"),("manifest:full-path","/")]$$vcat(maptoFileEntry$files)))letarchive'=addEntryToArchivemanifestEntryarchivereturn$fromArchivearchive'transformPic::FilePath->IORef[Entry]->Inline->IOInlinetransformPicsourceDirentriesRef(Imagelab(src,tit))=doletsrc'=unEscapeStringsrcmbSize<-readImageSizesrc'lettit'=casembSizeofJusts->let(w,h)=sizeInPointssinshoww++"x"++showhNothing->titentries<-readIORefentriesRefletnewsrc="Pictures/"++show(lengthentries)++takeExtensionsrc'catch(readEntry[](sourceDir</>src')>>=\entry->modifyIORefentriesRef(entry{eRelativePath=newsrc}:)>>return(Imagelab(newsrc,tit')))(\_->return(Emphlab))transformPic__x=returnx