3

I'm editing a 4.7M pure-text document, the task is simple, every book have chapters, and every chapter have each of its lines enumerated at the begin of the line, what I'm doing it putting the name of the book, the chapter number next to the verse number of each line. Let me illustrate the text structure:

* A very important book

** The old part

*** BOOK ONE

**** Chapter 1
1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
2 Donec pharetra venenatis felis, non mollis ligula pharetra sit amet. Fusce sodales, arcu vel imperdiet rhoncus.

**** Chapter 2
1 nulla felis fermentum neque
2 at posuere urna quam et eros. Sed sed rhoncus felis

*** BOOK TWO

**** Chapter 1
1 a lacinia velit. Aliquam erat volutpat.
2 Donec at congue sapien.

**** Chapter 2
1 Integer arcu erat, luctus quis orci et,
2 feugiat placerat tortor.

and this is what I want to achieve:

* A very important book

** The old part

*** BOOK ONE

**** Chapter 1
Book one 1, 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Book one 1, 2: Donec pharetra venenatis felis, non mollis ligula pharetra sit amet. Fusce sodales, arcu vel imperdiet rhoncus.

**** Chapter 2
Book one 2, 1: nulla felis fermentum neque
Book one 2, 2: at posuere urna quam et eros. Sed sed rhoncus felis

*** BOOK TWO

**** Chapter 1
Book two 1, 1: a lacinia velit. Aliquam erat volutpat.
Book two 1, 2: Donec at congue sapien.

**** Chapter 2
Book two 2, 1: Integer arcu erat, luctus quis orci et,
Book two 2, 2: feugiat placerat tortor.

I'm looking to build a function that works over the entire buffer. What I want to know is: How can I get the information regarding the heading where the regular expression have a coincidence and is going to apply the replacement string? I need to know that to prepare the correct replacement string.

1 Answer 1

3

Here you have a function that I think do what you want.

(defun test-bookfy ()
  (interactive)
  (save-excursion
    (let ((book "")
      (chapter ""))
      (goto-char 0)
      (while (not (= (point) (point-max)))
    (let ((line (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
      (cond ((string-match "^\\*\\*\\*\\* Chapter \\(.*\\)$" line)
         (setq chapter (match-string 1 line)))
        ((string-match "^\\*\\*\\* \\(.*\\)$" line)
         (setq book (match-string 1 line)))
        ((not (string-match "^\\([[:space:]]\\|\\*.*\\)*$" line))
         (insert (concat book " " chapter ", "))))
      )
    (forward-line 1)))))

But if you want to know strictly what you ask for, here you got a function that return the two levels up of point.

(defun test-get-up-2-elements ()
  (interactive)

  (let ((chapter "")
    (book ""))
    (save-excursion
      (setq chapter (org-get-heading t t))
      (outline-up-heading 1)
      (setq book (org-get-heading t t)))
    (message (concat book " " chapter))))
1
  • Impresive! your test-bookfy does the job (with some bugs, but this is a start)! May can you comment your code to know what it does? (So I can learn some elisp in the way!).
    – shackra
    Commented Nov 18, 2014 at 8:41

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.