branch: externals/eev
commit 91dcf84cf56ac8d3ad5ccf4d89016ad80d3865d8
Author: Eduardo Ochs <[email protected]>
Commit: Eduardo Ochs <[email protected]>

    New section: (find-templates-intro "7. let* macros").
---
 ChangeLog     |  22 +++++++++
 VERSION       |   4 +-
 eev-intro.el  | 152 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 eev-qrl.el    |   1 +
 eev-tlinks.el |  56 +++++++++++++++++-----
 5 files changed, 195 insertions(+), 40 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f41a9b0c39..cd2cf8ca57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2024-01-12  Eduardo Ochs  <[email protected]>
+
+       * eev-intro.el (find-templates-intro): new section: "7. let*
+       macros".
+       (find-intro-intro): replace the `(cadr (ee-intro-sexp-here))' by
+       an `(eval-defun nil)'.
+       (find-intro-dual): replace the `(eval (ee-intro-sexp-here))' by an
+       `(eval-defun nil)'.
+       (ee-sexp-at, ee-intro-sexp-end-re, ee-intro-sexp-here): commented
+       out.
+       (ee-this-line0): deleted.
+       (ee-this-line): use `ee-kl-line'.
+
+       * eev-tlinks.el (ee-show2-do-with-fname0): renamed to
+       `ee-let*-macro-show2-use'.
+
+2024-01-11  Eduardo Ochs  <[email protected]>
+
+       * eev-tlinks.el (find-let*-macro-links): new function.
+       (ee-find-1stclassvideo-do-with-c): renamed to
+       `ee-let*-macro-1stclassvideo-c'.
+
 2024-01-07  Eduardo Ochs  <[email protected]>
 
        * eev-tlinks.el (ee-find-1stclassvideo-links): added an "LSubs:"
diff --git a/VERSION b/VERSION
index a4f3460d61..103aa028b7 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-Sun Jan  7 06:30:21 GMT 2024
-Sun Jan  7 03:30:21 -03 2024
+Fri Jan 12 18:15:15 GMT 2024
+Fri Jan 12 15:15:15 -03 2024
diff --git a/eev-intro.el b/eev-intro.el
index 7f54ba0afe..34d3284afd 100644
--- a/eev-intro.el
+++ b/eev-intro.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20240106
+;; Version:    20240112
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eev-intro.el>
@@ -141,22 +141,21 @@
   (interactive)
   ;; The hackish functions begin here and end at the line with a single ")".
 
-;; Test: (ee-sexp-at "2)")
-;;             (+  1  2)
-(defun ee-sexp-at (re)
-  (save-excursion (re-search-forward re) (ee-last-sexp)))
-(setq ee-intro-sexp-end-re "\\(rest\\|pos-spec-list\\))))")
-(defun ee-intro-sexp-here ()
-  "Go to the end of the defun around point and `read' it.
-Only works for \"(defun find-xxx-intro ...)s\".
-Returns a list like this: (defun find-xxx-intro ...)."
-  (read (ee-sexp-at ee-intro-sexp-end-re)))
+;; ;; Test: (ee-sexp-at "2)")
+;; ;;             (+  1  2)
+;; (defun ee-sexp-at (re)
+;;   (save-excursion (re-search-forward re) (ee-last-sexp)))
+;;
+;; (setq ee-intro-sexp-end-re "\\(rest\\|pos-spec-list\\))))")
+;; (defun ee-intro-sexp-here ()
+;;   "Go to the end of the defun around point and `read' it.
+;; Only works for \"(defun find-xxx-intro ...)s\".
+;; Returns a list like this: (defun find-xxx-intro ...)."
+;;   (read (ee-sexp-at ee-intro-sexp-end-re)))
 
 (defun ee-bad-line (str) (string-match "[\\\"]" str))
-(defun ee-this-line0 ()
-  (buffer-substring-no-properties (ee-bol) (ee-eol)))
 (defun ee-this-line ()
-  (let ((line (ee-this-line0)))
+  (let ((line (ee-kl-line)))
     (if (ee-bad-line line)
        (error "Current line contains evil characters")
       line)))
@@ -166,7 +165,7 @@ Returns a list like this: (defun find-xxx-intro ...)."
 (defun find-intro-intro ()
 "If we're in the defun for `find-foo-intro' run (find-foo-intro 
(ee-this-line))."
   (interactive)
-  (funcall (cadr (ee-intro-sexp-here)) (ee-this-line)))
+  (funcall (eval-defun nil) (ee-this-line)))
 
 (defun find-intro-source ()
 "If we're in a buffer \"*(find-foo-intro)*\" go to the source for 
`find-foo-intro'.
@@ -183,7 +182,7 @@ Actually go to: (find-eev \"eev-intro.el\" 
\"find-foo-intro\" (ee-last-kill))."
 (defun find-intro-dual ()
   (interactive)
   (if (ee-intro-sourcep)
-      (progn (eval (ee-intro-sexp-here))
+      (progn (eval-defun nil)
             (find-c2b nil '(find-intro-intro)))
     (find-c2a '(find-intro-source) nil)))
 
@@ -10731,7 +10730,7 @@ functions to other files after they become minimally 
useful.
 ===================
 The third argument to `find-find-links-links-new' is a list of
 local variables in a `let*'. Compare the temporary buffers
-generated by:
+generated by the three sexps below (hint: use `M-2 M-e'):
 
   (find-find-links-links-new \"mytaskC\" \"foo bar\" \"\")
   (find-find-links-links-new \"mytaskC\" \"foo bar\" \"plic\")
@@ -10762,10 +10761,107 @@ added to the `defun's by hand. For examples, see:
 
 
 
+7. let* macros
+==============
+Let's discuss a concrete example.
+Consider the skeleton generated by:
 
+  (find-find-links-links-new \"mytaskC\" \"a b\" \"c d\")
 
-Garbage (to be recycled)
-========================
+Its `(let* ...)' block looks like this:
+
+  (let* ((c \"{<}c{>}\")
+         (d \"{<}d{>}\"))
+    ...)
+
+Let's replace that `(let* ...)' block by this other block
+
+  (let* ((c (format \"<%s,%s>\" a b)
+         (d (format \"[%s,%s]\" a b)))
+    ...)
+
+to make `c' and `d' depend on `a' and `b', and let's replace the
+`...' by something much shorter. The result - an adjusted
+skeleton, with the two kinds of meat - will be:
+
+  ;; Skel: (find-find-links-links-new \"mytaskC\" \"a b\" \"c d\")
+  ;;
+  (defun find-mytaskC-links (&optional a b &rest pos-spec-list)
+  \"Visit a temporary buffer containing hyperlinks for mytaskC.\"
+    (interactive)
+    (setq a (or a \"{a}\"))
+    (setq b (or b \"{b}\"))
+    (let* ((c (format \"<%s,%s>\" a b))
+           (d (format \"[%s,%s]\" a b)))
+      (apply
+       'find-elinks
+       `((find-mytaskC-links ,a ,b ,@pos-spec-list)
+         ;; Convention: the first sexp always regenerates the buffer.
+         (find-efunction 'find-mytaskC-links)
+         ,(ee-template0 \"\\na: {a}\\nb: {b}\\nc: {c}\\nd: {d}\"))
+       pos-spec-list)))
+
+Now run the defun above, and type <f8>s on the three lines below
+to understand how it works:
+
+ (find-2a nil '(find-mytaskC-links))
+ (find-2a nil '(find-mytaskC-links \"A\" \"B\"))
+ (find-2a nil '(find-mytaskC-links \"AA\" \"BB\"))
+
+When the `(let* ...)' block has many lines sometimes it's
+convenient to create a macro to substitute the `(let* ...)'. If
+we do that in the example above it becomes a `defun' and a
+`defmacro':
+
+  ;; Skel: (find-find-links-links-new \"mytaskC\" \"a b\" \"c d\")
+  ;;
+  (defun find-mytaskC-links (&optional a b &rest pos-spec-list)
+  \"Visit a temporary buffer containing hyperlinks for mytaskC.\"
+    (interactive)
+    (setq a (or a \"{a}\"))
+    (setq b (or b \"{b}\"))
+    (ee-let*-macro-mytaskC
+      a b
+      (apply
+       'find-elinks
+       `((find-mytaskC-links ,a ,b ,@pos-spec-list)
+         ;; Convention: the first sexp always regenerates the buffer.
+         (find-efunction 'find-mytaskC-links)
+         ,(ee-template0 \"\\na: {a}\\nb: {b}\\nc: {c}\\nd: {d}\"))
+       pos-spec-list)))
+
+  ;; Skel: (find-let*-macro-links \"mytaskC\" \"a b\" \"c d\")
+  (defmacro ee-let*-macro-mytaskC (a b &rest code)
+    \"An internal function used by `find-mytaskC-links'.\"
+    `(let* ((a ,a)
+            (b ,b)
+            (c (format \"<%s,%s>\" a b))
+            (d (format \"[%s,%s]\" a b)))
+       ,@code))
+
+Try it - eval the `defun' and the `defmacro' above and then run
+<f8>s on these three lines:
+
+ (find-2a nil '(find-mytaskC-links))
+ (find-2a nil '(find-mytaskC-links \"A\" \"B\"))
+ (find-2a nil '(find-mytaskC-links \"AA\" \"BB\"))
+
+The details of how the macro `ee-let*-macro-mytaskC' works are
+quite tricky, but what matters here is that we can generate
+macros like that by starting with skeletons. Try:
+
+  ;; Skel: (find-let*-macro-links \"mytaskC\" \"a b\" \"c d\")
+
+After generating the skeleton all the other adjustments need to
+be made by hand.
+
+
+
+
+
+
+G. Garbage (to be recycled)
+===========================
 
   (find-eev \"eev-tlinks.el\" \".find-debpkg-links\")
   (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
@@ -10791,8 +10887,9 @@ In 2021 I recorded a video, called
 
   (find-1stclassvideo-links \"2021ffll\")
 
-1. Introduction
----------------
+
+G.1. Introduction
+.................
 In dec/2019 I sent this e-mail to the eev mailing list:
 
   https://lists.gnu.org/archive/html/eev/2019-12/msg00001.html
@@ -10828,8 +10925,9 @@ To learn how to write your own templated functions you 
need to:
 
   3) learn how to use `find-find-links-links-new'.
 
-3. `find-elinks'
-----------------
+
+G.3. `find-elinks'
+..................
 See:
 
   (find-efunction 'find-elinks)
@@ -10903,8 +11001,8 @@ LIST that are sexps are converted to strings using 
`ee-HS'. See:
 
   (find-eev \"eev-wrap.el\" \"ee-S\")
 
-4. Skels
---------
+G.4. Skels
+..........
 Many functions in eev have comments that start with \";; Skel:\",
 like this:
 
@@ -10920,8 +11018,8 @@ Try:
   (find-eev \"eev-tlinks.el\" \"find-fossil-links\")
   (find-eevgrep \"grep --color -nH --null -e Skel: *.el\")
 
-5. `find-find-links-links'
-==========================
+G.5. `find-find-links-links'
+............................
 (Note: `find-find-links-links' is obsolete, and was superseded by
 `find-find-links-links-new')
 
diff --git a/eev-qrl.el b/eev-qrl.el
index fb88ab04f0..12c8cb0082 100644
--- a/eev-qrl.el
+++ b/eev-qrl.el
@@ -91,6 +91,7 @@
       (apply 'ee-qrl0 plist))))
 
 (defun ee-qrl (&rest plist)
+  "`query-replace-list'. See: (find-templates-intro \"4. Adding meat\")"
   (interactive)
   (if (region-active-p)                        ; if the region as active
       (apply 'ee-qrl-narrow plist)     ; then narrow to the region
diff --git a/eev-tlinks.el b/eev-tlinks.el
index 99ef872459..5a66ee8e50 100644
--- a/eev-tlinks.el
+++ b/eev-tlinks.el
@@ -19,7 +19,7 @@
 ;;
 ;; Author:     Eduardo Ochs <[email protected]>
 ;; Maintainer: Eduardo Ochs <[email protected]>
-;; Version:    20240106
+;; Version:    20240112
 ;; Keywords:   e-scripts
 ;;
 ;; Latest version: <http://anggtwu.net/eev-current/eev-tlinks.el>
@@ -84,6 +84,7 @@
 ;; «.find-find-links-links»            (to "find-find-links-links")
 ;; «.find-find-links-links-new»                (to "find-find-links-links-new")
 ;;   «.ee-ffll-functions»              (to "ee-ffll-functions")
+;;   «.find-let*-macro-links»          (to "find-let*-macro-links")
 ;;
 ;; «.find-intro-links»                 (to "find-intro-links")
 ;; «.find-eev-header-links»            (to "find-eev-header-links")
@@ -527,6 +528,38 @@ This is an internal function used by `find-{stem}-links'.\"
 
 
 
+;; «find-let*-macro-links»  (to ".find-let*-macro-links")
+;; Skel: (find-find-links-links-new "let*-macro" "stem args defs" "sep part1 
part2")
+;; Test: (find-let*-macro-links "foo" "a b c" "d e f")
+;;  See: (find-templates-intro "7. let* macros")
+;;
+(defun find-let*-macro-links (&optional stem args defs &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks for let*-macro."
+  (interactive)
+  (setq stem (or stem "{stem}"))
+  (setq args (or args "{args}"))
+  (setq defs (or defs "{defs}"))
+  (let* ((sep "\n          ")
+        (part1 (mapconcat (lambda (v) (format "(%s ,%s)" v v))
+                          (ee-split args) sep))
+        (part2 (mapconcat (lambda (v) (format "(%s nil)" v v))
+                          (ee-split defs) sep)))
+    (apply
+     'find-elinks-elisp
+     `((find-let*-macro-links ,stem ,args ,defs ,@pos-spec-list)
+       ;; Convention: the first sexp always regenerates the buffer.
+       (find-efunction 'find-let*-macro-links)
+       ""
+       ,(ee-template0 "\
+;; Skel: (find-let*-macro-links \"{stem}\" \"{args}\" \"{defs}\")
+(defmacro ee-let*-macro-{stem} ({args} &rest code)
+  \"An internal function used by `find-{stem}-links'.\"
+  `(let* ({part1}{sep}{part2})
+     ,@code))
+")
+       )
+     pos-spec-list)))
+
 
 
 
@@ -3341,10 +3374,11 @@ This function is used by `ee-0x0-upload-region'."
        )
      pos-spec-list)))
 
-;; Test: (ee-find-1stclassvideo-do-with-c "eev2021" title)
-(defmacro ee-find-1stclassvideo-do-with-c (c &rest code)
+;; Skel: (find-let*-macro-links "1stclassvideo-c" "c" "title mp4")
+;; Test: (ee-let*-macro-1stclassvideo-c "eev2021" title)
+(defmacro ee-let*-macro-1stclassvideo-c (c &rest code)
   "An internal function used by `find-1stclassvideo-links'."
-  `(let* ((c        ,c)
+  `(let* ((c ,c)
          (title    (ee-1stclassvideos-field c :title))
          (mp4      (ee-1stclassvideos-field c :mp4))
          (yt       (ee-1stclassvideos-field c :yt))
@@ -3357,8 +3391,7 @@ This function is used by `ee-0x0-upload-region'."
          (mp4stem  (ee-1stclassvideos-mp4stem c))
           (mp4found (ee-1stclassvideos-mp4found c))
          (hash     (ee-1stclassvideos-hash c))
-         (hassubs  exts)
-         )
+         (hassubs  exts))
      ,@code))
 
 ;; Test:
@@ -3366,7 +3399,7 @@ This function is used by `ee-0x0-upload-region'."
 ;;
 (defun ee-find-1stclassvideo-links (c)
   "An internal function used by `find-1stclassvideo-links'."
-  (ee-find-1stclassvideo-do-with-c
+  (ee-let*-macro-1stclassvideo-c
    c
    (let* ((lsubs    (if hassubs
                        (ee-template0 ";; LSubs: (find-{c}lsubs \"00:00\")\n")
@@ -3442,7 +3475,7 @@ For more info on this particular video, run:
 ;;
 (defun ee-1stclassvideos-dlsubs (c)
   "An internal function used by `find-1stclassvideo-links'."
-  (ee-find-1stclassvideo-do-with-c
+  (ee-let*-macro-1stclassvideo-c
    c
    (let* ((template00 ";;
 ;; You don't have a local copy of this video.
@@ -4564,8 +4597,9 @@ printmeaning \"@oddfoot\"
         (ee-show2-use fname0)
         pos-spec-list))
 
-(defmacro ee-show2-do-with-fname0 (fname0 &rest code)
-  "An internal function used by `show2-use'."
+;; Skel: (find-let*-macro-links "show2-use" "fname0" "fname dir stem0 stem tex 
pdf cmd")
+(defmacro ee-let*-macro-show2-use (fname0 &rest code)
+  "An internal function used by `find-show2-use'."
   `(let* ((fname0 ,fname0)
          (fname (ee-expand (or fname0 "/tmp/Show2.tex")))
          (dir   (file-name-directory fname))
@@ -4579,7 +4613,7 @@ printmeaning \"@oddfoot\"
 
 (defun ee-show2-use (&optional fname0)
   "An internal function used by `show2-use'."
-  (ee-show2-do-with-fname0
+  (ee-let*-macro-show2-use
    fname0
    (ee-template0 "\
 ;; (find-show2-use {(ee-S fname0)})

Reply via email to