1

I want to use org-capture-templates to scrape french verb conjugations from the web and insert them into an org-file to use with org-drill.

I have a (functioning) scraper that gets the desired data from www.verbix.com and prints out the preformatted conjugations like so:

    ** Indicatif
    *** Present
    | je ... | tu ...|
    |  ....  |  ...  |

I would like to call this python script from my capture using shell-command.

Here is my lisp function:

    (defun my-french-verb-template ()
    "Capture template for French verbs"
      (let* ((arg (org-completing-read-no-i "Verb: " nil))
             (conjugations (shell-command (concat "python2 ~/Nextcloud/05Code/python/verbix_scraper.py " arg))))
      (format "** Verb: %s :drill:\n    :PROPERTIES:\n    :DRILL_CARD_TYPE: french_verb\n    :END:\n*** Infinitive\n %s\n%s\n"
          arg arg conjugations)))

and my capture template:

    ("f" "French verb" entry (file+headline "~/Nextcloud/org-mode/brain/french.org" "Verb")
         (function my-french-verb-template))

Evaluating just

    (shell-command (concat "python2 ~/Nextcloud/05Code/python/verbix_scraper.py " arg))

from a scratch buffer prints out the desired output in a new minibuffer. However, calling org-capture-template will only print 0.

I think the problem is that shell-command will use a minibuffer to output the result from the shell command. How can I insert the result in the capture buffer?

Calling shell-command with (current-buffer) will replace whatever buffer I am in when I call the capture-template.

Any ideas? The documentation is not helping so far.

Edit 1:

I have also tried redirecting the result from shell-command to 'CAPTURE-french.org', but then my capture buffer will be renamed to 'CAPTURE-2-french.org'.

So I can think of two possibilities:

1) Delay the evaluation of (shell-command ...) until the capture buffer has been created.

2) Specify a (scratch) output buffer to catch the text from (shell-command ...) and then bind the buffer content to a variable which I insert in the capture buffer.

But I cannot think of a way to do this in emacs...

Edit 2:

lawlist's solution worked for me: using shell-command-to-string works pretty flawlessly for me and I now have a working capture which lets me type in a french verb as infinitive and then scrapes conjugations from the web and inserts them into my french-vocab.org file. #STARTUP: align takes care of table formatting. SAWEEEET!

  • I am unfamiliar with the utility being executed in shell, but the O.P. may be interested in shell-command-to-string and then modify the string as needed. If the output is too large to reasonably modify in string form and requires a buffer to operate upon, then shell-command-to-string may not suffice. For example, date in shell produces an undesired \n at the very end -- so, I might use something like this to remove the \n: (replace-regexp-in-string "\n$" "" (shell-command-to-string "date")) – lawlist Jun 3 '18 at 15:48
  • okay, will give this a try and get back here – mor3dr3ad Jun 4 '18 at 2:49
  • @lawlist, this was exaclty what I was looking for. do you want to post an answer? – mor3dr3ad Jun 4 '18 at 18:46
0

To the extent that a shell command does not take an appreciable amount of time to return a result, and depending upon the existence of certain Lisp calls that follow the shell command, one option would be to use shell-command-to-string. The following example uses the shell command date, which this author considers to contain an undesired \n at the tail end of the string. To remove the undesired \n from the result, this example uses replace-regexp-in-string:

(replace-regexp-in-string "\n$" "" (shell-command-to-string "date"))

To the extent the shell command takes an appreciable amount of time to return a result and/or subsequent Lisp calls rely upon that result, then a different approach would be needed: e.g., using a combination of set-process-sentinel and start-process. Filter-functions can be used in conjunction therewith. This author has used recursive-edit and exit-recursive-edit to prevent/permit Lisp portions of a function from/to continuing until the shell result has been returned. However, the O.P. has indicated in a comment above that shell-command-to-string suffices as to the particular use case cited in the question above.

Another consideration is the size of the output of the shell command. If the output is too large to reasonably modify with things like replace-regexp-in-string, then an output buffer would be needed to operate thereupon -- e.g., using start-process.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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