0

Goal

To parse text file in Python, search for string, and insert in current emacs buffer

Purpose

I do my document writing in LaTeX under Emacs and I would like to be able to do quick insertion of Bible verses as I type. I am aware of esv-mode in esv.el, which inserts Bible verses by querying biblegateway.org. However, that only works when I am online, and I want to be able to do insertion offline (I frequently work offline) as well.

I am aware of pymacs, which I have not tried since it looks to be severely outdated (I could not even open the help file under the GitHub repository...so it seems to be dying).

What I have tried

I created a simple test file in Python to read dummy text from dummy file:

def get_verse():
    with open('/home/test.txt','r') as tmp:
        text = tmp.read()

    return text

a = get_verse()
print(a)

I normally use Python for data transfer, analysis, and processing, so the current application is outside my experience. If there is some general improvement I would appreciate the suggestions.

I then define that function under my .emacs file as:

;; testing function
(defun bible-verse ()
  (interactive)
;  (insert (shell-command "python /home/test.py")))
  (insert (shell-command-to-string "python /home/test.py")))

(global-set-key
 (kbd "C-c pytest")
 'bible-verse
 )

As you can see, I have tried both the shell-command and shell-command-to-string commands. Neither of which work (i.e. no text is inserted).

However, I do get the text from the dummy file inserted when I execute the following in Emacs:

C-u M-! python /home/test.py

Right now I have two problems:

  1. How do I get Emacs to execute my Python code and insert the returned text within the current buffer?

  2. How can I pass a variable to the Python code from Emacs (i.e. to pull from specific book, chapter, verse)?

Since this is more of an Emacs issue I am not tagging this as Python (feel free to edit that if you think otherwise).

2 Answers 2

2

The documentation for shell-command recommends that you use call-process for programmatic use:

(call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS)

However, the code you wrote with shell-command-to-string works for me, with M-x bible-verse. You'll need to fix the invalid key sequence to get your key binding to work, though:

(global-set-key (kbd "C-c p") 'bible-verse)

Here's a version that takes arguments and passes them to the process:

(defun bible-verse (book chapter verse)
  (interactive "*sBook: \ns%s, chapter: \ns%s, chapter %s, verse: ")
  (call-process "python" nil t t
                "~/test.py" book chapter verse))

I've used the * flag in (interactive) to refuse to run in a non-writable buffer, and I've shown how to format prior arguments when prompting.

Sign up to request clarification or add additional context in comments.

1 Comment

Worked beautifully, thanks for the tip. I definitely need to get up to speed on lisp though...
0

With example code below in Emacs buffer and python-mode, C-c C-c should print a line starting with chars "1.2" in a Python3 shell-buffer - given there is such a line in text.

#! /usr/bin/env python3
import re

DATEI="My-path-to-bible.txt"
SATZ = re.compile('^1.2')

with open(DATEI, "r") as jetzt:
    for line in jetzt:
        k = SATZ.match(line)
        if k:
            print(line)

python-mode.el comes with an option py-store-result-p: when t, result is in kill-ring, ready being yanked.

https://gitlab.com/python-mode-devs/python-mode

2 Comments

Thanks Andreas, but I was looking for something to insert text directly in the document. Though this would have been a good alternative.
Just write a My-command be followed by a yank. This requires some very basic Emacs lisp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.