@@ -576,6 +576,23 @@ decimal = do
576 num <- many1 digit
576 num <- many1 digit
577 return (Decimal, read num)
577 return (Decimal, read num)
579+-- | Parses a '@' and optional label and
580+-- returns (DefaultStyle, [next example number]). The next
581+-- example number is incremented in parser state, and the label
582+-- (if present) is added to the label table.
583+exampleNum :: GenParser Char ParserState (ListNumberStyle, Int)
586+ lab <- many (alphaNum <|> oneOf "_-")
588+ let num = stateNextExample st
589+ let newlabels = if null lab
590+ then stateExamples st
591+ else M.insert lab num $ stateExamples st
592+ updateState $ \s -> s{ stateNextExample = num + 1
593+ , stateExamples = newlabels }
594+ return (Example, num)
579-- | Parses a '#' returns (DefaultStyle, 1).
596-- | Parses a '#' returns (DefaultStyle, 1).
580defaultNum :: GenParser Char st (ListNumberStyle, Int)
597defaultNum :: GenParser Char st (ListNumberStyle, Int)
581defaultNum = do
598defaultNum = do
@@ -600,10 +617,10 @@ romanOne = (char 'i' >> return (LowerRoman, 1)) <|>
600 (char 'I' >> return (UpperRoman, 1))
617 (char 'I' >> return (UpperRoman, 1))
602-- | Parses an ordered list marker and returns list attributes.
619-- | Parses an ordered list marker and returns list attributes.
603−anyOrderedListMarker :: GenParser Char st ListAttributes
620+anyOrderedListMarker :: GenParser Char ParserState ListAttributes
604anyOrderedListMarker = choice $
621anyOrderedListMarker = choice $
605 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
622 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
606− numParser <- [decimal, defaultNum, romanOne,
623+ numParser <- [decimal, exampleNum, defaultNum, romanOne,
607 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
624 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
609-- | Parses a list number (num) followed by a period, returns list attributes.
626-- | Parses a list number (num) followed by a period, returns list attributes.
@@ -638,11 +655,12 @@ inTwoParens num = try $ do
638-- returns number.
655-- returns number.
639orderedListMarker :: ListNumberStyle
656orderedListMarker :: ListNumberStyle
640 -> ListNumberDelim
657 -> ListNumberDelim
641− -> GenParser Char st Int
658+ -> GenParser Char ParserState Int
642orderedListMarker style delim = do
659orderedListMarker style delim = do
643 let num = defaultNum <|> -- # can continue any kind of list
660 let num = defaultNum <|> -- # can continue any kind of list
644 case style of
661 case style of
645 DefaultStyle -> decimal
662 DefaultStyle -> decimal
663+ Example -> exampleNum
646 Decimal -> decimal
664 Decimal -> decimal
647 UpperRoman -> upperRoman
665 UpperRoman -> upperRoman
648 LowerRoman -> lowerRoman
666 LowerRoman -> lowerRoman
@@ -700,7 +718,9 @@ data ParserState = ParserState
700 stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
718 stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
701 stateColumns :: Int, -- ^ Number of columns in terminal
719 stateColumns :: Int, -- ^ Number of columns in terminal
702 stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
720 stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
703− stateIndentedCodeClasses :: [String] -- ^ Classes to use for indented code blocks
721+ stateIndentedCodeClasses :: [String], -- ^ Classes to use for indented code blocks
722+ stateNextExample :: Int, -- ^ Number of next example
723+ stateExamples :: M.Map String Int -- ^ Map from example labels to numbers
705 deriving Show
725 deriving Show
@@ -725,7 +745,9 @@ defaultParserState =
725 stateLiterateHaskell = False,
745 stateLiterateHaskell = False,
726 stateColumns = 80,
746 stateColumns = 80,
727 stateHeaderTable = [],
747 stateHeaderTable = [],
728− stateIndentedCodeClasses = [] }
748+ stateIndentedCodeClasses = [],
749+ stateNextExample = 1,
750+ stateExamples = M.empty }
730data HeaderType
752data HeaderType
731 = SingleHeader Char -- ^ Single line of characters underneath
753 = SingleHeader Char -- ^ Single line of characters underneath
@@ -855,6 +877,7 @@ orderedListMarkers (start, numstyle, numdelim) =
855 let singleton c = [c]
877 let singleton c = [c]
856 nums = case numstyle of
878 nums = case numstyle of
857 DefaultStyle -> map show [start..]
879 DefaultStyle -> map show [start..]
880+ Example -> map show [start..]
858 Decimal -> map show [start..]
881 Decimal -> map show [start..]
859 UpperAlpha -> drop (start - 1) $ cycle $
882 UpperAlpha -> drop (start - 1) $ cycle $
860 map singleton ['A'..'Z']
883 map singleton ['A'..'Z']