{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{- |
   Module      : Text.Pandoc.Readers.LaTeX.Parsing
   Copyright   : Copyright (C) 2006-2023 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

General parsing types and functions for LaTeX.
-}
module Text.Pandoc.Readers.LaTeX.Parsing
  ( DottedNum(..)
  , renderDottedNum
  , incrementDottedNum
  , TheoremSpec(..)
  , TheoremStyle(..)
  , LaTeXState(..)
  , defaultLaTeXState
  , LP
  , TokStream(..)
  , withVerbatimMode
  , rawLaTeXParser
  , applyMacros
  , tokenize
  , tokenizeSources
  , getInputTokens
  , untokenize
  , untoken
  , satisfyTok
  , peekTok
  , parseFromToks
  , disablingWithRaw
  , doMacros
  , doMacros'
  , setpos
  , anyControlSeq
  , anySymbol
  , isNewlineTok
  , isWordTok
  , isArgTok
  , infile
  , spaces
  , spaces1
  , tokTypeIn
  , controlSeq
  , symbol
  , symbolIn
  , sp
  , whitespace
  , newlineTok
  , comment
  , anyTok
  , singleChar
  , tokWith
  , specialChars
  , endline
  , blankline
  , primEscape
  , bgroup
  , egroup
  , grouped
  , braced
  , braced'
  , bracedUrl
  , bracedOrToken
  , bracketed
  , bracketedToks
  , parenWrapped
  , dimenarg
  , ignore
  , withRaw
  , keyvals
  , verbEnv
  , begin_
  , end_
  , getRawCommand
  , skipopts
  , rawopt
  , overlaySpecification
  , getNextNumber
  , label
  , setCaption
  , resetCaption
  , env
  , addMeta
  , removeLabel
  ) where

import Control.Applicative (many, (<|>))
import Control.Monad
import Control.Monad.Except (throwError)
import Control.Monad.Trans (lift)
import Data.Char (chr, isAlphaNum, isDigit, isLetter, ord)
import Data.Default
import Data.List (intercalate)
import qualified Data.IntMap as IntMap
import qualified Data.Map as M
import qualified Data.Set as Set
import Data.Text (Text)
import Data.Maybe (fromMaybe)
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Text as T
import Text.Pandoc.Builder
import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
import Text.Pandoc.Error
         (PandocError (PandocMacroLoop,PandocShouldNeverHappenError))
import Text.Pandoc.Logging
import Text.Pandoc.Options
import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
                            space, spaces, withRaw, (<|>))
import Text.Pandoc.TeX (ExpansionPoint (..), Macro (..),
                                        ArgSpec (..), Tok (..), TokType (..))
import Text.Pandoc.Shared
import Text.Pandoc.Walk

newtype DottedNum = DottedNum [Int]
  deriving (Int -> DottedNum -> ShowS
[DottedNum] -> ShowS
DottedNum -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [DottedNum] -> ShowS
$cshowList :: [DottedNum] -> ShowS
show :: DottedNum -> [Char]
$cshow :: DottedNum -> [Char]
showsPrec :: Int -> DottedNum -> ShowS
$cshowsPrec :: Int -> DottedNum -> ShowS
Show, DottedNum -> DottedNum -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DottedNum -> DottedNum -> Bool
$c/= :: DottedNum -> DottedNum -> Bool
== :: DottedNum -> DottedNum -> Bool
$c== :: DottedNum -> DottedNum -> Bool
Eq)

renderDottedNum :: DottedNum -> T.Text
renderDottedNum :: DottedNum -> Text
renderDottedNum (DottedNum [Int]
xs) = [Char] -> Text
T.pack forall a b. (a -> b) -> a -> b
$
  forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"." (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> [Char]
show [Int]
xs)

incrementDottedNum :: Int -> DottedNum -> DottedNum
incrementDottedNum :: Int -> DottedNum -> DottedNum
incrementDottedNum Int
level (DottedNum [Int]
ns) = [Int] -> DottedNum
DottedNum forall a b. (a -> b) -> a -> b
$
  case forall a. [a] -> [a]
reverse (forall a. Int -> [a] -> [a]
take Int
level ([Int]
ns forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat Int
0)) of
       (Int
x:[Int]
xs) -> forall a. [a] -> [a]
reverse (Int
xforall a. Num a => a -> a -> a
+Int
1 forall a. a -> [a] -> [a]
: [Int]
xs)
       []     -> []  -- shouldn't happen

data TheoremStyle =
  PlainStyle | DefinitionStyle | RemarkStyle
  deriving (Int -> TheoremStyle -> ShowS
[TheoremStyle] -> ShowS
TheoremStyle -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [TheoremStyle] -> ShowS
$cshowList :: [TheoremStyle] -> ShowS
show :: TheoremStyle -> [Char]
$cshow :: TheoremStyle -> [Char]
showsPrec :: Int -> TheoremStyle -> ShowS
$cshowsPrec :: Int -> TheoremStyle -> ShowS
Show, TheoremStyle -> TheoremStyle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TheoremStyle -> TheoremStyle -> Bool
$c/= :: TheoremStyle -> TheoremStyle -> Bool
== :: TheoremStyle -> TheoremStyle -> Bool
$c== :: TheoremStyle -> TheoremStyle -> Bool
Eq)

data TheoremSpec =
  TheoremSpec
    { TheoremSpec -> Inlines
theoremName    :: Inlines
    , TheoremSpec -> TheoremStyle
theoremStyle   :: TheoremStyle
    , TheoremSpec -> Maybe Text
theoremSeries  :: Maybe Text
    , TheoremSpec -> Maybe Text
theoremSyncTo  :: Maybe Text
    , TheoremSpec -> Bool
theoremNumber  :: Bool
    , TheoremSpec -> DottedNum
theoremLastNum :: DottedNum }
    deriving (Int -> TheoremSpec -> ShowS
[TheoremSpec] -> ShowS
TheoremSpec -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [TheoremSpec] -> ShowS
$cshowList :: [TheoremSpec] -> ShowS
show :: TheoremSpec -> [Char]
$cshow :: TheoremSpec -> [Char]
showsPrec :: Int -> TheoremSpec -> ShowS
$cshowsPrec :: Int -> TheoremSpec -> ShowS
Show, TheoremSpec -> TheoremSpec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TheoremSpec -> TheoremSpec -> Bool
$c/= :: TheoremSpec -> TheoremSpec -> Bool
== :: TheoremSpec -> TheoremSpec -> Bool
$c== :: TheoremSpec -> TheoremSpec -> Bool
Eq)

data LaTeXState = LaTeXState{ LaTeXState -> ReaderOptions
sOptions       :: ReaderOptions
                            , LaTeXState -> Meta
sMeta          :: Meta
                            , LaTeXState -> QuoteContext
sQuoteContext  :: QuoteContext
                            , LaTeXState -> NonEmpty (Map Text Macro)
sMacros        :: NonEmpty (M.Map Text Macro)
                            , LaTeXState -> [Text]
sContainers    :: [Text]
                            , LaTeXState -> [LogMessage]
sLogMessages   :: [LogMessage]
                            , LaTeXState -> Set Text
sIdentifiers   :: Set.Set Text
                            , LaTeXState -> Bool
sVerbatimMode  :: Bool
                            , LaTeXState -> Maybe Caption
sCaption       :: Maybe Caption
                            , LaTeXState -> Bool
sInListItem    :: Bool
                            , LaTeXState -> Bool
sInTableCell   :: Bool
                            , LaTeXState -> DottedNum
sLastHeaderNum :: DottedNum
                            , LaTeXState -> DottedNum
sLastFigureNum :: DottedNum
                            , LaTeXState -> DottedNum
sLastTableNum  :: DottedNum
                            , LaTeXState -> Int
sLastNoteNum   :: Int
                            , LaTeXState -> Map Text TheoremSpec
sTheoremMap    :: M.Map Text TheoremSpec
                            , LaTeXState -> TheoremStyle
sLastTheoremStyle :: TheoremStyle
                            , LaTeXState -> Maybe Text
sLastLabel     :: Maybe Text
                            , LaTeXState -> Map Text [Inline]
sLabels        :: M.Map Text [Inline]
                            , LaTeXState -> Bool
sHasChapters   :: Bool
                            , LaTeXState -> Map Text Bool
sToggles       :: M.Map Text Bool
                            , LaTeXState -> Map Text Text
sFileContents  :: M.Map Text Text
                            , LaTeXState -> Bool
sEnableWithRaw :: Bool
                            , LaTeXState -> IntMap [Tok]
sRawTokens     :: IntMap.IntMap [Tok]
                            }
     deriving Int -> LaTeXState -> ShowS
[LaTeXState] -> ShowS
LaTeXState -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [LaTeXState] -> ShowS
$cshowList :: [LaTeXState] -> ShowS
show :: LaTeXState -> [Char]
$cshow :: LaTeXState -> [Char]
showsPrec :: Int -> LaTeXState -> ShowS
$cshowsPrec :: Int -> LaTeXState -> ShowS
Show

defaultLaTeXState :: LaTeXState
defaultLaTeXState :: LaTeXState
defaultLaTeXState = LaTeXState{ sOptions :: ReaderOptions
sOptions       = forall a. Default a => a
def
                              , sMeta :: Meta
sMeta          = Meta
nullMeta
                              , sQuoteContext :: QuoteContext
sQuoteContext  = QuoteContext
NoQuote
                              , sMacros :: NonEmpty (Map Text Macro)
sMacros        = forall k a. Map k a
M.empty forall a. a -> [a] -> NonEmpty a
:| []
                              , sContainers :: [Text]
sContainers    = []
                              , sLogMessages :: [LogMessage]
sLogMessages   = []
                              , sIdentifiers :: Set Text
sIdentifiers   = forall a. Set a
Set.empty
                              , sVerbatimMode :: Bool
sVerbatimMode  = Bool
False
                              , sCaption :: Maybe Caption
sCaption       = forall a. Maybe a
Nothing
                              , sInListItem :: Bool
sInListItem    = Bool
False
                              , sInTableCell :: Bool
sInTableCell   = Bool
False
                              , sLastHeaderNum :: DottedNum
sLastHeaderNum = [Int] -> DottedNum
DottedNum []
                              , sLastFigureNum :: DottedNum
sLastFigureNum = [Int] -> DottedNum
DottedNum []
                              , sLastTableNum :: DottedNum
sLastTableNum  = [Int] -> DottedNum
DottedNum []
                              , sLastNoteNum :: Int
sLastNoteNum   = Int
0
                              , sTheoremMap :: Map Text TheoremSpec
sTheoremMap    = forall k a. Map k a
M.empty
                              , sLastTheoremStyle :: TheoremStyle
sLastTheoremStyle = TheoremStyle
PlainStyle
                              , sLastLabel :: Maybe Text
sLastLabel     = forall a. Maybe a
Nothing
                              , sLabels :: Map Text [Inline]
sLabels        = forall k a. Map k a
M.empty
                              , sHasChapters :: Bool
sHasChapters   = Bool
False
                              , sToggles :: Map Text Bool
sToggles       = forall k a. Map k a
M.empty
                              , sFileContents :: Map Text Text
sFileContents  = forall k a. Map k a
M.empty
                              , sEnableWithRaw :: Bool
sEnableWithRaw = Bool
True
                              , sRawTokens :: IntMap [Tok]
sRawTokens     = forall a. IntMap a
IntMap.empty
                              }

instance PandocMonad m => HasQuoteContext LaTeXState m where
  getQuoteContext :: forall s t. Stream s m t => ParsecT s LaTeXState m QuoteContext
getQuoteContext = LaTeXState -> QuoteContext
sQuoteContext forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  withQuoteContext :: forall s a.
QuoteContext
-> ParsecT s LaTeXState m a -> ParsecT s LaTeXState m a
withQuoteContext QuoteContext
context ParsecT s LaTeXState m a
parser = do
    LaTeXState
oldState <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let oldQuoteContext :: QuoteContext
oldQuoteContext = LaTeXState -> QuoteContext
sQuoteContext LaTeXState
oldState
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState LaTeXState
oldState { sQuoteContext :: QuoteContext
sQuoteContext = QuoteContext
context }
    a
result <- ParsecT s LaTeXState m a
parser
    LaTeXState
newState <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState LaTeXState
newState { sQuoteContext :: QuoteContext
sQuoteContext = QuoteContext
oldQuoteContext }
    forall (m :: * -> *) a. Monad m => a -> m a
return a
result

instance HasLogMessages LaTeXState where
  addLogMessage :: LogMessage -> LaTeXState -> LaTeXState
addLogMessage LogMessage
msg LaTeXState
st = LaTeXState
st{ sLogMessages :: [LogMessage]
sLogMessages = LogMessage
msg forall a. a -> [a] -> [a]
: LaTeXState -> [LogMessage]
sLogMessages LaTeXState
st }
  getLogMessages :: LaTeXState -> [LogMessage]
getLogMessages LaTeXState
st = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ LaTeXState -> [LogMessage]
sLogMessages LaTeXState
st

instance HasIdentifierList LaTeXState where
  extractIdentifierList :: LaTeXState -> Set Text
extractIdentifierList     = LaTeXState -> Set Text
sIdentifiers
  updateIdentifierList :: (Set Text -> Set Text) -> LaTeXState -> LaTeXState
updateIdentifierList Set Text -> Set Text
f LaTeXState
st = LaTeXState
st{ sIdentifiers :: Set Text
sIdentifiers = Set Text -> Set Text
f forall a b. (a -> b) -> a -> b
$ LaTeXState -> Set Text
sIdentifiers LaTeXState
st }

instance HasIncludeFiles LaTeXState where
  getIncludeFiles :: LaTeXState -> [Text]
getIncludeFiles = LaTeXState -> [Text]
sContainers
  addIncludeFile :: Text -> LaTeXState -> LaTeXState
addIncludeFile Text
f LaTeXState
s = LaTeXState
s{ sContainers :: [Text]
sContainers = Text
f forall a. a -> [a] -> [a]
: LaTeXState -> [Text]
sContainers LaTeXState
s }
  dropLatestIncludeFile :: LaTeXState -> LaTeXState
dropLatestIncludeFile LaTeXState
s = LaTeXState
s { sContainers :: [Text]
sContainers = forall a. Int -> [a] -> [a]
drop Int
1 forall a b. (a -> b) -> a -> b
$ LaTeXState -> [Text]
sContainers LaTeXState
s }

instance HasMacros LaTeXState where
  extractMacros :: LaTeXState -> Map Text Macro
extractMacros  LaTeXState
st  = forall a. NonEmpty a -> a
NonEmpty.head forall a b. (a -> b) -> a -> b
$ LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
st
  updateMacros :: (Map Text Macro -> Map Text Macro) -> LaTeXState -> LaTeXState
updateMacros Map Text Macro -> Map Text Macro
f LaTeXState
st  = LaTeXState
st{ sMacros :: NonEmpty (Map Text Macro)
sMacros = Map Text Macro -> Map Text Macro
f (forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
st))
                                     forall a. a -> [a] -> NonEmpty a
:| forall a. NonEmpty a -> [a]
NonEmpty.tail (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
st) }

instance HasReaderOptions LaTeXState where
  extractReaderOptions :: LaTeXState -> ReaderOptions
extractReaderOptions = LaTeXState -> ReaderOptions
sOptions

instance HasMeta LaTeXState where
  setMeta :: forall b. ToMetaValue b => Text -> b -> LaTeXState -> LaTeXState
setMeta Text
field b
val LaTeXState
st =
    LaTeXState
st{ sMeta :: Meta
sMeta = forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
setMeta Text
field b
val forall a b. (a -> b) -> a -> b
$ LaTeXState -> Meta
sMeta LaTeXState
st }
  deleteMeta :: Text -> LaTeXState -> LaTeXState
deleteMeta Text
field LaTeXState
st =
    LaTeXState
st{ sMeta :: Meta
sMeta = forall a. HasMeta a => Text -> a -> a
deleteMeta Text
field forall a b. (a -> b) -> a -> b
$ LaTeXState -> Meta
sMeta LaTeXState
st }

instance Default LaTeXState where
  def :: LaTeXState
def = LaTeXState
defaultLaTeXState

-- The Boolean is True if macros have already been expanded,
-- False if they need expanding.
data TokStream = TokStream !Bool [Tok]
  deriving (Int -> TokStream -> ShowS
[TokStream] -> ShowS
TokStream -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [TokStream] -> ShowS
$cshowList :: [TokStream] -> ShowS
show :: TokStream -> [Char]
$cshow :: TokStream -> [Char]
showsPrec :: Int -> TokStream -> ShowS
$cshowsPrec :: Int -> TokStream -> ShowS
Show)

instance Semigroup TokStream where
  (TokStream Bool
exp1 [Tok]
ts1) <> :: TokStream -> TokStream -> TokStream
<> (TokStream Bool
exp2 [Tok]
ts2) =
    Bool -> [Tok] -> TokStream
TokStream (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Tok]
ts1 then Bool
exp2 else Bool
exp1) ([Tok]
ts1 forall a. Semigroup a => a -> a -> a
<> [Tok]
ts2)

instance Monoid TokStream where
  mempty :: TokStream
mempty = Bool -> [Tok] -> TokStream
TokStream Bool
False forall a. Monoid a => a
mempty
  mappend :: TokStream -> TokStream -> TokStream
mappend = forall a. Semigroup a => a -> a -> a
(<>)

instance Monad m => Stream TokStream m Tok where
  uncons :: TokStream -> m (Maybe (Tok, TokStream))
uncons (TokStream Bool
_ []) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  uncons (TokStream Bool
_ (Tok
t:[Tok]
ts)) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Tok
t, Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
ts)

type LP m = ParsecT TokStream LaTeXState m

withVerbatimMode :: PandocMonad m => LP m a -> LP m a
withVerbatimMode :: forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode LP m a
parser = do
  Bool
alreadyVerbatimMode <- LaTeXState -> Bool
sVerbatimMode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  if Bool
alreadyVerbatimMode
     then LP m a
parser
     else do
       forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sVerbatimMode :: Bool
sVerbatimMode = Bool
True }
       a
result <- LP m a
parser
       forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sVerbatimMode :: Bool
sVerbatimMode = Bool
False }
       forall (m :: * -> *) a. Monad m => a -> m a
return a
result

rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s, Show a)
               => [Tok] -> LP m a -> LP m a
               -> ParsecT Sources s m (a, Text)
rawLaTeXParser :: forall (m :: * -> *) s a.
(PandocMonad m, HasMacros s, HasReaderOptions s, Show a) =>
[Tok] -> LP m a -> LP m a -> ParsecT Sources s m (a, Text)
rawLaTeXParser [Tok]
toks LP m a
parser LP m a
valParser = do
  s
pstate <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  let lstate :: LaTeXState
lstate = forall a. Default a => a
def{ sOptions :: ReaderOptions
sOptions = forall st. HasReaderOptions st => st -> ReaderOptions
extractReaderOptions s
pstate }
  let lstate' :: LaTeXState
lstate' = LaTeXState
lstate { sMacros :: NonEmpty (Map Text Macro)
sMacros = forall st. HasMacros st => st -> Map Text Macro
extractMacros s
pstate forall a. a -> [a] -> NonEmpty a
:| [] }
  let setStartPos :: ParsecT s u m ()
setStartPos = case [Tok]
toks of
                      Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
                      [Tok]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
  let preparser :: LP m a
preparser = forall {s} {u}. ParsecT s u m ()
setStartPos forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LP m a
parser
  let rawparser :: ParsecT TokStream LaTeXState m ((a, [Tok]), LaTeXState)
rawparser = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw LP m a
valParser forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  Either ParseError (SourcePos, [Tok])
res' <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> [Char] -> s -> m (Either ParseError a)
runParserT (forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (LP m a
preparser forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition))
                            LaTeXState
lstate [Char]
"chunk" forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
toks
  case Either ParseError (SourcePos, [Tok])
res' of
       Left ParseError
_    -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
       Right (SourcePos
endpos, [Tok]
toks') -> do
         Either ParseError ((a, [Tok]), LaTeXState)
res <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> [Char] -> s -> m (Either ParseError a)
runParserT ParsecT TokStream LaTeXState m ((a, [Tok]), LaTeXState)
rawparser LaTeXState
lstate' [Char]
"chunk"
                     forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
toks'
         case Either ParseError ((a, [Tok]), LaTeXState)
res of
              Left ParseError
_    -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
              Right ((a
val, [Tok]
raw), LaTeXState
st) -> do
                forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState (forall st.
HasMacros st =>
(Map Text Macro -> Map Text Macro) -> st -> st
updateMacros ((forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
st)) forall a. Semigroup a => a -> a -> a
<>))
                let skipTilPos :: SourcePos -> ParsecT s u m ()
skipTilPos SourcePos
stopPos = do
                      forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar
                      SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                      if SourcePos
pos forall a. Ord a => a -> a -> Bool
>= SourcePos
stopPos
                         then forall (m :: * -> *) a. Monad m => a -> m a
return ()
                         else SourcePos -> ParsecT s u m ()
skipTilPos SourcePos
stopPos
                forall {m :: * -> *} {s} {u}.
(Stream s m Char, UpdateSourcePos s Char) =>
SourcePos -> ParsecT s u m ()
skipTilPos SourcePos
endpos
                let result :: Text
result = [Tok] -> Text
untokenize [Tok]
raw
                -- ensure we end with space if input did, see #4442
                let result' :: Text
result' =
                      case forall a. [a] -> [a]
reverse [Tok]
toks' of
                        (Tok SourcePos
_ (CtrlSeq Text
_) Text
t : [Tok]
_)
                         | Text
" " Text -> Text -> Bool
`T.isSuffixOf` Text
t
                         , Bool -> Bool
not (Text
" " Text -> Text -> Bool
`T.isSuffixOf` Text
result)
                          -> Text
result forall a. Semigroup a => a -> a -> a
<> Text
" "
                        [Tok]
_ -> Text
result
                forall (m :: * -> *) a. Monad m => a -> m a
return (a
val, Text
result')

applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
            => Text -> ParsecT Sources s m Text
applyMacros :: forall (m :: * -> *) s.
(PandocMonad m, HasMacros s, HasReaderOptions s) =>
Text -> ParsecT Sources s m Text
applyMacros Text
s = (forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardDisabled Extension
Ext_latex_macros forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Text
s) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
   do let retokenize :: ParsecT TokStream LaTeXState (ParsecT Sources s m) Text
retokenize = [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Alternative f => f a -> f [a]
many forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
      s
pstate <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      let lstate :: LaTeXState
lstate = forall a. Default a => a
def{ sOptions :: ReaderOptions
sOptions = forall st. HasReaderOptions st => st -> ReaderOptions
extractReaderOptions s
pstate
                      , sMacros :: NonEmpty (Map Text Macro)
sMacros  = forall st. HasMacros st => st -> Map Text Macro
extractMacros s
pstate forall a. a -> [a] -> NonEmpty a
:| [] }
      Either ParseError Text
res <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> [Char] -> s -> m (Either ParseError a)
runParserT ParsecT TokStream LaTeXState (ParsecT Sources s m) Text
retokenize LaTeXState
lstate [Char]
"math" forall a b. (a -> b) -> a -> b
$
                 Bool -> [Tok] -> TokStream
TokStream Bool
False (SourcePos -> Text -> [Tok]
tokenize ([Char] -> SourcePos
initialPos [Char]
"math") Text
s)
      case Either ParseError Text
res of
           Left ParseError
e   -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail (forall a. Show a => a -> [Char]
show ParseError
e)
           Right Text
s' -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
s'

{-
When tokenize or untokenize change, test with this
QuickCheck property:

> tokUntokRoundtrip :: String -> Bool
> tokUntokRoundtrip s =
>   let t = T.pack s in untokenize (tokenize "random" t) == t
-}

tokenizeSources :: Sources -> [Tok]
tokenizeSources :: Sources -> [Tok]
tokenizeSources = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (SourcePos, Text) -> [Tok]
tokenizeSource forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sources -> [(SourcePos, Text)]
unSources
 where
   tokenizeSource :: (SourcePos, Text) -> [Tok]
tokenizeSource (SourcePos
pos, Text
t) = SourcePos -> Text -> [Tok]
tokenize SourcePos
pos Text
t

-- Return tokens from input sources. Ensure that starting position is
-- correct.
getInputTokens :: PandocMonad m => ParsecT Sources s m [Tok]
getInputTokens :: forall (m :: * -> *) s. PandocMonad m => ParsecT Sources s m [Tok]
getInputTokens = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  Sources
ss <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    case Sources
ss of
      Sources [] -> []
      Sources ((SourcePos
_,Text
t):[(SourcePos, Text)]
rest) -> Sources -> [Tok]
tokenizeSources forall a b. (a -> b) -> a -> b
$ [(SourcePos, Text)] -> Sources
Sources ((SourcePos
pos,Text
t)forall a. a -> [a] -> [a]
:[(SourcePos, Text)]
rest)

tokenize :: SourcePos -> Text -> [Tok]
tokenize :: SourcePos -> Text -> [Tok]
tokenize = SourcePos -> Text -> [Tok]
totoks
 where
  totoks :: SourcePos -> Text -> [Tok]
totoks SourcePos
pos Text
t =
    case Text -> Maybe (Char, Text)
T.uncons Text
t of
       Maybe (Char, Text)
Nothing        -> []
       Just (Char
c, Text
rest)
         | Char
c forall a. Eq a => a -> a -> Bool
== Char
'\n' ->
           SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Newline Text
"\n"
           forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
setSourceColumn (SourcePos -> Int -> SourcePos
incSourceLine SourcePos
pos Int
1) Int
1) Text
rest
         | Char -> Bool
isSpaceOrTab Char
c ->
           let (Text
sps, Text
rest') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isSpaceOrTab Text
t
           in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Spaces Text
sps
               forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Text -> Int
T.length Text
sps))
                 Text
rest'
         | Char -> Bool
isAlphaNum Char
c ->
           let (Text
ws, Text
rest') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isAlphaNum Text
t
           in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Word Text
ws
               forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Text -> Int
T.length Text
ws)) Text
rest'
         | Char
c forall a. Eq a => a -> a -> Bool
== Char
'%' ->
           let (Text
cs, Text
rest') = (Char -> Bool) -> Text -> (Text, Text)
T.break (forall a. Eq a => a -> a -> Bool
== Char
'\n') Text
rest
           in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Comment (Text
"%" forall a. Semigroup a => a -> a -> a
<> Text
cs)
               forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
1 forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
cs)) Text
rest'
         | Char
c forall a. Eq a => a -> a -> Bool
== Char
'\\' ->
           case Text -> Maybe (Char, Text)
T.uncons Text
rest of
                Maybe (Char, Text)
Nothing -> [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
" ") Text
"\\"]
                Just (Char
d, Text
rest')
                  | Char -> Bool
isLetterOrAt Char
d ->
                      -- \makeatletter is common in macro defs;
                      -- ideally we should make tokenization sensitive
                      -- to \makeatletter and \makeatother, but this is
                      -- probably best for now
                      let (Text
ws, Text
rest'') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isLetterOrAt Text
rest
                          (Text
ss, Text
rest''') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isSpaceOrTab Text
rest''
                      in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
ws) (Text
"\\" forall a. Semigroup a => a -> a -> a
<> Text
ws forall a. Semigroup a => a -> a -> a
<> Text
ss)
                          forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos
                               (Int
1 forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
ws forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
ss)) Text
rest'''
                  | Char -> Bool
isSpaceOrTab Char
d Bool -> Bool -> Bool
|| Char
d forall a. Eq a => a -> a -> Bool
== Char
'\n' ->
                      let (Text
w1, Text
r1) = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isSpaceOrTab Text
rest
                          (Text
w2, (Text
w3, Text
r3)) = case Text -> Maybe (Char, Text)
T.uncons Text
r1 of
                                          Just (Char
'\n', Text
r2)
                                                  -> ([Char] -> Text
T.pack [Char]
"\n",
                                                        (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isSpaceOrTab Text
r2)
                                          Maybe (Char, Text)
_ -> (forall a. Monoid a => a
mempty, (forall a. Monoid a => a
mempty, Text
r1))
                          ws :: Text
ws = Text
"\\" forall a. Semigroup a => a -> a -> a
<> Text
w1 forall a. Semigroup a => a -> a -> a
<> Text
w2 forall a. Semigroup a => a -> a -> a
<> Text
w3
                      in  case Text -> Maybe (Char, Text)
T.uncons Text
r3 of
                               Just (Char
'\n', Text
_) ->
                                 SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
" ") (Text
"\\" forall a. Semigroup a => a -> a -> a
<> Text
w1)
                                 forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Text -> Int
T.length Text
ws))
                                   Text
r1
                               Maybe (Char, Text)
_ ->
                                 SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
" ") Text
ws
                                 forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Text -> Int
T.length Text
ws))
                                   Text
r3
                  | Bool
otherwise  ->
                      SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq (Char -> Text
T.singleton Char
d)) ([Char] -> Text
T.pack [Char
c,Char
d])
                      forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
2) Text
rest'
         | Char
c forall a. Eq a => a -> a -> Bool
== Char
'#' ->
           case Text -> Maybe (Char, Text)
T.uncons Text
rest of
             Just (Char
'#', Text
t3) ->
               let (Text
t1, Text
t2) = (Char -> Bool) -> Text -> (Text, Text)
T.span (\Char
d -> Char
d forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
d forall a. Ord a => a -> a -> Bool
<= Char
'9') Text
t3
               in  case forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
t1 of
                        Just Int
i ->
                           SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Int -> TokType
DeferredArg Int
i) (Text
"##" forall a. Semigroup a => a -> a -> a
<> Text
t1)
                           forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
2 forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
t1)) Text
t2
                        Maybe Int
Nothing -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"#"
                                  forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) TokType
Symbol Text
"#"
                                  forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) Text
t3
             Maybe (Char, Text)
_ ->
               let (Text
t1, Text
t2) = (Char -> Bool) -> Text -> (Text, Text)
T.span (\Char
d -> Char
d forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
d forall a. Ord a => a -> a -> Bool
<= Char
'9') Text
rest
               in  case forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
t1 of
                        Just Int
i ->
                           SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Int -> TokType
Arg Int
i) (Text
"#" forall a. Semigroup a => a -> a -> a
<> Text
t1)
                           forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
1 forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
t1)) Text
t2
                        Maybe Int
Nothing -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"#"
                                  forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) Text
rest
         | Char
c forall a. Eq a => a -> a -> Bool
== Char
'^' ->
           case Text -> Maybe (Char, Text)
T.uncons Text
rest of
                Just (Char
'^', Text
rest') ->
                  case Text -> Maybe (Char, Text)
T.uncons Text
rest' of
                       Just (Char
d, Text
rest'')
                         | Char -> Bool
isLowerHex Char
d ->
                           case Text -> Maybe (Char, Text)
T.uncons Text
rest'' of
                                Just (Char
e, Text
rest''') | Char -> Bool
isLowerHex Char
e ->
                                  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Esc2 ([Char] -> Text
T.pack [Char
'^',Char
'^',Char
d,Char
e])
                                  forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
4) Text
rest'''
                                Maybe (Char, Text)
_ ->
                                  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Esc1 ([Char] -> Text
T.pack [Char
'^',Char
'^',Char
d])
                                  forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
3) Text
rest''
                         | Char
d forall a. Ord a => a -> a -> Bool
< Char
'\128' ->
                                  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Esc1 ([Char] -> Text
T.pack [Char
'^',Char
'^',Char
d])
                                  forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
3) Text
rest''
                       Maybe (Char, Text)
_ -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"^" forall a. a -> [a] -> [a]
:
                            SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) TokType
Symbol Text
"^" forall a. a -> [a] -> [a]
:
                            SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
2) Text
rest'
                Maybe (Char, Text)
_ -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"^"
                     forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) Text
rest
         | Bool
otherwise ->
           SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol (Char -> Text
T.singleton Char
c) forall a. a -> [a] -> [a]
: SourcePos -> Text -> [Tok]
totoks (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) Text
rest

isSpaceOrTab :: Char -> Bool
isSpaceOrTab :: Char -> Bool
isSpaceOrTab Char
' '  = Bool
True
isSpaceOrTab Char
'\t' = Bool
True
isSpaceOrTab Char
_    = Bool
False

isLetterOrAt :: Char -> Bool
isLetterOrAt :: Char -> Bool
isLetterOrAt Char
'@' = Bool
True
isLetterOrAt Char
c   = Char -> Bool
isLetter Char
c

isLowerHex :: Char -> Bool
isLowerHex :: Char -> Bool
isLowerHex Char
x = Char
x forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
x forall a. Ord a => a -> a -> Bool
<= Char
'9' Bool -> Bool -> Bool
|| Char
x forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
x forall a. Ord a => a -> a -> Bool
<= Char
'f'

untokenize :: [Tok] -> Text
untokenize :: [Tok] -> Text
untokenize = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tok -> Text -> Text
untokenAccum forall a. Monoid a => a
mempty

untokenAccum :: Tok -> Text -> Text
untokenAccum :: Tok -> Text -> Text
untokenAccum (Tok SourcePos
_ (CtrlSeq Text
_) Text
t) Text
accum =
  -- insert space to prevent breaking a control sequence; see #5836
  case (Text -> Maybe (Text, Char)
T.unsnoc Text
t, Text -> Maybe (Char, Text)
T.uncons Text
accum) of
    (Just (Text
_,Char
c), Just (Char
d,Text
_))
      | Char -> Bool
isLetter Char
c
      , Char -> Bool
isLetter Char
d
      -> Text
t forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
accum
    (Maybe (Text, Char), Maybe (Char, Text))
_ -> Text
t forall a. Semigroup a => a -> a -> a
<> Text
accum
untokenAccum (Tok SourcePos
_ TokType
_ Text
t) Text
accum = Text
t forall a. Semigroup a => a -> a -> a
<> Text
accum

untoken :: Tok -> Text
untoken :: Tok -> Text
untoken Tok
t = Tok -> Text -> Text
untokenAccum Tok
t forall a. Monoid a => a
mempty

parseFromToks :: PandocMonad m => LP m a -> [Tok] -> LP m a
parseFromToks :: forall (m :: * -> *) a. PandocMonad m => LP m a -> [Tok] -> LP m a
parseFromToks LP m a
parser [Tok]
toks = do
  TokStream
oldInput <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
toks
  SourcePos
oldpos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  case [Tok]
toks of
     Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
     [Tok]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
  a
result <- forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
disablingWithRaw LP m a
parser
  forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput TokStream
oldInput
  forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
oldpos
  forall (m :: * -> *) a. Monad m => a -> m a
return a
result

disablingWithRaw :: PandocMonad m => LP m a -> LP m a
disablingWithRaw :: forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
disablingWithRaw LP m a
parser = do
  Bool
oldEnableWithRaw <- LaTeXState -> Bool
sEnableWithRaw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sEnableWithRaw :: Bool
sEnableWithRaw = Bool
False }
  a
result <- LP m a
parser
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sEnableWithRaw :: Bool
sEnableWithRaw = Bool
oldEnableWithRaw }
  forall (m :: * -> *) a. Monad m => a -> m a
return a
result

satisfyTok :: PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok :: forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
f = do
    forall (m :: * -> *). PandocMonad m => LP m ()
doMacros -- apply macros on remaining input stream
    Tok
res <- forall s (m :: * -> *) t a u.
Stream s m t =>
(t -> [Char])
-> (SourcePos -> t -> s -> SourcePos)
-> (t -> Maybe a)
-> ParsecT s u m a
tokenPrim (Text -> [Char]
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tok -> Text
untoken) SourcePos -> Tok -> TokStream -> SourcePos
updatePos Tok -> Maybe Tok
matcher
    forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st ->
      if LaTeXState -> Bool
sEnableWithRaw LaTeXState
st
         then
           let !newraws :: IntMap [Tok]
newraws = forall a b. (a -> b) -> IntMap a -> IntMap b
IntMap.map (Tok
resforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$! LaTeXState -> IntMap [Tok]
sRawTokens LaTeXState
st
            in  LaTeXState
st{ sRawTokens :: IntMap [Tok]
sRawTokens = IntMap [Tok]
newraws }
         else LaTeXState
st
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Tok
res
  where matcher :: Tok -> Maybe Tok
matcher Tok
t | Tok -> Bool
f Tok
t       = forall a. a -> Maybe a
Just Tok
t
                  | Bool
otherwise = forall a. Maybe a
Nothing
        updatePos :: SourcePos -> Tok -> TokStream -> SourcePos
        updatePos :: SourcePos -> Tok -> TokStream -> SourcePos
updatePos SourcePos
_spos Tok
_ (TokStream Bool
_ (Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_)) = SourcePos
pos
        updatePos SourcePos
spos (Tok SourcePos
_ TokType
_ Text
t) TokStream
_ = SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
spos (Text -> Int
T.length Text
t)

peekTok :: PandocMonad m => LP m Tok
peekTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
peekTok = do
  forall (m :: * -> *). PandocMonad m => LP m ()
doMacros
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (forall a b. a -> b -> a
const Bool
True))

doMacros :: PandocMonad m => LP m ()
doMacros :: forall (m :: * -> *). PandocMonad m => LP m ()
doMacros = do
  TokStream Bool
macrosExpanded [Tok]
toks <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
macrosExpanded forall a b. (a -> b) -> a -> b
$ do
    LaTeXState
st <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (LaTeXState -> Bool
sVerbatimMode LaTeXState
st) forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
1 [Tok]
toks forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [Tok] -> TokStream
TokStream Bool
True

doMacros' :: PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' :: forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
n [Tok]
inp =
  case [Tok]
inp of
     Tok SourcePos
spos (CtrlSeq Text
"begin") Text
_ : Tok SourcePos
_ TokType
Symbol Text
"{" :
      Tok SourcePos
_ TokType
Word Text
name : Tok SourcePos
_ TokType
Symbol Text
"}" : [Tok]
ts
        -> forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState m [Tok]
handleMacros Int
n SourcePos
spos Text
name [Tok]
ts forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
inp
     Tok SourcePos
spos (CtrlSeq Text
"end") Text
_ : Tok SourcePos
_ TokType
Symbol Text
"{" :
      Tok SourcePos
_ TokType
Word Text
name : Tok SourcePos
_ TokType
Symbol Text
"}" : [Tok]
ts
        -> forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState m [Tok]
handleMacros Int
n SourcePos
spos (Text
"end" forall a. Semigroup a => a -> a -> a
<> Text
name) [Tok]
ts forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
inp
     Tok SourcePos
_ (CtrlSeq Text
"expandafter") Text
_ : Tok
t : [Tok]
ts
        -> Tok -> [Tok] -> [Tok]
combineTok Tok
t forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
n [Tok]
ts
     Tok SourcePos
spos (CtrlSeq Text
name) Text
_ : [Tok]
ts
        -> forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState m [Tok]
handleMacros Int
n SourcePos
spos Text
name [Tok]
ts forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
inp
     [Tok]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
inp

  where
    combineTok :: Tok -> [Tok] -> [Tok]
combineTok (Tok SourcePos
spos (CtrlSeq Text
name) Text
x) (Tok SourcePos
_ TokType
Word Text
w : [Tok]
ts)
      | (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isLetterOrAt Text
w =
        SourcePos -> TokType -> Text -> Tok
Tok SourcePos
spos (Text -> TokType
CtrlSeq (Text
name forall a. Semigroup a => a -> a -> a
<> Text
w)) (Text
x1 forall a. Semigroup a => a -> a -> a
<> Text
w forall a. Semigroup a => a -> a -> a
<> Text
x2) forall a. a -> [a] -> [a]
: [Tok]
ts
          where (Text
x1, Text
x2) = (Char -> Bool) -> Text -> (Text, Text)
T.break Char -> Bool
isSpaceOrTab Text
x
    combineTok Tok
t [Tok]
ts = Tok
tforall a. a -> [a] -> [a]
:[Tok]
ts

    matchTok :: Tok -> LP m Tok
matchTok (Tok SourcePos
_ TokType
toktype Text
txt) =
      forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\(Tok SourcePos
_ TokType
toktype' Text
txt') ->
                    TokType
toktype forall a. Eq a => a -> a -> Bool
== TokType
toktype' Bool -> Bool -> Bool
&&
                    Text
txt forall a. Eq a => a -> a -> Bool
== Text
txt')

    matchPattern :: t Tok -> ParsecT TokStream LaTeXState m ()
matchPattern t Tok
toks = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchTok t Tok
toks

    getargs :: Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs Map Int [Tok]
argmap [] = forall (m :: * -> *) a. Monad m => a -> m a
return Map Int [Tok]
argmap
    getargs Map Int [Tok]
argmap (Pattern [Tok]
toks : [ArgSpec]
rest) = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
       forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState m ()
matchPattern [Tok]
toks
       Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs Map Int [Tok]
argmap [ArgSpec]
rest
    getargs Map Int [Tok]
argmap (ArgNum Int
i : Pattern [Tok]
toks : [ArgSpec]
rest) =
      forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        [Tok]
x <- forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill (forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((forall a. a -> [a] -> [a]
:[]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok))
                  (forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState m ()
matchPattern [Tok]
toks)
        Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs (forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Int
i [Tok]
x Map Int [Tok]
argmap) [ArgSpec]
rest
    getargs Map Int [Tok]
argmap (ArgNum Int
i : [ArgSpec]
rest) = do
      [Tok]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
      Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs (forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Int
i [Tok]
x Map Int [Tok]
argmap) [ArgSpec]
rest

    addTok :: Bool -> Map Int (t Tok) -> SourcePos -> Tok -> [Tok] -> [Tok]
addTok Bool
False Map Int (t Tok)
_args SourcePos
spos (Tok SourcePos
_ (DeferredArg Int
i) Text
txt) [Tok]
acc =
      SourcePos -> TokType -> Text -> Tok
Tok SourcePos
spos (Int -> TokType
Arg Int
i) Text
txt forall a. a -> [a] -> [a]
: [Tok]
acc
    addTok Bool
False Map Int (t Tok)
args SourcePos
spos (Tok SourcePos
_ (Arg Int
i) Text
_) [Tok]
acc =
       case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Int
i Map Int (t Tok)
args of
            Maybe (t Tok)
Nothing -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
            Just t Tok
xs -> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Bool -> Map Int (t Tok) -> SourcePos -> Tok -> [Tok] -> [Tok]
addTok Bool
True Map Int (t Tok)
args SourcePos
spos) [Tok]
acc t Tok
xs
    -- see #4007
    addTok Bool
_ Map Int (t Tok)
_ SourcePos
spos (Tok SourcePos
_ (CtrlSeq Text
x) Text
txt)
           acc :: [Tok]
acc@(Tok SourcePos
_ TokType
Word Text
_ : [Tok]
_)
      | Bool -> Bool
not (Text -> Bool
T.null Text
txt)
      , Char -> Bool
isLetter (Text -> Char
T.last Text
txt) =
        SourcePos -> TokType -> Text -> Tok
Tok SourcePos
spos (Text -> TokType
CtrlSeq Text
x) (Text
txt forall a. Semigroup a => a -> a -> a
<> Text
" ") forall a. a -> [a] -> [a]
: [Tok]
acc
    addTok Bool
_ Map Int (t Tok)
_ SourcePos
spos Tok
t [Tok]
acc = SourcePos -> Tok -> Tok
setpos SourcePos
spos Tok
t forall a. a -> [a] -> [a]
: [Tok]
acc

    handleMacros :: Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState m [Tok]
handleMacros Int
n' SourcePos
spos Text
name [Tok]
ts = do
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n' forall a. Ord a => a -> a -> Bool
> Int
20)  -- detect macro expansion loops
        forall a b. (a -> b) -> a -> b
$ forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocMacroLoop Text
name
      (Map Text Macro
macros :| [Map Text Macro]
_ ) <- LaTeXState -> NonEmpty (Map Text Macro)
sMacros forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
name Map Text Macro
macros of
           Maybe Macro
Nothing -> forall (m :: * -> *). PandocMonad m => Text -> [Tok] -> LP m [Tok]
trySpecialMacro Text
name [Tok]
ts
           Just (Macro MacroScope
_scope ExpansionPoint
expansionPoint [ArgSpec]
argspecs Maybe [Tok]
optarg [Tok]
newtoks) -> do
             let getargs' :: ParsecT TokStream LaTeXState m (Map Int [Tok], [Tok])
getargs' = do
                   Map Int [Tok]
args <-
                     (case ExpansionPoint
expansionPoint of
                        ExpansionPoint
ExpandWhenUsed    -> forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode
                        ExpansionPoint
ExpandWhenDefined -> forall a. a -> a
id)
                     forall a b. (a -> b) -> a -> b
$ case Maybe [Tok]
optarg of
                             Maybe [Tok]
Nothing -> forall {m :: * -> *}.
PandocMonad m =>
Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs forall k a. Map k a
M.empty [ArgSpec]
argspecs
                             Just [Tok]
o  -> do
                                [Tok]
x <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Tok]
o forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
                                forall {m :: * -> *}.
PandocMonad m =>
Map Int [Tok]
-> [ArgSpec] -> ParsecT TokStream LaTeXState m (Map Int [Tok])
getargs (forall k a. k -> a -> Map k a
M.singleton Int
1 [Tok]
x) forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
drop Int
1 [ArgSpec]
argspecs
                   TokStream Bool
_ [Tok]
rest <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
                   forall (m :: * -> *) a. Monad m => a -> m a
return (Map Int [Tok]
args, [Tok]
rest)
             LaTeXState
lstate <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
             Either ParseError (Map Int [Tok], [Tok])
res <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> [Char] -> s -> m (Either ParseError a)
runParserT ParsecT TokStream LaTeXState m (Map Int [Tok], [Tok])
getargs' LaTeXState
lstate [Char]
"args" forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
ts
             case Either ParseError (Map Int [Tok], [Tok])
res of
               Left ParseError
_ -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail forall a b. (a -> b) -> a -> b
$ [Char]
"Could not parse arguments for " forall a. [a] -> [a] -> [a]
++
                                Text -> [Char]
T.unpack Text
name
               Right (Map Int [Tok]
args, [Tok]
rest) -> do
                 -- first boolean param is true if we're tokenizing
                 -- an argument (in which case we don't want to
                 -- expand #1 etc.)
                 let result :: [Tok]
result = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall {t :: * -> *}.
Foldable t =>
Bool -> Map Int (t Tok) -> SourcePos -> Tok -> [Tok] -> [Tok]
addTok Bool
False Map Int [Tok]
args SourcePos
spos) [Tok]
rest [Tok]
newtoks
                 case ExpansionPoint
expansionPoint of
                   ExpansionPoint
ExpandWhenUsed    -> forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' (Int
n' forall a. Num a => a -> a -> a
+ Int
1) [Tok]
result
                   ExpansionPoint
ExpandWhenDefined -> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
result

-- | Certain macros do low-level tex manipulations that can't
-- be represented in our Macro type, so we handle them here.
trySpecialMacro :: PandocMonad m => Text -> [Tok] -> LP m [Tok]
trySpecialMacro :: forall (m :: * -> *). PandocMonad m => Text -> [Tok] -> LP m [Tok]
trySpecialMacro Text
"xspace" [Tok]
ts = do
  [Tok]
ts' <- forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
1 [Tok]
ts
  case [Tok]
ts' of
    Tok SourcePos
pos TokType
Word Text
t : [Tok]
_
      | Text -> Bool
startsWithAlphaNum Text
t -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Spaces Text
" " forall a. a -> [a] -> [a]
: [Tok]
ts'
    [Tok]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
ts'
trySpecialMacro Text
"iftrue" [Tok]
ts = forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
handleIf Bool
True [Tok]
ts
trySpecialMacro Text
"iffalse" [Tok]
ts = forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
handleIf Bool
False [Tok]
ts
trySpecialMacro Text
_ [Tok]
_ = forall (m :: * -> *) a. MonadPlus m => m a
mzero

handleIf :: PandocMonad m => Bool -> [Tok] -> LP m [Tok]
handleIf :: forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
handleIf Bool
b [Tok]
ts = do
  Either ParseError [Tok]
res' <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> [Char] -> s -> m (Either ParseError a)
runParserT (forall (m :: * -> *). PandocMonad m => Bool -> LP m [Tok]
ifParser Bool
b) LaTeXState
defaultLaTeXState [Char]
"tokens"
               forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
ts
  case Either ParseError [Tok]
res' of
    Left ParseError
_ -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Could not parse conditional"
    Right [Tok]
ts' -> forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
ts'

ifParser :: PandocMonad m => Bool -> LP m [Tok]
ifParser :: forall (m :: * -> *). PandocMonad m => Bool -> LP m [Tok]
ifParser Bool
b = do
  [Tok]
ifToks <- forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"else" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"fi")
                    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok)
  [Tok]
elseToks <- (forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"else" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok (forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"fi"))
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([] forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"fi")
  TokStream Bool
_ [Tok]
rest <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (if Bool
b then [Tok]
ifToks else [Tok]
elseToks) forall a. [a] -> [a] -> [a]
++ [Tok]
rest

startsWithAlphaNum :: Text -> Bool
startsWithAlphaNum :: Text -> Bool
startsWithAlphaNum Text
t =
  case Text -> Maybe (Char, Text)
T.uncons Text
t of
       Just (Char
c, Text
_) | Char -> Bool
isAlphaNum Char
c -> Bool
True
       Maybe (Char, Text)
_           -> Bool
False

setpos :: SourcePos -> Tok -> Tok
setpos :: SourcePos -> Tok -> Tok
setpos SourcePos
spos (Tok SourcePos
_ TokType
tt Text
txt) = SourcePos -> TokType -> Text -> Tok
Tok SourcePos
spos TokType
tt Text
txt

anyControlSeq :: PandocMonad m => LP m Tok
anyControlSeq :: forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isCtrlSeq

isCtrlSeq :: Tok -> Bool
isCtrlSeq :: Tok -> Bool
isCtrlSeq (Tok SourcePos
_ (CtrlSeq Text
_) Text
_) = Bool
True
isCtrlSeq Tok
_                     = Bool
False

anySymbol :: PandocMonad m => LP m Tok
anySymbol :: forall (m :: * -> *). PandocMonad m => LP m Tok
anySymbol = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isSymbolTok

isSymbolTok :: Tok -> Bool
isSymbolTok :: Tok -> Bool
isSymbolTok (Tok SourcePos
_ TokType
Symbol Text
_) = Bool
True
isSymbolTok Tok
_                = Bool
False

isWordTok :: Tok -> Bool
isWordTok :: Tok -> Bool
isWordTok (Tok SourcePos
_ TokType
Word Text
_) = Bool
True
isWordTok Tok
_              = Bool
False

isArgTok :: Tok -> Bool
isArgTok :: Tok -> Bool
isArgTok (Tok SourcePos
_ (Arg Int
_) Text
_) = Bool
True
isArgTok Tok
_                 = Bool
False

infile :: PandocMonad m => SourceName -> LP m Tok
infile :: forall (m :: * -> *). PandocMonad m => [Char] -> LP m Tok
infile [Char]
reference = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\(Tok SourcePos
source TokType
_ Text
_) -> (SourcePos -> [Char]
sourceName SourcePos
source) forall a. Eq a => a -> a -> Bool
== [Char]
reference)

spaces :: PandocMonad m => LP m ()
spaces :: forall (m :: * -> *). PandocMonad m => LP m ()
spaces = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Comment, TokType
Spaces, TokType
Newline]))

spaces1 :: PandocMonad m => LP m ()
spaces1 :: forall (m :: * -> *). PandocMonad m => LP m ()
spaces1 = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Comment, TokType
Spaces, TokType
Newline]))

tokTypeIn :: [TokType] -> Tok -> Bool
tokTypeIn :: [TokType] -> Tok -> Bool
tokTypeIn [TokType]
toktypes (Tok SourcePos
_ TokType
tt Text
_) = TokType
tt forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TokType]
toktypes

controlSeq :: PandocMonad m => Text -> LP m Tok
controlSeq :: forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
name = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isNamed
  where isNamed :: Tok -> Bool
isNamed (Tok SourcePos
_ (CtrlSeq Text
n) Text
_) = Text
n forall a. Eq a => a -> a -> Bool
== Text
name
        isNamed Tok
_                     = Bool
False

symbol :: PandocMonad m => Char -> LP m Tok
symbol :: forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
c = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isc
  where isc :: Tok -> Bool
isc (Tok SourcePos
_ TokType
Symbol Text
d) = case Text -> Maybe (Char, Text)
T.uncons Text
d of
                                    Just (Char
c',Text
_) -> Char
c forall a. Eq a => a -> a -> Bool
== Char
c'
                                    Maybe (Char, Text)
_           -> Bool
False
        isc Tok
_ = Bool
False

symbolIn :: PandocMonad m => [Char] -> LP m Tok
symbolIn :: forall (m :: * -> *). PandocMonad m => [Char] -> LP m Tok
symbolIn [Char]
cs = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isInCs
  where isInCs :: Tok -> Bool
isInCs (Tok SourcePos
_ TokType
Symbol Text
d) = case Text -> Maybe (Char, Text)
T.uncons Text
d of
                                       Just (Char
c,Text
_) -> Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
cs
                                       Maybe (Char, Text)
_          -> Bool
False
        isInCs Tok
_ = Bool
False

sp :: PandocMonad m => LP m ()
sp :: forall (m :: * -> *). PandocMonad m => LP m ()
sp = do
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (forall (m :: * -> *). PandocMonad m => LP m ()
whitespace forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m ()
comment)
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => LP m ()
endline  forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (forall (m :: * -> *). PandocMonad m => LP m ()
whitespace forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m ()
comment)

whitespace :: PandocMonad m => LP m ()
whitespace :: forall (m :: * -> *). PandocMonad m => LP m ()
whitespace = () forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isSpaceTok

isSpaceTok :: Tok -> Bool
isSpaceTok :: Tok -> Bool
isSpaceTok (Tok SourcePos
_ TokType
Spaces Text
_) = Bool
True
isSpaceTok Tok
_                = Bool
False

newlineTok :: PandocMonad m => LP m ()
newlineTok :: forall (m :: * -> *). PandocMonad m => LP m ()
newlineTok = () forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isNewlineTok

isNewlineTok :: Tok -> Bool
isNewlineTok :: Tok -> Bool
isNewlineTok (Tok SourcePos
_ TokType
Newline Text
_) = Bool
True
isNewlineTok Tok
_                 = Bool
False

comment :: PandocMonad m => LP m ()
comment :: forall (m :: * -> *). PandocMonad m => LP m ()
comment = () forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isCommentTok

isCommentTok :: Tok -> Bool
isCommentTok :: Tok -> Bool
isCommentTok (Tok SourcePos
_ TokType
Comment Text
_) = Bool
True
isCommentTok Tok
_                 = Bool
False

anyTok :: PandocMonad m => LP m Tok
anyTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok = forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (forall a b. a -> b -> a
const Bool
True)

singleCharTok :: PandocMonad m => LP m Tok
singleCharTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
singleCharTok =
  forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok forall a b. (a -> b) -> a -> b
$ \case
     Tok SourcePos
_ TokType
Word  Text
t   -> Text -> Int
T.length Text
t forall a. Eq a => a -> a -> Bool
== Int
1
     Tok SourcePos
_ TokType
Symbol Text
t  -> Bool -> Bool
not ((Char -> Bool) -> Text -> Bool
T.any (forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Char
specialChars) Text
t)
     Tok
_               -> Bool
False

singleChar :: PandocMonad m => LP m Tok
singleChar :: forall (m :: * -> *). PandocMonad m => LP m Tok
singleChar = forall (m :: * -> *). PandocMonad m => LP m Tok
singleCharTok forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState m Tok
singleCharFromWord
 where
  singleCharFromWord :: ParsecT TokStream LaTeXState m Tok
singleCharFromWord = do
    Tok SourcePos
pos TokType
toktype Text
t <- forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
disablingWithRaw forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok
    let (Text
t1, Text
t2) = (Int -> Text -> Text
T.take Int
1 Text
t, Int -> Text -> Text
T.drop Int
1 Text
t)
    TokStream Bool
macrosExpanded [Tok]
inp <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
    forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
macrosExpanded
             forall a b. (a -> b) -> a -> b
$ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
toktype Text
t1 forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) TokType
toktype Text
t2 forall a. a -> [a] -> [a]
: [Tok]
inp
    forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok

specialChars :: Set.Set Char
specialChars :: Set Char
specialChars = forall a. Ord a => [a] -> Set a
Set.fromList [Char]
"#$%&~_^\\{}"

endline :: PandocMonad m => LP m ()
endline :: forall (m :: * -> *). PandocMonad m => LP m ()
endline = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => LP m ()
newlineTok
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
  forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy forall (m :: * -> *). PandocMonad m => LP m ()
blankline

blankline :: PandocMonad m => LP m ()
blankline :: forall (m :: * -> *). PandocMonad m => LP m ()
blankline = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany forall (m :: * -> *). PandocMonad m => LP m ()
whitespace forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). PandocMonad m => LP m ()
newlineTok

primEscape :: PandocMonad m => LP m Char
primEscape :: forall (m :: * -> *). PandocMonad m => LP m Char
primEscape = do
  Tok SourcePos
_ TokType
toktype Text
t <- forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Esc1, TokType
Esc2])
  case TokType
toktype of
       TokType
Esc1 -> case Text -> Maybe (Char, Text)
T.uncons (Int -> Text -> Text
T.drop Int
2 Text
t) of
                    Just (Char
c, Text
_)
                      | Char
c forall a. Ord a => a -> a -> Bool
>= Char
'\64' Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\127' -> forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Char -> Int
ord Char
c forall a. Num a => a -> a -> a
- Int
64))
                      | Bool
otherwise                 -> forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Char -> Int
ord Char
c forall a. Num a => a -> a -> a
+ Int
64))
                    Maybe (Char, Text)
Nothing -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Empty content of Esc1"
       TokType
Esc2 -> case forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead (Text
"0x" forall a. Semigroup a => a -> a -> a
<> Int -> Text -> Text
T.drop Int
2 Text
t) of
                    Just Int
x  -> forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr Int
x)
                    Maybe Int
Nothing -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail forall a b. (a -> b) -> a -> b
$ [Char]
"Could not read: " forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t
       TokType
_    -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Expected an Esc1 or Esc2 token" -- should not happen

bgroup :: PandocMonad m => LP m Tok
bgroup :: forall (m :: * -> *). PandocMonad m => LP m Tok
bgroup = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall (m :: * -> *). PandocMonad m => LP m ()
sp
  Tok
t <- forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'{' forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"bgroup" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"begingroup"
  -- Add a copy of the macro table to the top of the macro stack,
  -- private for this group. We inherit all the macros defined in
  -- the parent group.
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s -> LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall a. a -> NonEmpty a -> NonEmpty a
NonEmpty.cons (forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s))
                                                 (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) }
  forall (m :: * -> *) a. Monad m => a -> m a
return Tok
t


egroup :: PandocMonad m => LP m Tok
egroup :: forall (m :: * -> *). PandocMonad m => LP m Tok
egroup = do
  Tok
t <- forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'}' forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"egroup" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"endgroup"
  -- remove the group's macro table from the stack
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s -> LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall a. a -> Maybe a -> a
fromMaybe (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) forall a b. (a -> b) -> a -> b
$
      forall a. [a] -> Maybe (NonEmpty a)
NonEmpty.nonEmpty (forall a. NonEmpty a -> [a]
NonEmpty.tail (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s)) }
  forall (m :: * -> *) a. Monad m => a -> m a
return Tok
t

grouped :: (PandocMonad m,  Monoid a) => LP m a -> LP m a
grouped :: forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
grouped LP m a
parser = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => LP m Tok
bgroup
  -- first we check for an inner 'grouped', because
  -- {{a,b}} should be parsed the same as {a,b}
  forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
grouped LP m a
parser forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *). PandocMonad m => LP m Tok
egroup) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill LP m a
parser forall (m :: * -> *). PandocMonad m => LP m Tok
egroup)

braced' :: PandocMonad m => LP m Tok -> LP m [Tok]
braced' :: forall (m :: * -> *). PandocMonad m => LP m Tok -> LP m [Tok]
braced' LP m Tok
getTok = forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'{' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall {t}.
(Ord t, Num t) =>
t -> ParsecT TokStream LaTeXState m [Tok]
go (Int
1 :: Int)
 where
  go :: t -> ParsecT TokStream LaTeXState m [Tok]
go t
n = do
    Tok
t <- LP m Tok
getTok
    case Tok
t of
      Tok SourcePos
_ TokType
Symbol Text
"}"
        | t
n forall a. Ord a => a -> a -> Bool
> t
1     -> (Tok
tforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState m [Tok]
go (t
n forall a. Num a => a -> a -> a
- t
1)
        | Bool
otherwise -> forall (m :: * -> *) a. Monad m => a -> m a
return []
      Tok SourcePos
_ TokType
Symbol Text
"{" -> (Tok
tforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState m [Tok]
go (t
n forall a. Num a => a -> a -> a
+ t
1)
      Tok
_ -> (Tok
tforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState m [Tok]
go t
n

braced :: PandocMonad m => LP m [Tok]
braced :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced = forall (m :: * -> *). PandocMonad m => LP m Tok -> LP m [Tok]
braced' forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok

-- URLs require special handling, because they can contain %
-- characters.  So we retonenize comments as we go...
bracedUrl :: PandocMonad m => LP m [Tok]
bracedUrl :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedUrl = forall (m :: * -> *). PandocMonad m => LP m Tok -> LP m [Tok]
braced' (forall (m :: * -> *). PandocMonad m => LP m ()
retokenizeComment forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok)

-- For handling URLs, which allow literal % characters...
retokenizeComment :: PandocMonad m => LP m ()
retokenizeComment :: forall (m :: * -> *). PandocMonad m => LP m ()
retokenizeComment = (do
  Tok SourcePos
pos TokType
Comment Text
txt <- forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isCommentTok
  let updPos :: Tok -> Tok
updPos (Tok SourcePos
pos' TokType
toktype' Text
txt') =
        SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn (SourcePos -> Int -> SourcePos
incSourceLine SourcePos
pos' (SourcePos -> Int
sourceLine SourcePos
pos forall a. Num a => a -> a -> a
- Int
1))
             (SourcePos -> Int
sourceColumn SourcePos
pos)) TokType
toktype' Text
txt'
  let newtoks :: [Tok]
newtoks = forall a b. (a -> b) -> [a] -> [b]
map Tok -> Tok
updPos forall a b. (a -> b) -> a -> b
$ SourcePos -> Text -> [Tok]
tokenize SourcePos
pos forall a b. (a -> b) -> a -> b
$ Text -> Text
T.tail Text
txt
  TokStream Bool
macrosExpanded [Tok]
ts <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
macrosExpanded ((SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"%" forall a. a -> [a] -> [a]
: [Tok]
newtoks) forall a. [a] -> [a] -> [a]
++ [Tok]
ts))
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ()

bracedOrToken :: PandocMonad m => LP m [Tok]
bracedOrToken :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken = forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((forall a. a -> [a] -> [a]
:[]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m Tok
singleChar))

bracketed :: PandocMonad m => Monoid a => LP m a -> LP m a
bracketed :: forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
bracketed LP m a
parser = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'['
  forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill LP m a
parser (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
']')

bracketedToks :: PandocMonad m => LP m [Tok]
bracketedToks :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks = do
  forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'['
  forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ((forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced)) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
1 forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok)
                      (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
']')

parenWrapped :: PandocMonad m => Monoid a => LP m a -> LP m a
parenWrapped :: forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
parenWrapped LP m a
parser = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'('
  forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill LP m a
parser (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
')')

dimenarg :: PandocMonad m => LP m Text
dimenarg :: forall (m :: * -> *). PandocMonad m => LP m Text
dimenarg = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall (m :: * -> *). PandocMonad m => LP m ()
sp
  Bool
ch  <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False forall a b. (a -> b) -> a -> b
$ Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'='
  Text
minus <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Text
"" forall a b. (a -> b) -> a -> b
$ Text
"-" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'-'
  Tok SourcePos
_ TokType
_ Text
s1 <- forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok
  Text
s2 <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Text
"" forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
          forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'.'
          Tok SourcePos
_ TokType
_ Text
t <-  forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok
          forall (m :: * -> *) a. Monad m => a -> m a
return (Text
"." forall a. Semigroup a => a -> a -> a
<> Text
t)
  let s :: Text
s = Text
s1 forall a. Semigroup a => a -> a -> a
<> Text
s2
  let (Text
num, Text
rest) = (Char -> Bool) -> Text -> (Text, Text)
T.span (\Char
c -> Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'.') Text
s
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
num forall a. Ord a => a -> a -> Bool
> Int
0
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Text
rest forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"", Text
"pt",Text
"pc",Text
"in",Text
"bp",Text
"cm",Text
"mm",Text
"dd",Text
"cc",Text
"sp"]
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Char] -> Text
T.pack [Char
'=' | Bool
ch] forall a. Semigroup a => a -> a -> a
<> Text
minus forall a. Semigroup a => a -> a -> a
<> Text
s

ignore :: (Monoid a, PandocMonad m) => Text -> ParsecT s u m a
ignore :: forall a (m :: * -> *) s u.
(Monoid a, PandocMonad m) =>
Text -> ParsecT s u m a
ignore Text
raw = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
SkippedContent Text
raw SourcePos
pos
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty

withRaw :: PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw :: forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw LP m a
parser = do
  IntMap [Tok]
rawTokensMap <- LaTeXState -> IntMap [Tok]
sRawTokens forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  let key :: Int
key = case forall a. IntMap a -> Maybe (Int, a)
IntMap.lookupMax IntMap [Tok]
rawTokensMap of
               Maybe (Int, [Tok])
Nothing     -> Int
0
               Just (Int
n,[Tok]
_)  -> Int
n forall a. Num a => a -> a -> a
+ Int
1
  -- insert empty list at key
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sRawTokens :: IntMap [Tok]
sRawTokens =
                             forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert Int
key [] forall a b. (a -> b) -> a -> b
$ LaTeXState -> IntMap [Tok]
sRawTokens LaTeXState
st }
  a
result <- LP m a
parser
  Maybe [Tok]
mbRevToks <- forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
key forall b c a. (b -> c) -> (a -> b) -> a -> c
. LaTeXState -> IntMap [Tok]
sRawTokens forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  [Tok]
raw <- case Maybe [Tok]
mbRevToks of
           Just [Tok]
revtoks -> do
             forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sRawTokens :: IntMap [Tok]
sRawTokens =
                                        forall a. Int -> IntMap a -> IntMap a
IntMap.delete Int
key forall a b. (a -> b) -> a -> b
$ LaTeXState -> IntMap [Tok]
sRawTokens LaTeXState
st}
             forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [Tok]
revtoks
           Maybe [Tok]
Nothing      ->
             forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocShouldNeverHappenError forall a b. (a -> b) -> a -> b
$
                Text
"sRawTokens has nothing at key " forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack (forall a. Show a => a -> [Char]
show Int
key)
  forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, [Tok]
raw)

keyval :: PandocMonad m => LP m (Text, Text)
keyval :: forall (m :: * -> *). PandocMonad m => LP m (Text, Text)
keyval = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  Text
key <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'=') forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                         (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'-' forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'_' forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok))
  forall (m :: * -> *). PandocMonad m => LP m ()
sp
  Text
val <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option forall a. Monoid a => a
mempty forall a b. (a -> b) -> a -> b
$ do
           forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'='
           forall (m :: * -> *). PandocMonad m => LP m ()
sp
           ([Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
             (forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (
                 ([Tok] -> Text
untokenize forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced)
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                 ([Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1
                      (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok
                         (\case
                                Tok SourcePos
_ TokType
Symbol Text
"]" -> Bool
False
                                Tok SourcePos
_ TokType
Symbol Text
"," -> Bool
False
                                Tok SourcePos
_ TokType
Symbol Text
"{" -> Bool
False
                                Tok SourcePos
_ TokType
Symbol Text
"}" -> Bool
False
                                Tok
_                -> Bool
True)))))
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
',')
  forall (m :: * -> *). PandocMonad m => LP m ()
sp
  forall (m :: * -> *) a. Monad m => a -> m a
return (Text
key, Text -> Text
T.strip Text
val)

keyvals :: PandocMonad m => LP m [(Text, Text)]
keyvals :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Text)]
keyvals = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'[' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m (Text, Text)
keyval (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
']') forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *). PandocMonad m => LP m ()
sp

verbEnv :: PandocMonad m => Text -> LP m Text
verbEnv :: forall (m :: * -> *). PandocMonad m => Text -> LP m Text
verbEnv Text
name = forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall (m :: * -> *). PandocMonad m => LP m ()
blankline
  [Tok]
res <- forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok (forall (m :: * -> *). PandocMonad m => Text -> LP m ()
end_ Text
name)
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text -> Text
stripTrailingNewline
         forall a b. (a -> b) -> a -> b
$ [Tok] -> Text
untokenize [Tok]
res

-- Strip single final newline and any spaces following it.
-- Input is unchanged if it doesn't end with newline +
-- optional spaces.
stripTrailingNewline :: Text -> Text
stripTrailingNewline :: Text -> Text
stripTrailingNewline Text
t =
  let (Text
b, Text
e) = Text -> Text -> (Text, Text)
T.breakOnEnd Text
"\n" Text
t
  in  if (Char -> Bool) -> Text -> Bool
T.all (forall a. Eq a => a -> a -> Bool
== Char
' ') Text
e
         then Int -> Text -> Text
T.dropEnd Int
1 Text
b
         else Text
t

begin_ :: PandocMonad m => Text -> LP m ()
begin_ :: forall (m :: * -> *). PandocMonad m => Text -> LP m ()
begin_ Text
t = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
  forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"begin"
  forall (m :: * -> *). PandocMonad m => LP m ()
spaces
  Text
txt <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text
t forall a. Eq a => a -> a -> Bool
== Text
txt)) forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> ([Char]
"\\begin{" forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t forall a. [a] -> [a] -> [a]
++ [Char]
"}")

end_ :: PandocMonad m => Text -> LP m ()
end_ :: forall (m :: * -> *). PandocMonad m => Text -> LP m ()
end_ Text
t = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
  forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"end"
  forall (m :: * -> *). PandocMonad m => LP m ()
spaces
  Text
txt <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Text
t forall a. Eq a => a -> a -> Bool
== Text
txt) forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> ([Char]
"\\end{" forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t forall a. [a] -> [a] -> [a]
++ [Char]
"}")

getRawCommand :: PandocMonad m => Text -> Text -> LP m Text
getRawCommand :: forall (m :: * -> *). PandocMonad m => Text -> Text -> LP m Text
getRawCommand Text
name Text
txt = do
  (()
_, [Tok]
rawargs) <- forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw forall a b. (a -> b) -> a -> b
$
      case Text
name of
           Text
"write" -> do
             forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Alternative f => f a -> f [a]
many forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isDigitTok -- digits
             forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"titleformat" -> do
             forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
             forall (m :: * -> *). PandocMonad m => LP m ()
skipopts
             forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
4 forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"def" ->
             forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"vadjust" ->
             forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isPreTok) -- see #7531
           Text
_ | Text -> Bool
isFontSizeCommand Text
name -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
             | Bool
otherwise -> do
               forall (m :: * -> *). PandocMonad m => LP m ()
skipopts
               forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Text
"" (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m Text
dimenarg)
               forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Alternative f => f a -> f [a]
many forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
txt forall a. Semigroup a => a -> a -> a
<> [Tok] -> Text
untokenize [Tok]
rawargs

isPreTok :: Tok -> Bool
isPreTok :: Tok -> Bool
isPreTok (Tok SourcePos
_ TokType
Word Text
"pre") = Bool
True
isPreTok Tok
_ = Bool
False

isDigitTok :: Tok -> Bool
isDigitTok :: Tok -> Bool
isDigitTok (Tok SourcePos
_ TokType
Word Text
t) = (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isDigit Text
t
isDigitTok Tok
_              = Bool
False

skipopts :: PandocMonad m => LP m ()
skipopts :: forall (m :: * -> *). PandocMonad m => LP m ()
skipopts = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). PandocMonad m => LP m Text
overlaySpecification forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). PandocMonad m => LP m Text
rawopt)

-- opts in angle brackets are used in beamer
overlaySpecification :: PandocMonad m => LP m Text
overlaySpecification :: forall (m :: * -> *). PandocMonad m => LP m Text
overlaySpecification = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'<'
  Text
t <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill forall (m :: * -> *). PandocMonad m => LP m Tok
overlayTok (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'>')
  -- see issue #3368
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not ((Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isLetter Text
t) Bool -> Bool -> Bool
||
          Text
t forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"beamer",Text
"presentation", Text
"trans",
                    Text
"handout",Text
"article", Text
"second"]
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<" forall a. Semigroup a => a -> a -> a
<> Text
t forall a. Semigroup a => a -> a -> a
<> Text
">"

overlayTok :: PandocMonad m => LP m Tok
overlayTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
overlayTok =
  forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\case
                    Tok SourcePos
_ TokType
Word Text
_       -> Bool
True
                    Tok SourcePos
_ TokType
Spaces Text
_     -> Bool
True
                    Tok SourcePos
_ TokType
Symbol Text
c     -> Text
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"-",Text
"+",Text
"@",Text
"|",Text
":",Text
","]
                    Tok
_                  -> Bool
False)

rawopt :: PandocMonad m => LP m Text
rawopt :: forall (m :: * -> *). PandocMonad m => LP m Text
rawopt = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *). PandocMonad m => LP m ()
sp
  Text
inner <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
  forall (m :: * -> *). PandocMonad m => LP m ()
sp
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"[" forall a. Semigroup a => a -> a -> a
<> Text
inner forall a. Semigroup a => a -> a -> a
<> Text
"]"

isFontSizeCommand :: Text -> Bool
isFontSizeCommand :: Text -> Bool
isFontSizeCommand Text
"tiny" = Bool
True
isFontSizeCommand Text
"scriptsize" = Bool
True
isFontSizeCommand Text
"footnotesize" = Bool
True
isFontSizeCommand Text
"small" = Bool
True
isFontSizeCommand Text
"normalsize" = Bool
True
isFontSizeCommand Text
"large" = Bool
True
isFontSizeCommand Text
"Large" = Bool
True
isFontSizeCommand Text
"LARGE" = Bool
True
isFontSizeCommand Text
"huge" = Bool
True
isFontSizeCommand Text
"Huge" = Bool
True
isFontSizeCommand Text
_ = Bool
False

getNextNumber :: Monad m
              => (LaTeXState -> DottedNum) -> LP m DottedNum
getNextNumber :: forall (m :: * -> *).
Monad m =>
(LaTeXState -> DottedNum) -> LP m DottedNum
getNextNumber LaTeXState -> DottedNum
getCurrentNum = do
  LaTeXState
st <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  let chapnum :: Maybe Int
chapnum =
        case LaTeXState -> DottedNum
sLastHeaderNum LaTeXState
st of
             DottedNum (Int
n:[Int]
_) | LaTeXState -> Bool
sHasChapters LaTeXState
st -> forall a. a -> Maybe a
Just Int
n
             DottedNum
_                                 -> forall a. Maybe a
Nothing
  forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> DottedNum
DottedNum forall a b. (a -> b) -> a -> b
$
    case LaTeXState -> DottedNum
getCurrentNum LaTeXState
st of
       DottedNum [Int
m,Int
n]  ->
         case Maybe Int
chapnum of
              Just Int
m' | Int
m' forall a. Eq a => a -> a -> Bool
== Int
m   -> [Int
m, Int
nforall a. Num a => a -> a -> a
+Int
1]
                      | Bool
otherwise -> [Int
m', Int
1]
              Maybe Int
Nothing             -> [Int
1]
                                      -- shouldn't happen
       DottedNum [Int
n]   ->
         case Maybe Int
chapnum of
              Just Int
m  -> [Int
m, Int
1]
              Maybe Int
Nothing -> [Int
n forall a. Num a => a -> a -> a
+ Int
1]
       DottedNum
_               ->
         case Maybe Int
chapnum of
               Just Int
n  -> [Int
n, Int
1]
               Maybe Int
Nothing -> [Int
1]

label :: PandocMonad m => LP m ()
label :: forall (m :: * -> *). PandocMonad m => LP m ()
label = do
  forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"label"
  [Tok]
t <- forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sLastLabel :: Maybe Text
sLastLabel = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ [Tok] -> Text
untokenize [Tok]
t }

setCaption :: PandocMonad m => LP m Inlines -> LP m ()
setCaption :: forall (m :: * -> *). PandocMonad m => LP m Inlines -> LP m ()
setCaption LP m Inlines
inline = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
  Maybe [Inline]
mbshort <- forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Many a -> [a]
toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
bracketed LP m Inlines
inline forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
  Inlines
ils <- forall (m :: * -> *). PandocMonad m => LP m Inlines -> LP m Inlines
tokWith LP m Inlines
inline
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). PandocMonad m => LP m ()
label
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sCaption :: Maybe Caption
sCaption = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
                              Maybe [Inline] -> [Block] -> Caption
Caption Maybe [Inline]
mbshort [[Inline] -> Block
Plain forall a b. (a -> b) -> a -> b
$ forall a. Many a -> [a]
toList Inlines
ils] }

resetCaption :: PandocMonad m => LP m ()
resetCaption :: forall (m :: * -> *). PandocMonad m => LP m ()
resetCaption = forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sCaption :: Maybe Caption
sCaption   = forall a. Maybe a
Nothing
                                      , sLastLabel :: Maybe Text
sLastLabel = forall a. Maybe a
Nothing }

env :: PandocMonad m => Text -> LP m a -> LP m a
env :: forall (m :: * -> *) a. PandocMonad m => Text -> LP m a -> LP m a
env Text
name LP m a
p = do
  -- environments are groups as far as macros are concerned,
  -- so we need a local copy of the macro table (see above, bgroup, egroup):
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s -> LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall a. a -> NonEmpty a -> NonEmpty a
NonEmpty.cons (forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s))
                                                 (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) }
  a
result <- LP m a
p
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s -> LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall a. a -> Maybe a -> a
fromMaybe (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) forall a b. (a -> b) -> a -> b
$
      forall a. [a] -> Maybe (NonEmpty a)
NonEmpty.nonEmpty (forall a. NonEmpty a -> [a]
NonEmpty.tail (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s)) }
  forall (m :: * -> *). PandocMonad m => Text -> LP m ()
end_ Text
name
  forall (m :: * -> *) a. Monad m => a -> m a
return a
result

tokWith :: PandocMonad m => LP m Inlines -> LP m Inlines
tokWith :: forall (m :: * -> *). PandocMonad m => LP m Inlines -> LP m Inlines
tokWith LP m Inlines
inlineParser = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                                 forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
grouped LP m Inlines
inlineParser
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LP m Inlines
inlineParser)
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LP m Inlines
singleChar'
  where singleChar' :: LP m Inlines
singleChar' = do
          Tok SourcePos
_ TokType
_ Text
t <- forall (m :: * -> *). PandocMonad m => LP m Tok
singleChar
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text -> Inlines
str Text
t

addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> LP m ()
addMeta :: forall (m :: * -> *) a.
(PandocMonad m, ToMetaValue a) =>
Text -> a -> LP m ()
addMeta Text
field a
val = forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
st ->
   LaTeXState
st{ sMeta :: Meta
sMeta = forall a. ToMetaValue a => Text -> a -> Meta -> Meta
addMetaField Text
field a
val forall a b. (a -> b) -> a -> b
$ LaTeXState -> Meta
sMeta LaTeXState
st }

-- remove label spans to avoid duplicated identifier
removeLabel :: Walkable [Inline] a => Text -> a -> a
removeLabel :: forall a. Walkable [Inline] a => Text -> a -> a
removeLabel Text
lbl = forall a b. Walkable a b => (a -> a) -> b -> b
walk [Inline] -> [Inline]
go
 where
  go :: [Inline] -> [Inline]
go (Span (Text
_,[Text]
_,[(Text, Text)]
kvs) [Inline]
_ : [Inline]
rest)
    | Just Text
lbl' <- forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"label" [(Text, Text)]
kvs
    , Text
lbl' forall a. Eq a => a -> a -> Bool
== Text
lbl = [Inline] -> [Inline]
go (forall a. (a -> Bool) -> [a] -> [a]
dropWhile Inline -> Bool
isSpaceOrSoftBreak [Inline]
rest)
  go (Inline
x:[Inline]
xs) = Inline
x forall a. a -> [a] -> [a]
: [Inline] -> [Inline]
go [Inline]
xs
  go [] = []
  isSpaceOrSoftBreak :: Inline -> Bool
isSpaceOrSoftBreak Inline
Space = Bool
True
  isSpaceOrSoftBreak Inline
SoftBreak = Bool
True
  isSpaceOrSoftBreak Inline
_ = Bool
False