{-# LANGUAGE OverloadedStrings #-}
module Text.Pandoc.Readers.LaTeX.Macro
( macroDef
)
where
import Text.Pandoc.Extensions (Extension(..))
import Text.Pandoc.Logging (LogMessage(MacroAlreadyDefined))
import Text.Pandoc.Readers.LaTeX.Parsing
import Text.Pandoc.TeX
import Text.Pandoc.Class
import Text.Pandoc.Shared (safeRead)
import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,
optional, space, spaces, withRaw, (<|>))
import Control.Applicative ((<|>), optional)
import qualified Data.Map as M
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.List.NonEmpty as NonEmpty
import Data.List.NonEmpty (NonEmpty(..))
macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
macroDef :: forall (m :: * -> *) a.
(PandocMonad m, Monoid a) =>
(Text -> a) -> LP m a
macroDef Text -> a
constructor = do
(()
_, [Tok]
s) <- forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
withRaw (ParsecT TokStream LaTeXState m ()
commandDef forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT TokStream LaTeXState m ()
environmentDef)
(Text -> a
constructor ([Tok] -> Text
untokenize [Tok]
s) forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardDisabled Extension
Ext_latex_macros)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
where commandDef :: ParsecT TokStream LaTeXState m ()
commandDef = do
[(Text, Macro)]
nameMacroPairs <- forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
newcommand forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *).
PandocMonad m =>
LP m [(Text, Macro)] -> LP m [(Text, Macro)]
checkGlobal (forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
letmacro forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
edefmacro forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
defmacro forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
newif)
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardDisabled Extension
Ext_latex_macros forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
insertMacro [(Text, Macro)]
nameMacroPairs
environmentDef :: ParsecT TokStream LaTeXState m ()
environmentDef = do
Maybe (Text, Macro, Macro)
mbenv <- forall (m :: * -> *).
PandocMonad m =>
LP m (Maybe (Text, Macro, Macro))
newenvironment
case Maybe (Text, Macro, Macro)
mbenv of
Maybe (Text, Macro, Macro)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just (Text
name, Macro
macro1, Macro
macro2) ->
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardDisabled Extension
Ext_latex_macros forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
do forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
insertMacro (Text
name, Macro
macro1)
forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
insertMacro (Text
"end" forall a. Semigroup a => a -> a -> a
<> Text
name, Macro
macro2)
insertMacro :: PandocMonad m => (Text, Macro) -> LP m ()
insertMacro :: forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
insertMacro (Text
name, macro' :: Macro
macro'@(Macro MacroScope
GlobalScope ExpansionPoint
_ [ArgSpec]
_ Maybe [Tok]
_ [Tok]
_)) =
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s ->
LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NonEmpty.map (forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Text
name Macro
macro') (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) }
insertMacro (Text
name, macro' :: Macro
macro'@(Macro MacroScope
GroupScope ExpansionPoint
_ [ArgSpec]
_ Maybe [Tok]
_ [Tok]
_)) =
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState forall a b. (a -> b) -> a -> b
$ \LaTeXState
s ->
LaTeXState
s{ sMacros :: NonEmpty (Map Text Macro)
sMacros = forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Text
name Macro
macro' (forall a. NonEmpty a -> a
NonEmpty.head (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s)) forall a. a -> [a] -> NonEmpty a
:|
forall a. NonEmpty a -> [a]
NonEmpty.tail (LaTeXState -> NonEmpty (Map Text Macro)
sMacros LaTeXState
s) }
lookupMacro :: PandocMonad m => Text -> LP m Macro
lookupMacro :: forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
lookupMacro Text
name = do
Map Text Macro
macros :| [Map Text Macro]
_ <- LaTeXState -> NonEmpty (Map Text Macro)
sMacros forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
name Map Text Macro
macros of
Just Macro
m -> forall (m :: * -> *) a. Monad m => a -> m a
return Macro
m
Maybe Macro
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Macro not found"
letmacro :: PandocMonad m => LP m [(Text, Macro)]
letmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
letmacro = do
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"let"
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
Tok SourcePos
_ (CtrlSeq Text
name) Text
_ <- forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'='
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Tok
target <- forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m Tok
singleChar
case Tok
target of
(Tok SourcePos
_ (CtrlSeq Text
name') Text
_) ->
(do Macro
m <- forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
lookupMacro Text
name'
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Text
name, Macro
m)])
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Text
name,
MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenDefined [] forall a. Maybe a
Nothing [Tok
target])]
Tok
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Text
name, MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenDefined [] forall a. Maybe a
Nothing [Tok
target])]
checkGlobal :: PandocMonad m => LP m [(Text, Macro)] -> LP m [(Text, Macro)]
checkGlobal :: forall (m :: * -> *).
PandocMonad m =>
LP m [(Text, Macro)] -> LP m [(Text, Macro)]
checkGlobal LP m [(Text, Macro)]
p =
(forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"global" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
(forall a b. (a -> b) -> [a] -> [b]
map (\(Text
n, Macro MacroScope
_ ExpansionPoint
expand [ArgSpec]
arg Maybe [Tok]
optarg [Tok]
contents) ->
(Text
n, MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GlobalScope ExpansionPoint
expand [ArgSpec]
arg Maybe [Tok]
optarg [Tok]
contents)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LP m [(Text, Macro)]
p))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LP m [(Text, Macro)]
p
edefmacro :: PandocMonad m => LP m [(Text, Macro)]
edefmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
edefmacro = do
MacroScope
scope <- (MacroScope
GroupScope forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"edef")
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (MacroScope
GlobalScope forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"xdef")
(Text
name, [Tok]
contents) <- forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
Tok SourcePos
_ (CtrlSeq Text
name) Text
_ <- forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq
[Tok]
contents <- forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
forall (m :: * -> *) a. Monad m => a -> m a
return (Text
name, [Tok]
contents)
[Tok]
contents' <- forall (m :: * -> *) a. PandocMonad m => LP m a -> [Tok] -> LP m a
parseFromToks (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall (m :: * -> *). PandocMonad m => LP m Tok
anyTok) [Tok]
contents
forall (m :: * -> *) a. Monad m => a -> m a
return [(Text
name, MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
scope ExpansionPoint
ExpandWhenDefined [] forall a. Maybe a
Nothing [Tok]
contents')]
defmacro :: PandocMonad m => LP m [(Text, Macro)]
defmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
defmacro = do
MacroScope
scope <- (MacroScope
GroupScope forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"def")
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (MacroScope
GlobalScope forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"gdef")
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
Tok SourcePos
_ (CtrlSeq Text
name) Text
_ <- forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq
[ArgSpec]
argspecs <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall (m :: * -> *). PandocMonad m => LP m ArgSpec
argspecArg forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). PandocMonad m => LP m ArgSpec
argspecPattern)
[Tok]
contents <- forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
forall (m :: * -> *) a. Monad m => a -> m a
return [(Text
name, MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
scope ExpansionPoint
ExpandWhenUsed [ArgSpec]
argspecs forall a. Maybe a
Nothing [Tok]
contents)]
newif :: PandocMonad m => LP m [(Text, Macro)]
newif :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
newif = do
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"newif"
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
Tok SourcePos
pos (CtrlSeq Text
name) Text
_ <- forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq
let base :: Text
base = Int -> Text -> Text
T.drop Int
2 Text
name
forall (m :: * -> *) a. Monad m => a -> m a
return [ (Text
name, MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [] forall a. Maybe a
Nothing
[SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"iffalse") Text
"\\iffalse"])
, (Text
base forall a. Semigroup a => a -> a -> a
<> Text
"true",
MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [] forall a. Maybe a
Nothing
[ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"def") Text
"\\def"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
name) (Text
"\\" forall a. Semigroup a => a -> a -> a
<> Text
name)
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"iftrue") Text
"\\iftrue"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}"
])
, (Text
base forall a. Semigroup a => a -> a -> a
<> Text
"false",
MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [] forall a. Maybe a
Nothing
[ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"def") Text
"\\def"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
name) (Text
"\\" forall a. Semigroup a => a -> a -> a
<> Text
name)
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"iffalse") Text
"\\iffalse"
, SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}"
])
]
argspecArg :: PandocMonad m => LP m ArgSpec
argspecArg :: forall (m :: * -> *). PandocMonad m => LP m ArgSpec
argspecArg = do
Tok SourcePos
_ (Arg Int
i) Text
_ <- forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok Tok -> Bool
isArgTok
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int -> ArgSpec
ArgNum Int
i
argspecPattern :: PandocMonad m => LP m ArgSpec
argspecPattern :: forall (m :: * -> *). PandocMonad m => LP m ArgSpec
argspecPattern =
[Tok] -> ArgSpec
Pattern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
satisfyTok (\(Tok SourcePos
_ TokType
toktype' Text
txt) ->
(TokType
toktype' forall a. Eq a => a -> a -> Bool
== TokType
Symbol Bool -> Bool -> Bool
|| TokType
toktype' forall a. Eq a => a -> a -> Bool
== TokType
Word) Bool -> Bool -> Bool
&&
(Text
txt forall a. Eq a => a -> a -> Bool
/= Text
"{" Bool -> Bool -> Bool
&& Text
txt forall a. Eq a => a -> a -> Bool
/= Text
"\\" Bool -> Bool -> Bool
&& Text
txt forall a. Eq a => a -> a -> Bool
/= Text
"}")))
newcommand :: PandocMonad m => LP m [(Text, Macro)]
newcommand :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
newcommand = do
Tok SourcePos
pos (CtrlSeq Text
mtype) Text
_ <- forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"newcommand" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"renewcommand" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"providecommand" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"DeclareMathOperator" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"DeclareRobustCommand"
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
Tok SourcePos
_ (CtrlSeq Text
name) Text
txt <- do
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'*')
forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
(forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'{' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). PandocMonad m => LP m Tok
anyControlSeq forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'}')
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Int
numargs <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Int
0 forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m Int
bracketedNum
let argspecs :: [ArgSpec]
argspecs = forall a b. (a -> b) -> [a] -> [b]
map Int -> ArgSpec
ArgNum [Int
1..Int
numargs]
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Maybe [Tok]
optarg <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
[Tok]
contents' <- forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
let contents :: [Tok]
contents =
case Text
mtype of
Text
"DeclareMathOperator" ->
SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"mathop") Text
"\\mathop"
forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{"
forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"mathrm") Text
"\\mathrm"
forall a. a -> [a] -> [a]
: SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"{"
forall a. a -> [a] -> [a]
: ([Tok]
contents' forall a. [a] -> [a] -> [a]
++
[ SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}", SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos TokType
Symbol Text
"}" ])
Text
_ -> [Tok]
contents'
let macro :: Macro
macro = MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [ArgSpec]
argspecs Maybe [Tok]
optarg [Tok]
contents
(do forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
lookupMacro Text
name
case Text
mtype of
Text
"providecommand" -> forall (m :: * -> *) a. Monad m => a -> m a
return []
Text
"renewcommand" -> forall (m :: * -> *) a. Monad m => a -> m a
return [(Text
name, Macro
macro)]
Text
_ -> [] forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (Text -> SourcePos -> LogMessage
MacroAlreadyDefined Text
txt SourcePos
pos))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Text
name, Macro
macro)]
newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
newenvironment :: forall (m :: * -> *).
PandocMonad m =>
LP m (Maybe (Text, Macro, Macro))
newenvironment = do
SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
Tok SourcePos
_ (CtrlSeq Text
mtype) Text
_ <- forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"newenvironment" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"renewenvironment" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
controlSeq Text
"provideenvironment"
forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
withVerbatimMode forall a b. (a -> b) -> a -> b
$ do
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). PandocMonad m => Char -> LP m Tok
symbol Char
'*'
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Text
name <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
braced
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Int
numargs <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Int
0 forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m Int
bracketedNum
forall (m :: * -> *). PandocMonad m => LP m ()
spaces
Maybe [Tok]
optarg <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
let argspecs :: [ArgSpec]
argspecs = forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> Int -> ArgSpec
ArgNum Int
i) [Int
1..Int
numargs]
[Tok]
startcontents <- forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
[Tok]
endcontents <- forall (m :: * -> *). PandocMonad m => LP m ()
spaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracedOrToken
let bg :: Tok
bg = SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"bgroup") Text
"\\bgroup "
let eg :: Tok
eg = SourcePos -> TokType -> Text -> Tok
Tok SourcePos
pos (Text -> TokType
CtrlSeq Text
"egroup") Text
"\\egroup "
let result :: (Text, Macro, Macro)
result = (Text
name,
MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [ArgSpec]
argspecs Maybe [Tok]
optarg
(Tok
bgforall a. a -> [a] -> [a]
:[Tok]
startcontents),
MacroScope
-> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
Macro MacroScope
GroupScope ExpansionPoint
ExpandWhenUsed [] forall a. Maybe a
Nothing
([Tok]
endcontents forall a. [a] -> [a] -> [a]
++ [Tok
eg]))
(do forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
lookupMacro Text
name
case Text
mtype of
Text
"provideenvironment" -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Text
"renewenvironment" -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (Text, Macro, Macro)
result)
Text
_ -> do
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
MacroAlreadyDefined Text
name SourcePos
pos
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (Text, Macro, Macro)
result)
bracketedNum :: PandocMonad m => LP m Int
bracketedNum :: forall (m :: * -> *). PandocMonad m => LP m Int
bracketedNum = do
Text
ds <- [Tok] -> Text
untokenize forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). PandocMonad m => LP m [Tok]
bracketedToks
case forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
ds of
Just Int
i -> forall (m :: * -> *) a. Monad m => a -> m a
return Int
i
Maybe Int
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Int
0