aboutsummaryrefslogtreecommitdiff
path: root/src/Text/Pandoc
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2017-07-07 11:41:28 +0200
committerJohn MacFarlane <jgm@berkeley.edu>2017-07-07 12:37:21 +0200
commit6f6e83a06e9793d26cb622024098af39c14cb60a (patch)
treeee87615278e4393f417cc46fbb2069dfed51c768 /src/Text/Pandoc
parent0feb7504b1c68cef76b30ea9987e2eae3101714c (diff)
downloadpandoc-6f6e83a06e9793d26cb622024098af39c14cb60a.tar.gz
Parsing: added takeP, takeWhileP for efficient parsing of [Char].
Diffstat (limited to 'src/Text/Pandoc')
-rw-r--r--src/Text/Pandoc/Parsing.hs35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs
index f6263c782..549042d14 100644
--- a/src/Text/Pandoc/Parsing.hs
+++ b/src/Text/Pandoc/Parsing.hs
@@ -35,7 +35,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A utility library with parsers used in pandoc readers.
-}
-module Text.Pandoc.Parsing ( anyLine,
+module Text.Pandoc.Parsing ( takeWhileP,
+ takeP,
+ anyLine,
anyLineNewline,
indentWith,
many1Till,
@@ -191,7 +193,7 @@ import qualified Text.Pandoc.Builder as B
import Text.Pandoc.XML (fromEntities)
import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
import Text.Parsec hiding (token)
-import Text.Parsec.Pos (newPos, initialPos)
+import Text.Parsec.Pos (newPos, initialPos, updatePosString)
import Data.Char ( toLower, toUpper, ord, chr, isAscii, isAlphaNum,
isHexDigit, isSpace, isPunctuation )
import Data.List ( intercalate, transpose, isSuffixOf )
@@ -244,6 +246,35 @@ instance Monoid a => Monoid (Future s a) where
mappend = liftM2 mappend
mconcat = liftM mconcat . sequence
+-- | Parse characters while a predicate is true.
+takeWhileP :: Stream [Char] m Char
+ => (Char -> Bool) -> ParserT [Char] st m [Char]
+takeWhileP f = do
+ -- faster than 'many (satisfy f)'
+ inp <- getInput
+ pos <- getPosition
+ let (xs, rest) = span f inp
+ -- needed to persuade parsec that this won't match an empty string:
+ anyChar
+ setInput rest
+ setPosition $ updatePosString pos xs
+ return xs
+
+-- Parse n characters of input (or the rest of the input if
+-- there aren't n characters).
+takeP :: Stream [Char] m Char => Int -> ParserT [Char] st m [Char]
+takeP n = do
+ guard (n > 0)
+ -- faster than 'count n anyChar'
+ inp <- getInput
+ pos <- getPosition
+ let (xs, rest) = splitAt n inp
+ -- needed to persuade parsec that this won't match an empty string:
+ anyChar
+ setInput rest
+ setPosition $ updatePosString pos xs
+ return xs
+
-- | Parse any line of text
anyLine :: Stream [Char] m Char => ParserT [Char] st m [Char]
anyLine = do