git.iko.soy/typeable/pandoc
on master help sign in
MediaWiki writer: Use native mediawiki tables instead of HTML.
4a84b78John MacFarlane
src/Text/Pandoc/Writers/MediaWiki.hs+39−44
@@ -36,7 +36,7 @@ import Text.Pandoc.Shared
36import Text.Pandoc.Writers.Shared
36import Text.Pandoc.Writers.Shared
37import Text.Pandoc.Templates (renderTemplate')
37import Text.Pandoc.Templates (renderTemplate')
38import Text.Pandoc.XML ( escapeStringForXML )
38import Text.Pandoc.XML ( escapeStringForXML )
39−import Data.List ( intersect, intercalate )
39+import Data.List ( intersect, intercalate, intersperse )
40import Network.URI ( isURI )
40import Network.URI ( isURI )
41import Control.Monad.State
41import Control.Monad.State
42
42
@@ -135,25 +135,17 @@ blockToMediaWiki opts (BlockQuote blocks) = do
135 return $ "<blockquote>" ++ contents ++ "</blockquote>"
135 return $ "<blockquote>" ++ contents ++ "</blockquote>"
136
136
137blockToMediaWiki opts (Table capt aligns widths headers rows') = do
137blockToMediaWiki opts (Table capt aligns widths headers rows') = do
138− let alignStrings = map alignmentToString aligns
139− captionDoc <- if null capt
138+ caption <- if null capt
140− then return ""
139+ then return ""
141− else do
140+ else do
142− c <- inlineListToMediaWiki opts capt
141+ c <- inlineListToMediaWiki opts capt
143− return $ "<caption>" ++ c ++ "</caption>\n"
142+ return $ "|+ " ++ trimr c ++ "\n"
144− let percent w = show (truncate (100*w) :: Integer) ++ "%"
143+ let headless = all null headers
145− let coltags = if all (== 0.0) widths
144+ let allrows = if headless then rows' else headers:rows'
146− then ""
145+ tableBody <- (concat . intersperse "|-\n") `fmap`
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'
146+ mapM (tableRowToMediaWiki opts headless aligns widths)
155− return $ "<table>\n" ++ captionDoc ++ coltags ++ head' ++
147+ (zip [1..] allrows)
156− "<tbody>\n" ++ unlines body' ++ "</tbody>\n</table>\n"
148+ return $ "{|\n" ++ caption ++ tableBody ++ "|}\n"
157
149
158blockToMediaWiki opts x@(BulletList items) = do
150blockToMediaWiki opts x@(BulletList items) = do
159 oldUseTags <- get >>= return . stUseTags
151 oldUseTags <- get >>= return . stUseTags
@@ -285,20 +277,34 @@ vcat = intercalate "\n"
285-- Auxiliary functions for tables:
277-- Auxiliary functions for tables:
286
278
287tableRowToMediaWiki :: WriterOptions
279tableRowToMediaWiki :: WriterOptions
288− -> [String]
280+ -> Bool
289− -> Int
281+ -> [Alignment]
282+ -> [Double]
290− -> [[Block]]
283+ -> (Int, [[Block]])
291 -> State WriterState String
284 -> State WriterState String
292−tableRowToMediaWiki opts alignStrings rownum cols' = do
285+tableRowToMediaWiki opts headless alignments widths (rownum, cells) = do
293− let celltype = if rownum == 0 then "th" else "td"
286+ cells' <- mapM (\cellData ->
294− let rowclass = case rownum of
287+ tableCellToMediaWiki opts headless rownum cellData)
295− 0 -> "header"
288+ $ zip3 alignments widths cells
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>"
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
302
308
303alignmentToString :: Alignment -> [Char]
309alignmentToString :: Alignment -> [Char]
304alignmentToString alignment = case alignment of
310alignmentToString alignment = case alignment of
@@ -307,17 +313,6 @@ alignmentToString alignment = case alignment of
307 AlignCenter -> "center"
313 AlignCenter -> "center"
308 AlignDefault -> "left"
314 AlignDefault -> "left"
309
315
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−
321-- | Convert list of Pandoc block elements to MediaWiki.
316-- | Convert list of Pandoc block elements to MediaWiki.
322blockListToMediaWiki :: WriterOptions -- ^ Options
317blockListToMediaWiki :: WriterOptions -- ^ Options
323 -> [Block] -- ^ List of block elements
318 -> [Block] -- ^ List of block elements
tests/tables.mediawiki+125−191
@@ -1,212 +1,146 @@
1Simple table with caption:
1Simple table with caption:
2
2
3−<table>
3+{|
4−<caption>Demonstration of simple table syntax.</caption>
4+|+ Demonstration of simple table syntax.
5−<thead>
6−<tr class="header">
7−<th align="right">Right</th>
5+!align="right"|Right
8−<th align="left">Left</th>
6+!Left
9−<th align="center">Center</th>
7+!align="center"|Center
10−<th align="left">Default</th>
8+!Default
11−</tr>
9+|-
12−</thead>
13−<tbody>
14−<tr class="odd">
15−<td align="right">12</td>
10+|align="right"|12
16−<td align="left">12</td>
11+|12
17−<td align="center">12</td>
12+|align="center"|12
18−<td align="left">12</td>
13+|12
19−</tr>
14+|-
20−<tr class="even">
21−<td align="right">123</td>
15+|align="right"|123
22−<td align="left">123</td>
16+|123
23−<td align="center">123</td>
17+|align="center"|123
24−<td align="left">123</td>
18+|123
25−</tr>
19+|-
26−<tr class="odd">
27−<td align="right">1</td>
20+|align="right"|1
28−<td align="left">1</td>
21+|1
29−<td align="center">1</td>
22+|align="center"|1
30−<td align="left">1</td>
23+|1
31−</tr>
24+|}
32−</tbody>
33−</table>
34
25
35Simple table without caption:
26Simple table without caption:
36
27
37−<table>
28+{|
38−<thead>
39−<tr class="header">
40−<th align="right">Right</th>
29+!align="right"|Right
41−<th align="left">Left</th>
30+!Left
42−<th align="center">Center</th>
31+!align="center"|Center
43−<th align="left">Default</th>
32+!Default
44−</tr>
33+|-
45−</thead>
46−<tbody>
47−<tr class="odd">
48−<td align="right">12</td>
34+|align="right"|12
49−<td align="left">12</td>
35+|12
50−<td align="center">12</td>
36+|align="center"|12
51−<td align="left">12</td>
37+|12
52−</tr>
38+|-
53−<tr class="even">
54−<td align="right">123</td>
39+|align="right"|123
55−<td align="left">123</td>
40+|123
56−<td align="center">123</td>
41+|align="center"|123
57−<td align="left">123</td>
42+|123
58−</tr>
43+|-
59−<tr class="odd">
60−<td align="right">1</td>
44+|align="right"|1
61−<td align="left">1</td>
45+|1
62−<td align="center">1</td>
46+|align="center"|1
63−<td align="left">1</td>
47+|1
64−</tr>
48+|}
65−</tbody>
66−</table>
67
49
68Simple table indented two spaces:
50Simple table indented two spaces:
69
51
70−<table>
52+{|
71−<caption>Demonstration of simple table syntax.</caption>
53+|+ Demonstration of simple table syntax.
72−<thead>
73−<tr class="header">
74−<th align="right">Right</th>
54+!align="right"|Right
75−<th align="left">Left</th>
55+!Left
76−<th align="center">Center</th>
56+!align="center"|Center
77−<th align="left">Default</th>
57+!Default
78−</tr>
58+|-
79−</thead>
80−<tbody>
81−<tr class="odd">
82−<td align="right">12</td>
59+|align="right"|12
83−<td align="left">12</td>
60+|12
84−<td align="center">12</td>
61+|align="center"|12
85−<td align="left">12</td>
62+|12
86−</tr>
63+|-
87−<tr class="even">
88−<td align="right">123</td>
64+|align="right"|123
89−<td align="left">123</td>
65+|123
90−<td align="center">123</td>
66+|align="center"|123
91−<td align="left">123</td>
67+|123
92−</tr>
68+|-
93−<tr class="odd">
94−<td align="right">1</td>
69+|align="right"|1
95−<td align="left">1</td>
70+|1
96−<td align="center">1</td>
71+|align="center"|1
97−<td align="left">1</td>
72+|1
98−</tr>
73+|}
99−</tbody>
100−</table>
101
74
102Multiline table with caption:
75Multiline table with caption:
103
76
104−<table>
77+{|
105−<caption>Here's the caption. It may span multiple lines.</caption>
78+|+ Here's the caption. It may span multiple lines.
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>
79+!align="center" width="15%"|Centered Header
113−<th align="left">Left Aligned</th>
80+!width="13%"|Left Aligned
114−<th align="right">Right Aligned</th>
81+!align="right" width="16%"|Right Aligned
115−<th align="left">Default aligned</th>
82+!width="33%"|Default aligned
116−</tr>
83+|-
117−</thead>
118−<tbody>
119−<tr class="odd">
120−<td align="center">First</td>
84+|align="center"|First
121−<td align="left">row</td>
85+|row
122−<td align="right">12.0</td>
86+|align="right"|12.0
123−<td align="left">Example of a row that spans multiple lines.</td>
87+|Example of a row that spans multiple lines.
124−</tr>
88+|-
125−<tr class="even">
126−<td align="center">Second</td>
89+|align="center"|Second
127−<td align="left">row</td>
90+|row
128−<td align="right">5.0</td>
91+|align="right"|5.0
129−<td align="left">Here's another one. Note the blank line between rows.</td>
92+|Here's another one. Note the blank line between rows.
130−</tr>
93+|}
131−</tbody>
132−</table>
133
94
134Multiline table without caption:
95Multiline table without caption:
135
96
136−<table>
97+{|
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>
98+!align="center" width="15%"|Centered Header
144−<th align="left">Left Aligned</th>
99+!width="13%"|Left Aligned
145−<th align="right">Right Aligned</th>
100+!align="right" width="16%"|Right Aligned
146−<th align="left">Default aligned</th>
101+!width="33%"|Default aligned
147−</tr>
102+|-
148−</thead>
149−<tbody>
150−<tr class="odd">
151−<td align="center">First</td>
103+|align="center"|First
152−<td align="left">row</td>
104+|row
153−<td align="right">12.0</td>
105+|align="right"|12.0
154−<td align="left">Example of a row that spans multiple lines.</td>
106+|Example of a row that spans multiple lines.
155−</tr>
107+|-
156−<tr class="even">
157−<td align="center">Second</td>
108+|align="center"|Second
158−<td align="left">row</td>
109+|row
159−<td align="right">5.0</td>
110+|align="right"|5.0
160−<td align="left">Here's another one. Note the blank line between rows.</td>
111+|Here's another one. Note the blank line between rows.
161−</tr>
112+|}
162−</tbody>
163−</table>
164
113
165Table without column headers:
114Table without column headers:
166
115
167−<table>
116+{|
168−<tbody>
169−<tr class="odd">
170−<td align="right">12</td>
117+|align="right"|12
171−<td align="left">12</td>
118+|12
172−<td align="center">12</td>
119+|align="center"|12
173−<td align="right">12</td>
120+|align="right"|12
174−</tr>
121+|-
175−<tr class="even">
176−<td align="right">123</td>
122+|align="right"|123
177−<td align="left">123</td>
123+|123
178−<td align="center">123</td>
124+|align="center"|123
179−<td align="right">123</td>
125+|align="right"|123
180−</tr>
126+|-
181−<tr class="odd">
182−<td align="right">1</td>
127+|align="right"|1
183−<td align="left">1</td>
128+|1
184−<td align="center">1</td>
129+|align="center"|1
185−<td align="right">1</td>
130+|align="right"|1
186−</tr>
131+|}
187−</tbody>
188−</table>
189
132
190Multiline table without column headers:
133Multiline table without column headers:
191
134
192−<table>
135+{|
193−<col width="15%" />
136+|align="center" width="15%"|First
194−<col width="13%" />
137+|width="13%"|row
195−<col width="16%" />
138+|align="right" width="16%"|12.0
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>
139+|width="33%"|Example of a row that spans multiple lines.
203−</tr>
140+|-
204−<tr class="even">
205−<td align="center">Second</td>
141+|align="center"|Second
206−<td align="left">row</td>
142+|row
207−<td align="right">5.0</td>
143+|align="right"|5.0
208−<td align="left">Here's another one. Note the blank line between rows.</td>
144+|Here's another one. Note the blank line between rows.
209−</tr>
145+|}
210−</tbody>
211−</table>
212
146