{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE OverloadedStrings          #-}
{- |
Module      : Text.Pandoc.Parsing.Smart
Copyright   : © 2006-2022 John MacFarlane
License     : GPL-2.0-or-later
Maintainer  : John MacFarlane <jgm@berkeley.edu>

Smart parsing of quotes, dashes, and other character combinations.
-}

module Text.Pandoc.Parsing.Smart
  ( apostrophe
  , dash
  , doubleCloseQuote
  , doubleQuoteEnd
  , doubleQuoteStart
  , doubleQuoted
  , ellipses
  , singleQuoteEnd
  , singleQuoteStart
  , singleQuoted
  , smartPunctuation
  )
where

import Control.Monad (guard , void)
import Text.Pandoc.Builder (Inlines)
import Text.Pandoc.Options
  ( extensionEnabled
  , Extension(Ext_old_dashes, Ext_smart)
  , ReaderOptions(readerExtensions) )
import Text.Pandoc.Sources
import Text.Pandoc.Parsing.Capabilities
import Text.Pandoc.Parsing.General
import Text.Pandoc.Parsing.Types (ParserT)
import Text.Parsec
  ( (<|>)
  , Stream(..)
  , choice
  , lookAhead
  , manyTill
  , notFollowedBy
  , try
  )

import qualified Text.Pandoc.Builder as B

-- | Parses various ASCII punctuation, quotes, and apostrophe in a smart
-- way, inferring their semantic meaning.
--
-- Fails unless the 'Ext_smart' extension has been enabled.
smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st,
                     HasQuoteContext st m,
                     Stream s m Char, UpdateSourcePos s Char)
                 => ParserT s st m Inlines
                 -> ParserT s st m Inlines
smartPunctuation :: forall st (m :: * -> *) s.
(HasReaderOptions st, HasLastStrPosition st, HasQuoteContext st m,
 Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
smartPunctuation ParserT s st m Inlines
inlineParser = do
  Extension -> ParserT s st m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParserT s st m ()
guardEnabled Extension
Ext_smart
  [ParserT s st m Inlines] -> ParserT s st m Inlines
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ ParserT s st m Inlines -> ParserT s st m Inlines
forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
quoted ParserT s st m Inlines
inlineParser, ParserT s st m Inlines
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
apostrophe, ParserT s st m Inlines
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
doubleCloseQuote, ParserT s st m Inlines
forall st s (m :: * -> *).
(HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
dash, ParserT s st m Inlines
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
ellipses ]

-- | Parses inline text in single or double quotes, assumes English
-- quoting conventions.
quoted :: (HasLastStrPosition st, HasQuoteContext st m,
           Stream s m Char, UpdateSourcePos s Char)
       => ParserT s st m Inlines
       -> ParserT s st m Inlines
quoted :: forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
quoted ParserT s st m Inlines
inlineParser = ParserT s st m Inlines -> ParserT s st m Inlines
forall st (m :: * -> *) s.
(HasQuoteContext st m, HasLastStrPosition st, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
doubleQuoted ParserT s st m Inlines
inlineParser ParserT s st m Inlines
-> ParserT s st m Inlines -> ParserT s st m Inlines
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParserT s st m Inlines -> ParserT s st m Inlines
forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
singleQuoted ParserT s st m Inlines
inlineParser

-- | Parses inline text in single quotes, assumes English quoting
-- conventions.
singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m,
                 Stream s m Char, UpdateSourcePos s Char)
             => ParserT s st m Inlines
             -> ParserT s st m Inlines
singleQuoted :: forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
singleQuoted ParserT s st m Inlines
inlineParser = do
  ParserT s st m ()
forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m ()
singleQuoteStart
  (Inlines -> Inlines
B.singleQuoted (Inlines -> Inlines)
-> ([Inlines] -> Inlines) -> [Inlines] -> Inlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inlines] -> Inlines
forall a. Monoid a => [a] -> a
mconcat ([Inlines] -> Inlines)
-> ParsecT s st m [Inlines] -> ParserT s st m Inlines
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    ParsecT s st m [Inlines] -> ParsecT s st m [Inlines]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try
     (QuoteContext
-> ParsecT s st m [Inlines] -> ParsecT s st m [Inlines]
forall st (m :: * -> *) s a.
HasQuoteContext st m =>
QuoteContext -> ParsecT s st m a -> ParsecT s st m a
withQuoteContext QuoteContext
InSingleQuote (ParserT s st m Inlines
-> ParserT s st m () -> ParsecT s st m [Inlines]
forall end s (m :: * -> *) t st a.
(Show end, Stream s m t) =>
ParserT s st m a -> ParserT s st m end -> ParserT s st m [a]
many1Till ParserT s st m Inlines
inlineParser ParserT s st m ()
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m ()
singleQuoteEnd)))
   ParserT s st m Inlines
-> ParserT s st m Inlines -> ParserT s st m Inlines
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Inlines -> ParserT s st m Inlines
forall (f :: * -> *) a. Applicative f => a -> f a
pure Inlines
"\8217"

-- | Parses inline text in double quotes; assumes English quoting
-- conventions.
doubleQuoted :: (HasQuoteContext st m, HasLastStrPosition st,
                 Stream s m Char, UpdateSourcePos s Char)
             => ParserT s st m Inlines
             -> ParserT s st m Inlines
doubleQuoted :: forall st (m :: * -> *) s.
(HasQuoteContext st m, HasLastStrPosition st, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m Inlines -> ParserT s st m Inlines
doubleQuoted ParserT s st m Inlines
inlineParser = do
  ParserT s st m ()
forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m ()
doubleQuoteStart
  (Inlines -> Inlines
B.doubleQuoted (Inlines -> Inlines)
-> ([Inlines] -> Inlines) -> [Inlines] -> Inlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inlines] -> Inlines
forall a. Monoid a => [a] -> a
mconcat ([Inlines] -> Inlines)
-> ParsecT s st m [Inlines] -> ParserT s st m Inlines
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    ParsecT s st m [Inlines] -> ParsecT s st m [Inlines]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try
     (QuoteContext
-> ParsecT s st m [Inlines] -> ParsecT s st m [Inlines]
forall st (m :: * -> *) s a.
HasQuoteContext st m =>
QuoteContext -> ParsecT s st m a -> ParsecT s st m a
withQuoteContext QuoteContext
InDoubleQuote (ParserT s st m Inlines
-> ParserT s st m () -> ParsecT s st m [Inlines]
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 ParserT s st m Inlines
inlineParser ParserT s st m ()
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m ()
doubleQuoteEnd)))
   ParserT s st m Inlines
-> ParserT s st m Inlines -> ParserT s st m Inlines
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Inlines -> ParserT s st m Inlines
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Inlines
B.str Text
"\8220")

charOrRef :: (Stream s m Char, UpdateSourcePos s Char) => [Char] -> ParserT s st m Char
charOrRef :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParserT s st m Char
charOrRef [Char]
cs =
  [Char] -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
cs ParsecT s st m Char -> ParsecT s st m Char -> ParsecT s st m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s st m Char -> ParsecT s st m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do Char
c <- ParsecT s st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Char
characterReference
                       Bool -> ParsecT s st m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
cs)
                       Char -> ParsecT s st m Char
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c)

-- | Succeeds if the parser is
--
-- * not within single quoted text;
-- * not directly after a word; and
-- * looking at an opening single quote char that's not followed by a
--   space.
--
-- Gobbles the quote character on success.
singleQuoteStart :: (HasLastStrPosition st, HasQuoteContext st m,
                     Stream s m Char, UpdateSourcePos s Char)
                 => ParserT s st m ()
singleQuoteStart :: forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m ()
singleQuoteStart = do
  QuoteContext -> ParserT s st m ()
forall st (m :: * -> *) s t.
(HasQuoteContext st m, Stream s m t) =>
QuoteContext -> ParserT s st m ()
failIfInQuoteContext QuoteContext
InSingleQuote
  -- single quote start can't be right after str
  Bool -> ParserT s st m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParserT s st m ())
-> ParsecT s st m Bool -> ParserT s st m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ParsecT s st m Bool
forall s (m :: * -> *) a st.
(Stream s m a, HasLastStrPosition st) =>
ParserT s st m Bool
notAfterString
  ParserT s st m () -> ParserT s st m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParserT s st m () -> ParserT s st m ())
-> ParserT s st m () -> ParserT s st m ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> ParserT s st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParserT s st m Char
charOrRef [Char]
"'\8216\145"
    ParserT s st m Char -> ParserT s st m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParserT s st m Char -> ParserT s st m ())
-> ParserT s st m Char -> ParserT s st m ()
forall a b. (a -> b) -> a -> b
$ ParserT s st m Char -> ParserT s st m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ((Char -> Bool) -> ParserT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpaceChar))

singleQuoteEnd :: (Stream s m Char, UpdateSourcePos s Char)
               => ParserT s st m ()
singleQuoteEnd :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m ()
singleQuoteEnd = ParsecT s st m () -> ParsecT s st m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s st m () -> ParsecT s st m ())
-> ParsecT s st m () -> ParsecT s st m ()
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParserT s st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParserT s st m Char
charOrRef [Char]
"'\8217\146"
  ParserT s st m Char -> ParsecT s st m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParserT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum

-- | Succeeds if the parser is
--
-- * not within a double quoted text;
--
-- * not directly after a word; and
--
-- * looking at an opening double quote char that's not followed by a
--   space.
--
-- Gobbles the quote character on success.
doubleQuoteStart :: (HasLastStrPosition st,
                     HasQuoteContext st m,
                     Stream s m Char, UpdateSourcePos s Char)
                 => ParserT s st m ()
doubleQuoteStart :: forall st (m :: * -> *) s.
(HasLastStrPosition st, HasQuoteContext st m, Stream s m Char,
 UpdateSourcePos s Char) =>
ParserT s st m ()
doubleQuoteStart = do
  QuoteContext -> ParserT s st m ()
forall st (m :: * -> *) s t.
(HasQuoteContext st m, Stream s m t) =>
QuoteContext -> ParserT s st m ()
failIfInQuoteContext QuoteContext
InDoubleQuote
  Bool -> ParserT s st m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParserT s st m ())
-> ParsecT s st m Bool -> ParserT s st m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ParsecT s st m Bool
forall s (m :: * -> *) a st.
(Stream s m a, HasLastStrPosition st) =>
ParserT s st m Bool
notAfterString
  ParserT s st m () -> ParserT s st m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParserT s st m () -> ParserT s st m ())
-> ParserT s st m () -> ParserT s st m ()
forall a b. (a -> b) -> a -> b
$ do [Char] -> ParserT s st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParserT s st m Char
charOrRef [Char]
"\"\8220\147"
           ParserT s st m Char -> ParserT s st m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParserT s st m Char -> ParserT s st m ())
-> ParserT s st m Char -> ParserT s st m ()
forall a b. (a -> b) -> a -> b
$ ParserT s st m Char -> ParserT s st m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ((Char -> Bool) -> ParserT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpaceChar))

-- | Parses a closing quote character.
doubleQuoteEnd :: (Stream s m Char, UpdateSourcePos s Char)
               => ParserT s st m ()
doubleQuoteEnd :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m ()
doubleQuoteEnd = ParsecT s st m Char -> ParsecT s st m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ([Char] -> ParsecT s st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParserT s st m Char
charOrRef [Char]
"\"\8221\148")

-- | Parses an ASCII apostrophe (@'@) or right single quotation mark and
-- returns a RIGHT SINGLE QUOtatiON MARK character.
apostrophe :: (Stream s m Char, UpdateSourcePos s Char)
           => ParserT s st m Inlines
apostrophe :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
apostrophe = (Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\'' ParsecT s st m Char -> ParsecT s st m Char -> ParsecT s st m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\8217') ParsecT s st m Char
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8217")

-- | Parses an ASCII quotation mark character and returns a RIGHT DOUBLE
-- QUOTATION MARK.
doubleCloseQuote :: (Stream s m Char, UpdateSourcePos s Char)
                 => ParserT s st m Inlines
doubleCloseQuote :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
doubleCloseQuote = Text -> Inlines
B.str Text
"\8221" Inlines -> ParsecT s st m Char -> ParsecT s st m Inlines
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'"'

-- | Parses three dots as HORIZONTAL ELLIPSIS.
ellipses :: (Stream s m Char, UpdateSourcePos s Char)
         => ParserT s st m Inlines
ellipses :: forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
ellipses = ParsecT s st m Inlines -> ParsecT s st m Inlines
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT s st m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"..." ParsecT s st m [Char]
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8230"))

-- | Parses two hyphens as EN DASH and three as EM DASH.
--
-- If the extension @'Ext_old_dashes'@ is enabled, then two hyphens are
-- parsed as EM DASH, and one hyphen is parsed as EN DASH if it is
-- followed by a digit.
dash :: (HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char)
     => ParserT s st m Inlines
dash :: forall st s (m :: * -> *).
(HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char) =>
ParserT s st m Inlines
dash = ParsecT s st m Inlines -> ParsecT s st m Inlines
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s st m Inlines -> ParsecT s st m Inlines)
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall a b. (a -> b) -> a -> b
$ do
  Bool
oldDashes <- Extension -> Extensions -> Bool
extensionEnabled Extension
Ext_old_dashes (Extensions -> Bool)
-> ParsecT s st m Extensions -> ParsecT s st m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ReaderOptions -> Extensions) -> ParsecT s st m Extensions
forall st s (m :: * -> *) t b.
(HasReaderOptions st, Stream s m t) =>
(ReaderOptions -> b) -> ParserT s st m b
getOption ReaderOptions -> Extensions
readerExtensions
  if Bool
oldDashes
     then do
       Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-'
       (Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-' ParsecT s st m Char
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8212"))
         ParsecT s st m Inlines
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT s st m Char -> ParsecT s st m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
digit ParsecT s st m Char
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8211"))
     else do
       [Char] -> ParsecT s st m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"--"
       (Char -> ParsecT s st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-' ParsecT s st m Char
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8212"))
         ParsecT s st m Inlines
-> ParsecT s st m Inlines -> ParsecT s st m Inlines
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Inlines -> ParsecT s st m Inlines
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Inlines
B.str Text
"\8211")