From ce82deede20bb588e44520fb51c4fb25cf39c97c Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Wed, 21 Oct 1998 11:50:56 +0000 Subject: [PATCH] (sentence-end-without-period): New variable. (canonically-space-region): Pay attention to sentence-end-without-period. (fill-find-break-point): The first argument CHARSET deleted. Caller changed. (fill-region-as-paragraph): Pay attention to charset property nospace-between-words and text property nospace-between-words. --- lisp/textmodes/fill.el | 87 ++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index e96d20ace1c..a563cb52d72 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -47,6 +47,12 @@ A value of nil means that any change in indentation starts a new paragraph." :type 'boolean :group 'fill) +(defcustom sentence-end-without-period nil + "*Non-nil means a sentence will end without period. +For example, Thai text ends with double space but without period." + :type 'boolean + :group 'fill) + (defvar fill-paragraph-function nil "Mode-specific function to fill a paragraph, or nil if there is none. If the function returns nil, then `fill-paragraph' does its normal work.") @@ -136,7 +142,8 @@ number equals or exceeds the local fill-column - right-margin difference." (defun canonically-space-region (beg end) "Remove extra spaces between words in region. Leave one space between words, two at end of sentences or after colons -\(depending on values of `sentence-end-double-space' and `colon-double-space'). +\(depending on values of `sentence-end-double-space', `colon-double-space', +and `sentence-end-without-period'). Remove indentation from each line." (interactive "r") (save-excursion @@ -154,7 +161,9 @@ Remove indentation from each line." (save-excursion (skip-chars-backward " ]})\"'") (cond ((and sentence-end-double-space - (memq (preceding-char) '(?. ?? ?!))) 2) + (or (memq (preceding-char) '(?. ?? ?!)) + (and sentence-end-without-period + (= (char-syntax (preceding-char)) ?w)))) 2) ((and colon-double-space (= (preceding-char) ?:)) 2) ((char-equal (preceding-char) ?\n) 0) @@ -252,6 +261,8 @@ act as a paragraph-separator." The predicate is called with no arguments, with point at the place to be tested. If it returns t, fill commands do not break the line there.") +;; Put `fill-find-break-point-function' property to charsets which +;; require special functions to find line breaking point. (let ((alist '((katakana-jisx0201 . kinsoku) (chinese-gb2312 . kinsoku) (japanese-jisx0208 . kinsoku) @@ -263,18 +274,28 @@ to be tested. If it returns t, fill commands do not break the line there.") (cdr (car alist))) (setq alist (cdr alist)))) -(defun fill-find-break-point (charset limit) - "Move point to a proper line wrapping position of the current line. - -CHARSET is a non-ascii character set before or after the current position. +(defun fill-find-break-point (limit) + "Move point to a proper line breaking position of the current line. Don't move back past the buffer position LIMIT. -If CHARSET has the property `fill-find-break-point-function', this +This function is called when we are going to break the current line +after or before a non-ascii character. If the charset of the +character has the property `fill-find-break-point-function', this function calls the property value as a function with one arg LINEBEG. -If CHARSET has no such property, do nothing." - (let ((func (get-charset-property charset 'fill-find-break-point-function))) - (if func - (funcall func limit)))) +If the charset has no such property, do nothing." + (let* ((ch (following-char)) + (charset (char-charset ch)) + func) + (if (eq charset 'ascii) + (setq ch (preceding-char) + charset (char-charset ch))) + (if (eq charset 'ascii) + nil + (if (eq charset 'composition) + (setq charset (char-charset (composite-char-component ch 0))))) + (setq func (get-charset-property charset 'fill-find-break-point-function)) + (if (and func (fboundp func)) + (funcall func limit)))) (defun fill-region-as-paragraph (from to &optional justify nosqueeze squeeze-after) @@ -398,19 +419,29 @@ space does not end a sentence, so don't break a line there." ;; loses on split abbrevs ("Mr.\nSmith") (while (re-search-forward "[.?!][])}\"']*$" nil t) (or (eobp) (insert-and-inherit ?\ ))) - (goto-char from) - ;; The character category `|' means that we can break a line - ;; at the character. Since we don't need a space between - ;; them, delete all newlines between them ... - (while (re-search-forward "\\c|\n\\|\n\\c|" nil t) - (if (bolp) - (delete-char -1) - (if (= (char-before (match-beginning 0)) ?\ ) - ;; ... except when there is end of sentence. The - ;; variable `sentence-end-double-space' is handled - ;; properly later. - nil - (delete-region (match-beginning 0) (1+ (match-beginning 0)))))) + + (goto-char from) + (if enable-multibyte-characters + ;; Delete unnecessay newlines surrounded by words. The + ;; character category `|' means that we can break a line + ;; at the character. And, charset property + ;; `nospace-between-words' tells how to concatenate + ;; words. If the value is non-nil, never put spaces + ;; between words, thus delete a newline between them. + ;; If the value is nil, delete a newline only when a + ;; character preceding a newline has text property + ;; `nospace-between-words'. + (while (search-forward "\n" nil t) + (let ((prev (char-before (match-beginning 0))) + (next (following-char))) + (if (and (or (aref (char-category-set next) ?|) + (aref (char-category-set prev) ?|)) + (or (get-charset-property (char-charset prev) + 'nospace-between-words) + (get-text-property (1- (match-beginning 0)) + 'nospace-between-words))) + (delete-char -1))))) + (goto-char from) (skip-chars-forward " \t") ;; Then change all newlines to spaces. @@ -504,11 +535,9 @@ space does not end a sentence, so don't break a line there." ;; before a non-ascii character, we may have to ;; run a special function for the charset of the ;; character to find the correct break point. - (let ((charset (charset-after (1- (point))))) - (if (eq charset 'ascii) - (setq charset (charset-after (point)))) - (if (not (eq charset 'ascii)) - (fill-find-break-point charset linebeg))))) + (if (not (and (eq (charset-after (1- (point))) 'ascii) + (eq (charset-after (point)) 'ascii))) + (fill-find-break-point linebeg)))) ;; If the left margin and fill prefix by themselves ;; pass the fill-column, keep at least one word.