Add denote-slug-remove-accents function

This is based on the code originally written by Jean-Philippe Gagné
Guay in issue 603: <https://github.com/protesilaos/denote/issues/603#issuecomment-2869702877>.
I made stylistic changes to it to make it fit with the rest of denote.el.

I am adding this in response to issue 603 and 718:

- <https://github.com/protesilaos/denote/issues/603> with
  participation from Davi Ramos and Jean-Philippe Gagné Guay;
- <https://github.com/protesilaos/denote/issues/718> with
  participation from o-rxw and Alan Schmitt.

In implementing this, I am changing my mind that this is purely a
documentation issue. I realised it is better for us to have the main
function in denote.el, so that we can test it better.
This commit is contained in:
Protesilaos 2026-07-27 19:51:51 +03:00
parent 1004f735b7
commit c8aa01c56a
No known key found for this signature in database
GPG key ID: 99BD6459CD5CA3EA
3 changed files with 89 additions and 7 deletions

View file

@ -2450,6 +2450,8 @@ You have been warned.
:CUSTOM_ID: h:d1e4eb5b-e7f2-4a3b-9243-e1c653817a4a
:END:
[ Also see: [[#h:65a6a2ec-02b9-4c9e-995f-19dfe0611e20][Custom sluggification to remove diacterics or accented characters]]. ]
A common use-case for Denote is to rename files such as videos
downloaded from the Internet. Sometimes, those files have Unicode
characters that (i) not all fonts support and (ii) create all sorts of
@ -2482,7 +2484,52 @@ use the following in their Emacs configuration ([[#h:d375c6d2-92c7-425f-9d9d-219
(denote-slug-keep-only-ascii str))))
(defcustom denote-file-name-slug-functions
'((title . my-denote-sluggify-title)
'((identifier . identity) ; keep the original
(title . my-denote-sluggify-title)
(signature . my-denote-sluggify-signature)
(keyword . my-denote-sluggify-keyword)))
#+end_src
*** Custom sluggification to remove diacterics or accented characters
:PROPERTIES:
:CUSTOM_ID: h:65a6a2ec-02b9-4c9e-995f-19dfe0611e20
:END:
[ Also see: [[#h:d1e4eb5b-e7f2-4a3b-9243-e1c653817a4a][Custom sluggification to remove non-ASCII characters]]. ]
For languages with diacretics, like =ê= and =ñ=, users may want to
instruct Denote to remove the diacretical marks from the underlying
characters. This way, the file names will be uniform and easier to
search through, instead of checking if, say, =être= is written thus or
as =etre=.
This is only for the sluggification of file name components ([[#h:d375c6d2-92c7-425f-9d9d-219ff47ed2a3][User-defined sluggification of file name components]]).
Any front matter will retain the diacretics.
#+begin_src emacs-lisp
;; These are the same as the default Denote sluggification functions,
;; except they remove all diacretics from the underlying characters
;; (e.g. ê becomes e while ñ becomes n).
(defun my-denote-sluggify-title (str)
(downcase
(denote-slug-hyphenate
(replace-regexp-in-string "[][{}!@#$%^&*()+'\"?,.\|;:~`‘’“”/=]*" ""
(denote-slug-remove-accents str)))))
(defun my-denote-sluggify-signature (str)
(downcase
(denote-slug-put-equals
(replace-regexp-in-string "[][{}!@#$%^&*()+'\"?,.\|;:~`‘’“”/-]*" ""
(denote-slug-remove-accents str)))))
(defun my-denote-sluggify-keyword (str)
(downcase
(replace-regexp-in-string "[][{}!@#$%^&*()+'\"?,.\|;:~`‘’“”/_ =-]*" ""
(denote-slug-remove-accents str))))
(defcustom denote-file-name-slug-functions
'((identifier . identity) ; keep the original
(title . my-denote-sluggify-title)
(signature . my-denote-sluggify-signature)
(keyword . my-denote-sluggify-keyword)))
#+end_src
@ -7165,8 +7212,8 @@ Denote is meant to be a collective effort. Every bit of help matters.
Purslane, Alfredo Borrás, Alp Eren Kose, André Bering, Ashton
Wiersdorf, Bhargav Kulkarni, Benjamin Kästner, Claudio Migliorelli,
Claudiu Tănăselia, Colin McLear, Cosmin-Octavian C, Damien Cassou,
Elias Storms, Federico Stilman, Florian, Frédéric Willem Frank
Ehmsen, Glenna D., Guo Yong, Hanspeter Gisler Harold Ollivier,
Davi Ramos, Elias Storms, Federico Stilman, Florian, Frédéric Willem
Frank Ehmsen, Glenna D., Guo Yong, Hanspeter Gisler Harold Ollivier,
IceAsteroid, Jack Baty, Jay Rajput, Jean-Charles Bagneris, Jeff
Valk, Jens Östlund, Jeremy Friesen, Jonathan Sahar, Johan Bolmsjö,
Jonas Großekathöfer, Jousimies, Juanjo Presa, Julian Hoch, Kai von
@ -7180,10 +7227,10 @@ Denote is meant to be a collective effort. Every bit of help matters.
Mealing, Wilf, Yi Liu, Ypot, 82Kang, atanasj, azegas, babusri,
bdillahu, coherentstate, doolio, duli, drcxd, elge70, elliottw,
fingerknight, GuutBoy, hpgisler, hyperfocus1337,johkneisl,
jtpavlock, juh, leafarbelm, mentalisttraceur, mjkalyan, oatmealm,
potchie-maker, Pratik-Mishra-4979, pRot0ta1p, rbenit68, relict007,
sarcom-sar, sienic, skissue, sundar bp, wuzhihao, yetanotherfossman,
zadca123
jtpavlock, juh, leafarbelm, mentalisttraceur, mjkalyan, o-rxw,
oatmealm, potchie-maker, Pratik-Mishra-4979, pRot0ta1p, rbenit68,
relict007, sarcom-sar, sienic, skissue, sundar bp, wuzhihao,
yetanotherfossman, zadca123
Special thanks to Peter Povinec who helped refine the file-naming
scheme, which is the cornerstone of this project.

View file

@ -1059,6 +1059,36 @@ This is useful as a helper function to construct
(characters (seq-filter #'characterp ascii-range)))
(mapconcat #'string characters)))
(defun denote-slug-remove-accents (str)
"Remove diacterics or accents from STR.
This means that something like ê becomes e while ñ becomes n."
;; Combining Diacritical Marks https://www.unicode.org/charts/PDF/U0300.pdf
(let* ((slug-trim-chars '(768 ; U+0300 COMBINING GRAVE ACCENT
769 ; U+0301 COMBINING ACUTE ACCENT
770 ; U+0302 COMBINING CIRCUMFLEX ACCENT
771 ; U+0303 COMBINING TILDE
772 ; U+0304 COMBINING MACRON
774 ; U+0306 COMBINING BREVE
775 ; U+0307 COMBINING DOT ABOVE
776 ; U+0308 COMBINING DIAERESIS
777 ; U+0309 COMBINING HOOK ABOVE
778 ; U+030A COMBINING RING ABOVE
779 ; U+030B COMBINING DOUBLE ACUTE ACCENT
780 ; U+030C COMBINING CARON
795 ; U+031B COMBINING HORN
803 ; U+0323 COMBINING DOT BELOW
804 ; U+0324 COMBINING DIAERESIS BELOW
805 ; U+0325 COMBINING RING BELOW
807 ; U+0327 COMBINING CEDILLA
813 ; U+032D COMBINING CIRCUMFLEX ACCENT BELOW
814 ; U+032E COMBINING BREVE BELOW
816 ; U+0330 COMBINING TILDE BELOW
817)) ; U+0331 COMBINING MACRON BELOW
(fn (lambda (char) (memq char slug-trim-chars)))
(chars (seq-remove fn (string-glyph-decompose str)))
(string (apply #'string chars)))
(string-glyph-compose string)))
(define-obsolete-function-alias
'denote--slug-hyphenate
'denote-slug-hyphenate

View file

@ -146,6 +146,11 @@ The function also account for the value of the user option
`denote-allow-multi-word-keywords'."
(should (equal (denote-sluggify-keywords '("one !@# --- one" " two" "__ three __")) '("oneone" "two" "three"))))
(ert-deftest dt-denote-slug-remove-accents ()
"Test that `denote-slug-remove-accents' removed diacretics."
(should (string= (denote-slug-remove-accents "ê") "e"))
(should (string= (denote-slug-remove-accents "ñ") "n")))
(ert-deftest dt-denote--file-empty-p ()
"Test that `denote--file-empty-p' returns non-nil on empty file."
(let ((file (make-temp-file "denote-test")))