kinsoku.el 6.3 KB
Newer Older
1
;;; kinsoku.el --- `Kinsoku' processing funcs -*- coding: iso-2022-7bit; -*-
Karl Heuer's avatar
Karl Heuer committed
2

Glenn Morris's avatar
Glenn Morris committed
3
;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Glenn Morris's avatar
Glenn Morris committed
4
;;   Free Software Foundation, Inc.
Kenichi Handa's avatar
Kenichi Handa committed
5
;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
Glenn Morris's avatar
Glenn Morris committed
6
;;   2005, 2006, 2007, 2008
Kenichi Handa's avatar
Kenichi Handa committed
7 8
;;   National Institute of Advanced Industrial Science and Technology (AIST)
;;   Registration Number H14PRO021
Karl Heuer's avatar
Karl Heuer committed
9

Richard M. Stallman's avatar
Richard M. Stallman committed
10
;; Keywords: mule, kinsoku
Karl Heuer's avatar
Karl Heuer committed
11 12 13

;; This file is part of GNU Emacs.

14
;; GNU Emacs is free software: you can redistribute it and/or modify
Karl Heuer's avatar
Karl Heuer committed
15
;; it under the terms of the GNU General Public License as published by
16 17
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
Karl Heuer's avatar
Karl Heuer committed
18 19 20 21 22 23 24

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
25
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Karl Heuer's avatar
Karl Heuer committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

;;; Commentary:

;; `Kinsoku' processing is to prohibit specific characters to be
;; placed at beginning of line or at end of line.  Characters not to
;; be placed at beginning and end of line have character category `>'
;; and `<' respectively.   This restriction is dissolved by making a
;; line longer or shorter.
;;
;; `Kinsoku' is a Japanese word which originally means ordering to
;; stay in one place, and is used for the text processing described
;; above in the context of text formatting.

;;; Code:

(defvar kinsoku-limit 4
  "How many more columns we can make lines longer by `kinsoku' processing.
The value 0 means there's no limitation.")

;; Setting character category `>' for characters which should not be
;; placed at beginning of line.
(let* ((kinsoku-bol
	(concat
	 ;; ASCII
	 "!)-_~}]:;',.?"
51
	 ;; Latin JISX0201
Karl Heuer's avatar
Karl Heuer committed
52
	 ;; Instead of putting Latin JISX0201 string directly, we
53 54 55 56 57 58 59 60 61 62 63 64 65 66
	 ;; generate the string as below to avoid character
	 ;; unification problem.
	 (let* ((str1 "!)-_~}]:;',.?")
		(len (length str1))
		(idx 0)
		(str2 "")
		ch)
	   (while (< idx len)
	     (setq ch (make-char 'latin-jisx0201 (aref str1 idx))
		   str2 (concat str2 (char-to-string ch))
		   idx (1+ idx)))
	   str2)
	 ;; Katakana JISX0201
	 "(I!#'()*+,-./0^_(B"
Karl Heuer's avatar
Karl Heuer committed
67 68 69 70 71 72 73 74 75 76
	 ;; Japanese JISX0208
	 "$B!"!#!$!%!&!'!(!)!*!+!,!-!.!/!0!1!2!3!4!5!6!7!8!9!:!;!<!=!>(B\
$B!?!@!A!B!C!D!E!G!I!K!M!O!Q!S!U!W!Y![!k!l!m!n(B\
$B$!$#$%$'$)$C$c$e$g$n%!%#%%%'%)%C%c%e%g%n%u%v(B"
	 ;; Chinese GB2312
	 "$A!"!##.#,!$!%!&!'!(!)!*!+!,!-!/!1#)!3!5!7!9!;!=(B\
$A!?#;#:#?#!!@!A!B!C!c!d!e!f#/#\#"#_#~#|(e(B"
	 ;; Chinese BIG5
	 "$(0!"!#!$!%!&!'!(!)!*!+!,!-!.!/!0!1!2(B\
$(0!3!4!5!6!7!8!9!:!;!<!=!?!A!C!E!G!I!K(B\
Kenichi Handa's avatar
Kenichi Handa committed
77
$(0!M!O!Q!S!U!W!Y![!]!_!a!c!e!g!i!k!q(B\
Karl Heuer's avatar
Karl Heuer committed
78 79 80 81 82
$(0"#"$"%"&"'"(")"*"+","2"3"4"j"k"l"x%7(B"))
       (len (length kinsoku-bol))
       (idx 0)
       ch)
  (while (< idx len)
Kenichi Handa's avatar
Kenichi Handa committed
83 84
    (setq ch (aref kinsoku-bol idx)
	  idx (1+ idx))
Karl Heuer's avatar
Karl Heuer committed
85 86 87 88 89 90 91 92
    (modify-category-entry ch ?>)))

;; Setting character category `<' for characters which should not be
;; placed at end of line.
(let* ((kinsoku-eol
	(concat
	 ;; ASCII
	 "({[`"
93 94 95 96 97 98 99 100 101 102 103 104 105 106
	 ;; Latin JISX0201
	 ;; See the comment above.
	 (let* ((str1 "({[`")
		(len (length str1))
		(idx 0)
		(str2 "")
		ch)
	   (while (< idx len)
	     (setq ch (make-char 'latin-jisx0201 (aref str1 idx))
		   str2 (concat str2 (char-to-string ch))
		   idx (1+ idx)))
	   str2)
	 ;; JISX0201 Katakana
	 "(I"(B"
Karl Heuer's avatar
Karl Heuer committed
107 108 109 110 111
	 ;; Japanese JISX0208
	 "$B!F!H!J!L!N!P!R!T!V!X!Z!k!l!m!n!w!x(B\
$A!.!0#"#(!2!4!6!8!:!<!>!c!d!e#@!f!l(B"
	 ;; Chinese GB2312
	 "$A(E(F(G(H(I(J(K(L(M(N(O(P(Q(R(S(T(U(V(W(X(Y(h(B\
112
\$(0!>!@!B!D!F!H!J!L!N!P!R!T!V!X!Z!\!^!`!b(B"
Karl Heuer's avatar
Karl Heuer committed
113 114 115 116 117 118 119
	 ;; Chinese BIG5
	 "$(0!d!f!h!j!k!q!p"i"j"k"n"x$u$v$w$x$y$z${(B\
$(0$|$}$~%!%"%#%$%%%&%'%(%)%*%+%:(B"))
       (len (length kinsoku-eol))
       (idx 0)
       ch)
  (while (< idx len)
Kenichi Handa's avatar
Kenichi Handa committed
120 121
    (setq ch (aref kinsoku-eol idx)
	  idx (1+ idx))
Karl Heuer's avatar
Karl Heuer committed
122 123 124 125
    (modify-category-entry ch ?<)))

;; Try to resolve `kinsoku' restriction by making the current line longer.
(defun kinsoku-longer ()
126 127 128
  (let ((pos-and-column
	 (save-excursion
	   (forward-char 1)
129
	   (while (and (not (eolp))
130 131 132 133 134 135 136
		       (or (aref (char-category-set (following-char)) ?>)
			   ;; protect non-kinsoku words
			   (not (or (eq (preceding-char) ? )
				    (aref (char-category-set (preceding-char))
					  ?|)))))
	     (forward-char 1))
	   (cons (point) (current-column)))))
Karl Heuer's avatar
Karl Heuer committed
137 138 139 140 141
    (if (or (<= kinsoku-limit 0)
	    (< (cdr pos-and-column) (+ (current-fill-column) kinsoku-limit)))
	(goto-char (car pos-and-column)))))

;; Try to resolve `kinsoku' restriction by making the current line shorter.
142
;; The line can't be broken before the buffer position LINEBEG.
Karl Heuer's avatar
Karl Heuer committed
143 144 145
(defun kinsoku-shorter (linebeg)
  (let ((pos (save-excursion
	       (forward-char -1)
146 147 148 149 150 151 152 153
	       (while (and
		       (< linebeg (point))
		       (or (aref (char-category-set (preceding-char)) ?<)
			   (aref (char-category-set (following-char)) ?>)
			   ;; protect non-kinsoku words
			   (not (or (eq (preceding-char) ? )
				    (aref (char-category-set (preceding-char))
					  ?|)))))
Karl Heuer's avatar
Karl Heuer committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
		 (forward-char -1))
	       (point))))
    (if (< linebeg pos)
	(goto-char pos))))

;;;###autoload
(defun kinsoku (linebeg)
  "Go to a line breaking position near point by doing `kinsoku' processing.
LINEBEG is a buffer position we can't break a line before.

`Kinsoku' processing is to prohibit specific characters to be placed
at beginning of line or at end of line.  Characters not to be placed
at beginning and end of line have character category `>' and `<'
respectively.  This restriction is dissolved by making a line longer or
shorter.

`Kinsoku' is a Japanese word which originally means ordering to stay
in one place, and is used for the text processing described above in
the context of text formatting."
173 174 175
  (if enable-kinsoku
      (if (or (and
	       ;; The character after point can't be placed at beginning
176
	       ;; of line.
177 178 179 180 181 182 183 184
	       (aref (char-category-set (following-char)) ?>)
	       ;; We at first try to dissolve this situation by making a
	       ;; line longer.  If it fails, then try making a line
	       ;; shorter.
	       (not (kinsoku-longer)))
	      ;; The character before point can't be placed at end of line.
	      (aref (char-category-set (preceding-char)) ?<))
	  (kinsoku-shorter linebeg))))
Karl Heuer's avatar
Karl Heuer committed
185

186
;; arch-tag: e6b036bc-9e5b-4e9f-a22c-4ed04e37777e
187
;;; kinsoku.el ends here