git.iko.soy/typeable/pandoc
on master help sign in
MediaWiki writer: Use native mediawiki tables instead of HTML.

Closes #720.

commit4a84b78100f2cfa0f7f7d13a24693a37af60003d authorJohn MacFarlane <jgm@berkeley.edu> dateSat 3 Aug 2013, 23:05 (13 years ago) parent97b2be5
2 files changed+164−235
src/Text/Pandoc/Writers/MediaWiki.hs+39−44 tests/tables.mediawiki+125−191
src/Text/Pandoc/Writers/MediaWiki.hs+39−44
@@ -36,7 +36,7 @@ import Text.Pandoc.Shared
3636import Text.Pandoc.Writers.Shared
3737import Text.Pandoc.Templates (renderTemplate')
3838import Text.Pandoc.XML ( escapeStringForXML )
39−import Data.List ( intersect, intercalate )
39+import Data.List ( intersect, intercalate, intersperse )
4040import Network.URI ( isURI )
4141import Control.Monad.State
4242
@@ -135,25 +135,17 @@ blockToMediaWiki opts (BlockQuote blocks) = do
135135 return $ "<blockquote>" ++ contents ++ "</blockquote>"
136136
137137blockToMediaWiki opts (Table capt aligns widths headers rows') = do
138− let alignStrings = map alignmentToString aligns
139− captionDoc <- if null capt
140− then return ""
141− else do
142− c <- inlineListToMediaWiki opts capt
143− return $ "<caption>" ++ c ++ "</caption>\n"
144− let percent w = show (truncate (100*w) :: Integer) ++ "%"
145− let coltags = if all (== 0.0) widths
146− then ""
147− else unlines $ map
148− (\w -> "<col width=\"" ++ percent w ++ "\" />") widths
149− head' <- if all null headers
150− then return ""
151− else do
152− hs <- tableRowToMediaWiki opts alignStrings 0 headers
153− return $ "<thead>\n" ++ hs ++ "\n</thead>\n"
154− body' <- zipWithM (tableRowToMediaWiki opts alignStrings) [1..] rows'
155− return $ "<table>\n" ++ captionDoc ++ coltags ++ head' ++
156− "<tbody>\n" ++ unlines body' ++ "</tbody>\n</table>\n"
138+ caption <- if null capt
139+ then return ""
140+ else do
141+ c <- inlineListToMediaWiki opts capt
142+ return $ "|+ " ++ trimr c ++ "\n"
143+ let headless = all null headers
144+ let allrows = if headless then rows' else headers:rows'
145+ tableBody <- (concat . intersperse "|-\n") `fmap`
146+ mapM (tableRowToMediaWiki opts headless aligns widths)
147+ (zip [1..] allrows)
148+ return $ "{|\n" ++ caption ++ tableBody ++ "|}\n"
157149
158150blockToMediaWiki opts x@(BulletList items) = do
159151 oldUseTags <- get >>= return . stUseTags
@@ -285,20 +277,34 @@ vcat = intercalate "\n"
285277-- Auxiliary functions for tables:
286278
287279tableRowToMediaWiki :: WriterOptions
288− -> [String]
289− -> Int
290− -> [[Block]]
280+ -> Bool
281+ -> [Alignment]
282+ -> [Double]
283+ -> (Int, [[Block]])
291284 -> State WriterState String
292−tableRowToMediaWiki opts alignStrings rownum cols' = do
293− let celltype = if rownum == 0 then "th" else "td"
294− let rowclass = case rownum of
295− 0 -> "header"
296− x | x `rem` 2 == 1 -> "odd"
297− _ -> "even"
298− cols'' <- sequence $ zipWith
299− (\alignment item -> tableItemToMediaWiki opts celltype alignment item)
300− alignStrings cols'
301− return $ "<tr class=\"" ++ rowclass ++ "\">\n" ++ unlines cols'' ++ "</tr>"
285+tableRowToMediaWiki opts headless alignments widths (rownum, cells) = do
286+ cells' <- mapM (\cellData ->
287+ tableCellToMediaWiki opts headless rownum cellData)
288+ $ zip3 alignments widths cells
289+ return $ unlines cells'
290+
291+tableCellToMediaWiki :: WriterOptions
292+ -> Bool
293+ -> Int
294+ -> (Alignment, Double, [Block])
295+ -> State WriterState String
296+tableCellToMediaWiki opts headless rownum (alignment, width, bs) = do
297+ contents <- blockListToMediaWiki opts bs
298+ let marker = if rownum == 1 && not headless then "!" else "|"
299+ let percent w = show (truncate (100*w) :: Integer) ++ "%"
300+ let attrs = ["align=" ++ show (alignmentToString alignment) |
301+ alignment /= AlignDefault && alignment /= AlignLeft] ++
302+ ["width=\"" ++ percent width ++ "\"" |
303+ width /= 0.0 && rownum == 1]
304+ let attr = if null attrs
305+ then ""
306+ else unwords attrs ++ "|"
307+ return $ marker ++ attr ++ trimr contents
302308
303309alignmentToString :: Alignment -> [Char]
304310alignmentToString alignment = case alignment of
@@ -307,17 +313,6 @@ alignmentToString alignment = case alignment of
307313 AlignCenter -> "center"
308314 AlignDefault -> "left"
309315
310−tableItemToMediaWiki :: WriterOptions
311− -> String
312− -> String
313− -> [Block]
314− -> State WriterState String
315−tableItemToMediaWiki opts celltype align' item = do
316− let mkcell x = "<" ++ celltype ++ " align=\"" ++ align' ++ "\">" ++
317− x ++ "</" ++ celltype ++ ">"
318− contents <- blockListToMediaWiki opts item
319− return $ mkcell contents
320−
321316-- | Convert list of Pandoc block elements to MediaWiki.
322317blockListToMediaWiki :: WriterOptions -- ^ Options
323318 -> [Block] -- ^ List of block elements
tests/tables.mediawiki+125−191
@@ -1,212 +1,146 @@
11Simple table with caption:
22
3−<table>
4−<caption>Demonstration of simple table syntax.</caption>
5−<thead>
6−<tr class="header">
7−<th align="right">Right</th>
8−<th align="left">Left</th>
9−<th align="center">Center</th>
10−<th align="left">Default</th>
11−</tr>
12−</thead>
13−<tbody>
14−<tr class="odd">
15−<td align="right">12</td>
16−<td align="left">12</td>
17−<td align="center">12</td>
18−<td align="left">12</td>
19−</tr>
20−<tr class="even">
21−<td align="right">123</td>
22−<td align="left">123</td>
23−<td align="center">123</td>
24−<td align="left">123</td>
25−</tr>
26−<tr class="odd">
27−<td align="right">1</td>
28−<td align="left">1</td>
29−<td align="center">1</td>
30−<td align="left">1</td>
31−</tr>
32−</tbody>
33−</table>
3+{|
4+|+ Demonstration of simple table syntax.
5+!align="right"|Right
6+!Left
7+!align="center"|Center
8+!Default
9+|-
10+|align="right"|12
11+|12
12+|align="center"|12
13+|12
14+|-
15+|align="right"|123
16+|123
17+|align="center"|123
18+|123
19+|-
20+|align="right"|1
21+|1
22+|align="center"|1
23+|1
24+|}
3425
3526Simple table without caption:
3627
37−<table>
38−<thead>
39−<tr class="header">
40−<th align="right">Right</th>
41−<th align="left">Left</th>
42−<th align="center">Center</th>
43−<th align="left">Default</th>
44−</tr>
45−</thead>
46−<tbody>
47−<tr class="odd">
48−<td align="right">12</td>
49−<td align="left">12</td>
50−<td align="center">12</td>
51−<td align="left">12</td>
52−</tr>
53−<tr class="even">
54−<td align="right">123</td>
55−<td align="left">123</td>
56−<td align="center">123</td>
57−<td align="left">123</td>
58−</tr>
59−<tr class="odd">
60−<td align="right">1</td>
61−<td align="left">1</td>
62−<td align="center">1</td>
63−<td align="left">1</td>
64−</tr>
65−</tbody>
66−</table>
28+{|
29+!align="right"|Right
30+!Left
31+!align="center"|Center
32+!Default
33+|-
34+|align="right"|12
35+|12
36+|align="center"|12
37+|12
38+|-
39+|align="right"|123
40+|123
41+|align="center"|123
42+|123
43+|-
44+|align="right"|1
45+|1
46+|align="center"|1
47+|1
48+|}
6749
6850Simple table indented two spaces:
6951
70−<table>
71−<caption>Demonstration of simple table syntax.</caption>
72−<thead>
73−<tr class="header">
74−<th align="right">Right</th>
75−<th align="left">Left</th>
76−<th align="center">Center</th>
77−<th align="left">Default</th>
78−</tr>
79−</thead>
80−<tbody>
81−<tr class="odd">
82−<td align="right">12</td>
83−<td align="left">12</td>
84−<td align="center">12</td>
85−<td align="left">12</td>
86−</tr>
87−<tr class="even">
88−<td align="right">123</td>
89−<td align="left">123</td>
90−<td align="center">123</td>
91−<td align="left">123</td>
92−</tr>
93−<tr class="odd">
94−<td align="right">1</td>
95−<td align="left">1</td>
96−<td align="center">1</td>
97−<td align="left">1</td>
98−</tr>
99−</tbody>
100−</table>
52+{|
53+|+ Demonstration of simple table syntax.
54+!align="right"|Right
55+!Left
56+!align="center"|Center
57+!Default
58+|-
59+|align="right"|12
60+|12
61+|align="center"|12
62+|12
63+|-
64+|align="right"|123
65+|123
66+|align="center"|123
67+|123
68+|-
69+|align="right"|1
70+|1
71+|align="center"|1
72+|1
73+|}
10174
10275Multiline table with caption:
10376
104−<table>
105−<caption>Here's the caption. It may span multiple lines.</caption>
106−<col width="15%" />
107−<col width="13%" />
108−<col width="16%" />
109−<col width="33%" />
110−<thead>
111−<tr class="header">
112−<th align="center">Centered Header</th>
113−<th align="left">Left Aligned</th>
114−<th align="right">Right Aligned</th>
115−<th align="left">Default aligned</th>
116−</tr>
117−</thead>
118−<tbody>
119−<tr class="odd">
120−<td align="center">First</td>
121−<td align="left">row</td>
122−<td align="right">12.0</td>
123−<td align="left">Example of a row that spans multiple lines.</td>
124−</tr>
125−<tr class="even">
126−<td align="center">Second</td>
127−<td align="left">row</td>
128−<td align="right">5.0</td>
129−<td align="left">Here's another one. Note the blank line between rows.</td>
130−</tr>
131−</tbody>
132−</table>
77+{|
78+|+ Here's the caption. It may span multiple lines.
79+!align="center" width="15%"|Centered Header
80+!width="13%"|Left Aligned
81+!align="right" width="16%"|Right Aligned
82+!width="33%"|Default aligned
83+|-
84+|align="center"|First
85+|row
86+|align="right"|12.0
87+|Example of a row that spans multiple lines.
88+|-
89+|align="center"|Second
90+|row
91+|align="right"|5.0
92+|Here's another one. Note the blank line between rows.
93+|}
13394
13495Multiline table without caption:
13596
136−<table>
137−<col width="15%" />
138−<col width="13%" />
139−<col width="16%" />
140−<col width="33%" />
141−<thead>
142−<tr class="header">
143−<th align="center">Centered Header</th>
144−<th align="left">Left Aligned</th>
145−<th align="right">Right Aligned</th>
146−<th align="left">Default aligned</th>
147−</tr>
148−</thead>
149−<tbody>
150−<tr class="odd">
151−<td align="center">First</td>
152−<td align="left">row</td>
153−<td align="right">12.0</td>
154−<td align="left">Example of a row that spans multiple lines.</td>
155−</tr>
156−<tr class="even">
157−<td align="center">Second</td>
158−<td align="left">row</td>
159−<td align="right">5.0</td>
160−<td align="left">Here's another one. Note the blank line between rows.</td>
161−</tr>
162−</tbody>
163−</table>
97+{|
98+!align="center" width="15%"|Centered Header
99+!width="13%"|Left Aligned
100+!align="right" width="16%"|Right Aligned
101+!width="33%"|Default aligned
102+|-
103+|align="center"|First
104+|row
105+|align="right"|12.0
106+|Example of a row that spans multiple lines.
107+|-
108+|align="center"|Second
109+|row
110+|align="right"|5.0
111+|Here's another one. Note the blank line between rows.
112+|}
164113
165114Table without column headers:
166115
167−<table>
168−<tbody>
169−<tr class="odd">
170−<td align="right">12</td>
171−<td align="left">12</td>
172−<td align="center">12</td>
173−<td align="right">12</td>
174−</tr>
175−<tr class="even">
176−<td align="right">123</td>
177−<td align="left">123</td>
178−<td align="center">123</td>
179−<td align="right">123</td>
180−</tr>
181−<tr class="odd">
182−<td align="right">1</td>
183−<td align="left">1</td>
184−<td align="center">1</td>
185−<td align="right">1</td>
186−</tr>
187−</tbody>
188−</table>
116+{|
117+|align="right"|12
118+|12
119+|align="center"|12
120+|align="right"|12
121+|-
122+|align="right"|123
123+|123
124+|align="center"|123
125+|align="right"|123
126+|-
127+|align="right"|1
128+|1
129+|align="center"|1
130+|align="right"|1
131+|}
189132
190133Multiline table without column headers:
191134
192−<table>
193−<col width="15%" />
194−<col width="13%" />
195−<col width="16%" />
196−<col width="33%" />
197−<tbody>
198−<tr class="odd">
199−<td align="center">First</td>
200−<td align="left">row</td>
201−<td align="right">12.0</td>
202−<td align="left">Example of a row that spans multiple lines.</td>
203−</tr>
204−<tr class="even">
205−<td align="center">Second</td>
206−<td align="left">row</td>
207−<td align="right">5.0</td>
208−<td align="left">Here's another one. Note the blank line between rows.</td>
209−</tr>
210−</tbody>
211−</table>
135+{|
136+|align="center" width="15%"|First
137+|width="13%"|row
138+|align="right" width="16%"|12.0
139+|width="33%"|Example of a row that spans multiple lines.
140+|-
141+|align="center"|Second
142+|row
143+|align="right"|5.0
144+|Here's another one. Note the blank line between rows.
145+|}
212146