0

So i basically want to (as the title suggest) to center a region of text, in the center of the screen. Current example is using part of this site.

From this

To this

And here a small gif video to show how i did it manually (for more detail):

  • Used screenkey to display the key i used. Roughly, i'm just putting a newline characters in front of the first line of the block of text (which is on the same line, in this example) and center it (very roughly) in the center.

  • Then i input space characters in front of each line, until it is formatted into one block of text, in the position i choose above.

This is basically what i want to do (on a region selected text) but in elisp.

  • So you really want to potentially modify your buffer, by adding empty lines at the beginnig (if necessary) and adding spaces on the left (if necessary) in order to center the block of text? – NickD May 16 at 11:54
  • 1
    Saying buffer but meaning window ? – Muihlinn May 16 at 12:49
  • Yep! @NickD Exactly – Nordine Lotfi May 16 at 19:27
  • @Muihlinn Exactly (though i did correct myself in the post by saying "screen" instead) – Nordine Lotfi May 16 at 19:27
  • What complicates this is that you have a single (long) line of text, but you expect to center it as a block. IOW, you will need to calculate the physical height and width of the block which depends on the frame/window size: if you make it smaller, it'll take fewer physical lines, so it will affect the top-to-bottom centering. Also it's not clear what left-to-right centering means in this case, since the line is longer than the frame/window is wide. Why should there be any space on the left or right? – NickD May 16 at 19:39
1

Here's an implementation of exactly what the OP is asking for, although I don't think it is of any use to anybody (except possibly the OP, but even there I have my doubts, as the extended discussion in the comments shows). It assumes that there is one long line starting at the beginning of the buffer and that you want to reformat it as a block of some specified width that is centered in the window of the buffer.

(defun insertN (c count)
   (insert (make-string count c)))

(defun center-block (text-width)
  "Assumption: there is one long line at the beginning of the buffer which this function
           is going to mangle in order to center it in the window.
   Assumption: the given text-width is smaller than the window body width."
  (interactive "NText width: ")

  (let* ((s (buffer-substring-no-properties (point-min) (point-max)))
     (slen (length s))
     (W (window-body-width))
     (H (window-body-height))
     (L text-width)
     (nlines (/ (+ slen L) L))           ; number of physical lines of block
                                         ; when shrunk to the required line length
     (toplines (/ (+ (- H nlines) 2) 2)) ; how many lines to leave at the top
     (lspaces (/ (- W L) 2))             ; how many spaces to insert at the beginning
     (rspaces (- (- W L) lspaces))       ; how many spaces to go to the right end of the window
     (nspaces (+ lspaces rspaces))       ; how many spaces to insert between physical lines
     sub)
    (erase-buffer)
    ;; insert the proper number of newlines
    (insertN ?\n toplines)
    ;; insert the proper number of spaces at the beginning of the string
    (insertN ?\s lspaces)
    ;; break up the string into substrings of length L and insert each
    ;; one, followed by the appropriate number of spaces. The loop inserts
    ;; the *full* logical lines of the block: there might be a tail that is
    ;; left over if the length of the string is not a multiple of L which is
    ;; inserted after the loop is done.
    (while (>= (length s) L)
      (setq sub (substring s 0 L))       ; first L chars
      (setq s (substring s L))           ; rest
      ;; insert the substring
      (insert sub)
      ;; insert nspaces spaces: rspaces to reach the right end of the window
      ;; and lspaces to indent the next physical line.
      (insertN ?\s  nspaces))
    ;; insert what's left over.
    (insert s)))

I have commented it copiously in an attempt to make it understandable to the OP.

Invoke it with M-x center-block RET 60 RET (or whatever width you want to specify instead of 60) while the cursor is in the window of the buffer that you are trying to modify.

| improve this answer | |
  • Two word: Pure perfection...Thanks again. – Nordine Lotfi May 17 at 17:43

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.