git.iko.soy/typeable/pandoc
on master help sign in
Changes to RTF writer:
c6323b2fiddlosopher
src/Text/Pandoc/Writers/RTF.hs+91−46
@@ -41,7 +41,8 @@ writeRTF options (Pandoc meta blocks) =
41 then rtfHeader (writerHeader options) meta
41 then rtfHeader (writerHeader options) meta
42 else ""
42 else ""
43 foot = if writerStandalone options then "\n}\n" else ""
43 foot = if writerStandalone options then "\n}\n" else ""
44− body = (writerIncludeBefore options) ++ concatMap (blockToRTF 0) blocks ++
44+ body = (writerIncludeBefore options) ++
45+ concatMap (blockToRTF 0 AlignDefault) blocks ++
45 (writerIncludeAfter options) in
46 (writerIncludeAfter options) in
46 head ++ body ++ foot
47 head ++ body ++ foot
47
48
@@ -74,26 +75,35 @@ latexToRTF :: String -> String
74latexToRTF str = "{\\cf1 " ++ (latexStringToRTF str) ++ "\\cf0 } "
75latexToRTF str = "{\\cf1 " ++ (latexStringToRTF str) ++ "\\cf0 } "
75
76
76-- | Make a paragraph with first-line indent, block indent, and space after.
77-- | Make a paragraph with first-line indent, block indent, and space after.
77−rtfParSpaced :: Int -- ^ space after (in twips)
78+rtfParSpaced :: Int -- ^ space after (in twips)
78− -> Int -- ^ block indent (in twips)
79+ -> Int -- ^ block indent (in twips)
79− -> Int -- ^ first line indent (relative to block) (in twips)
80+ -> Int -- ^ first line indent (relative to block) (in twips)
81+ -> Alignment -- ^ alignment
80− -> String -- ^ string with content
82+ -> String -- ^ string with content
81 -> String
83 -> String
82−rtfParSpaced spaceAfter indent firstLineIndent content =
84+rtfParSpaced spaceAfter indent firstLineIndent alignment content =
85+ let alignString = case alignment of
86+ AlignLeft -> "\\ql"
87+ AlignRight -> "\\qr"
88+ AlignCenter -> "\\qc"
89+ AlignDefault -> "\\ql"
90+ in "{\\pard " ++ alignString ++
83− "{\\pard \\f0 \\sa" ++ (show spaceAfter) ++ " \\li" ++ (show indent) ++
91+ "\\f0 \\sa" ++ (show spaceAfter) ++ " \\li" ++ (show indent) ++
84− " \\fi" ++ (show firstLineIndent) ++ " " ++ content ++ "\\par}\n"
92+ " \\fi" ++ (show firstLineIndent) ++ " " ++ content ++ "\\par}\n"
85
93
86-- | Default paragraph.
94-- | Default paragraph.
87−rtfPar :: Int -- ^ block indent (in twips)
95+rtfPar :: Int -- ^ block indent (in twips)
88− -> Int -- ^ first line indent (relative to block) (in twips)
96+ -> Int -- ^ first line indent (relative to block) (in twips)
97+ -> Alignment -- ^ alignment
89− -> String -- ^ string with content
98+ -> String -- ^ string with content
90 -> String
99 -> String
91rtfPar = rtfParSpaced 180
100rtfPar = rtfParSpaced 180
92
101
93-- | Compact paragraph (e.g. for compact list items).
102-- | Compact paragraph (e.g. for compact list items).
94−rtfCompact :: Int -- ^ block indent (in twips)
103+rtfCompact :: Int -- ^ block indent (in twips)
95− -> Int -- ^ first line indent (relative to block) (in twips)
104+ -> Int -- ^ first line indent (relative to block) (in twips)
105+ -> Alignment -- ^ alignment
96− -> String -- ^ string with content
106+ -> String -- ^ string with content
97 -> String
107 -> String
98rtfCompact = rtfParSpaced 0
108rtfCompact = rtfParSpaced 0
99
109
@@ -121,47 +131,71 @@ rtfHeader :: String -- ^ header text
121rtfHeader headerText (Meta title authors date) =
131rtfHeader headerText (Meta title authors date) =
122 let titletext = if null title
132 let titletext = if null title
123 then ""
133 then ""
124− else rtfPar 0 0 ("\\qc \\b \\fs36 " ++
134+ else rtfPar 0 0 AlignDefault ("\\qc \\b \\fs36 " ++
125− inlineListToRTF title)
135+ inlineListToRTF title)
126 authorstext = if null authors
136 authorstext = if null authors
127 then ""
137 then ""
128− else rtfPar 0 0 ("\\qc " ++ (joinWithSep "\\"
138+ else rtfPar 0 0 AlignDefault ("\\qc " ++ (joinWithSep "\\"
129− (map stringToRTF authors)))
139+ (map stringToRTF authors)))
130 datetext = if date == ""
140 datetext = if date == ""
131 then ""
141 then ""
132− else rtfPar 0 0 ("\\qc " ++ stringToRTF date) in
142+ else rtfPar 0 0 AlignDefault ("\\qc " ++ stringToRTF date) in
133 let spacer = if null (titletext ++ authorstext ++ datetext)
143 let spacer = if null (titletext ++ authorstext ++ datetext)
134 then ""
144 then ""
135− else rtfPar 0 0 "" in
145+ else rtfPar 0 0 AlignDefault "" in
136 headerText ++ titletext ++ authorstext ++ datetext ++ spacer
146 headerText ++ titletext ++ authorstext ++ datetext ++ spacer
137
147
138-- | Convert Pandoc block element to RTF.
148-- | Convert Pandoc block element to RTF.
139blockToRTF :: Int -- ^ indent level
149blockToRTF :: Int -- ^ indent level
150+ -> Alignment -- ^ alignment
140 -> Block -- ^ block to convert
151 -> Block -- ^ block to convert
141 -> String
152 -> String
142−blockToRTF indent Null = ""
153+blockToRTF _ _ Null = ""
143−blockToRTF indent (Plain lst) =
154+blockToRTF indent alignment (Plain lst) =
144− rtfCompact indent 0 (inlineListToRTF lst)
155+ rtfCompact indent 0 alignment (inlineListToRTF lst)
145−blockToRTF indent (Para lst) =
156+blockToRTF indent alignment (Para lst) =
146− rtfPar indent 0 (inlineListToRTF lst)
157+ rtfPar indent 0 alignment (inlineListToRTF lst)
147−blockToRTF indent (BlockQuote lst) =
158+blockToRTF indent alignment (BlockQuote lst) =
148− concatMap (blockToRTF (indent + indentIncrement)) lst
159+ concatMap (blockToRTF (indent + indentIncrement) alignment) lst
149−blockToRTF indent (CodeBlock str) =
160+blockToRTF indent _ (CodeBlock str) =
150− rtfPar indent 0 ("\\f1 " ++ (codeStringToRTF str))
161+ rtfPar indent 0 AlignLeft ("\\f1 " ++ (codeStringToRTF str))
151−blockToRTF indent (RawHtml str) = ""
162+blockToRTF _ _ (RawHtml str) = ""
152−blockToRTF indent (BulletList lst) =
163+blockToRTF indent alignment (BulletList lst) =
153 spaceAtEnd $
164 spaceAtEnd $
154− concatMap (listItemToRTF indent (bulletMarker indent)) lst
165+ concatMap (listItemToRTF alignment indent (bulletMarker indent)) lst
155−blockToRTF indent (OrderedList lst) =
166+blockToRTF indent alignment (OrderedList lst) =
156 spaceAtEnd $ concat $
167 spaceAtEnd $ concat $
157− zipWith (listItemToRTF indent) (orderedMarkers indent) lst
168+ zipWith (listItemToRTF alignment indent) (orderedMarkers indent) lst
169+blockToRTF indent alignment (DefinitionList lst) =
170+ spaceAtEnd $
171+ concatMap (definitionListItemToRTF alignment indent) lst
158−blockToRTF indent HorizontalRule =
172+blockToRTF indent _ HorizontalRule =
159− rtfPar indent 0 "\\qc \\emdash\\emdash\\emdash\\emdash\\emdash"
173+ rtfPar indent 0 AlignCenter "\\emdash\\emdash\\emdash\\emdash\\emdash"
160−blockToRTF indent (Header level lst) =
174+blockToRTF indent alignment (Header level lst) =
161− rtfPar indent 0 ("\\b \\fs" ++ (show (40 - (level * 4))) ++ " " ++
175+ rtfPar indent 0 alignment ("\\b \\fs" ++ (show (40 - (level * 4))) ++ " " ++
162 (inlineListToRTF lst))
176 (inlineListToRTF lst))
163−blockToRTF indent (Table caption _ _ headers rows) =
177+blockToRTF indent alignment (Table caption aligns sizes headers rows) =
164− blockToRTF indent (Para [Str "pandoc: TABLE unsupported in RST writer"])
178+ (tableRowToRTF True indent aligns sizes headers) ++ (concatMap
179+ (tableRowToRTF False indent aligns sizes) rows) ++
180+ rtfPar indent 0 alignment (inlineListToRTF caption)
181+
182+tableRowToRTF :: Bool -> Int -> [Alignment] -> [Float] -> [[Block]] -> String
183+tableRowToRTF header indent aligns sizes cols =
184+ let columns = concat $ zipWith (tableItemToRTF indent) aligns cols
185+ totalTwips = 6 * 1440 -- 6 inches
186+ rightEdges = tail $ scanl (\sofar new -> sofar + floor (new * totalTwips))
187+ 0 sizes
188+ cellDefs = map (\edge -> (if header then "\\clbrdrb\\brdrs"
189+ else "") ++ "\\cellx" ++ show edge) rightEdges
190+ start = "{\n\\trowd \\trgaph120\n" ++ concat cellDefs ++ "\n" ++
191+ "\\trkeep\\intbl\n{\n"
192+ end = "}\n\\intbl\\row}\n"
193+ in start ++ columns ++ end
194+
195+tableItemToRTF :: Int -> Alignment -> [Block] -> String
196+tableItemToRTF indent alignment item =
197+ let contents = concatMap (blockToRTF indent alignment) item
198+ in "{\\intbl " ++ contents ++ "\\cell}\n"
165
199
166-- | Ensure that there's the same amount of space after compact
200-- | Ensure that there's the same amount of space after compact
167-- lists as after regular lists.
201-- lists as after regular lists.
@@ -172,15 +206,16 @@ spaceAtEnd str =
172 else str
206 else str
173
207
174-- | Convert list item (list of blocks) to RTF.
208-- | Convert list item (list of blocks) to RTF.
209+listItemToRTF :: Alignment -- ^ alignment
175−listItemToRTF :: Int -- ^ indent level
210+ -> Int -- ^ indent level
176 -> String -- ^ list start marker
211 -> String -- ^ list start marker
177 -> [Block] -- ^ list item (list of blocks)
212 -> [Block] -- ^ list item (list of blocks)
178 -> [Char]
213 -> [Char]
179−listItemToRTF indent marker [] =
214+listItemToRTF alignment indent marker [] =
180− rtfCompact (indent + listIncrement) (0 - listIncrement)
215+ rtfCompact (indent + listIncrement) (0 - listIncrement) alignment
181 (marker ++ "\\tx" ++ (show listIncrement) ++ "\\tab ")
216 (marker ++ "\\tx" ++ (show listIncrement) ++ "\\tab ")
182−listItemToRTF indent marker list =
217+listItemToRTF alignment indent marker list =
183− let (first:rest) = map (blockToRTF (indent + listIncrement)) list in
218+ let (first:rest) = map (blockToRTF (indent + listIncrement) alignment) list in
184 -- insert the list marker into the (processed) first block
219 -- insert the list marker into the (processed) first block
185 let modFirst = case matchRegexAll (mkRegex "\\\\fi-?[0-9]+") first of
220 let modFirst = case matchRegexAll (mkRegex "\\\\fi-?[0-9]+") first of
186 Just (before, matched, after, _) -> before ++ "\\fi" ++
221 Just (before, matched, after, _) -> before ++ "\\fi" ++
@@ -189,6 +224,16 @@ listItemToRTF indent marker list =
189 Nothing -> first in
224 Nothing -> first in
190 modFirst ++ (concat rest)
225 modFirst ++ (concat rest)
191
226
227+-- | Convert definition list item (label, list of blocks) to RTF.
228+definitionListItemToRTF :: Alignment -- ^ alignment
229+ -> Int -- ^ indent level
230+ -> ([Inline],[Block]) -- ^ list item (list of blocks)
231+ -> [Char]
232+definitionListItemToRTF alignment indent (label, items) =
233+ let labelText = blockToRTF indent alignment (Plain label)
234+ itemsText = concatMap (blockToRTF (indent + listIncrement) alignment) items
235+ in labelText ++ itemsText
236+
192-- | Convert list of inline items to RTF.
237-- | Convert list of inline items to RTF.
193inlineListToRTF :: [Inline] -- ^ list of inlines to convert
238inlineListToRTF :: [Inline] -- ^ list of inlines to convert
194 -> String
239 -> String
@@ -221,5 +266,5 @@ inlineToRTF (Image alternate (source, tit)) =
221 "{\\cf1 [image: " ++ source ++ "]\\cf0}"
266 "{\\cf1 [image: " ++ source ++ "]\\cf0}"
222inlineToRTF (Note contents) =
267inlineToRTF (Note contents) =
223 "{\\super\\chftn}{\\*\\footnote\\chftn\\~\\plain\\pard " ++
268 "{\\super\\chftn}{\\*\\footnote\\chftn\\~\\plain\\pard " ++
224− (concatMap (blockToRTF 0) contents) ++ "}"
269+ (concatMap (blockToRTF 0 AlignDefault) contents) ++ "}"
225
270