2

Here is a valid URL which loads the intended page when I paste it into my browser:

https://en.wikipedia.org/wiki/Blue_(disambiguation)

For reasons I will explain later, I want to hex encode the last segment so it will look like this:

https://en.wikipedia.org/wiki/Blue_%28disambiguation%29

This doesn't change the URL:

(url-encode-url
 "https://en.wikipedia.org/wiki/Blue_(disambiguation)")
;; => "https://en.wikipedia.org/wiki/Blue_(disambiguation)"

This breaks the URL, making it unacceptable to the web browser:

(url-hexify-string
 "https://en.wikipedia.org/wiki/Blue_(disambiguation)")
;; => "https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBlue_%28disambiguation%29"

The reason I want the URL encoded this way is because markdown links get broken if the URL contains parens. When I write an Org document containing a link to the URL and then export it to markdown by C-c C-e m M it produces this:

[wikipedia](https://en.wikipedia.org/wiki/Blue_(disambiguation))

When the markdown is rendered to HTML (server side) it produces a link to https://en.wikipedia.org/wiki/Blue_(disambiguation (missing the closing parenthesis) followed by a ) (plain text closing parenthesis) which is not part of the link address:

<a href="https://en.wikipedia.org/wiki/Blue_(disambiguation">blue</a>)

I can't change the markdown processing server side, and I don't know enough about org-export to say whether this is a legitimate bug or intended behavior. I only know that it is not the behavior I desire, and I have to work around the problem somehow.

I have found that I can repair the link by expressing the parentheses in percent encoded form. So I want to transform the broken markdown produced by org-export to look as follows:

[wikipedia](https://en.wikipedia.org/wiki/Blue_%28disambiguation%29)

The following is as close as I have come, but it is very inconvenient to use and seems like it would be quite fragile in face of unanticipated inputs:

;; (correctly-hex-encode-wikipedia-url
;;  "https://en.wikipedia.org/wiki/Blue_(disambiguation)")
;; => "https://en.wikipedia.org/wiki/Blue_%28disambiguation%29"
;; 
(defun correctly-hex-encode-wikipedia-url (url)
  "Fix last segment of URL so it doesn't break markdown.
Wikipedia urls contain parens in the last segment which break
markdown links. This replaces them with percent encoded (aka
hexified) characters. It may do other unwanted things depending
on what you give it. This is just my way of getting around the
broken markdown exported from Org mode."
  (concat
   (substring url 0
      (string-match "[^/]+$" url))
   (url-hexify-string (substring url
                                 (string-match "[^/]+$" url)
                                 (length url)))))

(defun replace-region-with-correctly-hex-encoded-wikipedia-url ()
  "Changes the url in region."
  (interactive)
  (insert
   (correctly-hex-encode-wikipedia-url
    (delete-and-extract-region (point) (mark)))))

Edit to incorporate browse-url-url-encode-chars

(defun replace-region-with-correctly-hex-encoded-wikipedia-url ()
  "Replaces text in region with percent encoded parens."
  (interactive)
  (insert
   (browse-url-url-encode-chars
    (delete-and-extract-region (point) (mark))
    "[()]")))
  • The correct function is url-encode-url. The problem is in Markdown. () characters are totally fine as part of URI Component as per URL schema. However, to work around Markdown's shortcomings, you could use url-generic-parse-url, and then url-hexify-string the file part of the struct produced from parse. – wvxvw Jun 25 '17 at 4:54
  • @wvxvw Agree markdown is the problem, but it is everywhere (even here), and I don't see why org-export can't accommodate its shortcomings. I don't know if parens are allowed in the file part of the address, but they aren't specifically allowed in hostnames. I'm not sure there's anything to be gained by parsing the url, but thank you for informing me of url-generic-parse-url. The real sticking point now is how to integrate what I've got into my workflow as smoothly as possible. I just want to give folks a chance to suggest better ways. – takatakatek Jun 27 '17 at 13:56
  • What about replace-region-with-correctly-hex-encoded-wikipedia-url doesn't fit with your workflow? – dcorking Feb 22 at 15:20
2

The function browse-url-url-encode-chars translates

https://en.wikipedia.org/wiki/Blue_(disambiguation)

into

https://en.wikipedia.org/wiki/Blue_%28disambiguation%29

if used in the following way:

(require 'browse-url)
(browse-url-url-encode-chars "https://en.wikipedia.org/wiki/Blue_(disambiguation)" "[\"()$]")

Citation of the doc string of browse-url-url-encode-chars:

browse-url-url-encode-chars is a Lisp function in ‘browse-url.el’.

(browse-url-url-encode-chars TEXT CHARS)

URL-encode the chars in TEXT that match CHARS. CHARS is a regexp-like character alternative (e.g., "[)$]").

  • browse-url-url-encode-chars does the job. It's still not very convenient though. See edit. – takatakatek Jun 24 '17 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.