trying to fix

This commit is contained in:
Chris Cochrun 2022-01-03 12:41:35 -06:00
parent fa407dfeb6
commit e013d7569e
22945 changed files with 447936 additions and 0 deletions

View file

@ -0,0 +1,85 @@
<p>Earlier today I wanted to convert a bunch of Org meta data keywords to
lower case notation, with the help of <code>isearch-forward-regexp</code> and
<code>query-replace-regexp</code>. This included everything from special comments,
like <code>#+TITLE:</code> to property drawers in the form of <code>:PROPERTIES:</code>.
There were 340 such cases in my file and I was reluctant to do so
manually. Thankfully, Emacs makes such a task fairly simple once you
get past the essentials, because it lets you evaluate arbitrary Elisp
forms for the replacement text. This includes the possibility of
running some function on a matched regexp group. In this case that
function was <code>(downcase OBJECT)</code>.</p>
<p>First I needed a regular expression that would capture all targets.
<code>isearch-forward-regexp</code> and its <code>query-replace-regexp</code> counterpart
expect a single backslash for the escape character, so I ended up with
this pattern:</p>
<pre><code>^\(#\|:\)[^ ].*?:
</code></pre>
<p>If I were to test this in the buffer, I could use <code>M-x re-builder</code>,
which however requires double backslashes (same for when you write Elisp
code):</p>
<pre><code>^\\(#\\|:\\)[^ ].*?:
</code></pre>
<ul>
<li>
<p>Once I was sure of the regular expression I had to use, I went to the
top of the buffer and invoked <code>isearch-forward-regexp</code> (bound to
<code>C-M-s</code> by default).</p>
</li>
<li>
<p>Entered the pattern <code>^\(#\|:\)[^ ].*?:</code>, got live feedback of the
matching items, and switched to <code>query-replace</code> with <code>C-%</code>
(<code>isearch-query-replace</code>). When the Isearch is regexp-aware so is the
corresponding <code>query-replace</code>.</p>
</li>
<li>
<p>For the replacement text I instructed the command to evaluate the
<code>downcase</code> function. This is done by escaping the comma operator
(<code>,</code>) and then supplying the function with a regexp group. Because I
wished to match everything, the group should be <code>\0</code>. Which means
that the replacement should be expressed thus: <code>\,(downcase \0)</code>.</p>
</li>
</ul>
<p>Try this with any string in a buffer, say, <code>Hello</code>:</p>
<ul>
<li><code>M-x query-replace-regexp</code></li>
<li><code>Hello</code></li>
<li><code>\,(upcase \0)</code></li>
</ul>
<p>Confirm the operation and you should get <code>HELLO</code>. This works with
multiple groups and can read a series of Elisp forms. An example with
<code>Hello world</code>:</p>
<ul>
<li><code>M-x query-replace-regexp</code></li>
<li><code>\(Hello\) \(world\)</code></li>
<li><code>\,(downcase \1) \,(capitalize \2)</code></li>
</ul>
<p>Which should give you <code>hello World</code>.</p>
<p>The elegant minimalism of the <code>query-replace</code> interface grants you the
power to either replace each match one at a time or hit the exclamation
mark (<code>!</code>) to answer “yes to all”. This is what I did to downcase all
340 matches. Voila! All of my Org files meta data were converted to
lower case in one go.</p>
<p>Finally, I discovered <code>query-replace-regexp-eval</code> which saves you from
adding the escaped comma operator for the replacements Elisp form.
However its doc string reads thus:</p>
<pre><code>Interactive use of this function is deprecated in favor of the
\, feature of query-replace-regexp. For non-interactive use, a loop
using search-forward-regexp and replace-match is preferred.
</code></pre>