HaTeX-3.0.0: Text/LaTeX/Base/Syntax.hs
-- | LaTeX syntax description in the definition of the 'LaTeX' datatype.
-- If you want to add new commands or environments not defined in
-- the library, import this module and use 'LaTeX' data constructors.
module Text.LaTeX.Base.Syntax
( -- * @LaTeX@ datatype
LaTeX (..)
, braces
, TeXArg (..)
, (<>)
) where
import Data.Text (Text)
import Data.Monoid
import Data.String
-- | A 'LaTeX' object represents some expression written in LaTeX.
data LaTeX =
TeXRaw Text -- ^ Raw text.
| TeXComm String [TeXArg] -- ^ Constructor for commands.
-- First argument is the name of the command.
-- Second, its arguments.
| TeXCommS String
| TeXEnv String [TeXArg] LaTeX -- ^ Constructor for environments.
-- First argument is the name of the environment.
-- Second, its arguments.
-- Third, its content.
| TeXMath LaTeX -- ^ Mathematical expressions.
| TeXNewLine Bool -- ^ Newline character.
| TeXOp String LaTeX LaTeX -- ^ Operators.
| TeXBraces LaTeX -- A expression between braces.
| TeXSeq LaTeX LaTeX -- ^ Sequencing of 'LaTeX' expressions.
-- Use '<>' preferably.
| TeXEmpty -- ^ An empty expression.
-- Neutral element of '<>'.
deriving Show
-- | Alias for 'TeXBraces'.
braces :: LaTeX -> LaTeX
braces = TeXBraces
-- | An argument for a 'LaTeX' command or environment.
data TeXArg =
OptArg LaTeX -- ^ Optional argument.
| FixArg LaTeX -- ^ Fixed argument.
| MOptArg [LaTeX] -- ^ Multiple optional argument.
| SymArg LaTeX -- ^ An argument enclosed between @\<@ and @\>@.
| MSymArg [LaTeX] -- ^ Version of 'SymArg' with multiple options.
deriving Show
-- Monoid instance for 'LaTeX'.
-- | 'mappend' is strict in its first argument.
instance Monoid LaTeX where
mempty = TeXEmpty
mappend TeXEmpty x = x
mappend x TeXEmpty = x
mappend x y = TeXSeq x y
-- | Alias for 'mappend'.
(<>) :: Monoid a => a -> a -> a
(<>) = mappend
-- | 'fromString' escapes LaTeX reserved characters.
instance IsString LaTeX where
fromString = TeXRaw . fromString . protectString
-- | Escape LaTeX reserved characters in a 'String'.
protectString :: String -> String
protectString = mconcat . fmap protectChar
protectChar :: Char -> String
protectChar '#' = "\\#"
protectChar '$' = "\\$"
protectChar '%' = "\\%"
protectChar '^' = "\\^{}"
protectChar '&' = "\\&"
protectChar '{' = "\\{"
protectChar '}' = "\\}"
protectChar '~' = "\\~{}"
protectChar '\\' = "\\textbackslash{}"
protectChar '_' = "\\_{}"
protectChar x = [x]