emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Kaushal Modi <kaushal.modi@gmail.com>
To: emacs-org list <emacs-orgmode@gnu.org>,
	Nicolas Goaziou <mail@nicolasgoaziou.fr>
Subject: Re: Allow #+SETUPFILE to point to an URL for the org file
Date: Mon, 13 Mar 2017 17:37:03 +0000	[thread overview]
Message-ID: <CAFyQvY34SWBq3sMZ=t2teyRShNgO9bwEyijS6udE8GtEFMbeCw@mail.gmail.com> (raw)
In-Reply-To: <87twaef3iq.fsf@nicolasgoaziou.fr>

[-- Attachment #1: Type: text/plain, Size: 5135 bytes --]

On Thu, Dec 8, 2016 at 5:40 PM Nicolas Goaziou <mail@nicolasgoaziou.fr>
wrote:

> Kaushal Modi <kaushal.modi@gmail.com> writes:
>
> You can use something like `url-insert' and `url-retrieve' or
> `url-retrieve-synchronously'.
>

Thanks. I am using url-retrieve-synchronously.

>
> Sure, but SETUPFILE still accepts local file names. So I was pointing
> out that you need to check if the URL is a local file name before
> proceeding. In particular, this check needs to happen when using "C-c '"
> (which may display URL contents in a read-only buffer, BTW).
>

Understood. I might need some help when baking this into org.el,
org-macros.el, etc.


>
> Is it necessary? File contents could be stored in, e.g., a hash table,
> url being the key. The file is downloaded only if the entry doesn't
> exist in the table and the user didn't force download.-
>

Correct. Thanks for the idea. I am now using hash table for this.

Here is my implementation.. it is still not baked into org.el, etc and
provided as a complete patch; I have some questions..

=====
(defvar org-setupfile-ht (make-hash-table :test 'equal)
  "Hash table to store the org SETUPFILE.
This acts as a cache of setup files read using
`org-insert-setupfile-contents'.")

(defun org-setupfile-clear-cache ()
  "Clear the SETUPFILE cache stored in `org-setupfile-ht'."
  (interactive)
  (clrhash org-setupfile-ht))

(defun org-insert-setupfile-contents (setupfile &optional nocache noerror)
  "Insert the contents of SETUPFILE.
SETUPFILE can be a file path or URL.

If SETUPFILE is a file path, use `org-file-contents' to get the file
contents.
If it is a URL instead, download the contents. If the URL contents are
already
cached in the `org-setupfile-ht' hash table, the download step is skipped.

If NOCACHE is non-nil, do a fresh fetch of SETUPFILE even if cached version
is
available. This option applies only if SETUPFILE is a URL.

If NOERROR is non-nil, ignore the error when unable to read the SETUPFILE
from
file or URL."
  (require 'ffap)                       ;for `ffap-url-regexp'
  (let* ((is-url (string-match-p ffap-url-regexp setupfile))
         (cache (when (and is-url (not nocache))
                  (gethash setupfile org-setupfile-ht)))
         (contents (when (and is-url cache) cache)))
    (if is-url
        (unless cache
          (let (url-retrieve-header)
            (with-current-buffer (url-retrieve-synchronously setupfile)
              (goto-char (point-min))
              ;; Take point to after the url-retrieve header
              (re-search-forward "\n\n") ; 2 consecutive new-line chars
              (setq url-retrieve-header (buffer-substring-no-properties
                                         (point-min) (point)))
              (message url-retrieve-header) ;Dump the URL retrieve header
to *Messages*
              (if (string-match-p "HTTP.*\\s-+200\\s-OK"
url-retrieve-header) ;URL retrieved correctly
                  (progn
                    (setq contents (buffer-substring-no-properties (point)
(point-max)))
                    ;; Update the cache `org-setupfile-ht'
                    (puthash setupfile contents org-setupfile-ht))
                (funcall (if noerror 'message 'error)
                         "Unable to fetch SETUPFILE from `%s'"
setupfile)))))
      (setq contents (org-file-contents setupfile noerror)))
    (when contents
      (save-excursion
        (insert contents)))))
=====

Question:

- All the places where the content of SETUPFILE is inserted in a temp
buffer, it is assumed that the file is retrieved from disk and not from URL.

Example in ox.el:

 ((equal key "SETUPFILE")
  (let ((file
 (expand-file-name
  (org-unbracket-string "\"" "\"" (org-trim val)))))
    ;; Avoid circular dependencies.
    (unless (member file files)
      (with-temp-buffer
(setq default-directory
  (file-name-directory file))
(insert (org-file-contents file 'noerror))
(let ((org-inhibit-startup t)) (org-mode))
(funcall get-options (cons file files))))))


Note the use of expand-file-name, (member file files), default-directory,
(funcall get-options (cons file files)).

How do we deal with those parts of the code when the 'file' is a URL.

Using my implementation above,

    (org-insert-setupfile-contents "/file/path/or/url" nil :noerror)

works the same way as

    (insert (org-file-contents "/file/path" 'noerror))

So org-insert-setupfile-contents can replace (insert (org-file-contents
..)) easily. The unknown is how to deal with the surrounding code that
deals with

> expand-file-name, (member file files), default-directory, (funcall
get-options (cons file files)).

Here's a similar code snippet around setupfile insertion in ox.el again, in
org-export--list-bound-variables:

=====
    ;; Enter setup file.
    (let ((file (expand-file-name
 (org-unbracket-string "\"" "\"" val))))
      (unless (member file files)
(with-temp-buffer
  (setq default-directory
(file-name-directory file))
  (let ((org-inhibit-startup t)) (org-mode))
  (insert (org-file-contents file 'noerror))
  (setq alist
(funcall collect-bind
 (cons file files)
 alist))))))))))
=====




-- 

Kaushal Modi

[-- Attachment #2: Type: text/html, Size: 9864 bytes --]

  reply	other threads:[~2017-03-13 17:37 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-03 17:23 Allow #+SETUPFILE to point to an URL for the org file Kaushal Modi
2016-12-08 11:51 ` Kaushal Modi
2016-12-08 14:22   ` John Kitchin
2016-12-08 14:31   ` Nicolas Goaziou
2016-12-08 14:44     ` Kaushal Modi
2016-12-08 21:48       ` Nicolas Goaziou
2016-12-08 22:07         ` Kaushal Modi
2016-12-08 22:40           ` Nicolas Goaziou
2017-03-13 17:37             ` Kaushal Modi [this message]
2017-03-30  7:43               ` Nicolas Goaziou
2017-05-23 19:07                 ` Kaushal Modi
2017-05-25 10:13                   ` Nicolas Goaziou
2017-05-25 10:18                     ` Nicolas Goaziou
2017-05-25 11:43                     ` Kaushal Modi
2017-05-25 15:15                       ` Kaushal Modi
2017-05-26  7:47                         ` Nicolas Goaziou
2017-05-26 20:24                           ` Kaushal Modi
2017-05-28  7:35                             ` Nicolas Goaziou
2017-05-28 10:04                               ` Kaushal Modi
2017-06-09 16:59                               ` Kaushal Modi
2017-06-12 19:32                                 ` Kaushal Modi
2017-06-13 12:43                                   ` Nicolas Goaziou
2017-06-13 15:45                                     ` Kaushal Modi
2017-06-13 21:32                                       ` Nicolas Goaziou
2017-06-13 21:42                                         ` Kaushal Modi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFyQvY34SWBq3sMZ=t2teyRShNgO9bwEyijS6udE8GtEFMbeCw@mail.gmail.com' \
    --to=kaushal.modi@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=mail@nicolasgoaziou.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).