1

I am in the process of formatting a couple of hundred markdown files and am trying to automate that process. I am having two problems, but I guess I can ask two questions ;)

Goal

I am trying to achieve the following:

  • Every main title starting with # should have two newlines above and one newline below.
  • Every subtitle starting with two or more # should have one newline above and one newline below.

Example:

More text here
# The main title 
## Another title 


## The third title 
   More text 

# The second main title 

more text here 


## Second subsection 


# Third title 

more text 

Should be formatted to

More text here


# The main title 

## Another title 

## The third title 

   More text 


# The second main title 

more text here 

## Second subsection 


# Third title 

more text 

Attempt

I am not sure if this is best suited for regex or a well defined macro?

My attempt at regex has so far been

[#]+.*\n[^\n]

This is at least able to identify every title that is missing a newline underneath.

enter image description here

However, I have no idea how I would use the expression above to insert a newline after the title. Any help would be appreciated.

6
  • I'd use Perl :-)
    – choroba
    Commented Jul 12, 2018 at 21:35
  • A little bit of context for this could be appreciated: can it be elisp code that does this operation, regardless of regex use? can the regex have perl extensions (man perlre)? Commented Jul 12, 2018 at 21:49
  • I am quite new to emacs. Would such a elisp script be something I would add in my user-config and then trigger it with some hotkey? The end goal is to write tests to detect these cases, and trigger at least a warning when running travis in GitHub. So regex for detection would be preferred. Commented Jul 12, 2018 at 22:05
  • If you can do the editing in a systematic way manually then you can simply record your actions as a keyboard macro. Then you can replay that as many times as you want. If that's straightforward enough (and I'm guessing it is) then you don't need to know Elisp or regexps. See the Emacs manual, node [Keyboard Macros]()gnu.org/software/emacs/manual/html_node/emacs/….
    – Drew
    Commented Jul 13, 2018 at 2:26
  • I don't know what that screenshot is of, but you should be using M-x re-builder otherwise how can you tell if you're using appropriate syntax? See also emacs.stackexchange.com/q/5568/454
    – phils
    Commented Apr 9, 2019 at 4:23

2 Answers 2

1

If I were doing this as a one-time task, not expected to be done again, I would use keyboard macros with ordinary search (no regexps). It seems easiest to do it in two steps. First make sure there is one empty line before and after headers, and then change it to two before the main headers.

So first

f3                          Define a macro
C-s C-j # C-a                Search for a header line ('\n#') and go to its start
C-o C-o                      Create a couple of blank lines before it (*)
C-x C-o                      ... but keep only one of them.
C-n C-x C-o                  Go to the header, delete blank lines after it
C-2 C-a C-o                  Add one (**)
f4                          End of macro
C-u 999 f4                  Then run the macro many times

M-<                         Back to the start
M-% C-q C-j # SPC RET       Exchange '\n# ' ... (***)
C-q C-j C-q C-j # SPC RET   with '\n\n# '
!

Comments:

(*) C-x C-o which deletes all surrounding blank lines, leaving just one, is useful. Unfortunately (here) its behaviour when on an isolated blank line is to just delete that line, so that's why I somewhat unintuitively create a couple of blank lines before doing that. I guess there is a better way to do that, but this was good enough for me.

(**) Here I first did C-n instead of C-2 C-a to go the beginning of the next line, but that can surprise you with long lines. I really think visual-line-mode should be turned off when defining and executing macros!

(***) My plan was to do a new macro, but no need; this is a simple substitution.

This can certainly be done better in several ways, but is maybe useful as illustrative of how at least one Emacs user would think about this.

0

This is a working answer, however it is very rudementary. Hopefully it can be of help to someone else

Removes all the newlines except ONE BEFORE ALL titles

:%s/[\n\r]*\(#.*\)/\n\n\1

Removes all the newlines ONLY on the main title, inserts two above

:%s/[\r\n]\(#[^#].*\)/\n\n\1

Removes all EXCESS newlines after titles

:%s/\(^#.*\)\n\n[\n]+/\1\n\n

Finds Titles # ## ### without newlines and inserts ONE newline beneath them

:%s/\(^#.*\)\n\([^\n].*\)/\1\n\n\2
1
  • 1
    Please, note that this is meant to be used with evil and not out-of-the-box Emacs Commented Jul 13, 2018 at 12:56

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.