[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/fontaine 00a8b41a67: Accept common fallback values for
From: |
ELPA Syncer |
Subject: |
[elpa] externals/fontaine 00a8b41a67: Accept common fallback values for fontaine-presets |
Date: |
Mon, 9 May 2022 01:57:34 -0400 (EDT) |
branch: externals/fontaine
commit 00a8b41a67601a5eb4edc74a154e7e4a8d9eae69
Author: Protesilaos Stavrou <info@protesilaos.com>
Commit: Protesilaos Stavrou <info@protesilaos.com>
Accept common fallback values for fontaine-presets
Update the documentation to reflect all the user-facing changes.
Thanks to Ted Reed for proposing this idea and testing my prototype in
fontaine's official mailing list:
<https://lists.sr.ht/~protesilaos/fontaine/%3C87y1zcmo67.fsf@zenithia.net%3E>.
---
README.org | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fontaine.el | 131 +++++++++++++++++++--------------
2 files changed, 318 insertions(+), 53 deletions(-)
diff --git a/README.org b/README.org
index aae05ec1f3..6164cbab97 100644
--- a/README.org
+++ b/README.org
@@ -101,6 +101,8 @@ The doc string of ~fontaine-presets~ explains all
properties in detail
and documents some important caveats or information about font settings
in Emacs.
+[[#h:35bc7f51-6368-4718-ad25-b276a1f2cc08][Shared and implicit fallback values
for presets]].
+
#+findex: fontaine-set-preset
The command ~fontaine-set-preset~ applies the desired preset. If there
is only one available, it implements it outright. Otherwise it produces
@@ -165,6 +167,242 @@ which, in turn, is what the font or source is. However,
I will not
blame you if you can only interpret it as a descriptive acronym: FONTs
Are Irrelevant in Non-graphical Emacs (because that is actually true).
+** Shared and implicit fallback values for presets
+:PROPERTIES:
+:CUSTOM_ID: h:35bc7f51-6368-4718-ad25-b276a1f2cc08
+:END:
+#+cindex: Concise fontaine-presets
+
+The user option ~fontaine-presets~ may look like this (its default
+value):
+
+#+begin_src emacs-lisp
+(setq fontaine-presets
+ '((regular
+ :default-family "Hack"
+ :default-weight normal
+ :default-height 100
+ :fixed-pitch-family "Fira Code"
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "Noto Sans"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.0
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family "Source Code Pro"
+ :italic-slant italic
+ :line-spacing 1)
+ (large
+ :default-family "Iosevka"
+ :default-weight normal
+ :default-height 150
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family nil ; use whatever the underlying face has
+ :italic-slant italic
+ :line-spacing 1)))
+#+end_src
+
+Notice that not all properties need to be specified, as they have
+reasonable fallback values. The above can be written thus (removed
+lines are left empty for didactic purposes):
+
+#+begin_src emacs-lisp
+(setq fontaine-presets
+ '((regular
+ :default-family "Hack"
+
+ :default-height 100
+ :fixed-pitch-family "Fira Code"
+
+
+ :variable-pitch-family "Noto Sans"
+
+
+
+
+ :italic-family "Source Code Pro"
+
+ :line-spacing 1)
+ (large
+ :default-family "Iosevka"
+
+ :default-height 150
+
+
+
+ :variable-pitch-family "FiraGO"
+
+
+
+
+
+
+ :line-spacing 1)))
+#+end_src
+
+Without the empty lines, we have this, which yields the same results as
+the first example:
+
+#+begin_src emacs-lisp
+(setq fontaine-presets
+ '((regular
+ :default-family "Hack"
+ :default-height 100
+ :fixed-pitch-family "Fira Code"
+ :variable-pitch-family "Noto Sans"
+ :italic-family "Source Code Pro"
+ :line-spacing 1)
+ (large
+ :default-family "Iosevka"
+ :default-height 150
+ :variable-pitch-family "FiraGO"
+ :line-spacing 1)))
+#+end_src
+
+We call the properties of the removed lines "implicit fallback values".
+
+This already shows us that the value of ~fontaine-presets~ does not need
+to be extensive. To further improve its conciseness, it accepts a
+special preset that provides a list of "shared fallback properties": the
+=t= preset. This one is used to define properties that are common to
+multiple presets, such as the =regular= and =large= we have illustrated
+thus far. Here is how verbose presets can be expressed succinctly:
+
+#+begin_src emacs-lisp
+;; Notice the duplication of properties and how we will avoid it.
+(setq fontaine-presets
+ '((regular
+ :default-family "Iosevka Comfy"
+ :default-weight normal
+ :default-height 100
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family nil
+ :italic-slant italic
+ :line-spacing nil)
+ (medium
+ :default-family "Iosevka Comfy"
+ :default-weight semilight
+ :default-height 140
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family nil
+ :italic-slant italic
+ :line-spacing nil)
+ (large
+ :default-family "Iosevka Comfy"
+ :default-weight semilight
+ :default-height 180
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight extrabold
+ :italic-family nil
+ :italic-slant italic
+ :line-spacing nil)))
+
+(setq fontaine-presets
+ '((regular
+ :default-height 100)
+ (medium
+ :default-weight semilight
+ :default-height 140)
+ (large
+ :default-weight semilight
+ :default-height 180
+ :bold-weight extrabold)
+ (t ; our shared fallback properties
+ :default-family "Iosevka Comfy"
+ :default-weight normal
+ ;; :default-height 100
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family nil
+ :italic-slant italic
+ :line-spacing nil)))
+#+end_src
+
+The =t= preset does not need to explicitly cover all properties. It can
+rely on the aforementioned "implicit fallback values" to further reduce
+its verbosity (though the user can always write all properties if they
+intend to change their values). We then have this transformation:
+
+#+begin_src emacs-lisp
+;; The verbose form
+(setq fontaine-presets
+ '((regular
+ :default-height 100)
+ (medium
+ :default-weight semilight
+ :default-height 140)
+ (large
+ :default-weight semilight
+ :default-height 180
+ :bold-weight extrabold)
+ (t ; our shared fallback properties
+ :default-family "Iosevka Comfy"
+ :default-weight normal
+ ;; :default-height 100
+ :fixed-pitch-family nil ; falls back to :default-family
+ :fixed-pitch-weight nil ; falls back to :default-weight
+ :fixed-pitch-height 1.0
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-weight normal
+ :variable-pitch-height 1.05
+ :bold-family nil ; use whatever the underlying face has
+ :bold-weight bold
+ :italic-family nil
+ :italic-slant italic
+ :line-spacing nil)))
+
+;; The concise one which relies on "implicit fallback values"
+(setq fontaine-presets
+ '((regular
+ :default-height 100)
+ (medium
+ :default-weight semilight
+ :default-height 140)
+ (large
+ :default-weight semilight
+ :default-height 180
+ :bold-weight extrabold)
+ (t ; our shared fallback properties
+ :default-family "Iosevka Comfy"
+ :default-weight normal
+ :variable-pitch-family "FiraGO"
+ :variable-pitch-height 1.05)))
+#+end_src
+
* Installation
:PROPERTIES:
:CUSTOM_ID: h:031b9bea-d42b-4be0-82c7-42712cde94cc
@@ -286,6 +524,8 @@ Fontaine is meant to be a collective effort. Every bit of
help matters.
+ Contributions to the code or manual :: Christopher League, Eli Zaretskii.
++ Ideas and user feedback :: Ted Reed.
+
* GNU Free Documentation License
:PROPERTIES:
:APPENDIX: t
diff --git a/fontaine.el b/fontaine.el
index 8533587273..7a9f24c92f 100644
--- a/fontaine.el
+++ b/fontaine.el
@@ -170,6 +170,12 @@
The car of each cell is an arbitrary symbol that identifies
and/or describes the set of properties (e.g. 'small', 'reading').
+A preset whose car is t is treated as the default option. This
+makes it easier to specify multiple presets without duplicating
+their properties. The other presets beside t act as overrides of
+the defaults and, as such, need only consist of the properties
+that change from the default.
+
The cdr is a plist that specifies the typographic properties of
the faces `default', `fixed-pitch', `variable-pitch', `bold', and
`italic'. It also covers the `line-spacing' variable.
@@ -216,6 +222,9 @@ The properties in detail:
Use the desired preset with the command `fontaine-set-preset'.
+For detailed configuration: Info node `(fontaine) Shared and
+implicit fallback values for presets'.
+
Caveats or further notes:
- On a Windows system, setting a `default' weight other than
@@ -265,7 +274,8 @@ Caveats or further notes:
(const reverse-oblique)))
((const :tag "Line spacing" :line-spacing) ,(get
'line-spacing 'custom-type))))
- :key-type symbol))
+ :key-type symbol)
+ :link '(info-link "(fontaine) Shared and implicit fallback values for
presets"))
(defcustom fontaine-latest-state-file
(locate-user-emacs-file "fontaine-latest-state.eld")
@@ -352,63 +362,78 @@ combine the other two lists."
;;;; Apply preset configurations
-(defun fontaine--apply-default-preset (preset &optional frame)
- "Set `default' face attributes based on PRESET for optional FRAME."
- (if-let ((properties (alist-get preset fontaine-presets)))
- (progn
- (fontaine--set-face-attributes
- 'default
- (plist-get properties :default-family)
- (plist-get properties :default-weight)
- (plist-get properties :default-height)
- frame)
- (setq-default line-spacing (plist-get properties :line-spacing)))
- (user-error "%s is not in `fontaine-presets'" preset)))
-
-(defun fontaine--apply-fixed-pitch-preset (preset &optional frame)
- "Set `fixed-pitch' face attributes based on PRESET for optional FRAME."
- (if-let ((properties (alist-get preset fontaine-presets)))
- (fontaine--set-face-attributes
- 'fixed-pitch
- (or (plist-get properties :fixed-pitch-family) (plist-get properties
:default-family))
- (or (plist-get properties :fixed-pitch-weight) (plist-get properties
:default-weight))
- (or (plist-get properties :fixed-pitch-height) 1.0)
- frame)
- (user-error "%s is not in `fontaine-presets'" preset)))
-
-(defun fontaine--apply-variable-pitch-preset (preset &optional frame)
- "Set `variable-pitch' face attributes based on PRESET for optional FRAME."
- (if-let ((properties (alist-get preset fontaine-presets)))
- (fontaine--set-face-attributes
- 'variable-pitch
- (or (plist-get properties :variable-pitch-family) (plist-get properties
:default-family))
- (or (plist-get properties :variable-pitch-weight) (plist-get properties
:default-weight))
- (or (plist-get properties :variable-pitch-height) 1.0)
- frame)
- (user-error "%s is not in `fontaine-presets'" preset)))
-
-(defun fontaine--apply-bold-preset (preset &optional frame)
+(defmacro fontaine--apply-preset (fn doc args)
+ "Produce function to apply preset.
+FN is the symbol of the function, DOC is its documentation, and
+ARGS are its routines."
+ `(defun ,fn (preset &optional frame)
+ ,doc
+ (if-let ((properties (append (alist-get preset fontaine-presets)
+ (alist-get t fontaine-presets))))
+ ,args
+ (user-error "%s is not in `fontaine-presets' or is empty" preset))))
+
+(fontaine--apply-preset
+ fontaine--apply-default-preset
+ "Set `default' face attributes based on PRESET for optional FRAME."
+ (progn
+ (fontaine--set-face-attributes
+ 'default
+ (plist-get properties :default-family)
+ (plist-get properties :default-weight)
+ (plist-get properties :default-height)
+ frame)
+ (setq-default line-spacing (plist-get properties :line-spacing))))
+
+(fontaine--apply-preset
+ fontaine--apply-fixed-pitch-preset
+ "Set `fixed-pitch' face attributes based on PRESET for optional FRAME."
+ (fontaine--set-face-attributes
+ 'fixed-pitch
+ (or (plist-get properties :fixed-pitch-family) (plist-get properties
:default-family))
+ (or (plist-get properties :fixed-pitch-weight) (plist-get properties
:default-weight))
+ (or (plist-get properties :fixed-pitch-height) 1.0)
+ frame))
+
+(fontaine--apply-preset
+ fontaine--apply-variable-pitch-preset
+ "Set `variable-pitch' face attributes based on PRESET for optional FRAME."
+ (fontaine--set-face-attributes
+ 'variable-pitch
+ (or (plist-get properties :variable-pitch-family) (plist-get properties
:default-family))
+ (or (plist-get properties :variable-pitch-weight) (plist-get properties
:default-weight))
+ (or (plist-get properties :variable-pitch-height) 1.0)
+ frame))
+
+(fontaine--apply-preset
+ fontaine--apply-bold-preset
"Set `bold' face attributes based on PRESET for optional FRAME."
- (if-let ((properties (alist-get preset fontaine-presets)))
- (fontaine--set-face-attributes
- 'bold
- (or (plist-get properties :bold-family) 'unspecified)
- (or (plist-get properties :bold-weight) 'bold)
- frame)
- (user-error "%s is not in `fontaine-presets'" preset)))
-
-(defun fontaine--apply-italic-preset (preset &optional frame)
+ (fontaine--set-face-attributes
+ 'bold
+ (or (plist-get properties :bold-family) 'unspecified)
+ (or (plist-get properties :bold-weight) 'bold)
+ frame))
+
+(fontaine--apply-preset
+ fontaine--apply-italic-preset
"Set `italic' face attributes based on PRESET for optional FRAME."
- (if-let ((properties (alist-get preset fontaine-presets)))
- (fontaine--set-italic-slant
- (or (plist-get properties :italic-family) 'unspecified)
- (or (plist-get properties :italic-slant) 'italic)
- frame)
- (user-error "%s is not in `fontaine-presets'" preset)))
+ (fontaine--set-italic-slant
+ (or (plist-get properties :italic-family) 'unspecified)
+ (or (plist-get properties :italic-slant) 'italic)
+ frame))
(defvar fontaine--font-display-hist '()
"History of inputs for display-related font associations.")
+(defun fontaine--presets-no-fallback ()
+ "Return list of `fontaine-presets', minus the fallback value."
+ (delete
+ nil
+ (mapcar (lambda (symbol)
+ (unless (eq (car symbol) t)
+ symbol))
+ fontaine-presets)))
+
(defun fontaine--set-fonts-prompt ()
"Prompt for font set (used by `fontaine-set-fonts')."
(let* ((def (nth 1 fontaine--font-display-hist))
@@ -418,7 +443,7 @@ combine the other two lists."
(intern
(completing-read
prompt
- fontaine-presets
+ (fontaine--presets-no-fallback)
nil t nil 'fontaine--font-display-hist def))))
(defvar fontaine-set-preset-hook nil
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/fontaine 00a8b41a67: Accept common fallback values for fontaine-presets,
ELPA Syncer <=