{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

----------------------------------------------------------------------------
-- |
-- Module      :  System.Texrunner.Parse
-- Copyright   :  (c) 2015 Christopher Chalmers
-- License     :  BSD-style (see LICENSE)
-- Maintainer  :  c.chalmers@me.com
--
-- Functions for parsing Tex output and logs. This log is parser is
-- experimental and largely untested. Please make an issue for any logs
-- that aren't parsed properly.
--
-----------------------------------------------------------------------------

module System.Texrunner.Parse
  ( -- * Box
    Box (..)
  , parseBox
    -- * Errors
  , TexLog (..)
  , TexInfo (..)
  , TexError (..)
  , TexError' (..)
  , someError
  , badBox
  , parseUnit
  , parseLog
  , prettyPrintLog
  ) where

import           Control.Applicative
import           Data.Attoparsec.ByteString.Char8 as A
import           Data.ByteString.Char8            (ByteString, cons, pack)
import qualified Data.ByteString.Char8            as B
import           Data.Functor                     (($>))
import           Data.Maybe
import           Data.Semigroup

------------------------------------------------------------------------
-- Boxes
------------------------------------------------------------------------

-- | Data type for holding dimensions of a hbox. It is likely the
--   internal representation will change to allow nested boxes in the
--   future.
data Box n = Box
  { forall n. Box n -> n
boxHeight :: n
  , forall n. Box n -> n
boxDepth  :: n
  , forall n. Box n -> n
boxWidth  :: n
  } deriving Int -> Box n -> ShowS
[Box n] -> ShowS
Box n -> String
(Int -> Box n -> ShowS)
-> (Box n -> String) -> ([Box n] -> ShowS) -> Show (Box n)
forall n. Show n => Int -> Box n -> ShowS
forall n. Show n => [Box n] -> ShowS
forall n. Show n => Box n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> Box n -> ShowS
showsPrec :: Int -> Box n -> ShowS
$cshow :: forall n. Show n => Box n -> String
show :: Box n -> String
$cshowList :: forall n. Show n => [Box n] -> ShowS
showList :: [Box n] -> ShowS
Show

int :: Parser Int
int :: Parser Int
int = Parser Int
forall a. Integral a => Parser a
decimal

parseBox :: Fractional n => Parser (Box n)
parseBox :: forall n. Fractional n => Parser (Box n)
parseBox = do
  (Char -> Bool) -> Parser ()
A.skipWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'\\') Parser () -> Parser ByteString Char -> Parser ()
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'\\'
  Parser (Box n)
parseSingle Parser (Box n) -> Parser (Box n) -> Parser (Box n)
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Box n)
forall n. Fractional n => Parser (Box n)
parseBox
  where
    parseSingle :: Parser (Box n)
parseSingle = do
      Int
_ <- Parser ByteString ByteString
"box" Parser ByteString ByteString -> Parser Int -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Int
int Parser Int -> Parser ByteString ByteString -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ByteString
"=\n\\hbox("
      n
h <- Parser n
forall a. Fractional a => Parser a
rational Parser n -> Parser ByteString Char -> Parser n
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'+'
      n
d <- Parser n
forall a. Fractional a => Parser a
rational Parser n -> Parser ByteString ByteString -> Parser n
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ByteString
")x"
      n
w <- Parser n
forall a. Fractional a => Parser a
rational
      --
      Box n -> Parser (Box n)
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Box n -> Parser (Box n)) -> Box n -> Parser (Box n)
forall a b. (a -> b) -> a -> b
$ n -> n -> n -> Box n
forall n. n -> n -> n -> Box n
Box (n -> n
forall n. Fractional n => n -> n
pt2bp n
h) (n -> n
forall n. Fractional n => n -> n
pt2bp n
d) (n -> n
forall n. Fractional n => n -> n
pt2bp n
w)

parseUnit :: Fractional n => Parser n
parseUnit :: forall a. Fractional a => Parser a
parseUnit = do
  (Char -> Bool) -> Parser ()
A.skipWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'>') Parser () -> Parser ByteString Char -> Parser ()
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'>'
  Parser ()
skipSpace
  (n -> n) -> Parser n -> Parser n
forall a b. (a -> b) -> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap n -> n
forall n. Fractional n => n -> n
pt2bp Parser n
forall a. Fractional a => Parser a
rational Parser n -> Parser n -> Parser n
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser n
forall a. Fractional a => Parser a
parseUnit

pt2bp :: Fractional n => n -> n
pt2bp :: forall n. Fractional n => n -> n
pt2bp = (n -> n -> n
forall a. Fractional a => a -> a -> a
/n
1.00374)

------------------------------------------------------------------------
-- Logs
------------------------------------------------------------------------

-- Everything's done using ByteString because io-streams' attoparsec module
-- only has a ByteString function. It's very likely this will all change to
-- Text in the future.

data TexLog = TexLog
  { TexLog -> TexInfo
texInfo   :: TexInfo
  , TexLog -> Maybe Int
numPages  :: Maybe Int
  , TexLog -> [TexError]
texErrors :: [TexError]
  , TexLog -> ByteString
rawLog    :: ByteString
  } deriving Int -> TexLog -> ShowS
[TexLog] -> ShowS
TexLog -> String
(Int -> TexLog -> ShowS)
-> (TexLog -> String) -> ([TexLog] -> ShowS) -> Show TexLog
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TexLog -> ShowS
showsPrec :: Int -> TexLog -> ShowS
$cshow :: TexLog -> String
show :: TexLog -> String
$cshowList :: [TexLog] -> ShowS
showList :: [TexLog] -> ShowS
Show

data TexInfo = TexInfo
  { TexInfo -> Maybe ByteString
texCommand      :: Maybe ByteString
  , TexInfo -> Maybe ByteString
texVersion      :: Maybe ByteString
  , TexInfo -> Maybe ByteString
texDistribution :: Maybe ByteString
  -- , texDate    :: Maybe Date
  }
  deriving Int -> TexInfo -> ShowS
[TexInfo] -> ShowS
TexInfo -> String
(Int -> TexInfo -> ShowS)
-> (TexInfo -> String) -> ([TexInfo] -> ShowS) -> Show TexInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TexInfo -> ShowS
showsPrec :: Int -> TexInfo -> ShowS
$cshow :: TexInfo -> String
show :: TexInfo -> String
$cshowList :: [TexInfo] -> ShowS
showList :: [TexInfo] -> ShowS
Show

-- Make shift way to parse a log by combining it in this way.
instance Semigroup TexLog where
  TexLog TexInfo
prog Maybe Int
pages1 [TexError]
errors1 ByteString
raw1 <> :: TexLog -> TexLog -> TexLog
<> TexLog TexInfo
_ Maybe Int
pages2 [TexError]
errors2 ByteString
raw2 =
    case (Maybe Int
pages1,Maybe Int
pages2) of
      (Just Int
a,Maybe Int
_) -> TexInfo -> Maybe Int -> [TexError] -> ByteString -> TexLog
TexLog TexInfo
prog (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
a) ([TexError]
errors1 [TexError] -> [TexError] -> [TexError]
forall a. [a] -> [a] -> [a]
++ [TexError]
errors2) (ByteString
raw1 ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
raw2)
      (Maybe Int
_,Maybe Int
b)      -> TexInfo -> Maybe Int -> [TexError] -> ByteString -> TexLog
TexLog TexInfo
prog Maybe Int
b ([TexError]
errors1 [TexError] -> [TexError] -> [TexError]
forall a. [a] -> [a] -> [a]
++ [TexError]
errors2) (ByteString
raw1 ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
raw2)

instance Monoid TexLog where
  mempty :: TexLog
mempty  = TexInfo -> Maybe Int -> [TexError] -> ByteString -> TexLog
TexLog (Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> TexInfo
TexInfo Maybe ByteString
forall a. Maybe a
Nothing Maybe ByteString
forall a. Maybe a
Nothing Maybe ByteString
forall a. Maybe a
Nothing) Maybe Int
forall a. Maybe a
Nothing [] ByteString
""
  mappend :: TexLog -> TexLog -> TexLog
mappend = TexLog -> TexLog -> TexLog
forall a. Semigroup a => a -> a -> a
(<>)

infoParser :: Parser TexInfo
infoParser :: Parser TexInfo
infoParser
  = Maybe ByteString -> Maybe ByteString -> Maybe ByteString -> TexInfo
TexInfo
  (Maybe ByteString
 -> Maybe ByteString -> Maybe ByteString -> TexInfo)
-> Parser ByteString (Maybe ByteString)
-> Parser
     ByteString (Maybe ByteString -> Maybe ByteString -> TexInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ByteString ByteString
"This is"   Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
',') Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
anyChar)
  Parser ByteString (Maybe ByteString -> Maybe ByteString -> TexInfo)
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString (Maybe ByteString -> TexInfo)
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString ByteString
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser ByteString ByteString
" Version " Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
anyChar)
  Parser ByteString (Maybe ByteString -> TexInfo)
-> Parser ByteString (Maybe ByteString) -> Parser TexInfo
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString ByteString
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> Parser ByteString Char
char Char
'('    Parser ByteString Char
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
')') Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString Char
anyChar)
  -- <*> Nothing

logFile :: Parser TexLog
logFile :: Parser TexLog
logFile = [TexLog] -> TexLog
forall a. Monoid a => [a] -> a
mconcat ([TexLog] -> TexLog) -> Parser ByteString [TexLog] -> Parser TexLog
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TexLog -> Parser ByteString [TexLog]
forall a. Parser ByteString a -> Parser ByteString [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser TexLog
logLine
  where
    logLine :: Parser TexLog
logLine = do
      TexInfo
info   <- Parser TexInfo
infoParser
      Maybe Int
pages  <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Int
nPages
      [TexError]
errors <- Maybe TexError -> [TexError]
forall a. Maybe a -> [a]
maybeToList (Maybe TexError -> [TexError])
-> Parser ByteString (Maybe TexError)
-> Parser ByteString [TexError]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString TexError -> Parser ByteString (Maybe TexError)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString TexError
someError
      ByteString
_      <- Parser ByteString ByteString
restOfLine
      TexLog -> Parser TexLog
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexLog -> Parser TexLog) -> TexLog -> Parser TexLog
forall a b. (a -> b) -> a -> b
$ TexInfo -> Maybe Int -> [TexError] -> ByteString -> TexLog
TexLog TexInfo
info Maybe Int
pages [TexError]
errors ByteString
""

-- thisIs :: Parser TexVersion

parseLog :: ByteString -> TexLog
parseLog :: ByteString -> TexLog
parseLog ByteString
bs = (\(Right TexLog
a) -> TexLog
a { rawLog = bs }) (Either String TexLog -> TexLog)
-> (ByteString -> Either String TexLog) -> ByteString -> TexLog
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser TexLog -> ByteString -> Either String TexLog
forall a. Parser a -> ByteString -> Either String a
parseOnly Parser TexLog
logFile (ByteString -> TexLog) -> ByteString -> TexLog
forall a b. (a -> b) -> a -> b
$ ByteString
bs
-- the parse should never fail (I think)

prettyPrintLog :: TexLog -> ByteString
prettyPrintLog :: TexLog -> ByteString
prettyPrintLog TexLog {[TexError]
Maybe Int
ByteString
TexInfo
texInfo :: TexLog -> TexInfo
numPages :: TexLog -> Maybe Int
texErrors :: TexLog -> [TexError]
rawLog :: TexLog -> ByteString
texInfo :: TexInfo
numPages :: Maybe Int
texErrors :: [TexError]
rawLog :: ByteString
..} =
  ByteString -> Maybe ByteString -> ByteString
forall a. a -> Maybe a -> a
fromMaybe ByteString
"unknown program" (TexInfo -> Maybe ByteString
texCommand TexInfo
texInfo)
  ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
-> (ByteString -> ByteString) -> Maybe ByteString -> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
"" (ByteString
" version " ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>) (TexInfo -> Maybe ByteString
texVersion TexInfo
texInfo)
  ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
-> (ByteString -> ByteString) -> Maybe ByteString -> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
"" (ByteString
" " ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>) (TexInfo -> Maybe ByteString
texDistribution TexInfo
texInfo)
  ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\n"
  ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString -> (Int -> ByteString) -> Maybe Int -> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
"" ((ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"pages\n") (ByteString -> ByteString)
-> (Int -> ByteString) -> Int -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
pack (String -> ByteString) -> (Int -> String) -> Int -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show) Maybe Int
numPages
  ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [ByteString] -> ByteString
B.unlines ((TexError -> ByteString) -> [TexError] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (String -> ByteString
pack (String -> ByteString)
-> (TexError -> String) -> TexError -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TexError -> String
forall a. Show a => a -> String
show) [TexError]
texErrors)

------------------------------------------------------------------------
-- Errors
------------------------------------------------------------------------

-- | An error from tex with possible line number.
data TexError = TexError
  { TexError -> Maybe Int
errorLine :: Maybe Int
  , TexError -> TexError'
error'    :: TexError'
  }
  deriving Int -> TexError -> ShowS
[TexError] -> ShowS
TexError -> String
(Int -> TexError -> ShowS)
-> (TexError -> String) -> ([TexError] -> ShowS) -> Show TexError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TexError -> ShowS
showsPrec :: Int -> TexError -> ShowS
$cshow :: TexError -> String
show :: TexError -> String
$cshowList :: [TexError] -> ShowS
showList :: [TexError] -> ShowS
Show

instance Eq TexError where
  TexError Maybe Int
_ TexError'
a == :: TexError -> TexError -> Bool
== TexError Maybe Int
_ TexError'
b = TexError'
a TexError' -> TexError' -> Bool
forall a. Eq a => a -> a -> Bool
== TexError'
b

-- | A subset of possible error Tex can throw.
data TexError'
  = UndefinedControlSequence ByteString
  | MissingNumber
  | Missing Char
  | IllegalUnit -- (Maybe Char) (Maybe Char)
  | PackageError String String
  | LatexError ByteString
  | BadBox ByteString
  | EmergencyStop
  | ParagraphEnded
  | TooMany ByteString
  | DimensionTooLarge
  | TooManyErrors
  | NumberTooBig
  | ExtraBrace
  | FatalError ByteString
  | UnknownError ByteString
  deriving (Int -> TexError' -> ShowS
[TexError'] -> ShowS
TexError' -> String
(Int -> TexError' -> ShowS)
-> (TexError' -> String)
-> ([TexError'] -> ShowS)
-> Show TexError'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TexError' -> ShowS
showsPrec :: Int -> TexError' -> ShowS
$cshow :: TexError' -> String
show :: TexError' -> String
$cshowList :: [TexError'] -> ShowS
showList :: [TexError'] -> ShowS
Show, ReadPrec [TexError']
ReadPrec TexError'
Int -> ReadS TexError'
ReadS [TexError']
(Int -> ReadS TexError')
-> ReadS [TexError']
-> ReadPrec TexError'
-> ReadPrec [TexError']
-> Read TexError'
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TexError'
readsPrec :: Int -> ReadS TexError'
$creadList :: ReadS [TexError']
readList :: ReadS [TexError']
$creadPrec :: ReadPrec TexError'
readPrec :: ReadPrec TexError'
$creadListPrec :: ReadPrec [TexError']
readListPrec :: ReadPrec [TexError']
Read, TexError' -> TexError' -> Bool
(TexError' -> TexError' -> Bool)
-> (TexError' -> TexError' -> Bool) -> Eq TexError'
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TexError' -> TexError' -> Bool
== :: TexError' -> TexError' -> Bool
$c/= :: TexError' -> TexError' -> Bool
/= :: TexError' -> TexError' -> Bool
Eq)

-- | Parse any line beginning with "! ". Any unknown errors are returned as 'UnknownError'.
someError :: Parser TexError
someError :: Parser ByteString TexError
someError =  Parser ()
mark Parser ()
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString TexError
errors
  where
    -- in context exclamation mark isn't always at the beginning
    mark :: Parser ()
mark = (Parser ByteString ByteString
"! " Parser ByteString ByteString -> () -> Parser ()
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> ())
        Parser () -> Parser () -> Parser ()
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Parser ByteString ByteString
"tex error       >" Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser ByteString Char -> Parser ByteString String
forall a. Parser ByteString a -> Parser ByteString [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Char -> Parser ByteString Char
notChar Char
':') Parser ByteString String
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString ByteString
": ")) Parser ByteString ByteString -> () -> Parser ()
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> ())
        Parser () -> Parser () -> Parser ()
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> Parser ByteString Char
notChar Char
'\n' Parser ByteString Char -> Parser () -> Parser ()
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ()
mark)
    errors :: Parser ByteString TexError
errors =  Parser ByteString TexError
undefinedControlSequence
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
illegalUnit
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
missingNumber
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
missing
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
latexError
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
emergencyStop
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
extraBrace
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
paragraphEnded
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
numberTooBig
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
tooMany
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
dimensionTooLarge
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
tooManyErrors
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString TexError
fatalError
          Parser ByteString TexError
-> Parser ByteString TexError -> Parser ByteString TexError
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing (TexError' -> TexError)
-> (ByteString -> TexError') -> ByteString -> TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> TexError'
UnknownError (ByteString -> TexError)
-> Parser ByteString ByteString -> Parser ByteString TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
restOfLine

noteStar :: Parser ()
noteStar :: Parser ()
noteStar = Parser ()
skipSpace Parser ()
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString ByteString
"<*>" Parser ByteString ByteString -> Parser () -> Parser ()
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ()
skipSpace

toBeReadAgain :: Parser Char
toBeReadAgain :: Parser ByteString Char
toBeReadAgain = do
  Parser ()
skipSpace
  ByteString
_ <- Parser ByteString ByteString
"<to be read again>"
  Parser ()
skipSpace
  Parser ByteString Char
anyChar

-- insertedText :: Parser ByteString
-- insertedText = do
--   skipSpace
--   _ <- "<inserted text>"
--   skipSpace
--   restOfLine

------------------------------------------------------------------------
-- Error parsers
------------------------------------------------------------------------

undefinedControlSequence :: Parser TexError
undefinedControlSequence :: Parser ByteString TexError
undefinedControlSequence = do
  ByteString
_ <- Parser ByteString ByteString
"Undefined control sequence"
  Maybe ByteString
_ <- Parser ByteString ByteString
-> Parser ByteString (Maybe ByteString)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString ByteString
"."

  Maybe Int
_ <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Int -> Parser ByteString (Maybe Int))
-> Parser Int -> Parser ByteString (Maybe Int)
forall a b. (a -> b) -> a -> b
$ do -- for context log
    Parser ()
skipSpace
    ByteString
_ <- Parser ByteString ByteString
"system"
    let skipLines :: Parser Int
skipLines = Parser Int
line Parser Int -> Parser Int -> Parser Int
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ByteString
restOfLine Parser ByteString ByteString -> Parser Int -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Int
skipLines
    Parser Int
skipLines

  Maybe ()
_ <- Parser () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
noteStar
  Parser ()
skipSpace
  Maybe Int
l <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Int
line
  Parser ()
skipSpace
  ByteString
cs <- Parser ByteString ByteString
finalControlSequence
  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
l (ByteString -> TexError'
UndefinedControlSequence ByteString
cs)

finalControlSequence :: Parser ByteString
finalControlSequence :: Parser ByteString ByteString
finalControlSequence = [ByteString] -> ByteString
forall a. HasCallStack => [a] -> a
last ([ByteString] -> ByteString)
-> Parser ByteString [ByteString] -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString -> Parser ByteString [ByteString]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many1 Parser ByteString ByteString
controlSequence
  where
    controlSequence :: Parser ByteString ByteString
controlSequence = Char -> ByteString -> ByteString
cons Char
'\\' (ByteString -> ByteString)
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
      (Char -> Parser ByteString Char
char Char
'\\' Parser ByteString Char
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (\Char
x -> Char -> Bool
isSpace Char
x Bool -> Bool -> Bool
|| Char
xChar -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\\'))

illegalUnit :: Parser TexError
illegalUnit :: Parser ByteString TexError
illegalUnit = do
  ByteString
_ <- Parser ByteString ByteString
"Illegal unit of measure (pt inserted)"
  Maybe Char
_ <- Parser ByteString Char -> Parser ByteString (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString Char
toBeReadAgain
  Maybe Char
_ <- Parser ByteString Char -> Parser ByteString (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString Char
toBeReadAgain

  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
IllegalUnit

missingNumber :: Parser TexError
missingNumber :: Parser ByteString TexError
missingNumber = do
  ByteString
_ <- Parser ByteString ByteString
"Missing number, treated as zero"
  Maybe Char
_ <- Parser ByteString Char -> Parser ByteString (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ByteString Char
toBeReadAgain
  Maybe ()
_ <- Parser () -> Parser ByteString (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
noteStar
  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
MissingNumber

badBox :: Parser TexError
badBox :: Parser ByteString TexError
badBox = do
  ByteString
s <- [Parser ByteString ByteString] -> Parser ByteString ByteString
forall (f :: * -> *) a. Alternative f => [f a] -> f a
choice [Parser ByteString ByteString
"Underfull", Parser ByteString ByteString
"Overfull", Parser ByteString ByteString
"Tight", Parser ByteString ByteString
"Loose"]
  ByteString
_ <- Parser ByteString ByteString
" \\hbox " Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString Char
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> Parser ByteString Char
char Char
'(' Parser ByteString Char
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
')') Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
')'
  Maybe Int
l <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Int
line
  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
l (ByteString -> TexError'
BadBox ByteString
s)

missing :: Parser TexError
missing :: Parser ByteString TexError
missing = do
  Char
c <- Parser ByteString ByteString
"Missing " Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString Char
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Char
anyChar Parser ByteString Char
-> Parser ByteString ByteString -> Parser ByteString Char
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ByteString
" inserted"
  Maybe Int
l <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Int
line
  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
l (Char -> TexError'
Missing Char
c)

line :: Parser Int
line :: Parser Int
line =  Parser ByteString ByteString
" detected at line " Parser ByteString ByteString -> Parser Int -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Int
forall a. Integral a => Parser a
decimal
    Parser Int -> Parser Int -> Parser Int
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString ByteString
"l."                 Parser ByteString ByteString -> Parser Int -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Int
forall a. Integral a => Parser a
decimal

emergencyStop :: Parser TexError
emergencyStop :: Parser ByteString TexError
emergencyStop = Parser ByteString ByteString
"Emergency stop"
             Parser ByteString ByteString
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
EmergencyStop)

fatalError :: Parser TexError
fatalError :: Parser ByteString TexError
fatalError = Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing (TexError' -> TexError)
-> (ByteString -> TexError') -> ByteString -> TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> TexError'
FatalError (ByteString -> TexError)
-> Parser ByteString ByteString -> Parser ByteString TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString ByteString
" ==> Fatal error occurred, " Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString ByteString
restOfLine)

-- line 8058 tex.web
extraBrace :: Parser TexError
extraBrace :: Parser ByteString TexError
extraBrace = Parser ByteString ByteString
"Argument of" Parser ByteString ByteString
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
ExtraBrace)

tooMany :: Parser TexError
tooMany :: Parser ByteString TexError
tooMany = Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing (TexError' -> TexError)
-> (ByteString -> TexError') -> ByteString -> TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> TexError'
TooMany (ByteString -> TexError)
-> Parser ByteString ByteString -> Parser ByteString TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString ByteString
"Too Many " Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\''))

tooManyErrors :: Parser TexError
tooManyErrors :: Parser ByteString TexError
tooManyErrors = Parser ByteString ByteString
"That makes 100 errors; please try again"
             Parser ByteString ByteString
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
TooManyErrors)

dimensionTooLarge :: Parser TexError
dimensionTooLarge :: Parser ByteString TexError
dimensionTooLarge = Parser ByteString ByteString
"Dimension too large"
                 Parser ByteString ByteString
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
DimensionTooLarge)

-- line 8075 tex.web
paragraphEnded :: Parser TexError
paragraphEnded :: Parser ByteString TexError
paragraphEnded = do
  ByteString
_ <- Parser ByteString ByteString
"Paragraph ended before "
  ByteString
_ <- (Char -> Bool) -> Parser ByteString ByteString
takeTill Char -> Bool
isSpace
  Char
_ <- Parser ByteString Char
toBeReadAgain
  Maybe Int
l <- Parser Int -> Parser ByteString (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Int
line
  TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (TexError -> Parser ByteString TexError)
-> TexError -> Parser ByteString TexError
forall a b. (a -> b) -> a -> b
$ Maybe Int -> TexError' -> TexError
TexError Maybe Int
l TexError'
ParagraphEnded

numberTooBig :: Parser TexError
numberTooBig :: Parser ByteString TexError
numberTooBig = Parser ByteString ByteString
"Number too big"
            Parser ByteString ByteString
-> Parser ByteString TexError -> Parser ByteString TexError
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> TexError -> Parser ByteString TexError
forall a. a -> Parser ByteString a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing TexError'
NumberTooBig)

-- Latex errors

latexError :: Parser TexError
latexError :: Parser ByteString TexError
latexError = Maybe Int -> TexError' -> TexError
TexError Maybe Int
forall a. Maybe a
Nothing (TexError' -> TexError)
-> (ByteString -> TexError') -> ByteString -> TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> TexError'
LatexError (ByteString -> TexError)
-> Parser ByteString ByteString -> Parser ByteString TexError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString ByteString
"Latex Error: " Parser ByteString ByteString
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString ByteString
restOfLine)

-- Pages

nPages :: Parser Int
nPages :: Parser Int
nPages = Parser ByteString ByteString
"Output written on "
      Parser ByteString ByteString -> Parser () -> Parser ()
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser ()
skipWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'(') Parser () -> Parser ByteString Char -> Parser ByteString Char
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> Parser ByteString Char
char Char
'('
      Parser ByteString Char -> Parser Int -> Parser Int
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Int
forall a. Integral a => Parser a
decimal

-- Utilities

restOfLine :: Parser ByteString
restOfLine :: Parser ByteString ByteString
restOfLine = (Char -> Bool) -> Parser ByteString ByteString
takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\n') Parser ByteString ByteString
-> Parser ByteString Char -> Parser ByteString ByteString
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'\n'