git.iko.soy/typeable/pandoc
on master help sign in
Muse reader: add support for Text:Amuse multiline headings
commit17b04995161847494f00e7e7a6ecdff3d5775266 authorAlexander Krotov <ilabdsf@gmail.com> dateMon 9 Apr 2018, 01:05 (9 years ago) parentbfbc5ee
2 files changed+51−13
src/Text/Pandoc/Readers/Muse.hs+33−9 test/Tests/Readers/Muse.hs+18−4
src/Text/Pandoc/Readers/Muse.hs+33−9
@@ -263,8 +263,8 @@ parseBlocks =
263263 paraStart)
264264 where
265265 parseEnd = mempty <$ eof
266− blockStart = (B.<>) <$> (header <|> blockElements <|> emacsNoteBlock)
267− <*> parseBlocks
266+ blockStart = ((B.<>) <$> (emacsHeading <|> blockElements <|> emacsNoteBlock)
267+ <*> parseBlocks) <|> (uncurry (B.<>) <$> amuseHeadingUntil parseBlocks)
268268 listStart = do
269269 updateState (\st -> st { museInPara = False })
270270 uncurry (B.<>) <$> (anyListUntil parseBlocks <|> amuseNoteBlockUntil parseBlocks)
@@ -362,9 +362,10 @@ separator = try $ do
362362 eol
363363 return $ return B.horizontalRule
364364
365−-- | Parse a heading.
366−header :: PandocMonad m => MuseParser m (F Blocks)
367−header = try $ do
365+-- | Parse a single-line heading.
366+emacsHeading :: PandocMonad m => MuseParser m (F Blocks)
367+emacsHeading = try $ do
368+ guardDisabled Ext_amuse
368369 anchorId <- option "" $ try (parseAnchor <* manyTill spaceChar eol)
369370 getPosition >>= \pos -> guard (sourceColumn pos == 1)
370371 level <- fmap length $ many1 $ char '*'
@@ -374,6 +375,22 @@ header = try $ do
374375 attr <- registerHeader (anchorId, [], []) (runF content def)
375376 return $ B.headerWith attr level <$> content
376377
378+-- | Parse a multi-line heading.
379+-- It is a Text::Amuse extension, Emacs Muse does not allow heading to span multiple lines.
380+amuseHeadingUntil :: PandocMonad m
381+ => MuseParser m a -- ^ Terminator parser
382+ -> MuseParser m (F Blocks, a)
383+amuseHeadingUntil end = try $ do
384+ guardEnabled Ext_amuse
385+ anchorId <- option "" $ try (parseAnchor <* manyTill spaceChar eol)
386+ getPosition >>= \pos -> guard (sourceColumn pos == 1)
387+ level <- fmap length $ many1 $ char '*'
388+ guard $ level <= 5
389+ spaceChar
390+ (content, e) <- paraContentsUntil end
391+ attr <- registerHeader (anchorId, [], []) (runF content def)
392+ return (B.headerWith attr level <$> content, e)
393+
377394-- | Parse an example between @{{{@ and @}}}@.
378395-- It is an Amusewiki extension influenced by Creole wiki, as described in @Text::Amuse@ documentation.
379396example :: PandocMonad m => MuseParser m (F Blocks)
@@ -461,6 +478,16 @@ verseTag = do
461478commentTag :: PandocMonad m => MuseParser m (F Blocks)
462479commentTag = htmlBlock "comment" >> return mempty
463480
481+-- | Parse paragraph contents.
482+paraContentsUntil :: PandocMonad m
483+ => MuseParser m a -- ^ Terminator parser
484+ -> MuseParser m (F Inlines, a)
485+paraContentsUntil end = do
486+ updateState (\st -> st { museInPara = True })
487+ (l, e) <- someUntil inline $ try (manyTill spaceChar eol >> end)
488+ updateState (\st -> st { museInPara = False })
489+ return (trimInlinesF $ mconcat l, e)
490+
464491-- | Parse a paragraph.
465492paraUntil :: PandocMonad m
466493 => MuseParser m a -- ^ Terminator parser
@@ -468,10 +495,7 @@ paraUntil :: PandocMonad m
468495paraUntil end = do
469496 state <- getState
470497 guard $ not $ museInPara state
471− setState $ state{ museInPara = True }
472− (l, e) <- someUntil inline $ try (manyTill spaceChar eol >> end)
473− updateState (\st -> st { museInPara = False })
474− return (fmap B.para $ trimInlinesF $ mconcat l, e)
498+ first (fmap B.para) <$> paraContentsUntil end
475499
476500noteMarker :: PandocMonad m => MuseParser m String
477501noteMarker = try $ do
test/Tests/Readers/Muse.hs+18−4
@@ -558,18 +558,32 @@ tests =
558558 ] =?>
559559 headerWith ("bar",[],[]) 2 "Foo"
560560 , "Headers don't consume anchors separated with a blankline" =:
561− T.unlines [ "** Foo"
562− , ""
561+ T.unlines [ "; A comment to make sure anchor is not parsed as a directive"
563562 , "#bar"
563+ , ""
564+ , "** Foo"
565+ ] =?>
566+ para (spanWith ("bar", [], []) mempty) <>
567+ header 2 "Foo"
568+ , "Headers terminate paragraph" =:
569+ T.unlines [ "foo"
570+ , "* bar"
564571 ] =?>
565− header 2 "Foo" <>
566− para (spanWith ("bar", [], []) mempty)
572+ para "foo" <> header 1 "bar"
567573 , "Headers terminate lists" =:
568574 T.unlines [ " - foo"
569575 , "* bar"
570576 ] =?>
571577 bulletList [ para "foo" ] <>
572578 header 1 "bar"
579+ , test emacsMuse "Paragraphs terminate Emacs Muse headers"
580+ (T.unlines [ "* Foo"
581+ , "bar"
582+ ] =?> header 1 "Foo" <> para "bar")
583+ , "Paragraphs don't terminate Text::Amuse headers" =:
584+ T.unlines [ "* Foo"
585+ , "bar"
586+ ] =?> header 1 "Foo\nbar"
573587 ]
574588 , testGroup "Directives"
575589 [ "Title" =: