config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

ob-awk.el (4344B)


      1 ;;; ob-awk.el --- Babel Functions for Awk            -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2011-2024 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   (let ((prologue (cdr (assq :prologue params)))
     54         (epilogue (cdr (assq :epilogue params))))
     55     (concat
     56      (and prologue (concat prologue "\n"))
     57      body
     58      (and epilogue (concat "\n" epilogue "\n")))))
     59 
     60 (defun org-babel-execute:awk (body params)
     61   "Execute a block of Awk code BODY with org-babel.
     62 PARAMS is a plist of src block parameters .
     63 This function is called by `org-babel-execute-src-block'."
     64   (unless noninteractive (message "Executing Awk source code block"))
     65   (let* ((result-params (cdr (assq :result-params params)))
     66          (cmd-line (cdr (assq :cmd-line params)))
     67          (in-file (cdr (assq :in-file params)))
     68 	 (full-body (org-babel-expand-body:awk body params))
     69 	 (code-file (let ((file (org-babel-temp-file "awk-")))
     70                       (with-temp-file file (insert full-body)) file))
     71 	 (stdin (let ((stdin (cdr (assq :stdin params))))
     72 		  (when stdin
     73 		    (let ((tmp (org-babel-temp-file "awk-stdin-"))
     74 			  (res (org-babel-ref-resolve stdin)))
     75 		      (with-temp-file tmp
     76 			(insert (org-babel-awk-var-to-awk res)))
     77 		      tmp))))
     78          (cmd (mapconcat #'identity
     79 			 (append
     80 			  (list org-babel-awk-command
     81 				"-f" code-file cmd-line)
     82 			  (mapcar (lambda (pair)
     83 				    (format "-v %s='%s'"
     84 					    (car pair)
     85 					    (org-babel-awk-var-to-awk
     86 					     (cdr pair))))
     87 				  (org-babel--get-vars params))
     88 			  (list in-file))
     89 			 " ")))
     90     (org-babel-reassemble-table
     91      (let ((results
     92             (cond
     93              (stdin (with-temp-buffer
     94                       (call-process-shell-command cmd stdin (current-buffer))
     95                       (buffer-string)))
     96              (t (org-babel-eval cmd "")))))
     97        (when results
     98          (org-babel-result-cond result-params
     99 	   results
    100 	   (let ((tmp (org-babel-temp-file "awk-results-")))
    101 	     (with-temp-file tmp (insert results))
    102 	     (org-babel-import-elisp-from-file tmp)))))
    103      (org-babel-pick-name
    104       (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
    105      (org-babel-pick-name
    106       (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))))
    107 
    108 (defun org-babel-awk-var-to-awk (var &optional sep)
    109   "Return a printed value of VAR suitable for parsing with awk.
    110 SEP, when non-nil is a separator used when converting list values to awk
    111 table."
    112   (let ((echo-var (lambda (v) (if (stringp v) v (format "%S" v)))))
    113     (cond
    114      ((and (listp var) (listp (car var)))
    115       (orgtbl-to-generic var  (list :sep (or sep "\t") :fmt echo-var)))
    116      ((listp var)
    117       (mapconcat echo-var var "\n"))
    118      (t (funcall echo-var var)))))
    119 
    120 (provide 'ob-awk)
    121 
    122 ;;; ob-awk.el ends here