aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Belaïche2014-01-02 22:05:34 +0100
committerVincent Belaïche2014-01-02 22:05:34 +0100
commitb66b98fe412a97008778b34fa76ada7d1609631c (patch)
tree282ee059b79419b6d9e26ad2959f5af2c6a42038
parent112720b181938915e4d4a65cd86f03d3b2f1f17e (diff)
downloademacs-b66b98fe412a97008778b34fa76ada7d1609631c.tar.gz
emacs-b66b98fe412a97008778b34fa76ada7d1609631c.zip
Add support for local printer functions in SES.
-rw-r--r--doc/misc/ChangeLog4
-rw-r--r--doc/misc/ses.texi7
-rw-r--r--lisp/ChangeLog28
-rw-r--r--lisp/ses.el243
4 files changed, 259 insertions, 23 deletions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 8e9321445df..4017b34f02c 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -2,6 +2,10 @@
2 2
3 * eshell.text (top): Fix incorrect info filename in an xref. 3 * eshell.text (top): Fix incorrect info filename in an xref.
4 4
52014-01-02 Vincent Belaïche <vincentb1@users.sourceforge.net>
6
7 * ses.texi: Add documentation for local printer functions.
8
52014-01-02 Glenn Morris <rgm@gnu.org> 92014-01-02 Glenn Morris <rgm@gnu.org>
6 10
7 * Makefile.in (cc_mode_deps): Rename from (typo) ccmode_deps. 11 * Makefile.in (cc_mode_deps): Rename from (typo) ccmode_deps.
diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi
index e57ed802459..11fd55e8dcb 100644
--- a/doc/misc/ses.texi
+++ b/doc/misc/ses.texi
@@ -434,6 +434,13 @@ Centering with dashes and spill-over.
434Centering with tildes (~) and spill-over. 434Centering with tildes (~) and spill-over.
435@end table 435@end table
436 436
437You can define printer function local to a sheet with command
438@code{ses-define-local-printer}. For instance define printer
439@samp{foo} to @code{"%.2f"} and then use symbol @samp{foo} as a
440printer function. Then, if you call again
441@code{ses-define-local-printer} on @samp{foo} to redefine it as
442@code{"%.3f"} all the cells using printer @samp{foo} will be reprinted
443accordingly.
437 444
438@node Clearing cells 445@node Clearing cells
439@section Clearing cells 446@section Clearing cells
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4e5ec335936..32fa519242d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,31 @@
12014-01-02 Vincent Belaïche <vincentb1@users.sourceforge.net>
2
3 * ses.el (ses-initial-global-parameters-re): New defconst, a
4 specific regexp is needed now that ses.el can handle both
5 file-format 2 (no local printers) and 3 (may have local printers).
6 (silence compiler): Add local variables needed for local printer
7 handling.
8 (ses-set-localvars): Handle hashmap initialisation.
9 (ses-paramlines-plist): Add param-line for number of local printers.
10 (ses-paramfmt-plist): New defconst, needed for code factorization
11 between functions `ses-set-parameter' and
12 `ses-file-format-extend-paramter-list'
13 (ses-make-local-printer-info): New defsubst.
14 (ses-locprn-get-compiled, ses-locprn-compiled-aset)
15 (ses-locprn-get-def, ses-locprn-def-aset, ses-locprn-get-number)
16 (ses-cell-printer-aset): New defmacro.
17 (ses-local-printer-compile): New defun.
18 (ses-local-printer): New defmacro.
19 (ses-printer-validate, ses-call-printer): Add support for local
20 printer functions.
21 (ses-file-format-extend-paramter-list): New defun.
22 (ses-set-parameter): Use const `ses-paramfmt-plist' for code factorization.
23 (ses-load): Add support for local
24 printer functions.
25 (ses-read-printer): Update docstring and add support for local printer functions.
26 (ses-refresh-local-printer, ses-define-local-printer): New defun.
27 (ses-safe-printer): Add support for local printer functions.
28
12013-12-31 Eli Zaretskii <eliz@gnu.org> 292013-12-31 Eli Zaretskii <eliz@gnu.org>
2 30
3 * international/mule-conf.el: Unify the charset indian-is13194. 31 * international/mule-conf.el: Unify the charset indian-is13194.
diff --git a/lisp/ses.el b/lisp/ses.el
index feaa7bd91d4..cdf479398ed 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -238,6 +238,10 @@ Each function is called with ARG=1."
238 "\n( ;Global parameters (these are read first)\n 2 ;SES file-format\n 1 ;numrows\n 1 ;numcols\n)\n\n" 238 "\n( ;Global parameters (these are read first)\n 2 ;SES file-format\n 1 ;numrows\n 1 ;numcols\n)\n\n"
239 "Initial contents for the three-element list at the bottom of the data area.") 239 "Initial contents for the three-element list at the bottom of the data area.")
240 240
241(defconst ses-initial-global-parameters-re
242 "\n( ;Global parameters (these are read first)\n [23] ;SES file-format\n [0-9]+ ;numrows\n [0-9]+ ;numcols\n\\( [0-9]+ ;numlocprn\n\\)?)\n\n"
243 "Match Global parameters for .")
244
241(defconst ses-initial-file-trailer 245(defconst ses-initial-file-trailer
242 ";; Local Variables:\n;; mode: ses\n;; End:\n" 246 ";; Local Variables:\n;; mode: ses\n;; End:\n"
243 "Initial contents for the file-trailer area at the bottom of the file.") 247 "Initial contents for the file-trailer area at the bottom of the file.")
@@ -271,11 +275,17 @@ default printer and then modify its output.")
271;; Local variables and constants 275;; Local variables and constants
272;;---------------------------------------------------------------------------- 276;;----------------------------------------------------------------------------
273 277
274(eval-and-compile 278(eval-and-compile ; silence compiler
275 (defconst ses-localvars 279 (defconst ses-localvars
276 '(ses--blank-line ses--cells ses--col-printers 280 '(ses--blank-line ses--cells ses--col-printers
277 ses--col-widths ses--curcell ses--curcell-overlay 281 ses--col-widths ses--curcell ses--curcell-overlay
278 ses--default-printer 282 ses--default-printer
283 (ses--local-printer-hashmap . :hashmap)
284 ;; the list is there to remember the order of local printers like there
285 ;; are written to the SES filen which service the hashmap does not
286 ;; provide.
287 ses--local-printer-list
288 (ses--numlocprn . 0); count of local printers
279 ses--deferred-narrow ses--deferred-recalc 289 ses--deferred-narrow ses--deferred-recalc
280 ses--deferred-write ses--file-format 290 ses--deferred-write ses--file-format
281 ses--named-cell-hashmap 291 ses--named-cell-hashmap
@@ -298,7 +308,20 @@ default printer and then modify its output.")
298 ((symbolp x) 308 ((symbolp x)
299 (set (make-local-variable x) nil)) 309 (set (make-local-variable x) nil))
300 ((consp x) 310 ((consp x)
301 (set (make-local-variable (car x)) (cdr x))) 311 (cond
312 ((integerp (cdr x))
313 (set (make-local-variable (car x)) (cdr x)))
314 ((eq (cdr x) :hashmap)
315 (set (make-local-variable (car x))
316 (if (boundp (car x))
317 (let ((xv (symbol-value (car x))))
318 (if (hash-table-p xv)
319 (clrhash xv)
320 (warn "Unexpected value of symbol %S, should be a hash table" x)
321 (make-hash-table :test 'eq)))
322 (make-hash-table :test 'eq))))
323 (t (error "Unexpected initializer `%S' in list `ses-localvars' for entry %S"
324 (cdr x) (car x)) ) ))
302 (t (error "Unexpected elements `%S' in list `ses-localvars'" x)))))) 325 (t (error "Unexpected elements `%S' in list `ses-localvars'" x))))))
303 326
304(eval-when-compile ; silence compiler 327(eval-when-compile ; silence compiler
@@ -310,10 +333,21 @@ default printer and then modify its output.")
310(defconst ses-paramlines-plist 333(defconst ses-paramlines-plist
311 '(ses--col-widths -5 ses--col-printers -4 ses--default-printer -3 334 '(ses--col-widths -5 ses--col-printers -4 ses--default-printer -3
312 ses--header-row -2 ses--file-format 1 ses--numrows 2 335 ses--header-row -2 ses--file-format 1 ses--numrows 2
313 ses--numcols 3) 336 ses--numcols 3 ses--numlocprn 4)
314 "Offsets from 'Global parameters' line to various parameter lines in the 337 "Offsets from 'Global parameters' line to various parameter lines in the
315data area of a spreadsheet.") 338data area of a spreadsheet.")
316 339
340(defconst ses-paramfmt-plist
341 '(ses--col-widths "(ses-column-widths %S)"
342 ses--col-printers "(ses-column-printers %S)"
343 ses--default-printer "(ses-default-printer %S)"
344 ses--header-row "(ses-header-row %S)"
345 ses--file-format " %S ;SES file-format"
346 ses--numrows " %S ;numrows"
347 ses--numcols " %S ;numcols"
348 ses--numlocprn " %S ;numlocprn")
349 "Formats of 'Global parameters' various parameters in the data
350area of a spreadsheet.")
317 351
318;; 352;;
319;; "Side-effect variables". They are set in one function, altered in 353;; "Side-effect variables". They are set in one function, altered in
@@ -354,6 +388,30 @@ when to emit a progress message.")
354 property-list) 388 property-list)
355 (vector symbol formula printer references property-list)) 389 (vector symbol formula printer references property-list))
356 390
391(defsubst ses-make-local-printer-info (def &optional compiled-def number)
392 (let ((v (vector def
393 (or compiled-def (ses-local-printer-compile def))
394 (or number ses--numlocprn)
395 nil)))
396 (push v ses--local-printer-list)
397 (aset v 3 ses--local-printer-list)
398 v))
399
400(defmacro ses-locprn-get-compiled (locprn)
401 `(aref ,locprn 1))
402
403(defmacro ses-locprn-compiled-aset (locprn compiled)
404 `(aset ,locprn 1 ,compiled))
405
406(defmacro ses-locprn-get-def (locprn)
407 `(aref ,locprn 0))
408
409(defmacro ses-locprn-def-aset (locprn def)
410 `(aset ,locprn 0 ,def))
411
412(defmacro ses-locprn-get-number (locprn)
413 `(aref ,locprn 2))
414
357(defmacro ses-cell-symbol (row &optional col) 415(defmacro ses-cell-symbol (row &optional col)
358 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1." 416 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1."
359 `(aref ,(if col `(ses-get-cell ,row ,col) row) 0)) 417 `(aref ,(if col `(ses-get-cell ,row ,col) row) 0))
@@ -371,6 +429,10 @@ when to emit a progress message.")
371 "From a CELL or a pair (ROW,COL), get the function that prints its value." 429 "From a CELL or a pair (ROW,COL), get the function that prints its value."
372 `(aref ,(if col `(ses-get-cell ,row ,col) row) 2)) 430 `(aref ,(if col `(ses-get-cell ,row ,col) row) 2))
373 431
432(defmacro ses-cell-printer-aset (cell printer)
433 "From a CELL set the printer that prints its value."
434 `(aset ,cell 2 ,printer))
435
374(defmacro ses-cell-references (row &optional col) 436(defmacro ses-cell-references (row &optional col)
375 "From a CELL or a pair (ROW,COL), get the list of symbols for cells whose 437 "From a CELL or a pair (ROW,COL), get the list of symbols for cells whose
376functions refer to its value." 438functions refer to its value."
@@ -550,6 +612,29 @@ PRINTER are deferred until first use."
550 (set sym value) 612 (set sym value)
551 sym) 613 sym)
552 614
615(defun ses-local-printer-compile (printer)
616 "Convert local printer function into faster printer
617definition."
618 (cond
619 ((functionp printer) printer)
620 ((stringp printer)
621 `(lambda (x) (format ,printer x)))
622 (t (error "Invalid printer %S" printer))))
623
624(defmacro ses-local-printer (printer-name printer-def)
625 "Define a local printer with name PRINTER-NAME and definition
626PRINTER-DEF. Return the printer info."
627 (or
628 (and (symbolp printer-name)
629 (ses-printer-validate printer-def))
630 (error "Invalid local printer definition"))
631 (and (gethash printer-name ses--local-printer-hashmap)
632 (error "Duplicate printer definition %S" printer-name))
633 (add-to-list 'ses-read-printer-history (symbol-name printer-name))
634 (puthash printer-name
635 (ses-make-local-printer-info (ses-safe-printer printer-def))
636 ses--local-printer-hashmap))
637
553(defmacro ses-column-widths (widths) 638(defmacro ses-column-widths (widths)
554 "Load the vector of column widths from the spreadsheet file. This is a 639 "Load the vector of column widths from the spreadsheet file. This is a
555macro to prevent propagate-on-load viruses." 640macro to prevent propagate-on-load viruses."
@@ -663,6 +748,8 @@ is a vector--if a symbol, the new vector is assigned as the symbol's value."
663 "Signal an error if PRINTER is not a valid SES cell printer." 748 "Signal an error if PRINTER is not a valid SES cell printer."
664 (or (not printer) 749 (or (not printer)
665 (stringp printer) 750 (stringp printer)
751 ;; printer is a local printer
752 (and (symbolp printer) (gethash printer ses--local-printer-hashmap))
666 (functionp printer) 753 (functionp printer)
667 (and (stringp (car-safe printer)) (not (cdr printer))) 754 (and (stringp (car-safe printer)) (not (cdr printer)))
668 (error "Invalid printer function")) 755 (error "Invalid printer function"))
@@ -1260,7 +1347,13 @@ printer signaled one (and \"%s\" is used as the default printer), else nil."
1260 (format (car printer) value) 1347 (format (car printer) value)
1261 "")) 1348 ""))
1262 (t 1349 (t
1263 (setq value (funcall printer (or value ""))) 1350 (setq value (funcall
1351 (or (and (symbolp printer)
1352 (let ((locprn (gethash printer ses--local-printer-hashmap)))
1353 (and locprn
1354 (ses-locprn-get-compiled locprn))))
1355 printer)
1356 (or value "")))
1264 (if (stringp value) 1357 (if (stringp value)
1265 value 1358 value
1266 (or (stringp (car-safe value)) 1359 (or (stringp (car-safe value))
@@ -1333,6 +1426,22 @@ ses--default-printer, ses--numrows, or ses--numcols."
1333 (goto-char ses--params-marker) 1426 (goto-char ses--params-marker)
1334 (forward-line def)))) 1427 (forward-line def))))
1335 1428
1429(defun ses-file-format-extend-paramter-list (new-file-format)
1430 "Extend the global parameters list when file format is updated
1431from 2 to 3. This happens when local printer function are added
1432to a sheet that was created with SES version 2. This is not
1433undoable. Return nil when there was no change, and non nil otherwise."
1434 (save-excursion
1435 (cond
1436 ((and (= ses--file-format 2) (= 3 new-file-format))
1437 (ses-set-parameter 'ses--file-format 3 )
1438 (ses-widen)
1439 (goto-char ses--params-marker)
1440 (forward-line (plist-get ses-paramlines-plist 'ses--numlocprn ))
1441 (insert (format (plist-get ses-paramfmt-plist 'ses--numlocprn) ses--numlocprn)
1442 ?\n)
1443 t) )))
1444
1336(defun ses-set-parameter (def value &optional elem) 1445(defun ses-set-parameter (def value &optional elem)
1337 "Set parameter DEF to VALUE (with undo) and write the value to the data area. 1446 "Set parameter DEF to VALUE (with undo) and write the value to the data area.
1338See `ses-goto-data' for meaning of DEF. Newlines in the data are escaped. 1447See `ses-goto-data' for meaning of DEF. Newlines in the data are escaped.
@@ -1342,13 +1451,7 @@ If ELEM is specified, it is the array subscript within DEF to be set to VALUE."
1342 ;; in case one of them is being changed. 1451 ;; in case one of them is being changed.
1343 (ses-goto-data def) 1452 (ses-goto-data def)
1344 (let ((inhibit-read-only t) 1453 (let ((inhibit-read-only t)
1345 (fmt (plist-get '(ses--col-widths "(ses-column-widths %S)" 1454 (fmt (plist-get ses-paramfmt-plist
1346 ses--col-printers "(ses-column-printers %S)"
1347 ses--default-printer "(ses-default-printer %S)"
1348 ses--header-row "(ses-header-row %S)"
1349 ses--file-format " %S ;SES file-format"
1350 ses--numrows " %S ;numrows"
1351 ses--numcols " %S ;numcols")
1352 def)) 1455 def))
1353 oldval) 1456 oldval)
1354 (if elem 1457 (if elem
@@ -1734,29 +1837,38 @@ Does not execute cell formulas or print functions."
1734 (search-backward ";; Local Variables:\n" nil t) 1837 (search-backward ";; Local Variables:\n" nil t)
1735 (backward-list 1) 1838 (backward-list 1)
1736 (setq ses--params-marker (point-marker)) 1839 (setq ses--params-marker (point-marker))
1737 (let ((params (ignore-errors (read (current-buffer))))) 1840 (let* ((params (ignore-errors (read (current-buffer))))
1738 (or (and (= (safe-length params) 3) 1841 (params-len (safe-length params)))
1842 (or (and (>= params-len 3)
1843 (<= params-len 4)
1739 (numberp (car params)) 1844 (numberp (car params))
1740 (numberp (cadr params)) 1845 (numberp (cadr params))
1741 (>= (cadr params) 0) 1846 (>= (cadr params) 0)
1742 (numberp (nth 2 params)) 1847 (numberp (nth 2 params))
1743 (> (nth 2 params) 0)) 1848 (> (nth 2 params) 0)
1849 (or (<= params-len 3)
1850 (let ((numlocprn (nth 3 params)))
1851 (and (integerp numlocprn) (>= numlocprn 0)))))
1744 (error "Invalid SES file")) 1852 (error "Invalid SES file"))
1745 (setq ses--file-format (car params) 1853 (setq ses--file-format (car params)
1746 ses--numrows (cadr params) 1854 ses--numrows (cadr params)
1747 ses--numcols (nth 2 params)) 1855 ses--numcols (nth 2 params)
1856 ses--numlocprn (or (nth 3 params) 0))
1748 (when (= ses--file-format 1) 1857 (when (= ses--file-format 1)
1749 (let (buffer-undo-list) ; This is not undoable. 1858 (let (buffer-undo-list) ; This is not undoable.
1750 (ses-goto-data 'ses--header-row) 1859 (ses-goto-data 'ses--header-row)
1751 (insert "(ses-header-row 0)\n") 1860 (insert "(ses-header-row 0)\n")
1752 (ses-set-parameter 'ses--file-format 2) 1861 (ses-set-parameter 'ses--file-format 3)
1753 (message "Upgrading from SES-1 file format"))) 1862 (message "Upgrading from SES-1 file format")))
1754 (or (= ses--file-format 2) 1863 (or (> ses--file-format 3)
1755 (error "This file needs a newer version of the SES library code")) 1864 (error "This file needs a newer version of the SES library code"))
1756 ;; Initialize cell array. 1865 ;; Initialize cell array.
1757 (setq ses--cells (make-vector ses--numrows nil)) 1866 (setq ses--cells (make-vector ses--numrows nil))
1758 (dotimes (row ses--numrows) 1867 (dotimes (row ses--numrows)
1759 (aset ses--cells row (make-vector ses--numcols nil)))) 1868 (aset ses--cells row (make-vector ses--numcols nil)))
1869 ;; initialize local printer map.
1870 (clrhash ses--local-printer-hashmap))
1871
1760 ;; Skip over print area, which we assume is correct. 1872 ;; Skip over print area, which we assume is correct.
1761 (goto-char (point-min)) 1873 (goto-char (point-min))
1762 (forward-line ses--numrows) 1874 (forward-line ses--numrows)
@@ -1767,7 +1879,22 @@ Does not execute cell formulas or print functions."
1767 (forward-char (1- (length ses-print-data-boundary))) 1879 (forward-char (1- (length ses-print-data-boundary)))
1768 ;; Initialize printer and symbol lists. 1880 ;; Initialize printer and symbol lists.
1769 (mapc 'ses-printer-record ses-standard-printer-functions) 1881 (mapc 'ses-printer-record ses-standard-printer-functions)
1770 (setq ses--symbolic-formulas nil) 1882 (setq ses--symbolic-formulas nil)
1883
1884 ;; Load local printer definitions.
1885 ;; This must be loaded *BEFORE* cells and column printers because the latters
1886 ;; may call them.
1887 (save-excursion
1888 (forward-line (* ses--numrows (1+ ses--numcols)))
1889 (let ((numlocprn ses--numlocprn))
1890 (setq ses--numlocprn 0)
1891 (dotimes (lp numlocprn)
1892 (let ((x (read (current-buffer))))
1893 (or (and (looking-at-p "\n")
1894 (eq (car-safe x) 'ses-local-printer)
1895 (eval x))
1896 (error "local printer-def error"))
1897 (setq ses--numlocprn (1+ ses--numlocprn))))))
1771 ;; Load cell definitions. 1898 ;; Load cell definitions.
1772 (dotimes (row ses--numrows) 1899 (dotimes (row ses--numrows)
1773 (dotimes (col ses--numcols) 1900 (dotimes (col ses--numcols)
@@ -1780,6 +1907,8 @@ Does not execute cell formulas or print functions."
1780 (eval x))) 1907 (eval x)))
1781 (or (looking-at-p "\n\n") 1908 (or (looking-at-p "\n\n")
1782 (error "Missing blank line between rows"))) 1909 (error "Missing blank line between rows")))
1910 ;; Skip local printer function declaration --- that were already loaded.
1911 (forward-line (+ 2 ses--numlocprn))
1783 ;; Load global parameters. 1912 ;; Load global parameters.
1784 (let ((widths (read (current-buffer))) 1913 (let ((widths (read (current-buffer)))
1785 (n1 (char-after (point))) 1914 (n1 (char-after (point)))
@@ -1804,8 +1933,7 @@ Does not execute cell formulas or print functions."
1804 (1value (eval head-row))) 1933 (1value (eval head-row)))
1805 ;; Should be back at global-params. 1934 ;; Should be back at global-params.
1806 (forward-char 1) 1935 (forward-char 1)
1807 (or (looking-at-p (replace-regexp-in-string "1" "[0-9]+" 1936 (or (looking-at-p ses-initial-global-parameters-re)
1808 ses-initial-global-parameters))
1809 (error "Problem with column-defs or global-params")) 1937 (error "Problem with column-defs or global-params"))
1810 ;; Check for overall newline count in definitions area. 1938 ;; Check for overall newline count in definitions area.
1811 (forward-line 3) 1939 (forward-line 3)
@@ -2389,8 +2517,10 @@ cells."
2389;;---------------------------------------------------------------------------- 2517;;----------------------------------------------------------------------------
2390 2518
2391(defun ses-read-printer (prompt default) 2519(defun ses-read-printer (prompt default)
2392 "Common code for `ses-read-cell-printer', `ses-read-column-printer', and `ses-read-default-printer'. 2520 "Common code for functions `ses-read-cell-printer', `ses-read-column-printer',
2393PROMPT should end with \": \". Result is t if operation was canceled." 2521`ses-read-default-printer' and `ses-define-local-printer'.
2522PROMPT should end with \": \". Result is t if operation was
2523canceled."
2394 (barf-if-buffer-read-only) 2524 (barf-if-buffer-read-only)
2395 (if (eq default t) 2525 (if (eq default t)
2396 (setq default "") 2526 (setq default "")
@@ -2410,6 +2540,7 @@ PROMPT should end with \": \". Result is t if operation was canceled."
2410 (or (not new) 2540 (or (not new)
2411 (stringp new) 2541 (stringp new)
2412 (stringp (car-safe new)) 2542 (stringp (car-safe new))
2543 (and (symbolp new) (gethash new ses--local-printer-hashmap))
2413 (ses-warn-unsafe new 'unsafep-function) 2544 (ses-warn-unsafe new 'unsafep-function)
2414 (setq new t))) 2545 (setq new t)))
2415 new)) 2546 new))
@@ -3343,6 +3474,71 @@ highlighted range in the spreadsheet."
3343 (symbol-name new-name))) 3474 (symbol-name new-name)))
3344 (force-mode-line-update))) 3475 (force-mode-line-update)))
3345 3476
3477(defun ses-refresh-local-printer (name compiled-value)
3478 "Refresh printout of spreadsheet for all cells with printer
3479 defined to local printer named NAME using the value COMPILED-VALUE for this printer"
3480 (message "Refreshing cells using printer %S" name)
3481 (let (new-print)
3482 (dotimes (row ses--numrows)
3483 (dotimes (col ses--numcols)
3484 (let ((cell-printer (ses-cell-printer row col)))
3485 (when (eq cell-printer name)
3486 (unless new-print
3487 (setq new-print t)
3488 (ses-begin-change))
3489 (ses-print-cell row col)))))))
3490
3491(defun ses-define-local-printer (printer-name)
3492 "Define a local printer with name PRINTER-NAME."
3493 (interactive "*SEnter printer name: ")
3494 (let* ((cur-printer (gethash printer-name ses--local-printer-hashmap))
3495 (default (and (vectorp cur-printer) (ses-locprn-get-def cur-printer)))
3496 printer-def-text
3497 create-printer
3498 (new-printer (ses-read-printer (format "Enter definition of printer %S: " printer-name) default)))
3499 (cond
3500 ;; cancelled operation => do nothing
3501 ((eq new-printer t))
3502 ;; no change => do nothing
3503 ((and (vectorp cur-printer) (equal new-printer default)))
3504 ;; re-defined printer
3505 ((vectorp cur-printer)
3506 (setq create-printer 0)
3507 (ses-locprn-def-aset cur-printer new-printer)
3508 (ses-refresh-local-printer
3509 printer-name
3510 (ses-locprn-compiled-aset cur-printer (ses-local-printer-compile new-printer))))
3511 ;; new definition
3512 (t
3513 (setq create-printer 1)
3514 (puthash printer-name
3515 (setq cur-printer
3516 (ses-make-local-printer-info new-printer))
3517 ses--local-printer-hashmap)))
3518 (when create-printer
3519 (setq printer-def-text
3520 (concat
3521 "(ses-local-printer "
3522 (symbol-name printer-name)
3523 " "
3524 (prin1-to-string (ses-locprn-get-def cur-printer))
3525 ")"))
3526 (save-excursion
3527 (ses-goto-data ses--numrows
3528 (ses-locprn-get-number cur-printer))
3529 (let ((inhibit-read-only t))
3530 ;; Special undo since it's outside the narrowed buffer.
3531 (let (buffer-undo-list)
3532 (if (= create-printer 0)
3533 (delete-region (point) (line-end-position))
3534 (insert ?\n)
3535 (backward-char))
3536 (insert printer-def-text)
3537 (when (= create-printer 1)
3538 (ses-file-format-extend-paramter-list 3)
3539 (ses-set-parameter 'ses--numlocprn (+ ses--numlocprn create-printer))) ))))) )
3540
3541
3346;;---------------------------------------------------------------------------- 3542;;----------------------------------------------------------------------------
3347;; Checking formulas for safety 3543;; Checking formulas for safety
3348;;---------------------------------------------------------------------------- 3544;;----------------------------------------------------------------------------
@@ -3352,6 +3548,7 @@ highlighted range in the spreadsheet."
3352 (if (or (stringp printer) 3548 (if (or (stringp printer)
3353 (stringp (car-safe printer)) 3549 (stringp (car-safe printer))
3354 (not printer) 3550 (not printer)
3551 (and (symbolp printer) (gethash printer ses--local-printer-hashmap))
3355 (ses-warn-unsafe printer 'unsafep-function)) 3552 (ses-warn-unsafe printer 'unsafep-function))
3356 printer 3553 printer
3357 'ses-unsafe)) 3554 'ses-unsafe))