What separates the blocks in your example? 2 new lines. In Emacs Lisp, if the text is in a string, if you set dash and s , you can use one of these two equivalent expressions:
(s-join "\n\n" (nreverse (s-split "\n\n" s))) ; where s is your string (->> s (s-split "\n\n") nreverse (s-join "\n\n"))
->> - This is a macro of a rough thread that pulls s through successive function calls. Think * nix pipes : s | s-split "\n\n" | nreverse | s-join "\n\n" s | s-split "\n\n" | nreverse | s-join "\n\n" s | s-split "\n\n" | nreverse | s-join "\n\n" .
If you want to have an Emacs Lisp function that opens a file, cancels the blocks, and then saves them back to the same files, you can also set the file management library f :
(defun reverse-blocks (f) "F is a filename." (interactive "fFind file: ") ; letter `f` is filename goes in first arg (let ((s (f-read f))) ; read file into a string (--> s s-chomp ; remove trailing newline (s-split "\n\n" it) nreverse (s-join "\n\n" it) (f-write it 'utf-8 f)))) ; write to the same file
Here I use another trailing macro --> , which allows you to put the result of the previous calculation in the argument indicated by it next calculation. For example. if the result of nreverse is X , then the equivalent will be (s-join "\n\n" X) . Finally, suppose you not only want to cancel, but also sort your blocks based on the number after the word "Section":
(--sort (< (string-to-number (cadr (s-match "/.*?\\([0-9]\\)/" it))) (string-to-number (cadr (s-match "/.*?\\([0-9]\\)/" other)))) it) ; put it instead of nreverse
Which, using dash-functional , is equivalent to:
(--sort (-on '< (-compose 'string-to-number 'cadr (-partial 's-match "/.*?\\([0-9]+\\)/"))) it) ; put it instead of nreverse
Read the dash documentation to understand what -on , -compose , -partial do.
Mirzhan Irkegulov
source share