aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYan Pas <yanp.bugz@gmail.com>2018-10-16 03:12:06 +0300
committerYan Pas <yanp.bugz@gmail.com>2018-10-16 03:12:06 +0300
commitce27bf9a02d98a6a5412a493577fa9d2f3cfd1fe (patch)
treecb744eb93fad92cf767c08f8ce87cd5e8dab3fa5 /src
parent1684e918b286fad89425d2d5f45b7d51b5f4ddf8 (diff)
downloadpandoc-ce27bf9a02d98a6a5412a493577fa9d2f3cfd1fe.tar.gz
builders
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Readers/Man.hs122
1 files changed, 58 insertions, 64 deletions
diff --git a/src/Text/Pandoc/Readers/Man.hs b/src/Text/Pandoc/Readers/Man.hs
index 280acb9c4..d04718fc7 100644
--- a/src/Text/Pandoc/Readers/Man.hs
+++ b/src/Text/Pandoc/Readers/Man.hs
@@ -38,22 +38,22 @@ import Control.Monad (liftM, void)
import Control.Monad.Except (throwError)
import Data.Char (isDigit, isUpper, isLower)
import Data.Default (Default)
-import Data.Functor (($>))
import Data.Map (insert)
-import Data.Set (Set, singleton, fromList, toList)
+import Data.Set (Set, singleton)
+import qualified Data.Set as S (fromList, toList)
import Data.Maybe (catMaybes, fromMaybe, isNothing)
import Data.List (intersperse, intercalate)
import qualified Data.Text as T
import Text.Pandoc.Class (PandocMonad(..))
-import Text.Pandoc.Definition
+import Text.Pandoc.Builder as B hiding (singleton)
import Text.Pandoc.Error (PandocError (PandocParsecError))
import Text.Pandoc.Logging (LogMessage(..))
import Text.Pandoc.Options
import Text.Pandoc.Parsing
import Text.Pandoc.Shared (crFilter)
-import Text.Parsec hiding (tokenPrim)
-import Text.Parsec.Char ()
+import Text.Parsec hiding (tokenPrim, space)
+import qualified Text.Parsec as Parsec
import Text.Parsec.Pos (updatePosString)
--
@@ -158,14 +158,10 @@ parseMan :: PandocMonad m => ManParser m Pandoc
parseMan = do
let parsers = [ try parseList, parseTitle, parsePara, parseSkippedContent
, try parseCodeBlock, parseHeader, parseSkipMacro]
- blocks <- many $ choice parsers
- parserst <- getState
- return $ Pandoc (stateMeta parserst) (filter (not . isNull) blocks)
-
- where
-
- isNull Null = True
- isNull _ = False
+ bs <- many $ choice parsers
+ let (Pandoc _ blocks) = doc $ mconcat bs
+ meta <- stateMeta <$> getState
+ return $ Pandoc meta blocks
eofline :: Stream s m Char => ParsecT s u m ()
eofline = void newline <|> eof
@@ -216,7 +212,7 @@ escapeLexer = do
fs <- many letterFontKind
many letter
char ']'
- return $ fromList fs
+ return $ S.fromList fs
letterFontKind :: PandocMonad m => ManLexer m FontKind
letterFontKind = choice [
@@ -240,7 +236,7 @@ currentFont = fontKind <$> getState
lexComment :: PandocMonad m => ManLexer m ManToken
lexComment = do
try $ string ".\\\""
- many space
+ many Parsec.space
body <- many $ noneOf "\n"
char '\n'
return $ MComment body
@@ -265,7 +261,7 @@ lexMacro = do
"fi" -> knownMacro KCodeBlEnd
"B" -> MStr (joinedArgs, singleton Bold)
"BR" -> MMaybeLink joinedArgs
- x | x `elem` ["BI", "IB"] -> MStr (joinedArgs, fromList [Italic, Bold])
+ x | x `elem` ["BI", "IB"] -> MStr (joinedArgs, S.fromList [Italic, Bold])
x | x `elem` ["I", "IR", "RI"] -> MStr (joinedArgs, singleton Italic)
"SH" -> MHeader 2 args
"SS" -> MHeader 3 args
@@ -403,15 +399,15 @@ mcomment = msatisfy isMComment where
-- ManToken -> Block functions
--
-parseTitle :: PandocMonad m => ManParser m Block
+parseTitle :: PandocMonad m => ManParser m Blocks
parseTitle = do
(MMacro _ args) <- mmacro KTitle
if null args
- then return Null
+ then return mempty
else do
let mantitle = fst $ head args
modifyState (changeTitle mantitle)
- return $ Header 1 nullAttr [Str mantitle]
+ return $ header 1 $ str mantitle
where
changeTitle title pst =
let meta = stateMeta pst
@@ -419,11 +415,11 @@ parseTitle = do
in
pst {stateMeta = metaUp}
-parseSkippedContent :: PandocMonad m => ManParser m Block
+parseSkippedContent :: PandocMonad m => ManParser m Blocks
parseSkippedContent = do
tok <- munknownMacro <|> mcomment <|> memplyLine
onToken tok
- return Null
+ return mempty
where
@@ -433,50 +429,50 @@ parseSkippedContent = do
logMessage $ SkippedContent ("Unknown macro: " ++ mname) pos
onToken _ = return ()
-strToInline :: RoffStr -> Inline
-strToInline (s, fonts) = inner $ toList fonts where
- inner :: [FontKind] -> Inline
- inner [] = Str s
- inner (Bold:fs) = Strong [inner fs]
- inner (Italic:fs) = Emph [inner fs]
+strToInlines :: RoffStr -> Inlines
+strToInlines (s, fonts) = inner $ S.toList fonts where
+ inner :: [FontKind] -> Inlines
+ inner [] = str s
+ inner (Bold:fs) = strong $ inner fs
+ inner (Italic:fs) = emph $ inner fs
-- Monospace goes after Bold and Italic in ordered set
- inner (Monospace:_) = Code nullAttr s
+ inner (Monospace:_) = code s
inner (Regular:fs) = inner fs
-parsePara :: PandocMonad m => ManParser m Block
-parsePara = Para <$> parseInlines
+parsePara :: PandocMonad m => ManParser m Blocks
+parsePara = para <$> parseInlines
-parseInlines :: PandocMonad m => ManParser m [Inline]
+parseInlines :: PandocMonad m => ManParser m Inlines
parseInlines = do
inls <- many1 (strInl <|> lineInl <|> linkInl <|> comment)
- let withspaces = intersperse [Space] inls
- return $ concat withspaces
+ let withspaces = intersperse B.space inls
+ return $ mconcat withspaces
where
- strInl :: PandocMonad m => ManParser m [Inline]
+ strInl :: PandocMonad m => ManParser m Inlines
strInl = do
(MStr rstr) <- mstr
- return [strToInline rstr]
+ return $ strToInlines rstr
- lineInl :: PandocMonad m => ManParser m [Inline]
+ lineInl :: PandocMonad m => ManParser m Inlines
lineInl = do
(MLine fragments) <- mline
- return $ strToInline <$> fragments
+ return $ mconcat $ strToInlines <$> fragments
- linkInl :: PandocMonad m => ManParser m [Inline]
+ linkInl :: PandocMonad m => ManParser m Inlines
linkInl = do
(MMaybeLink txt) <- mmaybeLink
let inls = case runParser linkParser () "" txt of
Right lnk -> lnk
- Left _ -> [Strong [Str txt]]
+ Left _ -> strong $ str txt
return inls
where
-- assuming man pages are generated from Linux-like repository
- linkParser :: Parsec String () [Inline]
+ linkParser :: Parsec String () Inlines
linkParser = do
mpage <- many1 (alphaNum <|> char '_')
spacetab
@@ -485,21 +481,19 @@ parseInlines = do
char ')'
other <- many anyChar
let manurl pagename section = "../"++section++"/"++pagename++"."++section
- return $ [ Link nullAttr [Strong [Str mpage]] (manurl mpage [mansect], mpage)
- , Strong [Str $ " ("++[mansect] ++ ")"
- , Str other]
- ]
+ lnkInls = link (manurl mpage [mansect]) mpage (strong $ str mpage)
+ return $ lnkInls <> strong (str (" ("++[mansect] ++ ")") <> str other)
- comment :: PandocMonad m => ManParser m [Inline]
- comment = mcomment >> return []
+ comment :: PandocMonad m => ManParser m Inlines
+ comment = mcomment >> return mempty
-parseCodeBlock :: PandocMonad m => ManParser m Block
+parseCodeBlock :: PandocMonad m => ManParser m Blocks
parseCodeBlock = do
mmacro KCodeBlStart
toks <- many (mstr <|> mline <|> mmaybeLink <|> memplyLine <|> munknownMacro <|> mcomment)
mmacro KCodeBlEnd
- return $ CodeBlock nullAttr (intercalate "\n" . catMaybes $ extractText <$> toks)
+ return $ codeBlock (intercalate "\n" . catMaybes $ extractText <$> toks)
where
@@ -510,14 +504,14 @@ parseCodeBlock = do
extractText MEmptyLine = Just "" -- string are intercalated with '\n', this prevents double '\n'
extractText _ = Nothing
-parseHeader :: PandocMonad m => ManParser m Block
+parseHeader :: PandocMonad m => ManParser m Blocks
parseHeader = do
(MHeader lvl ss) <- mheader
- return $ Header lvl nullAttr $ intersperse Space $ strToInline <$> ss
+ return $ header lvl (mconcat $ intersperse B.space $ strToInlines <$> ss)
-type ListBuilder = [[Block]] -> Block
+type ListBuilder = [Blocks] -> Blocks
-parseList :: PandocMonad m => ManParser m Block
+parseList :: PandocMonad m => ManParser m Blocks
parseList = do
xx <- many1 paras
let bls = map snd xx
@@ -526,13 +520,13 @@ parseList = do
where
- macroIPInl :: [RoffStr] -> [Inline]
- macroIPInl (x:_:[]) = [strToInline x, Space]
- macroIPInl _ = []
+ macroIPInl :: [RoffStr] -> Inlines
+ macroIPInl (x:_:[]) = strToInlines x <> B.space
+ macroIPInl _ = mempty
listKind :: [RoffStr] -> Maybe ListBuilder
listKind (((c:_), _):_:[]) =
- let params style = OrderedList (1, style, DefaultDelim)
+ let params style = orderedListWith (1, style, DefaultDelim)
in case c of
_ | isDigit c -> Just $ params Decimal
_ | isUpper c -> Just $ params UpperAlpha
@@ -541,18 +535,18 @@ parseList = do
listKind _ = Nothing
- paras :: PandocMonad m => ManParser m (ListBuilder, [Block])
+ paras :: PandocMonad m => ManParser m (ListBuilder, Blocks)
paras = do
(MMacro _ args) <- mmacro KTab
let lbuilderOpt = listKind args
- lbuilder = fromMaybe BulletList lbuilderOpt
+ lbuilder = fromMaybe bulletList lbuilderOpt
macroinl = macroIPInl args
inls <- parseInlines
- let parainls = if isNothing lbuilderOpt then macroinl ++ inls else inls
- subls <- many sublist
- return $ (lbuilder, (Plain parainls) : subls)
+ let parainls = if isNothing lbuilderOpt then macroinl <> inls else inls
+ subls <- mconcat <$> many sublist
+ return $ (lbuilder, plain parainls <> subls)
- sublist :: PandocMonad m => ManParser m Block
+ sublist :: PandocMonad m => ManParser m Blocks
sublist = do
mmacro KSubTab
bl <- parseList
@@ -560,5 +554,5 @@ parseList = do
return bl
-- In case of weird man file it will be parsed succesfully
-parseSkipMacro :: PandocMonad m => ManParser m Block
-parseSkipMacro = mmacroAny >> return Null
+parseSkipMacro :: PandocMonad m => ManParser m Blocks
+parseSkipMacro = mmacroAny >> mempty