Initial Commit
[packages] / xemacs-packages / hyperbole / kotl / kotl.el
1 ;;; kotl.el --- Internal representation of outline kcells used by kviews.
2
3 ;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
4 ;; Developed with support from Motorola Inc.
5
6 ;; Author: Bob Weiner, Brown U.
7 ;;         Kellie Clark
8 ;; Maintainer: Mats Lidell <matsl@contactor.se>
9 ;; Keywords: outlines, wp
10
11 ;; This file is part of GNU Hyperbole.
12
13 ;; GNU Hyperbole is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 3, or (at
16 ;; your option) any later version.
17
18 ;; GNU Hyperbole is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 ;; General Public License for more details.
22
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 ;; Boston, MA 02110-1301, USA.
27
28 ;;; Commentary:
29
30 ;;; Code:
31
32 ;;;
33 ;;; Other required Elisp libraries
34 ;;;
35
36 (mapcar 'require '(klabel knode hinit htz))
37
38 ;;;
39 ;;; Public variables
40 ;;;
41
42 (defvar kcell:read-only-attributes
43   '(idstamp creator create-time modifier mod-time)
44   "List of kcell attributes which may not be modified by a user.
45 Add to this list but don't remove any of the default elements.")
46
47 ;;;
48 ;;; Public functions
49 ;;;
50
51 ;;;
52 ;;; kcell
53 ;;;
54
55 (fset 'kcell:contents     'knode:contents)
56
57 (defun kcell:copy (kcell)
58   "Return a copy of KCELL."
59   (knode:copy kcell))
60
61 (defun kcell:create (contents idstamp &optional plist)
62   "Return a new kcell which stores CONTENTS (a string or nil), has permanent IDSTAMP (an integer), and optional additional property list, PLIST.
63 User id of `creator' of cell and `create-time' are added to cell's PLIST if
64 not already there."
65   (and contents (not (stringp contents))
66        (error "(kcell:create): Invalid `contents' argument: %s" contents))
67   (if (or (not (integerp idstamp)) (< idstamp 0))
68       (error "(kcell:create): Invalid `idstamp' argument: %s" idstamp))
69   (knode:create
70    contents (nconc (list 'idstamp idstamp)
71                    (if (memq 'creator plist)
72                        nil
73                      (list 'creator (concat (user-login-name)
74                                             hyperb:host-domain)
75                            'create-time (htz:date-sortable-gmt)))
76                    plist)))
77
78 (defun kcell:create-top (&optional file counter)
79   "Return a new koutline top cell optionally attached to FILE with current idstamp COUNTER."
80   (kcell:create nil 0
81                 ;; id-counter = max idstamp value given out in this kotl
82                 (list 'id-counter (or counter 0) 'file file)))
83
84 (defun kcell:get-attr (kcell attribute)
85   "Return the value of KCELL's ATTRIBUTE."
86   (knode:get-attr (kcell:plist kcell) attribute))
87
88 (defun kcell:idstamp (kcell)
89   "Return permanent idstamp of KCELL as an integer."
90   (kcell:get-attr kcell 'idstamp))
91
92 (fset 'kcell:is-p      'knode:is-p)
93
94 (defun kcell:plist (kcell)
95   (knode:get-attr kcell 'plist))
96
97 (defun kcell:ref-to-id (cell-ref)
98   "Returns a CELL-REF string converted to a cell identifier string.
99 If CELL-REF contains both a relative and a permanent id, the permanent id is
100 returned.  If CELL-REF is invalid, nil is returned.
101
102 CELL-REF may be of any of the following forms:
103   1b        - relative id, augment style
104   1.2       - relative id, legal style
105   012       - permanent idstamp
106   1a=012    - both relative and permanent ids (in that order) separated by =
107   |viewspec - a viewspec setting, rather than a cell reference
108   :viewspec - an augment viewspec, ignored for now.
109
110 Optionally, any of the above id forms may be followed by a period and some
111 alpha characters indicating a location relative to the id.
112
113 Optionally, any of these id forms (or the relative form) may be followed by
114 zero or more whitespace characters, a | and some view specification
115 characters.  Augment viewspec characters preceded by a colon are ignored, for
116 now."
117
118   (if (not (stringp cell-ref))
119       nil
120     (setq cell-ref (hypb:replace-match-string "\\s +" cell-ref "" t))
121     (let ((specs) result)
122       ;; Ignore Augment :viewspecs.
123       (if (string-match ":" cell-ref)
124           (setq cell-ref (substring cell-ref 0 (match-beginning 0))))
125       ;; Separate koutline |viewspecs from cell id.
126       (if (string-match "\\(\\.[a-zA-Z]\\||\\)" cell-ref)
127           (setq specs (substring cell-ref (match-beginning 1))
128                 cell-ref (substring cell-ref 0 (match-beginning 0))))
129       (setq result
130             (cond
131              ((string-match "[^.= \t\n0-9a-zA-Z]" cell-ref) nil)
132              ((string-match "^\\([.0-9a-zA-Z]+\\)=\\(0[0-9]*\\)$"
133                             cell-ref)
134               (substring cell-ref (match-beginning 2) (match-end 2)))
135              ((string-match "^\\([.0-9a-zA-Z]+\\)$" cell-ref)
136               (substring cell-ref (match-beginning 1) (match-end 1)))))
137       (cond (result
138              (if specs (concat result specs) result))
139             (specs
140              (if (= ?| (aref specs 0)) specs))))))
141         
142 (defun kcell:remove-attr (kcell attribute)
143   "Remove KCELL's ATTRIBUTE, if any, return modified KCELL."
144   (knode:set-attr
145    kcell 'plist (knode:remove-attr (kcell:plist kcell) attribute)))
146
147 (defun kcell:set-attr (kcell attribute value)
148   "Set KCELL's ATTRIBUTE to VALUE and return modified KCELL."
149   (knode:set-attr
150    kcell 'plist (knode:set-attr (kcell:plist kcell)
151                                 attribute value)))
152
153 (defun kcell:set-create-time (kcell)
154   "Store the time of creation of KCELL."
155   (kcell:set-attr kcell 'create-time (htz:date-sortable-gmt)))
156
157 (defun kcell:set-creator (kcell)
158   "Store the current user's id as the creator of KCELL."
159   (kcell:set-attr
160    kcell 'creator (concat (user-login-name) hyperb:host-domain)))
161
162 (defun kcell:set-idstamp (kcell idstamp)
163   "Set KCELL's permanent IDSTAMP (an integer) and return IDSTAMP."
164   (kcell:set-attr kcell 'idstamp idstamp)
165   (kcell:idstamp kcell))
166
167 ;;;
168 ;;; kotl-data - Persistent representation of kotl cells (written to files).
169 ;;;
170
171 (defun kotl-data:create (cell)
172   "Given a kotl CELL, return a kotl-data structure to write to a file.
173 If CELL, its idstamp, or its property list are nil, this repairs the cell by
174 assuming it is the cell at point and filling in the missing information."
175    (let ((idstamp (kcell:idstamp cell))
176          (plist (nthcdr 2 (kcell:plist cell))))
177      (if (and cell idstamp plist)
178          (vector idstamp plist)
179        (kotl-data:create
180         (kcell:create nil
181                       (or idstamp (kview:id-increment kview))
182                       plist)))))
183
184 (defun kotl-data:idstamp (kotl-data)
185   (aref kotl-data 0))
186
187 (defun kotl-data:plist-v2 (kotl-data)
188   (aref kotl-data 2))
189
190 (defun kotl-data:plist-v3 (kotl-data)
191   (aref kotl-data 1))
192
193 (defun kotl-data:to-kcell-v2 (kotl-data)
194   (if (vectorp kotl-data)
195       (kcell:create
196        ;; Cell contents are no longer put into cells themselves by default
197        ;; when a file is read.  The contents are stored within the kview
198        ;; buffer, so use nil as a place-holder.
199        nil
200        ;; Repair invalid idstamps on the fly.
201        (or (kotl-data:idstamp kotl-data) (kview:id-increment kview))
202        (kotl-data:plist-v2 kotl-data))
203     ;; Repair invalid cells on the fly.
204     (kcell:create nil (kview:id-increment kview))))
205
206 (defun kotl-data:to-kcell-v3 (kotl-data)
207   (if (vectorp kotl-data)
208       (kcell:create
209        ;; Cell contents are no longer put into cells themselves by default
210        ;; when a file is read.  The contents are stored within the kview
211        ;; buffer, so use nil as a place-holder.
212        nil
213        ;; Repair invalid idstamps on the fly.
214        (or (kotl-data:idstamp kotl-data) (kview:id-increment kview))
215        (kotl-data:plist-v3 kotl-data))
216     ;; Repair invalid cells on the fly.
217     (kcell:create nil (kview:id-increment kview))))
218
219 (provide 'kotl)
220
221 ;;; kotl.el ends here