branch: externals/denote commit e94cc50fd4d422260102163c0ef371f30c6a6bb6 Author: Protesilaos Stavrou <i...@protesilaos.com> Commit: Protesilaos Stavrou <i...@protesilaos.com>
Make denote-file-name-slug-functions a user option; expand its documentation --- README.org | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- denote.el | 19 +++++++++-- 2 files changed, 111 insertions(+), 20 deletions(-) diff --git a/README.org b/README.org index d1fb389d46..129e995d5f 100644 --- a/README.org +++ b/README.org @@ -1707,22 +1707,42 @@ file names by default: + Spaces or other delimiters are removed from keywords, meaning that =hello-world= becomes =helloworld=. This is because hyphens in - keywords do not work everywhere, such as in Org. + keywords do not work everywhere, such as in Org. Plus, hyphens are + word separators in the title and we want to keep distinct separators + for each component to make search easier and semantic + ([[#h:1a953736-86c2-420b-b566-fb22c97df197][Features of the file-naming scheme for searching or filtering]]). + Signatures are like the above, but use the equals sign instead of - hyphens. + hyphens as a word separator. -+ All file name components are downcased. Consider a =helloWorld= or - =HelloWorld= convention for those cases where you would want to have a - hyphen between constituent words of a keyword. ++ All file name components are downcased. Further down we document how + to deviate from these rules, such as to accept input of the form + =helloWorld= or =HelloWorld= verbatim. + +Denote imposes these restrictions to enforce uniformity, which is +helpful long-term as it keeps all files with the same predictable +pattern. Too many permutations make searches more difficult to express +accurately and be confident that the matches cover all files. +Nevertheless, one of the principles of Denote is its flexibility or +hackability and so users can deviate from the aforementioned +([[#h:d375c6d2-92c7-425f-9d9d-219ff47ed2a3][User-defined sluggification of file name components]]). + +** User-defined sluggification of file name components +:PROPERTIES: +:CUSTOM_ID: h:d375c6d2-92c7-425f-9d9d-219ff47ed2a3 +:END: + +[ Part of {{{development-version}}}, superseding the deprecated user + option ~denote-file-name-letter-casing~. ] #+vindex: denote-file-name-slug-functions -The user option ~denote-file-name-slug-functions~ can be used to control -the sluggification of the components of file names ([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming -scheme]]). The default method is explained in the previous section. +The user option ~denote-file-name-slug-functions~ controls the +sluggification of file name components ([[#h:ae8b19a1-7f67-4258-96b3-370a72c43f4e][Sluggification of file name components]]). +The default method is outlined above and in the previous section +([[#h:4e9c7512-84dc-4dfb-9fa9-e15d51178e5d][The file-naming scheme]]). The value of this user option is an alist where each element is a cons -cell of the form =(COMPONENT . METHOD)=. For example, here is the +cell of the form =(COMPONENT . METHOD)=. For example, here is the default value: #+begin_example emacs-lisp @@ -1731,19 +1751,75 @@ default value: (keyword . denote-sluggify-keyword)) #+end_example -What these cons cells of =(COMPONENT . METHOD)= are: - - The =COMPONENT= is an unquoted symbol among =title=, =signature=, =keyword=, which refers to the corresponding component of the file name. -- The =METHOD= is the function to be used to format the given component. - This function should take a string as its parameter and return the - string formatted for the file name. In the case of the `keyword' - component, the function receives a SINGLE string representing a single - keyword and return it formatted for the file name. Joining the - keywords together is handled by Denote. Note that the `keyword' - function is also applied to the keywords of the front matter. +- The =METHOD= is a function to format the given component. This + function must take a string as its parameter and return the string + formatted for the file name. Note that even in the case of the + =keyword= component, the function receives one string representing a + single keyword and returns it formatted for the file name. Joining + the keywords together is handled internally by Denote. + +One commonly requested deviation from the sluggification rules is to +not sluggify individual keywords, such that the user's input is taken +as-is. This can be done as follows: + +#+begin_src emacs-lisp +(setq denote-file-name-slug-functions + '((title . denote-sluggify-title) + (keyword . identity) + (signature . denote-sluggify-signature))) +#+end_src + +The ~identity~ function simply returns the string it receives, thus +not altering it in any way. + +Another approach is to keep the sluggification but not downcase the +string. We can do this by modifying the original functions used by +Denote. For example, we have this: + +#+begin_src emacs-lisp +;; The original function for reference +(defun denote-sluggify-title (str) + "Make STR an appropriate slug for title." + (downcase (denote--slug-hyphenate (denote--slug-no-punct str)))) + +;; Our variant of the above, which does the same thing except from +;; downcasing the string. +(defun my-denote-sluggify-title (str) + "Make STR an appropriate slug for title." + (denote--slug-hyphenate (denote--slug-no-punct str))) + +;; Now we use our function to sluggify titles without affecting their +;; letter casing. +(setq denote-file-name-slug-functions + '((title . my-denote-sluggify-title) ; our function here + (signature . denote-sluggify-signature) + (keyword . denote-sluggify-keyword))) +#+end_src + +Follow this principle for all the sluggification functions. + +To access the source code, use either of the following built-in +methods: + +1. Call the command ~find-library~ and search for ~denote~. Then + navigate to the symbol you are searching for. + +2. Invoke the command ~describe-symbol~, search for the symbol you are + interested in, and from the resulting Help buffer either click on + the first link or do =M-x help-view-source= (bound to =s= in Help + buffers, by default). + +Remember that deviating from the default file-naming scheme of Denote +will make things harder to search in the future, as files can/will +have permutations that create uncertainty. The sluggification scheme +and concomitant restrictions we impose by default are there for a very +good reason: they are the distillation of years of experience. Here we +give you what you wish, but bear in mind it may not be what you need. +You have been warned. ** Features of the file-naming scheme for searching or filtering :PROPERTIES: diff --git a/denote.el b/denote.el index 0498812792..329e288664 100644 --- a/denote.el +++ b/denote.el @@ -623,7 +623,7 @@ and `denote-link-after-creating-with-command'." :link '(info-link "(denote) Choose which commands to prompt for") :type '(repeat symbol)) -(defvar denote-file-name-slug-functions +(defcustom denote-file-name-slug-functions '((title . denote-sluggify-title) (signature . denote-sluggify-signature) (keyword . denote-sluggify-keyword)) @@ -649,7 +649,22 @@ of the front matter. By default, if a function is not specified for a component, we use `denote-sluggify-title', `denote-sluggify-keyword' and -`denote-sluggify-signature'.") +`denote-sluggify-signature'. + +Remember that deviating from the default file-naming scheme of Denote +will make things harder to search in the future, as files can/will have +permutations that create uncertainty. The sluggification scheme and +concomitant restrictions we impose by default are there for a very good +reason: they are the distillation of years of experience. Here we give +you what you wish, but bear in mind it may not be what you need. You +have been warned." + :group 'denote + :package-version '(denote . "2.3.0") + :link '(info-link "(denote) User-defined sluggification of file name components") + :type '(alist :key (choice (const title) + (const signature) + (const keyword)) + :value function)) (make-obsolete 'denote-file-name-letter-casing