[comp.emacs] Filling of paragraphs in GNU emacs.

hjanssen@cbnewse.ATT.COM (hank janssen) (11/22/89)

Does anybody out there knows or has a lisp library function call  
somewhere  that will automaticly  (or via a keystroke) perfectly
fill a paragraph i am editing. It seems that fill-paragraph does
not  do what i  want it  to do. If you  wonder what i mean  with 
filling a paragraph than just look at this piece of text. 

Thanx
					Hank Janssen.

-----------------------------------------------+----------------------
It's better to burn out than to fade away......| uucp:
			Movie The HighLander.  | ...att!ihlpb!hjanssen
-----------------------------------------------+----------------------
			

emv@math.lsa.umich.edu (Edward Vielmetti) (11/23/89)

In article <2435@cbnewse.ATT.COM> hjanssen@cbnewse.ATT.COM (hank janssen) writes:

   Does anybody out there knows or has a lisp library function call  
   somewhere  that will automaticly  (or via a keystroke) perfectly
   fill a paragraph i am editing. It seems that fill-paragraph does
   not  do what i  want it  to do. If you  wonder what i mean  with 
   filling a paragraph than just look at this piece of text. 

Give   a   numeric    argument   to
fill-paragraph.   The   string   of
keystrokes M-1  M-Q will do    what
you'd  like it  to do.  As  you can
see by this paragraph here....

--Ed

bob@MorningStar.Com (Bob Sutterfield) (11/23/89)

In article <2435@cbnewse.ATT.COM> hjanssen@cbnewse.ATT.COM (hank janssen) writes:
   Does anybody out there knows or has a lisp library function call  
   somewhere  that will automaticly  (or via a keystroke) perfectly
   fill a paragraph i am editing. It seems that fill-paragraph does
   not  do what i  want it  to do. If you  wonder what i mean  with 
   filling a paragraph than just look at this piece of text. 

From the Info node for Fill Commands:

	A  numeric argument to   `M-g'  or  `M-q' [normally  bound  to
	fill-region  and  fill-paragraph -  BS] causes it to "justify"
	the text as well as filling  it.  This means that extra spaces
	are inserted to make the right  margin line  up exactly at the
	fill column.  To remove  the extra spaces, use `M-q'  or `M-g'
	with no argument.

So, just type C-u M-q.

jonathan@hcr.uucp (Jonathan Fischer) (11/29/89)

In article <BOB.89Nov22171814@volitans.MorningStar.Com> bob@MorningStar.Com (Bob Sutterfield) writes:
>...[about filling paragraphs with justification]
>So, just type C-u M-q.

	So how about getting auto-fill-mode to do this for me?  Is it
possible?  I kind of doubt it (I can't find a way to), but I just thought
I'd ask.
-- 
"Consequently, said staff will be   	| Jonathan A. Fischer
entering your unit to effectuate said	| HCR Corp.
maintenance." - my apartment management.| Toronto, Ontario, CANADA

jr@BBN.COM (John Robinson) (11/30/89)

I couldn't resist rising to this one.

auto-fill-mode works, basically, by calling the value of
auto-fill-hook when you type a space.  In text auto-fill mode (and
perhaps others), this is bound to the function do-auto-fill, which is
defined in simple.el.  What is needed is a do-auto-justify, which we
attempt to define here.  It makes use of the function
justify-current-line, in fill.el:

  (defun do-auto-justify ()
    (let ((ocol (current-column)))
      (do-auto-fill)
      (or (= ocol (current-column))
          (save-excursion
            (forward-line -1)
            (justify-current-line)))))

Then, hang it onto auto-fill-hook:

  (setq auto-fill-hook 'do-auto-justify)

Now if I  type a bunch   of stuff I   should get my  lines  all nicely
justified with lots of snappy extra spaces inserted each time  it goes
to a new line.  There, does that look okay to you all?  I  thought so.
Nothing like interpretive systems to check out new  things fast (ahem,
well I had  to use the debugger once  on this,  but  you know  how  it
goes... )
--
/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis

gmiller@udel.edu (Gregory Miller) (12/01/89)

In article <48910@bbn.COM> jr@BBN.COM (John Robinson) writes:
>I couldn't resist rising to this one.
>
>auto-fill-mode works, basically, by calling the value of
>auto-fill-hook when you type a space.  In text auto-fill mode (and
>perhaps others), this is bound to the function do-auto-fill, which is
>defined in simple.el.  What is needed is a do-auto-justify, which we
>attempt to define here.  It makes use of the function
>justify-current-line, in fill.el:
>
>  (defun do-auto-justify ()
>    (let ((ocol (current-column)))
>      (do-auto-fill)
>      (or (= ocol (current-column))
>          (save-excursion
>            (forward-line -1)
>            (justify-current-line)))))
>
>Then, hang it onto auto-fill-hook:
>
>  (setq auto-fill-hook 'do-auto-justify)
>
>Now if I  type a bunch   of stuff I   should get my  lines  all nicely
>justified with lots of snappy extra spaces inserted each time  it goes
>to a new line.  There, does that look okay to you all?  I  thought so.
>Nothing like interpretive systems to check out new  things fast (ahem,

  This is great! It's exactly what I've been trying to do; and I won't
even go  into the ridiculous  things I've tried   in my vain attempts.
  However, it works fine interactively as John says, but when I put it
in my .emacs file, it has no effect.   Perhaps someone could point out
where I was stupid. What I did was  put the  above code into my .emacs
file and then invoke auto-fill-mode with M-x auto-fill-mode. Auto-fill
worked fine, but the text  was not justified. After wrestling  with it
for a while I discovered that auto-fill-hook seems to forget its value
unless it's set within the  scope  of auto-fill-mode.  This is just  a
guess, though.  I came up with the following code, and it works, but I
have a feeling  that I'm going  to more trouble  than is necessary. By
the way, I  want auto-fill-mode    with justification  to come on   by
default.

(setq default-major-mode 'text-mode)
	
(defun do-auto-justify ()
  (let ((ocol (current-column)))
    (do-auto-fill)
    (or (= ocol (current-column))
	(save-excursion
	  (forward-line -1)
	  (justify-current-line)))))

(setq text-mode-hook '(lambda ()
			(auto-fill-mode 1)
			(setq auto-fill-hook 'do-auto-justify)))

  Maybe someone can gently point out  a  more reasonable approach. I'm
new at this stuff.   Also, why is  it that  auto-fill-hook can only be
set from within auto-fill-mode, or so it seems?

Greg

ben@nsf1.mth.msu.edu (Ben Lotto) (12/01/89)

>>>>> On 30 Nov 89 21:49:21 GMT, gmiller@udel.edu (Gregory Miller) said:

Gregory> In article <48910@bbn.COM> jr@BBN.COM (John Robinson) writes:
>(definition of 'do-auto-justify to fill and justify lines after
>executing (setq auto-fill-hook 'do-auto-justify))

Gregory>   However, it works fine interactively as John says, but when I put it
Gregory> in my .emacs file, it has no effect.   Perhaps someone could point out
Gregory> where I was stupid. What I did was  put the  above code into my .emacs
Gregory> file and then invoke auto-fill-mode with M-x auto-fill-mode. Auto-fill
Gregory> worked fine, but the text  was not justified. After wrestling  with it

The problem is that M-x auto-fill-mode sets auto-fill-hook to either nil
or do-auto-fill.  Here is a new function, auto-justify-mode, that does
the same thing as auto-fill-mode for your new do-auto-justify function.
Modified from simple.el:

(defun auto-justify-mode (arg)
  "Toggle auto-justify mode.
With arg, turn auto-justify mode on iff arg is positive.
In auto-justify mode, inserting a space at a column beyond fill-column
automatically breaks the line at a previous space."
  (interactive "P")
  (prog1 (setq auto-fill-hook
	       (if (if (null arg)
		       (not auto-fill-hook)
		       (> (prefix-numeric-value arg) 0))
		   'do-auto-justify
		   nil))
    ;; update mode-line
    (set-buffer-modified-p (buffer-modified-p))))
--

-B. A. Lotto  (ben@nsf1.mth.msu.edu)
Department of Mathematics/Michigan State University/East Lansing, MI  48824

jr@BBN.COM (John Robinson) (12/02/89)

>   Maybe someone can gently point out  a  more reasonable approach. I'm
> new at this stuff.   Also, why is  it that  auto-fill-hook can only be
> set from within auto-fill-mode, or so it seems?

What you have is perfectly reasonable, though cascading hooks in that
way seems a bit bizarre.

If you look up the definition of (auto-fill-mode), it turns out that
turning on auto-fill-mode is simply a matter of hanging the right
function on the hook.

So what we want is a new minor mode (this is simply auto-fill-mode,
modified):

(defun auto-justify-mode (arg)
  "Toggle auto-justify mode.
With arg, turn auto-justify mode on iff arg is positive.
In auto-justify mode, inserting a space at a column beyond  fill-column
automatically breaks the line at a previous space, and the line up to
that point is filled out with spaces to fill-column."
  (interactive "P")
  (prog1 (setq auto-fill-hook
	       (if (if (null arg)
		       (not auto-fill-hook)
		       (> (prefix-numeric-value arg) 0))
		   'do-auto-justify
		   nil))
    ;; update mode-line
    (set-buffer-modified-p (buffer-modified-p))))

Then you could:

(setq text-mode-hook '(lambda ()
			(auto-justify-mode 1)))

The only further problem here is that the modeline will still say
"Fill" even though you are now in "Justify" minor mode.  The way
minor-mode-alist is set up isn't quite right.  You could add the pair
('auto-just-flag " Justify") to the minor-mode-alist, say right after
the pair ('auto-fill-hook " Fill"), and then set this flag in the
function above by (setq auto-just-flag auto-fill-hook) just before the
mode-line hack.  Then you would see both minor modes on the modeline.
You would also need a (make-variable-buffer-local 'auto-just-flag).

Or modify auto-fill-mode to set a separate auto-fill-flag for the
minor-mode-alist to watch, and modify minor-mode-alist accordingly.
To me "Justify" would imply "Fill", so this would save some mode-line
space.

Remainder left as an exercise to the readership.

Ashwin Ram has a much improved version of justify-current-line, which
is due to get into the distribution some day.  He sent it to me but I
didn't keep a copy.  Perhaps he will post it here.

/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis

ashwin@gatech.edu (Ashwin Ram) (12/05/89)

In article <49028@bbn.COM> John Robinson writes:
>   Ashwin Ram has a much improved version of justify-current-line, which
>   is due to get into the distribution some day.  He sent it to me but I
>   didn't keep a copy.  Perhaps he will post it here.

I've gotten a couple of requests for this, so here goes:
------------------------------------------------------------------------------
; Rewrote to spread blanks evenly across inter-word spaces in line.  Randomly
; decide whether to put extra spaces from the right or the left, to avoid
; "rivers" as far as possible.  Don't modify original interword spaces.
; Ashwin Ram, 11/16/87.
(defun justify-current-line ()
   "Add spaces to line point is in, so it ends at fill-column."
   (interactive)
   (save-excursion
      (save-restriction
         (beginning-of-line)
         (skip-chars-forward " \t")
         (let ((begin (point)))
            (end-of-line)
            (narrow-to-region begin (point))
            (let ((blanks (- fill-column (current-column))))
               (if (<= blanks 0)
                   nil
                   (goto-char begin)
                   (let ((holes 0))
                      (while (re-search-forward "[ \t][^ \t]" nil t)
                         (setq holes (+ holes 1)))
                      (let ((each (/ blanks holes))
                            (extra (% blanks holes))
                            (dir (> (random) 0))
                            (count 1))
                         (end-of-line)
                         (while (<= count holes)
                            (re-search-backward "[ \t][^ \t]")
                            (let ((n 1))
                               (while (<= n each)
                                  (insert ? )
                                  (setq n (+ n 1))))
                            (if dir
                                (if (<= count extra) (insert ? ))
                                (if (>= count (- holes (- extra 1))) (insert ? )))
                            (setq count (+ count 1)))))))))))
------------------------------------------------------------------------------

-- Ashwin (ashwin@gatech.edu)
--
Ashwin Ram
Georgia Institute of Technology, Atlanta, Georgia 30332-0280
UUCP:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!ar17
Internet: ashwin@gatech.edu, ashwin@pravda.gatech.edu, ar17@prism.gatech.edu