@@ -141,14 +141,16 @@ nonindentSpaces = do
141141 then return sps
142142 else unexpected "indented line"
143143
144−skipNonindentSpaces :: MarkdownParser ()
144+-- returns number of spaces parsed
145+skipNonindentSpaces :: MarkdownParser Int
145146skipNonindentSpaces = do
146147 tabStop <- getOption readerTabStop
147− atMostSpaces (tabStop - 1)
148+ atMostSpaces (tabStop - 1) <* notFollowedBy (char ' ')
148149
149−atMostSpaces :: Int -> MarkdownParser ()
150−atMostSpaces 0 = notFollowedBy (char ' ')
151−atMostSpaces n = (char ' ' >> atMostSpaces (n-1)) <|> return ()
150+atMostSpaces :: Int -> MarkdownParser Int
151+atMostSpaces n
152+ | n > 0 = (char ' ' >> (+1) <$> atMostSpaces (n-1)) <|> return 0
153+ | otherwise = return 0
152154
153155litChar :: MarkdownParser Char
154156litChar = escapedChar'
@@ -717,35 +719,42 @@ blockQuote = do
717719bulletListStart :: MarkdownParser ()
718720bulletListStart = try $ do
719721 optional newline -- if preceded by a Plain block in a list context
722+ startpos <- sourceColumn <$> getPosition
720723 skipNonindentSpaces
721724 notFollowedBy' (() <$ hrule) -- because hrules start out just like lists
722725 satisfy isBulletListMarker
723− spaceChar <|> lookAhead newline
724− skipSpaces
726+ endpos <- sourceColumn <$> getPosition
727+ tabStop <- getOption readerTabStop
728+ lookAhead (newline <|> spaceChar)
729+ () <$ atMostSpaces (tabStop - (endpos - startpos))
725730
726731anyOrderedListStart :: MarkdownParser (Int, ListNumberStyle, ListNumberDelim)
727732anyOrderedListStart = try $ do
728733 optional newline -- if preceded by a Plain block in a list context
734+ startpos <- sourceColumn <$> getPosition
729735 skipNonindentSpaces
730736 notFollowedBy $ string "p." >> spaceChar >> digit -- page number
731− (guardDisabled Ext_fancy_lists >>
732− do many1 digit
733− char '.'
734− spaceChar
735− return (1, DefaultStyle, DefaultDelim))
736− <|> do (num, style, delim) <- anyOrderedListMarker
737− -- if it could be an abbreviated first name, insist on more than one space
738− if delim == Period && (style == UpperAlpha || (style == UpperRoman &&
739− num `elem` [1, 5, 10, 50, 100, 500, 1000]))
740− then char '\t' <|> (try $ char ' ' >> spaceChar)
741− else spaceChar
742− skipSpaces
743− return (num, style, delim)
737+ res <- do guardDisabled Ext_fancy_lists
738+ many1 digit
739+ char '.'
740+ return (1, DefaultStyle, DefaultDelim)
741+ <|> do (num, style, delim) <- anyOrderedListMarker
742+ -- if it could be an abbreviated first name,
743+ -- insist on more than one space
744+ when (delim == Period && (style == UpperAlpha ||
745+ (style == UpperRoman &&
746+ num `elem` [1, 5, 10, 50, 100, 500, 1000]))) $
747+ () <$ spaceChar
748+ return (num, style, delim)
749+ endpos <- sourceColumn <$> getPosition
750+ tabStop <- getOption readerTabStop
751+ lookAhead (newline <|> spaceChar)
752+ atMostSpaces (tabStop - (endpos - startpos))
753+ return res
744754
745755listStart :: MarkdownParser ()
746756listStart = bulletListStart <|> (anyOrderedListStart >> return ())
747757
748−-- parse a line of a list item (start = parser for beginning of list item)
749758listLine :: MarkdownParser String
750759listLine = try $ do
751760 notFollowedBy' (do indentSpaces
@@ -753,19 +762,21 @@ listLine = try $ do
753762 listStart)
754763 notFollowedByHtmlCloser
755764 optional (() <$ indentSpaces)
756− chunks <- manyTill
765+ listLineCommon
766+
767+listLineCommon :: MarkdownParser String
768+listLineCommon = concat <$> manyTill
757769 ( many1 (satisfy $ \c -> c /= '\n' && c /= '<')
758770 <|> liftM snd (htmlTag isCommentTag)
759771 <|> count 1 anyChar
760772 ) newline
761− return $ concat chunks
762773
763774-- parse raw text for one list item, excluding start marker and continuations
764775rawListItem :: MarkdownParser a
765776 -> MarkdownParser String
766777rawListItem start = try $ do
767778 start
768− first <- listLine
779+ first <- listLineCommon
769780 rest <- many (notFollowedBy listStart >> notFollowedBy blankline >> listLine)
770781 blanks <- many blankline
771782 return $ unlines (first:rest) ++ blanks
@@ -823,8 +834,14 @@ orderedList = try $ do
823834 items <- fmap sequence $ many1 $ listItem
824835 ( try $ do
825836 optional newline -- if preceded by Plain block in a list
837+ startpos <- sourceColumn <$> getPosition
826838 skipNonindentSpaces
827− orderedListMarker style delim )
839+ res <- orderedListMarker style delim
840+ endpos <- sourceColumn <$> getPosition
841+ tabStop <- getOption readerTabStop
842+ lookAhead (newline <|> spaceChar)
843+ atMostSpaces (tabStop - (endpos - startpos))
844+ return res )
828845 start' <- option 1 $ guardEnabled Ext_startnum >> return start
829846 return $ B.orderedListWith (start', style, delim) <$> fmap compactify' items
830847