diff options
| -rw-r--r-- | parser/src/rst.pest | 34 | ||||
| -rw-r--r-- | renderer/src/html/tests.rs | 9 |
2 files changed, 41 insertions, 2 deletions
diff --git a/parser/src/rst.pest b/parser/src/rst.pest index 2f17381..15ccf90 100644 --- a/parser/src/rst.pest +++ b/parser/src/rst.pest @@ -188,6 +188,36 @@ relative_url = { ( "//" ~ host ~ (":" ~ url_port)? ~ path_absolute_url? ) | path host = { ( !(":"|"/"|"?"|"#") ~ url_unit)+ | ("["~(ASCII_HEX_DIGIT|"."|":")+~"]") } special_url_scheme = { ^"ftp" | (^"http" | ^"ws") ~ ^"s"? } /* doesn't include "file" */ arbitrary_scheme = { ASCII_ALPHA ~ ASCII_ALPHANUMERIC* } +/* taken at 2020-09-06 from https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml */ +known_scheme = { + "aaa"|"aaas"|"about"|"acap"|"acct"|"acd"|"acr"|"adiumxtra"|"adt"|"afp"|"afs"|"aim"|"amss"|"android"|"appdata"|"apt"|"ark"|"attachment"|"aw"| + "barion"|"beshare"|"bitcoin"|"bitcoincash"|"blob"|"bolo"|"browserext"|"cabal"|"calculator"|"callto"|"cap"|"cast"|"casts"|"chrome"| + "chrome-extension"|"cid"|"coap"|"coap+tcp"|"coap+ws"|"coaps"|"coaps+tcp"|"coaps+ws"|"com-eventbrite-attendee"|"content"|"conti"|"crid"|"cvs"| + "dab"|"dat"|"data"|"dav"|"diaspora"|"dict"|"did"|"dis"|"dlna-playcontainer"|"dlna-playsingle"|"dns"|"dntp"|"doi"|"dpp"|"drm"|"drop"|"dtmi"| + "dtn"|"dvb"|"dweb"|"ed2k"|"elsi"|"ens"|"ethereum"|"example"|"facetime"|"fax"|"feed"|"feedready"|"file"|"filesystem"|"finger"| + "first-run-pen-experience"|"fish"|"fm"|"ftp"|"fuchsia-pkg"|"geo"|"gg"|"git"|"gizmoproject"|"go"|"gopher"|"graph"|"gtalk"|"h323"|"ham"|"hcap"| + "hcp"|"http"|"https"|"hxxp"|"hxxps"|"hydrazone"|"hyper"|"iax"|"icap"|"icon"|"im"|"imap"|"info"|"iotdisco"|"ipfs"|"ipn"|"ipns"|"ipp"|"ipps"| + "irc"|"irc6"|"ircs"|"iris"|"iris.beep"|"iris.lwz"|"iris.xpc"|"iris.xpcs"|"isostore"|"itms"|"jabber"|"jar"|"jms"|"keyparc"|"lastfm"|"lbry"| + "ldap"|"ldaps"|"leaptofrogans"|"lorawan"|"lvlt"|"magnet"|"mailserver"|"mailto"|"maps"|"market"|"matrix"|"message"|"microsoft.windows.camera"| + "microsoft.windows.camera.multipicker"|"microsoft.windows.camera.picker"|"mid"|"mms"|"modem"|"mongodb"|"moz"|"ms-access"| + "ms-browser-extension"|"ms-calculator"|"ms-drive-to"|"ms-enrollment"|"ms-excel"|"ms-eyecontrolspeech"|"ms-gamebarservices"| + "ms-gamingoverlay"|"ms-getoffice"|"ms-help"|"ms-infopath"|"ms-inputapp"|"ms-lockscreencomponent-config"|"ms-media-stream-id"| + "ms-mixedrealitycapture"|"ms-mobileplans"|"ms-officeapp"|"ms-people"|"ms-project"|"ms-powerpoint"|"ms-publisher"|"ms-restoretabcompanion"| + "ms-screenclip"|"ms-screensketch"|"ms-search"|"ms-search-repair"|"ms-secondary-screen-controller"|"ms-secondary-screen-setup"|"ms-settings"| + "ms-settings-airplanemode"|"ms-settings-bluetooth"|"ms-settings-camera"|"ms-settings-cellular"|"ms-settings-cloudstorage"| + "ms-settings-connectabledevices"|"ms-settings-displays-topology"|"ms-settings-emailandaccounts"|"ms-settings-language"| + "ms-settings-location"|"ms-settings-lock"|"ms-settings-nfctransactions"|"ms-settings-notifications"|"ms-settings-power"| + "ms-settings-privacy"|"ms-settings-proximity"|"ms-settings-screenrotation"|"ms-settings-wifi"|"ms-settings-workplace"|"ms-spd"| + "ms-sttoverlay"|"ms-transit-to"|"ms-useractivityset"|"ms-virtualtouchpad"|"ms-visio"|"ms-walk-to"|"ms-whiteboard"|"ms-whiteboard-cmd"| + "ms-word"|"msnim"|"msrp"|"msrps"|"mss"|"mtqp"|"mumble"|"mupdate"|"mvn"|"news"|"nfs"|"ni"|"nih"|"nntp"|"notes"|"ocf"|"oid"|"onenote"| + "onenote-cmd"|"opaquelocktoken"|"openpgp4fpr"|"otpauth"|"pack"|"palm"|"paparazzi"|"payment"|"payto"|"pkcs11"|"platform"|"pop"|"pres"| + "prospero"|"proxy"|"pwid"|"psyc"|"pttp"|"qb"|"query"|"quic-transport"|"redis"|"rediss"|"reload"|"res"|"resource"|"rmi"|"rsync"|"rtmfp"| + "rtmp"|"rtsp"|"rtsps"|"rtspu"|"secondlife"|"service"|"session"|"sftp"|"sgn"|"shttp"|"sieve"|"simpleledger"|"sip"|"sips"|"skype"|"smb"|"sms"| + "smtp"|"snews"|"snmp"|"soap.beep"|"soap.beeps"|"soldat"|"spiffe"|"spotify"|"ssb"|"ssh"|"steam"|"stun"|"stuns"|"submit"|"swh"|"svn"|"tag"| + "teamspeak"|"tel"|"teliaeid"|"telnet"|"tftp"|"things"|"thismessage"|"tip"|"tn3270"|"tool"|"turn"|"turns"|"tv"|"udp"|"unreal"|"upt"|"urn"| + "ut2004"|"v-event"|"vemmi"|"ventrilo"|"videotex"|"vnc"|"view-source"|"vscode"|"vscode-insiders"|"vsls"|"wais"|"webcal"|"wifi"|"wpid"|"ws"| + "wss"|"wtai"|"wyciwyg"|"xcon"|"xcon-userid"|"xfire"|"xmlrpc.beep"|"xmlrpc.beeps"|"xmpp"|"xri"|"ymsgr"|"z39.50"|"z39.50r"|"z39.50s" +} url_unit = { ASCII_ALPHANUMERIC | "!"|"$"|"&"|"'"|"("|")"|"*"|"+"|","|"-"|"."|"/"|":"|";"|"="|"?"|"@"|"_"|"~" | @@ -209,7 +239,7 @@ url_auto = { ( special_url_scheme ~ "://" ~ host ~ ":" ~ url_port ~ &follows_auto_url ) | ( special_url_scheme ~ "://" ~ ( domain_host_auto | "["~(ASCII_HEX_DIGIT|"."|":")+~"]" ~ &follows_auto_url ) ) | ( ^"file://" ~ ( host ~ !("/:/"|"/|/") )? ~ path_absolute_url_auto ) | - ( arbitrary_scheme ~ ":" ~ relative_url_auto ) + ( known_scheme ~ ":" ~ relative_url_auto ) } domain_host_auto = { ( !(":"|"/"|"?"|"#") ~ url_unit ~ url_units_auto ) | @@ -226,7 +256,7 @@ relative_url_auto = { ( "//" ~ ( domain_host_auto | "["~(ASCII_HEX_DIGIT|"."|":")+~"]" ~ &follows_auto_url ) ) | path_absolute_url_auto | // (prua1|prua2) is path_relative_url_auto minus the &follows_auto_url case - (!(arbitrary_scheme ~ ":") ~ (prua1 | prua2)) + (!(known_scheme ~ ":") ~ (prua1 | prua2)) } url_units_auto = { ( url_unit ~ url_units_auto ) | diff --git a/renderer/src/html/tests.rs b/renderer/src/html/tests.rs index 6a0f350..26c9e72 100644 --- a/renderer/src/html/tests.rs +++ b/renderer/src/html/tests.rs @@ -73,6 +73,15 @@ reference and the target.</p>\ } #[test] +fn standalone_hyperlinks() { + check_renders_to("\ +Some http://url and a not_url_scheme:foo that is not supposed to be an url. +", "\ +<p>Some <a href=\"http://url/\">http://url</a> and a not_url_scheme:foo that is not supposed to be an url.</p>\ +"); +} + +#[test] fn substitution() { check_renders_to("\ A |subst|. |
