@@ -30,10 +30,8 @@ Conversion of mediawiki text to 'Pandoc' document.
3030-}
3131{-
3232TODO:
33−_ tables - cell alignment and width
3433_ wikipedia {{cite}} tags
3534_ <references /> {{Reflist}}
36−_ calculate cell widths when not given??? see html? latex? reader
3735_ support tables http://www.mediawiki.org/wiki/Help:Tables
3836- footnotes?
3937-}
@@ -54,6 +52,7 @@ import Control.Monad
5452import Data.List (intersperse, intercalate, isPrefixOf )
5553import Text.HTML.TagSoup
5654import Data.Sequence (viewl, ViewL(..), (<|))
55+import Data.Char (isDigit)
5756
5857-- | Read mediawiki from an input string and return a Pandoc document.
5958readMediaWiki :: ReaderOptions -- ^ Reader options
@@ -185,20 +184,27 @@ table :: MWParser Blocks
185184table = do
186185 tableStart
187186 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
189+ Nothing -> 1.0
190190 caption <- option mempty tableCaption
191191 optional rowsep
192192 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
198+ then 0.0
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'
194202 rows' <- many $ try $ rowsep *> (map snd <$> tableRow)
195203 tableEnd
196− -- TODO handle cellspecs from styles and aligns...
197204 let cols = length hdr
198205 let (headers,rows) = if hasheader
199206 then (hdr, rows')
200207 else (replicate cols mempty, hdr:rows')
201− let cellspecs = zip aligns (repeat 0.0)
202208 return $ B.table caption cellspecs headers rows
203209
204210parseAttrs :: String -> [(String,String)]
@@ -224,11 +230,15 @@ tableEnd = try $ guardColumnOne *> sym "|}" <* blanklines
224230rowsep :: MWParser ()
225231rowsep = try $ guardColumnOne *> sym "|-" <* blanklines
226232
227−-- TODO add something like 'guard inTable' since this is used in endline
228233cellsep :: MWParser ()
229−cellsep = (try $ guardColumnOne <*
230− (char '!' <|> (char '|' <* notFollowedBy (oneOf "-}+"))))
231− <|> (() <$ try (string "||"))
234+cellsep = try $
235+ (guardColumnOne <*
236+ ( (char '|' <* notFollowedBy (oneOf "-}+"))
237+ <|> (char '!')
238+ )
239+ )
240+ <|> (() <$ try (string "||"))
241+ <|> (() <$ try (string "!!"))
232242
233243tableCaption :: MWParser Inlines
234244tableCaption = try $ do
@@ -238,10 +248,10 @@ tableCaption = try $ do
238248 res <- manyTill anyChar newline >>= parseFromString (many inline)
239249 return $ trimInlines $ mconcat res
240250
241−tableRow :: MWParser [(Alignment, Blocks)]
251+tableRow :: MWParser [((Alignment, Double), Blocks)]
242252tableRow = try $ many tableCell
243253
244−tableCell :: MWParser (Alignment, Blocks)
254+tableCell :: MWParser ((Alignment, Double), Blocks)
245255tableCell = try $ do
246256 cellsep
247257 skipMany spaceChar
@@ -255,7 +265,16 @@ tableCell = try $ do
255265 Just "right" -> AlignRight
256266 Just "center" -> AlignCenter
257267 _ -> AlignDefault
258− return (align, bs)
268+ let width = case lookup "width" attrs of
269+ Just xs -> maybe 0.0 id $ parseWidth xs
270+ Nothing -> 0.0
271+ return ((align, width), bs)
272+
273+parseWidth :: String -> Maybe Double
274+parseWidth s =
275+ case reverse s of
276+ ('%':ds) | all isDigit ds -> safeRead ('0':'.':reverse ds)
277+ _ -> Nothing
259278
260279template :: MWParser String
261280template = try $ do