Like, say I have a shell script source code block.

#+BEGIN_SRC shell
  echo 'Hello World!'

On export, I want the code text to pick up a dollar sign, so $ echo 'Hello World!'. But I only want this to happen to shell script blocks, not any other language blocks.

I know there are switches like -n that cause a code block to pick up line numbers on export, but it seems to me there’s no easy way to add a new switch or modify an old one to do what I want.

I hoped I could advise an appropriate function, but I can’t find the right function to hook into either.

  • You might be able to do it with an export filter (probably added to org-export-filter-src-block-functions), although I don't know how to select just shell src-blocks. See Advanced configuration in the org manual and the (admittedly opaque-unless-you-know-the-code) reference docs on Worg. – NickD Sep 25 '18 at 18:37
  • Oh snap, that's right. I had forgotten about that. Unfortunately the filter-src-block functions act too late to recognize the source block language (they only receive the post-processed string value of the source block). But I'm pretty sure I can work something into the filter-parse-tree functions that walks the tree and modifies shell source blocks specifically. – purple_arrows Sep 25 '18 at 22:03
  • If you want that sweet sweet stack exchange karma, and wanna write an answer based on your comment, I'll accept it. – purple_arrows Sep 25 '18 at 22:03
  • Oh wait! Just found org-babel-map-src-blocks and the two hooks org-export-before-{processing,parsing}-hook. That's probably what I'm going to do. – purple_arrows Sep 25 '18 at 22:14
  • If you write a good answer (either method), I'll upvote it :-) – NickD Sep 25 '18 at 22:37

As NickD points out, there is a hook that allows this. It falls under Advanced Configuration in the Org manual. Specifically,

The export process executes two hooks before the actual exporting begins. The first hook, org-export-before-processing-hook, runs before any expansions of macros, Babel code, and include keywords in the buffer. The second hook, org-export-before-parsing-hook, runs before the buffer is parsed.

I think the before-parsing hook is the better fit for this problem, but I’m not sure.

The manual doesn’t mention this, but the hook is actually an abnormal hook, so its functions must take an argument (the exporting backend).

It's also worth mentioning that these functions don't execute in the context of the org buffer you're exporting from. Like all export transformations, they run in a temporary buffer that starts with a copy of the org buffer's text.

To do the prefix insertion, use org-babel-map-src-blocks and take advantage of how it dynamically binds useful context variables like the source block language and the beginning / end of the code body.

(defun my-insert-shell-prompt (_backend)
  (org-babel-map-src-blocks nil         ; nil implies current buffer
    (let (;; capture macro-defined variables
         (lang lang)
         (beg-body beg-body)
         (end-body end-body)
         ;; other variables
         (shell-langs '("sh" "shell"))
         (prefix "$ "))
      (when (member lang shell-langs)
        (goto-char beg-body)
        (skip-chars-forward "\n\s-" end-body)
        (while (< (point) end-body)
          (insert prefix)
          (skip-chars-forward "\n\s-" end-body)))))))

(add-hook 'org-export-before-parsing-hook #'my-insert-shell-prompt)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.