8

I simply need to take the output of org-element-parse-buffer and put it in a file -- maybe with some "if-does-not-exist" etc. bells and whistles. In CL I have with-open-file and write as tools. For example, here's CL to read a file containing lines like foo=bar and output to a new file like this (foo . bar)

(defun arabic_to_roman (filename)
  (cl-flet ((read-it ()
                  (with-open-file (in filename
                                      :direction :input
                                      :if-does-not-exist nil)
                                  (loop for line = (read-line in nil)
                                        for pos = (position \= line)
                                        while line collect (cons (subseq line 0 pos)
                                                                 (subseq line (1+ pos))))))
         (write-it (list)
                   (with-open-file (cl-stream #p"ar_out.txt"
                                           :direction :output
                                           :if-exists :overwrite
                                           :if-does-not-exist :create)
                                   (write list :stream stream :escape nil :readably nil :pretty nil))))
    (write-it (read-it))
    'done-read-write))

This is someone abstruse compared to other languages -- but then I don't find anything like this in elisp. How is read-write done in elisp. What I find seems only buffer-oriented. . . .

Drew
  • 75,699
  • 9
  • 109
  • 225
147pm
  • 2,907
  • 1
  • 18
  • 39
  • 1
    How about using `with-temp-file`?: https://www.gnu.org/software/emacs/manual/html_node/elisp/Writing-to-Files.html I don't understand all the cl-stuff, but it probably is not necessary to use any of that. The same page of the manual also discusses `write-region`, which may also be helpful. See also `with-temp-buffer`: http://www.gnu.org/software/emacs/manual/html_node/elisp/Current-Buffer.html – lawlist Nov 21 '15 at 16:49
  • I guess I'll go Googling after elisp examples again. Your suggestions don't seem to do normal file read-write. There's only "buffer" manipulations with "start" and "end" of buffer. I just want to take the output of `org-element-parse-buffer` and write it to a file directly. Sure, I could do buffer work, but can't I just do normal file stuff in elisp? – 147pm Nov 21 '15 at 17:04
  • Thank you for the Common Lisp snippet, I have been looking for something similar for some time. While in elisp, sometimes I prefer to use "cl-lib" available commands, to maintain context switching to a minimum between my two favourite languages. – gsl Nov 22 '15 at 08:10
  • 2
    Using buffers *is* the normal way of operation in elisp, just like using callbacks it normal in JS. Better get used to it. – wasamasa Jan 12 '16 at 06:34

2 Answers2

12

Use with-temp-file; this is documented at M-: (info "(elisp) Writing to Files") (also available online).

This takes a filename or path and a list of body forms. It creates a temporary buffer, then executes the body forms with that new buffer as the current buffer, then writes the contents of that buffer to the file, then deletes the temporary buffer.

Don't be so down on buffers; you can think of them as strings with cursors, if you'd like. If you have a string and want to put it into a buffer, just insert it: (insert (org-element-parse-buffer ...)).

Followup:

I should have double-checked, but since org-element-parse-buffer doesn't return a string, you'll need to convert it to one first. As Drew mentioned, (format "%s" (org-element-parse-buffer)) will work.

db48x
  • 15,741
  • 1
  • 19
  • 23
  • Riiigt. Buffers are cool, I know. So I did this: `(defvar bufpar)` then `(setf bufpar (org-element-parse-buffer))` then `(with-temp-file "test.ast" (insert (format "%s" bufpar)))` and that worked. But just this `... (insert (org-element-parse-buffer))...` did not. Not sure why. . . . – 147pm Nov 21 '15 at 18:17
  • Did you check `C-h f insert`? That function expects strings or chars as its arguments. Try using `format` to get a string, like you did for your `with-temp-file` example. – Drew Nov 21 '15 at 18:44
  • There are some caveats as discussed [here](https://swsnr.de/blog/2016/11/15/read-and-write-files-in-emacs-lisp/) – clemera Dec 07 '18 at 14:47
  • @clemera - FYI that link is now 404'ed. – ocodo May 29 '22 at 00:58
9

f third-party library has f-write-text and some other file manipulation functions, such as f-exists? predicate:

(f-write-text "some string" 'utf-8 "path/to/my/file.txt")
Mirzhan Irkegulov
  • 1,088
  • 1
  • 9
  • 16