;;; eev-template0.el -- implement functions that eval `{}'s in a string. ;; Copyright (C) 2019-2021 Free Software Foundation, Inc. ;; ;; This file is part of GNU eev. ;; ;; GNU eev is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; GNU eev is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;; ;; Author: Eduardo Ochs ;; Maintainer: Eduardo Ochs ;; Version: 20210509 ;; Keywords: e-scripts ;; ;; Latest version: ;; htmlized: ;; See also: ;; (find-eev-quick-intro) ;;; Commentary: ;; ;; This file implements `ee-template00', a function that receives a ;; string STR and replaces all substrings in it enclosed in `{}'s by ;; the result of evaluating them; in particular, it replaces each ;; `{VAR}' in STR by the contents of the variable VAR. Here are some ;; examples/tests: ;; ;; (ee-template00 "a{(+ 2 3)}b") ;; --> "a5b" ;; ;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}")) ;; --> "Here: 22+33=55" ;; ;; (defun foo (a b) (ee-template00 "{a}+{b}={(+ a b)}")) ;; (foo 22 33) ;; --> "22+33=55" ;; ;; This file also implements `ee-template0', that is a higher-level ;; version of `ee-template00' that adds a trick that makes each "{<}" ;; and each "{>}" in STR be replaced by "{" and "}" respectively. For ;; example: ;; ;; (ee-template0 "{<} a{(+ 2 3)} {>}") ;; --> "{ a5 }" ;; ;; `ee-template0' is used by three families of functions in eev: ;; ;; 1) the `ee-wrap-*'s (and `eewrap-*'s), ;; 2) the `ee-code-*'s (and `code-*'s and `find-code-*'s), ;; 3) the `find-*-links' functions in "find-tlinks.el". ;; ;; To understand the kinds of templates that `ee-template0' is ;; typically used on, try the tests below; note that all of them ;; display their results in temporary buffers. ;; ;; (find-estring (ee-wrap-escript-block "ANCHOR" "LONG TITLE")) ;; (find-code-c-d "CODE" "/DIR/") ;; (find-code-c-d "CODE" "/DIR/" :info "INFO" :gz) ;; (find-code-pdf-page "livesofanimals" "/tmp/Coetzee99.pdf") ;; (find-code-pdf-text "livesofanimals" "/tmp/Coetzee99.pdf") ;; (find-code-brurl 'find-foo :remote 'brfoo :local 'brfool :dired 'brfood) ;; (find-code-brfile 'find-bar :local 'brbarl :dired 'brbard) ;; (find-latex-links "FOO") ;; ;; Note that `ee-template0' is intrinsically INCOMPATIBLE with lexical ;; binding - it is common to have `{VAR}'s in the string referring to ;; names of arguments of a `defun's, or to names of variables defined ;; in an enclosing `let' block, or to names of global variables. ;; ;; Here are some messages in help-gnu-emacs about dynamic binding ;; being deprecated: ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2021-06/msg00054.html ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2021-06/msg00085.html ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2021-06/msg00095.html ;; https://lists.gnu.org/archive/html/help-gnu-emacs/2021-06/msg00096.html ;; Some links to places where the documentation mentions uses of ;; `ee-template0': ;; (find-eevgrep "grep --color -nH -e ee-template0 *.el") ;; (find-eev-quick-intro "7.5. `find-latex-links'") ;; (find-eev-quick-intro "8.4. Creating e-script blocks" "`M-B'") ;; (find-eev-quick-intro "9.2. Extra arguments to `code-c-d'") ;; (find-eev-quick-intro "9.3. Hyperlinks to PDF files") (defvar ee-template00-re "{\\([^{}]+\\)}" "To make `ee-template0' use other delimiters instead of `{}'s set this variable temporarily in a `let'.") ;; Tests: ;; (ee-template00 "a{(+ 2 3)}b") ;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}")) ;; (defun ee-template00 (str) "Replace substrings enclosed by `{}'s in STR by the result of evaluating them. Examples:\n (ee-template00 \"a{(+ 2 3)}b\") --> \"a5b\"\n (let ((hi \"Here:\") (a 22) (b 33)) (ee-template00 \"{hi} {a} + {b} = {(+ a b)}\")) --> \"22 + 33 = 55\"" (save-match-data (replace-regexp-in-string ee-template00-re (lambda (_code_) (format "%s" (eval (read (substring _code_ 1 -1))))) str 'fixedcase 'literal))) ;; Test: ;; (ee-template0 "{<} a{(+ 2 3)} {>}") ;; (defun ee-template0 (str) "Replace substrings enclosed by `{}'s in STR by the result of evaluating them. Substrings of the form `{<}' and `{>}' in STR are replaced by `{' and `}' respectively; apart from that, this is the same as `ee-template00'. Example: (ee-template0 \"{<} a{(+ 2 3)} {>}\") --> \"{ 5 }\"" (let ((< "{") (> "}")) (ee-template00 str))) (provide 'eev-template0) ;; Local Variables: ;; coding: utf-8-unix ;; no-byte-compile: t ;; End: