git.iko.soy/typeable/pandoc
on master help sign in
Org reader: allow empty list items
cd85c73Albert Krewinkel
src/Text/Pandoc/Readers/Org/BlockStarts.hs+15−11
@@ -75,21 +75,25 @@ latexEnvStart = try $
75 latexEnvName :: Monad m => OrgParser m String
75 latexEnvName :: Monad m => OrgParser m String
76 latexEnvName = try $ mappend <$> many1 alphaNum <*> option "" (string "*")
76 latexEnvName = try $ mappend <$> many1 alphaNum <*> option "" (string "*")
77
77
78−
79−-- | Parses bullet list marker.
80−bulletListStart :: Monad m => OrgParser m ()
78+bulletListStart :: Monad m => OrgParser m Int
81−bulletListStart = try $
79+bulletListStart = try $ do
82− choice
80+ ind <- length <$> many spaceChar
83− [ () <$ skipSpaces <* oneOf "+-" <* skipSpaces1
81+ -- Unindented lists cannot use '*' bullets.
82+ oneOf (if ind == 0 then "+-" else "*+-")
84− , () <$ skipSpaces1 <* char '*' <* skipSpaces1
83+ skipSpaces1 <|> lookAhead eol
85− ]
84+ return (ind + 1)
86
85
87genericListStart :: Monad m
86genericListStart :: Monad m
88 => OrgParser m String
87 => OrgParser m String
89 -> OrgParser m Int
88 -> OrgParser m Int
90−genericListStart listMarker = try $
89+genericListStart listMarker = try $ do
91− (+) <$> (length <$> many spaceChar)
90+ ind <- length <$> many spaceChar
92− <*> (length <$> listMarker <* many1 spaceChar)
91+ void listMarker
92+ skipSpaces1 <|> lookAhead eol
93+ return (ind + 1)
94+
95+eol :: Monad m => OrgParser m ()
96+eol = void (char '\n')
93
97
94orderedListStart :: Monad m => OrgParser m Int
98orderedListStart :: Monad m => OrgParser m Int
95orderedListStart = genericListStart orderedListMarker
99orderedListStart = genericListStart orderedListMarker
src/Text/Pandoc/Readers/Org/Blocks.hs+27−34
@@ -744,7 +744,7 @@ paraOrPlain = try $ do
744 -- is directly followed by a list item, in which case the block is read as
744 -- is directly followed by a list item, in which case the block is read as
745 -- plain text.
745 -- plain text.
746 try (guard nl
746 try (guard nl
747− *> notFollowedBy (inList *> (() <$ orderedListStart <|> bulletListStart))
747+ *> notFollowedBy (inList *> (orderedListStart <|> bulletListStart))
748 *> return (B.para <$> ils))
748 *> return (B.para <$> ils))
749 <|> return (B.plain <$> ils)
749 <|> return (B.plain <$> ils)
750
750
@@ -757,40 +757,34 @@ list :: PandocMonad m => OrgParser m (F Blocks)
757list = choice [ definitionList, bulletList, orderedList ] <?> "list"
757list = choice [ definitionList, bulletList, orderedList ] <?> "list"
758
758
759definitionList :: PandocMonad m => OrgParser m (F Blocks)
759definitionList :: PandocMonad m => OrgParser m (F Blocks)
760+definitionList = try $ do
760−definitionList = try $ do n <- lookAhead (bulletListStart' Nothing)
761+ indent <- lookAhead bulletListStart
761− fmap (B.definitionList . compactifyDL) . sequence
762+ fmap (B.definitionList . compactifyDL) . sequence
762− <$> many1 (definitionListItem $ bulletListStart' (Just n))
763+ <$> many1 (definitionListItem (bulletListStart `indented` indent))
763
764
764bulletList :: PandocMonad m => OrgParser m (F Blocks)
765bulletList :: PandocMonad m => OrgParser m (F Blocks)
766+bulletList = try $ do
765−bulletList = try $ do n <- lookAhead (bulletListStart' Nothing)
767+ indent <- lookAhead bulletListStart
766− fmap (B.bulletList . compactify) . sequence
768+ fmap (B.bulletList . compactify) . sequence
767− <$> many1 (listItem (bulletListStart' $ Just n))
769+ <$> many1 (listItem (bulletListStart `indented` indent))
770+
771+indented :: Monad m => OrgParser m Int -> Int -> OrgParser m Int
772+indented indentedMarker minIndent = try $ do
773+ n <- indentedMarker
774+ guard (minIndent <= n)
775+ return n
768
776
769orderedList :: PandocMonad m => OrgParser m (F Blocks)
777orderedList :: PandocMonad m => OrgParser m (F Blocks)
778+orderedList = try $ do
779+ indent <- lookAhead orderedListStart
770−orderedList = fmap (B.orderedList . compactify) . sequence
780+ fmap (B.orderedList . compactify) . sequence
771− <$> many1 (listItem orderedListStart)
781+ <$> many1 (listItem (orderedListStart `indented` indent))
772−
773−bulletListStart' :: Monad m => Maybe Int -> OrgParser m Int
774−-- returns length of bulletList prefix, inclusive of marker
775−bulletListStart' Nothing = do ind <- length <$> many spaceChar
776− oneOf (bullets $ ind == 0)
777− skipSpaces1
778− return (ind + 1)
779−bulletListStart' (Just n) = do count (n-1) spaceChar
780− oneOf (bullets $ n == 1)
781− many1 spaceChar
782− return n
783−
784−-- Unindented lists are legal, but they can't use '*' bullets.
785−-- We return n to maintain compatibility with the generic listItem.
786−bullets :: Bool -> String
787−bullets unindented = if unindented then "+-" else "*+-"
788
782
789definitionListItem :: PandocMonad m
783definitionListItem :: PandocMonad m
790 => OrgParser m Int
784 => OrgParser m Int
791 -> OrgParser m (F (Inlines, [Blocks]))
785 -> OrgParser m (F (Inlines, [Blocks]))
792−definitionListItem parseMarkerGetLength = try $ do
786+definitionListItem parseIndentedMarker = try $ do
793− markerLength <- parseMarkerGetLength
787+ markerLength <- parseIndentedMarker
794 term <- manyTill (noneOf "\n\r") (try definitionMarker)
788 term <- manyTill (noneOf "\n\r") (try definitionMarker)
795 line1 <- anyLineNewline
789 line1 <- anyLineNewline
796 blank <- option "" ("\n" <$ blankline)
790 blank <- option "" ("\n" <$ blankline)
@@ -802,13 +796,12 @@ definitionListItem parseMarkerGetLength = try $ do
802 definitionMarker =
796 definitionMarker =
803 spaceChar *> string "::" <* (spaceChar <|> lookAhead newline)
797 spaceChar *> string "::" <* (spaceChar <|> lookAhead newline)
804
798
805−
806−-- parse raw text for one list item, excluding start marker and continuations
799+-- | parse raw text for one list item
807listItem :: PandocMonad m
800listItem :: PandocMonad m
808 => OrgParser m Int
801 => OrgParser m Int
809 -> OrgParser m (F Blocks)
802 -> OrgParser m (F Blocks)
810−listItem start = try . withContext ListItemState $ do
803+listItem parseIndentedMarker = try . withContext ListItemState $ do
811− markerLength <- try start
804+ markerLength <- try parseIndentedMarker
812 firstLine <- anyLineNewline
805 firstLine <- anyLineNewline
813 blank <- option "" ("\n" <$ blankline)
806 blank <- option "" ("\n" <$ blankline)
814 rest <- concat <$> many (listContinuation markerLength)
807 rest <- concat <$> many (listContinuation markerLength)
@@ -818,9 +811,9 @@ listItem start = try . withContext ListItemState $ do
818-- Note: nested lists are parsed as continuations.
811-- Note: nested lists are parsed as continuations.
819listContinuation :: Monad m => Int
812listContinuation :: Monad m => Int
820 -> OrgParser m String
813 -> OrgParser m String
821−listContinuation markerLength = try $
814+listContinuation markerLength = try $ do
822 notFollowedBy' blankline
815 notFollowedBy' blankline
823− *> (mappend <$> (concat <$> many1 listLine)
816+ mappend <$> (concat <$> many1 listLine)
824− <*> many blankline)
817+ <*> many blankline
825 where
818 where
826 listLine = try $ indentWith markerLength *> anyLineNewline
819 listLine = try $ indentWith markerLength *> anyLineNewline
test/Tests/Readers/Org.hs+12
@@ -1262,6 +1262,12 @@ tests =
1262 , headerWith ("notvalidlistitem", [], []) 1 "NotValidListItem"
1262 , headerWith ("notvalidlistitem", [], []) 1 "NotValidListItem"
1263 ]
1263 ]
1264
1264
1265+ , "Empty bullet points" =:
1266+ T.unlines [ "-"
1267+ , "- "
1268+ ] =?>
1269+ bulletList [ plain "", plain "" ]
1270+
1265 , "Simple Ordered List" =:
1271 , "Simple Ordered List" =:
1266 ("1. Item1\n" <>
1272 ("1. Item1\n" <>
1267 "2. Item2\n") =?>
1273 "2. Item2\n") =?>
@@ -1289,6 +1295,12 @@ tests =
1289 ]
1295 ]
1290 in orderedListWith listStyle listStructure
1296 in orderedListWith listStyle listStructure
1291
1297
1298+ , "Empty ordered list item" =:
1299+ T.unlines [ "1."
1300+ , "3. "
1301+ ] =?>
1302+ orderedList [ plain "", plain "" ]
1303+
1292 , "Nested Ordered Lists" =:
1304 , "Nested Ordered Lists" =:
1293 ("1. One\n" <>
1305 ("1. One\n" <>
1294 " 1. One-One\n" <>
1306 " 1. One-One\n" <>