<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><generator uri="https://gohugo.io/" version="0.101.0">Hugo</generator><title type="html">looping on A Scripter's Notes</title><subtitle type="html">Emacs, scripting and anything text oriented.</subtitle><link href="https://scripter.co/tags/looping/" rel="alternate" type="text/html" title="HTML"/><link href="https://scripter.co/tags/looping/index.xml" rel="alternate" type="application/rss+xml" title="RSS"/><link href="https://scripter.co/tags/looping/atom.xml" rel="self" type="application/atom+xml" title="Atom"/><link href="https://scripter.co/tags/looping/jf2feed.json" rel="alternate" type="application/jf2feed+json" title="jf2feed"/><updated>2026-04-22T08:24:58-04:00</updated><author><name>Kaushal Modi</name><email>kaushal.modi@gmail.com</email></author><id>https://scripter.co/tags/looping/</id><entry><title type="html">Org: Show only Post subtree headings</title><link href="https://scripter.co/org-show-only-post-subtree-headings/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/looping-through-org-mode-headings/?utm_source=atom_feed" rel="related" type="text/html" title="Looping through Org mode headings"/><link href="https://scripter.co/using-emacs-advice-to-silence-messages-from-functions/?utm_source=atom_feed" rel="related" type="text/html" title="Using Emacs advice to silence messages from functions"/><link href="https://scripter.co/firefox-always-open-a-new-tab-after-current/?utm_source=atom_feed" rel="related" type="text/html" title="Firefox: Always open a New Tab after Current"/><link href="https://scripter.co/saving-python-pip-dependencies/?utm_source=atom_feed" rel="related" type="text/html" title="Saving Python pip dependencies"/><link href="https://scripter.co/disarming-the-tar-bomb-in-10-seconds/?utm_source=atom_feed" rel="related" type="text/html" title="Disarming the 'tar' bomb in 10 seconds"/><id>https://scripter.co/org-show-only-post-subtree-headings/</id><author><name>Kaushal Modi</name></author><published>2022-06-16T00:21:00-04:00</published><updated>2022-06-16T00:21:00-04:00</updated><content type="html"><![CDATA[<blockquote>How to define a custom <code>org-global-cycle</code>-like command that collapses
only the Org subtrees with specific properties.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#org-global-cycle">Org Global Cycle</a></li>
<li><a href="#skeleton-of-only-post-headings">Skeleton of only Post headings</a></li>
<li><a href="#the-collapse-all-posts-function">The &ldquo;Collapse All Posts&rdquo; function</a></li>
<li><a href="#binding-with-c-u-c-c-tab">Binding with <code>C-u C-c TAB</code></a></li>
<li><a href="#result">Result</a></li>
</ul>
</div>
<!--endtoc-->
<p>I start this post by introducing what the Org mode global cycling
command does, what kind of subtree folding I actually need, and then
share the solution with code snippets.</p>

<h2 id="org-global-cycle">Org Global Cycle&nbsp;<a class="headline-hash no-text-decoration" href="#org-global-cycle">#</a></h2>


<p>Org mode has a built-in <code>org-global-cycle</code> command that you might be
familiar with. It&rsquo;s bound by default to the <code>S-TAB</code> key. Each time
this command is called, the Org buffer will cycle through these
states:</p>
<ol>
<li>Overview: Show only the Level 1 headings and collapse everything
underneath.</li>
<li>Contents: Show only the Org headings and collapse all the content.</li>
<li>Show All: Expand all the headings and show their contents too.</li>
</ol>
<p>If a numeric prefix <em>N</em> is used with this command, it will show only
the Org headings up to Level <em>N</em>. For example, <code>C-2 S-TAB</code> will show
only the headings up to Level 2.</p>
<p>This is a really helpful command, but I needed something different ..</p>

<h2 id="skeleton-of-only-post-headings">Skeleton of only Post headings&nbsp;<a class="headline-hash no-text-decoration" href="#skeleton-of-only-post-headings">#</a></h2>


<p>I maintain most of this website&rsquo;s content in a single Org file. I have
dozens of blog posts organized in Org subtrees, which I further
organize under &ldquo;category&rdquo; headings .. It kind of looks like the below
mock-up:
<span class="sidenote-number"><small class="sidenote">
It&rsquo;s amazing how many features PlantUML has. If you are interested in
creating diagrams like these, check out the <a href="https://plantuml.com/salt">PlantUML Salt</a> syntax.
</small></span></p>
<p><a id="figure--post-subtrees-collapsed-mockup"></a></p>



<figure>
    
        <img src="https://scripter.co/org-show-only-post-subtree-headings/post-subtrees.svg" alt="Figure 1: Post Subtrees at arbitrary heading levels"/> <figcaption>
                <p>
                    <span class="figure-number">Figure 1: </span>Post Subtrees at arbitrary heading levels
                    
                        
                        </p>
                
            </figcaption></figure>

<p>As we can see,</p>
<ul>
<li>All the post subtrees are not at Level 1 headings.</li>
<li>They are also not at a fixed Level <em>N</em>.</li>
<li>The heading level of the post depends on how many parent categories
that post has (and that will also change over time).</li>
</ul>
<p>I needed to basically show everything leading up to a post subtree
heading, and then collapse all the content under that post; even the
sub-headings.</p>

<h2 id="the-collapse-all-posts-function">The &ldquo;Collapse All Posts&rdquo; function&nbsp;<a class="headline-hash no-text-decoration" href="#the-collapse-all-posts-function">#</a></h2>


<p>The <code>modi/org-hugo-collapse-all-posts</code> function defined below meets
the above requirement:</p>
<ol>
<li>It first widens the whole buffer and expands all the headings.</li>
<li>Then it loops through all the headings and collapses all the <em>post
subtrees</em> i.e. all the subtrees that have the <code>EXPORT_FILE_NAME</code>
property set. This is where I use the <a href="/looping-through-org-mode-headings/"><code>org-map-entries</code></a> magic.</li>
<li>Finally it looks for Org headings that begin with &ldquo;Footnotes&rdquo; or
&ldquo;COMMENT&rdquo; and collapses them as well.</li>
</ol>
<p>I am using the development version of Org mode (version 9.6, yet to be
released as of <span class="timestamp-wrapper"><span class="timestamp">&lt;2022-06-15 Wed&gt;</span></span>) which has the new <code>org-fold</code>
library. This library obsoletes the use of <code>outline.el</code> library and
other <em>code-folding</em> related functions in Org mode. So <code>cl-flet</code> is
used to create function symbol aliases that use the <code>org-fold-*</code>
functions if available, otherwise they fall back to the legacy
functions.</p>
<p><a id="code-snippet--collapse-all-posts-fn"></a></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="hl"><span class="lnt">19
</span></span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="hl"><span class="lnt">23
</span></span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">modi/org-hugo-collapse-all-posts</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Collapse all post subtrees in the current buffer.
</span></span></span><span class="line"><span class="cl"><span class="s">Also collapse the Footnotes subtree and COMMENT subtrees if
</span></span></span><span class="line"><span class="cl"><span class="s">present.
</span></span></span><span class="line"><span class="cl"><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s">A post subtree is one that has the EXPORT_FILE_NAME property
</span></span></span><span class="line"><span class="cl"><span class="s">set.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">cl-flet</span> <span class="p">((</span><span class="nv">show-all</span> <span class="p">(</span><span class="nb">if</span> <span class="p">(</span><span class="nf">fboundp</span> <span class="ss">&#39;org-fold-show-all</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                          <span class="nf">#&#39;</span><span class="nv">org-fold-show-all</span>
</span></span><span class="line"><span class="cl">                        <span class="nf">#&#39;</span><span class="nv">org-show-all</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">hide-subtree</span> <span class="p">(</span><span class="nb">if</span> <span class="p">(</span><span class="nf">fboundp</span> <span class="ss">&#39;org-fold-hide-subtree</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                              <span class="nf">#&#39;</span><span class="nv">org-fold-hide-subtree</span>
</span></span><span class="line"><span class="cl">                            <span class="nf">#&#39;</span><span class="nv">outline-hide-subtree</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">widen</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">show-all</span> <span class="o">&#39;</span><span class="p">(</span><span class="nv">headings</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="c1">;; Collapse all the post subtrees (ones with EXPORT_FILE_NAME</span>
</span></span><span class="line"><span class="cl">    <span class="c1">;; property set).</span>
</span></span><span class="line hl"><span class="cl">    <span class="p">(</span><span class="nv">org-map-entries</span> <span class="nf">#&#39;</span><span class="nv">hide-subtree</span> <span class="s">&#34;EXPORT_FILE_NAME&lt;&gt;\&#34;\&#34;&#34;</span> <span class="ss">&#39;file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1">;; Also hide Footnotes and comments.</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">save-excursion</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nf">goto-char</span> <span class="p">(</span><span class="nf">point-min</span><span class="p">))</span>
</span></span><span class="line hl"><span class="cl">      <span class="p">(</span><span class="nb">while</span> <span class="p">(</span><span class="nf">re-search-forward</span> <span class="s">&#34;^\\(\\* Footnotes\\|\\*+ COMMENT\\)&#34;</span>
</span></span><span class="line"><span class="cl">                                <span class="no">nil</span> <span class="nb">:noerror</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">hide-subtree</span><span class="p">)))))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--collapse-all-posts-fn">Code Snippet 1</a>:</span>
  Function that collapses all the post subtrees in the current buffer
</div>

<h2 id="binding-with-c-u-c-c-tab">Binding with <code>C-u C-c TAB</code>&nbsp;<a class="headline-hash no-text-decoration" href="#binding-with-c-u-c-c-tab">#</a></h2>


<p>The function is ready, but let&rsquo;s now add a bit of convenience to it.</p>
<p>If a point is under a subtree, <code>C-c TAB</code> will collapse that subtree
while showing only Level 1 headings, and if a numeric prefix is used,
it will show only those many levels of headings. I decided to bind the
above function to <code>C-u C-c TAB</code> because,</p>
<ol>
<li>The behavior of <code>modi/org-hugo-collapse-all-posts</code> falls in the
same category as that of <code>C-c TAB</code>.</li>
<li>The <code>C-u C-c ..</code> binding rolls off the fingers pretty
nicely 😃.</li>
</ol>
<p>This <em>binding</em> is achieved using one of my favorite Emacs features
.. the <strong>advice</strong> system. The <code>:before-until</code> <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Advice-Combinators.html" title="Emacs Lisp: (info &quot;(elisp) Advice Combinators&quot;)">Advice Combinator</a> is used
here, which means that if the <em>advising</em> function (below) returns a
<em>nil</em>, the <em>advised</em> or the original function <code>org-ctrl-c-tab</code> is not
called.</p>
<p>The <em>advising</em> function below detects if the <code>C-u</code> prefix argument is
used. If it is, the <code>modi/org-hugo-collapse-all-posts</code> function is
called, otherwise the original <code>org-ctrl-c-tab</code> function is called.</p>
<p><a id="code-snippet--collapse-all-posts-binding"></a></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="hl"><span class="lnt">4
</span></span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">modi/org-ctrl-c-tab-advice</span> <span class="p">(</span><span class="kp">&amp;rest</span> <span class="nv">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Run </span><span class="ss">`modi/org-hugo-collapse-all-posts&#39;</span><span class="s"> when
</span></span></span><span class="line"><span class="cl"><span class="s">doing \\[universal-argument] \\[org-ctrl-c-tab].&#34;</span>
</span></span><span class="line hl"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">do-not-run-orig-fn</span> <span class="p">(</span><span class="nf">equal</span> <span class="o">&#39;</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="nv">current-prefix-arg</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">when</span> <span class="nv">do-not-run-orig-fn</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nv">modi/org-hugo-collapse-all-posts</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="nv">do-not-run-orig-fn</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">advice-add</span> <span class="ss">&#39;org-ctrl-c-tab</span> <span class="nb">:before-until</span> <span class="nf">#&#39;</span><span class="nv">modi/org-ctrl-c-tab-advice</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--collapse-all-posts-binding">Code Snippet 2</a>:</span>
  Bind <code>C-u C-c TAB</code> to call <code>modi/org-hugo-collapse-all-posts</code>
</div>

<h2 id="result">Result&nbsp;<a class="headline-hash no-text-decoration" href="#result">#</a></h2>


<p>After evaluating the above two snippets, when I do <code>C-u C-c TAB</code> in
my &ldquo;blog posts&rdquo; Org buffer, I see this:</p>
<p><a id="figure--post-subtrees-collapsed"></a></p>



<figure>
    <a href="post-subtrees-collapsed.png">
        <img src="https://scripter.co/org-show-only-post-subtree-headings/post-subtrees-collapsed.png" alt="Figure 2: My &ldquo;blog posts&rdquo; Org buffer showing only the Post subtree headings"/> </a><figcaption>
                <p>
                    <span class="figure-number">Figure 2: </span>My &ldquo;blog posts&rdquo; Org buffer showing only the Post subtree headings
                    
                        
                        </p>
                
            </figcaption></figure>

<p>It matches <a href="#figure--post-subtrees-collapsed-mockup">that earlier mockup</a> &mdash; Mission accomplished! 💯</p>
]]></content><category scheme="https://scripter.co/categories/emacs" term="emacs" label="emacs"/><category scheme="https://scripter.co/categories/org" term="org" label="org"/><category scheme="https://scripter.co/categories/elisp" term="elisp" label="elisp"/><category scheme="https://scripter.co/tags/100daystooffload" term="100daystooffload" label="100DaysToOffload"/><category scheme="https://scripter.co/tags/subtree" term="subtree" label="subtree"/><category scheme="https://scripter.co/tags/looping" term="looping" label="looping"/><category scheme="https://scripter.co/tags/advice" term="advice" label="advice"/></entry><entry><title type="html">Looping through Org mode headings</title><link href="https://scripter.co/looping-through-org-mode-headings/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/using-org-logbook-notes-to-record-blog-post-updates/?utm_source=atom_feed" rel="related" type="text/html" title="Using Org Logbook Notes to record blog post updates"/><link href="https://scripter.co/building-org-development-version/?utm_source=atom_feed" rel="related" type="text/html" title="Building Org Development version (2022)"/><link href="https://scripter.co/downloading-nim/?utm_source=atom_feed" rel="related" type="text/html" title="Downloading Nim"/><link href="https://scripter.co/creating-a-patch-file-using-magit/?utm_source=atom_feed" rel="related" type="text/html" title="Creating a patch file using Magit"/><link href="https://scripter.co/presenting-tomelr/?utm_source=atom_feed" rel="related" type="text/html" title="Presenting tomelr!"/><id>https://scripter.co/looping-through-org-mode-headings/</id><author><name>Kaushal Modi</name></author><published>2022-05-18T23:29:00-04:00</published><updated>2022-05-18T23:29:00-04:00</updated><content type="html"><![CDATA[<blockquote>Using the <code>org-map-entries</code> API to loop through selected or all
headings in an Org file.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#org-map-entries-api"><code>org-map-entries</code> API</a>
<ul>
<li><a href="#match-strings"><em>MATCH</em> strings</a></li>
<li><a href="#comparison-types">Comparison Types</a></li>
<li><a href="#other-notes">Other notes</a></li>
</ul>
</li>
<li><a href="#example-modifying-a-property-in-all-headings">Example: Modifying a property in all headings</a></li>
<li><a href="#org-map-entries-references"><code>org-map-entries</code> References</a></li>
</ul>
</div>
<!--endtoc-->
<p><a href="https://framapiaf.org/@postroutine/108313152514542145">Below question</a> on Mastodon by the user <a href="https://framapiaf.org/@postroutine">@postroutine</a> inspired me to
write this post:</p>
<blockquote>
<p>I got a lot of Org-Mode headings and I want to modify their properties
(add, remove, edit). Is there a function to do the same modifications
on each heading?</p>
</blockquote>
<p>I think that the best solution to that question is using the
<strong>org-map-entries</strong> function.</p>
<p>But somehow when replying to that question then, that wasn&rsquo;t what
first came to my mind! .. when ironically that function is the <a href="https://github.com/kaushalmodi/ox-hugo/blob/2b169e5e83d608e80f4faee9d681b98d87041f58/ox-hugo.el#L4781-L4788">main
function</a> that enables my preferred <em>subtree-based flow</em> in <code>ox-hugo</code>
😆. So I am writing this post to better ingrain the following
concept in myself ..</p>
<div class="note">
<p>If you need to loop through headings in an Org buffer, and especially
if you <strong>need to modify that buffer</strong> in the process, use
<strong>org-map-entries</strong><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
</div>
<p>Next,</p>
<ol>
<li>I will give a give introduction to the <code>org-map-entries</code> API.</li>
<li>Then provide a super-short solution to the above question.</li>
</ol>

<h2 id="org-map-entries-api"><code>org-map-entries</code> API&nbsp;<a class="headline-hash no-text-decoration" href="#org-map-entries-api">#</a></h2>


<p>I will give only a broad level overview on how to use this function. I
would encourage the reader to refer to the resources at the end of
this post to learn more about it.</p>
<p>So let&rsquo;s start by looking at this function&rsquo;s signature:</p>
<p><a id="code-snippet--org-map-entries-signature"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nv">org-map-entries</span> <span class="nv">FUNC</span> <span class="kp">&amp;optional</span> <span class="nv">MATCH</span> <span class="nv">SCOPE</span> <span class="kp">&amp;rest</span> <span class="nv">SKIP</span><span class="p">)</span>
</span></span></code></pre></div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--org-map-entries-signature">Code Snippet 1</a>:</span>
  Signature of the <code>org-map-entries</code> function
</div>
<p>The <code>org-map-entries</code> function iterates through all the headings
meeting the <em>MATCH</em> criteria in the determined <em>SCOPE</em>, and then calls
the specified function <em>FUNC</em> at each of those headings.</p>
<ul>
<li>The <code>FUNC</code> function accepts <strong>no</strong> arguments and is called at the
beginning of each Org heading.</li>
<li>The optional second argument <em>MATCH</em> is either <em>nil</em>, <code>t</code> or a
<em>search string</em>.
<ul>
<li>If <em>MATCH</em> is <em>nil</em> or <code>t</code>, <strong>all</strong> headings will be visited by the
iteration and <em>FUNC</em> will be called on all of them.</li>
<li>But if <em>MATCH</em> is a string, the headings will first be filtered
based on that string and then the <em>FUNC</em> will be called on only
those.</li>
</ul>
</li>
<li>For explanations on the optional <em>SCOPE</em> and <em>SKIP</em> arguments, see
<a href="https://orgmode.org/manual/Using-the-Mapping-API.html" title="Emacs Lisp: (info &quot;(org) Using the Mapping API&quot;)">Org Info: Using the Mapping API</a> or <kbd>C-h</kbd> <kbd>f</kbd> <code>org-map-entries</code> from
within Emacs.</li>
</ul>
<p>Here&rsquo;s a typical <code>org-map-entries</code> call that loops through <strong>all</strong> the
headings in the <strong>visible</strong> buffer: <code class="code-inline language-emacs-lisp"><span class="p">(</span><span class="nv">org-map-entries</span> <span class="nf">#&#39;</span><span class="nv">some-function</span><span class="p">)</span></code> where all the optional
argument values are <em>nil</em>. Next, we&rsquo;ll see some examples of
string-type <em>MATCH</em> arguments used for filtering the headings.</p>

<h3 id="match-strings"><em>MATCH</em> strings&nbsp;<a class="headline-hash no-text-decoration" href="#match-strings">#</a></h3>


<p>Below table shows few examples of match string patterns.</p>
<p><a id="table--org-map-entries-search-strings"></a></p>
<div class="table-caption">
  <span class="table-number"><a href="#table--org-map-entries-search-strings">Table 1</a>:</span>
  String-type <i>MATCH</i> argument examples for <code>org-map-entries</code>
</div>
<table>
<thead>
<tr>
<th>Search string</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>&quot;TAG&quot;</code></strong></td>
<td>Tag name</td>
<td><code>&quot;foo&quot;</code> matches all headings with that tag</td>
</tr>
<tr>
<td><strong><code>&quot;{TAG REGEXP}&quot;</code></strong></td>
<td>Regexp matching tags</td>
<td><code>&quot;{f.*}&quot;</code> matches all headings whose tags match that regexp</td>
</tr>
<tr>
<td><strong><code>&quot;TAG1+TAG2+..&quot;</code></strong></td>
<td>Tag set intersection</td>
<td><code>&quot;foo+bar&quot;</code> matches all headings with both of those tags</td>
</tr>
<tr>
<td><strong><code>&quot;TAG1-TAG2+..&quot;</code></strong></td>
<td>Tag set difference</td>
<td><code>&quot;foo-bar&quot;</code> matches all headings with <code>foo</code> tag but without <code>bar</code> tag</td>
</tr>
<tr>
<td><strong><code>&quot;TAG1</code>|​<code>TAG2</code>|​<code>..&quot;</code></strong></td>
<td>Tag set union or boolean <em>OR</em></td>
<td><code>&quot;foo</code>​|​<code>bar&quot;</code> matches all headings with either of those tags</td>
</tr>
<tr>
<td><strong><code>&quot;TAG1&amp;TAG2&amp;..&quot;</code></strong></td>
<td>Tag set intersection or boolean <em>AND</em></td>
<td><code>&quot;foo&amp;bar&quot;</code> is same as <code>&quot;foo+bar&quot;</code></td>
</tr>
<tr>
<td><strong><code>&quot;PROP</code>​=​<code>\&quot;STRVAL\&quot;&quot;</code></strong></td>
<td>Specified property value matching a string</td>
<td><code>&quot;color</code>​=​<code>\&quot;blue\&quot;&quot;</code> matches all headings where <code>color</code> property is <code>blue</code></td>
</tr>
<tr>
<td><strong><code>&quot;PROP&lt;&gt;\&quot;STRVAL\&quot;&quot;</code></strong></td>
<td>Specified property value not matching a string</td>
<td><code>&quot;color&lt;&gt;\&quot;blue\&quot;&quot;</code> matches all headings where <code>color</code> property is not <code>blue</code></td>
</tr>
<tr>
<td><strong><code>&quot;PROP</code>​=​<code>{VAL REGEXP}&quot;</code></strong></td>
<td>Specified property value matching a regexp</td>
<td><code>&quot;color={b.*}&quot;</code> matches all headings where <code>color</code> property value matches &lsquo;<code>b.*</code>&rsquo; regexp</td>
</tr>
<tr>
<td><strong><code>&quot;PROP[OP]NUMVAL&quot;</code></strong></td>
<td>Specified property value compared with a numeric value</td>
<td><code>&quot;some_num</code>​&gt;=​<code>10&quot;</code> matches all headings where <code>some_num</code> property is &gt;=10</td>
</tr>
<tr>
<td><strong><code>&quot;LEVEL[OP]VAL&quot;</code></strong></td>
<td>Check value of headline&rsquo;s special property <em>LEVEL</em></td>
<td><code>&quot;level&gt;2&quot;</code> matches all headlines at levels greater than 2</td>
</tr>
<tr>
<td><strong><code>&quot;TODO[OP]\&quot;STRVAL\&quot;&quot;</code></strong></td>
<td>Check value of headline&rsquo;s <em>TODO</em> state</td>
<td><code>&quot;TODO</code>​=​<code>\&quot;DONE\&quot;&quot;</code> matches all headlines with <em>TODO</em> state set to &lsquo;DONE&rsquo;</td>
</tr>
</tbody>
</table>

<h3 id="comparison-types">Comparison Types&nbsp;<a class="headline-hash no-text-decoration" href="#comparison-types">#</a></h3>


<ul>
<li>If the comparison value is a plain number, a numerical comparison is
done, and the allowed operators are &lsquo;&lt;&rsquo;, &lsquo;=​&rsquo;, &lsquo;&gt;&rsquo;, &lsquo;&lt;=​&rsquo;, &lsquo;&gt;=​&rsquo;,
and &lsquo;&lt;&gt;&rsquo;.</li>
<li>If the comparison value is enclosed in double quotes, a string
comparison is done, and the same operators are allowed.</li>
<li>If the comparison value is enclosed in curly braces, a regexp match
is performed. For this comparison, only &lsquo;=​&rsquo; (regexp matches) and
&lsquo;&lt;&gt;&rsquo; (regexp does not match) operators are allowed.</li>
<li>Comparison with dates and <a href="https://orgmode.org/manual/Tag-Hierarchy.html" title="Emacs Lisp: (info &quot;(org) Tag Hierarchy&quot;)">Group Tags</a> is also possible. See
<a href="https://orgmode.org/manual/Matching-tags-and-properties.html" title="Emacs Lisp: (info &quot;(org) Matching tags and properties&quot;)">Org Info: Matching tags and properties</a> for more details.</li>
</ul>

<h3 id="other-notes">Other notes&nbsp;<a class="headline-hash no-text-decoration" href="#other-notes">#</a></h3>


<ul>
<li>The property names are case-insensitive. So these all work the
same: <code>&quot;COLOR&lt;&gt;\&quot;blue\&quot;&quot;</code>, <code>&quot;color&lt;&gt;\&quot;blue\&quot;&quot;</code>,
<code>&quot;Color&lt;&gt;\&quot;blue\&quot;&quot;</code>.</li>
<li>The &ldquo;tag&rdquo; and &ldquo;property&rdquo; matches can be mixed up using the boolean
&lsquo;<code>&amp;</code>&rsquo;, &lsquo;<code>|</code>&rsquo;, &lsquo;<code>+</code>&rsquo; and &lsquo;<code>-</code>​&rsquo; operators. So searching
&lsquo;<code>+LEVEL=3+boss-TODO​=&quot;DONE&quot;</code>&rsquo; lists all level three headlines
that have the tag &lsquo;boss&rsquo; and are <span class="underline">not</span> marked with the TODO
keyword &lsquo;DONE&rsquo;.</li>
<li>&lsquo;<code>&amp;</code>&rsquo; binds more strongly than &lsquo;<code>|</code>&rsquo;.</li>
<li>Grouping of match expressions using parentheses is not
supported.</li>
</ul>

<h2 id="example-modifying-a-property-in-all-headings">Example: Modifying a property in all headings&nbsp;<a class="headline-hash no-text-decoration" href="#example-modifying-a-property-in-all-headings">#</a></h2>


<p>Below is an example solution to the <a href="https://framapiaf.org/@postroutine/108313152514542145">Mastoson question</a> that I
referenced in the beginning of this post.</p>
<p><a id="code-snippet--set-props-all-headings"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">test/set-property-at-heading</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Function to be called at the beginning of an Org heading.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">el</span> <span class="p">(</span><span class="nv">org-element-at-point</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">org-set-property</span> <span class="s">&#34;foo&#34;</span> <span class="p">(</span><span class="nv">org-element-property</span> <span class="nb">:title</span> <span class="nv">el</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">org-map-entries</span> <span class="nf">#&#39;</span><span class="nv">test/set-property-at-heading</span><span class="p">)</span>
</span></span></code></pre></div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--set-props-all-headings">Code Snippet 2</a>:</span>
  Dummy example showing how to set a property for all Org headings using <code>org-map-entries</code>
</div>
<ul>
<li>It defines a function that parses the Org element at point using
<code>org-element-at-point</code>, gets the <code>title</code> property of the element
<span class="sidenote-number"><small class="sidenote">
This function is designed to be called by <code>org-map-entries</code> and so
the point at the time of calling this function will always be on a
heading.
</small></span>
, and sets that to the <em>headline</em> element&rsquo;s <code>foo</code> property.</li>
<li>The <code>org-map-entries</code> call now simply calls this function on each
heading in the visible scope of the Org buffer.</li>
</ul>

<h2 id="org-map-entries-references"><code>org-map-entries</code> References&nbsp;<a class="headline-hash no-text-decoration" href="#org-map-entries-references">#</a></h2>


<ul>
<li><kbd>C-h</kbd> <kbd>f</kbd> <code>org-map-entries</code></li>
<li><a href="https://orgmode.org/manual/Using-the-Mapping-API.html" title="Emacs Lisp: (info &quot;(org) Using the Mapping API&quot;)">Org Info: Using the Mapping API</a></li>
<li><a href="https://orgmode.org/manual/Matching-tags-and-properties.html" title="Emacs Lisp: (info &quot;(org) Matching tags and properties&quot;)">Org Info: Matching tags and properties</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Org mode has another popular mapping/looping API function
<strong>org-element-map</strong>. I won&rsquo;t go into much detail about that in this post
&mdash; I&rsquo;ll just mention that <code>org-element-map</code> is not the best choice if
you need to modify the original Org buffer. It&rsquo;s main use is to loop
through a parsed <abbr aria-label="Abstract Syntax Tree" tabindex=0>AST</abbr> of an Org buffer
and optional modify those elements <em>in memory</em>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content><category scheme="https://scripter.co/categories/emacs" term="emacs" label="emacs"/><category scheme="https://scripter.co/categories/org" term="org" label="org"/><category scheme="https://scripter.co/categories/elisp" term="elisp" label="elisp"/><category scheme="https://scripter.co/tags/looping" term="looping" label="looping"/><category scheme="https://scripter.co/tags/100daystooffload" term="100daystooffload" label="100DaysToOffload"/></entry></feed>