<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Ashish Panigrahi</title>
  <subtitle>Ashish&#39;s website</subtitle>
  <link rel="self" type="application/atom+xml" href="https://ashishpanigrahi.com/atom.xml"/>
  <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com"/>
  <generator uri="https://orgmode.org/">Org mode</generator>
  <updated>2026-10-06T00:00:00+00:00</updated>
  <id>https://ashishpanigrahi.com/atom.xml</id>
  <entry xml:lang="en">
    <title>Another year gone (my poem)</title>
    <published>2026-10-06T00:00:00+00:00</published>
    <updated>2026-10-06T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/another-year-gone/"/>
    <id>https://ashishpanigrahi.com/blog/another-year-gone/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/another-year-gone/">&lt;blockquote&gt;
&lt;p&gt;
The day arrives every year.&lt;br&gt;
Reminding me of my eternal fear.&lt;br&gt;
Life inches closer to the end.&lt;br&gt;
As it is to be meant.&lt;br&gt;
&lt;br&gt;
People celebrate it as an event so joyous.&lt;br&gt;
The day you were born, the festivity so contagious.&lt;br&gt;
But alas, it is yet another year gone.&lt;br&gt;
I&#39;m afraid this thought is what I mourn.&lt;br&gt;
&lt;br&gt;
I realize I&#39;m a year older.&lt;br&gt;
Fearful that such a thought is so much colder.&lt;br&gt;
For what is there to celebrate?&lt;br&gt;
Just yet another year that&#39;s gone to waste.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>This website is now built with Org mode</title>
    <published>2026-10-05T00:00:00+00:00</published>
    <updated>2026-10-05T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/orgmode-website-update/"/>
    <id>https://ashishpanigrahi.com/blog/orgmode-website-update/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/orgmode-website-update/">&lt;p&gt;
&lt;a href=&quot;/blog/zola-website&quot;&gt;Since moving to Zola as my static site generator&lt;/a&gt;, I have had a nice
setup for my website. However, a recent update to zola (v0.22 -&amp;gt;
v0.23) broke my website (it apparently had something to do with the
&lt;a href=&quot;https://keats.github.io/tera/&quot;&gt;Tera&lt;/a&gt; templating engine that zola uses). This forced me to finally make
to move to switching to orgmode as my SSG.
&lt;/p&gt;

&lt;p&gt;
My ultimate goal has always been to build this website purely with
emacs and orgmode&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/orgmode-website-update/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, and I&#39;m glad now that&#39;s the case. Full
disclosure however, I did take the help of LLMs to implement this over
the weekend. There are still some rough edges to the site, which is
why I have this build on a different branch (instead of &lt;code&gt;main&lt;/code&gt;) on my
website&#39;s &lt;a href=&quot;https://gitlab.com/paniash/website&quot;&gt;source repository&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
The website is generated via &lt;a href=&quot;https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html&quot;&gt;org-publish&lt;/a&gt; with the following directory
structure for the source code:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;.
&amp;#9500;&amp;#9472;&amp;#9472; LICENSE
&amp;#9500;&amp;#9472;&amp;#9472; Makefile
&amp;#9500;&amp;#9472;&amp;#9472; README.org
&amp;#9500;&amp;#9472;&amp;#9472; content/
&amp;#9500;&amp;#9472;&amp;#9472; lisp/
&amp;#9500;&amp;#9472;&amp;#9472; publish.el
&amp;#9500;&amp;#9472;&amp;#9472; static/
&amp;#9500;&amp;#9472;&amp;#9472; statichost.yml
&amp;#9500;&amp;#9472;&amp;#9472; style.css
&amp;#9492;&amp;#9472;&amp;#9472; templates/

5 directories, 6 files&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
The key component is &lt;code&gt;publish.el&lt;/code&gt; which exports all of my blogposts (which
are orgmode files now) to html files. I also have the &lt;a href=&quot;https://github.com/emacsorphanage/htmlize/blob/master/htmlize.el&quot;&gt;htmlize.el&lt;/a&gt;
file hosted on the git repo for syntax highlighting.
&lt;/p&gt;

&lt;p&gt;
Feel free to peruse the &lt;a href=&quot;https://gitlab.com/paniash/website/-/tree/orgmode-build&quot;&gt;source code of this build&lt;/a&gt; if you&#39;re interested
in the technical details. At its current state, I&#39;m quite happy with
how it has turned out. A nice little addition (which is the default
behaviour of org-publish) is that I now have a footer entry mentioning
the emacs and orgmode version used to build this website!
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
As is the trend to move all of my computing needs to emacs.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/orgmode-website-update/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>An upgraded workflow on reviewing finished tasks with org-agenda</title>
    <published>2026-09-19T00:00:00+00:00</published>
    <updated>2026-09-21T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/completed-org-items-since-date/"/>
    <id>https://ashishpanigrahi.com/blog/completed-org-items-since-date/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/completed-org-items-since-date/">&lt;p&gt;
In my &lt;a href=&quot;/blog/done-items-org-agenda/&quot;&gt;last blogpost&lt;/a&gt;, I showcased how I
review tasks finished over the last seven days. It implicitly
assumes that I attend every group meeting&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/completed-org-items-since-date/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; and that the group
meeting happens during the same time every week&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/completed-org-items-since-date/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
In a more practical sense, it would be nice to generalize this
workflow. I would like to specify a date, since when completed tasks
would be displayed until the current day. This way I would be able to
review my finished agenda items since a particular day in the past.
This date would typically be when the group meeting last occured, but
we are not strictly bound to it.
&lt;/p&gt;
&lt;h2 id=&quot;implementation-in-emacs-lisp&quot;&gt;Implementation in emacs lisp&lt;/h2&gt;
&lt;p&gt;
We write an elisp snippet similar to the one in the previous blogpost.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;defvar&lt;/span&gt; &lt;span class=&quot;org-variable-name&quot;&gt;pani/last-group-meeting-date&lt;/span&gt; nil)

(&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; org-agenda-custom-commands
      &#39;((&lt;span class=&quot;org-string&quot;&gt;&quot;v&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;Finished tasks since last group meeting&quot;&lt;/span&gt;
          tags
          (format &lt;span class=&quot;org-string&quot;&gt;&quot;CLOSED&amp;gt;=\&quot;&amp;lt;%s&amp;gt;\&quot;&quot;&lt;/span&gt;
                  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; pani/last-group-meeting-date
                        (org-read-date nil nil nil &lt;span class=&quot;org-string&quot;&gt;&quot;Last group meeting: &quot;&lt;/span&gt;)))
          ((org-agenda-overriding-header
            (format &lt;span class=&quot;org-string&quot;&gt;&quot;Finished tasks since %s&quot;&lt;/span&gt; pani/last-group-meeting-date))
           (org-agenda-archives-mode t)
           (org-agenda-tag-filter-preset &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;-emacs&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;-personal&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;-email&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;-misc&quot;&lt;/span&gt;))
           (org-agenda-prefix-format &#39;((tags . &lt;span class=&quot;org-string&quot;&gt;&quot; &quot;&lt;/span&gt;)))
           (org-agenda-remove-tags nil)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Most of the config options are similar so I won&#39;t be going over in
detail. Let&#39;s instead point out the differences.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since we would like emacs to prompt for a date, we use the
&lt;code&gt;org-read-date&lt;/code&gt; function. We also replace &lt;code&gt;CLOSED&amp;gt;=\&quot;&amp;lt;-7d&amp;gt;\&quot;&lt;/code&gt;
with &lt;code&gt;CLOSED&amp;gt;=\&quot;&amp;lt;%s&amp;gt;\&quot;&lt;/code&gt; with &lt;code&gt;%s&lt;/code&gt; being a placeholder for the
specified date. For more details on &lt;code&gt;org-read-date&lt;/code&gt;, read the
&lt;a href=&quot;https://orgmode.org/manual/The-date_002ftime-prompt.html&quot;&gt;official documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;org-agenda-overriding-header&lt;/code&gt; is slightly modified to display
the text &quot;Finished tasks since 2026-09-16&quot; if 16th September is
selected during the date prompt.&lt;/li&gt;
&lt;li&gt;We define a variable &lt;code&gt;pani/last-group-meeting-date&lt;/code&gt; which stores the
value of the date specified. Hence, before the custom org-agenda
view is called, it stores nothing i.e. &lt;code&gt;NIL&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
To invoke this view, we simply run &lt;code&gt;M-x org-agenda&lt;/code&gt; and hit &lt;code&gt;v&lt;/code&gt; to
get into the view.
&lt;/p&gt;
&lt;h3 id=&quot;invoking-custom-org-agenda-views-slightly-faster&quot;&gt;Invoking custom org-agenda views (slightly) faster&lt;/h3&gt;
&lt;p&gt;
Just like in the previous workflow, we write another function to invoke
this custom org-agenda view and bind it to &lt;code&gt;C-c v&lt;/code&gt; to invoke it faster.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;pani/done-items-since-meeting-org-agenda&lt;/span&gt; ()
    &lt;span class=&quot;org-doc&quot;&gt;&quot;Prompt for the date of the last group meeting and show completed tasks since then.
It displays every DONE item closed from the chosen day upto today.&quot;&lt;/span&gt;
    (&lt;span class=&quot;org-keyword&quot;&gt;interactive&lt;/span&gt;)
    (org-agenda nil &lt;span class=&quot;org-string&quot;&gt;&quot;v&quot;&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
When invoking the view, we are prompted for a date with a pop-up calendar.
We select a particular date in the past; Typing &quot;-wed&quot; to select last
Wednesday, we are instantly greeted with the following view:
&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/custom-org-agenda-view-since-date-pixelated.png&quot; alt=&quot;My custom org-agenda view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;
With this, we can review tasks not just from the last seven days, but
basically from any day in the past!
&lt;/p&gt;

&lt;div class=&quot;meta&quot;&gt;
Special thanks to &lt;a href=&quot;https://marci.gunyho.com&quot;&gt;Marci&lt;/a&gt; for pointing out typos.
&lt;/div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
I wish I could wake up on time in the morning during winters!
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/completed-org-items-since-date/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
My supervisor is a busy person, which unfortunately requires the
group meeting to be rescheduled sometimes, albeit infrequently.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/completed-org-items-since-date/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Home isn&#39;t home without you (my poem)</title>
    <published>2026-08-18T00:00:00+00:00</published>
    <updated>2026-08-18T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/home-feels-empty/"/>
    <id>https://ashishpanigrahi.com/blog/home-feels-empty/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/home-feels-empty/">&lt;blockquote&gt;
&lt;p&gt;
Home isn&#39;t home without you.&lt;br&gt;
The week we spent together quickly flew.&lt;br&gt;
I forgot what it meant to live alone.&lt;br&gt;
Only to feel it with gusto once you were gone.&lt;br&gt;
&lt;br&gt;
For a fleeting moment, it felt like my childhood days.&lt;br&gt;
If only, a little longer you could stay.&lt;br&gt;
The week felt both long and short.&lt;br&gt;
But the time spent with you was never for naught.&lt;br&gt;
&lt;br&gt;
How I wish I could turn back time.&lt;br&gt;
To relive that week again would be sublime.&lt;br&gt;
I will miss you when you&#39;re not here.&lt;br&gt;
But such is life, while I await my dear.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Reviewing finished tasks from last week in org-agenda and emacs</title>
    <published>2026-07-26T00:00:00+00:00</published>
    <updated>2026-08-12T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/done-items-org-agenda/"/>
    <id>https://ashishpanigrahi.com/blog/done-items-org-agenda/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/done-items-org-agenda/">&lt;p&gt;
Being a PhD student within a research group entails some structure to
tracking your progress as you proceed with research. Within the
current team that I&#39;m in, we have weekly group meetings where each
member presents the tasks that they&#39;ve completed during the previous
week and discusses any issues they might&#39;ve faced (if any), to our
supervisor.
&lt;/p&gt;

&lt;p&gt;
Usually before the meeting, I jot down things that I&#39;ve finished with
pen and paper. But since I&#39;m in the spirit of integrating my workflow
with emacs and orgmode, I thought why don&#39;t I try implementing this
part of my routine also into orgmode.
&lt;/p&gt;
&lt;h2 id=&quot;enter-org-agenda&quot;&gt;Enter org-agenda&lt;/h2&gt;
&lt;p&gt;
All my todo items are tracked with
&lt;a href=&quot;https://orgmode.org/manual/Agenda-Views.html&quot;&gt;org-agenda&lt;/a&gt; where I
capture every task I need to finish with
&lt;a href=&quot;https://orgmode.org/manual/Capture.html&quot;&gt;org-capture&lt;/a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
I have a custom org-agenda view just for viewing my daily and weekly
&lt;code&gt;TODO&lt;/code&gt; items, events/meetings scheduled at a certain time and tasks
that have a deadline associated with them. Suffice to say, this
workflow has replaced all my needs for having a calendar over the
cloud, be it Google, Outlook, what have you&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;. The only downside
that I haven&#39;t figured out (yet) is to incorporate calendar invites
that I receive via email, into my org-agenda automatically instead of
manually capturing an event into the agenda view.
&lt;/p&gt;

&lt;p&gt;
With this custom agenda view, as I finish tasks and mark them &lt;code&gt;DONE&lt;/code&gt;,
they disappear from the current view. This is by design. I figured I
could just review my completed tasks by visiting the relevant files
(&lt;code&gt;tasks.org&lt;/code&gt;, &lt;code&gt;meetings.org&lt;/code&gt;, etc. in my case). But who wants to sift
through all the completed tasks and filter them manually to only note
down the tasks completed during the previous week? Why not automate
this with the power of emacs?
&lt;/p&gt;
&lt;h2 id=&quot;elisp-snippet-that-implements-this-weekly-review&quot;&gt;Elisp snippet that implements this weekly review&lt;/h2&gt;
&lt;p&gt;
The idea is fairly simple. I&#39;d like to look at the tasks that I&#39;ve
completed since the last group meeting. This assumes I review these
tasks on the day of the group meeting (which I do currently&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;).
&lt;/p&gt;

&lt;p&gt;
We simply then instruct orgmode to filter out the &lt;code&gt;DONE&lt;/code&gt; items from
the last 7 days. The &lt;code&gt;org-agenda-custom-commands&lt;/code&gt; variable is what
we&#39;ll use to define this custom org-agenda view.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; org-agenda-custom-commands
      &#39;((&lt;span class=&quot;org-string&quot;&gt;&quot;w&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;Finished tasks from last week&quot;&lt;/span&gt; tags &lt;span class=&quot;org-string&quot;&gt;&quot;CLOSED&amp;gt;=\&quot;&amp;lt;-7d&amp;gt;\&quot;&quot;&lt;/span&gt;
         ((org-agenda-overriding-header &lt;span class=&quot;org-string&quot;&gt;&quot;Finished tasks from last week&quot;&lt;/span&gt;)
         (org-agenda-archives-mode t)
         (org-agenda-tag-filter-preset &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;-emacs&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;-personal&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;-email&quot;&lt;/span&gt;))
         (org-agenda-prefix-format &#39;((tags . &lt;span class=&quot;org-string&quot;&gt;&quot; &quot;&lt;/span&gt;)))
         (org-agenda-remove-tags nil)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Let&#39;s go over the various config options one by one:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first line defines the keybinding in the primary org-agenda
dashboard and the associated title for the keybinding.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tags &quot;CLOSED&amp;gt;=\&quot;&amp;lt;-7d&amp;gt;\&quot;&quot;&lt;/code&gt; is pretty self-explanatory. We filter for
items that were completed in the last 7 days.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-agenda-overriding-header&lt;/code&gt;: Simply defines the title of the
agenda view.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-agenda-archives-mode&lt;/code&gt;: This is set to &lt;code&gt;t&lt;/code&gt; (True) meaning to
also look at the archived entries from last week. I typically archive
my entries frequently so this is helpful.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-agenda-tag-filter-preset&lt;/code&gt;: I don&#39;t want personal tasks
appearing in this view, so I remove any items that have the relevant tags.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-agenda-prefix-format&lt;/code&gt;: By default, the agenda view contains
information about which file the entries belong to (in my case, it&#39;s
&lt;code&gt;tasks.org&lt;/code&gt;). This appears as &lt;code&gt;tasks:&lt;/code&gt; per entry in the agenda
which unnecessarily clutters the view.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org-agenda-remove-tags&lt;/code&gt;: I don&#39;t want to remove the tags of the
various entries (they are useful to me) that appear in the right
margin. Hence this variable is set to &lt;code&gt;nil&lt;/code&gt; (False).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
To invoke the view, we can simply run &lt;code&gt;M-x org-agenda&lt;/code&gt; and hit &lt;code&gt;w&lt;/code&gt; to
get into the view. My org-agenda dashboard looks like this:
&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/org-agenda-dashboard.png&quot; alt=&quot;My org-agenda dashboard&quot; /&gt;&lt;/p&gt;

&lt;p&gt;
All the above keys are present in the default view, except my custom
views (depicted by &lt;code&gt;j&lt;/code&gt; and &lt;code&gt;w&lt;/code&gt; keys).
&lt;/p&gt;
&lt;h3 id=&quot;invoking-custom-org-agenda-views-slightly-faster&quot;&gt;Invoking custom org-agenda views (slightly) faster&lt;/h3&gt;
&lt;p&gt;
For my workflow, I mostly deal with just the two org-agenda views
(represented by &lt;code&gt;j&lt;/code&gt; and &lt;code&gt;w&lt;/code&gt;). It&#39;s a good idea to have a global
keybinding to quickly invoke these views. Let&#39;s define the function
and keybinding for it.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;pani/done-items-prev-week-org-agenda&lt;/span&gt; ()
  &lt;span class=&quot;org-doc&quot;&gt;&quot;Custom function to immediately jump to my custom org-agenda view.&quot;&lt;/span&gt;
  (&lt;span class=&quot;org-keyword&quot;&gt;interactive&lt;/span&gt;)
  (org-agenda nil &lt;span class=&quot;org-string&quot;&gt;&quot;w&quot;&lt;/span&gt;))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
To invoke the function, we define the keybinding like via a
&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_mono/use-package.html&quot;&gt;use-package&lt;/a&gt;
macro:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;(&lt;span class=&quot;org-keyword&quot;&gt;use-package&lt;/span&gt; org-agenda
  &lt;span class=&quot;org-builtin&quot;&gt;:ensure&lt;/span&gt; nil
  &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Don&#39;t need to go through org-agenda template for custom agenda
&lt;/span&gt;  &lt;span class=&quot;org-builtin&quot;&gt;:bind&lt;/span&gt; (&lt;span class=&quot;org-builtin&quot;&gt;:map&lt;/span&gt; global-map
          (&lt;span class=&quot;org-string&quot;&gt;&quot;C-c w&quot;&lt;/span&gt; . pani/done-items-prev-week-org-agenda)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
I can then just hit &lt;code&gt;CTRL c w&lt;/code&gt; to bring up this new agenda view.
&lt;/p&gt;

&lt;p&gt;
That&#39;s it! This should make things easier for me during our group&#39;s
weekly meetings.
&lt;/p&gt;

&lt;div class=&quot;meta&quot;&gt;
Special thanks to &lt;a href=&quot;https://marci.gunyho.com&quot;&gt;Marci&lt;/a&gt; and my sister, Alaka Panigrahi for
pointing out grammatical errors and typos.
&lt;/div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
More on this in a future blog-post.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
This is fully offline. Between my personal laptop and office PC,
I simply use &lt;a href=&quot;https://syncthing.net&quot;&gt;syncthing&lt;/a&gt; to sync all my orgmode
files via peer-to-peer.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;
This is perhaps not the best approach but is a good enough starting
point for me.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/done-items-org-agenda/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Will you shed tears when I die? (my poem)</title>
    <published>2026-06-21T00:00:00+00:00</published>
    <updated>2026-06-21T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/will-you-shed-tears/"/>
    <id>https://ashishpanigrahi.com/blog/will-you-shed-tears/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/will-you-shed-tears/">&lt;blockquote&gt;
&lt;p&gt;
Will you shed tears when I die?&lt;br&gt;
I envisage on my bed as I lie.&lt;br&gt;
Whence comes such a thought in my mind?&lt;br&gt;
As I feel my life has come to a grind.&lt;br&gt;
&lt;br&gt;
Ups and downs make up any life.&lt;br&gt;
I console myself with such thought to be rife.&lt;br&gt;
But why do I feel such deject?&lt;br&gt;
My mind keeps circling as I introspect.&lt;br&gt;
&lt;br&gt;
Today I&#39;m here and tomorrow perhaps not.&lt;br&gt;
Such is the nature of life with fraught.&lt;br&gt;
Would you still care enough to cry?&lt;br&gt;
As I head over the horizon and say goodbye.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Setting up offline email for Microsoft O365 with notmuch and emacs</title>
    <published>2026-06-07T00:00:00+00:00</published>
    <updated>2026-08-01T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/o365-offline-email/"/>
    <id>https://ashishpanigrahi.com/blog/o365-offline-email/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/o365-offline-email/">&lt;p&gt;
Having to deal with Microsoft&#39;s outlook has been a growing pain with
my computing needs. Of course, this is pertinent only for work email.
For personal email, I use &lt;a href=&quot;https://migadu.com&quot;&gt;Migadu&lt;/a&gt; which has good
standards for email unlike Microsoft&#39;s.
&lt;/p&gt;

&lt;p&gt;
At work, I can only use either the official Outlook webmail or
Thunderbird since those are the only clients that are whitelisted by
the IT department at my university. Thunderbird is slightly better (it
has a few problems of its own but I digress) but I would like to have
an offline copy of all my emails, fully searchable with an indexed
database provided by &lt;a href=&quot;https://notmuchmail.org&quot;&gt;notmuch&lt;/a&gt;, which uses
the excellent &lt;a href=&quot;http://xapian.org/&quot;&gt;Xapian&lt;/a&gt; library for indexing.
Notmuch is shipped as an emacs package in the form of &lt;code&gt;notmuch.el&lt;/code&gt;,
which is exactly what I like given that I&#39;m moving most of my
computing needs into emacs&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
I&#39;ve taken inspiration from &lt;a href=&quot;https://www.cosroe.com/2025/04/neomutt-notmuch-mbsync.html&quot;&gt;Fergus&#39; excellent
blogpost&lt;/a&gt;
which implements the same in &lt;a href=&quot;https://neomutt.org/&quot;&gt;neomutt&lt;/a&gt;. The
initial setup process is identical to Fergus&#39; blogpost.
&lt;/p&gt;

&lt;p&gt;
It should be noted that notmuch is only a mail indexer. It does not
fetch mail, nor does it send mail. Those are handled by
&lt;a href=&quot;https://isync.sourceforge.io/&quot;&gt;isync&lt;/a&gt; and
&lt;a href=&quot;https://marlam.de/msmtp/&quot;&gt;msmtp&lt;/a&gt;, which are commandline programs.
&lt;/p&gt;
&lt;h2 id=&quot;access-authentication-with-o365&quot;&gt;Access authentication with O365&lt;/h2&gt;
&lt;p&gt;
Since Thunderbird is still allowed to access O365&#39;s authentication, we
will use the client ID provided from it (this is publicly
available from Thunderbird&#39;s source code)&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;. For authentication for
IMAP and SMTP, we will use
&lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xoauth/0b717658-4ceb-4401-9da9-7860c9ca2f2f?redirectedfrom=MSDN&quot;&gt;XOAUTH&lt;/a&gt;,
which is a &lt;em&gt;simple authentication and security layer&lt;/em&gt; (SASL) more
suited for email clients.
&lt;/p&gt;

&lt;p&gt;
Tools like isync rely on SASL for authentication, for which we&#39;ll
require an XOAUTH SASL plugin:
&lt;a href=&quot;https://github.com/moriyoshi/cyrus-sasl-xoauth2&quot;&gt;&lt;code&gt;https://github.com/moriyoshi/cyrus-sasl-xoauth2&lt;/code&gt;&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
If you&#39;re on Arch, then this plugin is installable from the AUR:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;paru -S cyrus-sasl-xoauth2-git&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
If not, then we can build it from source:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;git clone https://github.com/moriyoshi/cyrus-sasl-xoauth2
&lt;span class=&quot;org-builtin&quot;&gt;cd&lt;/span&gt; cyrus-sasl-xoauth2/
./autogen.sh   &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;checks for requirements
&lt;/span&gt;./configure    &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;configure (here we use the defaults)
&lt;/span&gt;make           &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;compile
&lt;/span&gt;sudo make install     &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;install for root user&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;token-generation-for-oauth&quot;&gt;Token generation for OAuth&lt;/h3&gt;
&lt;p&gt;
Microsoft has conditionally allowed API access to clients and the only
way to get access for any client is to register the application in
the Microsot Application portal, which is something only my org&#39;s IT
department can do&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;. Fortunately, we can use Thunderbird&#39;s
credentials to generate an access token for our purposes.
&lt;/p&gt;

&lt;p&gt;
Another issue that comes up is the finite lifetime of these access
tokens (typically an hour or two), which is cumbersome to generate
each time one needs to download email. Fortunately,
&lt;a href=&quot;http://www.mutt.org/&quot;&gt;mutt&lt;/a&gt; comes with
&lt;a href=&quot;https://github.com/muttmua/mutt/blob/master/contrib/mutt_oauth2.py&quot;&gt;&lt;code&gt;mutt_oauth2.py&lt;/code&gt;&lt;/a&gt;,
a script to help in the automatic renewal of this token. This script
helps in decrypting the token file and renewing it everytime it is
invoked.
&lt;/p&gt;

&lt;p&gt;
Fetching the initial token is fairly simple but before we do it, there
are certain changes that we need to do to &lt;code&gt;mutt_oauth2.py&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Look into the &lt;code&gt;ENCRYPTION_PIPE&lt;/code&gt; variable (line 48) and make sure to specify your
gpg key. If you don&#39;t have one, then generate one:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;gpg --full-generate-key&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Select the default options (ed25519 cypher if it allows) and make sure
that the expiration of the key is set to 0 (no expiration). This makes
your life easier but of course for security reasons, this is &lt;strong&gt;not a
good practice&lt;/strong&gt;.
&lt;/p&gt;

&lt;p&gt;
Bring up your public key:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;gpg --list-keys&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Copy the second line (after the &lt;code&gt;pub&lt;/code&gt; line) and paste it into
&lt;code&gt;mutt_oauth2.py&lt;/code&gt;
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-variable-name&quot;&gt;ENCRYPTION_PIPE&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;org-string&quot;&gt;&#39;gpg&#39;&lt;/span&gt;, &lt;span class=&quot;org-string&quot;&gt;&#39;--encrypt&#39;&lt;/span&gt;, &lt;span class=&quot;org-string&quot;&gt;&#39;--recipient&#39;&lt;/span&gt;, &lt;span class=&quot;org-string&quot;&gt;&#39;YOUR-GPG-KEY&#39;&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
After this, look at line 79. This includes a &lt;code&gt;client_id&lt;/code&gt; for
&lt;code&gt;microsoft&lt;/code&gt;. For Thunderbird, the client id is
&lt;code&gt;9e5f94bc-e8a4-4e73-b8be-63364c29d753&lt;/code&gt;. Leave the &lt;code&gt;client_secret&lt;/code&gt;
value as is. It should look like so:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-doc&quot;&gt;&#39;client_id&#39;&lt;/span&gt;: &lt;span class=&quot;org-doc&quot;&gt;&#39;9e5f94bc-e8a4-4e73-b8be-63364c29d753&#39;&lt;/span&gt;,
&lt;span class=&quot;org-doc&quot;&gt;&#39;client_secret&#39;&lt;/span&gt;: &lt;span class=&quot;org-doc&quot;&gt;&#39;&#39;&lt;/span&gt;,&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Now we are ready to generate the access token. Simply run:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;./mutt_oauth2.py OUTPUT_TOKEN_FILE --verbose --authorize&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
A series of prompts should appear. Select &lt;code&gt;microsoft&lt;/code&gt;,
&lt;code&gt;localhostauthcode&lt;/code&gt; (or &lt;code&gt;authcode&lt;/code&gt;), followed by your email address, after which you
should automatically be redirected to a browser for adding your
credentials for authentication. Doing so, should reveal the access
token in your terminal. No need to copy it, it is present in your
&lt;code&gt;OUTPUT_TOKEN_FILE&lt;/code&gt; which is encrypted. To obtain the decrypted token,
we run the script again with just the file name as an argument
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;./mutt_oauth2.py OUTPUT_TOKEN_FILE&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
A nice thing is that running this script with the token file also
checks for expiry and renews it if necessary. This can be done
multiple times without worry.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;UPDATE (2026-06-19)&lt;/strong&gt;: About 20 days after I set this up, for whatever reason the
token file expired on my personal laptop. I&#39;m not entirely sure what
happened but the fix for now was to regenerate the token again. I&#39;ll
need to debug the exact cause to prevent it from happening again.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;UPDATE (2026-07-29)&lt;/strong&gt;: It looks like this problem only appears on my
personal laptop as it&#39;s not an authorized device and as
such, 14 days is the maximum duration before which the token needs
to be reauthorized. My office PC is within this &quot;authorized&quot; devices
whitelist and thus doesn&#39;t need reauthentication after the initial setup.
&lt;/p&gt;
&lt;h2 id=&quot;offline-email-setup&quot;&gt;Offline email setup&lt;/h2&gt;
&lt;p&gt;
Now that we are done with the difficult part, we move onto setting up
isync (the binary is called &lt;code&gt;mbsync&lt;/code&gt;) which is available in most
distributions. This program basically downloads your emails offline
and synchronizes it with your email&#39;s remote IMAP servers. It supports
multiple accounts too. The program is configurable with a
&lt;code&gt;~/.mbsyncrc&lt;/code&gt; file&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-4-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;. I highly recommend reading the manual for it
via &lt;code&gt;man mbsync&lt;/code&gt;. Here&#39;s a starting template:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# -- Global defaults
# These will be applied to all accounts

# Create new mail in either location, so if the remote or local has mail
# and the other does not, then create it
Create Both
# never remote mail from either side
Remove None
# Remove messages marked for deletion from the local side on the
# remote. Do not ever delete local if marked for deletion in the
# remote. Prevents admins from deleting one&#39;s local mail
Expunge Far
Sync All
SyncState *
CopyArrivalDate yes
# No maximum number of messages
MaxMessages 0

# -- First email account
IMAPAccount university
Host outlook.office365.com
Port 993
User my-username@university.edu
AuthMechs XOAUTH2
PassCmd &quot;~/.local/bin/mutt_oauth2.py ~/.local/bin/TOKEN&quot;
# Use TLS
TLSType IMAPS
SystemCertificates yes
Timeout 10

# A store defines a collection of mailboxes, so we associate the
# remote IMAP mailbox with the account we just configured
IMAPStore university-remote
# Associate the store with our account
Account university

# Where are we going to keep the mail associated with this account
MaildirStore university-local
SubFolders Verbatim
Path ~/.local/share/mail/university/
Inbox ~/.local/share/mail/university/INBOX

# Channel to synchronize everything except &quot;Sent&quot; email
Channel uni-main
Far :university-remote:
Near :university-local:
# Which directories to synchronize
Patterns INBOX &quot;Deleted Items&quot; &quot;Drafts&quot;

# Channel to synchronize &quot;Sent&quot; email
Channel uni-sent
Far :university-remote:&quot;Sent Items&quot;
Near :university-local:Sent

# Group the two channels and sync everything with `mbsync NAME`
Group university
Channel uni-main
Channel uni-sent

# -- Second email account
IMAPAccount personal
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Once you have everything configured, we can start downloading all our
email by running:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;mbsync university&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
The first time &lt;code&gt;mbsync&lt;/code&gt; is run, it will take a fair amount of time,
since you&#39;ll be downloading a lot of email (assuming you&#39;ve been using
your account for a long time). The subsequent runs would be just
incremental downloads, so it&#39;s much faster.
&lt;/p&gt;

&lt;p&gt;
After navigating to your local Maildir directory
(&lt;code&gt;~/.local/share/mail/university&lt;/code&gt; in my case), you should see all your
emails downloaded and categorized into inbox, drafts, sent, and
deleted-items folders.
&lt;/p&gt;

&lt;p&gt;
A way to automate this to run a script periodically. I use
&lt;a href=&quot;https://wiki.archlinux.org/title/Systemd/Timers&quot;&gt;systemd-timers&lt;/a&gt;
where I have a script which is periodically run every 15 mins and
notifies me if there&#39;s new email (I&#39;ll cover this later in the blogpost).
&lt;/p&gt;
&lt;h2 id=&quot;sending-mail-via-smtp&quot;&gt;Sending mail via SMTP&lt;/h2&gt;
&lt;p&gt;
Sending email is done via &lt;a href=&quot;https://marlam.de/msmtp/&quot;&gt;&lt;code&gt;msmtp&lt;/code&gt;&lt;/a&gt;. It
is configured by editing &lt;code&gt;~/.msmtprc&lt;/code&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-5-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;defaults
auth on
tls on
tls_trust_file system
logfile ~/.cache/msmtp.log
timeout 10

# -- First account
account university
tls_starttls on
host smtp.office365.com
port 587
auth xoauth2
user my-username@university.edu
passwordeval &quot;~/.local/bin/mutt_oauth2.py ~/.local/bin/TOKEN&quot;
from my-username@university.edu

# -- Second account
account personal&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
This is fairly self-explanatory. One thing to note is that
&lt;code&gt;tls_starttls&lt;/code&gt; should be on for this to work. I&#39;m not very familiar
with email security protocols like TLS and STARTTLS but from my
understanding, STARTTLS is an automatic upgrade (if supported) from
the more insecure TLS protocol. TLS however needs to be enabled for
any email service, otherwise it won&#39;t work.
&lt;/p&gt;

&lt;p&gt;
Now, we can test our configuration by sending email directly from the
commandline. Save the contents of a file called &lt;code&gt;example-mail&lt;/code&gt; as follows:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;From: my-username@university.edu
To: user@example.com
Subject: Hello World

This is a test for msmtp.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
And send the email by running:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;cat example-mail | msmtp -t -a university&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;indexing-email-offline-with-notmuch&quot;&gt;Indexing email offline with notmuch&lt;/h2&gt;
&lt;p&gt;
We have receiving and sending email configured. How about reading and
&quot;using&quot; email via an email client. In more technical terms, an email
client is called a &lt;em&gt;mail user agent&lt;/em&gt; (MUA), which is typically seen in
email headers. This includes clients like Thunderbird, Apple mail,
neomutt, etc. We will configure &lt;code&gt;notmuch&lt;/code&gt; which indexes email and
provides an interface for emacs natively with notmuch.el.
&lt;/p&gt;

&lt;p&gt;
Notmuch is entirely tag based. Basic tags exist like &lt;em&gt;unread&lt;/em&gt;,
&lt;em&gt;inbox&lt;/em&gt;, &lt;em&gt;draft&lt;/em&gt;, &lt;em&gt;sent&lt;/em&gt; but you can customize it with more tags to
filter out emails from a particular email address, from a
particular range of date, etc. Tags are heavily used and it&#39;s a
different paradigm of handling email compared to your typical webmail
interface. I won&#39;t go over the details of tagging in notmuch here for
the sake of brevity (to be covered in another blogpost).
&lt;/p&gt;

&lt;p&gt;
When first setting up notmuch, simply run:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;notmuch setup&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
This will prompt you for basic information like your name, email address,
Maildir directory, etc. Once this is done, notmuch needs to index your
Maildir. Run the following:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;notmuch new&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
This should be fairly fast, even if your Maildir is big. Notmuch is
quick like that.
&lt;/p&gt;

&lt;p&gt;
Now you can search an email entry via &lt;code&gt;notmuch search&lt;/code&gt;. For example, I
can search emails from a particular sender like so:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;notmuch search &lt;span class=&quot;org-string&quot;&gt;&#39;from:friend@university.edu&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
I would again advise you to go through the man pages (&lt;code&gt;man notmuch-search&lt;/code&gt;) for more details.
&lt;/p&gt;
&lt;h3 id=&quot;emacs-setup-for-notmuch&quot;&gt;Emacs setup for notmuch&lt;/h3&gt;
&lt;p&gt;
Simply running &lt;code&gt;M-x notmuch&lt;/code&gt; should give you a hello screen, where you
can then select tags like &lt;em&gt;inbox&lt;/em&gt;, &lt;em&gt;unread&lt;/em&gt; to view their respective
email. I have a fairly customized config for notmuch.el but below I
provide a fairly good starting point for a more minimal notmuch
interface&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-6-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fn-6&quot;&gt;[6]&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Notmuch for email
&lt;/span&gt;(&lt;span class=&quot;org-keyword&quot;&gt;use-package&lt;/span&gt; notmuch
  &lt;span class=&quot;org-builtin&quot;&gt;:load-path&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;/usr/share/emacs/site-lisp/&quot;&lt;/span&gt;
  &lt;span class=&quot;org-builtin&quot;&gt;:ensure&lt;/span&gt; nil
  &lt;span class=&quot;org-builtin&quot;&gt;:defer&lt;/span&gt; t
  &lt;span class=&quot;org-builtin&quot;&gt;:commands&lt;/span&gt; (notmuch notmuch-mua-new-mail)
  &lt;span class=&quot;org-builtin&quot;&gt;:init&lt;/span&gt;
  &lt;span class=&quot;org-comment-delimiter&quot;&gt;;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Search
&lt;/span&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-search-oldest-first nil)
  &lt;span class=&quot;org-builtin&quot;&gt;:config&lt;/span&gt;
  &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;General UI
&lt;/span&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-logo nil
    notmuch-column-control 1.0
    notmuch-hello-auto-refresh t
    notmuch-hello-recent-searches-max 20
    notmuch-hello-thousands-separator &lt;span class=&quot;org-string&quot;&gt;&quot;&quot;&lt;/span&gt;
    notmuch-hello-sections &#39;(notmuch-hello-insert-saved-searches)
    notmuch-show-all-tags-list t)

  &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Search
&lt;/span&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-search-result-format
        &#39;((&lt;span class=&quot;org-string&quot;&gt;&quot;date&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%12s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;count&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%-7s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;authors&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%-20s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;subject&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%-80s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;tags&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;(%s)&quot;&lt;/span&gt;)))
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-tree-result-format
        &#39;((&lt;span class=&quot;org-string&quot;&gt;&quot;date&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%12s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;authors&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%-20s  &quot;&lt;/span&gt;)
          (((&lt;span class=&quot;org-string&quot;&gt;&quot;tree&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%s&quot;&lt;/span&gt;)
            (&lt;span class=&quot;org-string&quot;&gt;&quot;subject&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;%s&quot;&lt;/span&gt;))
           . &lt;span class=&quot;org-string&quot;&gt;&quot; %-80s  &quot;&lt;/span&gt;)
          (&lt;span class=&quot;org-string&quot;&gt;&quot;tags&quot;&lt;/span&gt; . &lt;span class=&quot;org-string&quot;&gt;&quot;(%s)&quot;&lt;/span&gt;)))
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-empty-saved-searches t)

  &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Tags
&lt;/span&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-archive-tags nil &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;I don&#39;t archive email
&lt;/span&gt;    notmuch-message-replied-tags &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;+replied&quot;&lt;/span&gt;)
    notmuch-message-forwarded-tags &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;+forwarded&quot;&lt;/span&gt;)
    notmuch-show-mark-read-tags &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;-unread&quot;&lt;/span&gt;)
    notmuch-draft-tags &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;+draft&quot;&lt;/span&gt;)
    notmuch-draft-folder &lt;span class=&quot;org-string&quot;&gt;&quot;university/Drafts&quot;&lt;/span&gt;
    notmuch-draft-save-plaintext &#39;ask)

  &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Email composition
&lt;/span&gt;  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-mua-compose-in &#39;new-window)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-mua-hidden-headers nil)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-address-command &#39;internal)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-address-use-company nil)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-always-prompt-for-sender t)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-mua-cite-function
    &#39;message-cite-original-without-signature)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-mua-user-agent-function nil)

  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-relative-dates t)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-all-multipart/alternative-parts nil)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-indent-messages-width 0)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-indent-multipart nil)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-show-part-button-default-action &#39;notmuch-show-view-part)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-wash-wrap-lines-length 120)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-unthreaded-show-out nil)
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-message-headers &#39;(&lt;span class=&quot;org-string&quot;&gt;&quot;To&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;Cc&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;Subject&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;Date&quot;&lt;/span&gt;))
  (&lt;span class=&quot;org-keyword&quot;&gt;setq&lt;/span&gt; notmuch-message-headers-visible t)

  &lt;span class=&quot;org-builtin&quot;&gt;:bind&lt;/span&gt;
  ( &lt;span class=&quot;org-builtin&quot;&gt;:map&lt;/span&gt; global-map
    (&lt;span class=&quot;org-string&quot;&gt;&quot;C-c m m&quot;&lt;/span&gt; . notmuch)
    (&lt;span class=&quot;org-string&quot;&gt;&quot;C-x m&quot;&lt;/span&gt; . notmuch-mua-new-mail) &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;override `&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;&lt;span class=&quot;org-constant&quot;&gt;compose-mail&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;&#39;
&lt;/span&gt;    &lt;span class=&quot;org-builtin&quot;&gt;:map&lt;/span&gt; notmuch-search-mode-map
    (&lt;span class=&quot;org-string&quot;&gt;&quot;/&quot;&lt;/span&gt; . notmuch-search-filter) &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;alias for l
&lt;/span&gt;    (&lt;span class=&quot;org-string&quot;&gt;&quot;r&quot;&lt;/span&gt; . notmuch-search-reply-to-thread) &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;easier to reply to all by default
&lt;/span&gt;    (&lt;span class=&quot;org-string&quot;&gt;&quot;R&quot;&lt;/span&gt; . notmuch-search-reply-to-thread-sender)
    &lt;span class=&quot;org-builtin&quot;&gt;:map&lt;/span&gt; notmuch-show-mode-map
    (&lt;span class=&quot;org-string&quot;&gt;&quot;r&quot;&lt;/span&gt; . notmuch-show-reply) &lt;span class=&quot;org-comment-delimiter&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;easier to reply to all by default
&lt;/span&gt;    (&lt;span class=&quot;org-string&quot;&gt;&quot;R&quot;&lt;/span&gt; . notmuch-show-reply-sender)
    &lt;span class=&quot;org-builtin&quot;&gt;:map&lt;/span&gt; notmuch-hello-mode-map
    (&lt;span class=&quot;org-string&quot;&gt;&quot;J&quot;&lt;/span&gt; . notmuch-jump-search)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
You&#39;re free to look at my
&lt;a href=&quot;https://github.com/paniash/dotemacs/blob/413f60cd2b152a581a6a8d5cb952b6fae318a5ba/init.el#L861&quot;&gt;&lt;code&gt;init.el&lt;/code&gt;&lt;/a&gt;
for my own customization for notmuch.el.
&lt;/p&gt;
&lt;h2 id=&quot;automating-email-synchronization-with-systemd-timers&quot;&gt;Automating email synchronization with systemd timers&lt;/h2&gt;
&lt;p&gt;
Let&#39;s automate the email sync to happen every 15 mins (or whatever
frequency you prefer). First we create a shell-script to download
email via &lt;code&gt;mbsync&lt;/code&gt; and also index the email with &lt;code&gt;notmuch&lt;/code&gt;. Let&#39;s name it
it &lt;code&gt;syncmail.sh&lt;/code&gt; and place it in &lt;code&gt;$HOME/.local/bin/&lt;/code&gt;.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;org-comment-delimiter&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;!/bin/&lt;/span&gt;&lt;span class=&quot;org-keyword&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;org-builtin&quot;&gt;set&lt;/span&gt; -eu

&lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;Set environment variable for notmuch config file
&lt;/span&gt;&lt;span class=&quot;org-builtin&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;org-variable-name&quot;&gt;NOTMUCH_CONFIG&lt;/span&gt;=&lt;span class=&quot;org-string&quot;&gt;&quot;$HOME/.config/notmuch/notmuch-config&quot;&lt;/span&gt;

mbsync university

&lt;span class=&quot;org-variable-name&quot;&gt;before&lt;/span&gt;=$(notmuch count --lastmod &lt;span class=&quot;org-string&quot;&gt;&#39;*&#39;&lt;/span&gt; | cut -f3)
notmuch new &amp;gt; /dev/null

&lt;span class=&quot;org-variable-name&quot;&gt;query&lt;/span&gt;=&lt;span class=&quot;org-string&quot;&gt;&quot;lastmod:$((before + 1)).. and path:university/**&quot;&lt;/span&gt;
&lt;span class=&quot;org-variable-name&quot;&gt;count&lt;/span&gt;=$(notmuch count &lt;span class=&quot;org-string&quot;&gt;&quot;$query&quot;&lt;/span&gt;)

&lt;span class=&quot;org-keyword&quot;&gt;if&lt;/span&gt; [ &lt;span class=&quot;org-string&quot;&gt;&quot;$count&quot;&lt;/span&gt; -gt 0 ]; &lt;span class=&quot;org-keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;org-variable-name&quot;&gt;body&lt;/span&gt;=$(notmuch search --format=json --limit=5 &lt;span class=&quot;org-string&quot;&gt;&quot;$query&quot;&lt;/span&gt; &lt;span class=&quot;org-sh-escaped-newline&quot;&gt;\&lt;/span&gt;
           | jq -r &lt;span class=&quot;org-string&quot;&gt;&#39;.[] | &quot;\(.authors): \(.subject)&quot;&#39;&lt;/span&gt;)
    notify-send &lt;span class=&quot;org-string&quot;&gt;&quot;New mail: $count&quot;&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;$body&quot;&lt;/span&gt;
&lt;span class=&quot;org-keyword&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
In addition to downloading email and indexing, the script also
notifies through &lt;code&gt;notify-send&lt;/code&gt; if there&#39;s new email along with a
sender and subject in the notification. Make sure to make the script
executable with
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;chmod +x ./syncmail.sh&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Then we write the systemd script to run this script periodically.
First we create a &lt;code&gt;syncmail.service&lt;/code&gt; file in &lt;code&gt;$HOME/.config/systemd/user/&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;conf&quot;&gt;[&lt;span class=&quot;org-type&quot;&gt;Unit&lt;/span&gt;]
&lt;span class=&quot;org-variable-name&quot;&gt;Description&lt;/span&gt;=Sync mail with mbsync and index with notmuch

[&lt;span class=&quot;org-type&quot;&gt;Service&lt;/span&gt;]
&lt;span class=&quot;org-variable-name&quot;&gt;Type&lt;/span&gt;=oneshot
&lt;span class=&quot;org-variable-name&quot;&gt;ExecStart&lt;/span&gt;=%h/.local/bin/syncmail.sh&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Then we create a timer file (make sure it is named &lt;code&gt;syncmail.timer&lt;/code&gt;) for actually running the script every &lt;code&gt;n&lt;/code&gt; minutes.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;conf&quot;&gt;[&lt;span class=&quot;org-type&quot;&gt;Unit&lt;/span&gt;]
&lt;span class=&quot;org-variable-name&quot;&gt;Description&lt;/span&gt;=Run syncmail every 15 minutes

[&lt;span class=&quot;org-type&quot;&gt;Timer&lt;/span&gt;]
&lt;span class=&quot;org-variable-name&quot;&gt;OnBootSec&lt;/span&gt;=2m
&lt;span class=&quot;org-variable-name&quot;&gt;OnUnitActiveSec&lt;/span&gt;=15m
&lt;span class=&quot;org-variable-name&quot;&gt;Persistent&lt;/span&gt;=true

[&lt;span class=&quot;org-type&quot;&gt;Install&lt;/span&gt;]
&lt;span class=&quot;org-variable-name&quot;&gt;WantedBy&lt;/span&gt;=timers.target&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
The advantage over cronjobs is that if your system is asleep or
shutdown, then booting up accomodates accordingly and runs the script
after &lt;code&gt;m&lt;/code&gt; minutes (2 minutes in my case).
&lt;/p&gt;

&lt;p&gt;
Finally we enable the script with &lt;code&gt;systemctl&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;systemctl --user daemon-reload
systemctl --user enable --now syncmail.timer&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;concluding-remarks&quot;&gt;Concluding remarks&lt;/h2&gt;
&lt;p&gt;
Now you should have a working setup for using offline email for
Microsoft&#39;s O365. This is fairly minimal but if you&#39;d like to have
encrypted emails, addressbooks, etc., please take a look at the
original &lt;a href=&quot;https://www.cosroe.com/2025/04/neomutt-notmuch-mbsync.html&quot;&gt;blogpost from
Fergus&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
A basic emailing etiquette I like to follow is to use plaintext as
opposed to html. &lt;a href=&quot;https://useplaintext.email/&quot;&gt;Read more&lt;/a&gt; on why this is better.
&lt;/p&gt;

&lt;div class=&quot;meta&quot;&gt;
Special thanks to &lt;a href=&quot;https://marci.gunyho.com&quot;&gt;Marci&lt;/a&gt; for
pointing out grammatical errors and typos.
&lt;/div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
It&#39;s like the old adage from Vi advocates, &quot;Emacs is a great
operating system, lacking only a decent text editor&quot;. Although the latter part I would disagree with.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
I just found out that Mozilla has made it very convoluted to
find the source code and build Thunderbird locally. It uses
mercurial instead of Git (in this day and age?). Relevant docs are &lt;a href=&quot;https://developer.thunderbird.net/thunderbird-development/building-thunderbird/linux-build-prerequisites&quot;&gt;here&lt;/a&gt;.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;
Even after asking countless times, they&#39;ve rejected my request
to include notmuch/emacs into the allowed clients list. Ah well, here
we are.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;
Personally, I dislike that my &lt;code&gt;$HOME&lt;/code&gt; directory gets cluttered
with config files that don&#39;t respect the &lt;a href=&quot;https://wiki.archlinux.org/title/XDG_Base_Directory&quot;&gt;XDG
specifications&lt;/a&gt;.
I set it to &lt;code&gt;$HOME/.config/mbsync/mbsyncrc&lt;/code&gt; by exporting the variable &lt;code&gt;MBSYNCRC&lt;/code&gt;.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-4-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;
Same issue with this. I fix it to be at &lt;code&gt;$HOME/.config/msmtp/config&lt;/code&gt;.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-5-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-6&quot;&gt;
&lt;p&gt;
The default interface is too noisy for me, so I disable a lot of the bells and whistles.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/o365-offline-email/#fr-6-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>New update for this website</title>
    <published>2026-05-26T00:00:00+00:00</published>
    <updated>2026-10-05T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/zola-website/"/>
    <id>https://ashishpanigrahi.com/blog/zola-website/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/zola-website/">&lt;p&gt;
It has been a while since I updated my website. Over the years, I&#39;ve
grown to like minimal yet aesthetic websites which comply with
legibility standards.
&lt;/p&gt;

&lt;p&gt;
Recently, I came across the excellent &lt;a href=&quot;https://bearblog.dev&quot;&gt;Bear blog&lt;/a&gt; and was enamored by
its simplistic yet appealing stylistic nature. I think it&#39;s a great
platform to get started with writing your own blog page. But anyway, I
was more interested in the stylesheet rather than the actual method of
publishing a website. After diving into this &lt;a href=&quot;https://bearblog.dev/discover/&quot;&gt;rabbit hole of various
bear blogs&lt;/a&gt;, I was pleased to come across the &lt;a href=&quot;https://robertbirming.com/bearming/&quot;&gt;Bearming theme&lt;/a&gt; made by
&lt;a href=&quot;https://robertbirming.com&quot;&gt;Robert Birming&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Along with this, comes &lt;a href=&quot;https://getzola.org&quot;&gt;Zola&lt;/a&gt; which is yet another static site
generator. For now, I&#39;ve become so accustomed to the boilerplate that
SSGs provide that it&#39;s hard to move onto something truly
minimal&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/zola-website/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. But like they say &lt;em&gt;perfectionism is the enemy of
progress&lt;/em&gt;, and so here&#39;s another attempt at updating my website more
frequently&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/zola-website/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
Now that the stylistic nature of this website is to my liking, I can
write more blogposts about things that interest me. Stay tuned!
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;UPDATE (2026-10-05)&lt;/strong&gt;: My website is now fully built with orgmode&#39;s
&lt;a href=&quot;https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html&quot;&gt;org-publish&lt;/a&gt; and emacs! Check out the &lt;a href=&quot;/blog/orgmode-website-update&quot;&gt;blogpost&lt;/a&gt;.
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
Hopefully I can move my entire website to being built by
&lt;a href=&quot;https://orgmode.org&quot;&gt;orgmode&lt;/a&gt; and &lt;a href=&quot;https://www.gnu.org/software/emacs/&quot;&gt;emacs&lt;/a&gt; some day.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/zola-website/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
Depending on how much free time I can get as a PhD student.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/zola-website/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Hope (my poem)</title>
    <published>2025-11-18T00:00:00+00:00</published>
    <updated>2025-11-18T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/hope/"/>
    <id>https://ashishpanigrahi.com/blog/hope/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/hope/">&lt;blockquote&gt;
&lt;p&gt;
A shining light in the tunnel of darkness.&lt;br&gt;
That&#39;s how I see hope, with a longingness.&lt;br&gt;
Sometimes good and sometimes bad,&lt;br&gt;
But somehow makes me glad.&lt;br&gt;
&lt;br&gt;
Is it hope that I&#39;m looking for?&lt;br&gt;
Like a drop of water, in a large desert outdoor.&lt;br&gt;
Is it just something made up?&lt;br&gt;
A lie told even after I slipup.&lt;br&gt;
&lt;br&gt;
Hope is a dangerous thing.&lt;br&gt;
The results can feel like a swing.&lt;br&gt;
But is it enough to justify my life?&lt;br&gt;
The way I&#39;m living, with so much strife.&lt;br&gt;
&lt;br&gt;
I keep clinging to this hope.&lt;br&gt;
Even with my life being a downward slope.&lt;br&gt;
Sometimes I fear it won&#39;t be there.&lt;br&gt;
At that point, would I still care?&lt;br&gt;
&lt;br&gt;
I find myself in an abyss.&lt;br&gt;
At times, devoid of any bliss.&lt;br&gt;
Hope is the only thing in my mind.&lt;br&gt;
Alas it is hard to see, perhaps I left it too far behind.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Bypassing the storage limit on Zotero with Syncthing</title>
    <published>2025-03-22T00:00:00+00:00</published>
    <updated>2025-03-22T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/zotero-pdf-sync/"/>
    <id>https://ashishpanigrahi.com/blog/zotero-pdf-sync/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/zotero-pdf-sync/">&lt;p&gt;
Recently, I found out about this neat little trick to bypass the
storage limit on &lt;a href=&quot;https://zotero.org&quot;&gt;Zotero&lt;/a&gt; for PDFs. Currently on
the &quot;free&quot; tier there is a limit of 300 MB which fills up pretty
quickly when you&#39;re doing serious research. This guide helps bypass
this limit (subject to your computer&#39;s storage).
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/zotero-storage-price.png&quot; style=width:55%&gt;
&lt;figcaption&gt;The current pricing model. Not bad but you don&#39;t need it
if it&#39;s just for personal use.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
The prices are there for if you&#39;d like to store associated PDFs on the
cloud and makes sense if two or more people would like to share the
same bibliography data. What this blogpost helps with is storing the files locally and
syncing them &lt;a href=&quot;https://en.wikipedia.org/wiki/Peer-to-peer&quot;&gt;peer-to-peer&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Best part is it&#39;s &lt;strong&gt;free&lt;/strong&gt;!
&lt;/p&gt;
&lt;h3 id=&quot;prior-situation&quot;&gt;Prior situation&lt;/h3&gt;
&lt;p&gt;
Usually if you&#39;re employed at a university/research institution, the
institute has a subscription to various journals. I would use this
with Zotero, strictly only storing the metadata and journal links and
opening them on the browser. The PDF can then be downloaded if you&#39;re
on the institute&#39;s intranet.
&lt;/p&gt;
&lt;h3 id=&quot;storage-location-for-pdfs&quot;&gt;Storage location for PDFs&lt;/h3&gt;
&lt;p&gt;
On Linux&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, by default I believe Zotero creates a directory
&lt;code&gt;~/Zotero/&lt;/code&gt; for storage of files, notes and metadata. I usually create
my own custom location for the directory, &lt;code&gt;~/.zotero/&lt;/code&gt; in this case as
I don&#39;t like having my home directory cluttered&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
To change this, go to &lt;strong&gt;Edit -&amp;gt; Settings -&amp;gt; Advanced&lt;/strong&gt; and under
&quot;&lt;strong&gt;Data Directory Location&lt;/strong&gt;&quot; you can specify a custom path.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/zotero-location.png&quot;&gt;
&lt;figcaption&gt;Dialog box for specifying custom location for Zotero directory.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
Now assuming you already have a sizeable zotero
database, we go to this location and are interested in the
&lt;code&gt;~/.zotero/storage&lt;/code&gt; folder. This is where the PDFs are stored.
&lt;/p&gt;
&lt;h4 id=&quot;changing-a-few-settings&quot;&gt;Changing a few settings&lt;/h4&gt;
&lt;p&gt;
Now, by default Zotero syncs all your files to the cloud. We don&#39;t
want that. To disable it, go to &lt;strong&gt;Edit -&amp;gt; Settings -&amp;gt; Sync&lt;/strong&gt; and under
&lt;strong&gt;File Syncing&lt;/strong&gt; uncheck both &quot;Sync attachment files in My Library&quot; and
&quot;Sync attachment files in group libraries using Zotero storage&quot;.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/zotero-syncing.png&quot;&gt;
&lt;figcaption&gt;Uncheck both the boxes.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
Now that we have unchecked the boxes, one can simply save the PDFs as
we like and use it on their computer. But what if we need to access
files on a different computer? That&#39;s where peer-to-peer syncing comes
in.
&lt;/p&gt;
&lt;h3 id=&quot;syncing-with-syncthing&quot;&gt;Syncing with Syncthing&lt;/h3&gt;
&lt;p&gt;
&lt;a href=&quot;https://syncthing.net&quot;&gt;Syncthing&lt;/a&gt; is an excellent piece of software.
As described on their website:
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
Syncthing is a &lt;strong&gt;continuous file synchronization&lt;/strong&gt; program.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Basically it helps sync files between different computers in a
peer-to-peer fashion.
&lt;/p&gt;
&lt;h3 id=&quot;quickstart-guide&quot;&gt;Quickstart guide&lt;/h3&gt;
&lt;p&gt;
I would highly recommend the &lt;a href=&quot;https://docs.syncthing.net/intro/getting-started.html&quot;&gt;official
user-guide&lt;/a&gt; for
using syncthing. However, the following covers a quick and brief guide
to getting syncing setup with Zotero.
&lt;/p&gt;

&lt;p&gt;
Launching &lt;code&gt;syncthing&lt;/code&gt; in a terminal opens up &lt;code&gt;localhost:8384&lt;/code&gt; on your
web browser and you&#39;re greeted with the GUI.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/syncthing-gui.png&quot; style=width:100%&gt;
&lt;figcaption&gt;Syncthing GUI&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
The GUI shows three components, two of which we are concerned with. On
the left are the folders that are synced. The right bottom section
consists of the devices to which certain folders are being synced. In
my case, I have the &lt;em&gt;zotero storage&lt;/em&gt; folder synced with my office PC
and some other folders synced with my Android phone.
&lt;/p&gt;

&lt;p&gt;
The &quot;Add Folder&quot; button is a good starting point. Clicking it leads us
to a dialog box asking for a &lt;em&gt;folder label&lt;/em&gt; and a &lt;em&gt;folder path&lt;/em&gt;. The
latter is important. For now, just ignore the &lt;em&gt;folder ID&lt;/em&gt; variable. It
is auto-generated by syncthing and is meant to let syncthing know
which folders to sync across different computers based on this ID.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/syncthing-add-folder.png&quot; style=width:90%&gt;
&lt;figcaption&gt;Adding folder for syncing.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
Now, just set the folder path to &lt;code&gt;~/.zotero/storage&lt;/code&gt; (or whatever is
the custom folder path you&#39;ve set in Zotero) and click save.
&lt;/p&gt;
&lt;h4 id=&quot;adding-remote-device&quot;&gt;Adding remote device&lt;/h4&gt;
&lt;p&gt;
On the secondary device that you&#39;d like to access your PDFs on (laptop
or perhaps a desktop at your office like me), then you need to launch
syncthing on the remote device and add it on your main computer by
clicking &quot;Add Remote Device&quot; at the bottom right corner in the GUI.
&lt;/p&gt;

&lt;p&gt;
The device can be added either via a device ID or via a QR-code, which
is accessible under the &quot;Actions&quot; tab and clicking &quot;Show ID&quot;.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/syncthing-add-device.png&quot; style=width:100%&gt;
&lt;figcaption&gt;Accessing QR code for current device.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
Follow similar instructions on the remote device for setting up a sync
folder (should be empty as for the first sync, we&#39;re really
transferring PDFs from the main device to the remote one). Make sure
to have the same path in your Zotero settings on the remote device!
&lt;/p&gt;

&lt;p&gt;
After adding the remote device, we need to share the folder we had set
with the remote device. To do this, simply go to the &lt;em&gt;zotero-storage&lt;/em&gt;
folder under the &quot;Folders&quot; section and click edit. This will bring up
a dialog box that we had previously edited. Under the &quot;Sharing&quot; tab,
check the box for the added remote device&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
And just hit save.
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/syncthing-share-folder.png&quot; style=width:90%&gt;
&lt;figcaption&gt;Sharing the folder with remote device.&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
If you have everything setup properly, the folder should get synced
across both the devices and you should be able to access the PDFs in
both these device! Of course, you can add more devices if you&#39;d like.
&lt;/p&gt;

&lt;p&gt;
I&#39;ve been extremely happy with this setup and I hope it&#39;s useful to
you as it has been for me. Thanks to my friend &lt;a href=&quot;https://marci.gunyho.com&quot;&gt;Marci&lt;/a&gt; who introduced me
to the idea.
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
This guide assumes you&#39;re using Linux but I see no reason why it
cannot be adapter for Windows and macOS.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
To actually keep your &lt;code&gt;~/&lt;/code&gt; uncluttered, the best approach would be
something along the lines of &lt;code&gt;~/.local/share/zotero&lt;/code&gt; which is
&lt;code&gt;XDG_DATA_HOME&lt;/code&gt; according to XDG standards.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;
Don&#39;t worry about the &quot;enter encryption password&quot;. You only need it if
you&#39;re concerned with security and would like to have encrypted
folders. I don&#39;t really care about that for zotero so I leave it unchecked.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/zotero-pdf-sync/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>When did I stop being a child? (my poem)</title>
    <published>2024-06-19T00:00:00+00:00</published>
    <updated>2024-06-19T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/when-did-i-become-an-adult/"/>
    <id>https://ashishpanigrahi.com/blog/when-did-i-become-an-adult/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/when-did-i-become-an-adult/">&lt;blockquote&gt;
&lt;p&gt;
When did I stop being a child?&lt;br&gt;
It&#39;s been so long, but I used to be quite beguiled.&lt;br&gt;
While I reminisce the days of not caring about the world.&lt;br&gt;
I wonder, when that child stopped being one, as an adult labelled.&lt;br&gt;
&lt;br&gt;
Perhaps it was when my interests changed.&lt;br&gt;
Things that I used to like, now feel estranged.&lt;br&gt;
Oh, how I wish I could go back to those simpler times.&lt;br&gt;
That child exists no more, but an adult begrimed.&lt;br&gt;
&lt;br&gt;
Carefree is the emotion I took for granted.&lt;br&gt;
Now that I&#39;m older, responsibilities have been handed.&lt;br&gt;
I remember a time when I used to run wild.&lt;br&gt;
Oh, but when did I stop being a child?&lt;br&gt;
&lt;br&gt;
As I grow old, my anxiety only becomes stronger.&lt;br&gt;
Is adulthood really supposed to be this way, with nothing more to offer?&lt;br&gt;
Alas, it is too late now to think about a time bygone.&lt;br&gt;
But the only way forward, is to look ahead and march into the unknown.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>What is my purpose (my poem)</title>
    <published>2024-04-21T00:00:00+00:00</published>
    <updated>2024-04-21T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/what-is-my-purpose/"/>
    <id>https://ashishpanigrahi.com/blog/what-is-my-purpose/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/what-is-my-purpose/">&lt;blockquote&gt;
&lt;p&gt;
What is my purpose but a tiny speck on this big blue dot?&lt;br&gt;
Is it already decided or do I get myself taught?&lt;br&gt;
I do wonder how the rest of my life shall continue.&lt;br&gt;
Will it be the same things I now pursue?&lt;br&gt;
&lt;br&gt;
Family it is for some people.&lt;br&gt;
For others, it is their career to excel.&lt;br&gt;
But does it matter in the end?&lt;br&gt;
Perhaps the greater reason is to make oneself enlighten.&lt;br&gt;
&lt;br&gt;
Often I find myself asking such questions.&lt;br&gt;
I keep looking for entities of substance&lt;br&gt;
in this rollercoaster that is life.&lt;br&gt;
What can I do to make it more rife?&lt;br&gt;
&lt;br&gt;
For far too long I&#39;ve been looking far away.&lt;br&gt;
Always fearing that my life might go astray.&lt;br&gt;
Is it deep down something more precious?&lt;br&gt;
Only to find myself asking, &quot;what is my purpose?&quot;.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Switching to GNU Emacs</title>
    <published>2024-04-14T00:00:00+00:00</published>
    <updated>2024-04-14T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/switching-to-emacs/"/>
    <id>https://ashishpanigrahi.com/blog/switching-to-emacs/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/switching-to-emacs/">&lt;p&gt;
Over the past five years, I&#39;ve been using &lt;a href=&quot;https://www.vim.org&quot;&gt;Vim&lt;/a&gt;
(well &lt;a href=&quot;https://neovim.io&quot;&gt;NeoVim&lt;/a&gt; specifically) for all of my text
editing needs ranging from tinkering with config files, shell scripts,
to writing this website, making LaTeX reports and theses, etc. The
paradigm of modal text editing that is Vim, just feels right. The user
communicates exactly how text needs to be edited. For instance: delete
all characters until a specific character appears? Done. Only delete
lines in the file that cover certain patterns? Built-in regex has you
covered! The point is, once you understand how modal editing works,
any other form of text editing feels like it&#39;s from the stone ages.
&lt;/p&gt;

&lt;p&gt;
Now you might ask, why am I switching to &lt;a href=&quot;https://www.gnu.org/software/emacs/&quot;&gt;GNU
Emacs&lt;/a&gt;, the opposing contender to
Vim in the well known &lt;a href=&quot;https://en.wikipedia.org/wiki/Editor_war&quot;&gt;editor
war&lt;/a&gt;? Well, the more &quot;silly&quot;
reason is that it gives me an opportunity to learn a new piece of
software, understand it&#39;s inner workings, etc. The more pragmatic
reason is that, like any rivalry, both sides have their pros and cons.
GNU Emacs presents itself as a truly hackable editor in any way the
user desires. This is thanks to the editor being written and
configured in &lt;a href=&quot;https://en.wikipedia.org/wiki/Emacs_Lisp&quot;&gt;Emacs lisp&lt;/a&gt;,
a dialect of the Lisp family of languages. Vim on the other hand is
written mostly in C but is configured in an obscure language that is
Vimscript. The advantage with Emacs lisp is that one can write not
only specific functions to help in any form of text editing and beyond
(one of the charms of Emacs) but also supplements more experienced
users in contributing to the core development of Emacs. This appeals
to me from a FOSS perspective as I truly believe that free software
development being run by volunteers should be tightly knit with its
user community. This helps not only in raising issues with the
software better but also in users contributing to the
development.
&lt;/p&gt;

&lt;p&gt;
This truly hackable experience, presented by Emacs also benefits in
the form of tasks that are not necessarily based around text-editing.
Thanks to the wonderful community, Emacs boasts a wide-range of
well-written packages such as &lt;a href=&quot;https://orgmode.org&quot;&gt;org-mode&lt;/a&gt; (Task
management system with a markup style of its own) and
&lt;a href=&quot;https://magit.vc/&quot;&gt;Magit&lt;/a&gt; (A Git porcelain inside Emacs). One of the
primary reasons I&#39;ve decided to switch is due to org-mode (which I
intend to cover in detail in subsequent blog entries).
&lt;/p&gt;

&lt;p&gt;
Some people might argue that Emacs goes against the UNIX philosophy of
minimalism and &quot;doing one thing right&quot;. Technically Emacs is
more of a Lisp environment than a text editor, or like the more famous
vim adage: &quot;Emacs is a great operating system, but it lacks a good
text editor&quot;. I cannot really comment here because I&#39;m still very new
to Emacs but the quote does hold some truth. Emacs (atleast from my
first impressions) has esoteric keybindings which are completely
foreign to new users let alone someone coming from a vim background.
&lt;code&gt;Ctrl&lt;/code&gt; and &lt;code&gt;Alt&lt;/code&gt; (known as &lt;code&gt;Meta&lt;/code&gt; in Emacs parlance) are the most
common keys which form part of the key-chord style of using emacs.
These keys obviously are placed at positions on a standard QWERTY
keyboard layout that when used frequently leads to the more infamous
&lt;a href=&quot;https://stackoverflow.com/questions/52492/what-is-the-best-way-to-avoid-getting-emacs-pinky&quot;&gt;Emacs
pinky&lt;/a&gt;
which is basically &lt;a href=&quot;https://en.wikipedia.org/wiki/Repetitive_strain_injury&quot;&gt;repetitive strain injury
(RSI)&lt;/a&gt;. For
this reason, I will be using emacs with
&lt;a href=&quot;https://github.com/emacs-evil/evil&quot;&gt;Evil&lt;/a&gt; which is the Vi-emulation
package in emacs, atleast until I get the hang of working with Emacs
before perhaps trying the stock keybindings (which apparently most of
the emacs community adheres to).
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/real_programmers.png&quot;&gt;
&lt;figcaption&gt;Relevant xkcd&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
For the next couple weeks I will try to steadily convert to using
Emacs and hopefully perform all of my computing needs with emacs in
the not-so-long future. This blog post is mainly for me to make this
commitment. As a first step, this blog entry is written entirely in Emacs.
&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Easy fix for F4 mute LED light on ThinkPad laptops on GNU/Linux</title>
    <published>2023-09-05T00:00:00+00:00</published>
    <updated>2023-09-05T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/thinkpad-micmute-led/"/>
    <id>https://ashishpanigrahi.com/blog/thinkpad-micmute-led/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/thinkpad-micmute-led/">&lt;p&gt;
Recently I purchased a ThinkPad E14 Gen 5 laptop after spending 5 years with my
previous workhorse machine, the HP Pavilion 14 with an Intel i5 (4 cores) CPU. The
upgrade is quite significant, coming with an eight core AMD Ryzen 7 CPU... but I
digress.
&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;/h3&gt;
&lt;p&gt;
With modern day laptops, often there are backlit keys on certain media keys like mute
sound, mute mic, airplane mode and so on. The light being switched on,
for obvious reasons indicates that the particular function is in
operation. This is easy on Windows for which these machines are always
tested against&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
Similarly, macOS works well on Apple devices. With GNU/Linux&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fn-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;
however, almost all machines work but the tiny quality of life
improvements like those media key lights can be a hit or miss.
&lt;/p&gt;

&lt;p&gt;
As usual, I went ahead and installed &lt;a href=&quot;https://archlinux.org&quot;&gt;Arch Linux&lt;/a&gt; on my
machine with &lt;a href=&quot;https://dwm.suckless.org&quot;&gt;dwm&lt;/a&gt; as my window manager. After the
installation and a test drive of my laptop, I see this...
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/thinkpad-micmute-led.jpg&quot;&gt;
&lt;figcaption&gt;The annoying led being always ON&lt;/figcaption&gt;
&lt;/center&gt;

&lt;p&gt;
At first I thought perhaps it&#39;s a driver issue but all my drivers were up-to-date.
Looking through the &lt;a href=&quot;https://wiki.archlinux.org&quot;&gt;Arch wiki&lt;/a&gt; didn&#39;t help with the
issue. Knowing the vibrant thinkpad community, I ended up posting about my problem on
&lt;a href=&quot;https://reddit.com/r/thinkpad&quot;&gt;r/thinkpad&lt;/a&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;simple-fix&quot;&gt;Simple Fix&lt;/h3&gt;
&lt;p&gt;
I&#39;d much rather have the backlight fully off than have it functional. So, a fellow
redditor let me know to check for the output in a particular system file:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;~: $ cat /sys/class/leds/platform::micmute/brightness
1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
&#39;1&#39; here represents the light in the ON state, which is exactly the problem!
&lt;del&gt;Changing the value to &#39;0&#39; in the file instantly fixes the problem!&lt;/del&gt;
Changing it to &#39;0&#39; only fixes it temporarily until the next time the machine is
booted up. A rather simple &quot;hack&quot; is to make this change every time the user logs into
the machine. This is done simply through the &lt;code&gt;.xprofile&lt;/code&gt; or &lt;code&gt;.xinitrc&lt;/code&gt; file
(most people would use &lt;code&gt;.xinitrc&lt;/code&gt;) by adding the following line in said file:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;org-builtin&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;org-string&quot;&gt;&quot;0&quot;&lt;/span&gt; &amp;gt; /sys/class/leds/platform::micmute/brightness&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
This line simply replaces whatever the file previously had, with &#39;0&#39;. This works
rather well until I find a more permanent solution.
&lt;/p&gt;
&lt;h3 id=&quot;edit&quot;&gt;Edit&lt;/h3&gt;
&lt;p&gt;
Unfortunately, the above method doesn&#39;t work anymore. I&#39;m not exactly sure what changed but
apparently it isn&#39;t supposed to work in the first place simply because &lt;code&gt;/sys/class/leds/platform::micmute/brightness&lt;/code&gt; isn&#39;t a real directory.
&lt;/p&gt;

&lt;p&gt;
In any case, here&#39;s an updated method for the same that is slightly more involved. It
is adapted for any Linux distribution running systemd. For other init systems
(openrc, runit, etc.), I assume it&#39;s fairly simply to make the relevant changes.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a shell script &lt;code&gt;disable-mute.sh&lt;/code&gt; in your preferred directory
(&lt;code&gt;~/.local/bin/&lt;/code&gt; in my case) containing the following:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;org-comment-delimiter&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;!/bin/&lt;/span&gt;&lt;span class=&quot;org-keyword&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;org-builtin&quot;&gt;echo&lt;/span&gt; 0 | tee /sys/class/leds/platform::micmute/brightness&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;With root privileges, create a file &lt;code&gt;disable-mute.service&lt;/code&gt; in
&lt;code&gt;/etc/systemd/system/&lt;/code&gt; with the following content&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fn-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code&gt;[Unit]
Description=Disables the annoying mute light on keyboard
After=multi-user.target

[Service]
ExecStart=/bin/sh /home/ashish/.local/bin/disable-mute.sh
Type=simple

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;Simply run &lt;code&gt;sudo systemctl enable disable-mute.service&lt;/code&gt; and the LED should turn off
the next time you boot up your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;strong&gt;Late 2024 Update&lt;/strong&gt;: This method works so far for the 6.6-LTS Kernel,
NOT the bleeding edge one.
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;
The travesty being that laptop manufacturers being the profit
oriented businesses that they are, cater to the masses which
unfortunately sides with malicious, proprietary garbage like Windows.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;
Technically Linux is the kernel and not the operating system (the rest
is supplied by the GNU operating system sans its own kernel).
&lt;a href=&quot;https://www.gnu.org/gnu/why-gnu-linux.html&quot;&gt;Here&lt;/a&gt; is a better
explanation.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fr-2-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;
See &lt;a href=&quot;https://linuxhandbook.com/create-systemd-services/&quot;&gt;here&lt;/a&gt;
for a detailed tutorial on writing systemd service files.
 &lt;a href=&quot;https://ashishpanigrahi.com/blog/thinkpad-micmute-led/#fr-3-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Hello, World in Qiskit</title>
    <published>2021-07-16T00:00:00+00:00</published>
    <updated>2021-07-16T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/qiskit-hello-world/"/>
    <id>https://ashishpanigrahi.com/blog/qiskit-hello-world/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/qiskit-hello-world/">&lt;p&gt;
Qiskit is a python SDK for simulating and running quantum algorithms on real quantum
computers. As mentioned on &lt;a href=&quot;https://qiskit.org/&quot;&gt;qiskit.org&lt;/a&gt;:
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
Qiskit [kiss-kit] is an open-source SDK for working with quantum computers at the
level of pulses, circuits and application modules.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
I plan on writing a series of tutorials on getting started with quantum computing
using qiskit, as I learn as well. Like any other programming tutorial, we start with
a simple &quot;Hello, world&quot; program.
&lt;/p&gt;
&lt;h2 id=&quot;measuring-a-quantum-state&quot;&gt;Measuring a quantum state&lt;/h2&gt;
&lt;p&gt;
With conventional computers, the simplest program that one could perhaps make is
printing out &quot;hello, world&quot;. However, in contrast to this, in quantum systems, we go
ahead and measure a quantum state (this seems to be the most rudimentary but complete
program in quantum terms). Let&#39;s proceed to do just that!
&lt;/p&gt;
&lt;h3 id=&quot;defining-a-quantum-state&quot;&gt;Defining a quantum state&lt;/h3&gt;
&lt;p&gt;
We import the necessary modules from Qiskit for this operation. To define a quantum
circuit, we require the classes &lt;code&gt;QuantumCircuit&lt;/code&gt;, &lt;code&gt;QuantumRegister&lt;/code&gt;,
&lt;code&gt;ClassicalRegister&lt;/code&gt; and define a state variable &lt;code&gt;psi&lt;/code&gt; as
&lt;/p&gt;

&lt;p&gt;
\[ | \psi \rangle = \frac{1}{\sqrt{2}} \begin{pmatrix} 1\\ 1 \end{pmatrix} \]
&lt;/p&gt;

&lt;p&gt;
Notice that the state \(| \psi \rangle\) is normalized. This is important, otherwise we&#39;ll end up with an error.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-keyword&quot;&gt;from&lt;/span&gt; qiskit &lt;span class=&quot;org-keyword&quot;&gt;import&lt;/span&gt; QuantumCircuit, QuantumRegister, ClassicalRegister
&lt;span class=&quot;org-keyword&quot;&gt;from&lt;/span&gt; math &lt;span class=&quot;org-keyword&quot;&gt;import&lt;/span&gt; sqrt

&lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;define an initial state
&lt;/span&gt;&lt;span class=&quot;org-variable-name&quot;&gt;psi&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; [1&lt;span class=&quot;org-operator&quot;&gt;/&lt;/span&gt;sqrt(2), 1&lt;span class=&quot;org-operator&quot;&gt;/&lt;/span&gt;sqrt(2)]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
We then define a function &lt;code&gt;prepare()&lt;/code&gt; which takes two parameters: a &lt;code&gt;QuantumCircuit&lt;/code&gt;
object named &lt;code&gt;qc&lt;/code&gt; and the initial state &lt;code&gt;psi&lt;/code&gt;. Remember that the quantum circuit that
we define, only uses 1 qubit (notice the vector representation of \(| \psi \rangle\)).
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;org-function-name&quot;&gt;prepare&lt;/span&gt;(qc, psi):
    qc.initialize(psi, [0])     &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;[0] indicates the zeroth index (or) the first qubit&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Python by default, calls by reference, so we don&#39;t have to worry about returning
anything from &lt;code&gt;prepare()&lt;/code&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;building-a-quantum-circuit&quot;&gt;Building a quantum circuit&lt;/h3&gt;
&lt;p&gt;
Let&#39;s proceed with making an actual quantum circuit. For this, we define a
&lt;code&gt;QuantumRegister&lt;/code&gt; object &lt;code&gt;qr&lt;/code&gt;, which stores the qubits and a &lt;code&gt;ClassicalRegister&lt;/code&gt;
object &lt;code&gt;cr&lt;/code&gt; which stores the measured values of those qubits.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-variable-name&quot;&gt;qr&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; QuantumRegister(1)
&lt;span class=&quot;org-variable-name&quot;&gt;cr&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; ClassicalRegister(1)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Combining the two registers, we now make a quantum circuit:
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-variable-name&quot;&gt;qc&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; QuantumCircuit(qr, cr)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;initializing-and-measuring-the-qubit&quot;&gt;Initializing and measuring the qubit&lt;/h3&gt;
&lt;p&gt;
We then call our function &lt;code&gt;prepare()&lt;/code&gt; to initialize the first qubit (the only qubit)
of our quantum circuit &lt;code&gt;qc&lt;/code&gt;.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;prepare(qc, psi)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
How do we go about measuring our state? That&#39;s where the &lt;code&gt;ClassicalRegister&lt;/code&gt; object
&lt;code&gt;cr&lt;/code&gt; comes in. We use the &lt;code&gt;measure&lt;/code&gt; method under the &lt;code&gt;qc&lt;/code&gt; object to actually measure
the qubit.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;qc.measure(qr[0], cr[0])&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
The above syntax generally means that we&#39;re measuring the state of &lt;code&gt;qr[0]&lt;/code&gt; (the first
qubit) onto the classical register &lt;code&gt;cr[0]&lt;/code&gt; where we store the measured value.
&lt;/p&gt;
&lt;h2 id=&quot;visualizing-the-circuit&quot;&gt;Visualizing the circuit&lt;/h2&gt;
&lt;p&gt;
Ok so all of this is nice, but one can only describe so much. Let&#39;s see how our
circuit actually looks like after applying the above operations. For this, we use the
&lt;code&gt;draw()&lt;/code&gt; method with the &lt;code&gt;matplotlib&lt;/code&gt; backend.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-operator&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; qc.draw(output&lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;org-string&quot;&gt;&#39;mpl&#39;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;center&gt;
    &lt;img src=&quot;/images/qc.png&quot; style=&quot;width:50%&quot;&gt;
&lt;/center&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;choosing-a-backend-for-measurement&quot;&gt;Choosing a backend for measurement&lt;/h2&gt;
&lt;p&gt;
To measure the qubit and store the result in the classical register &lt;code&gt;cr&lt;/code&gt;, we use the
&lt;code&gt;qasm_simulator&lt;/code&gt; backend. As we know from basic quantum mechanics,
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-keyword&quot;&gt;from&lt;/span&gt; qiskit &lt;span class=&quot;org-keyword&quot;&gt;import&lt;/span&gt; Aer
&lt;span class=&quot;org-variable-name&quot;&gt;backend&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; Aer.get_backend(&lt;span class=&quot;org-string&quot;&gt;&#39;qasm_simulator&#39;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
We then transpile our circuit for the &lt;code&gt;qasm_simulator&lt;/code&gt; backend to understand and
execute the circuit.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-keyword&quot;&gt;from&lt;/span&gt; qiskit &lt;span class=&quot;org-keyword&quot;&gt;import&lt;/span&gt; transpile
&lt;span class=&quot;org-variable-name&quot;&gt;qc_compiled&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; transpile(qc, backend)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Now, we simply execute the circuit and gather the measurement results.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-variable-name&quot;&gt;job&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; backend.run(qc_compiled, shots&lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt;1024)  &lt;span class=&quot;org-comment-delimiter&quot;&gt;# &lt;/span&gt;&lt;span class=&quot;org-comment&quot;&gt;shots is the number of times we run the experiment
&lt;/span&gt;&lt;span class=&quot;org-variable-name&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; job.result()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
We store the value of the &lt;code&gt;result&lt;/code&gt; object and can further access the number of times we end up with a certain value of expected outcome with the &lt;code&gt;get_counts()&lt;/code&gt; method.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-variable-name&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;org-operator&quot;&gt;=&lt;/span&gt; results.get_counts(qc_compiled)
&lt;span class=&quot;org-builtin&quot;&gt;print&lt;/span&gt;(counts)&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;{&#39;0&#39;: 518, &#39;1&#39;: 506}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Here we end up with a dictionary of key values &lt;code&gt;&#39;0&#39;&lt;/code&gt; and &lt;code&gt;&#39;1&#39;&lt;/code&gt;, which indicate the following quantum states:
&lt;/p&gt;

&lt;p&gt;
\[ | 0 \rangle = \begin{pmatrix} 1\\ 0 \end{pmatrix} \qquad | 1 \rangle = \begin{pmatrix} 0\\ 1 \end{pmatrix} \]
&lt;/p&gt;

&lt;p&gt;
As expected, we get a 50-50 distribution of the states \(|0\rangle\) and \(|1\rangle\),
since our starting state was \(|\psi\rangle\). We can also calculate this probability
via the inner-product,
&lt;/p&gt;

&lt;p&gt;
\[ |\langle 0 | \psi \rangle|^2 = \frac{1}{2} \qquad |\langle 1 | \psi \rangle|^2 = \frac{1}{2} \]
&lt;/p&gt;

&lt;p&gt;
Let&#39;s visualize this in the form of a histogram. For this, we import the
&lt;code&gt;plot_histogram&lt;/code&gt; function.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;org-operator&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;org-keyword&quot;&gt;from&lt;/span&gt; qiskit.visualization &lt;span class=&quot;org-keyword&quot;&gt;import&lt;/span&gt; plot_histogram
&lt;span class=&quot;org-operator&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; plot_histogram(counts)&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;center&gt;
    &lt;img src=&quot;/images/histogram.png&quot; style=&quot;width:80%&quot;&gt;
&lt;/center&gt;
&lt;/figure&gt;

&lt;p&gt;
You can find the entire script in this
&lt;a href=&quot;https://gist.github.com/paniash/52497bf574ea4570ce5f0a21fa093b12&quot;&gt;gist&lt;/a&gt;.
&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Font Rendering in Firefox</title>
    <published>2021-05-30T00:00:00+00:00</published>
    <updated>2021-05-30T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/firefox-fonts/"/>
    <id>https://ashishpanigrahi.com/blog/firefox-fonts/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/firefox-fonts/">&lt;p&gt;
If you&#39;re on a *nix system and compare the fonts on chrome and firefox, you&#39;d notice
the difference. The fonts on the latter just look... &lt;em&gt;off&lt;/em&gt;, or atleast that was the
case on my system.
&lt;/p&gt;
&lt;h2 id=&quot;my-personal-odyssey&quot;&gt;My personal odyssey&lt;/h2&gt;
&lt;p&gt;
Recently I had made the switch from firefox to brave, for the naive reason that fonts
were just rendered better (and LaTeX looks like it) on it (being a chromium based
browser). However, I really missed the customizability and other nifty features of
firefox. It just felt like home. I knew for sure that I&#39;m missing something, because
surely firefox couldn&#39;t be responsible for messing fonts, right? (atleast I hoped).
&lt;/p&gt;

&lt;p&gt;
On firefox, you may have come across the font settings that look something like this:
&lt;/p&gt;

&lt;center&gt;
&lt;img src=&quot;/images/firefox-font.png&quot;&gt;
&lt;/center&gt;

&lt;p&gt;
My past self would unselect the option &lt;em&gt;&lt;strong&gt;Allow pages to choose their own fonts,
instead of your selections above&lt;/strong&gt;&lt;/em&gt;, just so that I can have my custom fonts
rendered. But oh boy, would that turn out disastrous to say the least. I visit a good
number of websites that render math equations in TeX, but with this setting turned
off, LaTeX looked more like some flunky &#39;90s PC trying to render math.
&lt;/p&gt;

&lt;p&gt;
What was the fix you might ask? Well, just select the option that I had unselected
earlier. But this would bring that the atrocious fonts back on many websites.
&lt;/p&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;/h2&gt;
&lt;p&gt;
I later came across
&lt;a href=&quot;https://nolanlawson.com/2020/05/02/customizing-fonts-in-firefox-on-linux/&quot;&gt;this&lt;/a&gt;
blog post where I got to know that firefox depends on an OS-level font configuration
called &lt;a href=&quot;https://wiki.archlinux.org/title/Font_configuration&quot;&gt;fontconfig&lt;/a&gt; and is
located at &lt;code&gt;~/.config/fontconfig/fonts.conf&lt;/code&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;create-a-fontconfig-file&quot;&gt;Create a fontconfig file&lt;/h3&gt;
&lt;p&gt;
If you don&#39;t have one, just create it at the specific location.
&lt;/p&gt;

&lt;pre&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;org-nxml-processing-instruction-delimiter&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;org-nxml-processing-instruction-target&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;org-nxml-processing-instruction-content&quot;&gt;version=&#39;1.0&#39;&lt;/span&gt;&lt;span class=&quot;org-nxml-processing-instruction-delimiter&quot;&gt;?&amp;gt;&lt;/span&gt;
&amp;lt;!&lt;span class=&quot;org-nxml-text&quot;&gt;DOCTYPE fontconfig SYSTEM &#39;fonts.dtd&#39;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;fontconfig&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;Helvetica&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;IBM Plex Sans&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;sans-serif&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;IBM Plex Sans&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;monospace&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;org-nxml-text&quot;&gt;DejaVu Sans Mono&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;prefer&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-slash&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;org-nxml-element-local-name&quot;&gt;fontconfig&lt;/span&gt;&lt;span class=&quot;org-nxml-tag-delimiter&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
A lot of websites these days use Helvetica as their serif font, and firefox will
fallback to a specific font if Helvetica is not found. By default, this fallback
seems to be Nimbus Sans, which is not pretty to say the least. This is where
fontconfig comes in.
&lt;/p&gt;

&lt;p&gt;
The above XML file tells firefox that, &quot;Hey! If you&#39;re trying to render Helvetica,
just use IBM Plex Sans&quot;, and similar font rules for sans-serif and monospace fonts.
&lt;/p&gt;
&lt;h3 id=&quot;the-result&quot;&gt;The result&lt;/h3&gt;
&lt;figure&gt;
&lt;center&gt;
    &lt;img src=&quot;/images/oldfonts.png&quot; style=&quot;width:100%&quot;&gt;
    &lt;figcaption&gt;Daniel&lt;/figcaption&gt;
    &lt;br&gt;&lt;/br&gt;
    &lt;img src=&quot;/images/newfonts.png&quot; style=&quot;width:100%&quot;&gt;
    &lt;figcaption&gt;The cooler Daniel&lt;/figcaption&gt;
&lt;/center&gt;
&lt;/figure&gt;

&lt;p&gt;
I was really happy when I came across this fix! and I hope this has helped you as
well.
&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="en">
    <title>Intro to Public-key Cryptography</title>
    <published>2020-07-20T00:00:00+00:00</published>
    <updated>2020-07-20T00:00:00+00:00</updated>
    <author><name>Ashish Panigrahi</name></author>
    <link rel="alternate" type="text/html" href="https://ashishpanigrahi.com/blog/cryptography-intro/"/>
    <id>https://ashishpanigrahi.com/blog/cryptography-intro/</id>
    <content type="html" xml:base="https://ashishpanigrahi.com/blog/cryptography-intro/">&lt;p&gt;
We have all heard fancy jargon like &quot;encryption&quot;, &quot;cryptography&quot; and what not, but
what do these terms actually mean? In this article, I attempt to give you a brief
introduction to the world of cryptography and how in particular, public-key
cryptography, a popular means of encryption works.
&lt;/p&gt;

&lt;p&gt;
In layman terms, &lt;a href=&quot;https://en.wikipedia.org/wiki/Cryptography&quot;&gt;&lt;em&gt;cryptography&lt;/em&gt;&lt;/a&gt; is the
study of securing messages between two parties without a third party knowing what the
message is. &lt;a href=&quot;https://en.wikipedia.org/wiki/Encryption&quot;&gt;&lt;em&gt;Encryption&lt;/em&gt;&lt;/a&gt; is the process
of securing these messages.
&lt;/p&gt;

&lt;p&gt;
Think of encryption as a process which is easy to do in one direction but rather
difficult to do in reverse. One such example is &lt;strong&gt;colour mixing&lt;/strong&gt;. One can mix
various colours and make a mixture out of it. However, if you ask another person, it
would be &lt;em&gt;almost&lt;/em&gt; impossible to tell the constituent colours from the mixture.
&lt;/p&gt;
&lt;h2 id=&quot;the-barebones-method-symmetric-encryption&quot;&gt;The barebones method - symmetric encryption&lt;/h2&gt;
&lt;p&gt;
The most basic and easy to understand method is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Symmetric-key_algorithm&quot;&gt;symmetric
encryption&lt;/a&gt; method. It
basically involves the following: Alice, who wants to send a message; Bob, who
receives the message; and a secret key used to encrypt the message (essentially
turning the message into gibberish).
&lt;/p&gt;

&lt;p&gt;
Alice has a message, encrypts the message using the secret key, sends the message.
Bob now decrypts the message using the same secret key and reads the message. This
way during the process when the message is sent, even if a third party gets a hold of
the message; they cannot read the message since they do not have the secret key.
&lt;/p&gt;
&lt;h3 id=&quot;caveats&quot;&gt;Caveats&lt;/h3&gt;
&lt;p&gt;
The above method has a major flaw, which is that both the parties must have a common
key. That means that the key to be used for encryption must be decided upon by the
two parties beforehand. So the two parties have to meet at a place or send the key to
the other through some means which isn&#39;t secure, unless one encrypts this key
information which requires another key.
&lt;/p&gt;
&lt;h2 id=&quot;a-better-method-asymmetric-encryption&quot;&gt;A better method - asymmetric encryption&lt;/h2&gt;
&lt;p&gt;
Asymmetric encryption AKA &lt;a href=&quot;https://en.wikipedia.org/wiki/Public-key_cryptography&quot;&gt;&lt;em&gt;public-key
cryptography&lt;/em&gt;&lt;/a&gt; involves the
same scenario as that of symmetric encryption, the only difference being that instead
of one secret key, two keys are used (called a &lt;em&gt;key pair&lt;/em&gt;). Let them be &lt;em&gt;key A&lt;/em&gt; and
&lt;em&gt;key B&lt;/em&gt;.
&lt;/p&gt;

&lt;p&gt;
Let us use the same scenario as before: Alice wishes to send a message; she encrypts
it with &lt;em&gt;key A&lt;/em&gt; and sends it to Bob; he receives it and decrypts it using &lt;em&gt;key B&lt;/em&gt;.
Note that there was no exchange regarding the information of the keys themselves.
&lt;em&gt;Key A&lt;/em&gt; cannot be guessed from &lt;em&gt;key B&lt;/em&gt; and vice-versa however they are linked in such
a way that a message encrypted with &lt;em&gt;key A&lt;/em&gt; can only be decrypted with &lt;em&gt;key B&lt;/em&gt; and a
message encrypted with &lt;em&gt;key B&lt;/em&gt; can only be decrypted with &lt;em&gt;key A&lt;/em&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;real-world-implications&quot;&gt;Real-world implications&lt;/h3&gt;
&lt;p&gt;
When using asymmetric encryption, a key-pair is generated i.e. a &lt;em&gt;public&lt;/em&gt; key and a
&lt;em&gt;private&lt;/em&gt; key.
&lt;/p&gt;

&lt;p&gt;
The public key is made public (who knew!) and is published everywhere, on websites,
posters and so on. The private key is kept to yourself. Any messages intended for you
could be then encrypted using your public-key that only you can decrypt since you
have the private-key.
&lt;/p&gt;

&lt;p&gt;
What about the other way round? You could encrypt a message that you wish to send,
using your private-key. But then you might ask, why should I encrypt a message that
can be decrypted using my public-key since anyone can decrypt the message? (since
you&#39;ve made your public-key, public)
&lt;/p&gt;
&lt;h3 id=&quot;signature-algorithms&quot;&gt;Signature algorithms&lt;/h3&gt;
&lt;p&gt;
By encrypting the message using your private-key, one can know that the message is
authentic since it can be decrypted using your public-key meaning, it must have been
encrypted using your private-key which only you have access to.
&lt;/p&gt;
&lt;h3 id=&quot;a-proper-communication&quot;&gt;A proper communication&lt;/h3&gt;
&lt;p&gt;
So the best way to communicate using this protocol would be as follows: Alice has a
key-pair and Bob has a key-pair. Alice wishes to send a message; she encrypts it
using her private-key &lt;em&gt;ensuring that the message is authentic&lt;/em&gt; and then encrypts it
again using Bob&#39;s public key &lt;em&gt;ensuring that only Bob can read the message&lt;/em&gt;. Bob upon
receiving the gibberish decrypts it using his private-key and then once again using
Alice&#39;s public-key establishing a secure channel for communication.
&lt;/p&gt;

&lt;p&gt;
Note that in this method no keys were exchanged, in fact, Alice and Bob might not
have even met before and this method still works. Isn&#39;t that amazing?
&lt;/p&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;
I understand that I have over-simplified things. This post is only meant to get a
brief overview of encryption. For a better understanding refer the &lt;strong&gt;Crypto 101&lt;/strong&gt;
textbook linked below.
&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;
This post was inspired by the book, &lt;a href=&quot;https://www.crypto101.io&quot;&gt;Crypto 101&lt;/a&gt; by Laurens
Van Houtven and this &lt;a href=&quot;https://www.youtube.com/watch?v=GSIDS_lvRv4&quot;&gt;video&lt;/a&gt; from the
YouTube channel &lt;a href=&quot;https://www.youtube.com/user/Computerphile&quot;&gt;Computerphile&lt;/a&gt; where Dr.
Robert Miles explains about public-key encryption.
&lt;/p&gt;

&lt;p&gt;
Lastly, I would like to end this post with a quote from Bruce Schneier:
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files.
&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
</feed>
