git.iko.soy/typeable/pandoc
on master help sign in
MediaWiki reader: Misc fixes, put category links at end.
commiteca9eeab6bcb5b36f40ca54659bb22658cecad30 authorJohn MacFarlane <jgm@berkeley.edu> dateSat 15 Sep 2012, 13:44 (14 years ago) parentbc5fe70
4 files changed+46−26
Makefile+1−1 src/Text/Pandoc/Readers/MediaWiki.hs+41−22 tests/mediawiki-reader.native+2−1 tests/mediawiki-reader.wiki+2−2
Makefile+1−1
@@ -30,4 +30,4 @@ citeproc-hs: pandoc-types
3030 cabal-dev add-source citeproc-hs
3131
3232install:
33− cabal-dev install
33+ cabal-dev install --enable-tests --enable-benchmarks
src/Text/Pandoc/Readers/MediaWiki.hs+41−22
@@ -43,8 +43,7 @@ import Text.Pandoc.Definition
4343import qualified Text.Pandoc.Builder as B
4444import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>))
4545import Text.Pandoc.Options
46−import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag,
47− isBlockTag, isCommentTag )
46+import Text.Pandoc.Readers.HTML ( htmlTag, isBlockTag, isCommentTag )
4847import Text.Pandoc.XML ( fromEntities )
4948import Text.Pandoc.Parsing hiding ( nested )
5049import Text.Pandoc.Generic ( bottomUp )
@@ -52,7 +51,7 @@ import Text.Pandoc.Shared ( stripTrailingNewlines, safeRead )
5251import Data.Monoid (mconcat, mempty)
5352import Control.Applicative ((<$>), (<*), (*>), (<$))
5453import Control.Monad
55−import Data.List (intersperse, intercalate )
54+import Data.List (intersperse, intercalate, isPrefixOf )
5655import Text.HTML.TagSoup
5756import Data.Sequence (viewl, ViewL(..), (<|))
5857
@@ -63,7 +62,9 @@ readMediaWiki :: ReaderOptions -- ^ Reader options
6362readMediaWiki opts s =
6463 case runParser parseMediaWiki MWState{ mwOptions = opts
6564 , mwMaxNestingLevel = 4
66− , mwNextLinkNumber = 1 }
65+ , mwNextLinkNumber = 1
66+ , mwCategoryLinks = []
67+ }
6768 "source" (s ++ "\n") of
6869 Left err' -> error $ "\nError:\n" ++ show err'
6970 Right result -> result
@@ -71,6 +72,7 @@ readMediaWiki opts s =
7172data MWState = MWState { mwOptions :: ReaderOptions
7273 , mwMaxNestingLevel :: Int
7374 , mwNextLinkNumber :: Int
75+ , mwCategoryLinks :: [Inlines]
7476 }
7577
7678type MWParser = Parser [Char] MWState
@@ -103,10 +105,20 @@ newBlockTags :: [String]
103105newBlockTags = ["haskell","syntaxhighlight","source","gallery"]
104106
105107isBlockTag' :: Tag String -> Bool
106−isBlockTag' tag@(TagOpen t _) = isBlockTag tag || t `elem` newBlockTags
107−isBlockTag' tag@(TagClose t) = isBlockTag tag || t `elem` newBlockTags
108+isBlockTag' tag@(TagOpen t _) = (isBlockTag tag || t `elem` newBlockTags) &&
109+ t `notElem` eitherBlockOrInline
110+isBlockTag' tag@(TagClose t) = (isBlockTag tag || t `elem` newBlockTags) &&
111+ t `notElem` eitherBlockOrInline
108112isBlockTag' tag = isBlockTag tag
109113
114+isInlineTag' :: Tag String -> Bool
115+isInlineTag' (TagComment _) = True
116+isInlineTag' t = not (isBlockTag' t)
117+
118+eitherBlockOrInline :: [String]
119+eitherBlockOrInline = ["applet", "button", "del", "iframe", "ins",
120+ "map", "area", "object"]
121+
110122htmlComment :: MWParser ()
111123htmlComment = () <$ htmlTag isCommentTag
112124
@@ -142,7 +154,11 @@ parseMediaWiki = do
142154 bs <- mconcat <$> many block
143155 spaces
144156 eof
145− return $ B.doc bs
157+ categoryLinks <- reverse . mwCategoryLinks <$> getState
158+ let categories = if null categoryLinks
159+ then mempty
160+ else B.para $ mconcat $ intersperse B.space categoryLinks
161+ return $ B.doc $ bs <> categories
146162
147163--
148164-- block parsers
@@ -159,7 +175,7 @@ block = mempty <$ skipMany1 blankline
159175 <|> mempty <$ try (spaces *> htmlComment)
160176 <|> preformatted
161177 <|> blockTag
162− <|> template
178+ <|> (B.rawBlock "mediawiki" <$> template)
163179 <|> para
164180
165181para :: MWParser Blocks
@@ -229,20 +245,18 @@ tableCell :: MWParser Blocks
229245tableCell = try $ do
230246 cellsep
231247 skipMany spaceChar
232− attrs <- (parseAttrs <$>
233− manyTill (satisfy (/='\n'))
234− (try $ char '|' <* notFollowedBy (char '|')))
248+ attrs <- option [] $ try $ parseAttrs <$>
249+ manyTill (satisfy (/='\n')) (char '|' <* notFollowedBy (char '|'))
235250 skipMany spaceChar
236251 ls <- many (notFollowedBy (cellsep <|> rowsep <|> tableEnd) *> anyChar)
237252 parseFromString (mconcat <$> many block) ls
238253
239−template :: MWParser Blocks
240−template = B.rawBlock "mediawiki" <$> doublebrackets
241− where doublebrackets = try $
242− do string "{{"
243− notFollowedBy (char '{')
244− contents <- manyTill anyChar (try $ string "}}")
245− return $ "{{" ++ contents ++ "}}"
254+template :: MWParser String
255+template = try $ do
256+ string "{{"
257+ notFollowedBy (char '{')
258+ contents <- manyTill anyChar (try $ string "}}")
259+ return $ "{{" ++ contents ++ "}}"
246260
247261blockTag :: MWParser Blocks
248262blockTag = do
@@ -403,7 +417,7 @@ inline = whitespace
403417 <|> B.singleton <$> charRef
404418 <|> inlineHtml
405419 <|> variable
406− <|> (mempty <$ template)
420+ <|> (B.rawInline "mediawiki" <$> template)
407421 <|> special
408422
409423str :: MWParser Inlines
@@ -418,7 +432,7 @@ variable = B.rawInline "mediawiki" <$> triplebrackets
418432
419433inlineTag :: MWParser Inlines
420434inlineTag = do
421− (tag, _) <- lookAhead $ htmlTag isInlineTag
435+ (tag, _) <- lookAhead $ htmlTag isInlineTag'
422436 case tag of
423437 TagOpen "nowiki" _ -> try $ do
424438 (_,raw) <- htmlTag (~== tag)
@@ -443,7 +457,7 @@ special = B.str <$> count 1 (notFollowedBy' (htmlTag isBlockTag') *>
443457 oneOf specialChars)
444458
445459inlineHtml :: MWParser Inlines
446−inlineHtml = B.rawInline "html" . snd <$> htmlTag isInlineTag
460+inlineHtml = B.rawInline "html" . snd <$> htmlTag isInlineTag'
447461
448462whitespace :: MWParser Inlines
449463whitespace = B.space <$ (skipMany1 spaceChar <|> endline <|> htmlComment)
@@ -491,7 +505,12 @@ internalLink = try $ do
491505 <|> (return $ B.text $ drop 1 $ dropWhile (/=':') pagename) )
492506 sym "]]"
493507 linktrail <- B.text <$> many (char '\'' <|> letter)
494− return $ B.link (addUnderscores pagename) "wikilink" (label <> linktrail)
508+ let link = B.link (addUnderscores pagename) "wikilink" (label <> linktrail)
509+ if "Category:" `isPrefixOf` pagename
510+ then do
511+ updateState $ \st -> st{ mwCategoryLinks = link : mwCategoryLinks st }
512+ return mempty
513+ else return link
495514
496515externalLink :: MWParser Inlines
497516externalLink = try $ do
tests/mediawiki-reader.native+2−1
@@ -51,7 +51,8 @@ Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
5151,Para [Str "bud"]
5252,Para [Str "another"]
5353,Header 2 [Str "raw",Space,Str "html"]
54−,Para [Str "hi",Space,RawInline "html" "<span style=\"color:red\">",Emph [Str "there"],RawInline "html" "</span>",Str ".",Space,RawInline "html" "<ins>",Str "inserted",RawInline "html" "</ins>"]
54+,Para [Str "hi",Space,RawInline "html" "<span style=\"color:red\">",Emph [Str "there"],RawInline "html" "</span>",Str "."]
55+,Para [RawInline "html" "<ins>",Str "inserted",RawInline "html" "</ins>"]
5556,RawBlock "html" "<div class=\"special\">"
5657,Para [Str "hi",Space,Emph [Str "there"]]
5758,RawBlock "html" "</div>"
tests/mediawiki-reader.wiki+2−2
@@ -91,6 +91,7 @@ another
9191== raw html ==
9292
9393hi <span style="color:red">''there''</span>.
94+
9495<ins>inserted</ins>
9596
9697<div class="special">
@@ -99,8 +100,7 @@ hi ''there''
99100
100101== sup, sub, del ==
101102
102−H<sub>2</sub>O
103−base<sup>''exponent''</sup>
103+H<sub>2</sub>O base<sup>''exponent''</sup>
104104<del>hello</del>
105105
106106== inline code ==