bccd7e5cb576998f2d918934f60beb7ec7343425
[elisp/flim.git] / ew-data.el
1 (require 'ew-var)
2 (require 'ew-util)
3 (provide 'ew-data)
4
5 (defun ew-make-anchor (column str)
6   (let ((anchor (make-symbol str)))
7     (put anchor 'anchor anchor)
8     (put anchor 'type 'ew:*anchor*)
9     (put anchor 'prev-frag anchor)
10     (put anchor 'next-frag anchor)
11     (put anchor 'column column)
12     (put anchor 'line-length 0)
13     anchor))
14
15 (defun ew-terminate (anchor)
16   (let ((frag (get anchor 'prev-frag))
17         (line-length (get anchor 'column)))
18     (while (null (get frag 'line-length))
19       (put frag 'line-length line-length)
20       (setq frag (get frag 'prev-frag)))))
21
22 (defsubst ew-add-frag (anchor start end type)
23   (let ((frag (make-symbol (substring (symbol-name anchor) start end))))
24     (put frag 'anchor anchor)
25     (put frag 'type type)
26     (put frag 'prev-frag (get anchor 'prev-frag))
27     (put frag 'next-frag anchor)
28     (put (get anchor 'prev-frag) 'next-frag frag)
29     (put anchor 'prev-frag frag)
30     (put frag 'decode (or (get type 'decode) 'ew-decode-none))
31     (if (string-match "\r\n\\(.*\r\n\\)*" (symbol-name frag))
32         (let ((prev-line-length (+ (get anchor 'column) (match-beginning 0)))
33               (next-line-column (- (length (symbol-name frag)) (match-end 0)))
34               (tmp frag))
35           (while (null (get tmp 'line-length))
36             (put tmp 'line-length prev-line-length)
37             (setq tmp (get tmp 'prev-frag)))
38           (put anchor 'column next-line-column))
39       (put anchor 'column (+ (get anchor 'column) (length (symbol-name frag)))))
40     frag))
41
42 ;;; listup
43
44 (defun ew-frag-list (anchor)
45   (let ((res ())
46         (tmp (get anchor 'prev-frag)))
47     (while (not (eq anchor tmp))
48       (setq res (cons tmp res)
49             tmp (get tmp 'prev-frag)))
50     res))
51
52 (defun ew-pair-list (anchor)
53   (mapcar
54    (lambda (frag)
55      (cons (symbol-value (get frag 'type))
56            frag))
57    (ew-frag-list anchor)))
58
59 (defun ew-separate-eword (frag1 frag2 targets)
60   (while (not (eq frag1 frag2))
61     (when (and (memq (get frag1 'type) targets)
62                (string-match ew-encoded-word-regexp
63                              (symbol-name frag1))
64                (or (< 0 (match-beginning 0))
65                    (< (match-end 0) (length (symbol-name frag1)))))
66       (let ((atom (symbol-name frag1))
67             (start (match-end 0))
68             result
69             frag)
70         (when (< 0 (match-beginning 0))
71           (setq frag (make-symbol (substring atom 0 (match-beginning 0)))
72                 result (ew-rcons* result frag)))
73         (setq frag (make-symbol (substring atom (match-beginning 0) (match-end 0)))
74               result (ew-rcons* result frag))
75         (when (cdr result)
76           (put frag 'prev-frag (cadr result))
77           (put (cadr result) 'next-frag frag)
78           (setq frag (cadr result)))
79         (put frag 'prev-frag (get frag1 'prev-frag))
80         (put (get frag1 'prev-frag) 'next-frag frag)
81         (while (string-match ew-encoded-word-regexp atom start)
82           (when (< start (match-beginning 0))
83             (setq frag (make-symbol (substring atom start (match-beginning 0)))
84                   result (ew-rcons* result frag))
85             (put frag 'prev-frag (cadr result))
86             (put (cadr result) 'next-frag frag))
87           (setq frag (make-symbol (substring atom (match-beginning 0) (match-end 0)))
88                 result (ew-rcons* result frag)
89                 start (match-end 0))
90           (put frag 'prev-frag (cadr result))
91           (put (cadr result) 'next-frag frag))
92         (when (< start (length (symbol-name frag1)))
93           (setq frag (make-symbol (substring atom start))
94                 result (ew-rcons* result frag))
95           (put frag 'prev-frag (cadr result))
96           (put (cadr result) 'next-frag frag))
97         (setq frag (car result))
98         (put frag 'next-frag (get frag1 'next-frag))
99         (put (get frag1 'next-frag) 'prev-frag frag)
100         (while result
101           (setq frag (car result)
102                 result (cdr result))
103           (put frag 'anchor (get frag1 'anchor))
104           (put frag 'type (get frag1 'type))
105           (put frag 'decode (get frag1 'decode))
106           (put frag 'line-length (get frag1 'line-length)))))
107     (setq frag1 (get frag1 'next-frag))))
108
109 ;;; phrase marking
110
111 (defun ew-mark-phrase (frag1 frag2)
112   (when ew-decode-sticked-encoded-word
113     (ew-separate-eword
114      frag1 frag2
115      (if ew-decode-quoted-encoded-word
116          '(ew:atom
117            ew:qs-texts)
118        '(ew:atom)))
119     (setq frag1 (get (get frag1 'prev-frag) 'next-frag)))
120   (while (not (eq frag1 frag2))
121     (unless (ew-comment-frag-p frag2)
122       (put frag2 'decode 'ew-decode-phrase))
123     (setq frag2 (get frag2 'prev-frag)))
124   (unless (ew-comment-frag-p frag2)
125     (put frag2 'decode 'ew-decode-phrase))
126   (setq frag2 (get frag2 'prev-frag))
127   (while (not (ew-token-last-frag-p frag2))
128     (unless (ew-comment-frag-p frag2)
129       (put frag2 'decode 'ew-decode-phrase))
130     (setq frag2 (get frag2 'prev-frag))))
131
132 ;;; frag predicate
133
134 (defun ew-token-last-frag-p (frag)
135   (member (get frag 'type)
136           '(ew:*anchor*
137             ew:lt
138             ew:gt
139             ew:at
140             ew:comma
141             ew:semicolon
142             ew:colon
143             ew:dot
144             ew:atom
145             ew:qs-end
146             ew:dl-end)))
147
148 (defun ew-comment-frag-p (frag)
149   (member (get frag 'type)
150           '(ew:cm-begin
151             ew:cm-end
152             ew:cm-nested-begin
153             ew:cm-nested-end
154             ew:cm-texts
155             ew:cm-wsp
156             ew:cm-fold
157             ew:cm-qfold
158             ew:cm-qpair)))
159
160 (defun ew-special-frag-p (frag)
161   (member (get frag 'type)
162           '(ew:lt
163             ew:gt
164             ew:at
165             ew:comma
166             ew:semicolon
167             ew:colon
168             ew:dot
169             ew:qs-begin
170             ew:qs-end
171             ew:dl-begin
172             ew:dl-end
173             ew:cm-begin
174             ew:cm-end)))