git.iko.soy/typeable/pandoc
on master help sign in
Org reader: fix paragraph/list interaction

Paragraphs can be followed by lists, even if there is no blank line between the two blocks. However, this should only be true if the paragraph is not within a list, were the preceding block should be parsed as a plain instead of paragraph (to allow for compact lists). Thanks to @rgaiacs for bringing this up. This fixes #2464.

commitb27366780f3df7bef7f8d24540f27b50d07b596a authorAlbert Krewinkel <albert@zeitkraut.de> dateSat 24 Oct 2015, 18:04 (11 years ago) parenta7150bb
2 files changed+37−6
src/Text/Pandoc/Readers/Org.hs+29−6 tests/Tests/Readers/Org.hs+8
src/Text/Pandoc/Readers/Org.hs+29−6
@@ -2,7 +2,7 @@
22{-# LANGUAGE GeneralizedNewtypeDeriving #-}
33{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-}
44{-
5−Copyright (C) 2014-2015 Albert Krewinkel <tarleb@moltkeplatz.de>
5+Copyright (C) 2014-2015 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
66
77This program is free software; you can redistribute it and/or modify
88it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2424 Copyright : Copyright (C) 2014 Albert Krewinkel
2525 License : GNU GPL, version 2 or above
2626
27− Maintainer : Albert Krewinkel <tarleb@moltkeplatz.de>
27+ Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
2828
2929Conversion of org-mode formatted plain text to 'Pandoc' document.
3030-}
@@ -140,6 +140,7 @@ data OrgParserState = OrgParserState
140140 , orgStateMeta :: Meta
141141 , orgStateMeta' :: F Meta
142142 , orgStateNotes' :: OrgNoteTable
143+ , orgStateParserContext :: ParserContext
143144 , orgStateIdentifiers :: [String]
144145 , orgStateHeaderMap :: M.Map Inlines String
145146 }
@@ -181,6 +182,7 @@ defaultOrgParserState = OrgParserState
181182 , orgStateMeta = nullMeta
182183 , orgStateMeta' = return nullMeta
183184 , orgStateNotes' = []
185+ , orgStateParserContext = NullState
184186 , orgStateIdentifiers = []
185187 , orgStateHeaderMap = M.empty
186188 }
@@ -291,6 +293,23 @@ blanklines =
291293 <* updateLastPreCharPos
292294 <* updateLastForbiddenCharPos
293295
296+-- | Succeeds when we're in list context.
297+inList :: OrgParser ()
298+inList = do
299+ ctx <- orgStateParserContext <$> getState
300+ guard (ctx == ListItemState)
301+
302+-- | Parse in different context
303+withContext :: ParserContext -- ^ New parser context
304+ -> OrgParser a -- ^ Parser to run in that context
305+ -> OrgParser a
306+withContext context parser = do
307+ oldContext <- orgStateParserContext <$> getState
308+ updateState $ \s -> s{ orgStateParserContext = context }
309+ result <- parser
310+ updateState $ \s -> s{ orgStateParserContext = oldContext }
311+ return result
312+
294313--
295314-- parsing blocks
296315--
@@ -891,9 +910,13 @@ noteBlock = try $ do
891910paraOrPlain :: OrgParser (F Blocks)
892911paraOrPlain = try $ do
893912 ils <- parseInlines
894− nl <- option False (newline >> return True)
895− try (guard nl >> notFollowedBy (orderedListStart <|> bulletListStart) >>
896− return (B.para <$> ils))
913+ nl <- option False (newline *> return True)
914+ -- Read block as paragraph, except if we are in a list context and the block
915+ -- is directly followed by a list item, in which case the block is read as
916+ -- plain text.
917+ try (guard nl
918+ *> notFollowedBy (inList *> (orderedListStart <|> bulletListStart))
919+ *> return (B.para <$> ils))
897920 <|> (return (B.plain <$> ils))
898921
899922inlinesTillNewline :: OrgParser (F Inlines)
@@ -970,7 +993,7 @@ definitionListItem parseMarkerGetLength = try $ do
970993-- parse raw text for one list item, excluding start marker and continuations
971994listItem :: OrgParser Int
972995 -> OrgParser (F Blocks)
973−listItem start = try $ do
996+listItem start = try . withContext ListItemState $ do
974997 markerLength <- try start
975998 firstLine <- anyLineNewline
976999 blank <- option "" ("\n" <$ blankline)
tests/Tests/Readers/Org.hs+8
@@ -870,6 +870,14 @@ tests =
870870 , para "orange"
871871 , para "peach"
872872 ]
873+
874+ , "Recognize preceding paragraphs in non-list contexts" =:
875+ unlines [ "CLOSED: [2015-10-19 Mon 15:03]"
876+ , "- Note taken on [2015-10-19 Mon 13:24]"
877+ ] =?>
878+ mconcat [ para "CLOSED: [2015-10-19 Mon 15:03]"
879+ , bulletList [ plain "Note taken on [2015-10-19 Mon 13:24]" ]
880+ ]
873881 ]
874882
875883 , testGroup "Tables"