For posterity, this is doing what I want. It's with some shock that I note, I'm actually starting to understand LISP.
hjh (defun hjh-get-string-from-nested-thing (thing) "Peel off 'car's from a nested list until the car is a string." (while (and thing (not (stringp thing))) (setq thing (car thing))) thing ) (defun hjh-src-blocks-to-string () "Iterate src blocks from org-element and add them to a string." (interactive) (let ((tree (org-element-parse-buffer)) (string "") (counter 0)) (org-element-map tree 'src-block (lambda (element) (setq element (car (cdr element))) (let ((caption (hjh-get-string-from-nested-thing (plist-get element :caption))) (source (hjh-get-string-from-nested-thing (plist-get element :value)))) (when caption (setq counter (1+ counter)) (setq string (concat string (format "/********* Listing %d. %s *********/ %s\n\n" counter (substring-no-properties caption) (substring-no-properties source)))))))) string)) (defun hjh-src-blocks-to-buffer () "Put all the captioned source blocks from a buffer into another buffer." (interactive) (let* ((contents (hjh-src-blocks-to-string)) (bufpath (buffer-file-name)) (newname (concat (file-name-sans-extension bufpath) ".scd")) (bufname (file-name-nondirectory newname)) (newbuf (get-buffer-create bufname))) (with-current-buffer newbuf (erase-buffer) (insert contents) (set-visited-file-name newname)) (switch-to-buffer-other-window newbuf)))