git.iko.soy/typeable/pandoc
on master help sign in
DokuWiki writer: Make tables prettier by aligning columns.

Also cleaned up crufty code and added tests.

commit374bb3c14785b77771d96319301ed5aef31089c5 authorJohn MacFarlane <jgm@berkeley.edu> dateSat 30 Aug 2014, 21:24 (12 years ago) parentd97aed3
4 files changed+50−66
changelog+2 src/Text/Pandoc/Writers/DokuWiki.hs+22−40 tests/dokuwiki_multiblock_table.dokuwiki+3−3 tests/tables.dokuwiki+23−23
changelog+2
@@ -60,6 +60,8 @@ pandoc (1.13.1)
6060 + Refactor to use Reader monad (Matthew Pickering).
6161 + Avoid using raw HTML in table cells; instead, use `\\`
6262 instead of newlines (Jesse Rosenthal).
63+ + Properly handle HTML table cell alignments, and use spacing
64+ to make the tables look prettier (#1566).
6365
6466 * Docx writer:
6567
src/Text/Pandoc/Writers/DokuWiki.hs+22−40
@@ -48,7 +48,7 @@ import Text.Pandoc.Shared ( escapeURI, removeFormatting, camelCaseToHyphenated
4848 , trimr, normalize, substitute )
4949import Text.Pandoc.Writers.Shared ( defField, metaToJSON )
5050import Text.Pandoc.Templates ( renderTemplate' )
51−import Data.List ( intersect, intercalate, isPrefixOf )
51+import Data.List ( intersect, intercalate, isPrefixOf, transpose )
5252import Data.Default (Default(..))
5353import Network.URI ( isURI )
5454import Control.Monad ( zipWithM )
@@ -181,20 +181,32 @@ blockToDokuWiki opts (BlockQuote blocks) = do
181181 then return $ "> " ++ contents
182182 else return $ "<HTML><blockquote>\n" ++ contents ++ "</blockquote></HTML>"
183183
184−blockToDokuWiki opts (Table capt aligns _ headers rows') = do
184+blockToDokuWiki opts (Table capt aligns _ headers rows) = do
185185 captionDoc <- if null capt
186186 then return ""
187187 else do
188188 c <- inlineListToDokuWiki opts capt
189189 return $ "" ++ c ++ "\n"
190− head' <- if all null headers
191− then return ""
192− else do
193− hs <- tableHeaderToDokuWiki opts aligns headers
194− return $ hs ++ "\n"
195− body' <- mapM (tableRowToDokuWiki opts aligns) rows'
196− return $ captionDoc ++ head' ++
197− unlines body'
190+ headers' <- if all null headers
191+ then return []
192+ else zipWithM (tableItemToDokuWiki opts) aligns headers
193+ rows' <- mapM (zipWithM (tableItemToDokuWiki opts) aligns) rows
194+ let widths = map (maximum . map length) $ transpose (headers':rows')
195+ let padTo (width, al) s =
196+ case (width - length s) of
197+ x | x > 0 ->
198+ if al == AlignLeft || al == AlignDefault
199+ then s ++ replicate x ' '
200+ else if al == AlignRight
201+ then replicate x ' ' ++ s
202+ else replicate (x `div` 2) ' ' ++
203+ s ++ replicate (x - x `div` 2) ' '
204+ | otherwise -> s
205+ let renderRow sep cells = sep ++
206+ intercalate sep (zipWith padTo (zip widths aligns) cells) ++ sep
207+ return $ captionDoc ++
208+ (if null headers' then "" else renderRow "^" headers' ++ "\n") ++
209+ unlines (map (renderRow "|") rows')
198210
199211blockToDokuWiki opts x@(BulletList items) = do
200212 oldUseTags <- stUseTags <$> ask
@@ -357,32 +369,10 @@ backSlashLineBreaks cs = reverse $ g $ reverse $ concatMap f cs
357369
358370-- Auxiliary functions for tables:
359371
360−-- TODO Eliminate copy-and-pasted code in tableHeaderToDokuWiki and tableRowToDokuWiki
361−tableHeaderToDokuWiki :: WriterOptions
362− -> [Alignment]
363− -> [[Block]]
364− -> DokuWiki String
365−tableHeaderToDokuWiki opts aligns cols' = do
366− cols'' <- zipWithM
367− (tableItemToDokuWiki opts)
368− aligns cols'
369− return $ "^ " ++ joinHeaders cols'' ++ " ^"
370−
371−tableRowToDokuWiki :: WriterOptions
372− -> [Alignment]
373− -> [[Block]]
374− -> DokuWiki String
375−tableRowToDokuWiki opts alignStrings cols' = do
376− cols'' <- zipWithM
377− (tableItemToDokuWiki opts)
378− alignStrings cols'
379− return $ "| " ++ "" ++ joinColumns cols'' ++ " |"
380−
381372tableItemToDokuWiki :: WriterOptions
382373 -> Alignment
383374 -> [Block]
384375 -> DokuWiki String
385−-- TODO Fix celltype and align' defined but not used
386376tableItemToDokuWiki opts align' item = do
387377 let mkcell x = (if align' == AlignRight || align' == AlignCenter
388378 then " "
@@ -394,14 +384,6 @@ tableItemToDokuWiki opts align' item = do
394384 blockListToDokuWiki opts item
395385 return $ mkcell contents
396386
397−-- | Concatenates columns together.
398−joinColumns :: [String] -> String
399−joinColumns = intercalate " | "
400−
401−-- | Concatenates headers together.
402−joinHeaders :: [String] -> String
403−joinHeaders = intercalate " ^ "
404−
405387-- | Convert list of Pandoc block elements to DokuWiki.
406388blockListToDokuWiki :: WriterOptions -- ^ Options
407389 -> [Block] -- ^ List of block elements
tests/dokuwiki_multiblock_table.dokuwiki+3−3
@@ -1,4 +1,4 @@
11Sample grid table.
2−^ Fruit ^ Price ^ Advantages ^
3−| Bananas | $1.34 | built-in wrapper\\ \\ potassium |
4−| Oranges | $2.10 | * cures scurvy\\ * tasty |
2+^Fruit ^Price^Advantages ^
3+|Bananas|$1.34|built-in wrapper\\ \\ potassium|
4+|Oranges|$2.10|* cures scurvy\\ * tasty |
tests/tables.dokuwiki+23−23
@@ -1,47 +1,47 @@
11Simple table with caption:
22
33Demonstration of simple table syntax.
4−^ Right ^ Left ^ Center ^ Default ^
5−| 12 | 12 | 12 | 12 |
6−| 123 | 123 | 123 | 123 |
7−| 1 | 1 | 1 | 1 |
4+^ Right^Left ^ Center ^Default^
5+| 12|12 | 12 |12 |
6+| 123|123 | 123 |123 |
7+| 1|1 | 1 |1 |
88
99Simple table without caption:
1010
11−^ Right ^ Left ^ Center ^ Default ^
12−| 12 | 12 | 12 | 12 |
13−| 123 | 123 | 123 | 123 |
14−| 1 | 1 | 1 | 1 |
11+^ Right^Left ^ Center ^Default^
12+| 12|12 | 12 |12 |
13+| 123|123 | 123 |123 |
14+| 1|1 | 1 |1 |
1515
1616Simple table indented two spaces:
1717
1818Demonstration of simple table syntax.
19−^ Right ^ Left ^ Center ^ Default ^
20−| 12 | 12 | 12 | 12 |
21−| 123 | 123 | 123 | 123 |
22−| 1 | 1 | 1 | 1 |
19+^ Right^Left ^ Center ^Default^
20+| 12|12 | 12 |12 |
21+| 123|123 | 123 |123 |
22+| 1|1 | 1 |1 |
2323
2424Multiline table with caption:
2525
2626Here's the caption. It may span multiple lines.
27−^ Centered Header ^ Left Aligned ^ Right Aligned ^ Default aligned ^
28−| First | row | 12.0 | Example of a row that spans multiple lines. |
29−| Second | row | 5.0 | Here's another one. Note the blank line between rows. |
27+^ Centered Header ^Left Aligned ^ Right Aligned^Default aligned ^
28+| First |row | 12.0|Example of a row that spans multiple lines. |
29+| Second |row | 5.0|Here's another one. Note the blank line between rows. |
3030
3131Multiline table without caption:
3232
33−^ Centered Header ^ Left Aligned ^ Right Aligned ^ Default aligned ^
34−| First | row | 12.0 | Example of a row that spans multiple lines. |
35−| Second | row | 5.0 | Here's another one. Note the blank line between rows. |
33+^ Centered Header ^Left Aligned ^ Right Aligned^Default aligned ^
34+| First |row | 12.0|Example of a row that spans multiple lines. |
35+| Second |row | 5.0|Here's another one. Note the blank line between rows. |
3636
3737Table without column headers:
3838
39−| 12 | 12 | 12 | 12 |
40−| 123 | 123 | 123 | 123 |
41−| 1 | 1 | 1 | 1 |
39+| 12|12 | 12 | 12|
40+| 123|123 | 123 | 123|
41+| 1|1 | 1 | 1|
4242
4343Multiline table without column headers:
4444
45−| First | row | 12.0 | Example of a row that spans multiple lines. |
46−| Second | row | 5.0 | Here's another one. Note the blank line between rows. |
45+| First |row | 12.0|Example of a row that spans multiple lines. |
46+| Second |row | 5.0|Here's another one. Note the blank line between rows.|
4747