git.iko.soy/typeable/pandoc
on master help sign in
OpenDocument Writer: Fixed handling of spaces and tabs in preformatted blocks.

git-svn-id: https://pandoc.googlecode.com/svn/trunk@1286 788f1e2b-df1e-0410-8736-df70ead52e1b

commit5eb204c86c3ab3bd413a89a7f29564498c846567 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateThu 12 Jun 2008, 17:14 (18 years ago) parentd07e582
1 file changed+25−11
Text/Pandoc/Writers/OpenDocument.hs+25−11
Text/Pandoc/Writers/OpenDocument.hs+25−11
@@ -36,7 +36,8 @@ import Text.Pandoc.XML
3636import Text.Pandoc.Readers.TeXMath
3737import Text.PrettyPrint.HughesPJ hiding ( Str )
3838
39−import Control.Applicative ((<$>))
39+import Control.Applicative ( (<$>) )
40+import Control.Arrow ( (***), (>>>) )
4041import Control.Monad.State hiding ( when )
4142import Data.Char (chr)
4243
@@ -68,6 +69,9 @@ defaultWriterState =
6869 , inDefinition = False
6970 }
7071
72+when :: Bool -> Doc -> Doc
73+when p a = if p then a else empty
74+
7175addTableStyle :: Doc -> State WriterState ()
7276addTableStyle i = modify $ \s -> s { stTableStyles = i : stTableStyles s }
7377
@@ -103,6 +107,19 @@ inQuotes :: QuoteType -> Doc -> Doc
103107inQuotes SingleQuote s = text "&#8216;" <> s <> text "&#8217;"
104108inQuotes DoubleQuote s = text "&#8220;" <> s <> text "&#8221;"
105109
110+handleSpaces :: String -> Doc
111+handleSpaces s
112+ | ( ' ':_) <- s = genTag s
113+ | ('\t':x) <- s = selfClosingTag "text:tab" [] <> rm x
114+ | otherwise = rm s
115+ where
116+ genTag = span (==' ') >>> tag . length *** rm >>> uncurry (<>)
117+ tag n = when (n /= 0) $ selfClosingTag "text:s" [("text:c", show n)]
118+ rm ( ' ':xs) = char ' ' <> genTag xs
119+ rm ('\t':xs) = selfClosingTag "text:tab" [] <> genTag xs
120+ rm ( x:xs) = char x <> rm xs
121+ rm [] = empty
122+
106123-- | Convert list of authors to a docbook <author> section
107124authorToOpenDocument :: [Char] -> Doc
108125authorToOpenDocument name =
@@ -125,8 +142,7 @@ authorToOpenDocument name =
125142-- | Convert Pandoc document to string in OpenDocument format.
126143writeOpenDocument :: WriterOptions -> Pandoc -> String
127144writeOpenDocument opts (Pandoc (Meta title authors date) blocks) =
128− let when p a = if p then a else empty
129− root = inTags True "office:document-content" openDocumentNameSpaces
145+ let root = inTags True "office:document-content" openDocumentNameSpaces
130146 header = when (writerStandalone opts) $ text (writerHeader opts)
131147 title' = case runState (wrap opts title) defaultWriterState of
132148 (t,_) -> if isEmpty t then empty else inHeaderTags 1 t
@@ -136,7 +152,6 @@ writeOpenDocument opts (Pandoc (Meta title authors date) blocks) =
136152 before = writerIncludeBefore opts
137153 after = writerIncludeAfter opts
138154 (doc, s) = runState (blocksToOpenDocument opts blocks) defaultWriterState
139−
140155 body = (if null before then empty else text before) $$
141156 doc $$
142157 (if null after then empty else text after)
@@ -158,7 +173,7 @@ withParagraphStyle _ _ [] = return empty
158173inPreformattedTags :: String -> State WriterState Doc
159174inPreformattedTags s = do
160175 n <- paraStyle "Preformatted_20_Text" []
161− return . inParagraphTagsWithStyle ("P" ++ show n) . text $ s
176+ return . inParagraphTagsWithStyle ("P" ++ show n) . handleSpaces $ s
162177
163178orderedListToOpenDocument :: WriterOptions -> Int -> [[Block]] -> State WriterState Doc
164179orderedListToOpenDocument o pn bs =
@@ -212,7 +227,7 @@ inBlockQuote o i (b:bs)
212227 go ni =<< inBlockQuote o ni l
213228 | Para l <- b = do go i =<< inParagraphTagsWithStyle ("P" ++ show i) <$> inlinesToOpenDocument o l
214229 | otherwise = do go i =<< blockToOpenDocument o b
215− where go ni block = ($$) block <$> inBlockQuote o ni bs
230+ where go ni block = ($$) block <$> inBlockQuote o ni bs
216231inBlockQuote _ _ [] = resetIndent >> return empty
217232
218233-- | Convert a list of Pandoc blocks to OpenDocument.
@@ -306,7 +321,7 @@ inlineToOpenDocument o ils
306321 | Apostrophe <- ils = return $ text "&#8217;"
307322 | Space <- ils = return $ char ' '
308323 | LineBreak <- ils = return $ selfClosingTag "text:line-break" []
309− | Str s <- ils = return $ text $ escapeStringForXML s
324+ | Str s <- ils = return $ handleSpaces $ escapeStringForXML s
310325 | Emph l <- ils = inSpanTags "Emphasis" <$> inlinesToOpenDocument o l
311326 | Strong l <- ils = inSpanTags "Strong_20_Emphasis" <$> inlinesToOpenDocument o l
312327 | Strikeout l <- ils = inSpanTags "Strikeout" <$> inlinesToOpenDocument o l
@@ -322,7 +337,7 @@ inlineToOpenDocument o ils
322337 | Note l <- ils = mkNote l
323338 | otherwise = return empty
324339 where
325− preformatted = return . inSpanTags "Teletype" . text . escapeStringForXML
340+ preformatted = return . inSpanTags "Teletype" . handleSpaces . escapeStringForXML
326341 mkLink s t = inTags False "text:a" [ ("xlink:type" , "simple")
327342 , ("xlink:href" , s )
328343 , ("office:name", t )
@@ -419,9 +434,8 @@ paraStyle parent attrs = do
419434 , ("style:family" , "paragraph" )
420435 , ("style:parent-style-name", parent )]
421436 indentVal = flip (++) "in" . show $ if b then (max 0.5 i) else i
422− indent = if i == 0 && not b
423− then empty
424− else selfClosingTag "style:paragraph-properties"
437+ indent = when (i /= 0 || b) $
438+ selfClosingTag "style:paragraph-properties"
425439 [ ("fo:margin-left" , indentVal)
426440 , ("fo:margin-right" , "0in" )
427441 , ("fo:text-indent" , "0in" )