@@ -81,6 +81,9 @@ module Text.Pandoc.Shared (
82 collapseFilePath,
82 collapseFilePath,
83 filteredFilesFromArchive,
83 filteredFilesFromArchive,
84 -- * Error handling
87 -- * Error handling
86 -- * for squashing blocks
89 -- * for squashing blocks
@@ -104,7 +107,7 @@ import Data.List ( find, stripPrefix, intercalate )
104import Data.Maybe (mapMaybe)
107import Data.Maybe (mapMaybe)
105import Data.Version ( showVersion )
108import Data.Version ( showVersion )
106import qualified Data.Map as M
109import qualified Data.Map as M
107−import Network.URI ( escapeURIString, unEscapeString )
110+import Network.URI ( URI(uriScheme), escapeURIString, unEscapeString, parseURI )
108import qualified Data.Set as Set
111import qualified Data.Set as Set
109import System.Directory
112import System.Directory
110import System.FilePath (splitDirectories, isPathSeparator)
113import System.FilePath (splitDirectories, isPathSeparator)
@@ -774,6 +777,70 @@ filteredFilesFromArchive zf f =
774 fileAndBinary :: Archive -> FilePath -> Maybe (FilePath, BL.ByteString)
777 fileAndBinary :: Archive -> FilePath -> Maybe (FilePath, BL.ByteString)
775 fileAndBinary a fp = findEntryByPath fp a >>= \e -> Just (fp, fromEntry e)
778 fileAndBinary a fp = findEntryByPath fp a >>= \e -> Just (fp, fromEntry e)
785+-- | Schemes from http://www.iana.org/assignments/uri-schemes.html plus
786+-- the unofficial schemes doi, javascript, isbn, pmid.
787+schemes :: Set.Set String
788+schemes = Set.fromList
789+ -- Official IANA schemes
790+ [ "aaa", "aaas", "about", "acap", "acct", "acr", "adiumxtra", "afp", "afs"
791+ , "aim", "appdata", "apt", "attachment", "aw", "barion", "beshare", "bitcoin"
792+ , "blob", "bolo", "browserext", "callto", "cap", "chrome", "chrome-extension"
793+ , "cid", "coap", "coaps", "com-eventbrite-attendee", "content", "crid", "cvs"
794+ , "data", "dav", "dict", "dis", "dlna-playcontainer", "dlna-playsingle"
795+ , "dns", "dntp", "dtn", "dvb", "ed2k", "example", "facetime", "fax", "feed"
796+ , "feedready", "file", "filesystem", "finger", "fish", "ftp", "geo", "gg"
797+ , "git", "gizmoproject", "go", "gopher", "graph", "gtalk", "h323", "ham"
798+ , "hcp", "http", "https", "hxxp", "hxxps", "hydrazone", "iax", "icap", "icon"
799+ , "im", "imap", "info", "iotdisco", "ipn", "ipp", "ipps", "irc", "irc6"
800+ , "ircs", "iris", "iris.beep", "iris.lwz", "iris.xpc", "iris.xpcs"
801+ , "isostore", "itms", "jabber", "jar", "jms", "keyparc", "lastfm", "ldap"
802+ , "ldaps", "lvlt", "magnet", "mailserver", "mailto", "maps", "market"
803+ , "message", "mid", "mms", "modem", "mongodb", "moz", "ms-access"
804+ , "ms-browser-extension", "ms-drive-to", "ms-enrollment", "ms-excel"
805+ , "ms-gamebarservices", "ms-getoffice", "ms-help", "ms-infopath"
806+ , "ms-media-stream-id", "ms-officeapp", "ms-project", "ms-powerpoint"
807+ , "ms-publisher", "ms-search-repair", "ms-secondary-screen-controller"
808+ , "ms-secondary-screen-setup", "ms-settings", "ms-settings-airplanemode"
809+ , "ms-settings-bluetooth", "ms-settings-camera", "ms-settings-cellular"
810+ , "ms-settings-cloudstorage", "ms-settings-connectabledevices"
811+ , "ms-settings-displays-topology", "ms-settings-emailandaccounts"
812+ , "ms-settings-language", "ms-settings-location", "ms-settings-lock"
813+ , "ms-settings-nfctransactions", "ms-settings-notifications"
814+ , "ms-settings-power", "ms-settings-privacy", "ms-settings-proximity"
815+ , "ms-settings-screenrotation", "ms-settings-wifi", "ms-settings-workplace"
816+ , "ms-spd", "ms-sttoverlay", "ms-transit-to", "ms-virtualtouchpad"
817+ , "ms-visio", "ms-walk-to", "ms-whiteboard", "ms-whiteboard-cmd", "ms-word"
818+ , "msnim", "msrp", "msrps", "mtqp", "mumble", "mupdate", "mvn", "news", "nfs"
819+ , "ni", "nih", "nntp", "notes", "ocf", "oid", "onenote", "onenote-cmd"
820+ , "opaquelocktoken", "pack", "palm", "paparazzi", "pkcs11", "platform", "pop"
821+ , "pres", "prospero", "proxy", "pwid", "psyc", "qb", "query", "redis"
822+ , "rediss", "reload", "res", "resource", "rmi", "rsync", "rtmfp", "rtmp"
823+ , "rtsp", "rtsps", "rtspu", "secondlife", "service", "session", "sftp", "sgn"
824+ , "shttp", "sieve", "sip", "sips", "skype", "smb", "sms", "smtp", "snews"
825+ , "snmp", "soap.beep", "soap.beeps", "soldat", "spotify", "ssh", "steam"
826+ , "stun", "stuns", "submit", "svn", "tag", "teamspeak", "tel", "teliaeid"
827+ , "telnet", "tftp", "things", "thismessage", "tip", "tn3270", "tool", "turn"
828+ , "turns", "tv", "udp", "unreal", "urn", "ut2004", "v-event", "vemmi"
829+ , "ventrilo", "videotex", "vnc", "view-source", "wais", "webcal", "wpid"
830+ , "ws", "wss", "wtai", "wyciwyg", "xcon", "xcon-userid", "xfire"
831+ , "xmlrpc.beep", "xmlrpc.beeps", "xmpp", "xri", "ymsgr", "z39.50", "z39.50r"
833+ -- Inofficial schemes
834+ , "doi", "isbn", "javascript", "pmid"
837+-- | Check if the string is a valid URL with a IANA or frequently used but
838+-- unofficial scheme (see @schemes@).
839+isURI :: String -> Bool
840+isURI = maybe False hasKnownScheme . parseURI
842+ hasKnownScheme = (`Set.member` schemes) . filter (/= ':') . uriScheme
778--- Squash blocks into inlines
845--- Squash blocks into inlines