@@ -45,6 +45,7 @@ import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
4545import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
4646import Text.ParserCombinators.Parsec
4747import Control.Monad (when, liftM, unless)
48+import Network.URI ( unEscapeString, escapeURIString, isUnescapedInURI )
4849
4950-- | Read markdown from an input string and return a Pandoc document.
5051readMarkdown :: ParserState -- ^ Parser state, including options for parser
@@ -73,6 +74,13 @@ specialChars = "\\[]*_~`<>$!^-.&'\"\8216\8217\8220\8221;"
7374-- auxiliary functions
7475--
7576
77+-- | Escape a URI in a markdown-appropriate way. First,
78+-- we unescape the string, since we don't want to screw things
79+-- up if they've entered a properly encoded URI. Then, we
80+-- escape the result.
81+escapeURI :: String -> String
82+escapeURI = escapeURIString isUnescapedInURI . unEscapeString
83+
7684indentSpaces :: GenParser Char ParserState [Char]
7785indentSpaces = try $ do
7886 state <- getState
@@ -194,7 +202,7 @@ referenceKey = try $ do
194202 tit <- option "" referenceTitle
195203 blanklines
196204 endPos <- getPosition
197− let newkey = (lab, (intercalate "+" $ words $ removeTrailingSpace src, tit))
205+ let newkey = (lab, (escapeURI $ removeTrailingSpace src, tit))
198206 st <- getState
199207 let oldkeys = stateKeys st
200208 updateState $ \s -> s { stateKeys = newkey : oldkeys }
@@ -1173,7 +1181,7 @@ source' = do
11731181 tit <- option "" linkTitle
11741182 skipSpaces
11751183 eof
1176− return (intercalate "+" $ words $ removeTrailingSpace src, tit)
1184+ return (escapeURI $ removeTrailingSpace src, tit)
11771185
11781186linkTitle :: GenParser Char st String
11791187linkTitle = try $ do