tags:

views:

298

answers:

1

I'm trying to write a little Emacs Lisp script that reads a csv file from standard input, turns all the rows into a table then prints it to standard out (Unix). I wrote a basic version that takes a csv string and outputs the table to a buffer. However, I would like to turn this into a Unix utility script.

#!/usr/bin/emacs --script

(defun gen-row (lst)
  (dolist (elm lst)
    (insert "<tr>")
    (insert (concat "<td>" elm "</td>"))
    (insert "</tr>")
    )
)
(defun parse-csv-line (txt)
  (setq lst (progn
          (insert "\n<table>\n")
          (setq str txt)
          (gen-row (split-string str ","))
          (insert "\n</table>\n")
          ))
  )

(parse-csv-line "this,is,a test")

The output to the current buffer when run from within Emacs:

<table>
<tr><td>this</td></tr><tr><td>is</td></tr><tr><td>a test</td></tr>
</table>

Usage of the script:

./csv2html < foo.csv > bar.html; # emacs --script instead of perl -ane '...' 
+1  A: 

Here's how I'd wrap your routines to get what you're after.

Note: I did change the routines to simply princ the strings as opposed to inserting them in a buffer.

#!/usr/local/bin/emacs --script

(require 'cl)
(defun gen-row (lst)
  (mapcar (lambda (elm)
            (princ (concat "<tr><td>" elm "</td></tr>")))
          lst))

(defun parse-csv-line (txt)
  (princ "\n<table>\n")
  (gen-row (split-string txt ","))
  (princ "\n</table>\n"))

; (parse-csv-line "this,is,a test")

(defun run-it (&optional argv)
  (with-temp-buffer
    (if argv
        (find-file (car argv))
      (condition-case nil
          (let ((line (read-from-minibuffer "")))
            (while line
              (insert line)
              (insert "\n")
              (setq line (read-from-minibuffer ""))))
        (error nil)))

    ;; the current buffer has the file contents (or stdin contents)
    ;; now process each line
    (goto-char (point-min))
    (while (< (point) (point-max))
      (parse-csv-line (buffer-substring (point) (progn (end-of-line) (point))))
      (forward-line 1)
      (beginning-of-line 1))))

(run-it argv)

If you're going to do more involved processing of the tables, it might be easier to manipulate the input as lists to get what you want and then use the xmlgen package to generate all the HTML tags.

Trey Jackson
Emacs batch mode with --script? http://www.emacswiki.org/emacs/CategoryBatchMode
Never thought of looking on the wiki, the Emacs *info* page for --script is woefully lacking. I've updated my script to handle this case.
Trey Jackson
Each row is wrapped in its own <table> but it's good enough for me. Thanks.