Function: thai-forward-word-update-info

thai-forward-word-update-info is a byte-compiled function defined in thai-word.el.gz.

Signature

(thai-forward-word-update-info VEC LIMIT)

Source Code

;; Defined in /usr/src/emacs/lisp/language/thai-word.el.gz
;; Move point forward to the end of Thai word which follows point and
;; update VEC.  VEC is a vector of three elements used to cache word
;; end positions.  The Nth element, if non-nil, is a list of end
;; points of the Nth word, or t indicating that there is no Thai
;; character.  LIMIT limits the point movement.

(defun thai-forward-word-update-info (vec limit)
  (let ((pos (point))
	v0 v1 v2 v3
	second-best
	tried
	positions)
    (if
	;; If four succeeding Thai words are found, throw t, otherwise
	;; throw nil.
	(catch 'tag
	  ;; Start with first vector element.
	  (setq v0 (aref vec 0))
	  (unless v0
	    ;; Update VEC if V0 is empty.
	    (setq v0 (thai-find-word-ends pos limit))
	    (aset vec 0 v0)
	    (aset vec 1 nil))
	  ;; In case we haven't found any wordbreaks resp. point has
	  ;; reached LIMIT, exit the catch body.
	  (if (symbolp v0)		; i.e. nil or t?
	      (throw 'tag nil))
	  ;; OK, V0 holds possible word ends for the current position.
	  ;; We save V0 for later reference.
	  (setq tried v0)
	  (setq v1 (aref vec 1))
	  ;; Now we try all end word positions to find the next word.
	  (while v0
	    (setq pos (car v0))
	    (unless v1
	      ;; Update VEC if V1 is empty, ignoring positions already
	      ;; found -- for Thai, we need the longest match, so if
	      ;; we have
	      ;;
	      ;;   start(long-word) = start(short-word1)
	      ;;   end(short-word1) = start(short-word2)
	      ;;   end(short-word2) = end(long-word)
	      ;;
	      ;; only long-word is used.
	      (setq v1 (thai-find-word-ends pos limit tried))
	      (aset vec 1 v1)
	      (aset vec 2 nil))
	    ;; If point has reached LIMIT, exit the catch body.
	    (if (eq v1 t)
		(throw 'tag t))
	    ;; Save SECOND-BEST, if this hasn't been done already.
	    ;; The `second best' solution is the end position of the
	    ;; longest first word followed by the longest second word.
	    (or second-best
		(not v1)
		(setq second-best (cons v0 v1)))
	    ;; Update the already tried end word positions.
	    (setq tried (append tried v1))
	    ;; Now repeat the whole process to find a third word.
	    (when v1
	      (setq v2 (aref vec 2))
	      (while v1
		(setq pos (car v1))
		(unless v2
		  (setq v2 (thai-find-word-ends pos limit tried))
		  (aset vec 2 v2))
		(if (eq v2 t)
		    (throw 'tag t))
		(setq tried (append tried v2))
		;; And the same for a fourth word.
		(while v2
		  (setq pos (car v2))
		  (setq v3 (thai-find-word-ends pos limit tried))
		  (if v3
		      (throw 'tag t))
		  (setq v2 (cdr v2)))
		(setq v1 (cdr v1))))
	    (setq v0 (cdr v0)))
	  ;; No success.
	  nil)
	(progn
	  ;; We found four succeeding Thai words (or LIMIT has been
	  ;; reached).  Move to the end of the first word.
	  (goto-char (car v0))
	  ;; Update VEC for the next function call.  If no larger word
	  ;; positions have been found, set the corresponding vector
	  ;; element to nil.
	  (if (and (consp v1) (< (car v1) (car (aref vec 1))))
	      (aset vec 0 nil)
	    (aset vec 0 v1)
	    (if (and (consp v2) (< (car v2) (car (aref vec 2))))
		(aset vec 1 nil)
	      (aset vec 1 v2)
	      (aset vec 2 v3)))) ; exit function successfully

      ;; We didn't find four consecutive words.  If we have found a
      ;; `second best' solution and the length of those two words is
      ;; longer than the longest word we can see at the current point,
      ;; adopt the second best solution.  This decision is based on
      ;; heuristic tests.
      (if (and second-best
	       (< (car (aref vec 0)) (car (cdr second-best))))
	  (progn
	    (goto-char (car (car second-best)))
	    (aset vec 0 (cdr second-best)))
	;; We finally failed to find a word break.  For Thai, the best
	;; solution is to extend the first longest word so that the
	;; end point starts a second word.
	(setq pos (or (car (aref vec 0)) pos))
	(while (and (< pos limit)
		    (not (setq positions (thai-find-word-ends pos limit))))
	  (setq pos (1+ pos)))
	(goto-char pos)
	(aset vec 0 positions))
      (aset vec 1 nil)
      nil)))