1

Could someone here write a small Elisp function for me?

What I would like Emacs to do is the following: I have a region like this:

[0.04579]    [0.06569]    [0.09507]
[0.12696]    [0.27929]    [0.51505]
[0.27959]    [0.60903]    [ 0.8672]
[0.55241]    [0.89048]    [0.93582]
[0.0399]    [0.05806]    [0.08848]

and I want to delete the square brackets and all spaces, and insert & between the columns and \\ at the end.

0.04579&0.06569&0.09507\\
0.12696&0.27929&0.51505\\
0.27959&0.60903&0.8672\\
0.55241&0.89048&0.93582\\
0.0399&0.05806&0.08848\\

I have no idea about programming in Elisp (yet) and this function would make my life a lot easier right now. I tried defining some kind of macro with forward-word but that didn't work.

  • 1
    This looks like a good candidate for one or two regex-replace operations. – wasamasa Jun 24 '18 at 15:44
2

Below you find a possible implementation. I assume that you want to generate a LaTeX table and modified your specification a bit: The last bracket is not replaced by backslashes but just removed. Note that the code becomes only simper when your version is implemented exactly.

The code has more comments than usual to give you an easy start. Each function in the code is self-documented. Put point on such a function and press C-h f RET to get that help.

(defun myfun (&optional b e)
  "Replace bracket table with LaTeX table.
Do that only in region if region is active in interactive calls."
  (interactive
   (and (use-region-p) (list (region-beginning) (region-end))) ;; empty list otherwise
   )
  (unless b (setq b (point-min)))
  (when (numberp e) ;; marker adapts the end postion when the text is modified; alternatively you could use `save-restriction' and `narrow-to-region'
    (setq e (set-marker (make-marker) e)))
  (goto-char b)
  ;; replace first bracket but keep indentation (captured in group 1 of the regexp)
  (re-search-forward "^\\([[:space:]]*\\)\\[" e) ;; bails out without match...
  (replace-match "\\1")
  ;; 1st pass: LaTeX - newline
  (while (re-search-forward "\\][[:space:]]*\n\\([[:space:]]*\\)\\[" e t)
    ;; brackets are special in regexps therefore the escape \
    ;; \n is the line-break
    ;; [[:space:]] is a character class
    (replace-match "\\\\\\\\\n\\1") ;; keep indentation with group 1
    ;; you really need 8 backslashes for the representation of the LaTeX newline in the replacement-text:
    ;; factor 2 since each backslash must be escaped in strings
    ;; factor 2 since one backslash in a regexp-replacement is special,
    ;;          e.g., \& means the whole match, \1 means the first sub-expression...
    ;; factor 2 since you need two backslashes for the LaTeX newline
    )
  ;; replace last bracket together plus potential trailing space
  (re-search-forward "\\][[:space:]]*$" e) ;; also bails out without match
  (replace-match "") ;; actually delete match
  ;; 2nd pass: replace column separators
  (goto-char b)
  (while (re-search-forward "\\][[:space:]]*\\[" e t)
    (replace-match "&")))
  • Works perfectly! Thanks, also for the useful comments! ;-) – Florian Jun 24 '18 at 19:05
1

This is a perfect candidate for a keyboard macro.

Go to the beginning of the buffer, then C-c ( (start keyboard macro), then C-d (delete forward). Move forward 2 words (M-f M-f) then use C-d to delete the ] [, then insert &. Repeat until you get to the end of the line, then insert \\. Go the beginning of the line C-a then move to the next line C-n. Finish the macro with C-C ). You now have a macro that can transform a single line, and when done, positions itself for the next macro call. You can the execute the macro with C-e. To repeat the macro many times, prefix using M-1234 where 1234 is the number of times you want to call the macro.

If you need to reuse this macro in later sessions, you can save it. See https://www.gnu.org/software/emacs/manual/html_node/emacs/Save-Keyboard-Macro.html for more information.

  • Thanks for the suggestion. I haven't worked with keyboard macros before, I'll try out your solution. – Florian Jun 24 '18 at 19:06
  • @Florian, do spend some time learning about keyboard macros; they can be amazingly useful and powerful -- particularly when you consider that the recorded key strokes do not need to be for text editing commands. – phils Jun 24 '18 at 23:38

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.