Function: woman-parse-numeric-value

woman-parse-numeric-value is a byte-compiled function defined in woman.el.gz.

Signature

(woman-parse-numeric-value)

Documentation

Get a single numeric value at or after point.

The value can be a number register or width function (which assumes 10 characters per inch) and can include scale indicators. It may be an expression in parentheses. Leaves point after the value.

Source Code

;; Defined in /usr/src/emacs/lisp/woman.el.gz
(defun woman-parse-numeric-value ()
  "Get a single numeric value at or after point.
The value can be a number register or width function (which assumes 10
characters per inch) and can include scale indicators.  It may be an
expression in parentheses.  Leaves point after the value."
  ;; Must replace every \' by some different single character first
  ;; before calling this function by calling
  ;; (woman2-process-escapes-to-eol 'numeric)
  (if (eq (following-char) ?\()
      ;; Treat parenthesized expression as a single value.
      (let (n)
	(forward-char)
	(setq n (woman-parse-numeric-arg))
	(skip-syntax-forward " " (line-end-position))
	(if (eq (following-char) ?\))
	    (forward-char)
	  (WoMan-warn "Parenthesis confusion in numeric expression!"))
	n)
    (let ((n (cond ((looking-at "[-+]?[.0-9]+")	; single number
		    ;; currently needed to set match-end, even though
		    ;; string-to-number returns 0 if number not parsed.
		    (string-to-number (match-string 0)))
		   ((looking-at "\\\\n\\([-+]\\)?\\(?:\
\\[\\([^]]+\\)\\]\\|(\\(..\\)\\|\\(.\\)\\)")
		    ;; interpolate number register, maybe auto-incremented
		    (let* ((pm (match-string-no-properties 1))
			   (name (or (match-string-no-properties 2)
				     (match-string-no-properties 3)
				     (match-string-no-properties 4)))
			   (value (assoc name woman-registers)))
		      (if value
			  (let (inc)
			    (setq value (cdr value) ; (value . inc)
				  inc (cdr value)
				  ;; eval internal (.X) registers
				  ;; stored as lisp variable names:
				  value (eval (car value) t))
			    (if (and pm inc) ; auto-increment
				(setq value
				      (funcall (intern-soft pm) value inc)
				      woman-registers
				      (cons (cons name (cons value inc))
					    woman-registers)))
			    value)
			(WoMan-warn "Undefined register %s defaulted to 0."
				    name)
			0)		; default to zero
		      ))
		   ((re-search-forward
		     ;; Delimiter can be special char escape \[xxx],
		     ;; \(xx or single normal char (usually '):
		     "\\=\\\\w\\(\\\\\\[[^]]+\\]\\|\\\\(..\\|.\\)" nil t)
		    (let ((from (match-end 0))
			  (delim (regexp-quote (match-string 1))))
		      (if (re-search-forward delim nil t)
			  ;; Return width of string:
			  (- (match-beginning 0) from)
			(WoMan-warn "Width escape delimiter error!")))))))
      (if (null n)
	  ;; ERROR -- should handle this better!
	  (progn
	    (WoMan-warn "Numeric/register argument error: %s"
			(buffer-substring
			 (point)
			 (line-end-position)))
	    (skip-syntax-forward "^ " (line-end-position))
	    0)
	(goto-char (match-end 0))
	;; Check for scale factor:
	(if
	    (cond
	     ((looking-at "\\s ") nil)	; stay put!
	     ((looking-at "[mnuv]"))	; ignore for now
	     ((looking-at "i") (setq n (* n 10))) ; inch
	     ((looking-at "c") (setq n (* n 3.9))) ; cm
	     ((let ((case-fold-search nil))
		(looking-at "P"))
	      (setq n (* n 1.7))) ; Pica
	     ((looking-at "p") (setq n (* n 0.14))) ; point
	     ;; NB: May be immediately followed by + or -, etc.,
	     ;; in which case do nothing and return nil.
	     )
	    (goto-char (match-end 0)))
	(if (numberp n) (round n) n)))))