git.iko.soy/typeable/pandoc
on master help sign in
Fix indirect hyperlink targets. Closes #512.
commit575014975e5ede206791c9389f07aeb2af9fe652 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 15 Feb 2017, 17:35 (10 years ago) parentebe4072
2 files changed+74−23
src/Text/Pandoc/Readers/RST.hs+33−23 test/command/512.md+41
src/Text/Pandoc/Readers/RST.hs+33−23
@@ -1232,43 +1232,53 @@ explicitLink = try $ do
12321232 then B.str src
12331233 else label'
12341234 -- `link <google_>` is a reference link to _google!
1235− (src',tit,attr) <- case reverse src of
1236− '_':xs -> do
1237− keyTable <- stateKeys <$> getState
1238− let key = toKey $ reverse xs
1239− case M.lookup key keyTable of
1240− Nothing -> do
1241− pos <- getPosition
1242− report $ ReferenceNotFound (show key) pos
1243− return ("","",nullAttr)
1244− Just ((s,t),a) -> return (s,t,a)
1245− _ -> return (src, "", nullAttr)
1235+ ((src',tit),attr) <- case reverse src of
1236+ '_':xs -> lookupKey [] (toKey (reverse xs))
1237+ _ -> return ((src, ""), nullAttr)
12461238 return $ B.linkWith attr (escapeURI src') tit label''
12471239
12481240referenceLink :: PandocMonad m => RSTParser m Inlines
12491241referenceLink = try $ do
12501242 (label',ref) <- withRaw (quotedReferenceName <|> simpleReferenceName) <*
12511243 char '_'
1252− state <- getState
1253− let keyTable = stateKeys state
12541244 let isAnonKey (Key ('_':_)) = True
12551245 isAnonKey _ = False
1246+ state <- getState
1247+ let keyTable = stateKeys state
12561248 key <- option (toKey $ stripTicks ref) $
12571249 do char '_'
12581250 let anonKeys = sort $ filter isAnonKey $ M.keys keyTable
1259− if null anonKeys
1260− then mzero
1261− else return (head anonKeys)
1262− ((src,tit), attr) <- case M.lookup key keyTable of
1263− Nothing -> do
1264− pos <- getPosition
1265− report $ ReferenceNotFound (show key) pos
1266− return (("",""),nullAttr)
1267− Just val -> return val
1251+ case anonKeys of
1252+ [] -> mzero
1253+ (k:_) -> return k
1254+ ((src,tit), attr) <- lookupKey [] key
12681255 -- if anonymous link, remove key so it won't be used again
12691256 when (isAnonKey key) $ updateState $ \s -> s{ stateKeys = M.delete key keyTable }
12701257 return $ B.linkWith attr src tit label'
12711258
1259+-- We keep a list of oldkeys so we can detect lookup loops.
1260+lookupKey :: PandocMonad m
1261+ => [Key] -> Key -> RSTParser m ((String, String), Attr)
1262+lookupKey oldkeys key = do
1263+ pos <- getPosition
1264+ state <- getState
1265+ let keyTable = stateKeys state
1266+ case M.lookup key keyTable of
1267+ Nothing -> do
1268+ let Key key' = key
1269+ report $ ReferenceNotFound key' pos
1270+ return (("",""),nullAttr)
1271+ -- check for keys of the form link_, which need to be resolved:
1272+ Just ((u@(_:_),""),_) | last u == '_' -> do
1273+ let rawkey = init u
1274+ let newkey = toKey rawkey
1275+ if newkey `elem` oldkeys
1276+ then do
1277+ report $ CircularReference rawkey pos
1278+ return (("",""),nullAttr)
1279+ else lookupKey (key:oldkeys) newkey
1280+ Just val -> return val
1281+
12721282autoURI :: Monad m => RSTParser m Inlines
12731283autoURI = do
12741284 (orig, src) <- uri
@@ -1305,7 +1315,7 @@ note = try $ do
13051315 case lookup ref notes of
13061316 Nothing -> do
13071317 pos <- getPosition
1308− report $ ReferenceNotFound (show ref) pos
1318+ report $ ReferenceNotFound ref pos
13091319 return mempty
13101320 Just raw -> do
13111321 -- We temporarily empty the note list while parsing the note,
test/command/512.mdnew file+41
@@ -0,0 +1,41 @@
1+```
2+% pandoc -f rst
3+`click here`__ or `click here`__
4+
5+.. _link1: http://www.example.com/
6+.. _link2: http://johnmacfarlane.net/pandoc/
7+
8+__ link1_
9+__ link2_
10+^D
11+<p><a href="http://www.example.com/">click here</a> or <a href="http://johnmacfarlane.net/pandoc/">click here</a></p>
12+```
13+
14+Multiple indirection:
15+
16+```
17+% pandoc -f rst
18+`click here`__
19+
20+.. _link1: link2_
21+.. _link2: http://johnmacfarlane.net/pandoc/
22+
23+__ link1_
24+^D
25+<p><a href="http://johnmacfarlane.net/pandoc/">click here</a></p>
26+```
27+
28+Loop detection:
29+
30+```
31+% pandoc -f rst
32+`click here`__
33+
34+.. _link1: link2_
35+.. _link2: link1_
36+
37+__ link1_
38+^D
39+<p><a href="">click here</a></p>
40+```
41+