git.iko.soy/typeable/pandoc
on master help sign in
Fixed handling of email addresses in markdown and reStructuredText.

Consolidated uri and email address parsers. (Resolves Issue #37.) + New emailAddress and uri parsers in Text.Pandoc.Shared. uri parser uses parseURI from Network.URI. emailAddress parser properly handles email addresses with periods in them. + Removed uri and emailAddress parsers from Text.Pandoc.Readers.RST. + Removed uri and emailAddress parsers from Text.Pandoc.Readers.Markdown. git-svn-id: https://pandoc.googlecode.com/svn/trunk@1149 788f1e2b-df1e-0410-8736-df70ead52e1b

commit0681d1d3e7ccf0cddfd452957c2d792df014064b authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateFri 21 Dec 2007, 16:13 (19 years ago) parent246e5f9
3 files changed+36−40
Text/Pandoc/Readers/Markdown.hs+1−15 Text/Pandoc/Readers/RST.hs−25 Text/Pandoc/Shared.hs+35
Text/Pandoc/Readers/Markdown.hs+1−15
@@ -35,7 +35,6 @@ import Data.List ( transpose, isPrefixOf, isSuffixOf, lookup, sortBy, findIndex
3535import Data.Ord ( comparing )
3636import Data.Char ( isAlphaNum )
3737import Data.Maybe ( fromMaybe )
38−import Network.URI ( isURI )
3938import Text.Pandoc.Definition
4039import Text.Pandoc.Shared
4140import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment )
@@ -850,22 +849,9 @@ referenceLink label = do
850849 Nothing -> fail "no corresponding key"
851850 Just target -> return target
852851
853−emailAddress = try $ do
854− name <- many1 (alphaNum <|> char '+')
855− char '@'
856− first <- many1 alphaNum
857− rest <- many1 (char '.' >> many1 alphaNum)
858− return $ "mailto:" ++ name ++ "@" ++ joinWithSep "." (first:rest)
859−
860−uri = try $ do
861− str <- many1 (noneOf "\n\t >")
862− if isURI str
863− then return str
864− else fail "not a URI"
865−
866852autoLink = try $ do
867853 char '<'
868− src <- uri <|> emailAddress
854+ src <- uri <|> (emailAddress >>= (return . ("mailto:" ++)))
869855 char '>'
870856 let src' = if "mailto:" `isPrefixOf` src
871857 then drop 7 src
Text/Pandoc/Readers/RST.hs−25
@@ -592,35 +592,10 @@ referenceLink = try $ do
592592 setState $ state { stateKeys = keyTable' }
593593 return $ Link (normalizeSpaces label) src
594594
595−uriScheme = oneOfStrings [ "http://", "https://", "ftp://", "file://",
596− "mailto:", "news:", "telnet:" ]
597−
598−uri = try $ do
599− scheme <- uriScheme
600− identifier <- many1 (noneOf " \t\n")
601− return $ scheme ++ identifier
602−
603595autoURI = do
604596 src <- uri
605597 return $ Link [Str src] (src, "")
606598
607−emailChar = alphaNum <|> oneOf "-+_."
608−
609−emailAddress = try $ do
610− firstLetter <- alphaNum
611− restAddr <- many emailChar
612− let addr = firstLetter:restAddr
613− char '@'
614− dom <- domain
615− return $ addr ++ '@':dom
616−
617−domainChar = alphaNum <|> char '-'
618−
619−domain = do
620− first <- many1 domainChar
621− dom <- many1 (try (do{ char '.'; many1 domainChar }))
622− return $ joinWithSep "." (first:dom)
623−
624599autoEmail = do
625600 src <- emailAddress
626601 return $ Link [Str src] ("mailto:" ++ src, "")
Text/Pandoc/Shared.hs+35
@@ -64,6 +64,8 @@ module Text.Pandoc.Shared (
6464 charsInBalanced,
6565 charsInBalanced',
6666 romanNumeral,
67+ emailAddress,
68+ uri,
6769 withHorizDisplacement,
6870 nullBlock,
6971 failIfStrict,
@@ -105,6 +107,7 @@ import Text.Pandoc.CharacterReferences ( characterReference )
105107import Data.Char ( toLower, toUpper, ord, isLower, isUpper )
106108import Data.List ( find, isPrefixOf )
107109import Control.Monad ( join )
110+import Network.URI ( parseURI, URI (..), isAllowedInURI )
108111
109112--
110113-- List processing
@@ -404,6 +407,38 @@ romanNumeral upperCase = do
404407 then fail "not a roman numeral"
405408 else return total
406409
410+-- Parsers for email addresses and URIs
411+
412+emailChar = alphaNum <|> oneOf "-+_."
413+
414+domainChar = alphaNum <|> char '-'
415+
416+domain = do
417+ first <- many1 domainChar
418+ dom <- many1 (try (do{ char '.'; many1 domainChar }))
419+ return $ joinWithSep "." (first:dom)
420+
421+-- | Parses an email address; returns string.
422+emailAddress :: GenParser Char st [Char]
423+emailAddress = try $ do
424+ firstLetter <- alphaNum
425+ restAddr <- many emailChar
426+ let addr = firstLetter:restAddr
427+ char '@'
428+ dom <- domain
429+ return $ addr ++ '@':dom
430+
431+-- | Parses a URI.
432+uri = try $ do
433+ str <- many1 $ satisfy isAllowedInURI
434+ case parseURI str of
435+ Just uri' -> if uriScheme uri' `elem` [ "http:", "https:", "ftp:",
436+ "file:", "mailto:",
437+ "news:", "telnet:" ]
438+ then return $ show uri'
439+ else fail "not a URI"
440+ Nothing -> fail "not a URI"
441+
407442-- | Applies a parser, returns tuple of its results and its horizontal
408443-- displacement (the difference between the source column at the end
409444-- and the source column at the beginning). Vertical displacement