{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{- |
   Module      : Text.Pandoc.Readers.LaTeX.Parsing
   Copyright   : Copyright (C) 2006-2024 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
  , LaTeXEnv(..)
  , emptyLaTeXEnv
  , askEnv
  , 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
  , verbTok
  , 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.Reader (ReaderT, ask, runReaderT)
import Control.Monad.Trans (lift)
import Data.Char (chr, isAlphaNum, isDigit, isLetter, ord)
import Data.Default
import Data.List (dropWhileEnd, intercalate, isSuffixOf, unfoldr)
import Numeric (showEFloat, showFFloat)
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))
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]
(Int -> DottedNum -> ShowS)
-> (DottedNum -> [Char])
-> ([DottedNum] -> ShowS)
-> Show DottedNum
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DottedNum -> ShowS
showsPrec :: Int -> DottedNum -> ShowS
$cshow :: DottedNum -> [Char]
show :: DottedNum -> [Char]
$cshowList :: [DottedNum] -> ShowS
showList :: [DottedNum] -> ShowS
Show, DottedNum -> DottedNum -> Bool
(DottedNum -> DottedNum -> Bool)
-> (DottedNum -> DottedNum -> Bool) -> Eq DottedNum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DottedNum -> DottedNum -> Bool
== :: DottedNum -> DottedNum -> Bool
$c/= :: DottedNum -> DottedNum -> Bool
/= :: DottedNum -> DottedNum -> Bool
Eq)

renderDottedNum :: DottedNum -> T.Text
renderDottedNum :: DottedNum -> Text
renderDottedNum (DottedNum [Int]
xs) = [Char] -> Text
T.pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$
  [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"." ((Int -> [Char]) -> [Int] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Int -> [Char]
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 ([Int] -> DottedNum) -> [Int] -> DottedNum
forall a b. (a -> b) -> a -> b
$
  case [Int] -> [Int]
forall a. [a] -> [a]
reverse (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
level ([Int]
ns [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
0)) of
       (Int
x:[Int]
xs) -> [Int] -> [Int]
forall a. [a] -> [a]
reverse (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Int]
xs)
       []     -> []  -- shouldn't happen

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

data TheoremSpec =
  TheoremSpec
    { TheoremSpec -> [Tok]
theoremName    :: [Tok]
    , 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]
(Int -> TheoremSpec -> ShowS)
-> (TheoremSpec -> [Char])
-> ([TheoremSpec] -> ShowS)
-> Show TheoremSpec
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TheoremSpec -> ShowS
showsPrec :: Int -> TheoremSpec -> ShowS
$cshow :: TheoremSpec -> [Char]
show :: TheoremSpec -> [Char]
$cshowList :: [TheoremSpec] -> ShowS
showList :: [TheoremSpec] -> ShowS
Show, TheoremSpec -> TheoremSpec -> Bool
(TheoremSpec -> TheoremSpec -> Bool)
-> (TheoremSpec -> TheoremSpec -> Bool) -> Eq TheoremSpec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TheoremSpec -> TheoremSpec -> Bool
== :: TheoremSpec -> TheoremSpec -> Bool
$c/= :: TheoremSpec -> TheoremSpec -> Bool
/= :: 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 -> Bool
sMathMode      :: 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 Int Blocks
sFootnoteTexts :: M.Map Int Blocks
                            , 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 -> [Tok]
sRawTokens     :: [Tok]
                              -- ^ reversed list of tokens consumed
                              -- while at least one withRaw scope is
                              -- active
                            , LaTeXState -> Int
sRawTokenCount :: !Int
                              -- ^ length of sRawTokens
                            , LaTeXState -> Int
sRawScopes     :: !Int
                              -- ^ number of active withRaw scopes
                            , LaTeXState -> Bool
sLigatures     :: Bool
                            , LaTeXState -> Map Text (Set Text)
sCaseExclusions :: M.Map Text (Set.Set Text)
                              -- ^ words excluded from case changing
                              -- (keys: @upper@, @lower@, @title@)
                            , LaTeXState -> Maybe (Text, SourcePos, Int)
sLastExpansion :: Maybe (Text, SourcePos, Int)
                              -- ^ name and position of the last macro
                              -- expanded, and the number of consecutive
                              -- times it has been expanded there
                              -- (used to detect expansion loops)
                            }
     deriving Int -> LaTeXState -> ShowS
[LaTeXState] -> ShowS
LaTeXState -> [Char]
(Int -> LaTeXState -> ShowS)
-> (LaTeXState -> [Char])
-> ([LaTeXState] -> ShowS)
-> Show LaTeXState
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LaTeXState -> ShowS
showsPrec :: Int -> LaTeXState -> ShowS
$cshow :: LaTeXState -> [Char]
show :: LaTeXState -> [Char]
$cshowList :: [LaTeXState] -> ShowS
showList :: [LaTeXState] -> ShowS
Show

defaultLaTeXState :: LaTeXState
defaultLaTeXState :: LaTeXState
defaultLaTeXState = LaTeXState{ sOptions :: ReaderOptions
sOptions       = ReaderOptions
forall a. Default a => a
def
                              , sMeta :: Meta
sMeta          = Meta
nullMeta
                              , sQuoteContext :: QuoteContext
sQuoteContext  = QuoteContext
NoQuote
                              , sMacros :: NonEmpty (Map Text Macro)
sMacros        = Map Text Macro
forall k a. Map k a
M.empty Map Text Macro -> [Map Text Macro] -> NonEmpty (Map Text Macro)
forall a. a -> [a] -> NonEmpty a
:| []
                              , sContainers :: [Text]
sContainers    = []
                              , sLogMessages :: [LogMessage]
sLogMessages   = []
                              , sIdentifiers :: Set Text
sIdentifiers   = Set Text
forall a. Set a
Set.empty
                              , sVerbatimMode :: Bool
sVerbatimMode  = Bool
False
                              , sMathMode :: Bool
sMathMode      = Bool
False
                              , sCaption :: Maybe Caption
sCaption       = Maybe Caption
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
                              , sFootnoteTexts :: Map Int Blocks
sFootnoteTexts = Map Int Blocks
forall k a. Map k a
M.empty
                              , sTheoremMap :: Map Text TheoremSpec
sTheoremMap    = Map Text TheoremSpec
forall k a. Map k a
M.empty
                              , sLastTheoremStyle :: TheoremStyle
sLastTheoremStyle = TheoremStyle
PlainStyle
                              , sLastLabel :: Maybe Text
sLastLabel     = Maybe Text
forall a. Maybe a
Nothing
                              , sLabels :: Map Text [Inline]
sLabels        = Map Text [Inline]
forall k a. Map k a
M.empty
                              , sHasChapters :: Bool
sHasChapters   = Bool
False
                              , sToggles :: Map Text Bool
sToggles       = Map Text Bool
forall k a. Map k a
M.empty
                              , sFileContents :: Map Text Text
sFileContents  = Map Text Text
forall k a. Map k a
M.empty
                              , sEnableWithRaw :: Bool
sEnableWithRaw = Bool
True
                              , sRawTokens :: [Tok]
sRawTokens     = []
                              , sRawTokenCount :: Int
sRawTokenCount = Int
0
                              , sRawScopes :: Int
sRawScopes     = Int
0
                              , sLigatures :: Bool
sLigatures     = Bool
True
                              , sCaseExclusions :: Map Text (Set Text)
sCaseExclusions = Map Text (Set Text)
forall k a. Map k a
M.empty
                              , sLastExpansion :: Maybe (Text, SourcePos, Int)
sLastExpansion = Maybe (Text, SourcePos, Int)
forall a. Maybe a
Nothing
                              }

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

instance HasLogMessages LaTeXState where
  addLogMessage :: LogMessage -> LaTeXState -> LaTeXState
addLogMessage LogMessage
msg LaTeXState
st = LaTeXState
st{ sLogMessages = msg : sLogMessages st }
  getLogMessages :: LaTeXState -> [LogMessage]
getLogMessages LaTeXState
st = [LogMessage] -> [LogMessage]
forall a. [a] -> [a]
reverse ([LogMessage] -> [LogMessage]) -> [LogMessage] -> [LogMessage]
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 = f $ sIdentifiers st }

instance HasIncludeFiles LaTeXState where
  getIncludeFiles :: LaTeXState -> [Text]
getIncludeFiles = LaTeXState -> [Text]
sContainers
  addIncludeFile :: Text -> LaTeXState -> LaTeXState
addIncludeFile Text
f LaTeXState
s = LaTeXState
s{ sContainers = f : sContainers s }
  dropLatestIncludeFile :: LaTeXState -> LaTeXState
dropLatestIncludeFile LaTeXState
s = LaTeXState
s { sContainers = drop 1 $ sContainers s }

instance HasMacros LaTeXState where
  extractMacros :: LaTeXState -> Map Text Macro
extractMacros  LaTeXState
st  = NonEmpty (Map Text Macro) -> Map Text Macro
forall a. NonEmpty a -> a
NonEmpty.head (NonEmpty (Map Text Macro) -> Map Text Macro)
-> NonEmpty (Map Text Macro) -> Map Text Macro
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 = f (NonEmpty.head (sMacros st))
                                     :| NonEmpty.tail (sMacros 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 = setMeta field val $ sMeta st }
  deleteMeta :: Text -> LaTeXState -> LaTeXState
deleteMeta Text
field LaTeXState
st =
    LaTeXState
st{ sMeta = deleteMeta field $ sMeta 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]
(Int -> TokStream -> ShowS)
-> (TokStream -> [Char])
-> ([TokStream] -> ShowS)
-> Show TokStream
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TokStream -> ShowS
showsPrec :: Int -> TokStream -> ShowS
$cshow :: TokStream -> [Char]
show :: TokStream -> [Char]
$cshowList :: [TokStream] -> ShowS
showList :: [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 [Tok] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Tok]
ts1 then Bool
exp2 else Bool
exp1) ([Tok]
ts1 [Tok] -> [Tok] -> [Tok]
forall a. Semigroup a => a -> a -> a
<> [Tok]
ts2)

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

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

type LP m = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m)

-- | Environment holding the command dispatch tables.  Because these
-- tables have types that mention the parser monad, they cannot be
-- top-level constants; passing them in a reader environment ensures
-- they are constructed once per parse rather than once per use.
data LaTeXEnv m = LaTeXEnv
  { forall (m :: * -> *). LaTeXEnv m -> Map Text (LP m Inlines)
envInlineCommands :: M.Map Text (LP m Inlines)
  , forall (m :: * -> *). LaTeXEnv m -> Map Text (LP m Blocks)
envBlockCommands  :: M.Map Text (LP m Blocks)
  , forall (m :: * -> *). LaTeXEnv m -> Map Text (LP m Blocks)
envEnvironments   :: M.Map Text (LP m Blocks)
  }

-- | An environment with empty dispatch tables, for running parsers
-- that do not consult them.
emptyLaTeXEnv :: LaTeXEnv m
emptyLaTeXEnv :: forall (m :: * -> *). LaTeXEnv m
emptyLaTeXEnv = Map Text (LP m Inlines)
-> Map Text (LP m Blocks) -> Map Text (LP m Blocks) -> LaTeXEnv m
forall (m :: * -> *).
Map Text (LP m Inlines)
-> Map Text (LP m Blocks) -> Map Text (LP m Blocks) -> LaTeXEnv m
LaTeXEnv Map Text (LP m Inlines)
forall a. Monoid a => a
mempty Map Text (LP m Blocks)
forall a. Monoid a => a
mempty Map Text (LP m Blocks)
forall a. Monoid a => a
mempty

-- | Retrieve the command dispatch tables.
askEnv :: Monad m => LP m (LaTeXEnv m)
askEnv :: forall (m :: * -> *). Monad m => LP m (LaTeXEnv m)
askEnv = ReaderT (LaTeXEnv m) m (LaTeXEnv m)
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (LaTeXEnv m)
forall (m :: * -> *) a.
Monad m =>
m a -> ParsecT TokStream LaTeXState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT (LaTeXEnv m) m (LaTeXEnv m)
forall r (m :: * -> *). MonadReader r m => m r
ask

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
  alreadyVerbatimMode <- LaTeXState -> Bool
sVerbatimMode (LaTeXState -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  if alreadyVerbatimMode
     then parser
     else do
       updateState $ \LaTeXState
st -> LaTeXState
st{ sVerbatimMode = True }
       result <- parser
       updateState $ \LaTeXState
st -> LaTeXState
st{ sVerbatimMode = False }
       return result

rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s, Show a)
               => LaTeXEnv m -> [Tok] -> LP m () -> LP m a
               -> ParsecT Sources s m (a, Text)
rawLaTeXParser :: forall (m :: * -> *) s a.
(PandocMonad m, HasMacros s, HasReaderOptions s, Show a) =>
LaTeXEnv m
-> [Tok] -> LP m () -> LP m a -> ParsecT Sources s m (a, Text)
rawLaTeXParser LaTeXEnv m
lenv [Tok]
toks LP m ()
parser LP m a
valParser = do
  pstate <- ParsecT Sources s m s
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  let lstate = LaTeXState
forall a. Default a => a
def{ sOptions = extractReaderOptions pstate }
  let lstate' = LaTeXState
lstate { sMacros = extractMacros pstate :| [] }
  let setStartPos = case [Tok]
toks of
                      Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> SourcePos -> ParsecT s u (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
                      [Tok]
_ -> () -> ParsecT s u (ReaderT (LaTeXEnv m) m) ()
forall a. a -> ParsecT s u (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  let preparser = LP m ()
forall {s} {u}. ParsecT s u (ReaderT (LaTeXEnv m) m) ()
setStartPos LP m () -> LP m () -> LP m ()
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LP m ()
parser
  let rawparser = (,) ((a, [Tok]) -> LaTeXState -> ((a, [Tok]), LaTeXState))
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (a, [Tok])
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv m) m)
     (LaTeXState -> ((a, [Tok]), LaTeXState))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (a, [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw LP m a
valParser ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv m) m)
  (LaTeXState -> ((a, [Tok]), LaTeXState))
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv m) m)
     ((a, [Tok]), LaTeXState)
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (a -> b)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  res' <- lift $ flip runReaderT lenv $
                 runParserT (withRaw (preparser >> getPosition))
                            lstate "chunk" $ TokStream False toks
  case res' of
       Left ParseError
_    -> ParsecT Sources s m (a, Text)
forall a. ParsecT Sources s m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
       Right (SourcePos
endpos, [Tok]
toks') -> do
         res <- m (Either ParseError ((a, [Tok]), LaTeXState))
-> ParsecT Sources s m (Either ParseError ((a, [Tok]), LaTeXState))
forall (m :: * -> *) a. Monad m => m a -> ParsecT Sources s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either ParseError ((a, [Tok]), LaTeXState))
 -> ParsecT
      Sources s m (Either ParseError ((a, [Tok]), LaTeXState)))
-> m (Either ParseError ((a, [Tok]), LaTeXState))
-> ParsecT Sources s m (Either ParseError ((a, [Tok]), LaTeXState))
forall a b. (a -> b) -> a -> b
$ (ReaderT
   (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
 -> LaTeXEnv m -> m (Either ParseError ((a, [Tok]), LaTeXState)))
-> LaTeXEnv m
-> ReaderT
     (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
-> m (Either ParseError ((a, [Tok]), LaTeXState))
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
-> LaTeXEnv m -> m (Either ParseError ((a, [Tok]), LaTeXState))
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT LaTeXEnv m
lenv (ReaderT
   (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
 -> m (Either ParseError ((a, [Tok]), LaTeXState)))
-> ReaderT
     (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
-> m (Either ParseError ((a, [Tok]), LaTeXState))
forall a b. (a -> b) -> a -> b
$
                       ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv m) m)
  ((a, [Tok]), LaTeXState)
-> LaTeXState
-> [Char]
-> TokStream
-> ReaderT
     (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
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
  (ReaderT (LaTeXEnv m) m)
  ((a, [Tok]), LaTeXState)
rawparser LaTeXState
lstate' [Char]
"chunk"
                     (TokStream
 -> ReaderT
      (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState)))
-> TokStream
-> ReaderT
     (LaTeXEnv m) m (Either ParseError ((a, [Tok]), LaTeXState))
forall a b. (a -> b) -> a -> b
$ Bool -> [Tok] -> TokStream
TokStream Bool
False [Tok]
toks'
         case res of
              Left ParseError
_    -> ParsecT Sources s m (a, Text)
forall a. ParsecT Sources s m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
              Right ((a
val, [Tok]
raw), LaTeXState
st) -> do
                (s -> s) -> ParsecT Sources s m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((Map Text Macro -> Map Text Macro) -> s -> s
forall st.
HasMacros st =>
(Map Text Macro -> Map Text Macro) -> st -> st
updateMacros ((NonEmpty (Map Text Macro) -> Map Text Macro
forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
st)) Map Text Macro -> Map Text Macro -> Map Text Macro
forall a. Semigroup a => a -> a -> a
<>))
                let rawChar :: ParsecT Sources u m Char
rawChar = do
                      pos <- ParsecT Sources u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                      if pos >= endpos
                         then mzero
                         else anyChar
                result <- (Extension -> ParsecT Sources s m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardEnabled Extension
Ext_latex_macros
                             ParsecT Sources s m ()
-> ParsecT Sources s m Text -> ParsecT Sources s m Text
forall a b.
ParsecT Sources s m a
-> ParsecT Sources s m b -> ParsecT Sources s m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ([Tok] -> Text
untokenize [Tok]
raw Text -> ParsecT Sources s m () -> ParsecT Sources s m Text
forall a b. a -> ParsecT Sources s m b -> ParsecT Sources s m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Sources s m Char -> ParsecT Sources s m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Sources s m Char
forall {u}. ParsecT Sources u m Char
rawChar))
                          ParsecT Sources s m Text
-> ParsecT Sources s m Text -> ParsecT Sources s m Text
forall a.
ParsecT Sources s m a
-> ParsecT Sources s m a -> ParsecT Sources s m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Char] -> Text
T.pack ([Char] -> Text)
-> ParsecT Sources s m [Char] -> ParsecT Sources s m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources s m Char -> ParsecT Sources s m [Char]
forall a. ParsecT Sources s m a -> ParsecT Sources s m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT Sources s m Char
forall {u}. ParsecT Sources u m Char
rawChar
                -- ensure we end with space if input did, see #4442
                let result' =
                      case [Tok] -> [Tok]
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 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
                        [Tok]
_ -> Text
result
                return (val, 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 = (Extension -> ParsecT Sources s m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardDisabled Extension
Ext_latex_macros ParsecT Sources s m ()
-> ParsecT Sources s m Text -> ParsecT Sources s m Text
forall a b.
ParsecT Sources s m a
-> ParsecT Sources s m b -> ParsecT Sources s m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> ParsecT Sources s m Text
forall a. a -> ParsecT Sources s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
s) ParsecT Sources s m Text
-> ParsecT Sources s m Text -> ParsecT Sources s m Text
forall a.
ParsecT Sources s m a
-> ParsecT Sources s m a -> ParsecT Sources s m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
   do let retokenize :: ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
  Text
retokenize = [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
     [Tok]
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
     Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
  Tok
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
     [Tok]
forall a.
ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
  a
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
     [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT
  TokStream
  LaTeXState
  (ReaderT (LaTeXEnv (ParsecT Sources s m)) (ParsecT Sources s m))
  Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
      pstate <- ParsecT Sources s m s
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      let lstate = LaTeXState
forall a. Default a => a
def{ sOptions = extractReaderOptions pstate
                      , sMacros  = extractMacros pstate :| [] }
      res <- flip runReaderT emptyLaTeXEnv $
                 runParserT retokenize lstate "math" $
                 TokStream False (tokenize (initialPos "math") s)
      case res of
           Left ParseError
e   -> [Char] -> ParsecT Sources s m Text
forall a. [Char] -> ParsecT Sources s m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail (ParseError -> [Char]
forall a. Show a => a -> [Char]
show ParseError
e)
           Right Text
s' -> Text -> ParsecT Sources s m Text
forall a. a -> ParsecT Sources s m a
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 = ((SourcePos, Text) -> [Tok]) -> [(SourcePos, Text)] -> [Tok]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (SourcePos, Text) -> [Tok]
tokenizeSource ([(SourcePos, Text)] -> [Tok])
-> (Sources -> [(SourcePos, Text)]) -> Sources -> [Tok]
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
  pos <- ParsecT Sources s m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  ss <- getInput
  return $
    case ss of
      Sources [] -> []
      Sources ((SourcePos
_,Text
t):[(SourcePos, Text)]
rest) -> Sources -> [Tok]
tokenizeSources (Sources -> [Tok]) -> Sources -> [Tok]
forall a b. (a -> b) -> a -> b
$ [(SourcePos, Text)] -> Sources
Sources ((SourcePos
pos,Text
t)(SourcePos, Text) -> [(SourcePos, Text)] -> [(SourcePos, Text)]
forall a. a -> [a] -> [a]
:[(SourcePos, Text)]
rest)

tokenize :: SourcePos -> Text -> [Tok]
tokenize :: SourcePos -> Text -> [Tok]
tokenize = TokenizerState -> SourcePos -> Text -> [Tok]
totoks (Bool -> Bool -> TokenizerState
TokenizerState Bool
False Bool
False)
 where
  totoks :: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter 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 Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' ->
           SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Newline Text
"\n"
           Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (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
               Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (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
               Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Text -> Int
T.length Text
ws)) Text
rest'
         | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'%' ->
           let (Text
cs, Text
rest') = (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n') Text
rest
           in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Comment (Text
"%" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
cs)
               Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
cs)) Text
rest'
         | Char
c Char -> Char -> Bool
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')
                  | TokenizerState -> Char -> Bool
isLetter' TokenizerState
atIsLetter Char
d ->
                      let (Text
ws, Text
rest'') = (Char -> Bool) -> Text -> (Text, Text)
T.span (TokenizerState -> Char -> Bool
isLetter' TokenizerState
atIsLetter) Text
rest
                          (Text
ss, Text
rest''') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isSpaceOrTab Text
rest''
                          atIsLetter' :: TokenizerState
atIsLetter' =
                            case Text
ws of
                              Text
"makeatletter" ->
                                TokenizerState
atIsLetter{ tsAtIsLetter = True }
                              Text
"makeatother" ->
                                TokenizerState
atIsLetter{ tsAtIsLetter = False }
                              Text
"ExplSyntaxOn" ->
                                TokenizerState
atIsLetter{ tsExplSyntax = True }
                              Text
"ExplSyntaxOff" ->
                                TokenizerState
atIsLetter{ tsExplSyntax = False }
                              Text
_ -> TokenizerState
atIsLetter
                      in  SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
ws) (Text
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ws Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ss)
                          Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter' (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos
                               (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
T.length Text
ws Int -> Int -> Int
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 Char -> Char -> Bool
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)
_ -> (Text
forall a. Monoid a => a
mempty, (Text
forall a. Monoid a => a
mempty, Text
r1))
                          ws :: Text
ws = Text
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
w1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
w2 Text -> Text -> Text
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
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
w1)
                                 Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                                    (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
                                 Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                                    (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])
                      Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
2) Text
rest'
         | Char
c Char -> Char -> Bool
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 Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
d Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9') Text
t3
               in  case Text -> Maybe Int
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
"##" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t1)
                           Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                              (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
2 Int -> Int -> Int
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
"#"
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) TokType
Symbol Text
"#"
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
2) Text
t3
             Maybe (Char, Text)
_ ->
               let (Text
t1, Text
t2) = (Char -> Bool) -> Text -> (Text, Text)
T.span (\Char
d -> Char
d Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
d Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9') Text
rest
               in  case Text -> Maybe Int
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
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t1)
                           Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                               (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos (Int
1 Int -> Int -> Int
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
"#"
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) Text
rest
         | Char
c Char -> Char -> Bool
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])
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                                     (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])
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                                      (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
3) Text
rest''
                         | Char
d Char -> Char -> Bool
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])
                                  Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter
                                     (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
3) Text
rest''
                       Maybe (Char, Text)
_ -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"^" Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:
                            SourcePos -> TokType -> Text -> Tok
Tok (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) TokType
Symbol Text
"^" Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:
                            TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
2) Text
rest'
                Maybe (Char, Text)
_ -> SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"^"
                     Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (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) Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:
             TokenizerState -> SourcePos -> Text -> [Tok]
totoks TokenizerState
atIsLetter (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

-- | State threaded through the tokenizer: whether @\@@ is a letter
-- (between @\makeatletter@ and @\makeatother@), and whether @:@ and
-- @_@ are letters (between @\ExplSyntaxOn@ and @\ExplSyntaxOff@).
data TokenizerState = TokenizerState
  { TokenizerState -> Bool
tsAtIsLetter :: Bool
  , TokenizerState -> Bool
tsExplSyntax :: Bool
  }

isLetter' :: TokenizerState -> Char -> Bool
isLetter' :: TokenizerState -> Char -> Bool
isLetter' TokenizerState
st Char
'@' = TokenizerState -> Bool
tsAtIsLetter TokenizerState
st
isLetter' TokenizerState
st Char
':' = TokenizerState -> Bool
tsExplSyntax TokenizerState
st
isLetter' TokenizerState
st Char
'_' = TokenizerState -> Bool
tsExplSyntax TokenizerState
st
isLetter' TokenizerState
_ Char
c = Char -> Bool
isLetter Char
c

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 Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9' Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'f'

untokenize :: [Tok] -> Text
untokenize :: [Tok] -> Text
untokenize = [Text] -> Text
T.concat ([Text] -> Text) -> ([Tok] -> [Text]) -> [Tok] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tok] -> [Text]
go
  where
    go :: [Tok] -> [Text]
go [] = []
    go (Tok SourcePos
_ (CtrlSeq Text
_) Text
t : [Tok]
ts)
      -- insert space to prevent breaking a control sequence; see #5836
      | Just (Text
_, Char
c) <- Text -> Maybe (Text, Char)
T.unsnoc Text
t
      , Char -> Bool
isLetter Char
c
      , [Tok] -> Bool
nextStartsWithLetter [Tok]
ts = Text
t Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text
" " Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Tok] -> [Text]
go [Tok]
ts
    go (Tok SourcePos
_ TokType
_ Text
t : [Tok]
ts) = Text
t Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Tok] -> [Text]
go [Tok]
ts
    nextStartsWithLetter :: [Tok] -> Bool
nextStartsWithLetter (Tok SourcePos
_ TokType
_ Text
t : [Tok]
ts) =
      case Text -> Maybe (Char, Text)
T.uncons Text
t of
        Just (Char
d, Text
_) -> Char -> Bool
isLetter Char
d
        Maybe (Char, Text)
Nothing     -> [Tok] -> Bool
nextStartsWithLetter [Tok]
ts
    nextStartsWithLetter [] = Bool
False

untoken :: Tok -> Text
untoken :: Tok -> Text
untoken (Tok SourcePos
_ TokType
_ Text
t) = Text
t

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
  oldInput <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) TokStream
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  setInput $ TokStream False toks
  oldpos <- getPosition
  case toks of
     Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> SourcePos
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
     [Tok]
_ -> () -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  -- we ignore existing raw token accumulation (see #9517)
  oldst <- getState
  updateState $ \LaTeXState
st -> LaTeXState
st{ sRawTokens = []
                         , sRawTokenCount = 0
                         , sRawScopes = 0 }
  result <- parser
  updateState $ \LaTeXState
st -> LaTeXState
st{ sRawTokens = sRawTokens oldst
                         , sRawTokenCount = sRawTokenCount oldst
                         , sRawScopes = sRawScopes oldst }
  setInput oldInput
  setPosition oldpos
  return 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
  oldEnableWithRaw <- LaTeXState -> Bool
sEnableWithRaw (LaTeXState -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  updateState $ \LaTeXState
st -> LaTeXState
st{ sEnableWithRaw = False }
  result <- parser
  updateState $ \LaTeXState
st -> LaTeXState
st{ sEnableWithRaw = oldEnableWithRaw }
  return result

satisfyTok :: PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok :: forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
f = do
    LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
doMacros -- apply macros on remaining input stream
    res <- (Tok -> [Char])
-> (SourcePos -> Tok -> TokStream -> SourcePos)
-> (Tok -> Maybe Tok)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 (Text -> [Char]) -> (Tok -> Text) -> Tok -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tok -> Text
untoken) SourcePos -> Tok -> TokStream -> SourcePos
updatePos Tok -> Maybe Tok
matcher
    updateState $ \LaTeXState
st ->
      if LaTeXState -> Int
sRawScopes LaTeXState
st Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& LaTeXState -> Bool
sEnableWithRaw LaTeXState
st
         then LaTeXState
st{ sRawTokens = res : sRawTokens st
                , sRawTokenCount = sRawTokenCount st + 1 }
         else LaTeXState
st
    return $! res
  where matcher :: Tok -> Maybe Tok
matcher Tok
t | Tok -> Bool
f Tok
t       = Tok -> Maybe Tok
forall a. a -> Maybe a
Just Tok
t
                  | Bool
otherwise = Maybe Tok
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
  LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
doMacros
  TokStream _ toks <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) TokStream
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  case toks of
    Tok
t : [Tok]
_ -> Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Tok
t
    []    -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a. ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

doMacros :: PandocMonad m => LP m ()
doMacros :: forall (m :: * -> *). PandocMonad m => LP m ()
doMacros = do
  TokStream macrosExpanded toks <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) TokStream
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
  unless macrosExpanded $
    case toks of
      -- only a control sequence at the head of the stream can
      -- trigger macro expansion; in other cases we skip the
      -- state update:
      Tok SourcePos
_ (CtrlSeq Text
_) Text
_ : [Tok]
_ -> do
        st <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
        unless (sVerbatimMode st) $
          doMacros' 1 toks >>= setInput . TokStream True
      [Tok]
_ -> () -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

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
        -> Int -> SourcePos -> Text -> [Tok] -> LP m [Tok]
forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
handleMacros Int
n SourcePos
spos Text
name [Tok]
ts LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) 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
        -> Int -> SourcePos -> Text -> [Tok] -> LP m [Tok]
forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
handleMacros Int
n SourcePos
spos (Text
"end" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name) [Tok]
ts LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) 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 ([Tok] -> [Tok]) -> LP m [Tok] -> LP m [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Tok] -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
n [Tok]
ts
     Tok SourcePos
spos (CtrlSeq Text
name) Text
_ : [Tok]
ts
        -> Int -> SourcePos -> Text -> [Tok] -> LP m [Tok]
forall {m :: * -> *}.
PandocMonad m =>
Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
handleMacros Int
n SourcePos
spos Text
name [Tok]
ts LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
inp
     [Tok]
_ -> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
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 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
w)) (Text
x1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
w Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x2) Tok -> [Tok] -> [Tok]
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
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:[Tok]
ts

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

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

    -- the first parameter is the number of the next argument
    -- to be bound (needed for the argspecs that don't carry an
    -- argument number themselves)
    getargs :: Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
_ Map Int [Tok]
argmap [] = Map Int [Tok]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Map Int [Tok]
argmap
    getargs Int
num Map Int [Tok]
argmap (Pattern [Tok]
toks : [ArgSpec]
rest) = ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok]))
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall a b. (a -> b) -> a -> b
$ do
       [Tok] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
matchPattern [Tok]
toks
       Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
num Map Int [Tok]
argmap [ArgSpec]
rest
    getargs Int
_ Map Int [Tok]
argmap (ArgNum Int
i : Pattern [Tok]
toks : [ArgSpec]
rest) =
      ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok]))
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall a b. (a -> b) -> a -> b
$ do
        x <- [[Tok]] -> [Tok]
forall a. Monoid a => [a] -> a
mconcat ([[Tok]] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
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 (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:[]) (Tok -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok))
                  ([Tok] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
matchPattern [Tok]
toks)
        getargs (i + 1) (M.insert i x argmap) rest
    getargs Int
_ Map Int [Tok]
argmap (ArgNum Int
i : [ArgSpec]
rest) = do
      x <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
      getargs (i + 1) (M.insert i x argmap) rest
    getargs Int
num Map Int [Tok]
argmap (BoolArg Bool
skipSp t :: Tok
t@(Tok SourcePos
pos TokType
_ Text
_) : [ArgSpec]
rest) = do
      -- the ! modifier (skipSp False) disables space-skipping:
      let sp' :: ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
sp' = Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
skipSp ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
      x <- [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"BooleanFalse") Text
"\\BooleanFalse "]
             ([SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"BooleanTrue") Text
"\\BooleanTrue "]
               [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
sp' ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchTok Tok
t))
      getargs (num + 1) (M.insert num x argmap) rest
    getargs Int
num Map Int [Tok]
argmap (DelimArg Bool
skipSp open :: Tok
open@(Tok SourcePos
pos TokType
_ Text
_) Tok
close Maybe [Tok]
mbdef
                         : [ArgSpec]
rest) = do
      let sp' :: ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
sp' = Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
skipSp ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
      let missing :: [Tok]
missing = [Tok] -> Maybe [Tok] -> [Tok]
forall a. a -> Maybe a -> a
fromMaybe [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"NoValue") Text
"\\NoValue "] Maybe [Tok]
mbdef
      x <- [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Tok]
missing (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
sp' ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Tok
-> Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => Tok -> Tok -> LP m [Tok]
delimitedToks Tok
open Tok
close))
      getargs (num + 1) (M.insert num x argmap) rest
    getargs Int
num Map Int [Tok]
argmap (ArgSpec
VerbArg : [ArgSpec]
rest) = do
      x <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
verbatimArg
      getargs (num + 1) (M.insert num x argmap) rest
    -- xparse 'b' specifier: environment body, grabbed up to the
    -- \end{name} pattern; spaces at the ends are trimmed unless
    -- the ! modifier was used:
    getargs Int
_ Map Int [Tok]
argmap (BodyArg Bool
doTrim Int
i : Pattern [Tok]
toks : [ArgSpec]
rest) = ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok]))
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall a b. (a -> b) -> a -> b
$ do
      x <- [[Tok]] -> [Tok]
forall a. Monoid a => [a] -> a
mconcat ([[Tok]] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
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 ((([Tok], [Tok]) -> [Tok]
forall a b. (a, b) -> b
snd (([Tok], [Tok]) -> [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced))
                                  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:[]) (Tok -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok))
                ([Tok] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
matchPattern [Tok]
toks)
      let x' = if Bool
doTrim then [Tok] -> [Tok]
trimSpaceToks [Tok]
x else [Tok]
x
      getargs (i + 1) (M.insert i x' argmap) rest
    getargs Int
num Map Int [Tok]
argmap (BodyArg Bool
_ Int
i : [ArgSpec]
rest) =
      Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
num Map Int [Tok]
argmap (Int -> ArgSpec
ArgNum Int
i ArgSpec -> [ArgSpec] -> [ArgSpec]
forall a. a -> [a] -> [a]
: [ArgSpec]
rest)
    -- xparse 'c' specifier: environment body, grabbed verbatim up
    -- to the \end{name} pattern; blank lines at the ends are
    -- trimmed unless the ! modifier was used:
    getargs Int
_ Map Int [Tok]
argmap (VerbBodyArg Bool
doTrim Int
i : Pattern [Tok]
toks : [ArgSpec]
rest) = ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok]))
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
forall a b. (a -> b) -> a -> b
$ do
      x <- [[Tok]] -> [Tok]
forall a. Monoid a => [a] -> a
mconcat ([[Tok]] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
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 ((([Tok], [Tok]) -> [Tok]
forall a b. (a, b) -> b
snd (([Tok], [Tok]) -> [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced))
                                  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:[]) (Tok -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok))
                ([Tok] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall {t :: * -> *} {m :: * -> *}.
(Foldable t, PandocMonad m) =>
t Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
matchPattern [Tok]
toks)
      getargs (i + 1) (M.insert i (verbatimBodyToks doTrim x) argmap) rest
    getargs Int
num Map Int [Tok]
argmap (VerbBodyArg Bool
_ Int
i : [ArgSpec]
rest) =
      Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
num Map Int [Tok]
argmap (Int -> ArgSpec
ArgNum Int
i ArgSpec -> [ArgSpec] -> [ArgSpec]
forall a. a -> [a] -> [a]
: [ArgSpec]
rest)
    getargs Int
num Map Int [Tok]
argmap (EmbellishArg [(Tok, Maybe [Tok])]
embs : [ArgSpec]
rest) = do
      let grab :: [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
grab [(Int, [Tok])]
seen
            | [(Int, [Tok])] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, [Tok])]
seen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [(Tok, Maybe [Tok])] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Tok, Maybe [Tok])]
embs = [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Int, [Tok])]
seen
            | Bool
otherwise = [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [(Int, [Tok])]
seen (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall a b. (a -> b) -> a -> b
$ ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall a b. (a -> b) -> a -> b
$ do
                LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
                i <- [ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Int]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Int
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ Int
i Int
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Int
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Tok -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchTok Tok
t
                            | (Int
i, (Tok
t, Maybe [Tok]
_)) <- [Int] -> [(Tok, Maybe [Tok])] -> [(Int, (Tok, Maybe [Tok]))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Int
0 :: Int)..] [(Tok, Maybe [Tok])]
embs
                            , Int
i Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` ((Int, [Tok]) -> Int) -> [(Int, [Tok])] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, [Tok]) -> Int
forall a b. (a, b) -> a
fst [(Int, [Tok])]
seen ]
                x <- braced <|> count 1 anyTok
                grab ((i, x) : seen)
      seen <- [(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
forall {m :: * -> *}.
PandocMonad m =>
[(Int, [Tok])]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Int, [Tok])]
grab []
      let getval Int
i (Tok SourcePos
pos TokType
_ Text
_, Maybe [Tok]
mbdef) =
            case Int -> [(Int, [Tok])] -> Maybe [Tok]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
i [(Int, [Tok])]
seen of
              Just [Tok]
x  -> [Tok]
x
              Maybe [Tok]
Nothing ->
                [Tok] -> Maybe [Tok] -> [Tok]
forall a. a -> Maybe a -> a
fromMaybe [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"NoValue") Text
"\\NoValue "] Maybe [Tok]
mbdef
      let argmap' = ((Int, (Tok, Maybe [Tok])) -> Map Int [Tok] -> Map Int [Tok])
-> Map Int [Tok] -> [(Int, (Tok, Maybe [Tok]))] -> Map Int [Tok]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Int
i, (Tok, Maybe [Tok])
e) Map Int [Tok]
m -> Int -> [Tok] -> Map Int [Tok] -> Map Int [Tok]
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (Int
num Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) (Int -> (Tok, Maybe [Tok]) -> [Tok]
getval Int
i (Tok, Maybe [Tok])
e) Map Int [Tok]
m)
                          Map Int [Tok]
argmap ([Int] -> [(Tok, Maybe [Tok])] -> [(Int, (Tok, Maybe [Tok]))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [(Tok, Maybe [Tok])]
embs)
      getargs (num + length embs) argmap' rest
    getargs Int
num Map Int [Tok]
argmap (ProcessedArg [[Tok]]
procs ArgSpec
spec : [ArgSpec]
rest) = do
      newargs <- Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
num Map Int [Tok]
forall k a. Map k a
M.empty [ArgSpec
spec]
      newargs' <- traverse (applyArgProcessors procs) newargs
      getargs (num + M.size newargs) (M.union newargs' argmap) 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 Tok -> [Tok] -> [Tok]
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 Int -> Map Int (t Tok) -> Maybe (t Tok)
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 -> [Tok]
forall a. [a]
forall (m :: * -> *) a. MonadPlus m => m a
mzero
            Just t Tok
xs -> (Tok -> [Tok] -> [Tok]) -> [Tok] -> t Tok -> [Tok]
forall a b. (a -> b -> b) -> b -> t a -> b
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 (HasCallStack => Text -> Char
Text -> Char
T.last Text
txt) =
        SourcePos -> TokType -> Text -> Tok
Tok SourcePos
spos (Text -> TokType
CtrlSeq Text
x) (Text
txt Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ") Tok -> [Tok] -> [Tok]
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 Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
acc

    handleMacros :: Int
-> SourcePos
-> Text
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
handleMacros Int
n' SourcePos
spos Text
name [Tok]
ts = do
      Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
20)  -- detect macro expansion loops
        (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ PandocError
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
PandocError
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> PandocError
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocMacroLoop Text
name
      (macros :| _ ) <- LaTeXState -> NonEmpty (Map Text Macro)
sMacros (LaTeXState -> NonEmpty (Map Text Macro))
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv m) m)
     (NonEmpty (Map Text Macro))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      case M.lookup name macros of
           -- the result of a special macro may itself begin with a
           -- macro call, so we continue expanding:
           Maybe Macro
Nothing -> Text
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => Text -> [Tok] -> LP m [Tok]
trySpecialMacro Text
name [Tok]
ts ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ([Tok]
    -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> (a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
           Just (Macro MacroScope
_scope ExpansionPoint
expansionPoint [ArgSpec]
argspecs Maybe [Tok]
optarg [Tok]
newtoks) -> do
             -- A macro whose expansion contains itself after an
             -- unknown command (e.g. \def\small{\@setfontsize\small..})
             -- would be expanded again and again at the same position,
             -- each time in a fresh call to doMacros (#11088):
             lastExp <- LaTeXState -> Maybe (Text, SourcePos, Int)
sLastExpansion (LaTeXState -> Maybe (Text, SourcePos, Int))
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv m) m)
     (Maybe (Text, SourcePos, Int))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
             let expCount = case Maybe (Text, SourcePos, Int)
lastExp of
                              Just (Text
name', SourcePos
spos', Int
i)
                                | Text
name' Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
name, SourcePos
spos' SourcePos -> SourcePos -> Bool
forall a. Eq a => a -> a -> Bool
== SourcePos
spos -> Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                              Maybe (Text, SourcePos, Int)
_ -> Int
1 :: Int
             when (expCount > 1000) $ throwError $ PandocMacroLoop name
             updateState $ \LaTeXState
st -> LaTeXState
st{ sLastExpansion =
                                        Just (name, spos, expCount) }
             let getargs' = do
                   args <-
                     (case ExpansionPoint
expansionPoint of
                        ExpansionPoint
ExpandWhenUsed    -> LP m (Map Int [Tok]) -> LP m (Map Int [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode
                        ExpansionPoint
ExpandWhenDefined -> LP m (Map Int [Tok]) -> LP m (Map Int [Tok])
forall a. a -> a
id)
                     (LP m (Map Int [Tok]) -> LP m (Map Int [Tok]))
-> LP m (Map Int [Tok]) -> LP m (Map Int [Tok])
forall a b. (a -> b) -> a -> b
$ case Maybe [Tok]
optarg of
                             Maybe [Tok]
Nothing -> Int -> Map Int [Tok] -> [ArgSpec] -> LP m (Map Int [Tok])
forall {m :: * -> *}.
PandocMonad m =>
Int
-> Map Int [Tok]
-> [ArgSpec]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Map Int [Tok])
getargs Int
1 Map Int [Tok]
forall k a. Map k a
M.empty [ArgSpec]
argspecs
                             Just [Tok]
o  -> do
                                x <- [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Tok]
o ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
                                getargs 2 (M.singleton 1 x) $ drop 1 argspecs
                   TokStream _ rest <- getInput
                   return (args, rest)
             lstate <- getState
             res <- lift $ runParserT getargs' lstate "args" $ TokStream False ts
             case res of
               Left ParseError
_ -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail ([Char]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ [Char]
"Could not parse arguments for " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++
                                Text -> [Char]
T.unpack Text
name
               Right (Map Int [Tok]
args', [Tok]
rest) -> do
                 -- An argument default may refer to other arguments
                 -- (e.g. O{#2}); resolve such references (the visited
                 -- list guards against reference cycles):
                 let resolveTok :: [Int] -> Tok -> [Tok]
resolveTok [Int]
visited t :: Tok
t@(Tok SourcePos
_ (Arg Int
j) Text
_)
                       | Int
j Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Int]
visited
                       , Just [Tok]
ys <- Int -> Map Int [Tok] -> Maybe [Tok]
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Int
j Map Int [Tok]
args'
                       = (Tok -> [Tok]) -> [Tok] -> [Tok]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Int] -> Tok -> [Tok]
resolveTok (Int
j Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Int]
visited)) [Tok]
ys
                       | Bool
otherwise = [Tok
t]
                     resolveTok [Int]
_ Tok
t = [Tok
t]
                 let args :: Map Int [Tok]
args = (Int -> [Tok] -> [Tok]) -> Map Int [Tok] -> Map Int [Tok]
forall k a b. (k -> a -> b) -> Map k a -> Map k b
M.mapWithKey
                              (\Int
i -> (Tok -> [Tok]) -> [Tok] -> [Tok]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Int] -> Tok -> [Tok]
resolveTok [Int
i])) Map Int [Tok]
args'
                 -- In TeX, a newline in a macro body behaves like a
                 -- space; a single newline at the end of the body,
                 -- followed by a newline in the source, must not be
                 -- mistaken for a blank line (paragraph break):
                 let newtoks' :: [Tok]
newtoks' =
                       case [Tok] -> [Tok]
forall a. [a] -> [a]
reverse [Tok]
newtoks of
                         Tok SourcePos
p TokType
Newline Text
_ : [Tok]
rts
                           | Bool -> Bool
not ((Tok -> Bool) -> [Tok] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Tok -> Bool
isNewlineTok (Int -> [Tok] -> [Tok]
forall a. Int -> [a] -> [a]
take Int
1 [Tok]
rts))
                           , (Tok SourcePos
_ TokType
Newline Text
_ : [Tok]
_) <-
                               (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Comment]) [Tok]
rest
                           -> [Tok] -> [Tok]
forall a. [a] -> [a]
reverse (SourcePos -> TokType -> Text -> Tok
Tok SourcePos
p TokType
Spaces Text
" " Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
rts)
                         [Tok]
_ -> [Tok]
newtoks
                 -- 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 = (Tok -> [Tok] -> [Tok]) -> [Tok] -> [Tok] -> [Tok]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Bool -> Map Int [Tok] -> SourcePos -> Tok -> [Tok] -> [Tok]
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    -> Int
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Tok]
result
                   ExpansionPoint
ExpandWhenDefined -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
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
  ts' <- Int -> [Tok] -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => Int -> [Tok] -> LP m [Tok]
doMacros' Int
1 [Tok]
ts
  case ts' of
    Tok SourcePos
pos TokType
Word Text
t : [Tok]
_
      | Text -> Bool
startsWithAlphaNum Text
t -> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Tok] -> LP m [Tok]) -> [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Spaces Text
" " Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
ts'
    [Tok]
_ -> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
ts'
trySpecialMacro Text
"iftrue" [Tok]
ts = Bool -> [Tok] -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
doIf Bool
True [Tok]
ts
trySpecialMacro Text
"iffalse" [Tok]
ts = Bool -> [Tok] -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
doIf Bool
False [Tok]
ts
trySpecialMacro Text
"ifmmode" [Tok]
ts = do
  mathMode <- LaTeXState -> Bool
sMathMode (LaTeXState -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  doIf mathMode ts
trySpecialMacro Text
"ifstrequal" [Tok]
ts = do
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
ifStrequalParser [Tok]
ts
-- xparse (LaTeX3) argument conditionals:
trySpecialMacro Text
"IfNoValueTF" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isNoValueArg Bool
True Bool
True) [Tok]
ts
trySpecialMacro Text
"IfNoValueT" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isNoValueArg Bool
True Bool
False) [Tok]
ts
trySpecialMacro Text
"IfNoValueF" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isNoValueArg Bool
False Bool
True) [Tok]
ts
trySpecialMacro Text
"IfValueTF" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf (Bool -> Bool
not (Bool -> Bool) -> ([Tok] -> Bool) -> [Tok] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tok] -> Bool
isNoValueArg) Bool
True Bool
True) [Tok]
ts
trySpecialMacro Text
"IfValueT" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf (Bool -> Bool
not (Bool -> Bool) -> ([Tok] -> Bool) -> [Tok] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tok] -> Bool
isNoValueArg) Bool
True Bool
False) [Tok]
ts
trySpecialMacro Text
"IfValueF" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf (Bool -> Bool
not (Bool -> Bool) -> ([Tok] -> Bool) -> [Tok] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tok] -> Bool
isNoValueArg) Bool
False Bool
True) [Tok]
ts
trySpecialMacro Text
"IfBooleanTF" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBooleanTrueArg Bool
True Bool
True) [Tok]
ts
trySpecialMacro Text
"IfBooleanT" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBooleanTrueArg Bool
True Bool
False) [Tok]
ts
trySpecialMacro Text
"IfBooleanF" [Tok]
ts =
  LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBooleanTrueArg Bool
False Bool
True) [Tok]
ts
trySpecialMacro Text
"IfBlankTF" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBlankArg Bool
True Bool
True) [Tok]
ts
trySpecialMacro Text
"IfBlankT" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBlankArg Bool
True Bool
False) [Tok]
ts
trySpecialMacro Text
"IfBlankF" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf (([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
isBlankArg Bool
False Bool
True) [Tok]
ts
-- \ProcessList{list}{tokens}: apply tokens to every item of list:
trySpecialMacro Text
"ProcessList" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
processListParser [Tok]
ts
-- \UseName{string}: turn string into a csname and execute it:
trySpecialMacro Text
"UseName" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
useNameParser [Tok]
ts
-- \ExpandArgs{spec}\cmd{arg1}...: pre-expand the command's
-- arguments as described by the spec:
trySpecialMacro Text
"ExpandArgs" [Tok]
ts = LP m [Tok] -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
LP m [Tok] -> [Tok] -> LP m [Tok]
handleIf LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
expandArgsParser [Tok]
ts
-- LaTeX3 expandable evaluators:
trySpecialMacro Text
"inteval" [Tok]
ts = (Text -> Maybe Text) -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
(Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval Text -> Maybe Text
evalInteval [Tok]
ts
trySpecialMacro Text
"fpeval" [Tok]
ts = (Text -> Maybe Text) -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
(Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval Text -> Maybe Text
evalFpeval [Tok]
ts
-- dimension expressions are not evaluated; we substitute the
-- expression itself:
trySpecialMacro Text
"dimeval" [Tok]
ts = (Text -> Maybe Text) -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
(Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> (Text -> Text) -> Text -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip) [Tok]
ts
trySpecialMacro Text
"skipeval" [Tok]
ts = (Text -> Maybe Text) -> [Tok] -> LP m [Tok]
forall (m :: * -> *).
PandocMonad m =>
(Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> (Text -> Text) -> Text -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip) [Tok]
ts
trySpecialMacro Text
_ [Tok]
_ = LP m [Tok]
forall a. ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- | Parse a conditional of the kind used with xparse commands
-- (@\\IfNoValueTF@ etc.): test the first argument and select the
-- true or false branch.  The Bool parameters indicate whether a
-- true and a false branch, respectively, are to be parsed.
xparseIf :: PandocMonad m => ([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf :: forall (m :: * -> *).
PandocMonad m =>
([Tok] -> Bool) -> Bool -> Bool -> LP m [Tok]
xparseIf [Tok] -> Bool
test Bool
hasTrueBranch Bool
hasFalseBranch = do
  -- spaces and comments may intervene between the arguments:
  let grabArg :: LP m [Tok]
grabArg = LP m [Tok] -> LP m [Tok]
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode (LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces LP m () -> LP m [Tok] -> LP m [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m [Tok]
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
1 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok))
  let getBranch :: Bool -> LP m [Tok]
getBranch Bool
cond = if Bool
cond
                          then LP m [Tok]
grabArg
                          else [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
  arg <- LP m [Tok]
grabArg
  trueToks <- getBranch hasTrueBranch
  falseToks <- getBranch hasFalseBranch
  TokStream _ rest <- getInput
  return $ (if test arg then trueToks else falseToks) ++ rest

isNoValueArg :: [Tok] -> Bool
isNoValueArg :: [Tok] -> Bool
isNoValueArg [Tok]
toks =
  case (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Tok -> Bool) -> Tok -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline, TokType
Comment]) [Tok]
toks of
    [Tok SourcePos
_ (CtrlSeq Text
"NoValue") Text
_] -> Bool
True
    [Tok SourcePos
_ TokType
Symbol Text
"-", Tok SourcePos
_ TokType
Word Text
"NoValue", Tok SourcePos
_ TokType
Symbol Text
"-"] -> Bool
True
    [Tok]
_ -> Bool
False

isBooleanTrueArg :: [Tok] -> Bool
isBooleanTrueArg :: [Tok] -> Bool
isBooleanTrueArg [Tok]
toks =
  case (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Tok -> Bool) -> Tok -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline, TokType
Comment]) [Tok]
toks of
    [Tok SourcePos
_ (CtrlSeq Text
"BooleanTrue") Text
_] -> Bool
True
    [Tok]
_ -> Bool
False

-- | An argument is \"blank\" (in the sense of @\\IfBlankTF@) if it
-- is empty or consists only of blanks.
isBlankArg :: [Tok] -> Bool
isBlankArg :: [Tok] -> Bool
isBlankArg = (Tok -> Bool) -> [Tok] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline, TokType
Comment])

-- | Parser for the arguments of @\\ProcessList{list}{tokens}@:
-- apply the tokens to every item (braced group or single token) of
-- the list.
processListParser :: PandocMonad m => LP m [Tok]
processListParser :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
processListParser = LP m [Tok] -> LP m [Tok]
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode (LP m [Tok] -> LP m [Tok]) -> LP m [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ do
  pos <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  spaces
  list <- braced <|> count 1 anyTok
  spaces
  fn <- braced <|> count 1 anyTok
  TokStream _ rest <- getInput
  let items = ([Tok] -> Maybe ([Tok], [Tok])) -> [Tok] -> [[Tok]]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr [Tok] -> Maybe ([Tok], [Tok])
tokGroup [Tok]
list
  let braceIt [Tok]
item = SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{" Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
item [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}"]
  return $ concatMap (\[Tok]
item -> [Tok]
fn [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [Tok] -> [Tok]
braceIt [Tok]
item) items ++ rest

-- | Parser for the argument of @\\UseName{string}@: turn the
-- string into a control sequence.
useNameParser :: PandocMonad m => LP m [Tok]
useNameParser :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
useNameParser = do
  pos <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  name <- untokenize <$> withVerbatimMode (spaces *> braced)
  TokStream _ rest <- getInput
  return $ Tok pos (CtrlSeq name) ("\\" <> name <> " ") : rest

-- | Parser for the arguments of @\\ExpandArgs{spec}\\cmd{arg1}...@:
-- transform each argument as described by the corresponding letter
-- of the spec (@c@ = turn a string into a control sequence, @n@ =
-- leave a braced argument unchanged, @N@ = leave a single token
-- unchanged), then put the command before the transformed
-- arguments.
expandArgsParser :: PandocMonad m => LP m [Tok]
expandArgsParser :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
expandArgsParser = LP m [Tok] -> LP m [Tok]
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode (LP m [Tok] -> LP m [Tok]) -> LP m [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ do
  spec <- Text -> [Char]
T.unpack (Text -> [Char]) -> ([Tok] -> Text) -> [Tok] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Tok] -> Text
untokenize ([Tok] -> [Char])
-> LP m [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces LP m () -> LP m [Tok] -> LP m [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced)
  spaces
  cmd <- anyTok
  args <- concat <$> mapM transformArg spec
  TokStream _ rest <- getInput
  return $ cmd : args ++ rest
 where
  transformArg :: Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
transformArg Char
'c' = do
    pos <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    name <- untokenize <$> (spaces *> braced)
    return [Tok pos (CtrlSeq name) ("\\" <> name <> " ")]
  transformArg Char
'n' = do
    pos <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    toks <- spaces *> braced
    return $ Tok pos Symbol "{" : toks ++ [Tok pos Symbol "}"]
  transformArg Char
'N' = LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces LP m ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
1 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
  transformArg Char
_ = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a. ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

ifStrequalParser :: PandocMonad m => LP m [Tok]
ifStrequalParser :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
ifStrequalParser = do
  str1 <- LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m [Tok]
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
1 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
  str2 <- braced <|> count 1 anyTok
  ifequal <- withVerbatimMode (braced <|> count 1 anyTok)
  ifnotequal <- withVerbatimMode (braced <|> count 1 anyTok)
  TokStream _ ts <- getInput
  return $
    if untokenize str1 == untokenize str2
       then ifequal ++ ts
       else ifnotequal ++ ts

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

-- | Names of TeX's primitive conditionals.  While scanning for the
-- @\\else@ or @\\fi@ that ends a conditional branch, we need to
-- know which control sequences begin a conditional, so that the
-- @\\else@ and @\\fi@ belonging to nested conditionals are not
-- mistaken for the end of the current one.
primitiveConditionalNames :: Set.Set Text
primitiveConditionalNames :: Set Text
primitiveConditionalNames = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
Set.fromList
  [ Text
"if", Text
"ifcase", Text
"ifcat", Text
"ifcsname", Text
"ifdefined", Text
"ifdim"
  , Text
"ifeof", Text
"iffalse", Text
"iffontchar", Text
"ifhbox", Text
"ifhmode"
  , Text
"ifincsname", Text
"ifinner", Text
"ifmmode", Text
"ifnum", Text
"ifodd", Text
"iftrue"
  , Text
"ifvbox", Text
"ifvmode", Text
"ifvoid", Text
"ifx" ]

-- | Handle a conditional like @\\iftrue@: select the branch before
-- @\\else@ (or @\\fi@) if the Bool is True, the else branch
-- otherwise.  The unselected branch is skipped without expansion
-- (as TeX does), keeping nested conditionals balanced.
doIf :: PandocMonad m => Bool -> [Tok] -> LP m [Tok]
doIf :: forall (m :: * -> *). PandocMonad m => Bool -> [Tok] -> LP m [Tok]
doIf Bool
b [Tok]
ts = do
  macros <- LaTeXState -> NonEmpty (Map Text Macro)
sMacros (LaTeXState -> NonEmpty (Map Text Macro))
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT
     TokStream
     LaTeXState
     (ReaderT (LaTeXEnv m) m)
     (NonEmpty (Map Text Macro))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  -- Conditionals defined with \newif (or \let from a primitive
  -- conditional) expand to a single conditional token; TeX
  -- recognizes these too when skipping conditional text.
  let isConditionalMacro (Macro MacroScope
_ ExpansionPoint
_ [] Maybe [Tok]
Nothing [Tok SourcePos
_ (CtrlSeq Text
n) Text
_]) =
        Text
n Text -> Set Text -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Text
primitiveConditionalNames
      isConditionalMacro Macro
_ = Bool
False
  let conditionals = (Map Text Macro -> Set Text -> Set Text)
-> Set Text -> NonEmpty (Map Text Macro) -> Set Text
forall a b. (a -> b -> b) -> b -> NonEmpty a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
        (\Map Text Macro
m Set Text
s -> (Text -> Macro -> Set Text -> Set Text)
-> Set Text -> Map Text Macro -> Set Text
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
M.foldrWithKey
           (\Text
k Macro
v Set Text
s' -> if Macro -> Bool
isConditionalMacro Macro
v
                          then Text -> Set Text -> Set Text
forall a. Ord a => a -> Set a -> Set a
Set.insert Text
k Set Text
s'
                          else Set Text
s')
           Set Text
s Map Text Macro
m)
        Set Text
primitiveConditionalNames NonEmpty (Map Text Macro)
macros
  case splitConditional conditionals ts of
    Just ([Tok]
ifToks, [Tok]
elseToks, [Tok]
rest) ->
      [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Tok]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ (if Bool
b then [Tok]
ifToks else [Tok]
elseToks) [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [Tok]
rest
    Maybe ([Tok], [Tok], [Tok])
Nothing -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Could not parse conditional"

-- | Split the tokens following a conditional into the tokens
-- before @\\else@ (or @\\fi@), the tokens of the else branch (if
-- any), and the tokens after the matching @\\fi@.  Returns Nothing
-- if there is no matching @\\fi@.
splitConditional :: Set.Set Text -> [Tok] -> Maybe ([Tok], [Tok], [Tok])
splitConditional :: Set Text -> [Tok] -> Maybe ([Tok], [Tok], [Tok])
splitConditional Set Text
conditionals = Int -> ([Tok] -> [Tok]) -> [Tok] -> Maybe ([Tok], [Tok], [Tok])
forall {a} {c}.
(Eq a, Num a) =>
a -> ([Tok] -> c) -> [Tok] -> Maybe (c, [Tok], [Tok])
goIf (Int
0 :: Int) [Tok] -> [Tok]
forall a. a -> a
id
 where
  goIf :: a -> ([Tok] -> c) -> [Tok] -> Maybe (c, [Tok], [Tok])
goIf a
_ [Tok] -> c
_ [] = Maybe (c, [Tok], [Tok])
forall a. Maybe a
Nothing
  goIf a
depth [Tok] -> c
acc (t :: Tok
t@(Tok SourcePos
_ (CtrlSeq Text
name) Text
_) : [Tok]
rest)
    | Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"fi"
    , a
depth a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = (c, [Tok], [Tok]) -> Maybe (c, [Tok], [Tok])
forall a. a -> Maybe a
Just ([Tok] -> c
acc [], [], [Tok]
rest)
    | Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"fi" = a -> ([Tok] -> c) -> [Tok] -> Maybe (c, [Tok], [Tok])
goIf (a
depth a -> a -> a
forall a. Num a => a -> a -> a
- a
1) ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest
    | Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"else"
    , a
depth a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = c -> Int -> ([Tok] -> [Tok]) -> [Tok] -> Maybe (c, [Tok], [Tok])
forall {t} {t} {c}.
(Eq t, Num t) =>
t -> t -> ([Tok] -> c) -> [Tok] -> Maybe (t, c, [Tok])
goElse ([Tok] -> c
acc []) (Int
0 :: Int) [Tok] -> [Tok]
forall a. a -> a
id [Tok]
rest
    | Text
name Text -> Set Text -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Text
conditionals = a -> ([Tok] -> c) -> [Tok] -> Maybe (c, [Tok], [Tok])
goIf (a
depth a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest
  goIf a
depth [Tok] -> c
acc (Tok
t : [Tok]
rest) = a -> ([Tok] -> c) -> [Tok] -> Maybe (c, [Tok], [Tok])
goIf a
depth ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest
  goElse :: t -> t -> ([Tok] -> c) -> [Tok] -> Maybe (t, c, [Tok])
goElse t
_ t
_ [Tok] -> c
_ [] = Maybe (t, c, [Tok])
forall a. Maybe a
Nothing
  goElse t
ifToks t
depth [Tok] -> c
acc (t :: Tok
t@(Tok SourcePos
_ (CtrlSeq Text
name) Text
_) : [Tok]
rest)
    | Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"fi"
    , t
depth t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0 = (t, c, [Tok]) -> Maybe (t, c, [Tok])
forall a. a -> Maybe a
Just (t
ifToks, [Tok] -> c
acc [], [Tok]
rest)
    | Text
name Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"fi" = t -> t -> ([Tok] -> c) -> [Tok] -> Maybe (t, c, [Tok])
goElse t
ifToks (t
depth t -> t -> t
forall a. Num a => a -> a -> a
- t
1) ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest
    | Text
name Text -> Set Text -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Text
conditionals =
        t -> t -> ([Tok] -> c) -> [Tok] -> Maybe (t, c, [Tok])
goElse t
ifToks (t
depth t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest
  goElse t
ifToks t
depth [Tok] -> c
acc (Tok
t : [Tok]
rest) = t -> t -> ([Tok] -> c) -> [Tok] -> Maybe (t, c, [Tok])
goElse t
ifToks t
depth ([Tok] -> c
acc ([Tok] -> c) -> ([Tok] -> [Tok]) -> [Tok] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:)) [Tok]
rest

-- | Handle a LaTeX3 expandable evaluator (@\inteval@, @\fpeval@,
-- ...): grab the braced argument (macros in it are expanded as it
-- is consumed), evaluate it, and substitute the result.  If the
-- expression cannot be evaluated, substitute the expression text
-- itself and report it.
handleEval :: PandocMonad m => (Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval :: forall (m :: * -> *).
PandocMonad m =>
(Text -> Maybe Text) -> [Tok] -> LP m [Tok]
handleEval Text -> Maybe Text
evaluator [Tok]
ts = do
  lstate <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  res <- lift $ runParserT evalParser lstate "eval" $ TokStream False ts
  case res of
    Left ParseError
_ -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Could not parse evaluator argument"
    Right [Tok]
ts' -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Tok]
ts'
 where
  evalParser :: ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
evalParser = do
    pos <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    arg <- untokenize <$> braced
    TokStream _ rest <- getInput
    case evaluator arg of
      Just Text
result -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Tok]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ SourcePos -> Text -> [Tok]
tokenize SourcePos
pos Text
result [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [Tok]
rest
      Maybe Text
Nothing -> do
        LogMessage
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> LogMessage
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
SkippedContent (Text
"evaluation of " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
arg) SourcePos
pos
        [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Tok]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ SourcePos -> Text -> [Tok]
tokenize SourcePos
pos Text
arg [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [Tok]
rest

-- | Evaluate an integer expression (@\inteval@): @+ - * / ( )@,
-- with division rounding to the nearest integer (ties away from
-- zero, as in eTeX's @\numexpr@).
evalInteval :: Text -> Maybe Text
evalInteval :: Text -> Maybe Text
evalInteval Text
t = do
  (n, rest) <- Text -> Maybe (Integer, Text)
pIntExpr Text
t
  guard $ T.null (skipWs rest)
  pure $ T.pack (show n)
 where
  pIntExpr :: Text -> Maybe (Integer, Text)
pIntExpr Text
s0 = Text -> Maybe (Integer, Text)
pIntTerm Text
s0 Maybe (Integer, Text)
-> ((Integer, Text) -> Maybe (Integer, Text))
-> Maybe (Integer, Text)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Integer, Text) -> Maybe (Integer, Text)
addLoop
  addLoop :: (Integer, Text) -> Maybe (Integer, Text)
addLoop (Integer
acc, Text
s) =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s) of
      Just (Char
'+', Text
s') -> do (y, s'') <- Text -> Maybe (Integer, Text)
pIntTerm Text
s'
                           addLoop (acc + y, s'')
      Just (Char
'-', Text
s') -> do (y, s'') <- Text -> Maybe (Integer, Text)
pIntTerm Text
s'
                           addLoop (acc - y, s'')
      Maybe (Char, Text)
_ -> (Integer, Text) -> Maybe (Integer, Text)
forall a. a -> Maybe a
Just (Integer
acc, Text
s)
  pIntTerm :: Text -> Maybe (Integer, Text)
pIntTerm Text
s0 = Text -> Maybe (Integer, Text)
pIntFactor Text
s0 Maybe (Integer, Text)
-> ((Integer, Text) -> Maybe (Integer, Text))
-> Maybe (Integer, Text)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Integer, Text) -> Maybe (Integer, Text)
mulLoop
  mulLoop :: (Integer, Text) -> Maybe (Integer, Text)
mulLoop (Integer
acc, Text
s) =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s) of
      Just (Char
'*', Text
s') -> do (y, s'') <- Text -> Maybe (Integer, Text)
pIntFactor Text
s'
                           mulLoop (acc * y, s'')
      Just (Char
'/', Text
s') -> do (y, s'') <- Text -> Maybe (Integer, Text)
pIntFactor Text
s'
                           guard $ y /= 0
                           mulLoop (divRound acc y, s'')
      Maybe (Char, Text)
_ -> (Integer, Text) -> Maybe (Integer, Text)
forall a. a -> Maybe a
Just (Integer
acc, Text
s)
  pIntFactor :: Text -> Maybe (Integer, Text)
pIntFactor Text
s0 =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s0) of
      Just (Char
'-', Text
s) -> do (x, s') <- Text -> Maybe (Integer, Text)
pIntFactor Text
s
                          pure (negate x, s')
      Just (Char
'+', Text
s) -> Text -> Maybe (Integer, Text)
pIntFactor Text
s
      Just (Char
'(', Text
s) -> do
        (x, s') <- Text -> Maybe (Integer, Text)
pIntExpr Text
s
        case T.uncons (skipWs s') of
          Just (Char
')', Text
s'') -> (Integer, Text) -> Maybe (Integer, Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer
x, Text
s'')
          Maybe (Char, Text)
_ -> Maybe (Integer, Text)
forall a. Maybe a
Nothing
      Just (Char
c, Text
_) | Char -> Bool
isDigit Char
c ->
        let (Text
ds, Text
s) = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isDigit (Text -> Text
skipWs Text
s0)
        in do n <- Text -> Maybe Integer
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
ds
              pure (n :: Integer, s)
      Maybe (Char, Text)
_ -> Maybe (Integer, Text)
forall a. Maybe a
Nothing
  divRound :: a -> a -> a
divRound a
a a
b =
    let (a
q, a
r) = a
a a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
`quotRem` a
b
    in if a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a -> a
forall a. Num a => a -> a
abs a
r a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a -> a
forall a. Num a => a -> a
abs a
b
          then a
q a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Num a => a -> a
signum a
a a -> a -> a
forall a. Num a => a -> a -> a
* a -> a
forall a. Num a => a -> a
signum a
b
          else a
q

-- | Evaluate a floating point expression (a practical subset of
-- @\fpeval@): @+ - * / ^ ( )@ (also @**@ for @^@) and decimal
-- literals.
evalFpeval :: Text -> Maybe Text
evalFpeval :: Text -> Maybe Text
evalFpeval Text
t0 = do
  let t :: Text
t = HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"**" Text
"^" Text
t0
  (x, rest) <- Text -> Maybe (Double, Text)
pFpExpr Text
t
  guard $ T.null (skipWs rest)
  guard $ not (isNaN x || isInfinite x)
  pure $ formatFp x
 where
  pFpExpr :: Text -> Maybe (Double, Text)
pFpExpr Text
s0 = Text -> Maybe (Double, Text)
pFpTerm Text
s0 Maybe (Double, Text)
-> ((Double, Text) -> Maybe (Double, Text)) -> Maybe (Double, Text)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Double, Text) -> Maybe (Double, Text)
addLoop
  addLoop :: (Double, Text) -> Maybe (Double, Text)
addLoop (Double
acc, Text
s) =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s) of
      Just (Char
'+', Text
s') -> do (y, s'') <- Text -> Maybe (Double, Text)
pFpTerm Text
s'
                           addLoop (acc + y, s'')
      Just (Char
'-', Text
s') -> do (y, s'') <- Text -> Maybe (Double, Text)
pFpTerm Text
s'
                           addLoop (acc - y, s'')
      Maybe (Char, Text)
_ -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
Just (Double
acc, Text
s)
  pFpTerm :: Text -> Maybe (Double, Text)
pFpTerm Text
s0 = Text -> Maybe (Double, Text)
pFpPow Text
s0 Maybe (Double, Text)
-> ((Double, Text) -> Maybe (Double, Text)) -> Maybe (Double, Text)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Double, Text) -> Maybe (Double, Text)
mulLoop
  mulLoop :: (Double, Text) -> Maybe (Double, Text)
mulLoop (Double
acc, Text
s) =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s) of
      Just (Char
'*', Text
s') -> do (y, s'') <- Text -> Maybe (Double, Text)
pFpPow Text
s'
                           mulLoop (acc * y, s'')
      Just (Char
'/', Text
s') -> do (y, s'') <- Text -> Maybe (Double, Text)
pFpPow Text
s'
                           mulLoop (acc / y, s'')
      Maybe (Char, Text)
_ -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
Just (Double
acc, Text
s)
  pFpPow :: Text -> Maybe (Double, Text)
pFpPow Text
s0 = do
    (x, s) <- Text -> Maybe (Double, Text)
pFpFactor Text
s0
    case T.uncons (skipWs s) of
      Just (Char
'^', Text
s') -> do (y, s'') <- Text -> Maybe (Double, Text)
pFpPow Text
s'  -- right-associative
                           pure (x ** y, s'')
      Maybe (Char, Text)
_ -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
x, Text
s)
  pFpFactor :: Text -> Maybe (Double, Text)
pFpFactor Text
s0 =
    case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s0) of
      Just (Char
'-', Text
s) -> do (x, s') <- Text -> Maybe (Double, Text)
pFpFactor Text
s
                          pure (negate x, s')
      Just (Char
'+', Text
s) -> Text -> Maybe (Double, Text)
pFpFactor Text
s
      Just (Char
'(', Text
s) -> do
        (x, s') <- Text -> Maybe (Double, Text)
pFpExpr Text
s
        case T.uncons (skipWs s') of
          Just (Char
')', Text
s'') -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
x, Text
s'')
          Maybe (Char, Text)
_ -> Maybe (Double, Text)
forall a. Maybe a
Nothing
      Just (Char
c, Text
_) | Char -> Bool
isLetter Char
c ->
        let (Text
name, Text
s1) = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isLetter (Text -> Text
skipWs Text
s0)
        in case Text
name of
             Text
"pi"  -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
forall a. Floating a => a
pi, Text
s1)
             Text
"deg" -> (Double, Text) -> Maybe (Double, Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
forall a. Floating a => a
pi Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
180, Text
s1)  -- one degree in radians
             Text
_ ->
               case Text -> Maybe (Char, Text)
T.uncons (Text -> Text
skipWs Text
s1) of
                 Just (Char
'(', Text
s2) -> do
                   (args, s3) <- Text -> Maybe ([Double], Text)
pFpArgs Text
s2
                   x <- applyFn name args
                   pure (x, s3)
                 Maybe (Char, Text)
_ -> do
                   -- prefix application without parentheses,
                   -- e.g. "sqrt 2":
                   (y, s2) <- Text -> Maybe (Double, Text)
pFpFactor Text
s1
                   x <- applyFn name [y]
                   pure (x, s2)
      Just (Char
c, Text
_) | Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.' ->
        let s :: Text
s = Text -> Text
skipWs Text
s0
            (Text
ds, Text
s') = (Char -> Bool) -> Text -> (Text, Text)
T.span (\Char
d -> Char -> Bool
isDigit Char
d Bool -> Bool -> Bool
|| Char
d Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') Text
s
            (Text
expt, Text
s'') = case Text -> Maybe (Char, Text)
T.uncons Text
s' of
                            Just (Char
e, Text
r) | Char
e Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'e' Bool -> Bool -> Bool
|| Char
e Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'E' ->
                              let (Text
sign, Text
r') =
                                    case Text -> Maybe (Char, Text)
T.uncons Text
r of
                                      Just (Char
sg, Text
rr) | Char
sg Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'+' Bool -> Bool -> Bool
|| Char
sg Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-'
                                        -> (Char -> Text
T.singleton Char
sg, Text
rr)
                                      Maybe (Char, Text)
_ -> (Text
"", Text
r)
                                  (Text
eds, Text
r'') = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isDigit Text
r'
                              in if Text -> Bool
T.null Text
eds
                                    then (Text
"", Text
s')
                                    else (Text
"e" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sign Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
eds, Text
r'')
                            Maybe (Char, Text)
_ -> (Text
"", Text
s')
        in do x <- Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead (Text -> Text
fixup Text
ds Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
expt)
              pure (x :: Double, s'')
      Maybe (Char, Text)
_ -> Maybe (Double, Text)
forall a. Maybe a
Nothing
  fixup :: Text -> Text
fixup Text
ds -- make the literal readable for Haskell's 'read'
    | Text
"." Text -> Text -> Bool
`T.isPrefixOf` Text
ds = Text
"0" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
fixup' Text
ds
    | Bool
otherwise = Text -> Text
fixup' Text
ds
  fixup' :: Text -> Text
fixup' Text
ds
    | Text
"." Text -> Text -> Bool
`T.isSuffixOf` Text
ds = Text
ds Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"0"
    | Bool
otherwise = Text
ds
  -- comma-separated function arguments, ending with ')':
  pFpArgs :: Text -> Maybe ([Double], Text)
pFpArgs Text
s0 = do
    (x, s) <- Text -> Maybe (Double, Text)
pFpExpr Text
s0
    case T.uncons (skipWs s) of
      Just (Char
',', Text
s') -> do (xs, s'') <- Text -> Maybe ([Double], Text)
pFpArgs Text
s'
                           pure (x : xs, s'')
      Just (Char
')', Text
s') -> ([Double], Text) -> Maybe ([Double], Text)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Double
x], Text
s')
      Maybe (Char, Text)
_ -> Maybe ([Double], Text)
forall a. Maybe a
Nothing
  applyFn :: Text -> [Double] -> Maybe Double
applyFn Text
name [Double]
args =
    case (Text -> [(Text, Double -> Double)] -> Maybe (Double -> Double)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
name [(Text, Double -> Double)]
unaryFns, [Double]
args) of
      (Just Double -> Double
f, [Double
x]) -> Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Double
f Double
x)
      (Maybe (Double -> Double), [Double])
_ ->
        case (Text
name, [Double]
args) of
          (Text
"max", Double
_:[Double]
_) -> Double -> Maybe Double
forall a. a -> Maybe a
Just ([Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Double]
args)
          (Text
"min", Double
_:[Double]
_) -> Double -> Maybe Double
forall a. a -> Maybe a
Just ([Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Double]
args)
          (Text
"atan", [Double
x, Double
y]) -> Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
atan2 Double
x Double
y)
          (Text
"atand", [Double
x, Double
y]) -> Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
atan2 Double
x Double
y))
          (Text
"round", [Double]
_) -> (Double -> Double) -> [Double] -> Maybe Double
rounder (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> (Double -> Integer) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round) [Double]
args
          (Text
"floor", [Double]
_) -> (Double -> Double) -> [Double] -> Maybe Double
rounder (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> (Double -> Integer) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor) [Double]
args
          (Text
"ceil", [Double]
_) -> (Double -> Double) -> [Double] -> Maybe Double
rounder (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> (Double -> Integer) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling) [Double]
args
          (Text
"trunc", [Double]
_) -> (Double -> Double) -> [Double] -> Maybe Double
rounder (Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Integer -> Double) -> (Double -> Integer) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate) [Double]
args
          (Text, [Double])
_ -> Maybe Double
forall a. Maybe a
Nothing
  -- rounding functions take an optional number of decimal places:
  rounder :: (Double -> Double) -> [Double] -> Maybe Double
rounder Double -> Double
f [Double
x] = Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Double
f Double
x)
  rounder Double -> Double
f [Double
x, Double
n] | Double
n Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
n) =
    let m :: Double
m = Double
10 Double -> Integer -> Double
forall a b. (Fractional a, Integral b) => a -> b -> a
^^ (Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
n :: Integer)
        -- round to 16 significant digits first (like l3fp), so
        -- that e.g. round(2.345,2) gives 2.34, not 2.35:
        y :: Double
y = [Char] -> Double
forall a. Read a => [Char] -> a
read (Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showEFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
15) (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
m) [Char]
"") :: Double
    in Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Double
f Double
y Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
m)
  rounder Double -> Double
_ [Double]
_ = Maybe Double
forall a. Maybe a
Nothing
  rad :: a -> a
rad a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
180
  unrad :: a -> a
unrad a
x = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
180 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Floating a => a
pi
  unaryFns :: [(Text, Double -> Double)]
  unaryFns :: [(Text, Double -> Double)]
unaryFns =
    [ (Text
"abs", Double -> Double
forall a. Num a => a -> a
abs), (Text
"sign", Double -> Double
forall a. Num a => a -> a
signum), (Text
"sqrt", Double -> Double
forall {a}. Floating a => a -> a
sqrt)
    , (Text
"exp", Double -> Double
forall {a}. Floating a => a -> a
exp), (Text
"ln", Double -> Double
forall {a}. Floating a => a -> a
log)
    , (Text
"fact", \Double
x -> if Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
0 Bool -> Bool -> Bool
&& Double
x Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Double
forall a. Num a => Integer -> a
fromInteger (Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
x) Bool -> Bool -> Bool
&& Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
171
                        then Integer -> Double
forall a. Num a => Integer -> a
fromInteger ([Integer] -> Integer
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
1 .. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
x])
                        else Double
0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
0)
    , (Text
"sin", Double -> Double
forall {a}. Floating a => a -> a
sin), (Text
"cos", Double -> Double
forall {a}. Floating a => a -> a
cos), (Text
"tan", Double -> Double
forall {a}. Floating a => a -> a
tan)
    , (Text
"cot", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
tan), (Text
"sec", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
cos), (Text
"csc", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
sin)
    , (Text
"asin", Double -> Double
forall {a}. Floating a => a -> a
asin), (Text
"acos", Double -> Double
forall {a}. Floating a => a -> a
acos), (Text
"atan", Double -> Double
forall {a}. Floating a => a -> a
atan)
    , (Text
"acot", Double -> Double
forall {a}. Floating a => a -> a
atan (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip), (Text
"asec", Double -> Double
forall {a}. Floating a => a -> a
acos (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip), (Text
"acsc", Double -> Double
forall {a}. Floating a => a -> a
asin (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip)
    , (Text
"sind", Double -> Double
forall {a}. Floating a => a -> a
sin (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad), (Text
"cosd", Double -> Double
forall {a}. Floating a => a -> a
cos (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad), (Text
"tand", Double -> Double
forall {a}. Floating a => a -> a
tan (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad)
    , (Text
"cotd", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
tan (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad), (Text
"secd", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
cos (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad)
    , (Text
"cscd", Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
sin (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
rad)
    , (Text
"asind", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
asin), (Text
"acosd", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
acos)
    , (Text
"atand", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
atan), (Text
"acotd", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
atan (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip)
    , (Text
"asecd", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
acos (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip), (Text
"acscd", Double -> Double
forall {a}. Floating a => a -> a
unrad (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. Floating a => a -> a
asin (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall a. Fractional a => a -> a
recip)
    ]

formatFp :: Double -> Text
formatFp :: Double -> Text
formatFp Double
x0
  | Double
x Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
r Bool -> Bool -> Bool
&& Double -> Double
forall a. Num a => a -> a
abs Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1e16 = [Char] -> Text
T.pack (Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
r)
  | Bool
otherwise = [Char] -> Text
T.pack (ShowS
trimZeros (Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Double
x [Char]
""))
 where
  -- l3fp computes with 16 significant decimal digits; round to
  -- that precision so that e.g. 0.1 + 0.2 yields 0.3.
  x :: Double
x = [Char] -> Double
forall a. Read a => [Char] -> a
read (Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showEFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
15) Double
x0 [Char]
"") :: Double
  r :: Integer
r = Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Double
x
  trimZeros :: ShowS
trimZeros [Char]
s
    | Char
'.' Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
s = case (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'0') [Char]
s of
                       [Char]
s' | [Char]
"." [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` [Char]
s' -> Int -> ShowS
forall a. Int -> [a] -> [a]
take ([Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
s' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [Char]
s'
                          | Bool
otherwise -> [Char]
s'
    | Bool
otherwise = [Char]
s

skipWs :: Text -> Text
skipWs :: Text -> Text
skipWs = (Char -> Bool) -> Text -> Text
T.dropWhile (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\r')

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 = (Tok -> Bool) -> LP m Tok
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 = (Tok -> Bool) -> LP m Tok
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 = (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\(Tok SourcePos
source TokType
_ Text
_) -> (SourcePos -> [Char]
sourceName SourcePos
source) [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
reference)

spaces :: PandocMonad m => LP m ()
spaces :: forall (m :: * -> *). PandocMonad m => LP m ()
spaces = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ((Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ((Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 TokType -> [TokType] -> Bool
forall a. Eq a => a -> [a] -> Bool
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 = (Tok -> Bool) -> LP m Tok
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 Text -> Text -> Bool
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 = (Tok -> Bool) -> LP m Tok
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 Char -> Char -> Bool
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 = (Tok -> Bool) -> LP m Tok
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 Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
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
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
whitespace ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
comment)
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
endline  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
whitespace ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
comment)

whitespace :: PandocMonad m => LP m ()
whitespace :: forall (m :: * -> *). PandocMonad m => LP m ()
whitespace = () ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 = () ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 = () ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 = (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (Bool -> Tok -> Bool
forall a b. a -> b -> a
const Bool
True)

singleCharTok :: PandocMonad m => LP m Tok
singleCharTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
singleCharTok =
  (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ((Tok -> Bool) -> LP m Tok) -> (Tok -> Bool) -> LP m Tok
forall a b. (a -> b) -> a -> b
$ \case
     Tok SourcePos
_ TokType
Word  Text
t   -> Text -> Int
T.length Text
t Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
     Tok SourcePos
_ TokType
Symbol Text
t  -> Bool -> Bool
not ((Char -> Bool) -> Text -> Bool
T.any (Char -> Set Char -> Bool
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 = LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
singleCharTok LP m Tok -> LP m Tok -> LP m Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LP m Tok
singleCharFromWord
 where
  singleCharFromWord :: LP m Tok
singleCharFromWord = do
    Tok pos toktype t <- LP m Tok -> LP m Tok
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
disablingWithRaw (LP m Tok -> LP m Tok) -> LP m Tok -> LP m Tok
forall a b. (a -> b) -> a -> b
$ (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok
    let (t1, t2) = (T.take 1 t, T.drop 1 t)
    TokStream macrosExpanded inp <- getInput
    setInput $ TokStream macrosExpanded
             $ Tok pos toktype t1 : Tok (incSourceColumn pos 1) toktype t2 : inp
    anyTok

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

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

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

primEscape :: PandocMonad m => LP m Char
primEscape :: forall (m :: * -> *). PandocMonad m => LP m Char
primEscape = do
  Tok _ toktype t <- (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Esc1, TokType
Esc2])
  case 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 Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\64' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\127' -> Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
64))
                      | Bool
otherwise                 -> Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr (Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
64))
                    Maybe (Char, Text)
Nothing -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail [Char]
"Empty content of Esc1"
       TokType
Esc2 -> case Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead (Text
"0x" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text -> Text
T.drop Int
2 Text
t) of
                    Just Int
x  -> Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Char
chr Int
x)
                    Maybe Int
Nothing -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
Prelude.fail ([Char]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char)
-> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a b. (a -> b) -> a -> b
$ [Char]
"Could not read: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t
       TokType
_    -> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
[Char] -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a b. (a -> b) -> a -> b
$ do
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
  t <- Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'{' ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"bgroup" ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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.
  updateState $ \LaTeXState
s -> LaTeXState
s{ sMacros = NonEmpty.cons (NonEmpty.head (sMacros s))
                                                 (sMacros s) }
  return t


egroup :: PandocMonad m => LP m Tok
egroup :: forall (m :: * -> *). PandocMonad m => LP m Tok
egroup = do
  t <- Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'}' LP m Tok -> LP m Tok -> LP m Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> LP m Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"egroup" LP m Tok -> LP m Tok -> LP m Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> LP m Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"endgroup"
  -- remove the group's macro table from the stack
  updateState $ \LaTeXState
s -> LaTeXState
s{ sMacros = fromMaybe (sMacros s) $
      NonEmpty.nonEmpty (NonEmpty.tail (sMacros s)) }
  return 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 = LP m a -> LP m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m a -> LP m a) -> LP m a -> LP m a
forall a b. (a -> b) -> a -> b
$ do
  LP m Tok
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}
  LP m a -> LP m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m a -> LP m a
forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
grouped LP m a
parser LP m a -> LP m Tok -> LP m a
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
egroup) LP m a -> LP m a -> LP m a
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([a] -> a
forall a. Monoid a => [a] -> a
mconcat ([a] -> a)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
-> LP m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m a
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
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 LP m Tok
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 = Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'{' LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall {t}.
(Ord t, Num t) =>
t -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go (Int
1 :: Int)
 where
  go :: t -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go t
n = do
    t <- LP m Tok
getTok
    case t of
      Tok SourcePos
_ TokType
Symbol Text
"}"
        | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
1     -> (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:) ([Tok] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
        | Bool
otherwise -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []
      Tok SourcePos
_ TokType
Symbol Text
"{" -> (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:) ([Tok] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
+ t
1)
      Tok
_ -> (Tok
tTok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:) ([Tok] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> t -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go t
n

braced :: PandocMonad m => LP m [Tok]
braced :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced = LP m Tok -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m Tok -> LP m [Tok]
braced' LP m Tok
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 = LP m Tok -> LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m Tok -> LP m [Tok]
braced' (LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
retokenizeComment LP m () -> LP m Tok -> LP m Tok
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LP m Tok
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 pos Comment txt <- (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isCommentTok
  let newtoks = SourcePos -> Text -> [Tok]
tokenize (SourcePos -> Int -> SourcePos
incSourceColumn SourcePos
pos Int
1) (Text -> [Tok]) -> Text -> [Tok]
forall a b. (a -> b) -> a -> b
$ HasCallStack => Text -> Text
Text -> Text
T.tail Text
txt
  TokStream macrosExpanded ts <- getInput
  setInput $ TokStream macrosExpanded ((Tok pos Symbol "%" : newtoks) ++ ts))
    ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> () -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) 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 = LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced LP m [Tok] -> LP m [Tok] -> LP m [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
:[]) (Tok -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
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 = LP m a -> LP m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m a -> LP m a) -> LP m a -> LP m a
forall a b. (a -> b) -> a -> b
$ do
  Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'['
  [a] -> a
forall a. Monoid a => [a] -> a
mconcat ([a] -> a)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
-> LP m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m a
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
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 (Char -> LP m Tok
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
  Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'['
  [[Tok]] -> [Tok]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Tok]] -> [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
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 ((([Tok], [Tok]) -> [Tok]
forall a b. (a, b) -> b
snd (([Tok], [Tok]) -> [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced)) ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
1 LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok)
                      (Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
']')

-- | Tokens between opening and closing delimiter tokens (which are
-- compared by token type and text, ignoring position).  Nested
-- delimiter pairs are balanced (when the delimiters differ), and
-- braced groups are skipped, so delimiters inside braces don't count.
delimitedToks :: PandocMonad m => Tok -> Tok -> LP m [Tok]
delimitedToks :: forall (m :: * -> *). PandocMonad m => Tok -> Tok -> LP m [Tok]
delimitedToks Tok
open Tok
close = Tok -> LP m Tok
forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchesTok Tok
open LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall {m :: * -> *} {a}.
(PandocMonad m, Eq a, Num a) =>
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go (Int
1 :: Int)
 where
  matchesTok :: Tok -> LP m Tok
matchesTok (Tok SourcePos
_ TokType
toktype Text
txt) =
    (Tok -> Bool) -> LP m Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\(Tok SourcePos
_ TokType
toktype' Text
txt') -> TokType
toktype TokType -> TokType -> Bool
forall a. Eq a => a -> a -> Bool
== TokType
toktype' Bool -> Bool -> Bool
&& Text
txt Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
txt')
  go :: a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
go a
n = (do ts <- ([Tok], [Tok]) -> [Tok]
forall a b. (a, b) -> b
snd (([Tok], [Tok]) -> [Tok])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ([Tok], [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced)
             (ts ++) <$> go n)
     ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (do t <- Tok -> LP m Tok
forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchesTok Tok
close
             if n == 1
                then return []
                else (t:) <$> go (n - 1))
     ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (do t <- Tok -> LP m Tok
forall {m :: * -> *}. PandocMonad m => Tok -> LP m Tok
matchesTok Tok
open
             (t:) <$> go (n + 1))
     ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (do t <- LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
             (t:) <$> go n)

-- | A verbatim argument (xparse @v@ specifier): either a braced
-- group or tokens between two identical delimiter characters.
-- The result is a single Word token containing the raw text, so
-- that its contents are not reinterpreted when substituted.
verbatimArg :: PandocMonad m => LP m [Tok]
verbatimArg :: forall (m :: * -> *). PandocMonad m => LP m [Tok]
verbatimArg = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ do
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
  toks <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
delimited
  case toks of
    [] -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Word ([Tok] -> Text
untokenize [Tok]
toks)]
 where
  delimited :: ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
delimited = do
    Tok _ Symbol t <- LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anySymbol
    marker <- case T.uncons t of
                Just (Char
c, Text
ts) | Text -> Bool
T.null Text
ts -> Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c
                Maybe (Char, Text)
_            -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Char
forall a. ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
    manyTill (notFollowedBy newlineTok >> verbTok marker) (symbol marker)

-- | Convert a verbatim environment body (xparse @c@ specifier) to
-- tokens for substitution.  The body is typeset verbatim by LaTeX,
-- with each space rendered as the character in slot 32 of the
-- current font (the visible space U+2423 in typewriter fonts) and
-- each source line on its own line; we emulate this by making each
-- line a single Word token (so contents are not reinterpreted),
-- with spaces replaced by U+2423 and lines separated by @\\\\@.
-- Tabs are kept as-is (LaTeX typesets the raw tab character, not a
-- visible space).  Note that the typewriter font is not automatic:
-- it comes from a @\\ttfamily@ or similar in the environment
-- definition.  If the first parameter is True, leading and trailing
-- blank lines are trimmed.
verbatimBodyToks :: Bool -> [Tok] -> [Tok]
verbatimBodyToks :: Bool -> [Tok] -> [Tok]
verbatimBodyToks Bool
_ [] = []
verbatimBodyToks Bool
doTrim toks :: [Tok]
toks@(Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_) =
  [Tok] -> [[Tok]] -> [Tok]
forall a. [a] -> [[a]] -> [a]
intercalate [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"\\") Text
"\\\\"] ((Text -> [Tok]) -> [Text] -> [[Tok]]
forall a b. (a -> b) -> [a] -> [b]
map Text -> [Tok]
lineToks [Text]
ls)
 where
  lineToks :: Text -> [Tok]
lineToks Text
l
    | Text -> Bool
T.null Text
l = []
    | Bool
otherwise = [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Word ((Char -> Char) -> Text -> Text
T.map Char -> Char
toVisibleSpace Text
l)]
  toVisibleSpace :: Char -> Char
toVisibleSpace Char
c = if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' then Char
'\x2423' else Char
c
  ls :: [Text]
ls = (if Bool
doTrim
           then (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd Text -> Bool
isBlankLine ([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Text -> Bool
isBlankLine
           else [Text] -> [Text]
forall a. a -> a
id) ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines ([Tok] -> Text
untokenize [Tok]
toks)
  isBlankLine :: Text -> Bool
isBlankLine = (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t')

-- | Apply xparse argument processors (from the @>{...}@ modifier)
-- to a grabbed argument.  Processors are applied from right to left
-- (i.e., the one nearest the argument specifier first).
applyArgProcessors :: PandocMonad m => [[Tok]] -> [Tok] -> LP m [Tok]
applyArgProcessors :: forall (m :: * -> *).
PandocMonad m =>
[[Tok]] -> [Tok] -> LP m [Tok]
applyArgProcessors [] [Tok]
x = [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Tok]
x
applyArgProcessors ([Tok]
p:[[Tok]]
ps) [Tok]
x = [[Tok]]
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *).
PandocMonad m =>
[[Tok]] -> [Tok] -> LP m [Tok]
applyArgProcessors [[Tok]]
ps [Tok]
x ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ([Tok]
    -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> (a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Tok]
-> [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => [Tok] -> [Tok] -> LP m [Tok]
applyArgProcessor [Tok]
p

applyArgProcessor :: PandocMonad m => [Tok] -> [Tok] -> LP m [Tok]
applyArgProcessor :: forall (m :: * -> *). PandocMonad m => [Tok] -> [Tok] -> LP m [Tok]
applyArgProcessor [Tok]
proc [Tok]
x =
  case (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Tok -> Bool
spaceLike [Tok]
proc of
    Tok SourcePos
_ (CtrlSeq Text
"TrimSpaces") Text
_ : [Tok]
_ -> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Tok] -> LP m [Tok]) -> [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ [Tok] -> [Tok]
trimSpaceToks [Tok]
x
    Tok SourcePos
pos (CtrlSeq Text
"ReverseBoolean") Text
_ : [Tok]
_ ->
      [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Tok] -> LP m [Tok]) -> [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ case (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Tok -> Bool) -> Tok -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tok -> Bool
spaceLike) [Tok]
x of
        [Tok SourcePos
_ (CtrlSeq Text
"BooleanTrue") Text
_]  ->
          [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"BooleanFalse") Text
"\\BooleanFalse "]
        [Tok SourcePos
_ (CtrlSeq Text
"BooleanFalse") Text
_] ->
          [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"BooleanTrue") Text
"\\BooleanTrue "]
        [Tok]
_ -> [Tok]
x
    Tok SourcePos
pos (CtrlSeq Text
"SplitArgument") Text
_ : [Tok]
ts
      | Just ([Tok]
numtoks, [Tok]
ts') <- [Tok] -> Maybe ([Tok], [Tok])
tokGroup [Tok]
ts
      , Just Int
numparts <- Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead ([Tok] -> Text
untokenize [Tok]
numtoks)
      , Just ([Tok]
delimtoks, [Tok]
_) <- [Tok] -> Maybe ([Tok], [Tok])
tokGroup [Tok]
ts'
      , (Tok
d : [Tok]
_) <- (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Tok -> Bool
spaceLike [Tok]
delimtoks ->
        let missing :: [Tok]
missing = [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"NoValue") Text
"\\NoValue "]
            pieces :: [[Tok]]
pieces = Int -> [[Tok]] -> [[Tok]]
forall a. Int -> [a] -> [a]
take (Int
numparts Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ([[Tok]] -> [[Tok]]) -> [[Tok]] -> [[Tok]]
forall a b. (a -> b) -> a -> b
$
                       ([Tok] -> [Tok]) -> [[Tok]] -> [[Tok]]
forall a b. (a -> b) -> [a] -> [b]
map [Tok] -> [Tok]
trimSpaceToks (Tok -> [Tok] -> [[Tok]]
splitToksOn Tok
d [Tok]
x) [[Tok]] -> [[Tok]] -> [[Tok]]
forall a. [a] -> [a] -> [a]
++ [Tok] -> [[Tok]]
forall a. a -> [a]
repeat [Tok]
missing
        in [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Tok] -> LP m [Tok]) -> [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ ([Tok] -> [Tok]) -> [[Tok]] -> [Tok]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (SourcePos -> [Tok] -> [Tok]
braceGroup SourcePos
pos) [[Tok]]
pieces
    Tok SourcePos
pos (CtrlSeq Text
"SplitList") Text
_ : [Tok]
ts
      | Just ([Tok]
delimtoks, [Tok]
_) <- [Tok] -> Maybe ([Tok], [Tok])
tokGroup [Tok]
ts
      , (Tok
d : [Tok]
_) <- (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Tok -> Bool
spaceLike [Tok]
delimtoks ->
        [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Tok] -> LP m [Tok]) -> [Tok] -> LP m [Tok]
forall a b. (a -> b) -> a -> b
$ ([Tok] -> [Tok]) -> [[Tok]] -> [Tok]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (SourcePos -> [Tok] -> [Tok]
braceGroup SourcePos
pos) (([Tok] -> [Tok]) -> [[Tok]] -> [[Tok]]
forall a b. (a -> b) -> [a] -> [b]
map [Tok] -> [Tok]
trimSpaceToks (Tok -> [Tok] -> [[Tok]]
splitToksOn Tok
d [Tok]
x))
    Tok SourcePos
pos TokType
_ Text
_ : [Tok]
_ -> do
      -- unknown (or malformed) processor: keep the argument unprocessed
      LogMessage
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> LogMessage
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
SkippedContent (Text
"processor " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Tok] -> Text
untokenize [Tok]
proc) SourcePos
pos
      [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Tok]
x
    [] -> [Tok] -> LP m [Tok]
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Tok]
x
 where
  spaceLike :: Tok -> Bool
spaceLike = [TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline, TokType
Comment]
  braceGroup :: SourcePos -> [Tok] -> [Tok]
braceGroup SourcePos
pos [Tok]
ts = SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{" Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
ts [Tok] -> [Tok] -> [Tok]
forall a. [a] -> [a] -> [a]
++ [SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}"]

-- | Remove space tokens at both ends of a token list.
trimSpaceToks :: [Tok] -> [Tok]
trimSpaceToks :: [Tok] -> [Tok]
trimSpaceToks = (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Tok -> Bool
isSp ([Tok] -> [Tok]) -> ([Tok] -> [Tok]) -> [Tok] -> [Tok]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd Tok -> Bool
isSp
  where isSp :: Tok -> Bool
isSp = [TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline]

-- | Parse a braced group (or a single token) from the beginning of
-- a token list, skipping leading spaces; return the group's
-- contents and the remaining tokens.
tokGroup :: [Tok] -> Maybe ([Tok], [Tok])
tokGroup :: [Tok] -> Maybe ([Tok], [Tok])
tokGroup [Tok]
ts =
  case (Tok -> Bool) -> [Tok] -> [Tok]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile ([TokType] -> Tok -> Bool
tokTypeIn [TokType
Spaces, TokType
Newline, TokType
Comment]) [Tok]
ts of
    Tok SourcePos
_ TokType
Symbol Text
"{" : [Tok]
rest -> Int -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
forall {a}.
(Num a, Eq a) =>
a -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
go (Int
1 :: Int) [] [Tok]
rest
    Tok
t : [Tok]
rest -> ([Tok], [Tok]) -> Maybe ([Tok], [Tok])
forall a. a -> Maybe a
Just ([Tok
t], [Tok]
rest)
    [] -> Maybe ([Tok], [Tok])
forall a. Maybe a
Nothing
 where
  go :: a -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
go a
_ [Tok]
_ [] = Maybe ([Tok], [Tok])
forall a. Maybe a
Nothing
  go a
depth [Tok]
acc (Tok
t : [Tok]
rest)
    | Text -> Tok -> Bool
isSym Text
"{" Tok
t = a -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
go (a
depth a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) (Tok
t Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
acc) [Tok]
rest
    | Text -> Tok -> Bool
isSym Text
"}" Tok
t = if a
depth a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
1
                       then ([Tok], [Tok]) -> Maybe ([Tok], [Tok])
forall a. a -> Maybe a
Just ([Tok] -> [Tok]
forall a. [a] -> [a]
reverse [Tok]
acc, [Tok]
rest)
                       else a -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
go (a
depth a -> a -> a
forall a. Num a => a -> a -> a
- a
1) (Tok
t Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
acc) [Tok]
rest
    | Bool
otherwise = a -> [Tok] -> [Tok] -> Maybe ([Tok], [Tok])
go a
depth (Tok
t Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
acc) [Tok]
rest
  isSym :: Text -> Tok -> Bool
isSym Text
s (Tok SourcePos
_ TokType
Symbol Text
s') = Text
s Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
s'
  isSym Text
_ Tok
_ = Bool
False

-- | Split a token list at each depth-0 occurrence of the delimiter
-- token (compared by token type and text).
splitToksOn :: Tok -> [Tok] -> [[Tok]]
splitToksOn :: Tok -> [Tok] -> [[Tok]]
splitToksOn (Tok SourcePos
_ TokType
dtype Text
dtxt) = Int -> [Tok] -> [Tok] -> [[Tok]]
forall {t}. (Num t, Ord t) => t -> [Tok] -> [Tok] -> [[Tok]]
go (Int
0 :: Int) []
 where
  go :: t -> [Tok] -> [Tok] -> [[Tok]]
go t
_ [Tok]
acc [] = [[Tok] -> [Tok]
forall a. [a] -> [a]
reverse [Tok]
acc]
  go t
depth [Tok]
acc (t :: Tok
t@(Tok SourcePos
_ TokType
toktype Text
txt) : [Tok]
rest)
    | t
depth t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0, TokType
toktype TokType -> TokType -> Bool
forall a. Eq a => a -> a -> Bool
== TokType
dtype, Text
txt Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
dtxt = [Tok] -> [Tok]
forall a. [a] -> [a]
reverse [Tok]
acc [Tok] -> [[Tok]] -> [[Tok]]
forall a. a -> [a] -> [a]
: t -> [Tok] -> [Tok] -> [[Tok]]
go t
0 [] [Tok]
rest
    | Bool
otherwise =
        let depth' :: t
depth' = case Tok
t of
                       Tok SourcePos
_ TokType
Symbol Text
"{" -> t
depth t -> t -> t
forall a. Num a => a -> a -> a
+ t
1
                       Tok SourcePos
_ TokType
Symbol Text
"}" -> t -> t -> t
forall a. Ord a => a -> a -> a
max t
0 (t
depth t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
                       Tok
_ -> t
depth
        in t -> [Tok] -> [Tok] -> [[Tok]]
go t
depth' (Tok
t Tok -> [Tok] -> [Tok]
forall a. a -> [a] -> [a]
: [Tok]
acc) [Tok]
rest

-- | Any token, but if the token contains @stopchar@, it is split
-- so that the part before @stopchar@ is returned and @stopchar@
-- itself (plus what follows) is left in the input.  Used for
-- parsing verbatim text delimited by @stopchar@.
verbTok :: PandocMonad m => Char -> LP m Tok
verbTok :: forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
verbTok Char
stopchar = do
  t@(Tok pos toktype txt) <- LP m Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok
  case T.findIndex (== stopchar) txt of
       Maybe Int
Nothing -> Tok -> LP m Tok
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Tok
t
       Just Int
i  -> do
         let (Text
t1, Text
t2) = Int -> Text -> (Text, Text)
T.splitAt Int
i Text
txt
         TokStream macrosExpanded inp <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) TokStream
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
         setInput $ TokStream macrosExpanded
                  $ Tok (incSourceColumn pos i) Symbol (T.singleton stopchar)
                  : tokenize (incSourceColumn pos (i + 1)) (T.drop 1 t2) ++ inp
         return $ Tok pos toktype t1

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 = LP m a -> LP m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m a -> LP m a) -> LP m a -> LP m a
forall a b. (a -> b) -> a -> b
$ do
  Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'('
  [a] -> a
forall a. Monoid a => [a] -> a
mconcat ([a] -> a)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
-> LP m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m a
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
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 (Char -> LP m Tok
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall a b. (a -> b) -> a -> b
$ do
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
  ch  <- Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall a b. (a -> b) -> a -> b
$ Bool
True Bool
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Bool
forall a b.
a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'='
  minus <- option "" $ "-" <$ symbol '-'
  s1 <- option ""
        (do Tok _ _ s1 <- satisfyTok isWordTok
            guard (case T.uncons s1 of
                     Just (Char
c,Text
_) -> Char -> Bool
isDigit Char
c
                     Maybe (Char, Text)
Nothing -> Bool
False)
            pure s1)
  s2 <- option "" $ try $ do
          symbol '.'
          Tok _ _ t <-  satisfyTok isWordTok
          return ("." <> t)
  let s = Text
s1 Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s2
  let (num, rest) = T.span (\Char
c -> Char -> Bool
isDigit Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') s
  guard $ T.length num > 0
  guard $ rest `elem`
    ["", "pt","pc","in","bp","cm","mm","dd","cc","sp","ex","em",
     "mu", -- "mu" in math mode only
     "px" -- "px" with pdftex and luatex only
    ]
  return $ T.pack ['=' | ch] <> minus <> 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
  pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  report $ SkippedContent raw pos
  return 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
  startCount <- LaTeXState -> Int
sRawTokenCount (LaTeXState -> Int)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  updateState $ \LaTeXState
st -> LaTeXState
st{ sRawScopes = sRawScopes st + 1 }
  result <- parser
  st <- getState
  let raw = [Tok] -> [Tok]
forall a. [a] -> [a]
reverse ([Tok] -> [Tok]) -> [Tok] -> [Tok]
forall a b. (a -> b) -> a -> b
$ Int -> [Tok] -> [Tok]
forall a. Int -> [a] -> [a]
take (LaTeXState -> Int
sRawTokenCount LaTeXState
st Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
startCount) (LaTeXState -> [Tok]
sRawTokens LaTeXState
st)
  setState $ if sRawScopes st <= 1
                then st{ sRawScopes = 0
                       , sRawTokens = []
                       , sRawTokenCount = 0 }
                else st{ sRawScopes = sRawScopes st - 1 }
  return (result, raw)

keyval :: PandocMonad m => LP m (Text, Text)
keyval :: forall (m :: * -> *). PandocMonad m => LP m (Text, Text)
keyval = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text))
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
forall a b. (a -> b) -> a -> b
$ do
  LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
  key <- [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'=') LP m ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                         (Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'-' ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'_' ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isWordTok))
  sp
  val <- option mempty $ do
           symbol '='
           sp
           (untokenize <$> braced) <|>
             (mconcat <$> many1 (
                 (untokenize . snd <$> withRaw braced)
                 <|>
                 (untokenize <$> many1
                      (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)))))
  sp
  optional (symbol ',')
  sp
  return (key, T.strip val)

keyvals :: PandocMonad m => LP m [(Text, Text)]
keyvals :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Text)]
keyvals = ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT
   TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
 -> ParsecT
      TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)])
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
forall a b. (a -> b) -> a -> b
$ Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'[' LP m Tok
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
-> LP m Tok
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
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 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) (Text, Text)
forall (m :: * -> *). PandocMonad m => LP m (Text, Text)
keyval (Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
']') ParsecT
  TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT
     TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [(Text, Text)]
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
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 = LP m Text -> LP m Text
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode (LP m Text -> LP m Text) -> LP m Text -> LP m Text
forall a b. (a -> b) -> a -> b
$ do
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
blankline
  res <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
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 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok (Text -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => Text -> LP m ()
end_ Text
name)
  return $ stripTrailingNewline
         $ untokenize 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) = HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOnEnd Text
"\n" Text
t
  in  if (Char -> Bool) -> Text -> Bool
T.all (Char -> Char -> Bool
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
  Text -> LP m Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"begin"
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
  txt <- [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  guard (t == txt)) ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> ([Char]
"\\begin{" [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
"}")

end_ :: PandocMonad m => Text -> LP m ()
end_ :: forall (m :: * -> *). PandocMonad m => Text -> LP m ()
end_ Text
t = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
  Text -> LP m Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"end"
  ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
  txt <- [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  guard $ t == txt) ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> [Char]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> ([Char]
"\\end{" [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
t [Char] -> ShowS
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
  (_, rawargs) <- LP m () -> LP m ((), [Tok])
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (LP m () -> LP m ((), [Tok])) -> LP m () -> LP m ((), [Tok])
forall a b. (a -> b) -> a -> b
$
      case Text
name of
           Text
"write" -> do
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
 -> LP m ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok])
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall a b. (a -> b) -> a -> b
$ (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isDigitTok -- digits
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"titleformat" -> do
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
             LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
skipopts
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
 -> LP m ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> LP m ()
forall a b. (a -> b) -> a -> b
$ Int
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
4 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"def" ->
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
 -> LP m ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
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 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
           Text
"vadjust" ->
             ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
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 ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced) LP m () -> LP m () -> LP m ()
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ((Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isPreTok) -- see #7531
           Text
_ | Text -> Bool
isFontSizeCommand Text
name -> () -> LP m ()
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
             | Text
name Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"hfil", Text
"hfill", Text
"vfil", Text
"vfill",
                            Text
"hfilneg", Text
"vfilneg"] -> () -> LP m ()
forall a.
a -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
             | Text
name Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"hskip", Text
"vskip", Text
"mskip"] -> do
                 LP m Text
forall (m :: * -> *). PandocMonad m => LP m Text
dimenarg
                 LP m Text -> LP m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (LP m Text -> LP m ()) -> LP m Text -> LP m ()
forall a b. (a -> b) -> a -> b
$ LP m Text -> LP m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m Text -> LP m Text) -> LP m Text -> LP m Text
forall a b. (a -> b) -> a -> b
$ do
                   LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
                   (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok ((Tok -> Bool)
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok)
-> (Tok -> Bool)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall a b. (a -> b) -> a -> b
$
                     \case
                       Tok SourcePos
_ TokType
Word Text
"plus" -> Bool
True
                       Tok SourcePos
_ TokType
Word Text
"minus" -> Bool
True
                       Tok
_ -> Bool
False
                   LP m Text
forall (m :: * -> *). PandocMonad m => LP m Text
dimenarg
             | Bool
otherwise -> do
               LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
skipopts
               Text -> LP m Text -> LP m Text
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Text
"" (LP m Text -> LP m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try LP m Text
forall (m :: * -> *). PandocMonad m => LP m Text
dimenarg)
               ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> LP m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
 -> LP m ())
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
-> LP m ()
forall a b. (a -> b) -> a -> b
$ ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [[Tok]]
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  return $ txt <> untokenize 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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (m :: * -> *). PandocMonad m => LP m Text
overlaySpecification ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall a b. (a -> b) -> a -> b
$ do
  Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'<'
  t <- [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m Tok
-> LP m Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
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 Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
overlayTok (Char -> LP m Tok
forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'>')
  -- see issue #3368
  guard $ not (T.all isLetter t) ||
          t `elem` ["beamer","presentation", "trans",
                    "handout","article", "second"]
  return $ "<" <> t <> ">"

overlayTok :: PandocMonad m => LP m Tok
overlayTok :: forall (m :: * -> *). PandocMonad m => LP m Tok
overlayTok =
  (Tok -> Bool) -> LP m Tok
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 Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
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 = ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall a b. (a -> b) -> a -> b
$ do
  LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
sp
  inner <- [Tok] -> Text
untokenize ([Tok] -> Text)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
  sp
  return $ "[" <> inner <> "]"

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
  st <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) LaTeXState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  let chapnum =
        case LaTeXState -> DottedNum
sLastHeaderNum LaTeXState
st of
             DottedNum (Int
n:[Int]
_) | LaTeXState -> Bool
sHasChapters LaTeXState
st -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
             DottedNum
_                                 -> Maybe Int
forall a. Maybe a
Nothing
  return . DottedNum $
    case getCurrentNum st of
       DottedNum [Int
m,Int
n]  ->
         case Maybe Int
chapnum of
              Just Int
m' | Int
m' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
m   -> [Int
m, Int
nInt -> Int -> Int
forall 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 Int -> Int -> Int
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
  Text -> LP m Tok
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"label"
  t <- LP m [Tok]
forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
  updateState $ \LaTeXState
st -> LaTeXState
st{ sLastLabel = Just $ untokenize t }

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

resetCaption :: PandocMonad m => LP m ()
resetCaption :: forall (m :: * -> *). PandocMonad m => LP m ()
resetCaption = (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((LaTeXState -> LaTeXState)
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ \LaTeXState
st -> LaTeXState
st{ sCaption   = Nothing
                                      , sLastLabel = 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):
  (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((LaTeXState -> LaTeXState)
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ \LaTeXState
s -> LaTeXState
s{ sMacros = NonEmpty.cons (NonEmpty.head (sMacros s))
                                                 (sMacros s) }
  result <- LP m a
p
  updateState $ \LaTeXState
s -> LaTeXState
s{ sMacros = fromMaybe (sMacros s) $
      NonEmpty.nonEmpty (NonEmpty.tail (sMacros s)) }
  end_ name
  return 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 = LP m Inlines -> LP m Inlines
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (LP m Inlines -> LP m Inlines) -> LP m Inlines -> LP m Inlines
forall a b. (a -> b) -> a -> b
$ LP m ()
forall (m :: * -> *). PandocMonad m => LP m ()
spaces LP m () -> LP m Inlines -> LP m Inlines
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                                 LP m Inlines -> LP m Inlines
forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
LP m a -> LP m a
grouped LP m Inlines
inlineParser
                            LP m Inlines -> LP m Inlines -> LP m Inlines
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
-> LP m Inlines -> LP m Inlines
forall a b.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LP m Inlines
inlineParser)
                            LP m Inlines -> LP m Inlines -> LP m Inlines
forall a.
ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LP m Inlines
singleChar'
  where singleChar' :: LP m Inlines
singleChar' = do
          Tok _ _ t <- ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) Tok
forall (m :: * -> *). PandocMonad m => LP m Tok
singleChar
          return $ str 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 = (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((LaTeXState -> LaTeXState)
 -> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ())
-> (LaTeXState -> LaTeXState)
-> ParsecT TokStream LaTeXState (ReaderT (LaTeXEnv m) m) ()
forall a b. (a -> b) -> a -> b
$ \LaTeXState
st ->
   LaTeXState
st{ sMeta = addMetaField field val $ sMeta 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 = ([Inline] -> [Inline]) -> a -> a
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' <- Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"label" [(Text, Text)]
kvs
    , Text
lbl' Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
lbl = [Inline] -> [Inline]
go ((Inline -> Bool) -> [Inline] -> [Inline]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Inline -> Bool
isSpaceOrSoftBreak [Inline]
rest)
  go (Inline
x:[Inline]
xs) = Inline
x Inline -> [Inline] -> [Inline]
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