@@ -34,7 +34,9 @@ import Text.Pandoc.Definition
34import Text.Pandoc.Shared
34import Text.Pandoc.Shared
35import Text.ParserCombinators.Parsec
35import Text.ParserCombinators.Parsec
36import Control.Monad ( when, unless, liftM )
36import 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 )
39-- | Parse reStructuredText string and return Pandoc document.
41-- | Parse reStructuredText string and return Pandoc document.
40readRST :: ParserState -- ^ Parser state, including options for parser
42readRST :: ParserState -- ^ Parser state, including options for parser
@@ -93,9 +95,6 @@ parseRST = do
93 docMinusKeys <- manyTill (referenceKey <|> lineClump) eof >>= return . concat
95 docMinusKeys <- manyTill (referenceKey <|> lineClump) eof >>= return . concat
94 setInput docMinusKeys
96 setInput docMinusKeys
95 setPosition startPos
97 setPosition startPos
97− let reversedKeys = stateKeys st
98− updateState $ \s -> s { stateKeys = reverse reversedKeys }
99 -- now parse it for real...
98 -- now parse it for real...
100 blocks <- parseBlocks
99 blocks <- parseBlocks
101 let blocks' = filter (/= Null) blocks
100 let blocks' = filter (/= Null) blocks
@@ -540,10 +539,10 @@ referenceName = quotedReferenceName <|>
540referenceKey :: GenParser Char ParserState [Char]
539referenceKey :: GenParser Char ParserState [Char]
541referenceKey = do
540referenceKey = do
542 startPos <- getPosition
541 startPos <- getPosition
543− key <- choice [imageKey, anonymousKey, regularKey]
542+ (key, target) <- choice [imageKey, anonymousKey, regularKey]
544 st <- getState
543 st <- getState
545 let oldkeys = stateKeys st
544 let oldkeys = stateKeys st
546− updateState $ \s -> s { stateKeys = key : oldkeys }
545+ updateState $ \s -> s { stateKeys = M.insert key target oldkeys }
547 optional blanklines
546 optional blanklines
548 endPos <- getPosition
547 endPos <- getPosition
549 -- return enough blanks to replace key
548 -- return enough blanks to replace key
@@ -558,28 +557,29 @@ targetURI = do
558 blanklines
557 blanklines
559 return $ escapeURI $ removeLeadingTrailingSpace $ contents
558 return $ escapeURI $ removeLeadingTrailingSpace $ contents
561−imageKey :: GenParser Char ParserState ([Inline], (String, [Char]))
560+imageKey :: GenParser Char ParserState (Key, Target)
562imageKey = try $ do
561imageKey = try $ do
563 string ".. |"
562 string ".. |"
564 ref <- manyTill inline (char '|')
563 ref <- manyTill inline (char '|')
565 skipSpaces
564 skipSpaces
566 string "image::"
565 string "image::"
567 src <- targetURI
566 src <- targetURI
568− return (normalizeSpaces ref, (src, ""))
567+ return (Key (normalizeSpaces ref), (src, ""))
570−anonymousKey :: GenParser Char st ([Inline], (String, [Char]))
569+anonymousKey :: GenParser Char st (Key, Target)
571anonymousKey = try $ do
570anonymousKey = try $ do
572 oneOfStrings [".. __:", "__"]
571 oneOfStrings [".. __:", "__"]
573 src <- targetURI
572 src <- targetURI
574− return ([Str "_"], (src, ""))
574+ return (Key [Str $ "_" ++ printf "%09d" (sourceLine pos)], (src, ""))
576−regularKey :: GenParser Char ParserState ([Inline], (String, [Char]))
576+regularKey :: GenParser Char ParserState (Key, Target)
577regularKey = try $ do
577regularKey = try $ do
578 string ".. _"
578 string ".. _"
579 ref <- referenceName
579 ref <- referenceName
581 src <- targetURI
581 src <- targetURI
582− return (normalizeSpaces ref, (src, ""))
582+ return (Key (normalizeSpaces ref), (src, ""))
@@ -889,17 +889,21 @@ explicitLink = try $ do
889referenceLink :: GenParser Char ParserState Inline
889referenceLink :: GenParser Char ParserState Inline
890referenceLink = try $ do
890referenceLink = try $ do
891 label' <- (quotedReferenceName <|> simpleReferenceName) >>~ char '_'
891 label' <- (quotedReferenceName <|> simpleReferenceName) >>~ char '_'
892− key <- option label' (do{char '_'; return [Str "_"]}) -- anonymous link
893 state <- getState
892 state <- getState
894 let keyTable = stateKeys state
893 let keyTable = stateKeys state
894+ let isAnonKey (Key [Str ('_':_)]) = True
896+ key <- option (Key label') $
898+ let anonKeys = sort $ filter isAnonKey $ M.keys keyTable
901+ else return (head anonKeys)
895 (src,tit) <- case lookupKeySrc keyTable key of
902 (src,tit) <- case lookupKeySrc keyTable key of
896 Nothing -> fail "no corresponding key"
903 Nothing -> fail "no corresponding key"
897 Just target -> return target
904 Just target -> return target
898− -- if anonymous link, remove first anon key so it won't be used again
905+ -- if anonymous link, remove key so it won't be used again
899− let keyTable' = if (key == [Str "_"]) -- anonymous link?
906+ when (isAnonKey key) $ updateState $ \s -> s{ stateKeys = M.delete key keyTable }
900− then delete ([Str "_"], (src,tit)) keyTable -- remove first anon key
902− setState $ state { stateKeys = keyTable' }
903 return $ Link (normalizeSpaces label') (src, tit)
907 return $ Link (normalizeSpaces label') (src, tit)
905autoURI :: GenParser Char ParserState Inline
909autoURI :: GenParser Char ParserState Inline
@@ -922,7 +926,7 @@ image = try $ do
922 ref <- manyTill inline (char '|')
926 ref <- manyTill inline (char '|')
923 state <- getState
927 state <- getState
924 let keyTable = stateKeys state
928 let keyTable = stateKeys state
925− (src,tit) <- case lookupKeySrc keyTable ref of
929+ (src,tit) <- case lookupKeySrc keyTable (Key ref) of
926 Nothing -> fail "no corresponding key"
930 Nothing -> fail "no corresponding key"
927 Just target -> return target
931 Just target -> return target
928 return $ Image (normalizeSpaces ref) (src, tit)
932 return $ Image (normalizeSpaces ref) (src, tit)