git.iko.soy/typeable/pandoc
on master help sign in
Roff tokenizer: use Seq for lineparts rather than lists.

This didn't make much measurable difference (compiled w/o optimizations), but it still seems worth doing. Eventually we may want an abstraction like RoffTokens for LineParts.

commit3a5726b2cf9cdb511635209d412ccb8c50f14d6d authorJohn MacFarlane <jgm@berkeley.edu> dateSat 27 Oct 2018, 11:40 (8 years ago) parent0b8a31f
1 file changed+44−42
src/Text/Pandoc/Readers/Roff.hs+44−42
src/Text/Pandoc/Readers/Roff.hs+44−42
@@ -66,6 +66,7 @@ import Text.Parsec hiding (tokenPrim)
6666import qualified Text.Parsec as Parsec
6767import Text.Pandoc.RoffChar (characterCodes, combiningAccents)
6868import qualified Data.Sequence as Seq
69+import Data.Sequence (Seq)
6970import qualified Data.Foldable as Foldable
7071import qualified Data.Text.Normalize as Normalize
7172
@@ -110,7 +111,7 @@ data RoffToken = MLine [LinePart]
110111 | MTable [TableOption] [TableRow] SourcePos
111112 deriving Show
112113
113−newtype RoffTokens = RoffTokens { unRoffTokens :: Seq.Seq RoffToken }
114+newtype RoffTokens = RoffTokens { unRoffTokens :: Seq RoffToken }
114115 deriving (Show, Semigroup, Monoid)
115116
116117singleTok :: RoffToken -> RoffTokens
@@ -156,7 +157,7 @@ combiningAccentsMap :: M.Map String Char
156157combiningAccentsMap =
157158 M.fromList $ map (\(x,y) -> (y,x)) combiningAccents
158159
159−escape :: PandocMonad m => RoffLexer m [LinePart]
160+escape :: PandocMonad m => RoffLexer m (Seq LinePart)
160161escape = do
161162 char '\\'
162163 c <- anyChar
@@ -176,18 +177,18 @@ escape = do
176177 ':' -> return mempty
177178 '0' -> return mempty
178179 'c' -> return mempty
179− '-' -> return [RoffStr "-"]
180− '_' -> return [RoffStr "_"]
181− ' ' -> return [RoffStr " "]
182− '\\' -> return [RoffStr "\\"]
183− 't' -> return [RoffStr "\t"]
184− 'e' -> return [RoffStr "\\"]
185− '`' -> return [RoffStr "`"]
186− '^' -> return [RoffStr " "]
187− '|' -> return [RoffStr " "]
188− '\'' -> return [RoffStr "`"]
189− '.' -> return [RoffStr "`"]
190− '~' -> return [RoffStr "\160"] -- nonbreaking space
180+ '-' -> return $ Seq.singleton $ RoffStr "-"
181+ '_' -> return $ Seq.singleton $ RoffStr "_"
182+ ' ' -> return $ Seq.singleton $ RoffStr " "
183+ '\\' -> return $ Seq.singleton $ RoffStr "\\"
184+ 't' -> return $ Seq.singleton $ RoffStr "\t"
185+ 'e' -> return $ Seq.singleton $ RoffStr "\\"
186+ '`' -> return $ Seq.singleton $ RoffStr "`"
187+ '^' -> return $ Seq.singleton $ RoffStr " "
188+ '|' -> return $ Seq.singleton $ RoffStr " "
189+ '\'' -> return $ Seq.singleton $ RoffStr "`"
190+ '.' -> return $ Seq.singleton $ RoffStr "`"
191+ '~' -> return $ Seq.singleton $ RoffStr "\160" -- nonbreaking space
191192 _ -> escUnknown ['\\',c]
192193
193194 where
@@ -195,7 +196,7 @@ escape = do
195196 twoCharGlyph = do
196197 cs <- count 2 anyChar
197198 case M.lookup cs characterCodeMap of
198− Just c -> return [RoffStr [c]]
199+ Just c -> return $ Seq.singleton $ RoffStr [c]
199200 Nothing -> escUnknown ('\\':'(':cs)
200201
201202 bracketedGlyph = unicodeGlyph <|> charGlyph
@@ -206,7 +207,7 @@ escape = do
206207 [] -> mzero
207208 [s] -> case M.lookup s characterCodeMap of
208209 Nothing -> mzero
209− Just c -> return [RoffStr [c]]
210+ Just c -> return $ Seq.singleton $ RoffStr [c]
210211 (s:ss) -> do
211212 basechar <- case M.lookup cs characterCodeMap of
212213 Nothing ->
@@ -222,12 +223,13 @@ escape = do
222223 case M.lookup a combiningAccentsMap of
223224 Just x -> addAccents as (x:xs)
224225 Nothing -> mzero
225− addAccents ss [basechar] >>= \xs -> return [RoffStr xs])
226+ addAccents ss [basechar] >>= \xs ->
227+ return (Seq.singleton $ RoffStr xs))
226228 <|> escUnknown ("\\[" ++ cs ++ "]")
227229
228230 unicodeGlyph = try $ do
229231 xs <- ucharCode `sepBy1` (char '_') <* char ']'
230− return [RoffStr xs]
232+ return $ Seq.singleton $ RoffStr xs
231233
232234 ucharCode = try $ do
233235 char 'u'
@@ -238,20 +240,20 @@ escape = do
238240 Nothing -> mzero
239241 Just c -> return c
240242
241− escUnknown :: PandocMonad m => String -> RoffLexer m [LinePart]
243+ escUnknown :: PandocMonad m => String -> RoffLexer m (Seq LinePart)
242244 escUnknown s = do
243245 pos <- getPosition
244246 report $ SkippedContent ("Unknown escape sequence " ++ s) pos
245− return [RoffStr "\xFFFD"]
247+ return $ Seq.singleton $ RoffStr "\xFFFD"
246248
247249-- \s-1 \s0
248−escFontSize :: PandocMonad m => RoffLexer m [LinePart]
250+escFontSize :: PandocMonad m => RoffLexer m (Seq LinePart)
249251escFontSize = do
250252 let sign = option "" $ ("-" <$ char '-' <|> "" <$ char '+')
251253 let toFontSize xs =
252254 case safeRead xs of
253255 Nothing -> mzero
254− Just n -> return [FontSize n]
256+ Just n -> return $ Seq.singleton $ FontSize n
255257 choice
256258 [ do char '('
257259 s <- sign
@@ -267,7 +269,7 @@ escFontSize = do
267269 toFontSize (s ++ ds)
268270 ]
269271
270−escFont :: PandocMonad m => RoffLexer m [LinePart]
272+escFont :: PandocMonad m => RoffLexer m (Seq LinePart)
271273escFont = do
272274 font <- choice
273275 [ digit >> return defaultFontSpec
@@ -277,7 +279,7 @@ escFont = do
277279 ]
278280 modifyState $ \st -> st{ prevFont = currentFont st
279281 , currentFont = font }
280− return [Font font]
282+ return $ Seq.singleton $ Font font
281283
282284lettersFont :: PandocMonad m => RoffLexer m FontSpec
283285lettersFont = try $ do
@@ -536,24 +538,24 @@ lexArgs = do
536538 args <- many $ try oneArg
537539 skipMany spacetab
538540 eofline
539− return args
541+ return $ map Foldable.toList args
540542
541543 where
542544
543− oneArg :: PandocMonad m => RoffLexer m [LinePart]
545+ oneArg :: PandocMonad m => RoffLexer m (Seq LinePart)
544546 oneArg = do
545547 skipMany $ try $ string "\\\n" -- continuation line
546548 try quotedArg <|> plainArg
547549 -- try, because there are some erroneous files, e.g. linux/bpf.2
548550
549− plainArg :: PandocMonad m => RoffLexer m [LinePart]
551+ plainArg :: PandocMonad m => RoffLexer m (Seq LinePart)
550552 plainArg = do
551553 skipMany spacetab
552554 mconcat <$> many1 (macroArg <|> escape <|> regularText <|> unescapedQuote)
553555 where
554− unescapedQuote = char '"' >> return [RoffStr "\""]
556+ unescapedQuote = char '"' >> return (Seq.singleton $ RoffStr "\"")
555557
556− quotedArg :: PandocMonad m => RoffLexer m [LinePart]
558+ quotedArg :: PandocMonad m => RoffLexer m (Seq LinePart)
557559 quotedArg = do
558560 skipMany spacetab
559561 char '"'
@@ -566,9 +568,9 @@ lexArgs = do
566568 escapedQuote = try $ do
567569 char '"'
568570 char '"'
569− return [RoffStr "\""]
571+ return $ Seq.singleton $ RoffStr "\""
570572
571−escStar :: PandocMonad m => RoffLexer m [LinePart]
573+escStar :: PandocMonad m => RoffLexer m (Seq LinePart)
572574escStar = try $ do
573575 pos <- getPosition
574576 c <- anyChar
@@ -589,14 +591,14 @@ escStar = try $ do
589591 resolveString stringname pos = do
590592 RoffTokens ts <- resolveMacro stringname [] pos
591593 case Foldable.toList ts of
592− [MLine xs] -> return xs
594+ [MLine xs] -> return $ Seq.fromList xs
593595 _ -> do
594596 report $ SkippedContent ("unknown string " ++ stringname) pos
595597 return mempty
596598
597599lexLine :: PandocMonad m => RoffLexer m RoffTokens
598600lexLine = do
599− lnparts <- mconcat <$> many1 linePart
601+ lnparts <- Foldable.toList . mconcat <$> many1 linePart
600602 eofline
601603 go lnparts
602604 where -- return empty line if we only have empty strings;
@@ -605,30 +607,30 @@ lexLine = do
605607 go (RoffStr "" : xs) = go xs
606608 go xs = return $ singleTok $ MLine xs
607609
608−linePart :: PandocMonad m => RoffLexer m [LinePart]
610+linePart :: PandocMonad m => RoffLexer m (Seq LinePart)
609611linePart = macroArg <|> escape <|>
610612 regularText <|> quoteChar <|> spaceTabChar
611613
612−macroArg :: PandocMonad m => RoffLexer m [LinePart]
614+macroArg :: PandocMonad m => RoffLexer m (Seq LinePart)
613615macroArg = try $ do
614616 string "\\\\$"
615617 x <- digit
616− return [MacroArg $ ord x - ord '0']
618+ return $ Seq.singleton $ MacroArg $ ord x - ord '0'
617619
618−regularText :: PandocMonad m => RoffLexer m [LinePart]
620+regularText :: PandocMonad m => RoffLexer m (Seq LinePart)
619621regularText = do
620622 s <- many1 $ noneOf "\n\r\t \\\""
621− return [RoffStr s]
623+ return $ Seq.singleton $ RoffStr s
622624
623−quoteChar :: PandocMonad m => RoffLexer m [LinePart]
625+quoteChar :: PandocMonad m => RoffLexer m (Seq LinePart)
624626quoteChar = do
625627 char '"'
626− return [RoffStr "\""]
628+ return $ Seq.singleton $ RoffStr "\""
627629
628−spaceTabChar :: PandocMonad m => RoffLexer m [LinePart]
630+spaceTabChar :: PandocMonad m => RoffLexer m (Seq LinePart)
629631spaceTabChar = do
630632 c <- spacetab
631− return [RoffStr [c]]
633+ return $ Seq.singleton $ RoffStr [c]
632634
633635lexEmptyLine :: PandocMonad m => RoffLexer m RoffTokens
634636lexEmptyLine = newline >> return (singleTok MEmptyLine)