Add gist on using rx inside lisp-data
This commit is contained in:
parent
fd3d099105
commit
0dfe23c528
2 changed files with 83 additions and 0 deletions
44
gists.org
44
gists.org
|
@ -1140,6 +1140,50 @@ Which covers my (potential) GPG/SSH usage within Emacs. Now, anytime a I perform
|
||||||
(run-with-timer nil (* 2 60 60) (lambda () (run-with-idle-timer 120 nil 'elfeed-update))))
|
(run-with-timer nil (* 2 60 60) (lambda () (run-with-idle-timer 120 nil 'elfeed-update))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
* Use rx style regular expressions in Lisp data files
|
||||||
|
|
||||||
|
#+begin_src org :noweb no :tangle gists/rx-in-lisp-data.org
|
||||||
|
Plain regular expressions are difficult to write and sometimes difficult to read, therefore I prefer constructing regular expressions with the =rx= macro. It will take care of the special characters and the proper escaping, as I can't remember those details that well. With =rx=, you construct regular expressions in a Lisp format, e.g.:
|
||||||
|
|
||||||
|
,#+begin_src elisp
|
||||||
|
(rx string-start (or "foo" "bar") string-end)
|
||||||
|
,#+end_src
|
||||||
|
|
||||||
|
,#+RESULTS:
|
||||||
|
: \`\(?:bar\|foo\)\'
|
||||||
|
|
||||||
|
It's not only more readable (in my opinion), but it's also easier to construct with all the Lisp writing tools that can be used within Emacs (e.g. paredit or puni).
|
||||||
|
|
||||||
|
However, using =rx= is not always possible. Lisp data files may contain regular expressions but they are treated as data and not as executable code.
|
||||||
|
|
||||||
|
One prime example is elfeed-score: an Emacs package that allows you to write scoring rules for elfeed entries. Scoring rules are defined with an Lisp data file, and a rule may allow regular expressions but they have to be written out verbatim.
|
||||||
|
|
||||||
|
Luckily there's a work-around with Org Mode:
|
||||||
|
|
||||||
|
- Write the scoring rules in an =lisp-data= source block.
|
||||||
|
- Tangle the file to a location that is read by the elfeed-score package (see variable ~elfeed-score-score-file~).
|
||||||
|
- For the regular expression we use a small =elisp= block as follows:
|
||||||
|
|
||||||
|
,#+begin_src org
|
||||||
|
,,#+name: rx
|
||||||
|
,,#+begin_src elisp :var expression='any :tangle=no
|
||||||
|
(string-replace "\\" "\\\\" (format "\"%s\"" (rx-to-string expression)))
|
||||||
|
,,#+end_src
|
||||||
|
,#+end_src
|
||||||
|
|
||||||
|
It accepts an /expression/ that is a Lisp form that =rx= accepts. It is converted to a string, surrounded by quotes and since we use it in a Lisp string, backslashes should be doubled.
|
||||||
|
|
||||||
|
- By naming the source block =rx= we can call it from other source blocks:
|
||||||
|
|
||||||
|
,#+begin_src org
|
||||||
|
,,#+begin_src lisp-data :tangle elfeed-scores.eld :noweb yes
|
||||||
|
(("title" (:text <<rx '(or "foo" "bar")>> :value 1 :type r)))
|
||||||
|
,,#+end_src
|
||||||
|
,#+end_src
|
||||||
|
|
||||||
|
Upon tangling, the <<rx ...>> is converted to a regex string and therefore readable by elfeed-score.
|
||||||
|
#+end_src
|
||||||
|
|
||||||
* Meta
|
* Meta
|
||||||
** License
|
** License
|
||||||
|
|
||||||
|
|
39
gists/rx-in-lisp-data.org
Normal file
39
gists/rx-in-lisp-data.org
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Plain regular expressions are difficult to write and sometimes difficult to read, therefore I prefer constructing regular expressions with the =rx= macro. It will take care of the special characters and the proper escaping, as I can't remember those details that well. With =rx=, you construct regular expressions in a Lisp format, e.g.:
|
||||||
|
|
||||||
|
#+begin_src elisp
|
||||||
|
(rx string-start (or "foo" "bar") string-end)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: \`\(?:bar\|foo\)\'
|
||||||
|
|
||||||
|
It's not only more readable (in my opinion), but it's also easier to construct with all the Lisp writing tools that can be used within Emacs (e.g. paredit or puni).
|
||||||
|
|
||||||
|
However, using =rx= is not always possible. Lisp data files may contain regular expressions but they are treated as data and not as executable code.
|
||||||
|
|
||||||
|
One prime example is elfeed-score: an Emacs package that allows you to write scoring rules for elfeed entries. Scoring rules are defined with an Lisp data file, and a rule may allow regular expressions but they have to be written out verbatim.
|
||||||
|
|
||||||
|
Luckily there's a work-around with Org Mode:
|
||||||
|
|
||||||
|
- Write the scoring rules in an =lisp-data= source block.
|
||||||
|
- Tangle the file to a location that is read by the elfeed-score package (see variable ~elfeed-score-score-file~).
|
||||||
|
- For the regular expression we use a small =elisp= block as follows:
|
||||||
|
|
||||||
|
#+begin_src org
|
||||||
|
,#+name: rx
|
||||||
|
,#+begin_src elisp :var expression='any :tangle=no
|
||||||
|
(string-replace "\\" "\\\\" (format "\"%s\"" (rx-to-string expression)))
|
||||||
|
,#+end_src
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
It accepts an /expression/ that is a Lisp form that =rx= accepts. It is converted to a string, surrounded by quotes and since we use it in a Lisp string, backslashes should be doubled.
|
||||||
|
|
||||||
|
- By naming the source block =rx= we can call it from other source blocks:
|
||||||
|
|
||||||
|
#+begin_src org
|
||||||
|
,#+begin_src lisp-data :tangle elfeed-scores.eld :noweb yes
|
||||||
|
(("title" (:text <<rx '(or "foo" "bar")>> :value 1 :type r)))
|
||||||
|
,#+end_src
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Upon tangling, the <<rx ...>> is converted to a regex string and therefore readable by elfeed-score.
|
Loading…
Reference in a new issue