mdoc-0.1.0.0: src/Mdoc/Parse/TroffMacro.hs
-- |
--
-- Module : Mdoc.Parse.TroffMacro
-- Copyright : (c) 2026 Patrick Brisbin
-- License : AGPL-3
-- Maintainer : pbrisbin@gmail.com
-- Stability : experimental
-- Portability : POSIX
module Mdoc.Parse.TroffMacro
( parseTroffMacro
) where
import Mdoc.Prelude
import Control.Monad.State.Strict (get, modify)
import Data.Monoid (Last (..))
import Data.Set qualified as Set
import Data.Text qualified as T
import Mdoc.Parse
import Mdoc.TroffMacro
parseTroffMacro :: Parser TroffMacro
parseTroffMacro =
choice
[ try troffMacroDefine
, try troffMacroDefineS
, try troffMacroCall
, try troffMacroEnd
]
troffMacroDefine :: Parser TroffMacro
troffMacroDefine = do
void $ string ".de" >> hspace1
name <- restOfWord
mClose <- optional $ hspace1 *> restOfWord
lift
$ modify (<> mempty {defined = Set.singleton name, nextClose = Last mClose})
pure $ TroffMacroDefine name mClose
troffMacroDefineS :: Parser TroffMacro
troffMacroDefineS = do
void $ string ".ds" >> hspace1
name <- restOfWord
value <- optional $ hspace1 *> restOfLine
lift $ modify (<> mempty {defined = Set.singleton name})
pure $ TroffMacroDefineS name value
troffMacroCall :: Parser TroffMacro
troffMacroCall = do
s <- lift get
let
names = toList s.defined
pName =
choice (map string names)
<?> "custom macro "
<> unpack (T.intercalate "|" names)
macroCall TroffMacroCall pName restOfWord
troffMacroEnd :: Parser TroffMacro
troffMacroEnd = do
s <- lift get
t <- case getLast s.nextClose of
Nothing -> string ".."
Just cl -> char '.' *> string cl
TroffMacroEnd t <$ peek (hspace >> eol)