@@ -30,10 +30,8 @@ Conversion of mediawiki text to 'Pandoc' document.
33−_ tables - cell alignment and width
34_ wikipedia {{cite}} tags
33_ wikipedia {{cite}} tags
35_ <references /> {{Reflist}}
34_ <references /> {{Reflist}}
36−_ calculate cell widths when not given??? see html? latex? reader
37_ support tables http://www.mediawiki.org/wiki/Help:Tables
35_ support tables http://www.mediawiki.org/wiki/Help:Tables
38- footnotes?
36- footnotes?
@@ -54,6 +52,7 @@ import Control.Monad
54import Data.List (intersperse, intercalate, isPrefixOf )
52import Data.List (intersperse, intercalate, isPrefixOf )
55import Text.HTML.TagSoup
53import Text.HTML.TagSoup
56import Data.Sequence (viewl, ViewL(..), (<|))
54import Data.Sequence (viewl, ViewL(..), (<|))
55+import Data.Char (isDigit)
58-- | Read mediawiki from an input string and return a Pandoc document.
57-- | Read mediawiki from an input string and return a Pandoc document.
59readMediaWiki :: ReaderOptions -- ^ Reader options
58readMediaWiki :: ReaderOptions -- ^ Reader options
@@ -185,20 +184,27 @@ table :: MWParser Blocks
185table = do
184table = do
186 tableStart
185 tableStart
187 styles <- manyTill anyChar newline
186 styles <- manyTill anyChar newline
188− let tableWidth = maybe (1.0 :: Double) read
189− $ lookup "width" $ parseAttrs styles
187+ let tableWidth = case lookup "width" $ parseAttrs styles of
188+ Just w -> maybe 1.0 id $ parseWidth w
190 caption <- option mempty tableCaption
190 caption <- option mempty tableCaption
191 optional rowsep
191 optional rowsep
192 hasheader <- option False $ True <$ (lookAhead (char '!'))
192 hasheader <- option False $ True <$ (lookAhead (char '!'))
193− (aligns,hdr) <- unzip <$> tableRow
193+ (cellspecs',hdr) <- unzip <$> tableRow
194+ let widths = map ((tableWidth *) . snd) cellspecs'
195+ let restwidth = tableWidth - sum widths
196+ let zerocols = length $ filter (==0.0) widths
197+ let defaultwidth = if zerocols == 0 || zerocols == length widths
199+ else restwidth / fromIntegral zerocols
200+ let widths' = map (\w -> if w == 0 then defaultwidth else w) widths
201+ let cellspecs = zip (map fst cellspecs') widths'
194 rows' <- many $ try $ rowsep *> (map snd <$> tableRow)
202 rows' <- many $ try $ rowsep *> (map snd <$> tableRow)
196− -- TODO handle cellspecs from styles and aligns...
197 let cols = length hdr
204 let cols = length hdr
198 let (headers,rows) = if hasheader
205 let (headers,rows) = if hasheader
199 then (hdr, rows')
206 then (hdr, rows')
200 else (replicate cols mempty, hdr:rows')
207 else (replicate cols mempty, hdr:rows')
201− let cellspecs = zip aligns (repeat 0.0)
202 return $ B.table caption cellspecs headers rows
208 return $ B.table caption cellspecs headers rows
204parseAttrs :: String -> [(String,String)]
210parseAttrs :: String -> [(String,String)]
@@ -224,11 +230,15 @@ tableEnd = try $ guardColumnOne *> sym "|}" <* blanklines
224rowsep :: MWParser ()
230rowsep :: MWParser ()
225rowsep = try $ guardColumnOne *> sym "|-" <* blanklines
231rowsep = try $ guardColumnOne *> sym "|-" <* blanklines
227−-- TODO add something like 'guard inTable' since this is used in endline
228cellsep :: MWParser ()
233cellsep :: MWParser ()
229−cellsep = (try $ guardColumnOne <*
235+ (guardColumnOne <*
230− (char '!' <|> (char '|' <* notFollowedBy (oneOf "-}+"))))
236+ ( (char '|' <* notFollowedBy (oneOf "-}+"))
231− <|> (() <$ try (string "||"))
240+ <|> (() <$ try (string "||"))
241+ <|> (() <$ try (string "!!"))
233tableCaption :: MWParser Inlines
243tableCaption :: MWParser Inlines
234tableCaption = try $ do
244tableCaption = try $ do
@@ -238,10 +248,10 @@ tableCaption = try $ do
238 res <- manyTill anyChar newline >>= parseFromString (many inline)
248 res <- manyTill anyChar newline >>= parseFromString (many inline)
239 return $ trimInlines $ mconcat res
249 return $ trimInlines $ mconcat res
241−tableRow :: MWParser [(Alignment, Blocks)]
251+tableRow :: MWParser [((Alignment, Double), Blocks)]
242tableRow = try $ many tableCell
252tableRow = try $ many tableCell
244−tableCell :: MWParser (Alignment, Blocks)
254+tableCell :: MWParser ((Alignment, Double), Blocks)
245tableCell = try $ do
255tableCell = try $ do
247 skipMany spaceChar
257 skipMany spaceChar
@@ -255,7 +265,16 @@ tableCell = try $ do
255 Just "right" -> AlignRight
265 Just "right" -> AlignRight
256 Just "center" -> AlignCenter
266 Just "center" -> AlignCenter
257 _ -> AlignDefault
267 _ -> AlignDefault
268+ let width = case lookup "width" attrs of
269+ Just xs -> maybe 0.0 id $ parseWidth xs
258− return (align, bs)
271+ return ((align, width), bs)
273+parseWidth :: String -> Maybe Double
276+ ('%':ds) | all isDigit ds -> safeRead ('0':'.':reverse ds)
260template :: MWParser String
279template :: MWParser String
261template = try $ do
280template = try $ do