git.iko.soy/typeable/pandoc
on master help sign in
Muse reader: forbid whitespace after opening and before closing markup elements
d28dca5Alexander Krotov
src/Text/Pandoc/Readers/Muse.hs+16−4
@@ -78,6 +78,7 @@ data MuseState = MuseState { museMeta :: F Meta -- ^ Document metadata
78 , museOptions :: ReaderOptions
78 , museOptions :: ReaderOptions
79 , museHeaders :: M.Map Inlines String -- ^ List of headers and ids (used for implicit ref links)
79 , museHeaders :: M.Map Inlines String -- ^ List of headers and ids (used for implicit ref links)
80 , museIdentifierList :: Set.Set String
80 , museIdentifierList :: Set.Set String
81+ , museLastSpacePos :: Maybe SourcePos -- ^ Position after last space or newline parsed
81 , museLastStrPos :: Maybe SourcePos -- ^ Position after last str parsed
82 , museLastStrPos :: Maybe SourcePos -- ^ Position after last str parsed
82 , museLogMessages :: [LogMessage]
83 , museLogMessages :: [LogMessage]
83 , museNotes :: M.Map String (SourcePos, F Blocks)
84 , museNotes :: M.Map String (SourcePos, F Blocks)
@@ -89,6 +90,7 @@ instance Default MuseState where
89 , museHeaders = M.empty
90 , museHeaders = M.empty
90 , museIdentifierList = Set.empty
91 , museIdentifierList = Set.empty
91 , museLastStrPos = Nothing
92 , museLastStrPos = Nothing
93+ , museLastSpacePos = Nothing
92 , museLogMessages = []
94 , museLogMessages = []
93 , museNotes = M.empty
95 , museNotes = M.empty
94 }
96 }
@@ -124,6 +126,10 @@ instance HasLogMessages MuseState where
124 addLogMessage m s = s{ museLogMessages = m : museLogMessages s }
126 addLogMessage m s = s{ museLogMessages = m : museLogMessages s }
125 getLogMessages = reverse . museLogMessages
127 getLogMessages = reverse . museLogMessages
126
128
129+updateLastSpacePos :: Monad m => MuseParser m ()
130+updateLastSpacePos = getPosition >>= \pos ->
131+ updateState $ \s -> s { museLastSpacePos = Just pos }
132+
127-- | Parse Muse document
133-- | Parse Muse document
128parseMuse :: PandocMonad m => MuseParser m Pandoc
134parseMuse :: PandocMonad m => MuseParser m Pandoc
129parseMuse = do
135parseMuse = do
@@ -159,6 +165,12 @@ atStart = do
159 st <- getState
165 st <- getState
160 guard $ museLastStrPos st /= Just pos
166 guard $ museLastStrPos st /= Just pos
161
167
168+noSpaceBefore :: PandocMonad m => MuseParser m ()
169+noSpaceBefore = do
170+ pos <- getPosition
171+ st <- getState
172+ guard $ museLastSpacePos st /= Just pos
173+
162firstColumn :: PandocMonad m => MuseParser m ()
174firstColumn :: PandocMonad m => MuseParser m ()
163firstColumn = getPosition >>= \pos -> guard (sourceColumn pos == 1)
175firstColumn = getPosition >>= \pos -> guard (sourceColumn pos == 1)
164
176
@@ -738,7 +750,7 @@ inline = endline <|> inline'
738
750
739-- | Parse a soft break.
751-- | Parse a soft break.
740endline :: PandocMonad m => MuseParser m (F Inlines)
752endline :: PandocMonad m => MuseParser m (F Inlines)
741−endline = try $ pure B.softbreak <$ newline <* notFollowedBy blankline
753+endline = try $ pure B.softbreak <$ newline <* notFollowedBy blankline <* updateLastSpacePos
742
754
743parseAnchor :: PandocMonad m => MuseParser m String
755parseAnchor :: PandocMonad m => MuseParser m String
744parseAnchor = try $ (:)
756parseAnchor = try $ (:)
@@ -769,7 +781,7 @@ footnote = try $ do
769 return $ B.note contents'
781 return $ B.note contents'
770
782
771whitespace :: PandocMonad m => MuseParser m (F Inlines)
783whitespace :: PandocMonad m => MuseParser m (F Inlines)
772−whitespace = try $ pure B.space <$ skipMany1 spaceChar
784+whitespace = try $ pure B.space <$ skipMany1 spaceChar <* updateLastSpacePos
773
785
774-- | Parse @\<br>@ tag.
786-- | Parse @\<br>@ tag.
775br :: PandocMonad m => MuseParser m (F Inlines)
787br :: PandocMonad m => MuseParser m (F Inlines)
@@ -781,8 +793,8 @@ emphasisBetween :: (PandocMonad m, Show a)
781emphasisBetween p = try $ trimInlinesF . mconcat
793emphasisBetween p = try $ trimInlinesF . mconcat
782 <$ atStart
794 <$ atStart
783 <* p
795 <* p
784− <* notFollowedBy spaceChar
796+ <* notFollowedBy space
785− <*> many1Till inline p
797+ <*> many1Till inline (try $ noSpaceBefore *> p)
786 <* notFollowedBy alphaNum
798 <* notFollowedBy alphaNum
787
799
788-- | Parse an inline tag, such as @\<em>@ and @\<strong>@.
800-- | Parse an inline tag, such as @\<em>@ and @\<strong>@.
test/Tests/Readers/Muse.hs+10−2
@@ -66,10 +66,10 @@ tests =
66 -- Emacs Muse allows this
66 -- Emacs Muse allows this
67 , "Newline in the beginning of emphasis" =:
67 , "Newline in the beginning of emphasis" =:
68 "*\nFoo bar*" =?>
68 "*\nFoo bar*" =?>
69− para (emph ("Foo" <> space <> "bar"))
69+ para (text "*\nFoo bar*")
70 , "Newline in the end of emphasis" =:
70 , "Newline in the end of emphasis" =:
71 "*Foo bar\n*" =?>
71 "*Foo bar\n*" =?>
72− para (emph ("Foo" <> space <> "bar"))
72+ para (text "*Foo bar\n*")
73
73
74 , "Comma after closing *" =:
74 , "Comma after closing *" =:
75 "Foo *bar*, baz" =?>
75 "Foo *bar*, baz" =?>
@@ -101,6 +101,14 @@ tests =
101 "***strength***" =?>
101 "***strength***" =?>
102 para (strong . emph $ "strength")
102 para (strong . emph $ "strength")
103
103
104+ , "Strong inside emphasis" =:
105+ "*foo **bar** baz*" =?>
106+ para (emph (text "foo " <> strong (text "bar") <> text " baz"))
107+
108+ , "Emphasis inside strong" =:
109+ "**foo *bar* baz**" =?>
110+ para (strong (text "foo " <> emph (text "bar") <> text " baz"))
111+
104 , test emacsMuse "Underline"
112 , test emacsMuse "Underline"
105 ("_Underline_" =?> para (underlineSpan "Underline"))
113 ("_Underline_" =?> para (underlineSpan "Underline"))
106
114