dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

ob-awk.el (3985B)


      1 ;;; ob-awk.el --- Babel Functions for Awk            -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
      4 
      5 ;; Author: Eric Schulte
      6 ;; Maintainer: Tyler Smith <tyler@plantarum.ca>
      7 ;; Keywords: literate programming, reproducible research
      8 ;; URL: https://orgmode.org
      9 
     10 ;; This file is part of GNU Emacs.
     11 
     12 ;; GNU Emacs is free software: you can redistribute it and/or modify
     13 ;; it under the terms of the GNU General Public License as published by
     14 ;; the Free Software Foundation, either version 3 of the License, or
     15 ;; (at your option) any later version.
     16 
     17 ;; GNU Emacs is distributed in the hope that it will be useful,
     18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 ;; GNU General Public License for more details.
     21 
     22 ;; You should have received a copy of the GNU General Public License
     23 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     24 
     25 ;;; Commentary:
     26 
     27 ;; Babel's awk can use special header argument:
     28 ;;
     29 ;; - :in-file takes a path to a file of data to be processed by awk
     30 ;;
     31 ;; - :stdin takes an Org data or code block reference, the value of
     32 ;;          which will be passed to the awk process through STDIN
     33 
     34 ;;; Code:
     35 
     36 (require 'org-macs)
     37 (org-assert-version)
     38 
     39 (require 'ob)
     40 (require 'org-compat)
     41 
     42 (declare-function org-babel-ref-resolve "ob-ref" (ref))
     43 (declare-function orgtbl-to-generic "org-table" (table params))
     44 
     45 (defvar org-babel-tangle-lang-exts)
     46 (add-to-list 'org-babel-tangle-lang-exts '("awk" . "awk"))
     47 
     48 (defvar org-babel-awk-command "awk"
     49   "Name of the awk executable command.")
     50 
     51 (defun org-babel-expand-body:awk (body _params)
     52   "Expand BODY according to PARAMS, return the expanded body."
     53   body)
     54 
     55 (defun org-babel-execute:awk (body params)
     56   "Execute a block of Awk code with org-babel.
     57 This function is called by `org-babel-execute-src-block'."
     58   (message "Executing Awk source code block")
     59   (let* ((result-params (cdr (assq :result-params params)))
     60          (cmd-line (cdr (assq :cmd-line params)))
     61          (in-file (cdr (assq :in-file params)))
     62 	 (full-body (org-babel-expand-body:awk body params))
     63 	 (code-file (let ((file (org-babel-temp-file "awk-")))
     64                       (with-temp-file file (insert full-body)) file))
     65 	 (stdin (let ((stdin (cdr (assq :stdin params))))
     66 		  (when stdin
     67 		    (let ((tmp (org-babel-temp-file "awk-stdin-"))
     68 			  (res (org-babel-ref-resolve stdin)))
     69 		      (with-temp-file tmp
     70 			(insert (org-babel-awk-var-to-awk res)))
     71 		      tmp))))
     72          (cmd (mapconcat #'identity
     73 			 (append
     74 			  (list org-babel-awk-command
     75 				"-f" code-file cmd-line)
     76 			  (mapcar (lambda (pair)
     77 				    (format "-v %s='%s'"
     78 					    (car pair)
     79 					    (org-babel-awk-var-to-awk
     80 					     (cdr pair))))
     81 				  (org-babel--get-vars params))
     82 			  (list in-file))
     83 			 " ")))
     84     (org-babel-reassemble-table
     85      (let ((results
     86             (cond
     87              (stdin (with-temp-buffer
     88                       (call-process-shell-command cmd stdin (current-buffer))
     89                       (buffer-string)))
     90              (t (org-babel-eval cmd "")))))
     91        (when results
     92          (org-babel-result-cond result-params
     93 	   results
     94 	   (let ((tmp (org-babel-temp-file "awk-results-")))
     95 	     (with-temp-file tmp (insert results))
     96 	     (org-babel-import-elisp-from-file tmp)))))
     97      (org-babel-pick-name
     98       (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
     99      (org-babel-pick-name
    100       (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))
    101 
    102 (defun org-babel-awk-var-to-awk (var &optional sep)
    103   "Return a printed value of VAR suitable for parsing with awk."
    104   (let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v)))))
    105     (cond
    106      ((and (listp var) (listp (car var)))
    107       (orgtbl-to-generic var  (list :sep (or sep "\t") :fmt echo-var)))
    108      ((listp var)
    109       (mapconcat echo-var var "\n"))
    110      (t (funcall echo-var var)))))
    111 
    112 (provide 'ob-awk)
    113 
    114 ;;; ob-awk.el ends here