From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: dalanicolai Newsgroups: gmane.emacs.devel Subject: Re: new package: sketch-mode Date: Wed, 15 Sep 2021 17:42:06 +0200 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000109b8405cc0a8bed" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="23435"; mail-complaints-to="usenet@ciao.gmane.io" Cc: larsi@gnus.org, Emacs Devel To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Sep 15 17:44:01 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mQX4q-0005ri-VX for ged-emacs-devel@m.gmane-mx.org; Wed, 15 Sep 2021 17:44:01 +0200 Original-Received: from localhost ([::1]:33688 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mQX4q-0006mJ-0v for ged-emacs-devel@m.gmane-mx.org; Wed, 15 Sep 2021 11:44:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46748) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mQX3H-0004al-3L for emacs-devel@gnu.org; Wed, 15 Sep 2021 11:42:23 -0400 Original-Received: from mail-yb1-xb2f.google.com ([2607:f8b0:4864:20::b2f]:34466) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mQX3E-000509-5C for emacs-devel@gnu.org; Wed, 15 Sep 2021 11:42:22 -0400 Original-Received: by mail-yb1-xb2f.google.com with SMTP id a93so6656194ybi.1 for ; Wed, 15 Sep 2021 08:42:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=gxCQqFggavCtSKkw7iR+uZpe4CECjOxs5T0zEBrb6to=; b=EWDGVeCgWdNi9S8r0oQBaWlmJSm8fngBGTsgv1o3Ieb5q4HK+5SweWt3ROiNJpkIqa awvgdSE7rsi+t8SoVjbz8N1X/uZ554EirNfs08nxnitFpO2N9RpXdVAARaC6750aCGgE 5qdtE6hslcPT6iwxkOs2fcqjIkBMK/eo1EDNzI1tYnkCN5JVOzeDl1UP2NYnqVRMYPzX 6d6fjwVo+vwwi3gkZwTHbpN2+zPL79+IoJD4RQnYh0KmMf5zRid41lEAPRCdz3Tc7Aw3 Z94237sad4IbkKuyOhvdUp/KKh42OBJC6V49ZztkNmJQcTKDxp6FODmUcG4QKiCpGliO 7tyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=gxCQqFggavCtSKkw7iR+uZpe4CECjOxs5T0zEBrb6to=; b=bv15QVPVq5tRiS+DyRD94rjWoL3sFs/vpASeMolLNk3vG5LddqyWxVB6+5cQOJim1V 4iu+b5x8NZaozr3UCony99AQYwuVxmQwktJxUhxJTdPTAtGwFOPGUY6xfEnE4qJWBN+w qgsmurRYeI7kIfQrrBol3r14n6W3xuVQAAcKCg8lYpg2Tf7EAollI6E+KPm0LNnBCqCy 8z21+L0fKbLZTXO4Prnn+V/zGrvY9h2t9d/4VlbALfDCbqrw+uSOe4Hn87NvbkkBEC4n JKHhhy9pOckGUd970EPu+q71eWghK+4PVugfhO835ad45Q6p360VVbc/if6JkeCzJWkI 3QsA== X-Gm-Message-State: AOAM531DJ5a9B9I7bN55ulGtG//rPHLH/oigRrC9Nu0es7wErKvBmNJ5 n7ShE684OPm6zLiwbZNbuzzQmcyrEcuWYWURpyk= X-Google-Smtp-Source: ABdhPJxFGJZbsv6VYSFEckEX7VlGidoh4qLJLOfzH+8WXa0cB3uZTjsV9KI4kOGXoEFPcxoxXfvLzTfuM1mX/NAXfD0= X-Received: by 2002:a25:b941:: with SMTP id s1mr812717ybm.304.1631720538412; Wed, 15 Sep 2021 08:42:18 -0700 (PDT) In-Reply-To: Received-SPF: pass client-ip=2607:f8b0:4864:20::b2f; envelope-from=dalanicolai@gmail.com; helo=mail-yb1-xb2f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:274745 Archived-At: --000000000000109b8405cc0a8bed Content-Type: text/plain; charset="UTF-8" Hi Stefan (et al.) The paperwork is ready. Do I need to send the contract somewhere? Also thank you for the patch and the tip. I have applied the patch, and I am checking things regularly by byte-compiling the file. I am still getting some `... function` is for interactive use only warnings, but I am not sure how to best deal with that, so I better ask here (they all refer to transient suffixes) I worked a little more on the package, so that it has become again a little nicer. Of course, there are still many possibilities to improve it, but it is a nice start (e.g. would be nice to merge some canvas-mode features in it, i.e. freehand drawing and mouse selection/moving objects, then it would become a very nice(r) alternative to https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio ; just noticed that package very recently). Daniel On Tue, 31 Aug 2021 at 00:45, Stefan Monnier wrote: > > Cool! Thanks. Yeah, for sure I am happy with that. So I will fill in the > > paperform request. > > Let me know when it's done. > > > It might still take some work/time to prepare the package for ELPA > though. > > In the mean time, here's a patch which addresses some of the warnings > emitted by the byte-compiler. I strongly recommend to byte-compile your > code on a regular basis and pay attention to the warnings. > > > Stefan > > > diff --git a/.gitignore b/.gitignore > new file mode 100644 > index 0000000000..aa3ed33912 > --- /dev/null > +++ b/.gitignore > @@ -0,0 +1,3 @@ > +*.elc > +/sketch-mode-autoloads.el > +/sketch-mode-pkg.el > diff --git a/sketch-mode.el b/sketch-mode.el > index bedd344eaa..d59672f63f 100644 > --- a/sketch-mode.el > +++ b/sketch-mode.el > @@ -1,10 +1,10 @@ > ;;; sketch-mode.el --- Quickly create svg sketches using keyboard and > mouse -*- lexical-binding: t; -*- > > -;; Copyright (C) 2021 Daniel Nicolai > - > +;; Copyright (C) 2021 Free Software Foundation, Inc. > > ;; Author: D.L. Nicolai > ;; Created: 17 Jul 2021 > +;; Version: 0 > > ;; Keywords: multimedia > ;; URL: https://github.com/dalanicolai/sketch-mode > @@ -79,7 +79,7 @@ > "Default size for sketch canvas. > Cons cell with car and cdr both integers, respectively > representing the image width and image height > -(default: '(800 . 600))." > +default: (800 . 600)." > :type '(cons integer integer)) > > (defcustom sketch-show-grid t > @@ -134,7 +134,7 @@ STOPS is a list of percentage/color pairs." > (svg--def > svg > (apply > - 'dom-node > + #'dom-node > 'marker > `((id . ,id) > (viewBox . "0 0 10 10") > @@ -174,8 +174,8 @@ transient." > (expt (- (cdr end-coords) (cdr start-coords)) 2)))) > > (defun sketch--rectangle-coords (start-coords end-coords) > - (let ((base-coords (cons (apply 'min (list (car start-coords) (car > end-coords))) > - (apply 'min (list (cdr start-coords) (cdr > end-coords)))))) > + (let ((base-coords (cons (apply #'min (list (car start-coords) (car > end-coords))) > + (apply #'min (list (cdr start-coords) (cdr > end-coords)))))) > (list (car base-coords) > (cdr base-coords) > (abs (- (car end-coords) (car start-coords))) > @@ -187,12 +187,13 @@ transient." > (abs (/ (- (car end-coords) (car start-coords)) 2)) > (abs (/ (- (cdr end-coords) (cdr start-coords)) 2)))) > > +(defvar svg) ;FIXME: Use a longer name with `sketch-' prefix for dynbound > vars! > +(defvar svg-canvas) > +(defvar svg-grid) > +(defvar svg-sketch) > + > (defun sketch--create-canvas (width height &optional grid-param) > "Create canvas for drawing svg using the mouse." > - (defvar svg) > - (defvar svg-canvas) > - (defvar svg-grid) > - (defvar svg-sketch) > (insert-image > (let ((width width) > (height height)) > @@ -240,6 +241,8 @@ values" > (let ((width (if arg (car sketch-default-image-size) (read-number > "Enter width: ") )) > (height (if arg 600 (read-number "Enter height: ")))) > (switch-to-buffer (get-buffer-create "*sketch*")) > + ;; FIXME: `defvar' can't be meaningfully inside a function like > that. > + ;; FIXME: Use a `sketch-' prefix for all dynbound vars. > (defvar-local sketch-elements nil) > (defvar-local grid-param 25) > (setq grid-param (if arg 25 (read-number "Enter grid parameter > (enter 0 for no grid): "))) > @@ -304,7 +307,7 @@ values" > ((fallback :initarg :fallback :initform nil) > (default :initarg :default :initform nil))) > > -(cl-defmethod transient-infix-read ((obj sketch-variable:colors)) > +(cl-defmethod transient-infix-read ((_obj sketch-variable:colors)) > (read-color "Select color: ")) > > (cl-defmethod transient-infix-value ((obj sketch-variable:colors)) > @@ -314,19 +317,24 @@ values" > (when default > (concat (oref obj argument) (substring-no-properties default)))))) > > +;; We always call the autoloaded `color-name-to-rgb' before calling this > +;; function, so we know it's available even tho the compiler doesn't. > +(declare-function color-rgb-to-hex "color" > + (red green blue &optional digits-per-component)) > + > (cl-defmethod transient-format-value ((obj sketch-variable:colors)) > (let ((value (oref obj value)) > (default (oref obj default))) > (if value > (format "%s (%s)" > (propertize value 'face (cons 'foreground-color value)) > - (propertize (apply 'color-rgb-to-hex (color-name-to-rgb > value)) > + (propertize (apply #'color-rgb-to-hex (color-name-to-rgb > value)) > 'face 'transient-inactive-argument)) > (if (string= default "none") > (propertize "none" 'face 'transient-inactive-argument) > (format "%s (%s)" > (propertize default 'face (cons 'foreground-color > default)) > - (propertize (apply 'color-rgb-to-hex (color-name-to-rgb > default)) > + (propertize (apply #'color-rgb-to-hex (color-name-to-rgb > default)) > 'face 'transient-inactive-argument)))))) > > ;; (let* ((args (when transient-current-prefix (transient-args > 'sketch-transient))) > @@ -474,7 +482,7 @@ values" > (defun sketch-create-label () > (interactive) > (let* ((alphabet "abcdefghijklmnopqrstuvwxyz") > - (labels-list (mapcar 'string (concat alphabet (upcase > alphabet)))) > + (labels-list (mapcar #'string (concat alphabet (upcase > alphabet)))) > (labels (sketch-labels-list))) > (while (member (car labels-list) labels) > (setq labels-list (cdr labels-list))) > @@ -489,7 +497,8 @@ values" > (dolist (coord args node) > (cl-decf (alist-get coord (cadr node)) amount))) > > -(defun svg-translate (dx dy) > +;; FIXME: Use a `sketch-' prefix for all definitions. > +(defun sketch--svg-translate (dx dy) > (interactive) > (mapcar (lambda (node) > (pcase (car node) > @@ -607,7 +616,7 @@ values" > (transient-quit-one) > (switch-to-buffer-other-window buffer) > (erase-buffer) > - (pp svg-sketch (current-buffer))) > + (pp sketch (current-buffer))) > (emacs-lisp-mode)) > > (transient-define-suffix sketch-copy-definition () > @@ -621,9 +630,10 @@ values" > (interactive) > (setq svg-sketch (read (buffer-string)))) > > +(defvar sketch-undo-redo nil) > + > (transient-define-suffix sketch-undo () > (interactive) > - (defvar sketch-undo-redo nil) > (let ((sketch-reverse (nreverse svg-sketch))) > (push (pop sketch-reverse) sketch-undo-redo) > (setq svg-sketch (nreverse sketch-reverse))) > @@ -660,7 +670,7 @@ values" > ;; (if > sketch-include-end-marker > ;; "url(#arrow)" > ;; "none")))) > - (apply 'svg-text svg-sketch text :x (car coords) :y (cdr coords) > object-props)) > + (apply #'svg-text svg-sketch text :x (car coords) :y (cdr coords) > object-props)) > (sketch-redraw)) > > (transient-define-infix sketch-select-font () > @@ -702,7 +712,7 @@ values" > (setq svg-canvas (svg-create new-width new-height :stroke "gray")) > (svg-marker svg-canvas "arrow" 8 8 "black" t) > (svg-rectangle svg-canvas 0 0 new-width new-height :fill "white") > - (setf (cddr svg-sketch) (svg-translate (car start-coords) (cdr > start-coords))) > + (setf (cddr svg-sketch) (sketch--svg-translate (car start-coords) > (cdr start-coords))) > (sketch-redraw))) > > (transient-define-suffix sketch-save () > @@ -710,4 +720,4 @@ values" > (image-save)) > > (provide 'sketch-mode) > -;;; filename ends here > +;;; sketch-mode.el ends here > diff --git a/sketch-scratch.el b/sketch-scratch.el > index c9f60b21ad..6bf62552a7 100644 > --- a/sketch-scratch.el > +++ b/sketch-scratch.el > @@ -1,3 +1,7 @@ > +;;; sketch-scratch.el --- -*- lexical-binding: t; -*- > + > +;; Copyright (C) 2021 Free Software Foundation, Inc. > + > ;; (setq svg-scratch (svg-create 100 100)) > ;; (svg-rectangle svg-scratch 25 25 50 50 :id "a") > ;; (svg-line svg-scratch 25 25 75 75 :id "b" :stroke-color "black") > @@ -10,6 +14,7 @@ > (dolist (coord args node) > (cl-decf (alist-get coord (cadr node)) amount))) > > +;; FIXME: Use a `sketch-' prefix for all definitions. > (defun svg-translate (dx dy) > (interactive) > (mapcar (lambda (node) > > --000000000000109b8405cc0a8bed Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Stefan (et al.)

The p= aperwork is ready. Do I need to send the contract somewhere?

=
Also thank you for the patch and the tip. I have applied the pat= ch, and I am checking things regularly by byte-compiling the file.
I am still getting some

`... function` is for in= teractive use only

warnings, but I am not sure= how to best deal with that, so I better ask here (they all refer to transi= ent suffixes)

I worked a little more on the pa= ckage, so that it has become again a little nicer. Of course, there are sti= ll many possibilities to improve it,
but it is a nice start (e.g= . would be nice to merge some canvas-mode features in it, i.e. freehand dra= wing and mouse
selection/moving objects, then it would become a = very nice(r) alternative to

Daniel
=
On Tue= , 31 Aug 2021 at 00:45, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> Cool! Thanks. Yeah, for sure I am = happy with that. So I will fill in the
> paperform request.

Let me know when it's done.

> It might still take some work/time to prepare the package for ELPA tho= ugh.

In the mean time, here's a patch which addresses some of the warnings emitted by the byte-compiler.=C2=A0 I strongly recommend to byte-compile yo= ur
code on a regular basis and pay attention to the warnings.


=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan


diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..aa3ed33912
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.elc
+/sketch-mode-autoloads.el
+/sketch-mode-pkg.el
diff --git a/sketch-mode.el b/sketch-mode.el
index bedd344eaa..d59672f63f 100644
--- a/sketch-mode.el
+++ b/sketch-mode.el
@@ -1,10 +1,10 @@
=C2=A0;;; sketch-mode.el --- Quickly create svg sketches using keyboard and= mouse -*- lexical-binding: t; -*-

-;; Copyright (C) 2021 Daniel Nicolai
-
+;; Copyright (C) 2021=C2=A0 Free Software Foundation, Inc.

=C2=A0;; Author: D.L. Nicolai <dalanicolai@gmail.com>
=C2=A0;; Created: 17 Jul 2021
+;; Version: 0

=C2=A0;; Keywords: multimedia
=C2=A0;; URL: https://github.com/dalanicolai/sketch-mode
@@ -79,7 +79,7 @@
=C2=A0 =C2=A0"Default size for sketch canvas.
=C2=A0Cons cell with car and cdr both integers, respectively
=C2=A0representing the image width and image height
-(default: '(800 . 600))."
+default: (800 . 600)."
=C2=A0 =C2=A0:type '(cons integer integer))

=C2=A0(defcustom sketch-show-grid t
@@ -134,7 +134,7 @@ STOPS is a list of percentage/color pairs."
=C2=A0 =C2=A0(svg--def
=C2=A0 =C2=A0 svg
=C2=A0 =C2=A0 (apply
-=C2=A0 =C2=A0 'dom-node
+=C2=A0 =C2=A0 #'dom-node
=C2=A0 =C2=A0 =C2=A0'marker
=C2=A0 =C2=A0 =C2=A0`((id . ,id)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(viewBox . "0 0 10 10")
@@ -174,8 +174,8 @@ transient."
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (expt (- (cdr end-coords) (cdr st= art-coords)) 2))))

=C2=A0(defun sketch--rectangle-coords (start-coords end-coords)
-=C2=A0 (let ((base-coords (cons (apply 'min (list (car start-coords) (= car end-coords)))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(apply 'min (list (cdr start-coords) (cdr end-c= oords))))))
+=C2=A0 (let ((base-coords (cons (apply #'min (list (car start-coords) = (car end-coords)))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(apply #'min (list (cdr start-coords) (cdr end-= coords))))))
=C2=A0 =C2=A0(list (car base-coords)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cdr base-coords)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(abs (- (car end-coords) (car start-coord= s)))
@@ -187,12 +187,13 @@ transient."
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(abs (/ (- (car end-coords) (car start-co= ords)) 2))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(abs (/ (- (cdr end-coords) (cdr start-co= ords)) 2))))

+(defvar svg) ;FIXME: Use a longer name with `sketch-' prefix for dynbo= und vars!
+(defvar svg-canvas)
+(defvar svg-grid)
+(defvar svg-sketch)
+
=C2=A0(defun sketch--create-canvas (width height &optional grid-param)<= br> =C2=A0 =C2=A0"Create canvas for drawing svg using the mouse."
-=C2=A0 (defvar svg)
-=C2=A0 (defvar svg-canvas)
-=C2=A0 (defvar svg-grid)
-=C2=A0 (defvar svg-sketch)
=C2=A0 =C2=A0 =C2=A0(insert-image
=C2=A0 =C2=A0 =C2=A0 (let ((width width)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (height height))
@@ -240,6 +241,8 @@ values"
=C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((width (if arg (car sketch-default-image-s= ize) (read-number "Enter width: ") ))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(height (if arg 600 (read-n= umber "Enter height: "))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(switch-to-buffer (get-buffer-create &quo= t;*sketch*"))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: `defvar' can't be meaningful= ly inside a function like that.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; FIXME: Use a `sketch-' prefix for all d= ynbound vars.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(defvar-local sketch-elements nil)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(defvar-local grid-param 25)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq grid-param (if arg 25 (read-number = "Enter grid parameter (enter 0 for no grid): ")))
@@ -304,7 +307,7 @@ values"
=C2=A0 =C2=A0((fallback=C2=A0 =C2=A0 :initarg :fallback=C2=A0 =C2=A0 :initf= orm nil)
=C2=A0 =C2=A0 (default=C2=A0 =C2=A0 =C2=A0:initarg :default=C2=A0 =C2=A0 = =C2=A0:initform nil)))

-(cl-defmethod transient-infix-read ((obj sketch-variable:colors))
+(cl-defmethod transient-infix-read ((_obj sketch-variable:colors))
=C2=A0 =C2=A0(read-color "Select color: "))

=C2=A0(cl-defmethod transient-infix-value ((obj sketch-variable:colors)) @@ -314,19 +317,24 @@ values"
=C2=A0 =C2=A0 =C2=A0 =C2=A0(when default
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(concat (oref obj argument) (substring-no= -properties default))))))

+;; We always call the autoloaded `color-name-to-rgb' before calling th= is
+;; function, so we know it's available even tho the compiler doesn'= ;t.
+(declare-function color-rgb-to-hex "color"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (red green = blue &optional digits-per-component))
+
=C2=A0(cl-defmethod transient-format-value ((obj sketch-variable:colors)) =C2=A0 =C2=A0(let ((value (oref obj value))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(default=C2=A0 (oref obj default)))
=C2=A0 =C2=A0 =C2=A0(if value
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(format "%s (%s)"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(propertize v= alue 'face (cons 'foreground-color value))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (propertize (apply= 'color-rgb-to-hex (color-name-to-rgb value))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (propertize (apply= #'color-rgb-to-hex (color-name-to-rgb value))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'face 'transient-inactive-argument))=
=C2=A0 =C2=A0 =C2=A0 =C2=A0(if (string=3D default "none")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(propertize "none" '= face 'transient-inactive-argument)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(format "%s (%s)"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(propertize d= efault 'face (cons 'foreground-color default))
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (propertize (apply= 'color-rgb-to-hex (color-name-to-rgb default))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (propertize (apply= #'color-rgb-to-hex (color-name-to-rgb default))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'face 'transient-inactive-argument))= ))))

=C2=A0 =C2=A0;; (let* ((args (when transient-current-prefix (transient-args= 'sketch-transient)))
@@ -474,7 +482,7 @@ values"
=C2=A0(defun sketch-create-label ()
=C2=A0 =C2=A0(interactive)
=C2=A0 =C2=A0(let* ((alphabet "abcdefghijklmnopqrstuvwxyz")
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(labels-list (mapcar 'string (concat= alphabet (upcase alphabet))))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(labels-list (mapcar #'string (conca= t alphabet (upcase alphabet))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (labels (sketch-labels-list)))
=C2=A0 =C2=A0 =C2=A0(while (member (car labels-list) labels)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq labels-list (cdr labels-list)))
@@ -489,7 +497,8 @@ values"
=C2=A0 =C2=A0(dolist (coord args node)
=C2=A0 =C2=A0 =C2=A0(cl-decf (alist-get coord (cadr node)) amount)))

-(defun svg-translate (dx dy)
+;; FIXME: Use a `sketch-' prefix for all definitions.
+(defun sketch--svg-translate (dx dy)
=C2=A0 =C2=A0(interactive)
=C2=A0 =C2=A0(mapcar (lambda (node)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(pcase (car node)
@@ -607,7 +616,7 @@ values"
=C2=A0 =C2=A0 =C2=A0(transient-quit-one)
=C2=A0 =C2=A0 =C2=A0(switch-to-buffer-other-window buffer)
=C2=A0 =C2=A0 =C2=A0(erase-buffer)
-=C2=A0 =C2=A0 (pp svg-sketch (current-buffer)))
+=C2=A0 =C2=A0 (pp sketch (current-buffer)))
=C2=A0 =C2=A0 =C2=A0(emacs-lisp-mode))

=C2=A0(transient-define-suffix sketch-copy-definition ()
@@ -621,9 +630,10 @@ values"
=C2=A0 =C2=A0(interactive)
=C2=A0 =C2=A0(setq svg-sketch (read (buffer-string))))

+(defvar sketch-undo-redo nil)
+
=C2=A0(transient-define-suffix sketch-undo ()
=C2=A0 =C2=A0(interactive)
-=C2=A0 (defvar sketch-undo-redo nil)
=C2=A0 =C2=A0(let ((sketch-reverse (nreverse svg-sketch)))
=C2=A0 =C2=A0 =C2=A0(push (pop sketch-reverse) sketch-undo-redo)
=C2=A0 =C2=A0 =C2=A0(setq svg-sketch (nreverse sketch-reverse)))
@@ -660,7 +670,7 @@ values"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(if sketch-include-end-marker
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0"url(#arrow)"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0"none"))))
-=C2=A0 =C2=A0 (apply 'svg-text svg-sketch text :x (car coords) :y (cdr= coords) object-props))
+=C2=A0 =C2=A0 (apply #'svg-text svg-sketch text :x (car coords) :y (cd= r coords) object-props))
=C2=A0 =C2=A0 =C2=A0(sketch-redraw))

=C2=A0(transient-define-infix sketch-select-font ()
@@ -702,7 +712,7 @@ values"
=C2=A0 =C2=A0 =C2=A0(setq svg-canvas (svg-create new-width new-height :stro= ke "gray"))
=C2=A0 =C2=A0 =C2=A0(svg-marker svg-canvas "arrow" 8 8 "blac= k" t)
=C2=A0 =C2=A0 =C2=A0(svg-rectangle svg-canvas 0 0 new-width new-height :fil= l "white")
-=C2=A0 =C2=A0 (setf (cddr svg-sketch) (svg-translate (car start-coords) (c= dr start-coords)))
+=C2=A0 =C2=A0 (setf (cddr svg-sketch) (sketch--svg-translate (car start-co= ords) (cdr start-coords)))
=C2=A0 =C2=A0 =C2=A0(sketch-redraw)))

=C2=A0(transient-define-suffix sketch-save ()
@@ -710,4 +720,4 @@ values"
=C2=A0 =C2=A0(image-save))

=C2=A0(provide 'sketch-mode)
-;;; filename ends here
+;;; sketch-mode.el ends here
diff --git a/sketch-scratch.el b/sketch-scratch.el
index c9f60b21ad..6bf62552a7 100644
--- a/sketch-scratch.el
+++ b/sketch-scratch.el
@@ -1,3 +1,7 @@
+;;; sketch-scratch.el ---=C2=A0 =C2=A0 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021=C2=A0 Free Software Foundation, Inc.
+
=C2=A0;; (setq svg-scratch (svg-create 100 100))
=C2=A0;; (svg-rectangle svg-scratch 25 25 50 50 :id "a")
=C2=A0;; (svg-line svg-scratch 25 25 75 75 :id "b" :stroke-color = "black")
@@ -10,6 +14,7 @@
=C2=A0 =C2=A0(dolist (coord args node)
=C2=A0 =C2=A0 =C2=A0(cl-decf (alist-get coord (cadr node)) amount)))

+;; FIXME: Use a `sketch-' prefix for all definitions.
=C2=A0(defun svg-translate (dx dy)
=C2=A0 =C2=A0(interactive)
=C2=A0 =C2=A0(mapcar (lambda (node)

--000000000000109b8405cc0a8bed--