module Xmobar.Config.Template (parseString) where
import Data.Maybe (fromMaybe)
import qualified Control.Monad as CM
import Text.Parsec ((<|>))
import Text.Read (readMaybe)
import qualified Text.Parsec as P
import qualified Text.Parsec.Combinator as C
import Text.ParserCombinators.Parsec (Parser)
import qualified Xmobar.Config.Types as T
type Context = (T.TextRenderInfo, T.FontIndex, Maybe [T.Action])
retSegment :: Context -> T.Widget -> Parser [T.Segment]
retSegment :: Context -> Widget -> Parser [Segment]
retSegment (TextRenderInfo
i, Int
idx, Maybe [Action]
as) Widget
widget = forall (m :: * -> *) a. Monad m => a -> m a
return [(Widget
widget, TextRenderInfo
i, Int
idx, Maybe [Action]
as)]
parseString :: T.Config -> String -> [T.Segment]
parseString :: Config -> String -> [Segment]
parseString Config
c String
s =
case forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse (Context -> Parser [[Segment]]
stringParser forall {a}. (TextRenderInfo, Int, Maybe a)
ci) String
"" String
s of
Left ParseError
_ -> [(String -> Widget
T.Text forall a b. (a -> b) -> a -> b
$ String
"Could not parse string: " forall a. [a] -> [a] -> [a]
++ String
s, TextRenderInfo
ti, Int
0, forall a. Maybe a
Nothing)]
Right [[Segment]]
x -> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Segment]]
x
where ci :: (TextRenderInfo, Int, Maybe a)
ci = (TextRenderInfo
ti , Int
0, forall a. Maybe a
Nothing)
ti :: TextRenderInfo
ti = String -> Int32 -> Int32 -> [Box] -> TextRenderInfo
T.TextRenderInfo (Config -> String
T.fgColor Config
c) Int32
0 Int32
0 []
stringParser :: Context -> Parser [[T.Segment]]
stringParser :: Context -> Parser [[Segment]]
stringParser Context
c = 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]
C.manyTill (Context -> Parser [Segment]
allParsers Context
c) forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
C.eof
allParsers :: Context -> Parser [T.Segment]
allParsers :: Context -> Parser [Segment]
allParsers Context
c = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
C.choice (Context -> Parser [Segment]
textParser Context
cforall a. a -> [a] -> [a]
:forall a b. (a -> b) -> [a] -> [b]
map (\Context -> Parser [Segment]
f -> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Context -> Parser [Segment]
f Context
c)) [Context -> Parser [Segment]]
parsers)
where parsers :: [Context -> Parser [Segment]]
parsers = [ Context -> Parser [Segment]
iconParser, Context -> Parser [Segment]
hspaceParser, Context -> Parser [Segment]
rawParser, Context -> Parser [Segment]
actionParser
, Context -> Parser [Segment]
fontParser, Context -> Parser [Segment]
boxParser, Context -> Parser [Segment]
colorParser ]
notFollowedBy' :: Parser a -> Parser b -> Parser a
notFollowedBy' :: forall a b. Parser a -> Parser b -> Parser a
notFollowedBy' Parser a
p Parser b
e = do a
x <- Parser a
p
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
C.notFollowedBy forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Parser b
e forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Char
'*')
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
textParser :: Context -> Parser [T.Segment]
textParser :: Context -> Parser [Segment]
textParser Context
c =
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"<" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (forall a b. Parser a -> Parser b -> Parser a
notFollowedBy' (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'<') forall {u}. ParsecT String u Identity String
suffixes))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Context -> Widget -> Parser [Segment]
retSegment Context
c forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Widget
T.Text
where suffixes :: ParsecT String u Identity String
suffixes = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
C.choice forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string)
[ String
"icon=" , String
"hspace=", String
"raw="
, String
"action=", String
"/action>", String
"fn=", String
"/fn>"
, String
"box", String
"/box>", String
"fc=", String
"/fc>" ]
rawParser :: Context -> Parser [T.Segment]
rawParser :: Context -> Parser [Segment]
rawParser Context
c = do
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<raw="
String
lenstr <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
':'
case forall a. Read a => ReadS a
reads String
lenstr of
[(Integer
len,[])] -> do
forall (f :: * -> *). Alternative f => Bool -> f ()
CM.guard ((Integer
len :: Integer) forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Int))
String
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
C.count (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
len) forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.anyChar
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"/>"
Context -> Widget -> Parser [Segment]
retSegment Context
c (String -> Widget
T.Text String
s)
[(Integer, String)]
_ -> forall (m :: * -> *) a. MonadPlus m => m a
CM.mzero
iconParser :: Context -> Parser [T.Segment]
iconParser :: Context -> Parser [Segment]
iconParser Context
c = do
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<icon="
String
i <- 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]
C.manyTill (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
">") (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"/>"))
Context -> Widget -> Parser [Segment]
retSegment Context
c (String -> Widget
T.Icon String
i)
hspaceParser :: Context -> Parser [T.Segment]
hspaceParser :: Context -> Parser [Segment]
hspaceParser Context
c = do
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<hspace="
String
pVal <- 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]
C.manyTill forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"/>"))
Context -> Widget -> Parser [Segment]
retSegment Context
c (Int32 -> Widget
T.Hspace (forall a. a -> Maybe a -> a
fromMaybe Int32
0 forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
pVal))
actionParser :: Context -> Parser [T.Segment]
actionParser :: Context -> Parser [Segment]
actionParser (TextRenderInfo
ti, Int
fi, Maybe [Action]
act) = do
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<action="
String
command <- forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
C.between (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'`') (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'`') (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
"`"))
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf String
">")
String
buttons <- (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'>' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
"1") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.space forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
P.spaces forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
C.between (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"button=") (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
">") (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"12345")))
let a :: Action
a = [Button] -> String -> Action
T.Spawn (String -> [Button]
toButtons String
buttons) String
command
a' :: Maybe [Action]
a' = case Maybe [Action]
act of
Maybe [Action]
Nothing -> forall a. a -> Maybe a
Just [Action
a]
Just [Action]
act' -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Action
a forall a. a -> [a] -> [a]
: [Action]
act'
[[Segment]]
s <- 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]
C.manyTill (Context -> Parser [Segment]
allParsers (TextRenderInfo
ti, Int
fi, Maybe [Action]
a')) (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"</action>")
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Segment]]
s)
toButtons :: String -> [T.Button]
toButtons :: String -> [Button]
toButtons = forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> forall a. Read a => String -> a
read [Char
x])
colorParser :: Context -> Parser [T.Segment]
colorParser :: Context -> Parser [Segment]
colorParser (T.TextRenderInfo String
_ Int32
_ Int32
_ [Box]
bs, Int
fidx, Maybe [Action]
a) = do
String
c <- forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
C.between (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<fc=") (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
">") (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 forall {u}. ParsecT String u Identity Char
colorc)
let colorParts :: (String, String)
colorParts = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
==Char
':') String
c
let (String
ot,String
ob) = case forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
==Char
',') (forall a. Int -> [a] -> [a]
drop Int
1 forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd (String, String)
colorParts) of
(String
top,Char
',':String
btm) -> (String
top, String
btm)
(String
top, String
_) -> (String
top, String
top)
tri :: TextRenderInfo
tri = String -> Int32 -> Int32 -> [Box] -> TextRenderInfo
T.TextRenderInfo (forall a b. (a, b) -> a
fst (String, String)
colorParts)
(forall a. a -> Maybe a -> a
fromMaybe (-Int32
1) forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
ot)
(forall a. a -> Maybe a -> a
fromMaybe (-Int32
1) forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
ob)
[Box]
bs
[[Segment]]
s <- 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]
C.manyTill (Context -> Parser [Segment]
allParsers (TextRenderInfo
tri, Int
fidx, Maybe [Action]
a)) (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"</fc>")
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Segment]]
s)
where colorc :: ParsecT String u Identity Char
colorc = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.alphaNum forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
",:#"
boxParser :: Context -> Parser [T.Segment]
boxParser :: Context -> Parser [Segment]
boxParser (T.TextRenderInfo String
cs Int32
ot Int32
ob [Box]
bs, Int
f, Maybe [Action]
a) = do
String
c <- forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
C.between (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<box") (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
">")
(forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
C.option String
"" (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.alphaNum forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"= #,")))
let b :: Box
b = BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box BoxBorder
T.BBFull (Align -> Int32 -> BoxOffset
T.BoxOffset Align
T.C Int32
0) CInt
1 String
cs (Int32 -> Int32 -> Int32 -> Int32 -> BoxMargins
T.BoxMargins Int32
0 Int32
0 Int32
0 Int32
0)
let g :: Box
g = Box -> [String] -> Box
boxReader Box
b (String -> [String]
words String
c)
[[Segment]]
s <- 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]
C.manyTill
(Context -> Parser [Segment]
allParsers (String -> Int32 -> Int32 -> [Box] -> TextRenderInfo
T.TextRenderInfo String
cs Int32
ot Int32
ob (Box
g forall a. a -> [a] -> [a]
: [Box]
bs), Int
f, Maybe [Action]
a))
(forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"</box>")
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Segment]]
s)
boxReader :: T.Box -> [String] -> T.Box
boxReader :: Box -> [String] -> Box
boxReader Box
b [] = Box
b
boxReader Box
b (String
x:[String]
xs) = Box -> [String] -> Box
boxReader (Box -> String -> String -> Box
boxParamReader Box
b String
param String
val) [String]
xs
where (String
param,String
val) = case forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
==Char
'=') String
x of
(String
p,Char
'=':String
v) -> (String
p, String
v)
(String
p, String
_) -> (String
p, String
"")
boxParamReader :: T.Box -> String -> String -> T.Box
boxParamReader :: Box -> String -> String -> Box
boxParamReader Box
b String
_ String
"" = Box
b
boxParamReader (T.Box BoxBorder
bb BoxOffset
off CInt
lw String
fc BoxMargins
mgs) String
"type" String
val =
BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box (forall a. a -> Maybe a -> a
fromMaybe BoxBorder
bb forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe (String
"BB" forall a. [a] -> [a] -> [a]
++ String
val)) BoxOffset
off CInt
lw String
fc BoxMargins
mgs
boxParamReader (T.Box BoxBorder
bb (T.BoxOffset Align
alg Int32
off) CInt
lw String
fc BoxMargins
mgs) String
"offset" (Char
a:String
o) =
BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box BoxBorder
bb (Align -> Int32 -> BoxOffset
T.BoxOffset Align
align Int32
offset) CInt
lw String
fc BoxMargins
mgs
where offset :: Int32
offset = forall a. a -> Maybe a -> a
fromMaybe Int32
off forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
o
align :: Align
align = forall a. a -> Maybe a -> a
fromMaybe Align
alg forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe [Char
a]
boxParamReader (T.Box BoxBorder
bb BoxOffset
off CInt
lw String
fc BoxMargins
mgs) String
"width" String
val =
BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box BoxBorder
bb BoxOffset
off (forall a. a -> Maybe a -> a
fromMaybe CInt
lw forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
val) String
fc BoxMargins
mgs
boxParamReader (T.Box BoxBorder
bb BoxOffset
off CInt
lw String
_ BoxMargins
mgs) String
"color" String
val =
BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box BoxBorder
bb BoxOffset
off CInt
lw String
val BoxMargins
mgs
boxParamReader (T.Box BoxBorder
bb BoxOffset
off CInt
lw String
fc mgs :: BoxMargins
mgs@(T.BoxMargins Int32
mt Int32
mr Int32
mb Int32
ml)) (Char
'm':String
pos) String
v =
let mgs' :: BoxMargins
mgs' = case String
pos of
String
"t" -> Int32 -> Int32 -> Int32 -> Int32 -> BoxMargins
T.BoxMargins (forall {a}. Read a => a -> a
maybeVal Int32
mt) Int32
mr Int32
mb Int32
ml
String
"r" -> Int32 -> Int32 -> Int32 -> Int32 -> BoxMargins
T.BoxMargins Int32
mt (forall {a}. Read a => a -> a
maybeVal Int32
mr) Int32
mb Int32
ml
String
"b" -> Int32 -> Int32 -> Int32 -> Int32 -> BoxMargins
T.BoxMargins Int32
mt Int32
mr (forall {a}. Read a => a -> a
maybeVal Int32
mb) Int32
ml
String
"l" -> Int32 -> Int32 -> Int32 -> Int32 -> BoxMargins
T.BoxMargins Int32
mt Int32
mr Int32
mb (forall {a}. Read a => a -> a
maybeVal Int32
ml)
String
_ -> BoxMargins
mgs
maybeVal :: a -> a
maybeVal a
d = forall a. a -> Maybe a -> a
fromMaybe a
d (forall a. Read a => String -> Maybe a
readMaybe String
v)
in BoxBorder -> BoxOffset -> CInt -> String -> BoxMargins -> Box
T.Box BoxBorder
bb BoxOffset
off CInt
lw String
fc BoxMargins
mgs'
boxParamReader Box
b String
_ String
_ = Box
b
fontParser :: Context -> Parser [T.Segment]
fontParser :: Context -> Parser [Segment]
fontParser (TextRenderInfo
i, Int
_, Maybe [Action]
a) = do
String
f <- forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
C.between (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"<fn=") (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
">") (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
C.many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit)
[[Segment]]
s <- 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]
C.manyTill (Context -> Parser [Segment]
allParsers (TextRenderInfo
i, forall a. a -> Maybe a -> a
fromMaybe Int
0 forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe String
f, Maybe [Action]
a))
(forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"</fn>")
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Segment]]
s)