unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattiase@acm.org>
To: 45917@debbugs.gnu.org
Subject: bug#45917: [PATCH] Use big brackets in Calc in big mode
Date: Sat, 16 Jan 2021 18:10:31 +0100	[thread overview]
Message-ID: <99D62C96-8FA8-4089-BB4C-9BA65F30B7E3@acm.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 877 bytes --]

The attached patch makes Calc use big brackets in Big mode when the Unicode characters are available. This makes for prettier display which is sort of the point of using Big mode. It follows previous use of Unicode characters for square root and integral signs.

The code supports big versions of round, square and curly brackets. Big square brackets are currently only used for intervals and curly ones not at all (maybe they could be put to use for Stirling numbers of the second kind).

Matrices do not use big brackets but they probably should since it is standard mathematical notation.

As far as I can tell the only reasons for not applying this would be that it is common with fonts or terminals where this doesn't look good, or that the resulting formula isn't recognised by the embedded-mode parser (which is already the case with several other constructs).


[-- Attachment #2: 0001-Calc-use-big-Unicode-brackets-in-Big-mode-when-avail.patch --]
[-- Type: application/octet-stream, Size: 15245 bytes --]

From 01a065dfb6047e0c0db7a89f6113723a1763bd2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Sat, 16 Jan 2021 17:30:57 +0100
Subject: [PATCH] Calc: use big Unicode brackets in Big mode when available

* lisp/calc/calccomp.el (math--big-bracket-alist)
(math--big-bracket, math--comp-bracket, math--comp-round-bracket):
New.
(math-compose-expr, math-compose-log, math-compose-log10)
(math-compose-choose, math-compose-integ, math-compose-sum)
(math-compose-prod): Use big brackets when available.
---
 lisp/calc/calccomp.el | 247 +++++++++++++++++++++++++++---------------
 1 file changed, 162 insertions(+), 85 deletions(-)

diff --git a/lisp/calc/calccomp.el b/lisp/calc/calccomp.el
index 07e70cad0a..5f38ee71c7 100644
--- a/lisp/calc/calccomp.el
+++ b/lisp/calc/calccomp.el
@@ -138,19 +138,19 @@ math-compose-expr
 				      (math-format-number (nth 2 aa))))))
 		  (if (= calc-number-radix 10)
 		      c
-		    (list 'horiz "(" c
-			  (list 'subscr ")"
-				(int-to-string calc-number-radix)))))
+                    (list 'subscr (math--comp-round-bracket c)
+			  (int-to-string calc-number-radix))))
 	      (math-format-number a)))
 	(if (not (eq calc-language 'big))
 	    (math-format-number a prec)
 	  (if (memq (car-safe a) '(cplx polar))
 	      (if (math-zerop (nth 2 a))
 		  (math-compose-expr (nth 1 a) prec)
-		(list 'horiz "("
-		      (math-compose-expr (nth 1 a) 0)
-		      (if (eq (car a) 'cplx) ", " "; ")
-		      (math-compose-expr (nth 2 a) 0) ")"))
+                (math--comp-round-bracket
+		 (list 'horiz
+		       (math-compose-expr (nth 1 a) 0)
+		       (if (eq (car a) 'cplx) ", " "; ")
+		       (math-compose-expr (nth 2 a) 0))))
 	    (if (or (= calc-number-radix 10)
 		    (not (Math-realp a))
 		    (and calc-group-digits
@@ -340,12 +340,13 @@ math-compose-expr
               (funcall spfn a prec)
             (math-compose-var a)))))
      ((eq (car a) 'intv)
-      (list 'horiz
-            (if (memq (nth 1 a) '(0 1)) "(" "[")
-	    (math-compose-expr (nth 2 a) 0)
-            " .. "
-	    (math-compose-expr (nth 3 a) 0)
-            (if (memq (nth 1 a) '(0 2)) ")" "]")))
+      (math--comp-bracket
+       (if (memq (nth 1 a) '(0 1)) ?\( ?\[)
+       (if (memq (nth 1 a) '(0 2)) ?\) ?\])
+       (list 'horiz
+	     (math-compose-expr (nth 2 a) 0)
+             " .. "
+	     (math-compose-expr (nth 3 a) 0))))
      ((eq (car a) 'date)
       (if (eq (car calc-date-format) 'X)
 	  (math-format-date a)
@@ -377,7 +378,7 @@ math-compose-expr
 		    (and (eq (car-safe (nth 1 a)) 'cplx)
 			 (math-negp (nth 1 (nth 1 a)))
 			 (eq (nth 2 (nth 1 a)) 0)))
-		(list 'horiz "(" (math-compose-expr (nth 1 a) 0) ")")
+                (math--comp-round-bracket (math-compose-expr (nth 1 a) 0))
 	      (math-compose-expr (nth 1 a) 201))
 	    (let ((calc-language 'flat)
 		  (calc-number-radix 10)
@@ -444,7 +445,7 @@ math-compose-expr
 	(if (> prec (nth 2 a))
             (if (setq spfn (get calc-language 'math-big-parens))
                 (list 'horiz (car spfn) c (cdr spfn))
-              (list 'horiz "(" c ")"))
+              (math--comp-round-bracket c))
 	  c)))
      ((and (eq (car a) 'calcFunc-choriz)
 	   (not (eq calc-language 'unform))
@@ -612,7 +613,7 @@ math-compose-expr
 			   (list 'horiz "{left ( "
 				 (math-compose-expr a -1)
 				 " right )}")))
-		     (list 'horiz "(" (math-compose-expr a 0) ")"))))
+                     (math--comp-round-bracket (math-compose-expr a 0)))))
 		((and (memq calc-language '(tex latex))
 		      (memq (car a) '(/ calcFunc-choose calcFunc-evalto))
 		      (>= prec 0))
@@ -638,7 +639,7 @@ math-compose-expr
 			(rhs (math-compose-expr (nth 2 a) (nth 3 op) (eq (nth 1 op) '/))))
 		   (and (equal (car op) "^")
 			(eq (math-comp-first-char lhs) ?-)
-			(setq lhs (list 'horiz "(" lhs ")")))
+			(setq lhs (math--comp-round-bracket lhs)))
 		   (and (memq calc-language '(tex latex))
 			(or (equal (car op) "^") (equal (car op) "_"))
 			(not (and (stringp rhs) (= (length rhs) 1)))
@@ -721,7 +722,7 @@ math-compose-expr
 			   (list 'horiz "{left ( "
 				 (math-compose-expr a -1)
 				 " right )}")))
-		     (list 'horiz "(" (math-compose-expr a 0) ")"))))
+		     (math--comp-round-bracket (math-compose-expr a 0)))))
 		(t
 		 (let ((lhs (math-compose-expr (nth 1 a) (nth 2 op))))
 		 (list 'horiz
@@ -759,7 +760,7 @@ math-compose-expr
 			   (list 'horiz "{left ( "
 				 (math-compose-expr a -1)
 				 " right )}")))
-		     (list 'horiz "(" (math-compose-expr a 0) ")"))))
+		     (math--comp-round-bracket (math-compose-expr a 0)))))
 		(t
 		 (let ((rhs (math-compose-expr (nth 1 a) (nth 3 op))))
 		   (list 'horiz
@@ -966,6 +967,69 @@ math-tex-expr-is-flat
       (and (memq (car a) '(^ calcFunc-subscr))
 	   (math-tex-expr-is-flat (nth 1 a)))))
 
+;; FIXME: maybe try box drawing chars if big bracket chars are unavailable,
+;; like  ┌     ┐n
+;;       │a + b│     ┌ a + b ┐n
+;;       │-----│  or │ ----- │    ?
+;;       │  c  │     └   c   ┘
+;;       └     ┘
+;; They are more common than the chars below, but look a bit square.
+;; Rounded corners exist but are less commonly available.
+
+(defconst math--big-bracket-alist
+  '((?\( . (?⎛ ?⎝ ?⎜))
+    (?\) . (?⎞ ?⎠ ?⎟))
+    (?\[ . (?⎡ ?⎣ ?⎢))
+    (?\] . (?⎤ ?⎦ ?⎥))
+    (?\{ . (?⎧ ?⎩ ?⎪ ?⎨))
+    (?\} . (?⎫ ?⎭ ?⎪ ?⎬)))
+  "Alist mapping bracket chars to (UPPER LOWER EXTENSION MIDPIECE).
+Not all brackets have midpieces.")
+
+(defun math--big-bracket (bracket-char height baseline)
+  "Composition for BRACKET-CHAR of HEIGHT with BASELINE."
+  (if (<= height 1)
+      (char-to-string bracket-char)
+    (let ((pieces (cdr (assq bracket-char math--big-bracket-alist))))
+      (if (memq nil (mapcar #'char-displayable-p pieces))
+          (char-to-string bracket-char)
+        (let* ((upper (nth 0 pieces))
+               (lower (nth 1 pieces))
+               (extension (nth 2 pieces))
+               (midpiece (nth 3 pieces)))
+          (cons 'vleft        ; alignment doesn't matter; width is 1 char
+                (cons baseline
+                      (mapcar
+                       #'char-to-string
+                       (append
+                        (list upper)
+                        (if midpiece
+                            (let ((lower-ext (/ (- height 3) 2)))
+                              (append
+                               (make-list (- height 3 lower-ext) extension)
+                               (list midpiece)
+                               (make-list lower-ext extension)))
+                          (make-list (- height 2) extension))
+                        (list lower))))))))))
+
+(defun math--comp-bracket (left-bracket right-bracket comp)
+  "Put the composition COMP inside LEFT-BRACKET and RIGHT-BRACKET."
+  (if (eq calc-language 'big)
+      (let ((height (math-comp-height comp))
+            (baseline (1- (math-comp-ascent comp))))
+        (list 'horiz
+              (math--big-bracket left-bracket height baseline)
+              comp
+              (math--big-bracket right-bracket height baseline)))
+    (list 'horiz
+          (char-to-string left-bracket)
+          comp
+          (char-to-string right-bracket))))
+
+(defun math--comp-round-bracket (comp)
+  "Put the composition COMP inside plain brackets."
+  (math--comp-bracket ?\( ?\) comp))
+
 (put 'calcFunc-log 'math-compose-big #'math-compose-log)
 (defun math-compose-log (a _prec)
   (and (= (length a) 3)
@@ -973,18 +1037,14 @@ math-compose-log
 	     (list 'subscr "log"
 		   (let ((calc-language 'flat))
 		     (math-compose-expr (nth 2 a) 1000)))
-	     "("
-	     (math-compose-expr (nth 1 a) 1000)
-	     ")")))
+             (math--comp-round-bracket (math-compose-expr (nth 1 a) 1000)))))
 
 (put 'calcFunc-log10 'math-compose-big #'math-compose-log10)
 (defun math-compose-log10 (a _prec)
   (and (= (length a) 2)
        (list 'horiz
-	     (list 'subscr "log" "10")
-	     "("
-	     (math-compose-expr (nth 1 a) 1000)
-	     ")")))
+             (list 'subscr "log" "10")
+             (math--comp-round-bracket (math-compose-expr (nth 1 a) 1000)))))
 
 (put 'calcFunc-deriv 'math-compose-big #'math-compose-deriv)
 (put 'calcFunc-tderiv 'math-compose-big #'math-compose-deriv)
@@ -1027,12 +1087,9 @@ math-compose-sqrt
 (defun math-compose-choose (a _prec)
   (let ((a1 (math-compose-expr (nth 1 a) 0))
 	(a2 (math-compose-expr (nth 2 a) 0)))
-    (list 'horiz
-	  "("
-	  (list 'vcent
-		(math-comp-height a1)
-		a1 " " a2)
-	  ")")))
+    (math--comp-round-bracket (list 'vcent
+		                    (+ (math-comp-height a1))
+		                    a1 " " a2))))
 
 (put 'calcFunc-integ 'math-compose-big #'math-compose-integ)
 (defun math-compose-integ (a prec)
@@ -1052,9 +1109,12 @@ math-compose-integ
 						       "d%s"
 						       (nth 1 (nth 2 a)))))
 					 (nth 1 a)) 185))
-	      (calc-language 'flat)
-	      (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0)))
-	      (high (and (nth 4 a) (math-compose-expr (nth 4 a) 0)))
+	      (low (and (nth 3 a)
+	                (let ((calc-language 'flat))
+                          (math-compose-expr (nth 3 a) 0))))
+	      (high (and (nth 4 a)
+	                 (let ((calc-language 'flat))
+                           (math-compose-expr (nth 4 a) 0))))
               ;; Check if we have Unicode integral top/bottom parts.
               (fancy (and (char-displayable-p ?⌠)
                           (char-displayable-p ?⌡)))
@@ -1066,40 +1126,47 @@ math-compose-integ
                                 ((char-displayable-p ?│) "│ ")
                                 ;; U+007C VERTICAL LINE
                                 (t "| "))))
-	 (list 'horiz
-	       (if parens "(" "")
-	       (append (list 'vcent (if fancy
-                                        (if high 2 1)
-                                      (if high 3 2)))
-		       (and high (list (if fancy
-                                           (list 'horiz high " ")
-                                         (list 'horiz "  " high))))
-                       (if fancy
-                           (list "⌠ " fancy-stem "⌡ ")
-		         '("  /"
-			   " | "
-			   " | "
-			   " | "
-			   "/  "))
-		       (and low (list (if fancy
-                                          (list 'horiz low " ")
-                                        (list 'horiz low "  ")))))
-	       expr
-	       (if over
-		   ""
-		 (list 'horiz " d" var))
-	       (if parens ")" "")))))
+         (let ((comp
+	        (list 'horiz
+	              (append (list 'vcent (if fancy
+                                               (if high 2 1)
+                                             (if high 3 2)))
+		              (and high (list (if fancy
+                                                  (list 'horiz high " ")
+                                                (list 'horiz "  " high))))
+                              (if fancy
+                                  (list "⌠ " fancy-stem "⌡ ")
+		                '("  /"
+			          " | "
+			          " | "
+			          " | "
+			          "/  "))
+		              (and low (list (if fancy
+                                                 (list 'horiz low " ")
+                                               (list 'horiz low "  ")))))
+	              expr
+	              (if over
+		          ""
+		        (list 'horiz " d" var)))))
+           (if parens
+               (math--comp-round-bracket comp)
+             comp)))))
 
 (put 'calcFunc-sum 'math-compose-big #'math-compose-sum)
 (defun math-compose-sum (a prec)
   (and (memq (length a) '(3 5 6))
        (let* ((expr (math-compose-expr (nth 1 a) 185))
-	      (calc-language 'flat)
-	      (var (math-compose-expr (nth 2 a) 0))
-	      (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0)))
-	      (high (and (nth 4 a) (math-compose-vector (nthcdr 4 a) ", " 0))))
-	 (list 'horiz
-	       (if (memq prec '(180 201)) "(" "")
+	      (var
+	       (let ((calc-language 'flat))
+                 (math-compose-expr (nth 2 a) 0)))
+	      (low (and (nth 3 a)
+	                (let ((calc-language 'flat))
+                          (math-compose-expr (nth 3 a) 0))))
+	      (high (and (nth 4 a)
+	                 (let ((calc-language 'flat))
+                           (math-compose-vector (nthcdr 4 a) ", " 0))))
+              (comp
+	       (list 'horiz
 	       (append (list 'vcent (if high 3 2))
 		       (and high (list high))
 		       '("---- "
@@ -1112,32 +1179,42 @@ math-compose-sum
 			 (list var)))
 	       (if (memq (car-safe (nth 1 a)) '(calcFunc-sum calcFunc-prod))
 		   " " "")
-	       expr
-	       (if (memq prec '(180 201)) ")" "")))))
+	       expr)))
+	 (if (memq prec '(180 201))
+             (math--comp-round-bracket comp)
+           comp))))
 
 (put 'calcFunc-prod 'math-compose-big #'math-compose-prod)
 (defun math-compose-prod (a prec)
   (and (memq (length a) '(3 5 6))
        (let* ((expr (math-compose-expr (nth 1 a) 198))
-	      (calc-language 'flat)
-	      (var (math-compose-expr (nth 2 a) 0))
-	      (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0)))
-	      (high (and (nth 4 a) (math-compose-vector (nthcdr 4 a) ", " 0))))
-	 (list 'horiz
-	       (if (memq prec '(196 201)) "(" "")
-	       (append (list 'vcent (if high 3 2))
-		       (and high (list high))
-		       '("----- "
-			 " | |  "
-			 " | |  "
-			 " | |  ")
-		       (if low
-			   (list (list 'horiz var " = " low))
-			 (list var)))
-	       (if (memq (car-safe (nth 1 a)) '(calcFunc-sum calcFunc-prod))
-		   " " "")
-	       expr
-	       (if (memq prec '(196 201)) ")" "")))))
+	      (var
+               (let ((calc-language 'flat))
+                 (math-compose-expr (nth 2 a) 0)))
+	      (low (and (nth 3 a)
+                        (let ((calc-language 'flat))
+                          (math-compose-expr (nth 3 a) 0))))
+	      (high (and (nth 4 a)
+                         (let ((calc-language 'flat))
+                           (math-compose-vector (nthcdr 4 a) ", " 0))))
+              (comp
+	       (list 'horiz
+	             (append (list 'vcent (if high 3 2))
+		             (and high (list high))
+		             '("----- "
+			       " | |  "
+			       " | |  "
+			       " | |  ")
+		             (if low
+			         (list (list 'horiz var " = " low))
+			       (list var)))
+	             (if (memq (car-safe (nth 1 a))
+                               '(calcFunc-sum calcFunc-prod))
+		         " " "")
+	             expr)))
+         (if (memq prec '(196 201))
+             (math--comp-round-bracket comp)
+           comp))))
 
 ;; The variables math-svo-c, math-svo-wid and math-svo-off are local
 ;; to math-stack-value-offset in calc.el, but are used by
-- 
2.21.1 (Apple Git-122.3)


[-- Attachment #3: Type: text/plain, Size: 2 bytes --]




             reply	other threads:[~2021-01-16 17:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-16 17:10 Mattias Engdegård [this message]
2021-01-19  5:37 ` bug#45917: [PATCH] Use big brackets in Calc in big mode Lars Ingebrigtsen
2021-01-19 10:12   ` Mattias Engdegård
2021-01-19 15:45     ` Lars Ingebrigtsen
2021-01-19 17:59       ` Mattias Engdegård

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=99D62C96-8FA8-4089-BB4C-9BA65F30B7E3@acm.org \
    --to=mattiase@acm.org \
    --cc=45917@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).