@@ -34,7 +34,9 @@ import Text.Pandoc.Definition
3434import Text.Pandoc.Shared
3535import Text.ParserCombinators.Parsec
3636import Control.Monad ( when, unless, liftM )
37−import Data.List ( findIndex, delete, intercalate, transpose )
37+import Data.List ( findIndex, intercalate, transpose, sort )
38+import qualified Data.Map as M
39+import Text.Printf ( printf )
3840
3941-- | Parse reStructuredText string and return Pandoc document.
4042readRST :: ParserState -- ^ Parser state, including options for parser
@@ -93,9 +95,6 @@ parseRST = do
9395 docMinusKeys <- manyTill (referenceKey <|> lineClump) eof >>= return . concat
9496 setInput docMinusKeys
9597 setPosition startPos
96− st <- getState
97− let reversedKeys = stateKeys st
98− updateState $ \s -> s { stateKeys = reverse reversedKeys }
9998 -- now parse it for real...
10099 blocks <- parseBlocks
101100 let blocks' = filter (/= Null) blocks
@@ -540,10 +539,10 @@ referenceName = quotedReferenceName <|>
540539referenceKey :: GenParser Char ParserState [Char]
541540referenceKey = do
542541 startPos <- getPosition
543− key <- choice [imageKey, anonymousKey, regularKey]
542+ (key, target) <- choice [imageKey, anonymousKey, regularKey]
544543 st <- getState
545544 let oldkeys = stateKeys st
546− updateState $ \s -> s { stateKeys = key : oldkeys }
545+ updateState $ \s -> s { stateKeys = M.insert key target oldkeys }
547546 optional blanklines
548547 endPos <- getPosition
549548 -- return enough blanks to replace key
@@ -558,28 +557,29 @@ targetURI = do
558557 blanklines
559558 return $ escapeURI $ removeLeadingTrailingSpace $ contents
560559
561−imageKey :: GenParser Char ParserState ([Inline], (String, [Char]))
560+imageKey :: GenParser Char ParserState (Key, Target)
562561imageKey = try $ do
563562 string ".. |"
564563 ref <- manyTill inline (char '|')
565564 skipSpaces
566565 string "image::"
567566 src <- targetURI
568− return (normalizeSpaces ref, (src, ""))
567+ return (Key (normalizeSpaces ref), (src, ""))
569568
570−anonymousKey :: GenParser Char st ([Inline], (String, [Char]))
569+anonymousKey :: GenParser Char st (Key, Target)
571570anonymousKey = try $ do
572571 oneOfStrings [".. __:", "__"]
573572 src <- targetURI
574− return ([Str "_"], (src, ""))
573+ pos <- getPosition
574+ return (Key [Str $ "_" ++ printf "%09d" (sourceLine pos)], (src, ""))
575575
576−regularKey :: GenParser Char ParserState ([Inline], (String, [Char]))
576+regularKey :: GenParser Char ParserState (Key, Target)
577577regularKey = try $ do
578578 string ".. _"
579579 ref <- referenceName
580580 char ':'
581581 src <- targetURI
582− return (normalizeSpaces ref, (src, ""))
582+ return (Key (normalizeSpaces ref), (src, ""))
583583
584584--
585585-- tables
@@ -889,17 +889,21 @@ explicitLink = try $ do
889889referenceLink :: GenParser Char ParserState Inline
890890referenceLink = try $ do
891891 label' <- (quotedReferenceName <|> simpleReferenceName) >>~ char '_'
892− key <- option label' (do{char '_'; return [Str "_"]}) -- anonymous link
893892 state <- getState
894893 let keyTable = stateKeys state
894+ let isAnonKey (Key [Str ('_':_)]) = True
895+ isAnonKey _ = False
896+ key <- option (Key label') $
897+ do char '_'
898+ let anonKeys = sort $ filter isAnonKey $ M.keys keyTable
899+ if null anonKeys
900+ then pzero
901+ else return (head anonKeys)
895902 (src,tit) <- case lookupKeySrc keyTable key of
896903 Nothing -> fail "no corresponding key"
897904 Just target -> return target
898− -- if anonymous link, remove first anon key so it won't be used again
899− let keyTable' = if (key == [Str "_"]) -- anonymous link?
900− then delete ([Str "_"], (src,tit)) keyTable -- remove first anon key
901− else keyTable
902− setState $ state { stateKeys = keyTable' }
905+ -- if anonymous link, remove key so it won't be used again
906+ when (isAnonKey key) $ updateState $ \s -> s{ stateKeys = M.delete key keyTable }
903907 return $ Link (normalizeSpaces label') (src, tit)
904908
905909autoURI :: GenParser Char ParserState Inline
@@ -922,7 +926,7 @@ image = try $ do
922926 ref <- manyTill inline (char '|')
923927 state <- getState
924928 let keyTable = stateKeys state
925− (src,tit) <- case lookupKeySrc keyTable ref of
929+ (src,tit) <- case lookupKeySrc keyTable (Key ref) of
926930 Nothing -> fail "no corresponding key"
927931 Just target -> return target
928932 return $ Image (normalizeSpaces ref) (src, tit)