diff options
| author | John MacFarlane <[email protected]> | 2021-03-11 15:49:27 -0800 |
|---|---|---|
| committer | John MacFarlane <[email protected]> | 2021-03-13 15:05:37 -0800 |
| commit | 8be95ad8e5150d5cab66c4abdf59baaf4670c6c8 (patch) | |
| tree | 9655036efbaabda6a2a7802dc971c7fba5a987ca /src/Text/Pandoc/Readers | |
| parent | 35b66a76718205c303f416bf0afc01c098e8a171 (diff) | |
Use custom Prelude based on relude.relude
The Prelude now longer exports partial functions, so
a large number of uses of these functions in the
code base have been rewritten.
A .ghci file has been added; this is necessary for
ghci to work properly with the custom Prelude.
Currently there are lots of compiler warnings.
We should either fix these or go to using a custom
Prelude that changes less than relude.
Diffstat (limited to 'src/Text/Pandoc/Readers')
35 files changed, 245 insertions, 246 deletions
diff --git a/src/Text/Pandoc/Readers/DocBook.hs b/src/Text/Pandoc/Readers/DocBook.hs index d38b07864..bf538e807 100644 --- a/src/Text/Pandoc/Readers/DocBook.hs +++ b/src/Text/Pandoc/Readers/DocBook.hs @@ -25,8 +25,8 @@ import qualified Data.Text.Lazy as TL import Control.Monad.Except (throwError) import Text.HTML.TagSoup.Entity (lookupEntity) import Text.Pandoc.Error (PandocError(..)) -import Text.Pandoc.Builder -import Text.Pandoc.Class.PandocMonad (PandocMonad, report) +import Text.Pandoc.Builder as B +import Text.Pandoc.Class as P (PandocMonad, report) import Text.Pandoc.Options import Text.Pandoc.Logging (LogMessage(..)) import Text.Pandoc.Shared (crFilter, safeRead, extractSpaces) @@ -544,7 +544,7 @@ readDocBook _ inp = do parseXMLContents (TL.fromStrict . handleInstructions $ crFilter inp) (bs, st') <- flip runStateT (def{ dbContent = tree }) $ mapM parseBlock tree - return $ Pandoc (dbMeta st') (toList . mconcat $ bs) + return $ Pandoc (dbMeta st') (B.toList . mconcat $ bs) -- We treat certain processing instructions by converting them to tags -- beginning "pi-". @@ -714,8 +714,8 @@ trimNl = T.dropAround (== '\n') -- assumes Blocks start with a Para; if not, does nothing. addToStart :: Inlines -> Blocks -> Blocks addToStart toadd bs = - case toList bs of - (Para xs : rest) -> para (toadd <> fromList xs) <> fromList rest + case B.toList bs of + (Para xs : rest) -> para (toadd <> B.fromList xs) <> B.fromList rest _ -> bs -- function that is used by both mediaobject (in parseBlock) @@ -949,9 +949,8 @@ parseBlock (Elem e) = (x >= '0' && x <= '9') || x == '.') w if n > 0 then Just n else Nothing - let numrows = case bodyrows of - [] -> 0 - xs -> maximum $ map length xs + let numrows = fromMaybe 0 $ + viaNonEmpty maximum1 $ map length bodyrows let aligns = case colspecs of [] -> replicate numrows AlignDefault cs -> map toAlignment cs diff --git a/src/Text/Pandoc/Readers/Docx.hs b/src/Text/Pandoc/Readers/Docx.hs index 00de6a0cd..37a0beab9 100644 --- a/src/Text/Pandoc/Readers/Docx.hs +++ b/src/Text/Pandoc/Readers/Docx.hs @@ -71,7 +71,7 @@ import Data.Maybe (isJust, fromMaybe) import Data.Sequence (ViewL (..), viewl) import qualified Data.Sequence as Seq import qualified Data.Set as Set -import Text.Pandoc.Builder as Pandoc +import Text.Pandoc.Builder as B import Text.Pandoc.MediaBag (MediaBag) import Text.Pandoc.Options import Text.Pandoc.Readers.Docx.Combine @@ -182,7 +182,7 @@ bodyPartsToMeta' (bp : bps) f (MetaInlines ils) (MetaBlocks blks) = MetaBlocks (Para ils : blks) f m (MetaList mv) = MetaList (m : mv) f m n = MetaList [m, n] - return $ M.insertWith f metaField (MetaInlines (toList inlines)) remaining + return $ M.insertWith f metaField (MetaInlines (B.toList inlines)) remaining bodyPartsToMeta' (_ : bps) = bodyPartsToMeta' bps bodyPartsToMeta :: PandocMonad m => [BodyPart] -> DocxContext m Meta @@ -293,7 +293,7 @@ runStyleToTransform rPr' = do | Just SubScrpt <- rVertAlign rPr = subscript . go rPr{rVertAlign = Nothing} | Just "single" <- rUnderline rPr = - Pandoc.underline . go rPr{rUnderline = Nothing} + B.underline . go rPr{rUnderline = Nothing} | otherwise = id return $ go rPr' @@ -335,7 +335,7 @@ blocksToInlinesWarn cmtId blks = do unless (all paraOrPlain blks) $ lift $ P.report $ DocxParserWarning $ "Docx comment " <> cmtId <> " will not retain formatting" - return $ blocksToInlines' (toList blks) + return $ blocksToInlines' (B.toList blks) -- The majority of work in this function is done in the primed -- subfunction `partPartToInlines'`. We make this wrapper so that we @@ -493,7 +493,7 @@ singleParaToPlain blks = blks cellToBlocks :: PandocMonad m => Docx.Cell -> DocxContext m Blocks cellToBlocks (Docx.Cell bps) = do blks <- smushBlocks <$> mapM bodyPartToBlocks bps - return $ fromList $ blocksToDefinitions $ blocksToBullets $ toList blks + return $ B.fromList $ blocksToDefinitions $ blocksToBullets $ B.toList blks rowToBlocksList :: PandocMonad m => Docx.Row -> DocxContext m [Blocks] rowToBlocksList (Docx.Row cells) = do @@ -647,16 +647,11 @@ bodyPartToBlocks (Tbl cap _ look parts@(r:rs)) = do cells <- mapM rowToBlocksList rows - let width = maybe 0 maximum $ nonEmpty $ map rowLength parts - -- Data.List.NonEmpty is not available with ghc 7.10 so we roll out - -- our own, see - -- https://github.com/jgm/pandoc/pull/4361#issuecomment-365416155 - nonEmpty [] = Nothing - nonEmpty l = Just l + let width = fromMaybe 0 $ viaNonEmpty maximum1 $ map rowLength parts rowLength :: Docx.Row -> Int rowLength (Docx.Row c) = length c - let toRow = Pandoc.Row nullAttr . map simpleCell + let toRow = B.Row nullAttr . map simpleCell toHeaderRow l = [toRow l | not (null l)] -- pad cells. New Text.Pandoc.Builder will do that for us, @@ -720,7 +715,7 @@ bodyToOutput (Body bps) = do let (metabps, blkbps) = sepBodyParts bps meta <- bodyPartsToMeta metabps blks <- smushBlocks <$> mapM bodyPartToBlocks blkbps - blks' <- rewriteLinks $ blocksToDefinitions $ blocksToBullets $ toList blks + blks' <- rewriteLinks $ blocksToDefinitions $ blocksToBullets $ B.toList blks blks'' <- removeOrphanAnchors blks' return (meta, blks'') diff --git a/src/Text/Pandoc/Readers/Docx/Combine.hs b/src/Text/Pandoc/Readers/Docx/Combine.hs index bcf26c4a3..96e86f136 100644 --- a/src/Text/Pandoc/Readers/Docx/Combine.hs +++ b/src/Text/Pandoc/Readers/Docx/Combine.hs @@ -61,7 +61,7 @@ import Data.List import Data.Bifunctor import Data.Sequence ( ViewL (..), ViewR (..), viewl, viewr, spanr, spanl , (><), (|>) ) -import Text.Pandoc.Builder +import Text.Pandoc.Builder as B data Modifier a = Modifier (a -> a) | AttrModifier (Attr -> a -> a) Attr @@ -101,7 +101,7 @@ unstackInlines ms = case ilModifierAndInnards ms of ilModifierAndInnards :: Inlines -> Maybe (Modifier Inlines, Inlines) ilModifierAndInnards ils = case viewl $ unMany ils of - x :< xs | null xs -> second fromList <$> case x of + x :< xs | null xs -> second B.fromList <$> case x of Emph lst -> Just (Modifier emph, lst) Strong lst -> Just (Modifier strong, lst) SmallCaps lst -> Just (Modifier smallcaps, lst) diff --git a/src/Text/Pandoc/Readers/Docx/Lists.hs b/src/Text/Pandoc/Readers/Docx/Lists.hs index e63f8457e..a86a608c7 100644 --- a/src/Text/Pandoc/Readers/Docx/Lists.hs +++ b/src/Text/Pandoc/Readers/Docx/Lists.hs @@ -17,7 +17,7 @@ module Text.Pandoc.Readers.Docx.Lists ( blocksToBullets , listParagraphStyles ) where -import Data.List +import Data.List (intersect, delete, (\\)) import Data.Maybe import Data.String (fromString) import qualified Data.Text as T @@ -109,12 +109,15 @@ handleListParagraphs (blk:blks) = blk : handleListParagraphs blks separateBlocks' :: Block -> [[Block]] -> [[Block]] separateBlocks' blk [[]] = [[blk]] -separateBlocks' b@(BulletList _) acc = init acc ++ [last acc ++ [b]] -separateBlocks' b@(OrderedList _ _) acc = init acc ++ [last acc ++ [b]] +separateBlocks' b@(BulletList _) acc = fromMaybe acc $ flip viaNonEmpty acc $ + \accNE -> init accNE ++ [last accNE ++ [b]] +separateBlocks' b@(OrderedList _ _) acc = fromMaybe acc $ flip viaNonEmpty acc $ + \accNE -> init accNE ++ [last accNE ++ [b]] -- The following is for the invisible bullet lists. This is how -- pandoc-generated ooxml does multiparagraph item lists. separateBlocks' b acc | fmap trim (getText b) == Just "" = - init acc ++ [last acc ++ [b]] + fromMaybe acc $ flip viaNonEmpty acc $ + \accNE -> init accNE ++ [last accNE ++ [b]] separateBlocks' b acc = acc ++ [[b]] separateBlocks :: [Block] -> [[Block]] @@ -178,9 +181,9 @@ blocksToDefinitions' ((defTerm, defItems):defs) acc defItems2 = if remainingAttr2 == ("", [], []) then blks2 else [Div remainingAttr2 blks2] - defAcc' = if null defItems - then (defTerm, [defItems2]) : defs - else (defTerm, init defItems ++ [last defItems ++ defItems2]) : defs + defAcc' = fromMaybe ((defTerm, [defItems2]) : defs) $ + flip viaNonEmpty defItems $ \items -> + (defTerm, init items ++ [last items ++ defItems2]) : defs in blocksToDefinitions' defAcc' acc blks blocksToDefinitions' [] acc (b:blks) = diff --git a/src/Text/Pandoc/Readers/Docx/Parse.hs b/src/Text/Pandoc/Readers/Docx/Parse.hs index f8ed248d7..818374398 100644 --- a/src/Text/Pandoc/Readers/Docx/Parse.hs +++ b/src/Text/Pandoc/Readers/Docx/Parse.hs @@ -60,7 +60,6 @@ import Control.Monad.State.Strict import Data.Bits ((.|.)) import qualified Data.ByteString.Lazy as B import Data.Char (chr, ord, readLitChar) -import Data.List import qualified Data.Map as M import qualified Data.Text as T import Data.Text (Text) @@ -909,7 +908,9 @@ elemToRun ns element | isElem ns "w" "r" element , Just altCont <- findChildByName ns "mc" "AlternateContent" element = do let choices = findChildrenByName ns "mc" "Choice" altCont - choiceChildren = map head $ filter (not . null) $ map elChildren choices + choiceChildren = mapMaybe (\n -> case elChildren n of + [] -> Nothing + (x:_) -> Just x) choices outputs <- mapD (childElemToRun ns) choiceChildren case outputs of r : _ -> return r diff --git a/src/Text/Pandoc/Readers/DokuWiki.hs b/src/Text/Pandoc/Readers/DokuWiki.hs index dedc1f03f..8c27a5132 100644 --- a/src/Text/Pandoc/Readers/DokuWiki.hs +++ b/src/Text/Pandoc/Readers/DokuWiki.hs @@ -24,7 +24,7 @@ import Data.Maybe (fromMaybe, catMaybes) import Data.Text (Text) import qualified Data.Text as T import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Error (PandocError (PandocParsecError)) import Text.Pandoc.Options @@ -388,7 +388,7 @@ block = do <|> blockElements <|> para skipMany blankline - trace (T.take 60 $ tshow $ B.toList res) + P.trace (T.take 60 $ tshow $ B.toList res) return res blockElements :: PandocMonad m => DWParser m B.Blocks @@ -466,10 +466,9 @@ blockPhp = try $ B.codeBlockWith ("", ["php"], []) table :: PandocMonad m => DWParser m B.Blocks table = do firstSeparator <- lookAhead tableCellSeparator - rows <- tableRows - let (headerRow, body) = if firstSeparator == '^' - then (head rows, tail rows) - else ([], rows) + rows@(headerRow:body) <- if firstSeparator == '^' + then tableRows + else ([]:) <$> tableRows let attrs = (AlignDefault, ColWidthDefault) <$ transpose rows let toRow = Row nullAttr . map B.simpleCell toHeaderRow l = [toRow l | not (null l)] diff --git a/src/Text/Pandoc/Readers/FB2.hs b/src/Text/Pandoc/Readers/FB2.hs index 66e390bd7..2f4e4bb64 100644 --- a/src/Text/Pandoc/Readers/FB2.hs +++ b/src/Text/Pandoc/Readers/FB2.hs @@ -35,7 +35,7 @@ import qualified Data.Text.Lazy as TL import Data.Default import Data.Maybe import Text.HTML.TagSoup.Entity (lookupEntity) -import Text.Pandoc.Builder +import Text.Pandoc.Builder as B import Text.Pandoc.Class.PandocMonad (PandocMonad, insertMedia, report) import Text.Pandoc.Error import Text.Pandoc.Logging @@ -72,7 +72,7 @@ readFB2 _ inp = let authors = if null $ fb2Authors st then id else setMeta "author" (map text $ reverse $ fb2Authors st) - pure $ Pandoc (authors $ fb2Meta st) $ toList bs + pure $ Pandoc (authors $ fb2Meta st) $ B.toList bs -- * Utility functions @@ -285,7 +285,7 @@ parsePoemChild e = name -> report (UnexpectedXmlElement name "poem") $> mempty parseStanza :: PandocMonad m => Element -> FB2 m Blocks -parseStanza e = fromList . joinLineBlocks . toList . mconcat <$> mapM parseStanzaChild (elChildren e) +parseStanza e = B.fromList . joinLineBlocks . B.toList . mconcat <$> mapM parseStanzaChild (elChildren e) joinLineBlocks :: [Block] -> [Block] joinLineBlocks (LineBlock xs:LineBlock ys:zs) = joinLineBlocks (LineBlock (xs ++ ys) : zs) diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs index b73c138ab..5d9c06390 100644 --- a/src/Text/Pandoc/Readers/HTML.hs +++ b/src/Text/Pandoc/Readers/HTML.hs @@ -43,7 +43,7 @@ import Text.HTML.TagSoup import Text.HTML.TagSoup.Match import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.CSS (pickStyleAttrProps) import qualified Text.Pandoc.UTF8 as UTF8 import Text.Pandoc.Definition @@ -214,7 +214,7 @@ block = ((do -> eSwitch B.para block _ -> mzero _ -> mzero) <|> pPlain <|> pRawHtmlBlock) >>= \res -> - res <$ trace (T.take 60 $ tshow $ B.toList res) + res <$ P.trace (T.take 60 $ tshow $ B.toList res) namespaces :: PandocMonad m => [(Text, TagParser m Inlines)] namespaces = [(mathMLNamespace, pMath True)] @@ -360,7 +360,8 @@ pDefListItem = try $ do terms <- many1 (try $ skipMany nonItem >> pInTags "dt" inline) defs <- many1 (try $ skipMany nonItem >> pInTags "dd" block) skipMany nonItem - let term = foldl1 (\x y -> x <> B.linebreak <> y) $ map trimInlines terms + let term = fromMaybe mempty $ viaNonEmpty + (foldl1' (\x y -> x <> B.linebreak <> y)) $ map trimInlines terms return (term, map (fixPlains True) defs) fixPlains :: Bool -> Blocks -> Blocks @@ -611,7 +612,7 @@ inline = pTagText <|> do "script" | Just x <- lookup "type" attr , "math/tex" `T.isPrefixOf` x -> pScriptMath - _ | name `elem` htmlSpanLikeElements -> pSpanLike + _ | name `Set.member` htmlSpanLikeElements -> pSpanLike _ -> pRawHtmlInline TagText _ -> pTagText _ -> pRawHtmlInline diff --git a/src/Text/Pandoc/Readers/HTML/Table.hs b/src/Text/Pandoc/Readers/HTML/Table.hs index 6179ea8e7..b8091d7e9 100644 --- a/src/Text/Pandoc/Readers/HTML/Table.hs +++ b/src/Text/Pandoc/Readers/HTML/Table.hs @@ -216,7 +216,7 @@ normalize widths head' bodies foot = do let rows = headRows head' <> concatMap bodyRows bodies <> footRows foot let cellWidth (Cell _ _ _ (ColSpan cs) _) = cs let rowLength = foldr (\cell acc -> cellWidth cell + acc) 0 . rowCells - let ncols = maximum (map rowLength rows) + let ncols = fromMaybe 0 $ viaNonEmpty maximum1 (map rowLength rows) let tblType = tableType (map rowCells rows) -- fail on empty table if null rows diff --git a/src/Text/Pandoc/Readers/HTML/TagCategories.hs b/src/Text/Pandoc/Readers/HTML/TagCategories.hs index b7bd40fee..a339b2e76 100644 --- a/src/Text/Pandoc/Readers/HTML/TagCategories.hs +++ b/src/Text/Pandoc/Readers/HTML/TagCategories.hs @@ -21,17 +21,18 @@ module Text.Pandoc.Readers.HTML.TagCategories ) where -import Data.Set (Set, fromList, unions) +import Data.Set (Set) +import qualified Data.Set as Set import Data.Text (Text) eitherBlockOrInline :: Set Text -eitherBlockOrInline = fromList +eitherBlockOrInline = Set.fromList ["audio", "applet", "button", "iframe", "embed", "del", "ins", "progress", "map", "area", "noscript", "script", "object", "svg", "video", "source"] blockHtmlTags :: Set Text -blockHtmlTags = fromList +blockHtmlTags = Set.fromList ["?xml", "!DOCTYPE", "address", "article", "aside", "blockquote", "body", "canvas", "caption", "center", "col", "colgroup", "dd", "details", @@ -48,7 +49,7 @@ blockHtmlTags = fromList -- We want to allow raw docbook in markdown documents, so we -- include docbook block tags here too. blockDocBookTags :: Set Text -blockDocBookTags = fromList +blockDocBookTags = Set.fromList ["calloutlist", "bibliolist", "glosslist", "itemizedlist", "orderedlist", "segmentedlist", "simplelist", "variablelist", "caution", "important", "note", "tip", @@ -63,10 +64,10 @@ blockDocBookTags = fromList "sidebar", "title"] epubTags :: Set Text -epubTags = fromList ["case", "switch", "default"] +epubTags = Set.fromList ["case", "switch", "default"] blockTags :: Set Text -blockTags = unions [blockHtmlTags, blockDocBookTags, epubTags] +blockTags = Set.unions [blockHtmlTags, blockDocBookTags, epubTags] sectioningContent :: [Text] sectioningContent = ["article", "aside", "nav", "section"] diff --git a/src/Text/Pandoc/Readers/Haddock.hs b/src/Text/Pandoc/Readers/Haddock.hs index 25d69f040..a50117f28 100644 --- a/src/Text/Pandoc/Readers/Haddock.hs +++ b/src/Text/Pandoc/Readers/Haddock.hs @@ -88,12 +88,12 @@ docHToBlocks d' = toRow = Row nullAttr . map B.simpleCell toHeaderRow l = [toRow l | not (null l)] (header, body) = - if null headerRows - then ([], map toCells bodyRows) - else (toCells (head headerRows), - map toCells (tail headerRows ++ bodyRows)) - colspecs = replicate (maximum (map length body)) - (AlignDefault, ColWidthDefault) + case headerRows of + [] -> ([], map toCells bodyRows) + (x:xs) -> (toCells x, map toCells (xs ++ bodyRows)) + colspecs = replicate + (fromMaybe 0 $ viaNonEmpty maximum1 (map length body)) + (AlignDefault, ColWidthDefault) in B.table B.emptyCaption colspecs (TableHead nullAttr $ toHeaderRow header) diff --git a/src/Text/Pandoc/Readers/JATS.hs b/src/Text/Pandoc/Readers/JATS.hs index 602f3b4f2..d253775d8 100644 --- a/src/Text/Pandoc/Readers/JATS.hs +++ b/src/Text/Pandoc/Readers/JATS.hs @@ -26,7 +26,7 @@ import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Text.HTML.TagSoup.Entity (lookupEntity) -import Text.Pandoc.Builder +import Text.Pandoc.Builder as B import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Options import Text.Pandoc.Shared (crFilter, safeRead, extractSpaces) @@ -57,7 +57,7 @@ readJATS _ inp = do tree <- either (throwError . PandocXMLError "") return $ parseXMLContents (TL.fromStrict $ crFilter inp) (bs, st') <- flip runStateT (def{ jatsContent = tree }) $ mapM parseBlock tree - return $ Pandoc (jatsMeta st') (toList . mconcat $ bs) + return $ Pandoc (jatsMeta st') (B.toList . mconcat $ bs) -- convenience function to get an attribute value, defaulting to "" attrValue :: Text -> Element -> Text diff --git a/src/Text/Pandoc/Readers/Jira.hs b/src/Text/Pandoc/Readers/Jira.hs index 89aecbf56..f280bc983 100644 --- a/src/Text/Pandoc/Readers/Jira.hs +++ b/src/Text/Pandoc/Readers/Jira.hs @@ -16,7 +16,7 @@ import Data.Text (Text, append, pack, singleton, unpack) import Text.HTML.TagSoup.Entity (lookupEntity) import Text.Jira.Parser (parse) import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) -import Text.Pandoc.Builder hiding (cell) +import Text.Pandoc.Builder as B hiding (cell) import Text.Pandoc.Error (PandocError (PandocParseError)) import Text.Pandoc.Options (ReaderOptions) import Text.Pandoc.Shared (stringify) @@ -128,7 +128,7 @@ jiraToPandocInlines = \case in imageWith attr (Jira.fromURL url) title mempty Jira.Link lt alias url -> jiraLinkToPandoc lt alias url Jira.Linebreak -> linebreak - Jira.Monospaced inlns -> code . stringify . toList . fromInlines $ inlns + Jira.Monospaced inlns -> code . stringify . B.toList . fromInlines $ inlns Jira.Space -> space Jira.SpecialChar c -> str (Data.Text.singleton c) Jira.Str t -> str t diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs index ceac261d2..5c494bbd6 100644 --- a/src/Text/Pandoc/Readers/LaTeX.hs +++ b/src/Text/Pandoc/Readers/LaTeX.hs @@ -36,10 +36,8 @@ import qualified Data.Text as T import System.FilePath (addExtension, replaceExtension, takeExtension) import Text.Pandoc.BCP47 (renderLang) import Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocPure (PandocPure) -import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath, - readFileFromDirs, report, - setResourcePath) +import Text.Pandoc.Class as P (PandocPure, PandocMonad (..), getResourcePath, + readFileFromDirs, report, setResourcePath) import Text.Pandoc.Error (PandocError (PandocParseError, PandocParsecError)) import Text.Pandoc.Highlighting (languagesByExtension) import Text.Pandoc.ImageSize (numUnit, showFl) @@ -382,7 +380,7 @@ inlineCommands = M.unions , ("it", extractSpaces emph <$> inlines) , ("sl", extractSpaces emph <$> inlines) , ("bf", extractSpaces strong <$> inlines) - , ("tt", code . stringify . toList <$> inlines) + , ("tt", code . stringify . B.toList <$> inlines) , ("rm", inlines) , ("itshape", extractSpaces emph <$> inlines) , ("slshape", extractSpaces emph <$> inlines) @@ -451,10 +449,10 @@ ifdim = do return $ rawInline "latex" $ "\\ifdim" <> untokenize contents <> "\\fi" makeUppercase :: Inlines -> Inlines -makeUppercase = fromList . walk (alterStr T.toUpper) . toList +makeUppercase = B.fromList . walk (alterStr T.toUpper) . B.toList makeLowercase :: Inlines -> Inlines -makeLowercase = fromList . walk (alterStr T.toLower) . toList +makeLowercase = B.fromList . walk (alterStr T.toLower) . B.toList alterStr :: (Text -> Text) -> Inline -> Inline alterStr f (Str xs) = Str (f xs) @@ -476,7 +474,7 @@ hypertargetBlock :: PandocMonad m => LP m Blocks hypertargetBlock = try $ do ref <- untokenize <$> braced bs <- grouped block - case toList bs of + case B.toList bs of [Header 1 (ident,_,_) _] | ident == ref -> return bs _ -> return $ divWith (ref, [], []) bs @@ -534,7 +532,7 @@ coloredInline stylename = do spanWith ("",[],[("style",stylename <> ": " <> untokenize color)]) <$> tok ttfamily :: PandocMonad m => LP m Inlines -ttfamily = code . stringify . toList <$> tok +ttfamily = code . stringify . B.toList <$> tok processHBox :: Inlines -> Inlines processHBox = walk convert @@ -824,7 +822,7 @@ closing = do extractInlines _ = [] let sigs = case lookupMeta "author" (sMeta st) of Just (MetaList xs) -> - para $ trimInlines $ fromList $ + para $ trimInlines $ B.fromList $ intercalate [LineBreak] $ map extractInlines xs _ -> mempty return $ para (trimInlines contents) <> sigs @@ -1049,8 +1047,8 @@ fancyverbEnv name = do obeylines :: PandocMonad m => LP m Blocks obeylines = - para . fromList . removeLeadingTrailingBreaks . - walk softBreakToHard . toList <$> env "obeylines" inlines + para . B.fromList . removeLeadingTrailingBreaks . + walk softBreakToHard . B.toList <$> env "obeylines" inlines where softBreakToHard SoftBreak = LineBreak softBreakToHard x = x removeLeadingTrailingBreaks = reverse . dropWhile isLineBreak . @@ -1095,7 +1093,7 @@ letterContents = do -- add signature (author) and address (title) let addr = case lookupMeta "address" (sMeta st) of Just (MetaBlocks [Plain xs]) -> - para $ trimInlines $ fromList xs + para $ trimInlines $ B.fromList xs _ -> mempty return $ addr <> bs -- sig added by \closing @@ -1110,7 +1108,7 @@ addImageCaption = walkM go | not ("fig:" `T.isPrefixOf` tit) = do st <- getState let (alt', tit') = case sCaption st of - Just ils -> (toList ils, "fig:" <> tit) + Just ils -> (B.toList ils, "fig:" <> tit) Nothing -> (alt, tit) attr' = case sLastLabel st of Just lab -> (lab, cls, kvs) @@ -1255,7 +1253,7 @@ block = do _ -> mzero) <|> paragraph <|> grouped block - trace (T.take 60 $ tshow $ B.toList res) + P.trace (T.take 60 $ tshow $ B.toList res) return res blocks :: PandocMonad m => LP m Blocks diff --git a/src/Text/Pandoc/Readers/LaTeX/Citation.hs b/src/Text/Pandoc/Readers/LaTeX/Citation.hs index 655823dab..8e3b56220 100644 --- a/src/Text/Pandoc/Readers/LaTeX/Citation.hs +++ b/src/Text/Pandoc/Readers/LaTeX/Citation.hs @@ -88,15 +88,15 @@ addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks addPrefix _ _ = [] addSuffix :: [Inline] -> [Citation] -> [Citation] -addSuffix s ks@(_:_) = - let k = last ks - in init ks ++ [k {citationSuffix = citationSuffix k ++ s}] -addSuffix _ _ = [] +addSuffix s = + fromMaybe [] . viaNonEmpty + (\ks' -> let k = last ks' + in init ks' ++ [k {citationSuffix = citationSuffix k ++ s}]) simpleCiteArgs :: forall m . PandocMonad m => LP m Inlines -> LP m [Citation] simpleCiteArgs inline = try $ do - first <- optionMaybe $ toList <$> opt - second <- optionMaybe $ toList <$> opt + first <- optionMaybe $ B.toList <$> opt + second <- optionMaybe $ B.toList <$> opt keys <- try $ bgroup *> manyTill citationLabel egroup let (pre, suf) = case (first , second ) of (Just s , Nothing) -> (mempty, s ) @@ -140,8 +140,8 @@ cites inline mode multi = try $ do let paropt = parenWrapped inline cits <- if multi then do - multiprenote <- optionMaybe $ toList <$> paropt - multipostnote <- optionMaybe $ toList <$> paropt + multiprenote <- optionMaybe $ B.toList <$> paropt + multipostnote <- optionMaybe $ B.toList <$> paropt let (pre, suf) = case (multiprenote, multipostnote) of (Just s , Nothing) -> (mempty, s) (Nothing , Just t) -> (mempty, t) @@ -149,10 +149,11 @@ cites inline mode multi = try $ do _ -> (mempty, mempty) tempCits <- many1 $ simpleCiteArgs inline case tempCits of - (k:ks) -> case ks of - (_:_) -> return $ (addMprenote pre k : init ks) ++ - [addMpostnote suf (last ks)] - _ -> return [addMprenote pre (addMpostnote suf k)] + (k:ks) -> + return $ fromMaybe [addMprenote pre (addMpostnote suf k)] + $ viaNonEmpty + (\ks' -> addMprenote pre k : init ks' ++ + [addMpostnote suf (last ks')]) ks _ -> return [[]] else count 1 $ simpleCiteArgs inline let cs = concat cits @@ -183,7 +184,7 @@ handleCitationPart :: Inlines -> [Citation] handleCitationPart ils = let isCite Cite{} = True isCite _ = False - (pref, rest) = break isCite (toList ils) + (pref, rest) = break isCite (B.toList ils) in case rest of (Cite cs _:suff) -> addPrefix pref $ addSuffix suff cs _ -> [] diff --git a/src/Text/Pandoc/Readers/LaTeX/Inline.hs b/src/Text/Pandoc/Readers/LaTeX/Inline.hs index 7b8bca4af..6d14bf747 100644 --- a/src/Text/Pandoc/Readers/LaTeX/Inline.hs +++ b/src/Text/Pandoc/Readers/LaTeX/Inline.hs @@ -25,7 +25,7 @@ where import qualified Data.Map as M import Data.Text (Text) import qualified Data.Text as T -import Text.Pandoc.Builder +import Text.Pandoc.Builder as B import Text.Pandoc.Shared (toRomanNumeral, safeRead) import Text.Pandoc.Readers.LaTeX.Types (Tok (..), TokType (..)) import Control.Applicative (optional, (<|>)) @@ -162,8 +162,8 @@ accentWith :: PandocMonad m => LP m Inlines -> Char -> Maybe Char -> LP m Inlines accentWith tok combiningAccent fallBack = try $ do ils <- tok - case toList ils of - (Str (T.uncons -> Just (x, xs)) : ys) -> return $ fromList $ + case B.toList ils of + (Str (T.uncons -> Just (x, xs)) : ys) -> return $ B.fromList $ -- try to normalize to the combined character: Str (Normalize.normalize Normalize.NFC (T.pack [x, combiningAccent]) <> xs) : ys diff --git a/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs b/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs index 1952f4e1a..991ec4d98 100644 --- a/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs +++ b/src/Text/Pandoc/Readers/LaTeX/SIunitx.hs @@ -60,9 +60,9 @@ doSInumlist = do case xs of [] -> return mempty [x] -> return x - _ -> return $ - mconcat (intersperse (str "," <> space) (init xs)) <> - text ", & " <> last xs + _ -> return $ fromMaybe mempty $ viaNonEmpty + (\xsNE -> mconcat (intersperse (str "," <> space) (init xsNE)) <> + text ", & " <> last xsNE) xs parseNum :: Parser Text () Inlines parseNum = (mconcat <$> many parseNumPart) <* eof diff --git a/src/Text/Pandoc/Readers/LaTeX/Table.hs b/src/Text/Pandoc/Readers/LaTeX/Table.hs index 7833da081..10d41912e 100644 --- a/src/Text/Pandoc/Readers/LaTeX/Table.hs +++ b/src/Text/Pandoc/Readers/LaTeX/Table.hs @@ -194,8 +194,8 @@ cellAlignment = skipMany (symbol '|') *> alignment <* skipMany (symbol '|') _ -> AlignDefault plainify :: Blocks -> Blocks -plainify bs = case toList bs of - [Para ils] -> plain (fromList ils) +plainify bs = case B.toList bs of + [Para ils] -> plain (B.fromList ils) _ -> bs multirowCell :: PandocMonad m => LP m Blocks -> LP m Cell @@ -231,7 +231,7 @@ multicolumnCell blocks = controlSeq "multicolumn" >> do alignment (RowSpan rs) (ColSpan span') - (fromList bs) + (B.fromList bs) symbol '{' *> (nestedCell <|> singleCell) <* symbol '}' diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs index 34edbcc17..4dddd3500 100644 --- a/src/Text/Pandoc/Readers/Markdown.hs +++ b/src/Text/Pandoc/Readers/Markdown.hs @@ -33,7 +33,7 @@ import System.FilePath (addExtension, takeExtension) import Text.HTML.TagSoup hiding (Row) import Text.Pandoc.Builder (Blocks, Inlines) import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..), report) +import Text.Pandoc.Class as P (PandocMonad (..), report) import Text.Pandoc.Definition as Pandoc import Text.Pandoc.Emoji (emojiToInline) import Text.Pandoc.Error @@ -357,7 +357,7 @@ referenceKey = try $ do addKvs <- option [] $ guardEnabled Ext_mmd_link_attributes >> many (try $ spnl >> keyValAttr) blanklines - let attr' = extractIdClass $ foldl (\x f -> f x) attr addKvs + let attr' = extractIdClass $ foldl' (\x f -> f x) attr addKvs target = (escapeURI $ trimr src, tit) st <- getState let oldkeys = stateKeys st @@ -476,7 +476,7 @@ block = do , para , plain ] <?> "block" - trace (T.take 60 $ tshow $ B.toList $ runF res defaultParserState) + P.trace (T.take 60 $ tshow $ B.toList $ runF res defaultParserState) return res -- @@ -613,7 +613,7 @@ attributes = try $ do spnl attrs <- many (attribute <* spnl) char '}' - return $ foldl (\x f -> f x) nullAttr attrs + return $ foldl' (\x f -> f x) nullAttr attrs attribute :: PandocMonad m => MarkdownParser m (Attr -> Attr) attribute = identifierAttr <|> classAttr <|> keyValAttr <|> specialAttr @@ -1204,10 +1204,9 @@ simpleTableHeader headless = try $ do let (lengths, lines') = unzip dashes let indices = scanl (+) (T.length initSp) lines' -- If no header, calculate alignment on basis of first row of text - rawHeads <- fmap (tail . splitTextByIndices (init indices)) $ - if headless - then lookAhead anyLine - else return rawContent + rawHeads <- splitLine indices <$> if headless + then lookAhead anyLine + else return rawContent let aligns = zipWith alignType (map (: []) rawHeads) lengths let rawHeads' = if headless then [] @@ -1217,6 +1216,10 @@ simpleTableHeader headless = try $ do mapM (parseFromString' (mconcat <$> many plain).trim) rawHeads' return (heads, aligns, indices) +splitLine :: [Int] -> Text -> [Text] +splitLine indices = + drop 1 . splitTextByIndices (fromMaybe [] $ viaNonEmpty init indices) + -- Returns an alignment type for a table, based on a list of strings -- (the rows of the column header) and a number (the length of the -- dashed line under the rows. @@ -1251,8 +1254,7 @@ rawTableLine :: PandocMonad m rawTableLine indices = do notFollowedBy' (blanklines' <|> tableFooter) line <- take1WhileP (/='\n') <* newline - return $ map trim $ tail $ - splitTextByIndices (init indices) line + return $ map trim $ splitLine indices line -- Parse a table line and return a list of lists of blocks (columns). tableLine :: PandocMonad m @@ -1322,11 +1324,9 @@ multilineTableHeader headless = try $ do [] -> [] (x:xs) -> reverse (x+1:xs) rawHeadsList <- if headless - then fmap (map (:[]) . tail . - splitTextByIndices (init indices')) $ lookAhead anyLine + then map (:[]) . splitLine indices' <$> lookAhead anyLine else return $ transpose $ map - (tail . splitTextByIndices (init indices')) - rawContent + (splitLine indices') rawContent let aligns = zipWith alignType rawHeadsList lengths let rawHeads = if headless then [] @@ -1363,8 +1363,8 @@ pipeTable = try $ do let heads' = take (length aligns) <$> heads lines' <- many pipeTableRow let lines'' = map (take (length aligns) <$>) lines' - let maxlength = maximum $ - map (\x -> T.length . stringify $ runF x def) (heads' : lines'') + let maxlength = maximum1 $ + fmap (\x -> T.length . stringify $ runF x def) (heads' :| lines'') numColumns <- getOption readerColumns let widths = if maxlength > numColumns then map (\len -> @@ -1626,9 +1626,9 @@ enclosure c = do (return (B.str cs) <>) <$> whitespace <|> case T.length cs of - 3 -> three c - 2 -> two c mempty - 1 -> one c mempty + 3 -> three' c + 2 -> two' c mempty + 1 -> one' c mempty _ -> return (return $ B.str cs) ender :: PandocMonad m => Char -> Int -> MarkdownParser m () @@ -1642,18 +1642,18 @@ ender c n = try $ do -- If one c, emit emph and then parse two. -- If two cs, emit strong and then parse one. -- Otherwise, emit ccc then the results. -three :: PandocMonad m => Char -> MarkdownParser m (F Inlines) -three c = do +three' :: PandocMonad m => Char -> MarkdownParser m (F Inlines) +three' c = do contents <- mconcat <$> many (notFollowedBy (ender c 1) >> inline) (ender c 3 >> updateLastStrPos >> return (B.strong . B.emph <$> contents)) - <|> (ender c 2 >> updateLastStrPos >> one c (B.strong <$> contents)) - <|> (ender c 1 >> updateLastStrPos >> two c (B.emph <$> contents)) + <|> (ender c 2 >> updateLastStrPos >> one' c (B.strong <$> contents)) + <|> (ender c 1 >> updateLastStrPos >> two' c (B.emph <$> contents)) <|> return (return (B.str $ T.pack [c,c,c]) <> contents) -- Parse inlines til you hit two c's, and emit strong. -- If you never do hit two cs, emit ** plus inlines parsed. -two :: PandocMonad m => Char -> F Inlines -> MarkdownParser m (F Inlines) -two c prefix' = do +two' :: PandocMonad m => Char -> F Inlines -> MarkdownParser m (F Inlines) +two' c prefix' = do contents <- mconcat <$> many (try $ notFollowedBy (ender c 2) >> inline) (ender c 2 >> updateLastStrPos >> return (B.strong <$> (prefix' <> contents))) @@ -1661,12 +1661,12 @@ two c prefix' = do -- Parse inlines til you hit a c, and emit emph. -- If you never hit a c, emit * plus inlines parsed. -one :: PandocMonad m => Char -> F Inlines -> MarkdownParser m (F Inlines) -one c prefix' = do +one' :: PandocMonad m => Char -> F Inlines -> MarkdownParser m (F Inlines) +one' c prefix' = do contents <- mconcat <$> many ( (notFollowedBy (ender c 1) >> inline) <|> try (string [c,c] >> notFollowedBy (ender c 1) >> - two c mempty) ) + two' c mempty) ) (ender c 1 >> updateLastStrPos >> return (B.emph <$> (prefix' <> contents))) <|> return (return (B.str $ T.singleton c) <> (prefix' <> contents)) diff --git a/src/Text/Pandoc/Readers/MediaWiki.hs b/src/Text/Pandoc/Readers/MediaWiki.hs index 9f4d5e170..d812b0a34 100644 --- a/src/Text/Pandoc/Readers/MediaWiki.hs +++ b/src/Text/Pandoc/Readers/MediaWiki.hs @@ -30,7 +30,7 @@ import qualified Data.Text as T import Text.HTML.TagSoup import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Logging import Text.Pandoc.Options @@ -192,7 +192,7 @@ block = do <|> blockTag <|> (B.rawBlock "mediawiki" <$> template) <|> para - trace (T.take 60 $ tshow $ B.toList res) + P.trace (T.take 60 $ tshow $ B.toList res) return res para :: PandocMonad m => MWParser m Blocks diff --git a/src/Text/Pandoc/Readers/Muse.hs b/src/Text/Pandoc/Readers/Muse.hs index b4eea9d3a..155c36844 100644 --- a/src/Text/Pandoc/Readers/Muse.hs +++ b/src/Text/Pandoc/Readers/Muse.hs @@ -31,7 +31,7 @@ import Data.Text (Text) import qualified Data.Text as T import Text.Pandoc.Builder (Blocks, Inlines, underline) import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Error (PandocError (PandocParsecError)) import Text.Pandoc.Logging @@ -293,7 +293,7 @@ listItemContentsUntil col pre end = p parseBlock :: PandocMonad m => MuseParser m (F Blocks) parseBlock = do res <- blockElements <|> para - trace (T.take 60 $ tshow $ B.toList $ runF res def) + P.trace (T.take 60 $ tshow $ B.toList $ runF res def) return res where para = fst <$> paraUntil (try (eof <|> void (lookAhead blockElements))) diff --git a/src/Text/Pandoc/Readers/OPML.hs b/src/Text/Pandoc/Readers/OPML.hs index 5f2ddb876..248a15709 100644 --- a/src/Text/Pandoc/Readers/OPML.hs +++ b/src/Text/Pandoc/Readers/OPML.hs @@ -18,7 +18,7 @@ import Data.Maybe (fromMaybe) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Lazy as TL -import Text.Pandoc.Builder +import Text.Pandoc.Builder as B import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Options import Text.Pandoc.Error (PandocError(..)) @@ -77,7 +77,7 @@ asMarkdown :: PandocMonad m => Text -> OPML m Blocks asMarkdown s = do opts <- gets opmlOptions Pandoc _ bs <- readMarkdown def{ readerExtensions = readerExtensions opts } s - return $ fromList bs + return $ B.fromList bs getBlocks :: PandocMonad m => Element -> OPML m Blocks getBlocks e = mconcat <$> mapM parseBlock (elContent e) diff --git a/src/Text/Pandoc/Readers/Odt/Arrows/State.hs b/src/Text/Pandoc/Readers/Odt/Arrows/State.hs index 93c6b5e79..dddf512fb 100644 --- a/src/Text/Pandoc/Readers/Odt/Arrows/State.hs +++ b/src/Text/Pandoc/Readers/Odt/Arrows/State.hs @@ -22,7 +22,7 @@ module Text.Pandoc.Readers.Odt.Arrows.State where import Control.Arrow import qualified Control.Category as Cat import Control.Monad - +import Prelude hiding (first, second) import Text.Pandoc.Readers.Odt.Arrows.Utils import Text.Pandoc.Readers.Odt.Generic.Fallible @@ -122,7 +122,7 @@ iterateS a = ArrowState $ \(s,f) -> foldr a' (s,mzero) f iterateSL :: (Foldable f, MonadPlus m) => ArrowState s x y -> ArrowState s (f x) (m y) -iterateSL a = ArrowState $ \(s,f) -> foldl a' (s,mzero) f +iterateSL a = ArrowState $ \(s,f) -> foldl' a' (s,mzero) f where a' (s',m) x = second (mplus m.return) $ runArrowState a (s',x) diff --git a/src/Text/Pandoc/Readers/Odt/ContentReader.hs b/src/Text/Pandoc/Readers/Odt/ContentReader.hs index df90880fa..9ebeca30c 100644 --- a/src/Text/Pandoc/Readers/Odt/ContentReader.hs +++ b/src/Text/Pandoc/Readers/Odt/ContentReader.hs @@ -23,22 +23,22 @@ module Text.Pandoc.Readers.Odt.ContentReader , read_body ) where -import Control.Applicative hiding (liftA, liftA2, liftA3) -import Control.Arrow +import Prelude hiding (liftA, liftA2, liftA3, first, second) +import Control.Applicative ((<|>)) import Control.Monad ((<=<)) - +import Control.Arrow (ArrowChoice(..), (>>^), (^>>), first, second, + arr, returnA) import qualified Data.ByteString.Lazy as B import Data.Foldable (fold) import Data.List (find) import qualified Data.Map as M import qualified Data.Text as T import Data.Maybe -import Data.Semigroup (First(..), Option(..)) import Text.TeXMath (readMathML, writeTeX) import qualified Text.Pandoc.XML.Light as XML -import Text.Pandoc.Builder hiding (underline) +import Text.Pandoc.Builder as B hiding (underline) import Text.Pandoc.MediaBag (MediaBag, insertMedia) import Text.Pandoc.Shared import Text.Pandoc.Extensions (extensionsFromList, Extension(..)) @@ -244,7 +244,7 @@ getHeaderAnchor :: OdtReaderSafe Inlines Anchor getHeaderAnchor = proc title -> do state <- getExtraState -< () let exts = extensionsFromList [Ext_auto_identifiers] - let anchor = uniqueIdent exts (toList title) + let anchor = uniqueIdent exts (B.toList title) (Set.fromList $ usedAnchors state) modifyExtraState (putPrettyAnchor anchor anchor) -<< anchor @@ -306,7 +306,7 @@ withNewStyle a = proc x -> do isCodeStyle _ = False inlineCode :: Inlines -> Inlines - inlineCode = code . T.concat . map stringify . toList + inlineCode = code . T.concat . map stringify . B.toList type PropertyTriple = (ReaderState, TextProperties, Maybe StyleFamily) type InlineModifier = Inlines -> Inlines @@ -510,7 +510,7 @@ newtype FirstMatch a = FirstMatch (Option (First a)) deriving (Foldable, Monoid, Semigroup) firstMatch :: a -> FirstMatch a -firstMatch = FirstMatch . Option . Just . First +firstMatch = FirstMatch . Option . Just . First . Just -- @@ -571,7 +571,7 @@ read_text_seq = matchingElement NsText "sequence" read_spaces :: InlineMatcher read_spaces = matchingElement NsText "s" ( readAttrWithDefault NsText "c" 1 -- how many spaces? - >>^ fromList.(`replicate` Space) + >>^ B.fromList.(`replicate` Space) ) -- read_line_break :: InlineMatcher @@ -733,8 +733,7 @@ read_table = matchingElement NsTable "table" -- | Infers the number of headers from rows simpleTable' :: [[Blocks]] -> Blocks simpleTable' [] = simpleTable [] [] -simpleTable' (x : rest) = simpleTable (fmap (const defaults) x) (x : rest) - where defaults = fromList [] +simpleTable' (x : rest) = simpleTable (fmap (const mempty) x) (x : rest) -- read_table_row :: ElementMatcher [[Blocks]] @@ -784,7 +783,7 @@ read_frame_img = titleNodes <- matchChildContent' [ read_frame_title ] -< () alt <- matchChildContent [] read_plain_text -< () arr (firstMatch . uncurry4 imageWith) -< - (image_attributes w h, src', inlineListToIdentifier exts (toList titleNodes), alt) + (image_attributes w h, src', inlineListToIdentifier exts (B.toList titleNodes), alt) read_frame_title :: InlineMatcher read_frame_title = matchingElement NsSVG "title" (matchChildContent [] read_plain_text) @@ -814,7 +813,7 @@ read_frame_mathml = read_frame_text_box :: OdtReaderSafe XML.Element (FirstMatch Inlines) read_frame_text_box = proc box -> do paragraphs <- executeIn (matchChildContent' [ read_paragraph ]) -< box - arr read_img_with_caption -< toList paragraphs + arr read_img_with_caption -< B.toList paragraphs read_img_with_caption :: [Block] -> FirstMatch Inlines read_img_with_caption (Para [Image attr alt (src,title)] : _) = diff --git a/src/Text/Pandoc/Readers/Odt/Generic/Utils.hs b/src/Text/Pandoc/Readers/Odt/Generic/Utils.hs index edefe3c70..a065e817d 100644 --- a/src/Text/Pandoc/Readers/Odt/Generic/Utils.hs +++ b/src/Text/Pandoc/Readers/Odt/Generic/Utils.hs @@ -34,6 +34,7 @@ import qualified Data.Foldable as F (Foldable, foldr) import Data.Maybe import Data.Text (Text) import qualified Data.Text as T +import Text.Read -- | Equivalent to -- > foldr (.) id @@ -104,9 +105,6 @@ uncurry4 fun (a,b,c,d ) = fun a b c d uncurry5 fun (a,b,c,d,e ) = fun a b c d e uncurry6 fun (a,b,c,d,e,f ) = fun a b c d e f -swap :: (a,b) -> (b,a) -swap (a,b) = (b,a) - -- | A version of "Data.List.find" that uses a converter to a Maybe instance. -- The returned value is the first which the converter returns in a 'Just' -- wrapper. diff --git a/src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs b/src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs index 0d921e23b..b384d3504 100644 --- a/src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs +++ b/src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs @@ -73,7 +73,7 @@ import Text.Pandoc.Readers.Odt.Arrows.Utils import Text.Pandoc.Readers.Odt.Generic.Namespaces import Text.Pandoc.Readers.Odt.Generic.Utils import Text.Pandoc.Readers.Odt.Generic.Fallible - +import Prelude hiding (withState, first, second) -------------------------------------------------------------------------------- -- Basis types for readability -------------------------------------------------------------------------------- @@ -101,7 +101,7 @@ data XMLConverterState nsID extraState where -- Arguably, a real Zipper would be better. But that is an -- optimization that can be made at a later time, e.g. when -- replacing Text.XML.Light. - parentElements :: [XML.Element] + parentElements :: NonEmpty XML.Element -- | A map from internal namespace IDs to the namespace prefixes -- used in XML elements , namespacePrefixes :: NameSpacePrefixes nsID @@ -126,7 +126,7 @@ createStartState :: (NameSpaceID nsID) -> XMLConverterState nsID extraState createStartState element extraState = XMLConverterState - { parentElements = [element] + { parentElements = element :| [] , namespacePrefixes = M.empty , namespaceIRIs = getInitialIRImap , moreState = extraState @@ -152,8 +152,8 @@ currentElement state = head (parentElements state) -- | Replace the current position by another, modifying the extra state -- in the process swapStack' :: XMLConverterState nsID extraState - -> [XML.Element] - -> ( XMLConverterState nsID extraState , [XML.Element] ) + -> NonEmpty XML.Element + -> ( XMLConverterState nsID extraState , NonEmpty XML.Element ) swapStack' state stack = ( state { parentElements = stack } , parentElements state @@ -163,13 +163,13 @@ swapStack' state stack pushElement :: XML.Element -> XMLConverterState nsID extraState -> XMLConverterState nsID extraState -pushElement e state = state { parentElements = e:parentElements state } +pushElement e state = state { parentElements = e :| toList (parentElements state) } -- | Pop the top element from the call stack, unless it is the last one. popElement :: XMLConverterState nsID extraState -> Maybe (XMLConverterState nsID extraState) popElement state - | _:es@(_:_) <- parentElements state = Just $ state { parentElements = es } + | _:|(e:es) <- parentElements state = Just $ state { parentElements = e:|es } | otherwise = Nothing -------------------------------------------------------------------------------- @@ -293,7 +293,7 @@ readNSattributes = fromState $ \state -> maybe (state, failEmpty ) => XMLConverterState nsID extraState -> Maybe (XMLConverterState nsID extraState) extractNSAttrs startState - = foldl (\state d -> state >>= addNS d) + = foldl' (\state d -> state >>= addNS d) (Just startState) nsAttribs where nsAttribs = mapMaybe readNSattr (XML.elAttribs element) @@ -553,7 +553,7 @@ jumpThere = withState (\state element ) -- -swapStack :: XMLConverter nsID extraState [XML.Element] [XML.Element] +swapStack :: XMLConverter nsID extraState (NonEmpty XML.Element) (NonEmpty XML.Element) swapStack = withState swapStack' -- @@ -568,7 +568,7 @@ jumpBack = tryModifyState (popElement >>> maybeToChoice) -- accessible to the converter. switchingTheStack :: XMLConverter nsID moreState a b -> XMLConverter nsID moreState (a, XML.Element) b -switchingTheStack a = second ( (:[]) ^>> swapStack ) +switchingTheStack a = second ( (:|[]) ^>> swapStack ) >>> first a >>> second swapStack >>^ fst diff --git a/src/Text/Pandoc/Readers/Odt/StyleReader.hs b/src/Text/Pandoc/Readers/Odt/StyleReader.hs index 5e10f896c..b019aeb5a 100644 --- a/src/Text/Pandoc/Readers/Odt/StyleReader.hs +++ b/src/Text/Pandoc/Readers/Odt/StyleReader.hs @@ -50,7 +50,8 @@ import Data.Maybe import Data.Text (Text) import qualified Data.Text as T import qualified Data.Set as S - +import Text.Read +import qualified GHC.Show import qualified Text.Pandoc.XML.Light as XML import Text.Pandoc.Shared (safeRead, tshow) @@ -65,6 +66,8 @@ import Text.Pandoc.Readers.Odt.Generic.XMLConverter import Text.Pandoc.Readers.Odt.Base import Text.Pandoc.Readers.Odt.Namespaces +import Prelude hiding (liftA3, liftA2) + readStylesAt :: XML.Element -> Fallible Styles readStylesAt e = runConverter' readAllStyles mempty e @@ -120,7 +123,7 @@ fontPitchReader = executeInSub NsOffice "font-face-decls" ( &&& lookupDefaultingAttr NsStyle "font-pitch" )) - >>?^ ( M.fromList . foldl accumLegalPitches [] ) + >>?^ ( M.fromList . foldl' accumLegalPitches [] ) ) `ifFailedDo` returnV (Right M.empty) where accumLegalPitches ls (Nothing,_) = ls accumLegalPitches ls (Just n,p) = (n,p):ls @@ -305,7 +308,7 @@ data XslUnit = XslUnitMM | XslUnitCM | XslUnitPixel | XslUnitEM -instance Show XslUnit where +instance GHC.Show.Show XslUnit where show XslUnitMM = "mm" show XslUnitCM = "cm" show XslUnitInch = "in" diff --git a/src/Text/Pandoc/Readers/Org/Blocks.hs b/src/Text/Pandoc/Readers/Org/Blocks.hs index d1aff701e..bcae5c57b 100644 --- a/src/Text/Pandoc/Readers/Org/Blocks.hs +++ b/src/Text/Pandoc/Readers/Org/Blocks.hs @@ -542,8 +542,7 @@ include = try $ do in case (minlvl >>= safeRead :: Maybe Int) of Nothing -> blks Just lvl -> let levels = Walk.query headerLevel blks - -- CAVE: partial function in else - curMin = if null levels then 0 else minimum levels + curMin = fromMaybe 0 $ viaNonEmpty minimum1 levels in Walk.walk (shiftHeader (curMin - lvl)) blks headerLevel :: Block -> [Int] diff --git a/src/Text/Pandoc/Readers/Org/DocumentTree.hs b/src/Text/Pandoc/Readers/Org/DocumentTree.hs index 2dcbecb1d..5469f1f4d 100644 --- a/src/Text/Pandoc/Readers/Org/DocumentTree.hs +++ b/src/Text/Pandoc/Readers/Org/DocumentTree.hs @@ -15,7 +15,7 @@ module Text.Pandoc.Readers.Org.DocumentTree , unprunedHeadlineToBlocks ) where -import Control.Arrow ((***), first) +import Control.Arrow ((***)) import Control.Monad (guard) import Data.List (intersperse) import Data.Maybe (mapMaybe) diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs index 514e3b88d..06a7e37b7 100644 --- a/src/Text/Pandoc/Readers/RST.hs +++ b/src/Text/Pandoc/Readers/RST.hs @@ -14,7 +14,6 @@ Conversion from reStructuredText to 'Pandoc' document. -} module Text.Pandoc.Readers.RST ( readRST ) where -import Control.Arrow (second) import Control.Monad (forM_, guard, liftM, mplus, mzero, when) import Control.Monad.Except (throwError) import Control.Monad.Identity (Identity (..)) @@ -99,12 +98,13 @@ titleTransform (bs, meta) = case bs of (Header 1 _ head1:Header 2 _ head2:rest) | not (any (isHeader 1) rest || any (isHeader 2) rest) -> -- tit/sub - (promoteHeaders 2 rest, setMeta "title" (fromList head1) $ - setMeta "subtitle" (fromList head2) meta) + (promoteHeaders 2 rest, + setMeta "title" (B.fromList head1) $ + setMeta "subtitle" (B.fromList head2) meta) (Header 1 _ head1:rest) | not (any (isHeader 1) rest) -> -- title only (promoteHeaders 1 rest, - setMeta "title" (fromList head1) meta) + setMeta "title" (B.fromList head1) meta) _ -> (bs, meta) in case bs' of (DefinitionList ds : rest) -> @@ -113,7 +113,8 @@ titleTransform (bs, meta) = metaFromDefList :: [([Inline], [[Block]])] -> Meta -> Meta metaFromDefList ds meta = adjustAuthors $ foldr f meta ds - where f (k,v) = setMeta (T.toLower $ stringify k) (mconcat $ map fromList v) + where f (k,v) = setMeta (T.toLower $ stringify k) + (mconcat (map B.fromList v)) adjustAuthors (Meta metamap) = Meta $ M.adjust splitAuthors "author" $ M.adjust toPlain "date" $ M.adjust toPlain "title" @@ -501,7 +502,8 @@ includeDirective top fields body = do setInput oldInput setPosition oldPos updateState $ \s -> s{ stateContainers = - tail $ stateContainers s } + fromMaybe [] $ viaNonEmpty tail + $ stateContainers s } return bs @@ -837,7 +839,7 @@ listTableDirective top fields body = do (TableFoot nullAttr []) where takeRows [BulletList rows] = map takeCells rows takeRows _ = [] - takeCells [BulletList cells] = map B.fromList cells + takeCells [BulletList cells] = map B.fromList cells :: [Blocks] takeCells _ = [] normWidths ws = strictPos . (/ max 1 (sum ws)) <$> ws strictPos w @@ -888,7 +890,7 @@ csvTableDirective top fields rawcsv = do Right rawrows -> do let singleParaToPlain bs = case B.toList bs of - [Para ils] -> B.fromList [Plain ils] + [Para ils] -> B.plain (B.fromList ils) _ -> bs let parseCell t = singleParaToPlain <$> parseFromString' parseBlocks (t <> "\n\n") @@ -1291,8 +1293,12 @@ simpleTableRow indices = do simpleTableSplitLine :: [Int] -> Text -> [Text] simpleTableSplitLine indices line = - map trimr - $ tail $ splitTextByIndices (init indices) line + case viaNonEmpty init indices of + Nothing -> [] + Just indicesInit -> + case splitTextByIndices indicesInit line of + (_:xs) -> map trimr xs + [] -> [] simpleTableHeader :: PandocMonad m => Bool -- ^ Headerless table diff --git a/src/Text/Pandoc/Readers/TWiki.hs b/src/Text/Pandoc/Readers/TWiki.hs index 484a6c923..c9fb757f1 100644 --- a/src/Text/Pandoc/Readers/TWiki.hs +++ b/src/Text/Pandoc/Readers/TWiki.hs @@ -23,7 +23,7 @@ import Data.Text (Text) import qualified Data.Text as T import Text.HTML.TagSoup import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Options import Text.Pandoc.Parsing hiding (enclosed, nested) @@ -116,7 +116,7 @@ block = do <|> blockElements <|> para skipMany blankline - trace (T.take 60 $ tshow $ B.toList res) + P.trace (T.take 60 $ tshow $ B.toList res) return res blockElements :: PandocMonad m => TWParser m B.Blocks @@ -223,7 +223,8 @@ table :: PandocMonad m => TWParser m B.Blocks table = try $ do tableHead <- optionMaybe (unzip <$> many1Till tableParseHeader newline) rows <- many1 tableParseRow - return $ buildTable mempty rows $ fromMaybe (align rows, columns rows) tableHead + return $ buildTable mempty rows $ + fromMaybe (align rows, columns rows) tableHead where buildTable caption rows (aligns, heads) = B.table (B.simpleCaption $ B.plain caption) @@ -231,9 +232,11 @@ table = try $ do (TableHead nullAttr $ toHeaderRow heads) [TableBody nullAttr 0 [] $ map toRow rows] (TableFoot nullAttr []) - align rows = replicate (columCount rows) (AlignDefault, ColWidthDefault) - columns rows = replicate (columCount rows) mempty - columCount rows = length $ head rows + align rows = replicate (columnCount rows) (AlignDefault, ColWidthDefault) + columns rows = replicate (columnCount rows) mempty + columnCount rows = case rows of + (r:_) -> length r + _ -> 0 toRow = Row nullAttr . map B.simpleCell toHeaderRow l = [toRow l | not (null l)] diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs index 860da2dc3..cfd5e09d9 100644 --- a/src/Text/Pandoc/Readers/Textile.hs +++ b/src/Text/Pandoc/Readers/Textile.hs @@ -45,7 +45,7 @@ import Text.HTML.TagSoup (Tag (..), fromAttrib) import Text.HTML.TagSoup.Match import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class as P (PandocMonad (..)) import Text.Pandoc.CSS import Text.Pandoc.Definition import Text.Pandoc.Options @@ -123,7 +123,7 @@ blockParsers = [ codeBlock block :: PandocMonad m => ParserT Text ParserState m Blocks block = do res <- choice blockParsers <?> "block" - trace (T.take 60 $ tshow $ B.toList res) + P.trace (T.take 60 $ tshow $ B.toList res) return res commentBlock :: PandocMonad m => ParserT Text ParserState m Blocks @@ -375,8 +375,9 @@ table = try $ do (toprow:rest) | any (fst . fst) toprow -> (toprow, rest) _ -> (mempty, rawrows) - let nbOfCols = maximum $ map length (headers:rows) - let aligns = map minimum $ transpose $ map (map (snd . fst)) (headers:rows) + let nbOfCols = maximum1 $ fmap length (headers :| rows) + let aligns = map (fromMaybe AlignDefault . viaNonEmpty minimum1) + $ transpose $ map (map (snd . fst)) (headers:rows) let toRow = Row nullAttr . map B.simpleCell toHeaderRow l = [toRow l | not (null l)] return $ B.table (B.simpleCaption $ B.plain caption) @@ -627,7 +628,7 @@ code2 = do -- | Html / CSS attributes attributes :: PandocMonad m => ParserT Text ParserState m Attr -attributes = foldl (flip ($)) ("",[],[]) <$> +attributes = foldl' (flip ($)) ("",[],[]) <$> try (do special <- option id specialAttribute attrs <- many attribute return (special : attrs)) diff --git a/src/Text/Pandoc/Readers/TikiWiki.hs b/src/Text/Pandoc/Readers/TikiWiki.hs index fb4b662c5..61d34f96f 100644 --- a/src/Text/Pandoc/Readers/TikiWiki.hs +++ b/src/Text/Pandoc/Readers/TikiWiki.hs @@ -24,8 +24,8 @@ import Data.Maybe (fromMaybe) import Data.Text (Text) import qualified Data.Text as T import qualified Text.Pandoc.Builder as B -import Text.Pandoc.Class.CommonState (CommonState (..)) -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Class (CommonState (..), PandocMonad (..)) +import Text.Pandoc.Class as P import Text.Pandoc.Definition import Text.Pandoc.Logging (Verbosity (..)) import Text.Pandoc.Options @@ -87,7 +87,7 @@ block = do <|> para skipMany blankline when (verbosity >= INFO) $ - trace (T.pack $ printf "line %d: %s" (sourceLine pos) (take 60 $ show $ B.toList res)) + P.trace (T.pack $ printf "line %d: %s" (sourceLine pos) (take 60 $ show $ B.toList res)) return res blockElements :: PandocMonad m => TikiWikiParser m B.Blocks @@ -163,11 +163,12 @@ table = try $ do string "||" newline -- return $ B.simpleTable (headers rows) $ trace ("rows: " ++ (show rows)) rows - return $B.simpleTable (headers rows) rows + return $ B.simpleTable (headers rows) rows where -- The headers are as many empty strings as the number of columns -- in the first row - headers rows = map (B.plain . B.str) $replicate (length $ head rows) "" + headers rows@(firstRow:_) = + replicate (length firstRow) (B.plain $ B.str "") para :: PandocMonad m => TikiWikiParser m B.Blocks para = fmap (result . mconcat) ( many1Till inline endOfParaElement) @@ -232,35 +233,31 @@ mixedList = try $ do fixListNesting :: [B.Blocks] -> [B.Blocks] fixListNesting [] = [] fixListNesting [first] = [recurseOnList first] --- fixListNesting nestall | trace ("\n\nfixListNesting: " ++ (show nestall)) False = undefined --- fixListNesting nestall@(first:second:rest) = fixListNesting (first:second:rest) = - let secondBlock = head $ B.toList second in - case secondBlock of - BulletList _ -> fixListNesting $ mappend (recurseOnList first) (recurseOnList second) : rest - OrderedList _ _ -> fixListNesting $ mappend (recurseOnList first) (recurseOnList second) : rest - _ -> recurseOnList first : fixListNesting (second:rest) + case B.toList second of + (BulletList{}:_) -> fixListNesting $ + mappend (recurseOnList first) (recurseOnList second) : rest + (OrderedList{}:_) -> fixListNesting $ + mappend (recurseOnList first) (recurseOnList second) : rest + _ -> recurseOnList first : fixListNesting (second:rest) -- This function walks the Block structure for fixListNesting, -- because it's a bit complicated, what with converting to and from -- lists and so on. recurseOnList :: B.Blocks -> B.Blocks --- recurseOnList item | trace ("rOL: " ++ (show $ length $ B.toList item) ++ ", " ++ (show $ B.toList item)) False = undefined recurseOnList items - | length (B.toList items) == 1 = - let itemBlock = head $ B.toList items in - case itemBlock of - BulletList listItems -> B.bulletList $ fixListNesting $ map B.fromList listItems - OrderedList _ listItems -> B.orderedList $ fixListNesting $ map B.fromList listItems - _ -> items - + = case B.toList items of + [BulletList listItems] -> + B.bulletList $ fixListNesting $ map B.fromList listItems + [OrderedList _ listItems] -> + B.orderedList $ fixListNesting $ map B.fromList listItems + _ -> items -- The otherwise works because we constructed the blocks, and we -- know for a fact that no mappends have been run on them; each -- Blocks consists of exactly one Block. -- -- Anything that's not like that has already been processed by -- fixListNesting; don't bother to process it again. - | otherwise = items -- Turn the list if list items into a tree by breaking off the first diff --git a/src/Text/Pandoc/Readers/Txt2Tags.hs b/src/Text/Pandoc/Readers/Txt2Tags.hs index 08083b177..6a8525c2f 100644 --- a/src/Text/Pandoc/Readers/Txt2Tags.hs +++ b/src/Text/Pandoc/Readers/Txt2Tags.hs @@ -58,7 +58,8 @@ getT2TMeta = do curMtime <- case inps of [] -> formatTime defaultTimeLocale "%T" <$> P.getZonedTime _ -> catchError - (maximum <$> mapM getModTime inps) + (fromMaybe mempty . viaNonEmpty maximum1 + <$> mapM getModTime inps) (const (return "")) return $ T2TMeta (T.pack curDate) (T.pack curMtime) (intercalate ", " inps) outp @@ -261,9 +262,11 @@ table = try $ do rows <- many1 (many commentLine *> tableRow) let columns = transpose rows let ncolumns = length columns - let aligns = map (foldr1 findAlign . map fst) columns + let aligns = map (fromMaybe AlignDefault . + viaNonEmpty (foldl1' findAlign) . map fst) + columns let rows' = map (map snd) rows - let size = maximum (map length rows') + let size = fromMaybe 0 $ viaNonEmpty maximum1 (map length rows') let rowsPadded = map (pad size) rows' let headerPadded = if null tableHeader then mempty else pad size tableHeader let toRow = Row nullAttr . map B.simpleCell @@ -445,9 +448,9 @@ titleLink = try $ do tokens <- sepBy1 (manyChar $ noneOf " ]") space guard (length tokens >= 2) char ']' - let link' = last tokens + let link' = fromMaybe mempty $ viaNonEmpty last tokens guard $ not $ T.null link' - let tit = T.unwords (init tokens) + let tit = maybe mempty T.unwords (viaNonEmpty init tokens) return $ B.link link' "" (B.text tit) -- Link with image diff --git a/src/Text/Pandoc/Readers/Vimwiki.hs b/src/Text/Pandoc/Readers/Vimwiki.hs index 74dac5ea7..8f5a2e250 100644 --- a/src/Text/Pandoc/Readers/Vimwiki.hs +++ b/src/Text/Pandoc/Readers/Vimwiki.hs @@ -54,17 +54,9 @@ import Data.List (isInfixOf) import Data.Maybe import Data.Text (Text) import qualified Data.Text as T -import Text.Pandoc.Builder (Blocks, Inlines, fromList, toList, trimInlines) -import qualified Text.Pandoc.Builder as B (blockQuote, bulletList, code, - codeBlockWith, definitionList, - displayMath, divWith, emph, - headerWith, horizontalRule, image, - imageWith, link, math, orderedList, - para, plain, setMeta, simpleTable, - softbreak, space, spanWith, str, - strikeout, strong, subscript, - superscript) -import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) +import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) +import qualified Text.Pandoc.Builder as B +import Text.Pandoc.Class as P (PandocMonad(..)) import Text.Pandoc.Definition (Attr, Block (BulletList, OrderedList), Inline (Space), ListNumberDelim (..), ListNumberStyle (..), Pandoc (..), @@ -110,7 +102,7 @@ parseVimwiki = do eof st <- getState let meta = stateMeta st - return $ Pandoc meta (toList bs) + return $ Pandoc meta (B.toList bs) -- block parser @@ -129,7 +121,7 @@ block = do , definitionList , para ] - trace (T.take 60 $ tshow $ toList res) + P.trace (T.take 60 $ tshow $ toList res) return res blockML :: PandocMonad m => VwParser m Blocks @@ -244,13 +236,13 @@ syntax _ = [] nameValue :: Text -> Maybe (Text, Text) nameValue s = - let t = splitTextBy (== '=') s in - if length t /= 2 - then Nothing - else let (a, b) = (head t, last t) in - if (T.length b < 2) || ((T.head b, T.last b) /= ('"', '"')) - then Nothing - else Just (a, stripFirstAndLast b) + case splitTextBy (== '=') s of + [a,b] + | T.length b >= 2 + , T.head b == '"' + , T.last b == '"' + -> Just (a, stripFirstAndLast b) + _ -> Nothing displayMath :: PandocMonad m => VwParser m Blocks @@ -286,8 +278,8 @@ mathTagLaTeX s = case s of mixedList :: PandocMonad m => VwParser m Blocks mixedList = try $ do - (bl, _) <- mixedList' (-1) - return $ head bl + (b:_, _) <- mixedList' (-1) + return b mixedList' :: PandocMonad m => Int -> VwParser m ([Blocks], Int) mixedList' prevInd = do @@ -358,9 +350,9 @@ makeListMarkerSpan x = combineList :: Blocks -> [Blocks] -> [Blocks] combineList x [y] = case toList y of - [BulletList z] -> [fromList $ toList x + [BulletList z] -> [B.fromList $ B.toList x ++ [BulletList z]] - [OrderedList attr z] -> [fromList $ toList x + [OrderedList attr z] -> [B.fromList $ B.toList x ++ [OrderedList attr z]] _ -> x:[y] combineList x xs = x:xs @@ -401,8 +393,8 @@ table1 = try $ do -- headerless table table2 :: PandocMonad m => VwParser m ([Blocks], [[Blocks]]) table2 = try $ do - trs <- many1 tableRow - return (replicate (length $ head trs) mempty, trs) + trs@(firstRow:_) <- many1 tableRow + return (replicate (length firstRow) mempty, trs) tableHeaderSeparator :: PandocMonad m => VwParser m () tableHeaderSeparator = try $ do @@ -502,8 +494,8 @@ bareURL = try $ do strong :: PandocMonad m => VwParser m Inlines strong = try $ do s <- lookAhead $ between (char '*') (char '*') (many1 $ noneOf "*") - guard $ (head s `notElem` spaceChars) - && (last s `notElem` spaceChars) + guard $ Just True == viaNonEmpty (\s' -> + (head s' `notElem` spaceChars) && (last s' `notElem` spaceChars)) s char '*' contents <- mconcat <$>manyTill inline' (char '*' >> notFollowedBy alphaNum) @@ -516,8 +508,8 @@ makeId i = T.concat (stringify <$> toList i) emph :: PandocMonad m => VwParser m Inlines emph = try $ do s <- lookAhead $ between (char '_') (char '_') (many1 $ noneOf "_") - guard $ (head s `notElem` spaceChars) - && (last s `notElem` spaceChars) + guard $ Just True == viaNonEmpty (\s' -> + (head s' `notElem` spaceChars) && (last s' `notElem` spaceChars)) s char '_' contents <- mconcat <$>manyTill inline' (char '_' >> notFollowedBy alphaNum) @@ -618,8 +610,8 @@ tag = try $ do char ':' s <- manyTillChar (noneOf spaceChars) (try (char ':' >> lookAhead space)) guard $ not $ "::" `T.isInfixOf` (":" <> s <> ":") - let ss = splitTextBy (==':') s - return $ mconcat $ makeTagSpan' (head ss):(makeTagSpan <$> tail ss) + let (ssHead:ssTail) = splitTextBy (==':') s + return $ mconcat $ makeTagSpan' ssHead : (makeTagSpan <$> ssTail) todoMark :: PandocMonad m => VwParser m Inlines todoMark = try $ do |
