3

I am new to the Emacs (Doom Emacs to be precise) scene, and recently I came up with a minor mode that could come in handy for me so I decided to implement it.

To achieve the full functionality of my mode I need to process some text, but I thought that a good idea could be to implement my own set of tags/delimeters (sorry if this is not the right terminology for it) for org-mode. I am referring to something like the #+BEGIN_SRC and #+END_SRC that org-mode provides, but with my custom processing. So my question is if there's a way to accomplish this task.

EDIT: Some code to what I would want to get

#+MY_CUSTOM_TAG_START
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam

#+MY_CUSTOM_TAG_END

Somehow I would like to process the text in between those two tags. Get as a String and use a function (that I already have implemented) to process that text.

2
  • 1
    What do you mean by "custom processing"? Please, give a minimal example (assumed Org code and expected behavior).
    – Tobias
    Aug 27 '20 at 7:09
  • Thanks for your response, I have added a little code to try to explain what I want to achieve. Aug 27 '20 at 8:18
2

You can use a source block with a self-defined major mode. It is easy to define a customized major mode with helper functions like define-derived-mode.

Let us name your new major mode myorg-mode. Then the name of the function executed on C-c C-c is org-babel-execute:myorg.

It is called with two arguments. The first arg is the content of the source block as a string. The second arg is an association list that maps the keys of the header arguments of the source blocks to their vaules.

The following source code demonstrates the method.

(define-derived-mode myorg-mode org-mode "Org"
  "Add special processing to `myorg` source blocks."
  )

(defun org-babel-execute:myorg (body params)
  "Processing of `myorg' source blocks.
BODY is the text of the source block
and PARAMS is an alist mapping the keys of the header args
to their vaules."
  (let* ((sep (or (cdr (assq :sep params)) "\n")) ;; Example for getting the values of source block header arguments. Here we extract the value for :sep.
     ;; Beginning of the special action for source blocks of this kind:
     ;; We split the body into a list of words and collect only every second word from this list.
     (words (split-string body nil t "[[:space:]]+")))
    (mapconcat ;; Concatenating the collected words to the output string.
     #'identity
     (cl-loop for word in words by #'cddr
          when (string-match "[[:alpha:]]" word)
          collect word)
     sep)))

A little usage example:

#+BEGIN_SRC myorg :sep "; " :results raw drawer
,* Some text
Lorem *ipsum* dolor /sit/ amet, consectetuer adipiscing elit, ~sed~ diam
#+END_SRC

#+RESULTS:
:results:
text; *ipsum*; /sit/; consectetuer; elit,; diam
:end:

Note, if you switch org-src-fontify-natively on the content of the source block is rendered like the major mode of the source block would do it. In our case Org formatting is applied.

2
  • Thanks a lot!! The simplest solution was to use your method. I have one more doubt: is it possible to suppress the result output programmatically. I now I can add :result noneas a header argument but I want my users to not to worry about it, is there a way to do that? Aug 31 '20 at 19:43
  • You can add (setq org-babel-default-header-args:myorg '((:results . "none"))) to the code. (That should actually have been a new question. Since it is of separate interest.)
    – Tobias
    Sep 1 '20 at 0:32

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.