I am trying to select each content-heading extracted with org-noter and then remove all erroneous newlines.

This is my function.

(defun sanitize-noter-import ()
  "Sanitizes org-noter imports. This removes white-spaces from all '* Contents' headings."
  (let (($headings nil)
        (nl "
") ; newline
        (nlb "-
") ; newline with hyphen-break
     (lambda ()
       (setq heading (org-entry-get (point) "ITEM"))
       (if (string= heading "Contents")
             (message heading)
             (replace-string nlb "" nil (point) (mark)) ; reconnect hyphenated words
             (replace-string nl " " nil (point) (mark)) ; remove line breaks
             (message "point is %s" (point))
             (message "mark is %s" (mark))

This is some example text.

** Skeleton

*** Highlight on page 2
:NOTER_PAGE: (2 . 0.18962766666666667)

**** Contents
Gamification is the application of game features, mainly video game elements, into non-game
context for the purpose of promoting motivation and engagement in learning. The application of
gamification in a pedagogical context provides some remedy for many students who find
themselves alienated by traditional methods of instruction. The use of gamifica-
tion could provide...

When I call the function nothing gets replaced and I get the output

point is 3983
mark is 4022
Mark set
Replaced 0 occurrences

Point and marker are here:

*** Highlight on page 2
:NOTER_PAGE: (2 . 0.18962766666666667)  // point
:END:                                   // marker

How do I select the headings "body" and perform a text-operation on it?

1 Answer 1


I solved it myself!

(defun sanitize-noter-import ()
  "Sanitizes org-noter imports. This operates on '* Contents' headings"
  (let (heading cbeg cend)
     (lambda ()
       (if (string= "Contents" (org-element-property :title (org-element-at-point)))
             (message "Found 'Contents' heading")
             (message "%s" (org-element-context))
             (setq cbeg (org-element-property :contents-begin (org-element-at-point)))
             (setq cend (org-element-property :contents-end (org-element-at-point)))
             (sanitize-region cbeg cend)

(defun sanitize-region (cbeg cend)
  "Removes all line-breaks between CBEG and CEND"
  (let ((nl "
        (nlb "-
    (message "contents-begin: %s contents-end: cend" cbeg)
    (message "Removing hyphen-breaks")
    (replace-string nlb "" nil cbeg cend)
    (message "Removing newlines")
    (replace-string nl " " nil cbeg cend)

What I don't really understand is why the cend does not delimit the full end, but instead points to a space two chars before.

If I do (goto-char cend) (insert "END"), then it would insert it like last woENDrd.

  • Careful: your first replace-string can change the length of the original region, but since the limits don't change the second replace-string is applied to a different region. It's better to copy the required buffer substring to a temporary buffer, delete it from the original buffer, do all the modifications on the temp buffer (using (point-min) and (point-max) as limits - they adapt to the current lenght of the buffer) and then insert the contents of the temporary buffer back into the original buffer. That might explain your last paragraph.
    – NickD
    Commented Feb 28, 2021 at 18:34
  • Yes, very likely. I macgyvered it with (sanitize-region cbeg (- cend 2)), as I don't really care about the full length of the region, but yours is way better!
    – jsteinbach
    Commented Mar 1, 2021 at 21:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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