<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>软件onDocs</title><link>https://hiraethecho.github.io/docs/software/</link><description>Recent contentin软件onDocs</description><generator>Hugo --0.152.2</generator><language>en</language><managingEditor>wyz2016zxc@outlook.com(Hiraeth)</managingEditor><webMaster>wyz2016zxc@outlook.com(Hiraeth)</webMaster><atom:link href="https://hiraethecho.github.io/docs/software/index.xml" rel="self" type="application/rss+xml"/><item><title>latex基本概念</title><link>https://hiraethecho.github.io/docs/software/latex/</link><pubDate>Mon, 25 Aug 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/latex/</guid><description>&lt;h1 id="latex概览"&gt;
&lt;a class="anchor inpage" href="#latex%e6%a6%82%e8%a7%88"&gt;#&lt;/a&gt;latex概览&lt;/h1&gt;
&lt;h2 id="tex-和-latex"&gt;
&lt;a class="anchor inpage" href="#tex-%e5%92%8c-latex"&gt;##&lt;/a&gt;tex 和 latex&lt;/h2&gt;
&lt;h3 id="1-tex底层排版引擎"&gt;
&lt;a class="anchor inpage" href="#1-tex%e5%ba%95%e5%b1%82%e6%8e%92%e7%89%88%e5%bc%95%e6%93%8e"&gt;###&lt;/a&gt;&lt;strong&gt;1. TeX：底层排版引擎&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作者&lt;/strong&gt;：Donald Knuth（高德纳）开发，1978 年发布。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定位&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;是一个&lt;strong&gt;底层的排版编程语言&lt;/strong&gt;，提供精确的排版控制（如盒模型、断行算法、数学公式布局等）。&lt;/li&gt;
&lt;li&gt;语法类似编程（需手动处理格式细节），适合专业人士或极客。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;直接操作命令（如 &lt;code&gt;\hbox&lt;/code&gt;, &lt;code&gt;\vskip&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;默认生成 &lt;code&gt;.dvi&lt;/code&gt; 文件（需转换为 PDF/PS）。&lt;/li&gt;
&lt;li&gt;无预定义的高层结构（如章节、目录需手动实现）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;示例（纯 TeX 代码）&lt;/strong&gt;：&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="latex概览">
  <a class="anchor inpage" href="#latex%e6%a6%82%e8%a7%88">#</a>latex概览</h1>
<h2 id="tex-和-latex">
  <a class="anchor inpage" href="#tex-%e5%92%8c-latex">##</a>tex 和 latex</h2>
<h3 id="1-tex底层排版引擎">
  <a class="anchor inpage" href="#1-tex%e5%ba%95%e5%b1%82%e6%8e%92%e7%89%88%e5%bc%95%e6%93%8e">###</a><strong>1. TeX：底层排版引擎</strong></h3>
<ul>
<li><strong>作者</strong>：Donald Knuth（高德纳）开发，1978 年发布。</li>
<li><strong>定位</strong>：
<ul>
<li>是一个<strong>底层的排版编程语言</strong>，提供精确的排版控制（如盒模型、断行算法、数学公式布局等）。</li>
<li>语法类似编程（需手动处理格式细节），适合专业人士或极客。</li>
</ul>
</li>
<li><strong>特点</strong>：
<ul>
<li>直接操作命令（如 <code>\hbox</code>, <code>\vskip</code>）。</li>
<li>默认生成 <code>.dvi</code> 文件（需转换为 PDF/PS）。</li>
<li>无预定义的高层结构（如章节、目录需手动实现）。</li>
</ul>
</li>
</ul>
<p><strong>示例（纯 TeX 代码）</strong>：</p>
<details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span><span style="color:#66d9ef">\font\myfont</span>=cmr12 at 14pt
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\myfont</span> Hello, <span style="color:#66d9ef">\TeX</span>!
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\bye</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="2-latex基于-tex-的高级封装">
  <a class="anchor inpage" href="#2-latex%e5%9f%ba%e4%ba%8e-tex-%e7%9a%84%e9%ab%98%e7%ba%a7%e5%b0%81%e8%a3%85">###</a><strong>2. LaTeX：基于 TeX 的高级封装</strong></h3>
<ul>
<li><strong>作者</strong>：Leslie Lamport（莱斯利·兰波特）开发，1984 年发布。</li>
<li><strong>定位</strong>：
<ul>
<li>是 <strong>TeX 的宏包集合</strong>（一组预定义的命令和模板），提供<strong>文档逻辑结构</strong>（如章节、参考文献、交叉引用）。</li>
<li>隐藏了 TeX 的底层复杂性，用户只需关注内容。</li>
</ul>
</li>
<li><strong>特点</strong>：
<ul>
<li>提供标准文档类（如 <code>article</code>, <code>book</code>）。</li>
<li>内置自动化功能（目录、编号、参考文献管理）。</li>
<li>依赖宏包扩展功能（如 <code>graphicx</code> 插入图片、<code>amsmath</code> 增强数学公式）。</li>
</ul>
</li>
</ul>
<p><strong>示例（LaTeX 代码）</strong>：</p>
<details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span><span style="color:#66d9ef">\documentclass</span>{article}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\begin</span>{document}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\section</span>{Introduction}
</span></span><span style="display:flex;"><span>Hello, <span style="color:#66d9ef">\LaTeX</span>!
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\end</span>{document}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="核心区别">
  <a class="anchor inpage" href="#%e6%a0%b8%e5%bf%83%e5%8c%ba%e5%88%ab">###</a><strong>核心区别</strong></h3>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th>TeX</th>
          <th>LaTeX</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>设计目标</strong></td>
          <td>底层排版控制</td>
          <td>高层文档结构</td>
      </tr>
      <tr>
          <td><strong>语法复杂度</strong></td>
          <td>复杂（类似编程）</td>
          <td>简单（声明式）</td>
      </tr>
      <tr>
          <td><strong>典型用户</strong></td>
          <td>排版系统开发者、极客</td>
          <td>学术作者、普通用户</td>
      </tr>
      <tr>
          <td><strong>扩展性</strong></td>
          <td>需手动实现一切</td>
          <td>通过宏包（如 <code>hyperref</code>）扩展</td>
      </tr>
      <tr>
          <td><strong>默认输出</strong></td>
          <td><code>.dvi</code></td>
          <td><code>.dvi</code> 或 <code>.pdf</code>（现代工具链）</td>
      </tr>
  </tbody>
</table>
<h3 id="类比解释">
  <a class="anchor inpage" href="#%e7%b1%bb%e6%af%94%e8%a7%a3%e9%87%8a">###</a><strong>类比解释</strong></h3>
<ul>
<li><strong>TeX 类似汇编语言</strong>：
<ul>
<li>直接控制硬件（排版细节），但编写复杂。</li>
</ul>
</li>
<li><strong>LaTeX 类似高级语言（如 Python）</strong>：
<ul>
<li>通过抽象（如 <code>\section</code>）隐藏细节，提升效率。</li>
</ul>
</li>
</ul>
<h3 id="技术关系">
  <a class="anchor inpage" href="#%e6%8a%80%e6%9c%af%e5%85%b3%e7%b3%bb">###</a><strong>技术关系</strong></h3>
<ul>
<li>LaTeX 本质是一组 TeX 宏（<code>.sty</code> 文件），最终仍由 TeX 引擎（如 <code>pdftex</code>, <code>xetex</code>, <code>luatex</code>）执行。</li>
<li>编译流程示例：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>latex document.tex   <span style="color:#75715e"># 调用 pdftex 引擎处理 LaTeX 宏</span>
</span></span><span style="display:flex;"><span>xelatex document.tex <span style="color:#75715e"># 调用 xetex 引擎处理 LaTeX 宏</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="总结">
  <a class="anchor inpage" href="#%e6%80%bb%e7%bb%93">###</a><strong>总结</strong></h3>
<ul>
<li><strong>TeX 是引擎，LaTeX 是模板</strong>。</li>
<li>LaTeX 让用户摆脱 TeX 的底层复杂性，专注于内容逻辑。</li>
<li>现代用户通常直接使用 <code>pdflatex</code>/<code>xelatex</code>/<code>lualatex</code>，无需接触原始 TeX 命令。</li>
</ul>
<p>如果需要进一步解释某个具体细节（如宏包机制或引擎差异），可以继续讨论！</p>
<h2 id="引擎和使用">
  <a class="anchor inpage" href="#%e5%bc%95%e6%93%8e%e5%92%8c%e4%bd%bf%e7%94%a8">##</a>引擎和使用</h2>
<h3 id="1-排版引擎engines">
  <a class="anchor inpage" href="#1-%e6%8e%92%e7%89%88%e5%bc%95%e6%93%8eengines">###</a><strong>1. 排版引擎（Engines）</strong></h3>
<p>引擎是实际执行排版工作的底层程序，负责解析代码、计算布局并生成输出文件（如 PDF/DVI）。<br>
<strong>属于引擎的有</strong>：</p>
<ul>
<li><code>tex</code>：Knuth 原始 TeX 引擎（生成 <code>.dvi</code>）。</li>
<li><code>pdftex</code>：扩展的 TeX 引擎，直接生成 PDF（<code>pdflatex</code> 的基础）。</li>
<li><code>xetex</code>（XeTeX）：支持 Unicode 和系统字体的引擎（<code>xelatex</code> 的基础）。</li>
<li><code>luatex</code>（LuaTeX）：内嵌 Lua 脚本的引擎（<code>lualatex</code> 的基础）。</li>
</ul>
<h3 id="2-模板格式formats">
  <a class="anchor inpage" href="#2-%e6%a8%a1%e6%9d%bf%e6%a0%bc%e5%bc%8fformats">###</a><strong>2. 模板/格式（Formats）</strong></h3>
<p>格式是基于引擎的预定义命令集合（宏包），提供高层抽象，简化用户操作。<br>
<strong>属于格式的有</strong>：</p>
<ul>
<li><code>latex</code>：LaTeX 格式（运行在 <code>pdftex</code>/<code>xetex</code>/<code>luatex</code> 等引擎上）。
<ul>
<li>不是独立引擎，而是通过 <code>latex</code> 命令调用引擎（如 <code>pdftex + LaTeX 宏</code> → <code>pdflatex</code>）。</li>
</ul>
</li>
<li><code>plain tex</code>：Knuth 提供的极简格式（比原始 TeX 稍友好，但远不如 LaTeX）。</li>
<li><code>contex</code>：另一种高级格式（基于 LuaTeX，适合复杂排版）。</li>
</ul>
<h3 id="3-前端命令frontends">
  <a class="anchor inpage" href="#3-%e5%89%8d%e7%ab%af%e5%91%bd%e4%bb%a4frontends">###</a><strong>3. 前端命令（Frontends）</strong></h3>
<p>用户直接调用的命令，本质是 <strong>“引擎 + 格式” 的组合</strong>：</p>
<table>
  <thead>
      <tr>
          <th>命令</th>
          <th>实际调用</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>latex</code></td>
          <td><code>pdftex + LaTeX 格式</code></td>
          <td>传统 LaTeX（DVI 输出）。</td>
      </tr>
      <tr>
          <td><code>pdflatex</code></td>
          <td><code>pdftex + LaTeX 格式</code></td>
          <td>直接生成 PDF（无 Unicode 支持）。</td>
      </tr>
      <tr>
          <td><code>xelatex</code></td>
          <td><code>xetex + LaTeX 格式</code></td>
          <td>支持 Unicode 和系统字体。</td>
      </tr>
      <tr>
          <td><code>lualatex</code></td>
          <td><code>luatex + LaTeX 格式</code></td>
          <td>支持 Lua 脚本和现代字体。</td>
      </tr>
  </tbody>
</table>
<h3 id="关键区分">
  <a class="anchor inpage" href="#%e5%85%b3%e9%94%ae%e5%8c%ba%e5%88%86">###</a><strong>关键区分</strong></h3>
<ul>
<li><strong>引擎</strong>：<code>tex</code>, <code>pdftex</code>, <code>xetex</code>, <code>luatex</code>（核心执行者）。</li>
<li><strong>格式</strong>：<code>latex</code>, <code>plain tex</code>, <code>contex</code>（定义高级命令的规则）。</li>
<li><strong>前端命令</strong>：<code>latex</code>, <code>pdflatex</code>, <code>xelatex</code>, <code>lualatex</code>（组合引擎和格式的快捷方式）。</li>
</ul>
<h3 id="常见误解澄清">
  <a class="anchor inpage" href="#%e5%b8%b8%e8%a7%81%e8%af%af%e8%a7%a3%e6%be%84%e6%b8%85">###</a><strong>常见误解澄清</strong></h3>
<ol>
<li><strong><code>latex</code> 不是引擎</strong>：
<ul>
<li>它是 LaTeX 格式通过 <code>pdftex</code> 引擎运行的接口（命令）。</li>
</ul>
</li>
<li><strong><code>pdflatex</code> vs <code>pdftex</code></strong>：
<ul>
<li><code>pdftex</code> 是引擎，<code>pdflatex</code> = <code>pdftex</code> + LaTeX 格式。</li>
</ul>
</li>
</ol>
<hr>
<h2 id="引擎engines">
  <a class="anchor inpage" href="#%e5%bc%95%e6%93%8eengines">##</a>引擎（Engines）</h2>
<h3 id="基础引擎">
  <a class="anchor inpage" href="#%e5%9f%ba%e7%a1%80%e5%bc%95%e6%93%8e">###</a>基础引擎</h3>
<table>
  <thead>
      <tr>
          <th>引擎名称</th>
          <th>特点</th>
          <th>输出格式</th>
          <th>主要用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>tex</strong></td>
          <td>Knuth原始引擎，底层控制</td>
          <td>.dvi</td>
          <td>历史兼容、底层排版开发</td>
      </tr>
      <tr>
          <td><strong>pdftex</strong></td>
          <td>TeX的扩展，直接PDF输出</td>
          <td>.pdf</td>
          <td>传统LaTeX文档排版</td>
      </tr>
      <tr>
          <td><strong>xetex</strong> (XeTeX)</td>
          <td>支持Unicode和系统字体</td>
          <td>.xdv/.pdf</td>
          <td>多语言排版、系统字体支持</td>
      </tr>
      <tr>
          <td><strong>luatex</strong> (LuaTeX)</td>
          <td>内嵌Lua解释器，动态脚本</td>
          <td>.pdf</td>
          <td>复杂排版、自动化处理</td>
      </tr>
  </tbody>
</table>
<h3 id="引擎特性对比">
  <a class="anchor inpage" href="#%e5%bc%95%e6%93%8e%e7%89%b9%e6%80%a7%e5%af%b9%e6%af%94">###</a>引擎特性对比</h3>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th>tex</th>
          <th>pdftex</th>
          <th>xetex</th>
          <th>luatex</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Unicode支持</td>
          <td>❌</td>
          <td>❌</td>
          <td>✔️</td>
          <td>✔️</td>
      </tr>
      <tr>
          <td>OpenType字体</td>
          <td>❌</td>
          <td>❌</td>
          <td>✔️</td>
          <td>✔️</td>
      </tr>
      <tr>
          <td>Lua脚本</td>
          <td>❌</td>
          <td>❌</td>
          <td>❌</td>
          <td>✔️</td>
      </tr>
      <tr>
          <td>系统字体</td>
          <td>❌</td>
          <td>❌</td>
          <td>✔️</td>
          <td>✔️</td>
      </tr>
      <tr>
          <td>输出格式</td>
          <td>DVI</td>
          <td>PDF</td>
          <td>XDV/PDF</td>
          <td>PDF</td>
      </tr>
  </tbody>
</table>
<h2 id="格式formats">
  <a class="anchor inpage" href="#%e6%a0%bc%e5%bc%8fformats">##</a>格式（Formats）</h2>
<h3 id="主要格式">
  <a class="anchor inpage" href="#%e4%b8%bb%e8%a6%81%e6%a0%bc%e5%bc%8f">###</a>主要格式</h3>
<table>
  <thead>
      <tr>
          <th>格式名称</th>
          <th>基于引擎</th>
          <th>特点</th>
          <th>适用场景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>plain tex</strong></td>
          <td>tex</td>
          <td>Knuth提供的极简格式</td>
          <td>底层TeX编程</td>
      </tr>
      <tr>
          <td><strong>latex</strong></td>
          <td>多引擎</td>
          <td>高级文档结构，宏包丰富</td>
          <td>学术论文、书籍、报告</td>
      </tr>
      <tr>
          <td><strong>contex</strong></td>
          <td>luatex</td>
          <td>模块化设计，强大功能</td>
          <td>复杂排版、图形密集型文档</td>
      </tr>
  </tbody>
</table>
<h2 id="前端命令frontend-commands">
  <a class="anchor inpage" href="#%e5%89%8d%e7%ab%af%e5%91%bd%e4%bb%a4frontend-commands">##</a>前端命令（Frontend Commands）</h2>
<h3 id="常用命令组合">
  <a class="anchor inpage" href="#%e5%b8%b8%e7%94%a8%e5%91%bd%e4%bb%a4%e7%bb%84%e5%90%88">###</a>常用命令组合</h3>
<table>
  <thead>
      <tr>
          <th>命令</th>
          <th>实际组成</th>
          <th>输出格式</th>
          <th>特点</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>tex</code></td>
          <td>tex + plain tex</td>
          <td>.dvi</td>
          <td>原始TeX排版</td>
      </tr>
      <tr>
          <td><code>latex</code></td>
          <td>pdftex + latex格式</td>
          <td>.dvi</td>
          <td>传统LaTeX处理</td>
      </tr>
      <tr>
          <td><code>pdflatex</code></td>
          <td>pdftex + latex格式</td>
          <td>.pdf</td>
          <td>直接PDF输出</td>
      </tr>
      <tr>
          <td><code>xelatex</code></td>
          <td>xetex + latex格式</td>
          <td>.pdf</td>
          <td>Unicode和字体支持</td>
      </tr>
      <tr>
          <td><code>lualatex</code></td>
          <td>luatex + latex格式</td>
          <td>.pdf</td>
          <td>Lua脚本+现代特性</td>
      </tr>
  </tbody>
</table>
<h2 id="文件格式">
  <a class="anchor inpage" href="#%e6%96%87%e4%bb%b6%e6%a0%bc%e5%bc%8f">##</a>文件格式</h2>
<h3 id="输入文件类型">
  <a class="anchor inpage" href="#%e8%be%93%e5%85%a5%e6%96%87%e4%bb%b6%e7%b1%bb%e5%9e%8b">###</a>输入文件类型</h3>
<table>
  <thead>
      <tr>
          <th>扩展名</th>
          <th>类型</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>.tex</code></td>
          <td>源文件</td>
          <td>TeX/LaTeX源代码</td>
      </tr>
      <tr>
          <td><code>.sty</code></td>
          <td>宏包文件</td>
          <td>LaTeX功能扩展包</td>
      </tr>
      <tr>
          <td><code>.cls</code></td>
          <td>文档类</td>
          <td>文档类型定义</td>
      </tr>
      <tr>
          <td><code>.bib</code></td>
          <td>参考文献</td>
          <td>BibTeX数据库文件</td>
      </tr>
  </tbody>
</table>
<h3 id="输出文件类型">
  <a class="anchor inpage" href="#%e8%be%93%e5%87%ba%e6%96%87%e4%bb%b6%e7%b1%bb%e5%9e%8b">###</a>输出文件类型</h3>
<table>
  <thead>
      <tr>
          <th>扩展名</th>
          <th>生成工具</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>.dvi</code></td>
          <td>tex/latex</td>
          <td>设备无关文件</td>
      </tr>
      <tr>
          <td><code>.pdf</code></td>
          <td>pdflatex/xelatex/lualatex</td>
          <td>便携文档格式</td>
      </tr>
      <tr>
          <td><code>.xdv</code></td>
          <td>xetex</td>
          <td>扩展DVI格式</td>
      </tr>
      <tr>
          <td><code>.aux</code></td>
          <td>所有引擎</td>
          <td>辅助信息文件</td>
      </tr>
      <tr>
          <td><code>.log</code></td>
          <td>所有引擎</td>
          <td>编译日志文件</td>
      </tr>
  </tbody>
</table>
<h2 id="工具链组件">
  <a class="anchor inpage" href="#%e5%b7%a5%e5%85%b7%e9%93%be%e7%bb%84%e4%bb%b6">##</a>工具链组件</h2>
<h3 id="核心工具">
  <a class="anchor inpage" href="#%e6%a0%b8%e5%bf%83%e5%b7%a5%e5%85%b7">###</a>核心工具</h3>
<table>
  <thead>
      <tr>
          <th>工具名称</th>
          <th>用途</th>
          <th>示例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>texlua</strong></td>
          <td>Lua解释器</td>
          <td>运行TeX相关Lua脚本</td>
      </tr>
      <tr>
          <td><strong>kpsewhich</strong></td>
          <td>文件查找</td>
          <td>定位TeX文件位置</td>
      </tr>
      <tr>
          <td><strong>bibtex</strong></td>
          <td>参考文献处理</td>
          <td>生成参考文献列表</td>
      </tr>
      <tr>
          <td><strong>makeindex</strong></td>
          <td>索引生成</td>
          <td>创建文档索引</td>
      </tr>
  </tbody>
</table>
<h3 id="编译工具链">
  <a class="anchor inpage" href="#%e7%bc%96%e8%af%91%e5%b7%a5%e5%85%b7%e9%93%be">###</a>编译工具链</h3>
<pre class="mermaid">graph TD
    A[.tex源文件] --&gt; B{选择引擎}
    B --&gt; C[pdflatex]
    B --&gt; D[xelatex]
    B --&gt; E[lualatex]

    C --&gt; F[生成PDF]
    D --&gt; F
    E --&gt; F

    subgraph &#34;可选处理&#34;
        G[.bib文件] --&gt; H[bibtex]
        I[.idx文件] --&gt; J[makeindex]
        H --&gt; K[.bbl文件]
        J --&gt; L[.ind文件]
    end

    K --&gt; C
    L --&gt; C</pre><h2 id="选择指南">
  <a class="anchor inpage" href="#%e9%80%89%e6%8b%a9%e6%8c%87%e5%8d%97">##</a>选择指南</h2>
<h3 id="引擎选择建议">
  <a class="anchor inpage" href="#%e5%bc%95%e6%93%8e%e9%80%89%e6%8b%a9%e5%bb%ba%e8%ae%ae">###</a>引擎选择建议</h3>
<ol>
<li><strong>中文/多语言文档</strong>：<code>xelatex</code> 或 <code>lualatex</code></li>
<li><strong>传统英文文档</strong>：<code>pdflatex</code></li>
<li><strong>需要动态功能</strong>：<code>lualatex</code>（Lua脚本）</li>
<li><strong>底层开发</strong>：<code>tex</code> 或 <code>luatex</code></li>
</ol>
<h2 id="列举">
  <a class="anchor inpage" href="#%e5%88%97%e4%b8%be">##</a>列举</h2>
<h3 id="1">
  <a class="anchor inpage" href="#1">###</a><strong>1. <code>tex</code>（原始 TeX 引擎）</strong></h3>
<ul>
<li><strong>作用</strong>：Knuth 开发的原始 TeX 排版引擎，处理 <code>.tex</code> 文件并生成 <code>.dvi</code>（DeVice Independent）文件。</li>
<li><strong>特点</strong>：
<ul>
<li>仅支持传统的 TeX 命令，不支持现代字体（如 OpenType）。</li>
<li>主要用于历史兼容性或极简排版。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>tex mydocument.tex  <span style="color:#75715e"># 生成 mydocument.dvi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="2">
  <a class="anchor inpage" href="#2">###</a><strong>2. <code>latex</code>（LaTeX 格式 + pdfTeX 引擎）</strong></h3>
<ul>
<li><strong>作用</strong>：使用 <code>pdftex</code> 引擎处理 LaTeX 文档（<code>.tex</code>），默认生成 PDF（也可生成 DVI）。</li>
<li><strong>特点</strong>：
<ul>
<li>基于 <code>pdftex</code>，支持 PDF 输出、微调排版和基本字体扩展。</li>
<li>但不支持 Unicode 和 OpenType 字体（需额外宏包如 <code>fontspec</code>）。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>latex mydocument.tex  <span style="color:#75715e"># 生成 mydocument.dvi</span>
</span></span><span style="display:flex;"><span>pdflatex mydocument.tex  <span style="color:#75715e"># 生成 mydocument.pdf</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="3">
  <a class="anchor inpage" href="#3">###</a><strong>3. <code>xetex</code>（XeTeX 引擎，支持 Unicode 和系统字体）</strong></h3>
<ul>
<li><strong>作用</strong>：TeX 引擎，原生支持 Unicode 和系统字体（如 <code>.ttf</code>/<code>.otf</code>）。</li>
<li><strong>特点</strong>：
<ul>
<li>直接调用系统字体，无需额外配置。</li>
<li>适用于多语言排版（如中文、阿拉伯语）。</li>
<li>输出格式为 <code>.xdv</code>（扩展 DVI），通常转换为 PDF。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>xetex mydocument.tex  <span style="color:#75715e"># 生成 mydocument.xdv（通常自动转 PDF）</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="4">
  <a class="anchor inpage" href="#4">###</a><strong>4. <code>xelatex</code>（LaTeX + XeTeX 引擎）</strong></h3>
<ul>
<li><strong>作用</strong>：<code>latex</code> 的增强版，使用 <code>xetex</code> 引擎处理 LaTeX 文档，支持现代字体。</li>
<li><strong>特点</strong>：
<ul>
<li>支持 <code>fontspec</code> 宏包，可轻松使用系统字体。</li>
<li>适合中文排版（如配合 <code>ctex</code> 宏包）。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>xelatex mydocument.tex  <span style="color:#75715e"># 直接生成 PDF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="5">
  <a class="anchor inpage" href="#5">###</a><strong>5. <code>luatex</code>（LuaTeX 引擎，支持 Lua 脚本）</strong></h3>
<ul>
<li><strong>作用</strong>：扩展的 TeX 引擎，内置 Lua 解释器，允许动态脚本控制排版。</li>
<li><strong>特点</strong>：
<ul>
<li>支持 Unicode 和 OpenType 字体（类似 XeTeX）。</li>
<li>可通过 <code>\directlua{}</code> 嵌入 Lua 代码，实现高级自动化。</li>
<li>默认生成 PDF。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>luatex mydocument.tex  <span style="color:#75715e"># 生成 PDF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="6">
  <a class="anchor inpage" href="#6">###</a><strong>6. <code>lualatex</code>（LaTeX + LuaTeX 引擎）</strong></h3>
<ul>
<li><strong>作用</strong>：<code>latex</code> 的现代替代品，使用 <code>luatex</code> 引擎，结合 LaTeX 和 Lua 扩展。</li>
<li><strong>特点</strong>：
<ul>
<li>支持 <code>fontspec</code> 和 Lua 脚本，灵活性极高。</li>
<li>适合复杂排版（如自动生成内容、动态调整格式）。</li>
</ul>
</li>
<li><strong>使用示例</strong>：
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>lualatex mydocument.tex  <span style="color:#75715e"># 生成 PDF</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<h3 id="总结对比">
  <a class="anchor inpage" href="#%e6%80%bb%e7%bb%93%e5%af%b9%e6%af%94">###</a><strong>总结对比</strong></h3>
<table>
  <thead>
      <tr>
          <th>命令</th>
          <th>引擎</th>
          <th>输出格式</th>
          <th>Unicode 支持</th>
          <th>OpenType 支持</th>
          <th>Lua 支持</th>
          <th>典型用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>tex</code></td>
          <td>TeX</td>
          <td>DVI</td>
          <td>❌</td>
          <td>❌</td>
          <td>❌</td>
          <td>原始 TeX 排版</td>
      </tr>
      <tr>
          <td><code>latex</code></td>
          <td>pdfTeX</td>
          <td>DVI/PDF</td>
          <td>❌</td>
          <td>❌</td>
          <td>❌</td>
          <td>传统 LaTeX 文档</td>
      </tr>
      <tr>
          <td><code>pdflatex</code></td>
          <td>pdfTeX</td>
          <td>PDF</td>
          <td>❌</td>
          <td>❌</td>
          <td>❌</td>
          <td>直接生成 PDF</td>
      </tr>
      <tr>
          <td><code>xetex</code></td>
          <td>XeTeX</td>
          <td>XDV/PDF</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>❌</td>
          <td>多语言排版（系统字体）</td>
      </tr>
      <tr>
          <td><code>xelatex</code></td>
          <td>XeTeX</td>
          <td>PDF</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>❌</td>
          <td>现代 LaTeX（中文友好）</td>
      </tr>
      <tr>
          <td><code>luatex</code></td>
          <td>LuaTeX</td>
          <td>PDF</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>动态脚本控制排版</td>
      </tr>
      <tr>
          <td><code>lualatex</code></td>
          <td>LuaTeX</td>
          <td>PDF</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>✔️</td>
          <td>高级 LaTeX 自动化</td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item><item><title>一些nvim的配置和使用技巧</title><link>https://hiraethecho.github.io/docs/software/nvim-trick/</link><pubDate>Wed, 06 Aug 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/nvim-trick/</guid><description>&lt;h1 id="一些nvim的配置和使用技巧"&gt;
&lt;a class="anchor inpage" href="#%e4%b8%80%e4%ba%9bnvim%e7%9a%84%e9%85%8d%e7%bd%ae%e5%92%8c%e4%bd%bf%e7%94%a8%e6%8a%80%e5%b7%a7"&gt;#&lt;/a&gt;一些nvim的配置和使用技巧&lt;/h1&gt;
&lt;h2 id="cmd"&gt;
&lt;a class="anchor inpage" href="#cmd"&gt;##&lt;/a&gt;cmd&lt;/h2&gt;
&lt;p&gt;Lua 输出：&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;nvim&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-nvim" data-lang="nvim"&gt;:lua =vim.opt.runtimepath:get()&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;&lt;code&gt;:setl ma! ma?&lt;/code&gt; 可以切换一个buffer的只读状态。
注意其他编辑器的只读一般是“你可以修改但不能保存“，这个是你根本不能修改，比如说根本就不能进入插入模式。
可以设一个顺手的keymap，比如说我是nnoremap &lt;silent&gt; ;m :setl ma! ma?&lt;cr&gt; 。&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="一些nvim的配置和使用技巧">
  <a class="anchor inpage" href="#%e4%b8%80%e4%ba%9bnvim%e7%9a%84%e9%85%8d%e7%bd%ae%e5%92%8c%e4%bd%bf%e7%94%a8%e6%8a%80%e5%b7%a7">#</a>一些nvim的配置和使用技巧</h1>
<h2 id="cmd">
  <a class="anchor inpage" href="#cmd">##</a>cmd</h2>
<p>Lua 输出：</p>
<details open>
    <summary>nvim</summary><pre
        class="codeblock"
      ><code class="language-nvim" data-lang="nvim">:lua =vim.opt.runtimepath:get()</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><code>:setl ma! ma?</code> 可以切换一个buffer的只读状态。
注意其他编辑器的只读一般是“你可以修改但不能保存“，这个是你根本不能修改，比如说根本就不能进入插入模式。
可以设一个顺手的keymap，比如说我是nnoremap <silent> ;m :setl ma! ma?<cr> 。</p>
<p>另外，:setl xxx! xxx? 这个是一个常用切换option开关的模式，比如说:nnoremap <silent> <space>w<space> <CMD>setl wrap! wrap?<cr>设keymap来切换自动换行，并在状态栏显示当前实际状态。</p>
<details open>
    <summary>vimscript</summary><pre
        class="codeblock"
      ><code class="language-vimscript" data-lang="vimscript">xnoremap ,x &lt;ESC&gt;`.`gvp`P
abbrev ,f &lt;C-R&gt;=expand(&#34;%:&#34;)&lt;left&gt;&lt;left&gt;
abbrev ,c &lt;C-R&gt;=getcwd()&lt;cr&gt;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>下面的keymap可以直接执行一行vimscript或者lua （取决于当前文件类型）。用来调整或者测试vim配置非常方便，改完一行就执行一下，不需要source整个vimrc文件了。</p>
<details open>
    <summary>vimscript</summary><pre
        class="codeblock"
      ><code class="language-vimscript" data-lang="vimscript">command! -range ExecVimL call execute(getline(&lt;line1&gt;, &lt;line2&gt;), &#39;&#39;)
command! -range ExecLua call execute(&#39;lua &#39; . join(getline(&lt;line1&gt;, &lt;line2&gt;), &#34; \n &#34;), &#39;&#39;)
nnoremap &lt;silent&gt; &lt;expr&gt; ,r ((&amp;ft==&#39;lua&#39; ? &#39;:ExecLua&#39; : &#39;:ExecVimL&#39;) . &#39;&lt;cr&gt;:&lt;c-u&gt;echo &#34;Current line executed&#34;&lt;cr&gt;&#39;)
xnoremap &lt;silent&gt; &lt;expr&gt; ,r ((&amp;ft==&#39;lua&#39; ? &#39;:ExecLua&#39; : &#39;:ExecVimL&#39;) . &#39;&lt;cr&gt;:&lt;c-u&gt;echo &#34;Selected range executed&#34;&lt;cr&gt;&#39;)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>链接：https://www.zhihu.com/question/636018229/answer/3386613023
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</p>
<p>用<code>.!</code>（当前行），<code>%!</code>（整个buff），<code>'&lt;,'&gt;!</code> (选中）可以把文本作为stdin传给一个外部shell命令，并用其stdout输出内容替换相应文本，用来调外部的格式化命令很方便。另外，如果传给bash或zsh的话就相当于把文本作为shell命令执行。</p>
<p>「修改 1」→「撤销」→「修改 2」，这时如果想退回到「修改 1」，按 <code>u</code> 是回不去的。</p>
<p>可以按 <code>g-</code>（反方向是 <code>g+</code>）</p>
<p>实际上等同于 <code>:earlier</code> 和 <code>:later</code> 。这两个命令后边是可以跟「次数」而不是「时间」的顺便一说，不写默认是 1 次。</p>
<p>test 2</p>
<h2 id="start-up-of-nvim">
  <a class="anchor inpage" href="#start-up-of-nvim">##</a>start up of nvim</h2>
<p>
</p>
<h2 id="lazynvim">
  <a class="anchor inpage" href="#lazynvim">##</a>lazy.nvim</h2>
<p>
 <code>lazy.nvim</code> 配置的表合并情况。例如假设<code>treesitter</code>的默认配置为</p>
<details open>
    <summary>lua</summary><pre
        class="chroma codeblock"
      ><code class="language-lua" data-lang="lua"
          ><span style="display:flex;"><span><span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#34;nvim-treesitter/nvim-treesitter&#34;</span>,
</span></span><span style="display:flex;"><span>  opts <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    ensure_installed <span style="color:#f92672">=</span> { <span style="color:#e6db74">&#34;lua&#34;</span>, <span style="color:#e6db74">&#34;vim&#34;</span> },
</span></span><span style="display:flex;"><span>    highlight <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>手动配置</p>
<details open>
    <summary>lua</summary><pre
        class="chroma codeblock"
      ><code class="language-lua" data-lang="lua"
          ><span style="display:flex;"><span><span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#34;nvim-treesitter/nvim-treesitter&#34;</span>,
</span></span><span style="display:flex;"><span>  opts <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    ensure_installed <span style="color:#f92672">=</span> { <span style="color:#e6db74">&#34;python&#34;</span> },
</span></span><span style="display:flex;"><span>    highlight <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>,
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    indent <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>,
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>那么最后会得到<code>ensure_installed = { &quot;python&quot; }</code>。如何要拓展表，则要用</p>
<details open>
    <summary>lua</summary><pre
        class="chroma codeblock"
      ><code class="language-lua" data-lang="lua"
          ><span style="display:flex;"><span>table.insert(opts.ensure_installed, <span style="color:#e6db74">&#34;python&#34;</span>)</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>timewarrior</title><link>https://hiraethecho.github.io/docs/software/timewarrior/</link><pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/timewarrior/</guid><description>&lt;h1 id="timewarrior"&gt;
&lt;a class="anchor inpage" href="#timewarrior"&gt;#&lt;/a&gt;timewarrior&lt;/h1&gt;
&lt;h2 id="help"&gt;
&lt;a class="anchor inpage" href="#help"&gt;##&lt;/a&gt;help&lt;/h2&gt;
&lt;p&gt;A time tracking tool used to measure the duration of activities.
.&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;
Start tracking an activity:
timew start
Tag the current activity:
timew tag activity_tag
Start tracking and tag a new activity:
timew start activity_tag
Stop the current activity:
timew stop
Track an activity in the past:
timew track start_time - end_time activity_tag
View tracked items of the day:
timew summary
View report for the last day, week, current month, etc.:
timew summary :today|yesterday|week|lastweek|month|lastmonth|year|lastyear&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;Usage: timew [--version]
timew annotate @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;annotation&amp;gt;
timew cancel
timew config [&amp;lt;name&amp;gt; [&amp;lt;value&amp;gt; | &amp;#39;&amp;#39;]]
timew continue [@&amp;lt;id&amp;gt;] [&amp;lt;date&amp;gt;|&amp;lt;interval&amp;gt;]
timew day [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew delete @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...]
timew diagnostics
timew export [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew extensions
timew gaps [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew get &amp;lt;DOM&amp;gt; [&amp;lt;DOM&amp;gt; ...]
timew help [&amp;lt;command&amp;gt; | dates | dom | durations | hints | ranges]
timew join @&amp;lt;id&amp;gt; @&amp;lt;id&amp;gt;
timew lengthen @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;duration&amp;gt;
timew modify (start|end) @&amp;lt;id&amp;gt; &amp;lt;date&amp;gt;
timew modify range @&amp;lt;id&amp;gt; &amp;lt;interval&amp;gt;
timew month [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew move @&amp;lt;id&amp;gt; &amp;lt;date&amp;gt;
timew [report] &amp;lt;report&amp;gt; [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew retag @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;tag&amp;gt; [&amp;lt;tag&amp;gt; ...]
timew shorten @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;duration&amp;gt;
timew show
timew split @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...]
timew start [&amp;lt;date&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew stop [&amp;lt;tag&amp;gt; ...]
timew summary [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew tag @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;tag&amp;gt; [&amp;lt;tag&amp;gt; ...]
timew tags [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
timew track &amp;lt;interval&amp;gt; [&amp;lt;tag&amp;gt; ...]
timew undo
timew untag @&amp;lt;id&amp;gt; [@&amp;lt;id&amp;gt; ...] &amp;lt;tag&amp;gt; [&amp;lt;tag&amp;gt; ...]
timew week [&amp;lt;interval&amp;gt;] [&amp;lt;tag&amp;gt; ...]
Additional help:
timew help &amp;lt;command&amp;gt;
timew help dates
timew help dom
timew help durations
timew help hints
timew help ranges
Interval:
[from] &amp;lt;date&amp;gt;
[from] &amp;lt;date&amp;gt; to/- &amp;lt;date&amp;gt;
[from] &amp;lt;date&amp;gt; for &amp;lt;duration&amp;gt;
&amp;lt;duration&amp;gt; before/after &amp;lt;date&amp;gt;
&amp;lt;duration&amp;gt; ago
[for] &amp;lt;duration&amp;gt;
Tag:
Word
&amp;#39;Single Quoted Words&amp;#39;
&amp;#34;Double Quoted Words&amp;#34;
Escaped\ Spaces
Configuration overrides:
rc.&amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;h2 id="timew-dom---timewarrior-dom"&gt;
&lt;a class="anchor inpage" href="#timew-dom---timewarrior-dom"&gt;##&lt;/a&gt;timew-dom - Timewarrior DOM&lt;/h2&gt;
&lt;p&gt;Supported DOM references are:&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="timewarrior">
  <a class="anchor inpage" href="#timewarrior">#</a>timewarrior</h1>
<h2 id="help">
  <a class="anchor inpage" href="#help">##</a>help</h2>
<p>A time tracking tool used to measure the duration of activities. 
.</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">
  Start tracking an activity:

      timew start

  Tag the current activity:

      timew tag activity_tag

  Start tracking and tag a new activity:

      timew start activity_tag

  Stop the current activity:

      timew stop

  Track an activity in the past:

      timew track start_time - end_time activity_tag

  View tracked items of the day:

      timew summary

  View report for the last day, week, current month, etc.:

      timew summary :today|yesterday|week|lastweek|month|lastmonth|year|lastyear</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Usage: timew [--version]
       timew annotate @&lt;id&gt; [@&lt;id&gt; ...] &lt;annotation&gt;
       timew cancel
       timew config [&lt;name&gt; [&lt;value&gt; | &#39;&#39;]]
       timew continue [@&lt;id&gt;] [&lt;date&gt;|&lt;interval&gt;]
       timew day [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew delete @&lt;id&gt; [@&lt;id&gt; ...]
       timew diagnostics
       timew export [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew extensions
       timew gaps [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew get &lt;DOM&gt; [&lt;DOM&gt; ...]
       timew help [&lt;command&gt; | dates | dom | durations | hints | ranges]
       timew join @&lt;id&gt; @&lt;id&gt;
       timew lengthen @&lt;id&gt; [@&lt;id&gt; ...] &lt;duration&gt;
       timew modify (start|end) @&lt;id&gt; &lt;date&gt;
       timew modify range @&lt;id&gt; &lt;interval&gt;
       timew month [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew move @&lt;id&gt; &lt;date&gt;
       timew [report] &lt;report&gt; [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew retag @&lt;id&gt; [@&lt;id&gt; ...] &lt;tag&gt; [&lt;tag&gt; ...]
       timew shorten @&lt;id&gt; [@&lt;id&gt; ...] &lt;duration&gt;
       timew show
       timew split @&lt;id&gt; [@&lt;id&gt; ...]
       timew start [&lt;date&gt;] [&lt;tag&gt; ...]
       timew stop [&lt;tag&gt; ...]
       timew summary [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew tag @&lt;id&gt; [@&lt;id&gt; ...] &lt;tag&gt; [&lt;tag&gt; ...]
       timew tags [&lt;interval&gt;] [&lt;tag&gt; ...]
       timew track &lt;interval&gt; [&lt;tag&gt; ...]
       timew undo
       timew untag @&lt;id&gt; [@&lt;id&gt; ...] &lt;tag&gt; [&lt;tag&gt; ...]
       timew week [&lt;interval&gt;] [&lt;tag&gt; ...]

Additional help:
       timew help &lt;command&gt;
       timew help dates
       timew help dom
       timew help durations
       timew help hints
       timew help ranges

Interval:
       [from] &lt;date&gt;
       [from] &lt;date&gt; to/- &lt;date&gt;
       [from] &lt;date&gt; for &lt;duration&gt;
       &lt;duration&gt; before/after &lt;date&gt;
       &lt;duration&gt; ago
       [for] &lt;duration&gt;

Tag:
       Word
       &#39;Single Quoted Words&#39;
       &#34;Double Quoted Words&#34;
       Escaped\ Spaces

Configuration overrides:
       rc.&lt;name&gt;=&lt;value&gt;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="timew-dom---timewarrior-dom">
  <a class="anchor inpage" href="#timew-dom---timewarrior-dom">##</a>timew-dom - Timewarrior DOM</h2>
<p>Supported DOM references are:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">dom.tag.count             Count of all tags
dom.tag.1                 Nth tag used</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">dom.active                &#39;1&#39; if there is active tracking, otherwise &#39;0&#39;
dom.active.tag.count      Count of active tags
dom.active.tag.1          Active Nth tag
dom.active.start          Active start timestamp (ISO Extended local date)
dom.active.duration       Active elapsed (ISO Period)
dom.active.json           Active interval as JSON</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">dom.tracked.count         Count of tracked intervals
dom.tracked.1.tag.count   Count of active tags
dom.tracked.1.tag.1       Tracked Nth, Nth tag
dom.tracked.1.start       Tracked Nth, start time
dom.tracked.1.end         Tracked Nth, end time, blank if closed
dom.tracked.1.duration    Tracked Nth, elapsed
dom.tracked.1.json        Tracked Nth, interval as JSON</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">dom.rc.&lt;name&gt;             Configuration setting</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>ffmpeg</title><link>https://hiraethecho.github.io/docs/software/ffmpeg/</link><pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/ffmpeg/</guid><description>&lt;h1 id="ffmpeg"&gt;
&lt;a class="anchor inpage" href="#ffmpeg"&gt;#&lt;/a&gt;ffmpeg&lt;/h1&gt;
&lt;details open&gt;
&lt;summary&gt;tldr&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-tldr" data-lang="tldr"&gt; Video conversion tool.
More information: &amp;lt;https://ffmpeg.org&amp;gt;.
Extract the sound from a video and save it as MP3:
ffmpeg -i path/to/video.mp4 -vn path/to/sound.mp3
Transcode a FLAC file to Red Book CD format (44100kHz, 16bit):
ffmpeg -i path/to/input_audio.flac -ar 44100 -sample_fmt s16 path/to/output_audio.wav
Save a video as GIF, scaling the height to 1000px and setting framerate to 15:
ffmpeg -i path/to/video.mp4 [-vf|-filter:v] &amp;#39;scale=-1:1000&amp;#39; -r 15 path/to/output.gif
Combine numbered images (`frame_1.jpg`, `frame_2.jpg`, etc) into a video or GIF:
ffmpeg -i path/to/frame_%d.jpg -f image2 video.mpg|video.gif
Trim a video from a given start time mm:ss to an end time mm2:ss2 (omit the -to flag to trim till the end):
ffmpeg -i path/to/input_video.mp4 -ss mm:ss -to mm2:ss2 [-c|-codec] copy path/to/output_video.mp4
Convert AVI video to MP4. AAC Audio @ 128kbit, h264 Video @ CRF 23:
ffmpeg -i path/to/input_video.avi [-c|-codec]:a aac -b:a 128k [-c|-codec]:v libx264 -crf 23 path/to/output_video.mp4
Remux MKV video to MP4 without re-encoding audio or video streams:
ffmpeg -i path/to/input_video.mkv [-c|-codec] copy path/to/output_video.mp4
Convert MP4 video to VP9 codec. For the best quality, use a CRF value (recommended range 15-35) and -b:v MUST be 0:
ffmpeg -i path/to/input_video.mp4 [-c|-codec]:v libvpx-vp9 -crf 30 -b:v 0 [-c|-codec]:a libopus -vbr on -threads number_of_threads path/to/output_video.webm&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;</description><content:encoded><![CDATA[<h1 id="ffmpeg">
  <a class="anchor inpage" href="#ffmpeg">#</a>ffmpeg</h1>
<details open>
    <summary>tldr</summary><pre
        class="codeblock"
      ><code class="language-tldr" data-lang="tldr">  Video conversion tool.
  More information: &lt;https://ffmpeg.org&gt;.

  Extract the sound from a video and save it as MP3:

      ffmpeg -i path/to/video.mp4 -vn path/to/sound.mp3

  Transcode a FLAC file to Red Book CD format (44100kHz, 16bit):

      ffmpeg -i path/to/input_audio.flac -ar 44100 -sample_fmt s16 path/to/output_audio.wav

  Save a video as GIF, scaling the height to 1000px and setting framerate to 15:

      ffmpeg -i path/to/video.mp4 [-vf|-filter:v] &#39;scale=-1:1000&#39; -r 15 path/to/output.gif

  Combine numbered images (`frame_1.jpg`, `frame_2.jpg`, etc) into a video or GIF:

      ffmpeg -i path/to/frame_%d.jpg -f image2 video.mpg|video.gif

  Trim a video from a given start time mm:ss to an end time mm2:ss2 (omit the -to flag to trim till the end):

      ffmpeg -i path/to/input_video.mp4 -ss mm:ss -to mm2:ss2 [-c|-codec] copy path/to/output_video.mp4

  Convert AVI video to MP4. AAC Audio @ 128kbit, h264 Video @ CRF 23:

      ffmpeg -i path/to/input_video.avi [-c|-codec]:a aac -b:a 128k [-c|-codec]:v libx264 -crf 23 path/to/output_video.mp4

  Remux MKV video to MP4 without re-encoding audio or video streams:

      ffmpeg -i path/to/input_video.mkv [-c|-codec] copy path/to/output_video.mp4

  Convert MP4 video to VP9 codec. For the best quality, use a CRF value (recommended range 15-35) and -b:v MUST be 0:

      ffmpeg -i path/to/input_video.mp4 [-c|-codec]:v libvpx-vp9 -crf 30 -b:v 0 [-c|-codec]:a libopus -vbr on -threads number_of_threads path/to/output_video.webm</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>taskwarrior</title><link>https://hiraethecho.github.io/docs/software/taskwarrior/</link><pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/taskwarrior/</guid><description>&lt;h1 id="taskwarrior"&gt;
&lt;a class="anchor inpage" href="#taskwarrior"&gt;#&lt;/a&gt;taskwarrior&lt;/h1&gt;
&lt;p&gt;Command-line to-do list manager.
.&lt;/p&gt;
&lt;h2 id="overview"&gt;
&lt;a class="anchor inpage" href="#overview"&gt;##&lt;/a&gt;overview&lt;/h2&gt;
&lt;p&gt;Taskwarrior has a flexible command line syntax, but it may not be clear at first what the underlying structure means. Here is the general form of the syntax:&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;a
href="https://taskwarrior.org/images/syntax.png"
class="img-link"
data-sub-html=""
target="_blank"
&gt;
&lt;img
src="https://taskwarrior.org/images/syntax.png"
alt=""loading="lazy"
/&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;There are four parts to the syntax (&lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;command&lt;/code&gt;, &lt;code&gt;modifications&lt;/code&gt;, and &lt;code&gt;miscellaneous&lt;/code&gt;), and each part is optional.&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;tldr&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-tldr" data-lang="tldr"&gt; Add a new task which is due tomorrow:
task add description due:tomorrow
Update a task&amp;#39;s priority:
task task_id modify priority:H|M|L
Complete a task:
task task_id done
Delete a task:
task task_id delete
List all open tasks:
task list
List open tasks due before the end of the week:
task list due.before:eow
Show a graphical burndown chart, by day:
task burndown.daily
List all reports:
task reports&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;man:&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="taskwarrior">
  <a class="anchor inpage" href="#taskwarrior">#</a>taskwarrior</h1>
<p>Command-line to-do list manager. 
.</p>
<h2 id="overview">
  <a class="anchor inpage" href="#overview">##</a>overview</h2>
<p>Taskwarrior has a flexible command line syntax, but it may not be clear at first what the underlying structure means. Here is the general form of the syntax:</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/syntax.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/syntax.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<p>There are four parts to the syntax (<code>filter</code>, <code>command</code>, <code>modifications</code>, and <code>miscellaneous</code>), and each part is optional.</p>
<details open>
    <summary>tldr</summary><pre
        class="codeblock"
      ><code class="language-tldr" data-lang="tldr">  Add a new task which is due tomorrow:
      task add description due:tomorrow

  Update a task&#39;s priority:

      task task_id modify priority:H|M|L

  Complete a task:

      task task_id done

  Delete a task:

      task task_id delete

  List all open tasks:

      task list

  List open tasks due before the end of the week:

      task list due.before:eow

  Show a graphical burndown chart, by day:

      task burndown.daily

  List all reports:

      task reports</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>man:</p>
<details open>
    <summary>man</summary><pre
        class="chroma codeblock"
      ><code class="language-man" data-lang="man"
          ><span style="display:flex;"><span>Documentation for Taskwarrior can be found using &#39;man task&#39;, &#39;man taskrc&#39;, &#39;man task-color&#39;, &#39;man task-sync&#39; or at https://taskwarrior.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>The general form of commands is:
</span></span><span style="display:flex;"><span>  task [&lt;filter&gt;] &lt;command&gt; [&lt;mods&gt;]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>The &lt;mods&gt; consist of zero or more changes to apply to the selected tasks, such as:
</span></span><span style="display:flex;"><span>  task &lt;filter&gt; &lt;command&gt; project:Home
</span></span><span style="display:flex;"><span>  task &lt;filter&gt; &lt;command&gt; +weekend +garden due:tomorrow
</span></span><span style="display:flex;"><span>  task &lt;filter&gt; &lt;command&gt; Description/annotation text
</span></span><span style="display:flex;"><span>  task &lt;filter&gt; &lt;command&gt; /from/to/     &lt;- replace first match
</span></span><span style="display:flex;"><span>  task &lt;filter&gt; &lt;command&gt; /from/to/g    &lt;- replace all matches
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Tags are arbitrary words, any quantity:
</span></span><span style="display:flex;"><span>  +tag       The + means add the tag
</span></span><span style="display:flex;"><span>  -tag       The - means remove the tag
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Built-in attributes are:
</span></span><span style="display:flex;"><span>  description:    Task description text
</span></span><span style="display:flex;"><span>  status:         Status of task - pending, completed, deleted, waiting
</span></span><span style="display:flex;"><span>  project:        Project name
</span></span><span style="display:flex;"><span>  priority:       Priority
</span></span><span style="display:flex;"><span>  due:            Due date
</span></span><span style="display:flex;"><span>  recur:          Recurrence frequency
</span></span><span style="display:flex;"><span>  until:          Expiration date of a task
</span></span><span style="display:flex;"><span>  limit:          Desired number of rows in report, or &#39;page&#39;
</span></span><span style="display:flex;"><span>  wait:           Date until task becomes pending
</span></span><span style="display:flex;"><span>  entry:          Date task was created
</span></span><span style="display:flex;"><span>  end:            Date task was completed/deleted
</span></span><span style="display:flex;"><span>  start:          Date task was started
</span></span><span style="display:flex;"><span>  scheduled:      Date task is scheduled to start
</span></span><span style="display:flex;"><span>  modified:       Date task was last modified
</span></span><span style="display:flex;"><span>  depends:        Other tasks that this task depends upon
</span></span><span style="display:flex;"><span>Alternately algebraic expressions support:
</span></span><span style="display:flex;"><span>  and  or  xor            Logical operators
</span></span><span style="display:flex;"><span>  &lt;  &lt;=  =  !=  &gt;=  &gt;     Relational operators
</span></span><span style="display:flex;"><span>  (  )                    Precedence
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  task due.before:eom priority.not:L   list
</span></span><span style="display:flex;"><span>  task &#39;(due &lt; eom and priority != L)&#39;  list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="filter">
  <a class="anchor inpage" href="#filter">###</a>Filter</h3>
<p>A filter is a means of addressing a subset of tasks. Because filters are optional, the simplest case is no filter. A command with no filter addresses all tasks.</p>
<p>Generally filter arguments appear before the command, so any arguments to the left of the command are considered filter arguments.</p>
<p>There is a special case, in which a command that does not support modifications or miscellaneous arguments, expects only filter arguments, and so they can appear before or after the command, without confusing Taskwarrior:</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/filter.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/filter.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<h3 id="command">
  <a class="anchor inpage" href="#command">###</a>Command</h3>
<p>Each time you run Taskwarrior, you are issuing a <code>command</code> either explicitly, or implicitly with the default command (the <code>default.command</code> configuration setting). The command you specify determines how the command line is understood by Taskwarrior. Here are some examples of that:</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/syntaxes.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/syntaxes.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<p>The first example, <code>task list</code> is a report with no filter, and the second, <code>task +home list</code> is with a filter. The third, <code>task 12 modify project:Garden</code> has both a filter and modifications. The last example, <code>task show editor</code> has a miscellaneous argument.</p>
<p>Taskwarrior looks for the first argument on the command line that looks like an exact command name, and failing that, looks for an abbreviated command name. It is better to use the full name of a command to avoid ambiguity.</p>
<p>It is the position of the <code>command</code> argument, and the type of command that determines how the arguments are understood.</p>
<p>task的列信息</p>
<details open>
    <summary>task</summary><pre
        class="codeblock"
      ><code class="language-task" data-lang="task">Command          Category  R/W ID GC Recur Context Filter Mods Misc Description
columns          config     RO                                 Misc All supported columns and formatting styles
config           config     RO                                 Misc Change settings in the task configuration
reports          config     RO                                      Lists all supported reports
show             config     RO                                 Misc Shows all configuration variables or subset
udas             config     RO                                      Shows all the defined UDA details
commands         metadata   RO                                      Generates a list of all commands, with behavior details
stats            metadata   RO    GC          Ctxt   Filt           Shows task database statistics
ids              metadata   RO ID GC Recur           Filt           Shows the IDs of matching tasks, as a range
count            metadata   RO    GC Recur    Ctxt   Filt           Counts matching tasks
projects         metadata   RO    GC Recur    Ctxt   Filt           Shows all project names used
tags             metadata   RO    GC          Ctxt   Filt           Shows a list of all tags used
uuids            metadata   RO    GC Recur           Filt           Shows the UUIDs of matching tasks, as a space-separated list
context          context    RO                                 Misc Set and define contexts (default filters / modifications)</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>获取信息</p>
<details open>
    <summary>internals</summary><pre
        class="codeblock"
      ><code class="language-internals" data-lang="internals">_aliases         internal   RO                                      Generates a list of all aliases, for autocompletion purposes
_columns         internal   RO                                      Displays only a list of supported columns
_commands        internal   RO                                      Generates a list of all commands, for autocompletion purposes
_config          internal   RO                                      Lists all supported configuration variables, for completion purposes
_context         internal   RO                                      Lists all supported contexts, for completion purposes
_get             internal   RO                                 Misc DOM Accessor
_ids             internal   RO ID GC Recur           Filt           Shows the IDs of matching tasks, in the form of a list
_projects        internal   RO    GC Recur           Filt           Shows only a list of all project names used
_show            internal   RO    GC                                Shows all configuration settings in a machine-readable format
_tags            internal   RO    GC Recur           Filt           Shows only a list of all tags used, for autocompletion purposes
_udas            internal   RO                                      Shows the defined UDAs for completion purposes
_unique          internal   RO ID GC                 Filt      Misc Generates lists of unique attribute values
_urgency         internal   RO    GC                 Filt           Displays the urgency measure of a task
_uuids           internal   RO    GC Recur           Filt           Shows the UUIDs of matching tasks, as a list
_version         internal   RO                                      Shows only the Taskwarrior version number
_zshattributes   internal   RO                                      Generates a list of all attributes, for zsh autocompletion purposes
_zshcommands     internal   RO                                      Generates a list of all commands, for zsh autocompletion purposes
_zshids          internal   RO ID GC Recur           Filt           Shows the IDs and descriptions of matching tasks
_zshuuids        internal   RO    GC Recur           Filt           Shows the UUIDs and descriptions of matching tasks</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>操作</p>
<details open>
    <summary>operation</summary><pre
        class="codeblock"
      ><code class="language-operation" data-lang="operation">add              operation  RW                Ctxt        Mods      Adds a new task
annotate         operation  RW                       Filt Mods      Adds an
append           operation  RW                       Filt Mods      Appends text to
delete           operation  RW                Ctxt   Filt Mods      Deletes the
denotate         operation  RW                Ctxt   Filt      Misc Deletes an
done             operation  RW                Ctxt   Filt Mods      Marks the
duplicate        operation  RW                Ctxt   Filt Mods      Duplicates the
edit             operation  RW       Recur    Ctxt   Filt           Launches an
log              operation  RW                Ctxt        Mods      Adds a new task
modify           operation  RW                       Filt Mods      Modifies the
prepend          operation  RW                Ctxt   Filt Mods      Prepends text to
purge            operation  RW    GC          Ctxt   Filt           Removes the
start            operation  RW                Ctxt   Filt Mods      Marks specified
stop             operation  RW                Ctxt   Filt Mods      Removes the
undo             operation  RW                                      Reverts the most</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>统计</p>
<details open>
    <summary>graphs</summary><pre
        class="codeblock"
      ><code class="language-graphs" data-lang="graphs">burndown.daily   graphs     RO    GC Recur    Ctxt   Filt           Shows a
burndown.monthly graphs     RO    GC Recur    Ctxt   Filt           Shows a
burndown.weekly  graphs     RO    GC Recur    Ctxt   Filt           Shows a
calendar         graphs     RO ID GC                           Misc Shows a
ghistory.annual  graphs     RO       Recur    Ctxt   Filt           Shows a
ghistory.daily   graphs     RO       Recur    Ctxt   Filt           Shows a
ghistory.monthly graphs     RO       Recur    Ctxt   Filt           Shows a
ghistory.weekly  graphs     RO       Recur    Ctxt   Filt           Shows a
history.annual   graphs     RO       Recur    Ctxt   Filt           Shows a report
history.daily    graphs     RO       Recur    Ctxt   Filt           Shows a report
history.monthly  graphs     RO       Recur    Ctxt   Filt           Shows a report
history.weekly   graphs     RO       Recur    Ctxt   Filt           Shows a report
summary          graphs     RO    GC          Ctxt   Filt           Shows a report</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="modifications">
  <a class="anchor inpage" href="#modifications">###</a>Modifications</h3>
<p>If a command accepts modifications, they generally appear after the command. Most commands that accept modifications also accept filters, and so the filter arguments appear before the command, while the modifications appear after. Here is an example:</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/modification.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/modification.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<p>This command specifies a compound filter, consisting of more than one term. These terms are logically combined with an <code>and</code> operator by default, unless otherwise specified. In this case, tasks that have both the <code>home</code> tag, and a <code>status</code> value of <code>pending</code> are to be modified.</p>
<p>The modifications, appearing after the command, set the <code>priority</code> to <code>H</code> igh, and the <code>due</code> date to the end of the month (<code>eom</code>).</p>
<p>Because the filter is evaluated at runtime, we don’t know how many tasks will be modified. It could be none, one, many or all of the tasks. It could be determined with:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">task &#43;home status:pending count</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>The user writing this command would have an idea of how many tasks this will affect, but this is just an example, with no contextual data shown.</p>
<h3 id="miscellaneous">
  <a class="anchor inpage" href="#miscellaneous">###</a>Miscellaneous</h3>
<p>Some commands accept neither a filter, nor modifications, but do accept miscellaneous arguments. An example is the <code>show</code> command, that queries configuration settings, and does not accept a filter:</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/miscellaneous.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/miscellaneous.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<p>This is another special case, in which the command only accepts miscellaneous arguments, and so they can appear before or after the command.</p>
<h3 id="overrides">
  <a class="anchor inpage" href="#overrides">###</a>Overrides</h3>
<p>Overrides are temporary values for configuration settings, and can be specified anywhere on the command line, because they are not considered to be either filter, modification or miscellaneous. In fact, the command itself doesn’t see the overrides, instead they are handled before the command runs.</p>
<p><figure>
  <a
    href="https://taskwarrior.org/images/override.png"
    class="img-link"
    data-sub-html=""
    target="_blank"
  >
    <img
      src="https://taskwarrior.org/images/override.png"
      alt=""loading="lazy"
    />
  </a></figure>
</p>
<p>There can be any number of overrides on the command line, and they have no effect on the syntax.</p>
<h2 id="reports">
  <a class="anchor inpage" href="#reports">##</a>reports</h2>
<p>Taskwarrior has three kinds of reports. There are built-in reports that cannot be modified, such as <code>info</code> and <code>summary</code>. There are built-in reports which can be redefined completely or eliminated, such as <code>list</code>, <code>next</code>. And finally there are your own custom reports. To generate a list of <em>all</em> the reports, use the <code>reports</code> command:</p>
<details open>
    <summary>reposts</summary><pre
        class="codeblock"
      ><code class="language-reposts" data-lang="reposts">Report           Description
---------------- --------------------------------------------------
active           Active tasks
all              All tasks
blocked          Blocked tasks
blocking         Blocking tasks
burndown.daily   Shows a graphical burndown chart, by day
burndown.monthly Shows a graphical burndown chart, by month
burndown.weekly  Shows a graphical burndown chart, by week
completed        Completed tasks
ghistory.annual  Shows a graphical report of task history, by year
ghistory.monthly Shows a graphical report of task history, by month
history.annual   Shows a report of task history, by year
history.monthly  Shows a report of task history, by month
information      Shows all data and metadata
list             Most details of tasks
long             All details of tasks
ls               Few details of tasks
minimal          Minimal details of tasks
newest           Newest tasks
next             Most urgent tasks
oldest           Oldest tasks
overdue          Overdue tasks
projects         Shows all project names used
ready            Most urgent actionable tasks
recurring        Recurring Tasks
summary          Shows a report of task status by project
tags             Shows a list of all tags used
unblocked        Unblocked tasks
waiting          Waiting (hidden) tasks

28 reports</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="built-in-static-reports">
  <a class="anchor inpage" href="#built-in-static-reports">###</a>Built-In Static Reports</h3>
<p>Typically, a report consists of a table of data, with one row of data corresponding to a single task, with the task attributes represented as columns. But there are other reports which do not conform to this structure. Those are the built-in static reports, and they are not modifiable, because they are quirky and require custom code. These reports are:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">burndown.daily
burndown.monthly
burndown.weekly
calendar
colors
export
ghistory.annual
ghistory.monthly
history.annual
history.monthly
information
summary
timesheet</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Each of these reports takes non-standard arguments, may or may not support filters, and generates distinctive output.</p>
<h3 id="built-in-modifiable-reports">
  <a class="anchor inpage" href="#built-in-modifiable-reports">###</a>Built-In Modifiable Reports</h3>
<p>These reports are standard format, using standard arguments, and are also modifiable.</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">active
all
blocked
blocking
completed
list
long
ls
minimal
newest
next
oldest
overdue
ready
recurring
unblocked
waiting</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Suppose you wanted to remove a column from one of these reports, for example removing <code>tags</code> from the <code>minimal</code> report. First look at the existing columns and labels of the <code>minimal</code> report:</p>
<p><code>task show report.minimal.labels</code> shows</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Config Variable       Value
--------------------- ---------------------------
report.minimal.labels ID,Project,Tags,Description</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>and <code>task show report.minimal.columns</code> shows</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Config Variable        Value
---------------------- ---------------------------------------
report.minimal.columns id,project,tags.count,description.count</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Having determined what the current values are, simply override with the new values:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task config report.minimal.labels  <span style="color:#e6db74">&#39;ID,Project,Description&#39;</span>
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>$ task config report.minimal.columns <span style="color:#e6db74">&#39;id,project,description.count&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>You can think of the built-in modifiable reports as a set of default custom reports.</p>
<h3 id="custom-reports">
  <a class="anchor inpage" href="#custom-reports">###</a>Custom Reports</h3>
<p>Defining a custom report is straightforward. You have control over the data shown, the sort order and the column labels. A custom report is simply a set of configuration values, and those values include:</p>
<ul>
<li>description</li>
<li>columns</li>
<li>labels</li>
<li>sort</li>
<li>filter</li>
</ul>
<p>Let us quickly create a custom report, which will be named <code>simple</code>. This report will display the task ID, project name and description. We will need to gather the five settings listed above.</p>
<p>The description is the easiest, and in this case the report will be described:</p>
<details open>
    <summary>coffeescript</summary><pre
        class="chroma codeblock"
      ><code class="language-coffeescript" data-lang="coffeescript"
          ><span style="display:flex;"><span><span style="color:#a6e22e">Simple</span> <span style="color:#a6e22e">list</span> <span style="color:#66d9ef">of</span> <span style="color:#a6e22e">open</span> <span style="color:#a6e22e">tasks</span> <span style="color:#66d9ef">by</span> <span style="color:#a6e22e">project</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This is just a descriptive label that will be used when the report is listed. Next we need to specify the columns in the report, and the order in which those are shown. Here the <code>_columns</code> helper command will show the columns available:</p>
<p><code>task _columns</code> shows</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">depends
description
due
end
entry
foo
id
imask
mask
modified
parent
priority
project
recur
scheduled
start
status
tags
until
urgency
uuid
wait</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>That represents all the data that Taskwarrior stores, and therefore all the data that may be shown in a report. Our <code>simple</code> report will show id, project and description, which are all in the list. This means our column list is simply:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">id,project,description</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>But there are also formats for each column, and the <code>columns</code> command shows them, with examples. Here are the formats for our three columns: <code>task columns id</code></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Columns Supported Formats Example
------- ----------------- ------------------------------------
id      number*           123
uuid    long*             f30cb9c3-3fc0-483f-bfb2-3bf134f00694
        short             f30cb9c3</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This is easy, because there is only one <code>id</code> format. <code>task columns project</code></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Columns Supported Formats Example
------- ----------------- -------------
project full*             home.garden
        parent            home
        indented            home.garden</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>There are three formats for the <code>project</code> column, and the default, <code>full</code> is the one we want. <code>task columns description</code></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Columns     Supported Formats Example
----------- ----------------- -----------------------------------------------------------------------------
description combined*         Move your clothes down on to the lower peg
                                2014-02-08 Immediately before your lunch
                                2014-02-08 If you are playing in the match this afternoon
                                2014-02-08 Before you write your letter home
                                2014-02-08 If you&#39;re not getting your hair cut
            desc              Move your clothes down on to the lower peg
            oneline           Move your clothes down on to the lower peg 2014-02-08 Immediately before ...
                              this afternoon 2014-02-08 Before you write your letter home 2014-02-08 If ...
            truncated         Move your clothes do...
            count             Move your clothes down on to the lower peg [4]</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>There are five formats for description. This time we prefer the <code>count</code> format, so our columns list is now:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">id,project,description.count</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Labels are the column heading labels in the report. There are defaults, but we wish to specify these like this:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">ID,Proj,Desc</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Sorting is also straightforward, and we want the tasks sorted by project, and then by entry, which is the creation date for a task. This illustrates that a task attribute that is not visible can be used in the sort. The sort order is then:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">project&#43;/,entry&#43;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>The <code>+</code> means an ascending order, but we could have used <code>-</code> for descending. The <code>/</code> solidus indicates that <code>project</code> is a break column, which means a blank line is inserted between unique values, for a visual grouping effect. 2.4.0</p>
<p>Finally, we need a filter, otherwise our report will just display all tasks, which is rarely wanted. Here we wish to see only pending tasks, and that means the filter is:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">status:pending</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Now we have our report definition, so we just create the five configuration entries like this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task config report.simple.description <span style="color:#e6db74">&#39;Simple list of open tasks by project&#39;</span>
</span></span><span style="display:flex;"><span>task config report.simple.columns     <span style="color:#e6db74">&#39;id,project,description.count&#39;</span>
</span></span><span style="display:flex;"><span>task config report.simple.labels      <span style="color:#e6db74">&#39;ID,Proj,Desc&#39;</span>
</span></span><span style="display:flex;"><span>task config report.simple.sort        <span style="color:#e6db74">&#39;project+/,entry+&#39;</span>
</span></span><span style="display:flex;"><span>task config report.simple.filter      <span style="color:#e6db74">&#39;status:pending&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Note the equivalent report directly from the config file would look like that:</p>
<details open>
    <summary>config</summary><pre
        class="codeblock"
      ><code class="language-config" data-lang="config">report.simple.description=Simple list of open tasks by project
report.simple.columns=id,project,description.count
report.simple.labels=ID,Proj,Desc
report.simple.sort=project&#43;\/,entry&#43;
report.simple.filter=status:pending</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>And it is finished. Run the report like this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task simple
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ID Proj Desc
</span></span><span style="display:flex;"><span>-- ---- -----------------
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">1</span> Home Wash the windows
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">3</span> Home Vacuum the floors
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">2</span>      Food shopping</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Custom reports also show up in the help output.</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task help | grep simple
</span></span><span style="display:flex;"><span>task  simple              Simple list of open tasks by project</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>I can inspect the configuration.</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task show report.simple
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Config Variable           Value
</span></span><span style="display:flex;"><span>------------------------- ------------------------------------
</span></span><span style="display:flex;"><span>report.simple.columns     id,project,description.count
</span></span><span style="display:flex;"><span>report.simple.description Simple list of open tasks by project
</span></span><span style="display:flex;"><span>report.simple.filter      status:pending
</span></span><span style="display:flex;"><span>report.simple.labels      ID,Proj,Desc
</span></span><span style="display:flex;"><span>report.simple.sort        project+/,entry+</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Now the report is fully configured, it joins the others and is used in the same way.</p>
<h2 id="attributes">
  <a class="anchor inpage" href="#attributes">##</a>attributes</h2>
<h3 id="built-in">
  <a class="anchor inpage" href="#built-in">###</a>built-in</h3>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Built-in attributes are:
  description:    Task description text
  status:         Status of task - pending, completed, deleted, waiting
  project:        Project name
  priority:       Priority
  due:            Due date
  recur:          Recurrence frequency
  until:          Expiration date of a task
  limit:          Desired number of rows in report, or &#39;page&#39;
  wait:           Date until task becomes pending
  entry:          Date task was created
  end:            Date task was completed/deleted
  start:          Date task was started
  scheduled:      Date task is scheduled to start
  modified:       Date task was last modified
  depends:        Other tasks that this task depends upon</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="modifiers">
  <a class="anchor inpage" href="#modifiers">###</a>modifiers</h3>
<p>Attribute modifiers make filters more precise. Supported modifiers are:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  Modifiers         Example            Equivalent           Meaning
  ----------------  -----------------  -------------------  -------------------------
                    due:today          due = today          Fuzzy match
  not               due.not:today      due != today         Fuzzy non-match
  before, below     due.before:today   due &lt; today          Exact date comparison
  after, above      due.after:today    due &gt;= tomorrow      Exact date comparison
  none              project.none:      project == &#39;&#39;        Empty
  any               project.any:       project !== &#39;&#39;       Not empty
  is, equals        project.is:x       project == x         Exact match
  isnt              project.isnt:x     project !== x        Exact non-match
  has, contains     desc.has:Hello     desc ~ Hello         Pattern match
  hasnt,            desc.hasnt:Hello   desc !~ Hello        Pattern non-match
  startswith, left  desc.left:Hel      desc ~ &#39;^Hel&#39;        Beginning match
  endswith, right   desc.right:llo     desc ~ &#39;llo$&#39;        End match
  word              desc.word:Hello    desc ~ &#39;\bHello\b&#39;   Boundaried word match
  noword            desc.noword:Hello  desc !~ &#39;\bHello\b&#39;  Boundaried word non-match

Alternately algebraic expressions support:
  and  or  xor            Logical operators
  &lt;  &lt;=  =  !=  &gt;=  &gt;     Relational operators
  (  )                    Precedence

  task due.before:eom priority.not:L   list
  task &#39;(due &lt; eom and priority != L)&#39;  list</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>note that</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  by         due.by:today       due &lt;= today         Exact date comparison</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="how-recurrence-works">
  <a class="anchor inpage" href="#how-recurrence-works">###</a>How Recurrence Works</h3>
<p>A recurring task is a task with a due date that keeps coming back as a reminder. Here is an example:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">task add Pay the rent due:1st recur:monthly until:2015-03-31
Created task 123.</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This task has a due date, a monthly recurrence, and an optional until date coinciding with the end of the lease.</p>
<p>A recurring task is given a status of <code>recurring</code> which hides it from view, although you can see it in the <code>all</code> report. The recurring task you create is called the template task, from which recurring tasks instances are created. So the template remains hidden, and the recurring instances that spawn from it are the tasks that you will see and complete.</p>
<p>Here is a look at the template task:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task <span style="color:#ae81ff">123</span> info
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name        Value
</span></span><span style="display:flex;"><span>ID          <span style="color:#ae81ff">123</span>
</span></span><span style="display:flex;"><span>Description Pay the rent
</span></span><span style="display:flex;"><span>Status      Recurring
</span></span><span style="display:flex;"><span>Recurrence  monthly
</span></span><span style="display:flex;"><span>Entered     2014-03-01 12:13:28 <span style="color:#f92672">(</span><span style="color:#ae81ff">42</span> secs<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Due         2014-04-01 00:00:00
</span></span><span style="display:flex;"><span>Until       2015-03-31 00:00:00
</span></span><span style="display:flex;"><span>UUID        64bcf8fd-74d5-40d2-9e57-1d6a5922cdfc
</span></span><span style="display:flex;"><span>Urgency     2.4</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Now if you run a report, such as <code>task list</code>, you will see the first instance of that recurring task generated. We can take a look at the instance:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task <span style="color:#ae81ff">124</span> info
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name        Value
</span></span><span style="display:flex;"><span>ID          <span style="color:#ae81ff">124</span>
</span></span><span style="display:flex;"><span>Description Pay the rent
</span></span><span style="display:flex;"><span>Status      Pending
</span></span><span style="display:flex;"><span>Recurrence  monthly
</span></span><span style="display:flex;"><span>Parent task 64bcf8fd-74d5-40d2-9e57-1d6a5922cdfc
</span></span><span style="display:flex;"><span>Mask Index  <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>Entered     2014-03-01 12:17:03 <span style="color:#f92672">(</span><span style="color:#ae81ff">15</span> secs<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Due         2014-04-01 00:00:00
</span></span><span style="display:flex;"><span>Until       2015-03-31 00:00:00
</span></span><span style="display:flex;"><span>UUID        29d2df7a-1165-4559-b974-a727519e00f1
</span></span><span style="display:flex;"><span>Urgency     2.4</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Notice how the instance has a status <code>pending</code>, and a reference back to the template task (Parent task). In addition, you can see it inherited the recurrence and description, and if there was a project, priority and tags, those would also be inherited.</p>
<p>The recurring instance has an attribute named ‘Mask Index’, which is zero. This indicates that it is the first of the many recurring task instances, the counting being zero-based.</p>
<p>Now if we look back at the template task, we see changes:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task <span style="color:#ae81ff">123</span> info
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name          Value
</span></span><span style="display:flex;"><span>ID            <span style="color:#ae81ff">123</span>
</span></span><span style="display:flex;"><span>Description   Pay the rent
</span></span><span style="display:flex;"><span>Status        Recurring
</span></span><span style="display:flex;"><span>Recurrence    monthly
</span></span><span style="display:flex;"><span>Mask          -
</span></span><span style="display:flex;"><span>Entered       2014-03-01 12:13:28 <span style="color:#f92672">(</span><span style="color:#ae81ff">3</span> mins<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Due           2014-04-01 00:00:00
</span></span><span style="display:flex;"><span>Until         2015-03-31 00:00:00
</span></span><span style="display:flex;"><span>Last modified 2014-03-01 12:17:03 <span style="color:#f92672">(</span><span style="color:#ae81ff">24</span> secs<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>UUID          64bcf8fd-74d5-40d2-9e57-1d6a5922cdfc
</span></span><span style="display:flex;"><span>Urgency       2.4
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Date                Modification
</span></span><span style="display:flex;"><span>2014-03-01 12:17:03 Mask set to <span style="color:#e6db74">&#39;-&#39;</span>.
</span></span><span style="display:flex;"><span>                    Modified set to <span style="color:#e6db74">&#39;2014-03-01 12:17:03&#39;</span>.</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><blockquote class="alert alert-note">
      <p class="alert-heading">template mask</p><p>The template task now has a <code>mask</code> attribute, and some change history. That <code>mask</code> is a string of task statuses. It has a value of <code>-</code> which indicates that one instance was created, task 124, because it is one character long. The <code>-</code> means that instance is still pending. This is how the template task keeps track of what it does and does not need to generate. When the task instance changes status that <code>-</code> becomes <code>+</code> (completed) or <code>X</code> (deleted) or <code>W</code> (waiting).</p></blockquote><p>Note that you never directly interact with task 123, the template task. It is hidden for a reason. Instead, you interact with the recurring task instances, and in most cases, changes are propagated to the template task and optionally other sibling tasks.</p>
<p>In this example one task instance is generated for the next due period. This is because the configuration setting <code>recurrence.limit</code> is set to 1, the default. If this number is increased to 2, then you would see the next 2 instances generated. Note that this only generates two steps into the future, without regard for whether those two instances are completed or not - don’t expect to complete the first task and see a new one pop up immediately.</p>
<h2 id="filter-1">
  <a class="anchor inpage" href="#filter-1">##</a>filter</h2>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">The &lt;filter&gt; consists of zero or more restrictions on which tasks to select, such as:
  task                                      &lt;command&gt; &lt;mods&gt;
  task 28                                   &lt;command&gt; &lt;mods&gt;
  task &#43;weekend                             &lt;command&gt; &lt;mods&gt;
  task project:Home due.before:today        &lt;command&gt; &lt;mods&gt;
  task ebeeab00-ccf8-464b-8b58-f7f2d606edfb &lt;command&gt; &lt;mods&gt;

By default, filter elements are combined with an implicit &#39;and&#39; operator, but &#39;or&#39; and &#39;xor&#39; may also be used, provided parentheses are included:
  task &#39;(/[Cc]at|[Dd]og/ or /[0-9]&#43;/)&#39;      &lt;command&gt; &lt;mods&gt;

A filter may target specific tasks using ID or UUID numbers.  To specify multiple tasks use one of these forms:
  task 1,2,3                                    delete
  task 1-3                                      info
  task 1,2-5,19                                 modify pri:H
  task 4-7 ebeeab00-ccf8-464b-8b58-f7f2d606edfb info</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="tags-virtual-tags">
  <a class="anchor inpage" href="#tags-virtual-tags">###</a>Tags, Virtual Tags</h3>
<p>Tags are arbitrary words, any quantity:</p>
<p>+tag The + means add the tag
-tag The - means remove the tag</p>
<p>The basic tag syntax is very powerful and simple to use. There are two ways to use this, shown here:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task +HOME list
</span></span><span style="display:flex;"><span>task -WORK list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>These two commands illustrate the complete tag interface. The first command is a filter that lists only tasks that have the <code>HOME</code> tag. The second command is a filter that lists only tasks that <em>do not</em> have the <code>WORK</code> tag. The + and - syntax therefore means presence and absence of a tag. This is simple to use, and can be combined like this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task +HOME -WORK list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This shows tasks that have the <code>HOME</code> tag, but do not have the <code>WORK</code> tag. This is a very simple and easy to use mechanism, but it does require that your tasks are properly tagged. In other words, it is based directly on task metadata.</p>
<p>A tag may be any single word that does not start with a digit, punctuation, or mathematical operator.</p>
<h4 id="supported-virtual-tags">
  <a class="anchor inpage" href="#supported-virtual-tags">####</a>Supported Virtual Tags</h4>
<p>Since version 2.2.0, Taskwarrior has supported virtual tags, and the list will continue to grow. Here is the full list of supported virtual tags:</p>
<ul>
<li><code>BLOCKED</code> - Is the task dependent on another incomplete task?</li>
<li><code>UNBLOCKED</code> - The opposite of <code>BLOCKED</code>, for convenience. Note <code>+BLOCKED</code> == <code>-UNBLOCKED</code> and vice versa.</li>
<li><code>BLOCKING</code> - Does another task depend on this incomplete task?</li>
<li><code>DUE</code> - Is this task due within 7 days? Determined by <code>rc.due</code></li>
<li><code>DUETODAY</code> - Is this task due sometime today?</li>
<li><code>TODAY</code> - Is this task due sometime today?</li>
<li><code>OVERDUE</code> - Is this task past its due date?</li>
<li><code>WEEK</code> - Is this task due this week? 2.3.0</li>
<li><code>MONTH</code> - Is this task due this month? 2.3.0</li>
<li><code>QUARTER</code> - Is this task due this quarter? 2.6.0</li>
<li><code>YEAR</code> - Is this task due this year? 2.3.0</li>
<li><code>ACTIVE</code> - Is the task active, i.e. does it have a start date?</li>
<li><code>SCHEDULED</code> - Is the task scheduled, i.e. does it have a scheduled date?</li>
<li><code>PARENT</code> - Is the task a hidden parent recurring task? 2.3.0</li>
<li><code>CHILD</code> - Is the task a recurring child task?</li>
<li><code>UNTIL</code> - Does the task expire, i.e. does it have an until date?</li>
<li><code>WAITING</code> - Is the task hidden, i.e. does it have a wait date?</li>
<li><code>ANNOTATED</code> - Does the task have any annotations?</li>
<li><code>READY</code> - Is the task pending, not blocked, and either not scheduled, or scheduled before now. 2.4.0</li>
<li><code>YESTERDAY</code> - Was the task due yesterday? 2.4.0</li>
<li><code>TOMORROW</code> - Is the task due tomorrow? 2.4.0</li>
<li><code>TAGGED</code> - Does the task have any tags?</li>
<li><code>PENDING</code> - Is the task in the pending state? 2.4.0</li>
<li><code>COMPLETED</code> - Is the task in the completed state? 2.4.0</li>
<li><code>DELETED</code> - Is the task in the deleted state? 2.4.0</li>
<li><code>UDA</code> - Does the task contain any UDA values? 2.5.0</li>
<li><code>ORPHAN</code> - Does the task contain any orphaned UDA values? 2.5.0</li>
<li><code>PRIORITY</code> - Does the task have a priority? 2.5.0</li>
<li><code>PROJECT</code> - Does the task have a project? 2.5.0</li>
<li><code>LATEST</code> - Is the task the most recently added task? 2.5.0</li>
</ul>
<h3 id="filters-usage">
  <a class="anchor inpage" href="#filters-usage">###</a>filters usage</h3>
<h4 id="complex-filters">
  <a class="anchor inpage" href="#complex-filters">####</a>Complex Filters</h4>
<p>Some Taskwarrior filters are simple in concept, but the syntax is not that straightforward. For example, to determine whether a task has a due date that falls on the current day, you need to use this filter:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task due.after:yesterday and due.before:tomorrow list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This filters tasks with a due date during the narrow time window of ’today’. Note that it is not sufficient to just specify the date, because due dates all have associated times (defaulting to 0:00:00), and if you want to match the date, you need to consider the time. So for example, this command <em>does not</em> list tasks due today:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task due:today list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Instead, this filter matches tasks with a due date of today, and a time of 0:00. In order to see all tasks due today, you need to provide proper range bracketing.</p>
<h4 id="simplification">
  <a class="anchor inpage" href="#simplification">####</a>Simplification</h4>
<p>Here is where virtual tags can help, by providing a simple tag interface to more complex state conditions of the task. There is a virtual tag, named <code>TODAY</code> that can be used in filters, and it means that instead of this filter:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>task due.after:yesterday and due.before:tomorrow list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>We can now use this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task +TODAY list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Which is a much simpler way of filtering tasks due today. Because this is a tag interface, we can also invert it:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task -TODAY list</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This shows only tasks that are not due today.</p>
<p>Virtual tags are built in to Taskwarrior. They are evaluated at run time, which means they do not require direct metadata, and therefore do not occupy space in the database, but are determined according to the state of the task in the same way that the complex filter example above is determined.</p>
<p>Thus virtual tags combine the simplicity of the tag interface with more complex defined conditions, for convenience.</p>
<h2 id="using-dates-effectively">
  <a class="anchor inpage" href="#using-dates-effectively">##</a>Using Dates Effectively</h2>
<p>A task does not require a due date, and can simply be a statement of need:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>However, this is exactly the kind of task can benefit from having a due date, and perhaps several other dates also.</p>
<p>There are several dates that can decorate a task, each with its own meaning and effects. You can choose to use some, all or none of these, but like all Taskwarrior features, they are there in case your needs require it, but you do not pay a performance or friction penalty by not using them.</p>
<h3 id="the-due-date">
  <a class="anchor inpage" href="#the-due-date">###</a>The due Date</h3>
<p>Use a <code>due</code> date to specify the exact date by which a task must be completed. This corresponds to the last possible moment when the task can be considered on-time. Using our example, we can set the <code>due</code> date to be Alice’s birthday (line breaks added for clarity):</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           due:2016-11-08</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Now your task has an associated <code>due</code> date, to help you determine when you need to work on it. But what effect does this have on Taskwarrior? How can it be used to best advantage?</p>
<p>We call the <code>due</code> date of a task ‘metadata’. As such, it is just a piece of data associated with the task, and therefore it can become part of a filter:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task due:today list
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This is one way to find out if any of your tasks are due today. You could also use:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task +TODAY list
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>That is an example of a virtual tag, <code>TODAY</code>, which is not a real tag, but is something you can query, and is equivalent to the previous example. Additionally, you can use <code>DUE</code> which filters tasks that have a due date today or within the next 7 days, or <code>WEEK</code> for all tasks due within the current calendar week, or <code>YESTERDAY</code>, <code>TOMORROW</code>, <code>MONTH</code> and <code>YEAR</code>.</p>
<p>Note that number of days in which a task is considered <code>DUE</code> can be configured using the <code>rc.due</code> setting.</p>
<p>You can find tasks that have any due date at all:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task due.any: list
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Or no due date:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task due.none: list
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>There is also an <code>overdue</code> report that makes use of the <code>OVERDUE</code> virtual tag, to show you what is already late. If you run the <code>calendar</code> report, your due date will be highlighted on it.</p>
<p>What we see here is that Taskwarrior leverages the metadata to drive various features. Several reports will sort by <code>due</code> date, and as we see above, a task that has a due date now belongs on your schedule.</p>
<h3 id="the-scheduled-date">
  <a class="anchor inpage" href="#the-scheduled-date">###</a>The scheduled Date</h3>
<p>A <code>scheduled</code> date is different from a <code>due</code> date, and represents the earliest opportunity to work on a task. Let’s continue with the same example above. You need to send a birthday card to Alice, but her birthday isn’t until November, so it’s not the kind of task that can be done in advance. Ideally this would be done a few days ahead of the <code>due</code> date:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           due:2016-11-08 <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           scheduled:2016-11-04</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This means that you need to send Alice a birthday card, no later than 2016-11-08, and no earlier than 2016-11-04.</p>
<p>If a task has a <code>scheduled</code> date, then once that date passes, the task is considered ready, and there is a <code>ready</code> report and a <code>READY</code> virtual tag for this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task ready
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>$ task +READY list
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Tasks that have no <code>scheduled</code> date are considered always ready. Again, metadata drives the sophistication of your task list.</p>
<h3 id="the-wait-date">
  <a class="anchor inpage" href="#the-wait-date">###</a>The wait Date</h3>
<p>Many people do not like to look at long task lists, finding them daunting, or just distracting. You can add a <code>wait</code> date to a task, which has the effect of hiding the task from you until that date. In our example, Alice’s birthday isn’t close yet, so we applied a <code>scheduled</code> date to indicate that we should not begin the task yet, as it is not ready. Now let’s add a <code>wait</code> date to the task:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           due:2016-11-08 <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           scheduled:2016-11-04 <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>           wait:november</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Here the task is given a <code>wait</code> date of 2016-11-01, via the useful shortcut ’november’, which means the task will not appear on lists until November. At that time, it will reappear, but it will still not be ready until 2016-11-04.</p>
<p>You can view all the hidden waiting tasks using the <code>waiting</code> report:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task waiting
</span></span><span style="display:flex;"><span>...</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>There is a <code>WAITING</code> virtual tag to select these tasks, but note that you have to use the <code>all</code> report with it, otherwise you get conflicts with the other reports that specify a ‘pending’ status, because a waiting task is not pending.</p>
<h3 id="the-until-date">
  <a class="anchor inpage" href="#the-until-date">###</a>The until Date</h3>
<p>Now suppose I miss Alice’s birthday completely. Shame on me. The task would be overdue, but this is the kind of task where I don’t want to complete it late, I’d rather just forget it, and wish Alice a belated happy birthday in person. I could simply delete or complete the task, but there is another option, which is to add an <code>until</code> date:</p>
<details open>
    <summary>perl</summary><pre
        class="chroma codeblock"
      ><code class="language-perl" data-lang="perl"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           due:2016<span style="color:#f92672">-</span><span style="color:#ae81ff">11</span><span style="color:#f92672">-</span><span style="color:#ae81ff">08</span> <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           scheduled:2016<span style="color:#f92672">-</span><span style="color:#ae81ff">11</span><span style="color:#f92672">-</span><span style="color:#ae81ff">04</span> <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           wait:november <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           <span style="color:#66d9ef">until</span>:<span style="color:#ae81ff">2016</span><span style="color:#f92672">-</span><span style="color:#ae81ff">11</span><span style="color:#f92672">-</span><span style="color:#ae81ff">10</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This means that on 2016-11-10, the task self-destructs, and is automatically deleted. This might be the right thing to do for a birthday card task, but is not suitable for a “Pay the rent” task. Beware!</p>
<p>There is a DOM-based shortcut you can use, to make the command above a little more formulaic:</p>
<details open>
    <summary>perl</summary><pre
        class="chroma codeblock"
      ><code class="language-perl" data-lang="perl"
          ><span style="display:flex;"><span>$ task add Send Alice a birthday card <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           due:2016<span style="color:#f92672">-</span><span style="color:#ae81ff">11</span><span style="color:#f92672">-</span><span style="color:#ae81ff">08</span> <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           scheduled:due<span style="color:#f92672">-</span><span style="color:#ae81ff">4</span>d <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           wait:due<span style="color:#f92672">-</span><span style="color:#ae81ff">7</span>d <span style="color:#f92672">\</span>
</span></span><span style="display:flex;"><span>           <span style="color:#66d9ef">until</span>:due<span style="color:#f92672">+</span><span style="color:#ae81ff">2</span>d</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This is evaluated only at task creation time, so if you change the due date, you also need to change the other dates. Note there is an <code>UNTIL</code> virtual tag to show you all tasks that are set to auto-expire.</p>
<h3 id="other-dates">
  <a class="anchor inpage" href="#other-dates">###</a>Other Dates</h3>
<p>There are other dates associated with a task, but these are more for internal use, and are less useful for you.</p>
<p>Each task has an <code>entry</code> date which records when it was created. Each completed or deleted task has an <code>end</code> date, which records when it was completed or deleted. An active, or started task has a <code>start</code> date, but only while it is in the active state. Finally, every task has a <code>modification</code> date, which records when it was last modified. This is used as a hint when tasks are being synced.</p>
<p>In addition, you may find you have a use case for a different kind of date for your task lists. For example, you may adhere to an agile development process, and a task may be assigned to a sprint, and that sprint may be identified by its end date. You can add arbitrary dates like this to Taskwarrior by defining a 
 (UDA) and then storing that metadata with your tasks. In this case, Taskwarrior will do nothing with your UDA but store it, and let you use it in reports and filters.</p>
<h3 id="urgency">
  <a class="anchor inpage" href="#urgency">###</a>Urgency</h3>
<p>The presence and values of date metadata in your tasks affects the urgency calculations. For example, if a task is blocked by a dependency, the urgency is reduced. Similarly, tasks that are ready have an elevated urgency.</p>
<h2 id="dom---document-object-model">
  <a class="anchor inpage" href="#dom---document-object-model">##</a>DOM - Document Object Model</h2>
<p>Taskwarrior has a Document Object Model, or DOM, which defines a way to reference all the data managed by taskwarrior. You may be familiar with the DOM implemented by web browsers that let you access details on a page programmatically. For example:</p>
<details open>
    <summary>javascript</summary><pre
        class="chroma codeblock"
      ><code class="language-javascript" data-lang="javascript"
          ><span style="display:flex;"><span>document.<span style="color:#a6e22e">getElementById</span>(<span style="color:#e6db74">&#34;myAnchor&#34;</span>).<span style="color:#a6e22e">href</span>;</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Taskwarrior allows the same kind of data access in a similar form, for example:</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>task _get 1.description</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This references the description text of task 1. There is a 
 that queries data using a DOM reference. Let’s see it in action, by first creating a detailed task.</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>task add Buy milk due:tomorrow +store project:Home pri:H
</span></span><span style="display:flex;"><span>task <span style="color:#ae81ff">1</span> info
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name          Value
</span></span><span style="display:flex;"><span>------------- ------------------------------------------
</span></span><span style="display:flex;"><span>ID            <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>Description   Buy milk
</span></span><span style="display:flex;"><span>Status        Pending
</span></span><span style="display:flex;"><span>Project       Home
</span></span><span style="display:flex;"><span>Priority      H
</span></span><span style="display:flex;"><span>Entered       2014-09-28 21:53:59 <span style="color:#f92672">(</span><span style="color:#ae81ff">4</span> seconds<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Due           2014-09-29 00:00:00
</span></span><span style="display:flex;"><span>Last modified 2014-09-28 21:53:59 <span style="color:#f92672">(</span><span style="color:#ae81ff">4</span> seconds<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Tags          store
</span></span><span style="display:flex;"><span>UUID          c0ab2bf6-b4f5-45c2-8420-18ab4f1ba7e7
</span></span><span style="display:flex;"><span>Urgency       16.56
</span></span><span style="display:flex;"><span>                           project     <span style="color:#ae81ff">1</span>  *    1 <span style="color:#f92672">=</span>     <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>                          priority     <span style="color:#ae81ff">1</span>  *    6 <span style="color:#f92672">=</span>     <span style="color:#ae81ff">6</span>
</span></span><span style="display:flex;"><span>                              tags   0.8  *    1 <span style="color:#f92672">=</span>   0.8
</span></span><span style="display:flex;"><span>                               due  0.73  *   12 <span style="color:#f92672">=</span>  8.76</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>All the attributes of that task are available via DOM references. Here are some examples:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.description
</span></span><span style="display:flex;"><span>Buy milk
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ task _get 1.uuid
</span></span><span style="display:flex;"><span>c0ab2bf6-b4f5-45c2-8420-18ab4f1ba7e7
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ task _get c0ab2bf6-b4f5-45c2-8420-18ab4f1ba7e7.id
</span></span><span style="display:flex;"><span>    <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ task _get 1.due.year
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">2014</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ task _get 1.due.julian
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">272</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="supported-references">
  <a class="anchor inpage" href="#supported-references">###</a>Supported References</h3>
<p>system.version: The version of taskwarrior, for example:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get system.version
</span></span><span style="display:flex;"><span>2.4.0</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>system.os: The operating system, for example:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get system.os
</span></span><span style="display:flex;"><span>FreeBSD</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>rc.<name>: Any configuration value default, with any overrides from the <code>.taskrc</code> applied, then with any command line overrides applied last. For example:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get rc.data.location
</span></span><span style="display:flex;"><span>~/.task</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><attribute>: Any task attribute. Note that no task ID or UUID is specified, so this variant is only useful on the command line like this:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Pay rent due:eom wait:<span style="color:#e6db74">&#39;due - 3days&#39;</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Note that ‘due’ is a DOM reference from earlier on the command line.</p>
<p><id>.<attribute>: Any attribute of the specified task ID. For example:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task add Fix the leak depends:3 scheduled:3.due</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This makes the new task dependent on task 3, and scheduled on the due date of task 3. Note that ‘3.due’ is a DOM reference of a specific task.</p>
<p><uuid>.<attribute>: Any attribute of the specified task UUID, as above.</p>
<p>Any attribute that is of type <code>date</code> can be directly accessed as a date, or it can be accessed by the elements of that date. For example:</p>
<ul>
<li><code>&lt;date&gt;.year</code> - 2.4.0 The year, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.year
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">2014</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.month</code> - 2.4.0 The month, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.month
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">9</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.day</code> - 2.4.0 The day of the month, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.day
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">29</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.week</code> - 2.4.0 The week number of the date, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.week
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">40</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.weekday</code> - 2.4.0 The numbered weekday of the date, where 0 is Sunday and 6 is Saturday. For example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.weekday
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">1</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.julian</code> - 2.4.0 The Julian day of the date, which is the day number of the date in the year. For example, January 1st is 1, February 10th is 41. For example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.julian
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">272</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.hour</code> - 2.4.0 The hour of the day, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.hour
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">0</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.minute</code> - 2.4.0 The minute of the hour, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.minute
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">0</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>&lt;date&gt;.second</code> - 2.4.0 The seconds of the minute, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.due.second
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">0</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<p>Tags can be accessed as a single item as an <code>&lt;attribute&gt;</code>, of the individual tags can be accessed:</p>
<ul>
<li><code>tags.&lt;literal&gt;</code> - 2.4.0 Direct access, per-tag, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.tag.home
</span></span><span style="display:flex;"><span>home</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>If the tag is present, it is shown, otherwise the result is blank, and Taskwarrior exits with a non-zero status.
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.tag.DUE
</span></span><span style="display:flex;"><span>DUE
</span></span><span style="display:flex;"><span>$ task _get 1.tag.OVERDUE</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>Workѕ for virtual tags too, in the same manner.</li>
</ul>
<p>Annotations are compound data structures, with two elements, which are <code>description</code> and <code>entry</code>. Annotations are accessed by an ordinal.</p>
<ul>
<li><code>annotations.&lt;N&gt;.description</code> - 2.4.0 The description of the Nth annotation, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.annotations.0.description</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li><code>annotations.&lt;N&gt;.entry</code> - 2.4.0 The creation timestamp of the Nth annotation, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.annotations.0.entry</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>Note that because <code>entry</code> is of type <code>date</code>, the individual elements can be addressed, as above, for example:
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>$ task _get 1.annotations.0.entry.year
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">2014</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
</ul>
<p>UDA values can be accessed in the same manner.</p>
]]></content:encoded></item><item><title>豆瓣记录导入obsidian</title><link>https://hiraethecho.github.io/docs/software/obsidian_douban/</link><pubDate>Wed, 28 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/obsidian_douban/</guid><description>&lt;h1 id="obsidian-和豆瓣"&gt;
&lt;a class="anchor inpage" href="#obsidian-%e5%92%8c%e8%b1%86%e7%93%a3"&gt;#&lt;/a&gt;obsidian 和豆瓣&lt;/h1&gt;
&lt;h2 id="plugins"&gt;
&lt;a class="anchor inpage" href="#plugins"&gt;##&lt;/a&gt;plugins&lt;/h2&gt;
&lt;p&gt;发现一些插件可以把豆瓣的信息导入到obsidian，可以作为阅读管理统计。&lt;/p&gt;
&lt;p&gt;首先是豆瓣的
，可以登陆豆瓣账户，然后可以同步自己的书影音。&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="obsidian-和豆瓣">
  <a class="anchor inpage" href="#obsidian-%e5%92%8c%e8%b1%86%e7%93%a3">#</a>obsidian 和豆瓣</h1>
<h2 id="plugins">
  <a class="anchor inpage" href="#plugins">##</a>plugins</h2>
<p>发现一些插件可以把豆瓣的信息导入到obsidian，可以作为阅读管理统计。</p>
<p>首先是豆瓣的
，可以登陆豆瓣账户，然后可以同步自己的书影音。</p>
<p>
导出划线，这个和豆瓣的不能是同一个文件，会有同步的问题。可以看完了再把划线移动到其他文档。</p>
<p>用bookshelf来查看，和记录阅读进度。这个似乎可以用base之类的方法代替。</p>
<h2 id="模板配置">
  <a class="anchor inpage" href="#%e6%a8%a1%e6%9d%bf%e9%85%8d%e7%bd%ae">##</a>模板配置</h2>
<h3 id="豆瓣">
  <a class="anchor inpage" href="#%e8%b1%86%e7%93%a3">###</a>豆瓣</h3>
<p>book</p>
<details open>
    <summary>temple</summary><pre
        class="codeblock"
      ><code class="language-temple" data-lang="temple">---
title: {{title}}
lists: {{type}}
score: {{score}}
rating: {{myRating}}
originalTitle: {{originalTitle}}
published: {{datePublished}}
pages: {{totalPage}}
author: {{author}}
tags: {{myTags}}
state: {{myState}}
url: {{url}}
country: {{country}}
language: {{language}}
time: {{time}}
comment: {{desc}}
cover:
---

# {{title}}

![image]({{image}})

comment: {{desc}}

{{myComment}}

doubanId: {{id}}

## log</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>movie</p>
<details open>
    <summary>template</summary><pre
        class="codeblock"
      ><code class="language-template" data-lang="template">---
doubanId: {{id}}
title: {{title}}
lists: {{type}}
score: {{score}}
rating: {{myRating}}
originalTitle: {{originalTitle}}
published: {{datePublished}}
director: {{director}}
actor: {{actor}}
author: {{author}}
tags: {{myTags}}
url: {{url}}
aliases: {{aliases}}
country: {{country}}
language: {{language}}
time: {{time}}
comment: {{desc}}
cover:
---

# {{title}}
![]({{image}})
IMDb: {{IMDb}}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="weread">
  <a class="anchor inpage" href="#weread">###</a>weread</h3>
<p>这个是只导出划线和高亮没有评论，因为我不怎么在微信阅读写评论。</p>
<details open>
    <summary>template</summary><pre
        class="codeblock"
      ><code class="language-template" data-lang="template">---
title: {{ metaData.title }}
lists: book
author: {{ metaData.author }}
time: {{ metaData.publishTime }}
comment: {{ metaData.intro }}
cover: {{ metaDate.cover }}
---

![{{metaData.title}}|200]({{metaData.cover}})

作者： {{metaData.author}}
简介： {{metaData.intro}}
类型： {{metaData.category}}

## highlights

{% for chapter in chapterHighlights %}### {{chapter.chapterTitle}}

{% for highlight in chapter.highlights %}- {{ highlight.markText |trim }}
{% endfor %}
{% endfor %}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h3 id="bookshelf">
  <a class="anchor inpage" href="#bookshelf">###</a>bookshelf</h3>
<p>这个json可以直接放在<code>obsidian-repo/.obsidian/plugins/bookshelf/data.json</code>中。</p>
<details open>
    <summary>json</summary><pre
        class="chroma codeblock"
      ><code class="language-json" data-lang="json"
          ><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;settingsVersion&#34;</span>: <span style="color:#ae81ff">20250408</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;booksFolder&#34;</span>: <span style="color:#e6db74">&#34;gallery&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;bookProperties&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;cover&#34;</span>: <span style="color:#e6db74">&#34;cover&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;author&#34;</span>: <span style="color:#e6db74">&#34;author&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;published&#34;</span>: <span style="color:#e6db74">&#34;published&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;pages&#34;</span>: <span style="color:#e6db74">&#34;pages&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;tags&#34;</span>: <span style="color:#e6db74">&#34;tags&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;rating&#34;</span>: <span style="color:#e6db74">&#34;rating&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;lists&#34;</span>: <span style="color:#e6db74">&#34;lists&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;comment&#34;</span>: <span style="color:#e6db74">&#34;comment&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;links&#34;</span>: <span style="color:#e6db74">&#34;links&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;series&#34;</span>: <span style="color:#e6db74">&#34;series&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;positionInSeries&#34;</span>: <span style="color:#e6db74">&#34;position-in-series&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;duration&#34;</span>: <span style="color:#e6db74">&#34;duration&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;bookNote&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;enabled&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;heading&#34;</span>: <span style="color:#e6db74">&#34;log&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;dateFormat&#34;</span>: <span style="color:#e6db74">&#34;yyyy-MM-dd&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;patterns&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;started&#34;</span>: <span style="color:#e6db74">&#34;{date}: Started&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;finished&#34;</span>: <span style="color:#e6db74">&#34;{date}: Finished&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;abandoned&#34;</span>: <span style="color:#e6db74">&#34;{date}: Abandoned&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;absoluteProgress&#34;</span>: <span style="color:#e6db74">&#34;{date}: {start}-{end}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;relativeProgress&#34;</span>: <span style="color:#e6db74">&#34;{date}: {end}&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;dailyNote&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;enabled&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;heading&#34;</span>: <span style="color:#e6db74">&#34;Reading&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;patterns&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;started&#34;</span>: <span style="color:#e6db74">&#34;Started {{book}}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;finished&#34;</span>: <span style="color:#e6db74">&#34;Finished {book}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;abandoned&#34;</span>: <span style="color:#e6db74">&#34;Abandoned {book}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;absoluteProgress&#34;</span>: <span style="color:#e6db74">&#34;Read {book}: {start}-{end}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;relativeProgress&#34;</span>: <span style="color:#e6db74">&#34;Read {book}: {end}&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;readingProgress&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;newEntryLocation&#34;</span>: <span style="color:#e6db74">&#34;bookNote&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;previousVersion&#34;</span>: <span style="color:#e6db74">&#34;0.18.0&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;showReleaseNotes&#34;</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="解释">
  <a class="anchor inpage" href="#%e8%a7%a3%e9%87%8a">##</a>解释</h2>
<p>我的文件放在<code>obsidian-repo/gallery/</code>目录下，用bookshelf的lists来区分书、电影和音乐</p>
]]></content:encoded></item><item><title>Latex Tricks</title><link>https://hiraethecho.github.io/docs/software/latex-trick/</link><pubDate>Sun, 04 May 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/latex-trick/</guid><description>&lt;h1 id="latex-tricks"&gt;
&lt;a class="anchor inpage" href="#latex-tricks"&gt;#&lt;/a&gt;Latex tricks&lt;/h1&gt;
&lt;h2 id="note"&gt;
&lt;a class="anchor inpage" href="#note"&gt;##&lt;/a&gt;note&lt;/h2&gt;
&lt;h2 id="comment"&gt;
&lt;a class="anchor inpage" href="#comment"&gt;##&lt;/a&gt;comment&lt;/h2&gt;
&lt;p&gt;use following to comment mulilines:&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;tex&lt;/summary&gt;&lt;pre
class="chroma codeblock"
&gt;&lt;code class="language-tex" data-lang="tex"
&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\iffalse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;comments
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;another line
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code
&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;details open&gt;
&lt;summary&gt;tex&lt;/summary&gt;&lt;pre
class="chroma codeblock"
&gt;&lt;code class="language-tex" data-lang="tex"
&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\newcommand&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;\chen&lt;/span&gt;}[1]{{&lt;span style="color:#66d9ef"&gt;\textcolor&lt;/span&gt;{red}{[Chen: #1]}}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\newcommand&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;\liu&lt;/span&gt;}[1]{{&lt;span style="color:#66d9ef"&gt;\textcolor&lt;/span&gt;{magenta}{[Liu: #1]}}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\newcommand&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;\wang&lt;/span&gt;}[1]{{&lt;span style="color:#66d9ef"&gt;\textcolor&lt;/span&gt;{blue}{[Wang: #1]}}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\begin&lt;/span&gt;{document}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\liu&lt;/span&gt;{test}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\chen&lt;/span&gt;{test}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\wang&lt;/span&gt;{test}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;\end&lt;/span&gt;{document}&lt;/span&gt;&lt;/span&gt;&lt;/code
&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;h2 id="diff"&gt;
&lt;a class="anchor inpage" href="#diff"&gt;##&lt;/a&gt;diff&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;latexdiff&lt;/code&gt; to diff in pdf. tldr:&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="latex-tricks">
  <a class="anchor inpage" href="#latex-tricks">#</a>Latex tricks</h1>
<h2 id="note">
  <a class="anchor inpage" href="#note">##</a>note</h2>
<h2 id="comment">
  <a class="anchor inpage" href="#comment">##</a>comment</h2>
<p>use following to comment mulilines:</p>
<details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span><span style="color:#66d9ef">\iffalse</span>
</span></span><span style="display:flex;"><span>comments
</span></span><span style="display:flex;"><span>another line
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\fi</span></span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\newcommand</span>{<span style="color:#66d9ef">\chen</span>}[1]{{<span style="color:#66d9ef">\textcolor</span>{red}{[Chen: #1]}}}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\newcommand</span>{<span style="color:#66d9ef">\liu</span>}[1]{{<span style="color:#66d9ef">\textcolor</span>{magenta}{[Liu: #1]}}}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\newcommand</span>{<span style="color:#66d9ef">\wang</span>}[1]{{<span style="color:#66d9ef">\textcolor</span>{blue}{[Wang: #1]}}}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\begin</span>{document}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\liu</span>{test}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\chen</span>{test}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\wang</span>{test}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\end</span>{document}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="diff">
  <a class="anchor inpage" href="#diff">##</a>diff</h2>
<p><code>latexdiff</code> to diff in pdf. tldr:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">  Determine differences between two LaTeX files.
  More information: &lt;https://ctan.org/pkg/latexdiff&gt;.

  Determine changes between different versions of a LaTeX file (the resulting LaTeX file can be compiled to show differences underlined):

      latexdiff old.tex new.tex &gt; diff.tex

  Determine changes between different versions of a LaTeX file by highlighting differences in boldface:

      latexdiff --type=BOLD old.tex new.tex &gt; diff.tex

  Determine changes between different versions of a LaTeX file, and display minor changes in equations with both added and deleted graphics:

      latexdiff --math-markup=fine --graphics-markup=both old.tex new.tex &gt; diff.tex</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p><code>git-latexdiff</code> compare pdf in git history</p>
<p>Important options:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Usage: git latexdiff [options] OLD [NEW]
OLD and NEW are Git revision identifiers. NEW defaults to HEAD.
If &#34;--&#34; is used for NEW, then diff against the working directory.
    --latex               run latex instead of pdflatex
    --xelatex             run xelatex instead of pdflatex
    --lualatex            run lualatex instead of pdflatex
    --main &lt;file&gt;         name of the main LaTeX, R Sweave,
    --tmpdirprefix        where temporary directory will be created (default: /tmp).
                            Relative path will use repository root as a base
    --ignore-latex-errors keep on going even if latex gives errors, so long as
                          a PDF file is produced</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>For example, use <code>git latexdiff HEAD -- --tmpdirprefix tmp --main main.tex</code> to check differences between worktree and last commit.</p>
<h2 id="picture">
  <a class="anchor inpage" href="#picture">##</a>picture</h2>
<p>If fix position:</p>
<details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span><span style="color:#66d9ef">\usepackage</span>{float} <span style="color:#75715e">% 在导言区添加
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">\usepackage</span>{graphicx} <span style="color:#75715e">% 用于插入图片
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\begin</span>{figure}[H] <span style="color:#75715e">% 使用 [H] 固定位置
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">\centering</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\includegraphics</span><span style="color:#a6e22e">[width=0.8\textwidth]</span>{example-image}
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\caption</span>{固定位置的图片}
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\label</span>{fig:example}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\end</span>{figure}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>centering:</p>
<details open>
    <summary>tex</summary><pre
        class="chroma codeblock"
      ><code class="language-tex" data-lang="tex"
          ><span style="display:flex;"><span><span style="color:#66d9ef">\usepackage</span>{graphicx} <span style="color:#75715e">% 在导言区添加
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\centering</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\includegraphics</span><span style="color:#a6e22e">[width=0.8\textwidth]</span>{example-image}
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">\par</span> <span style="color:#75715e">% 确保居中生效
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script>]]></content:encoded></item><item><title>Write latex with neovim</title><link>https://hiraethecho.github.io/docs/software/vimtex/</link><pubDate>Sun, 27 Apr 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/vimtex/</guid><description>&lt;h1 id="write-latex-with-neovim"&gt;
&lt;a class="anchor inpage" href="#write-latex-with-neovim"&gt;#&lt;/a&gt;Write latex with neovim&lt;/h1&gt;
&lt;p&gt;\(\latex\)&lt;/p&gt;
&lt;h2 id="vimtex"&gt;
&lt;a class="anchor inpage" href="#vimtex"&gt;##&lt;/a&gt;vimtex&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;vimtex&lt;/code&gt;基本上是提供了全套的功能，包括&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目录，标签等&lt;/li&gt;
&lt;li&gt;各种环境，&lt;code&gt;insert&lt;/code&gt;模式下的各种snippets，&lt;code&gt;normal&lt;/code&gt;模式下的文本对象和命令&lt;/li&gt;
&lt;li&gt;编译，报错&lt;/li&gt;
&lt;li&gt;正向搜索（从tex定位到pdf）和反向搜索（从pdf定位到tex）&lt;/li&gt;
&lt;li&gt;conceal （有点影响性能）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而且帮助文档非常详尽，维护积极，而且&lt;code&gt;vim&lt;/code&gt;上也能用&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="write-latex-with-neovim">
  <a class="anchor inpage" href="#write-latex-with-neovim">#</a>Write latex with neovim</h1>
<p>\(\latex\)</p>
<h2 id="vimtex">
  <a class="anchor inpage" href="#vimtex">##</a>vimtex</h2>
<p><code>vimtex</code>基本上是提供了全套的功能，包括</p>
<ul>
<li>目录，标签等</li>
<li>各种环境，<code>insert</code>模式下的各种snippets，<code>normal</code>模式下的文本对象和命令</li>
<li>编译，报错</li>
<li>正向搜索（从tex定位到pdf）和反向搜索（从pdf定位到tex）</li>
<li>conceal （有点影响性能）</li>
</ul>
<p>而且帮助文档非常详尽，维护积极，而且<code>vim</code>上也能用</p>
<p>缺点几乎没有，除了对与某些信奉unix哲学<em>做一件事并做到最好</em>的人（比如说我）来说有些臃肿。另一个是预设置的快捷键很多，但不一定符合所有人习惯（又是我）。</p>
<h2 id="latex">
  <a class="anchor inpage" href="#latex">##</a>latex</h2>
<p>首先需要一个<code>latex</code>发行版，比如<code>texlive</code>或者<code>miktex</code>。实际编译过程很复杂，为了生成目录和参考文献需要多次编译。但是<code>latexmk</code>可以帮助完成复杂的顺序。最重要的是，<code>latexmk</code>可以监听文本变化，自动重新编译，以此实现“实时”预览。</p>
<blockquote class="alert alert-tip">
      <p class="alert-heading">实际上不是实时。会在每次保存文件时编译，所以<code>insert</code>模式下敲字时并不会更新。另一方面还取决于编译速度。</p></blockquote><p>在<code>archlinux</code>上，可以安装整个<code>texlive</code>，如果觉得太臃肿也可以安装其中部分包，例如我只安装了</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">texlive-bibtexextra
texlive-binextra
texlive-langchinese
texlive-latexextra
texlive-mathscience
texlive-pstricks
texlive-xetex</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>除此之外还有<code>tectonic</code>等可用，但是难以实现实时预览。</p>
<blockquote class="alert alert-note">
      <p class="alert-heading">可以用texpresso</p></blockquote><h2 id="lsp">
  <a class="anchor inpage" href="#lsp">##</a>lsp</h2>
<p><code>texlab</code></p>
<p><code>tex-fmt</code></p>
<h2 id="compile">
  <a class="anchor inpage" href="#compile">##</a>compile</h2>
<p>原则上可以直接用命令行编译。但是既然在<code>neovim</code>里，可以用插件封装的命令。</p>
<p>用<code>vimtex</code>或<code>texlab</code></p>
<h2 id="inverse-and-reverse-search">
  <a class="anchor inpage" href="#inverse-and-reverse-search">##</a>inverse and reverse search</h2>
<h2 id="snippets">
  <a class="anchor inpage" href="#snippets">##</a>snippets</h2>
<h3 id="mathzone">
  <a class="anchor inpage" href="#mathzone">###</a>mathzone</h3>
<p>为了在文本和数学公式环境中使用不同的片段，例如<code>CC</code>只在数学公式中自动展开为<code>\mathbb{C}</code>，需要对能检测数学环境。</p>
<p>最简单的方法是调用<code>vimtex</code>的功能。</p>
<p>用<code>python</code>检测。</p>
<p>用treesitter检测。</p>
<h3 id="engine">
  <a class="anchor inpage" href="#engine">###</a>engine</h3>
<p>UltiSnip</p>
<p>LuaSnip</p>
]]></content:encoded></item><item><title>My Neovim Config</title><link>https://hiraethecho.github.io/docs/software/nvim-config/</link><pubDate>Mon, 18 Nov 2024 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/nvim-config/</guid><description>&lt;h1 id="my-neovim"&gt;
&lt;a class="anchor inpage" href="#my-neovim"&gt;#&lt;/a&gt;My neovim&lt;/h1&gt;
&lt;p&gt;My
on github.&lt;/p&gt;
&lt;p&gt;There is a
of my config, for fun.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using nvim as a code editor, mainly for latex and markdown.&lt;/p&gt;
&lt;h2 id="usage"&gt;
&lt;a class="anchor inpage" href="#usage"&gt;##&lt;/a&gt;Usage&lt;/h2&gt;
&lt;h3 id="latex"&gt;
&lt;a class="anchor inpage" href="#latex"&gt;###&lt;/a&gt;latex&lt;/h3&gt;
&lt;p&gt;using vimtex to detect math environment, and texlab lsp to complie.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;cmp&lt;/del&gt; blink.cmp and &lt;del&gt;ultisnips&lt;/del&gt; luasnip to enhance editing.&lt;/p&gt;
&lt;p&gt;check
.&lt;/p&gt;
&lt;h3 id="markdown"&gt;
&lt;a class="anchor inpage" href="#markdown"&gt;###&lt;/a&gt;markdown&lt;/h3&gt;
&lt;p&gt;mkdnflow to enhance.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;&lt;kbd&gt;leader&lt;/kbd&gt;&lt;kbd&gt;m&lt;/kbd&gt;&lt;kbd&gt;p&lt;/kbd&gt; to open markdown-preview&lt;/del&gt; This is not necessary. Just render it in the terminal.&lt;/p&gt;
&lt;h2 id="detail-configure"&gt;
&lt;a class="anchor inpage" href="#detail-configure"&gt;##&lt;/a&gt;Detail Configure&lt;/h2&gt;
&lt;h3 id="options"&gt;
&lt;a class="anchor inpage" href="#options"&gt;###&lt;/a&gt;options&lt;/h3&gt;
&lt;p&gt;in /lua/config/options.lua&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="my-neovim">
  <a class="anchor inpage" href="#my-neovim">#</a>My neovim</h1>
<p>My 
 on github.</p>
<p>There is a 
 of my config, for fun.</p>
<p>I&rsquo;m using nvim as a code editor, mainly for latex and markdown.</p>
<h2 id="usage">
  <a class="anchor inpage" href="#usage">##</a>Usage</h2>
<h3 id="latex">
  <a class="anchor inpage" href="#latex">###</a>latex</h3>
<p>using vimtex to detect math environment, and texlab lsp to complie.</p>
<p><del>cmp</del> blink.cmp and <del>ultisnips</del> luasnip to enhance editing.</p>
<p>check 
.</p>
<h3 id="markdown">
  <a class="anchor inpage" href="#markdown">###</a>markdown</h3>
<p>mkdnflow to enhance.</p>
<p><del><kbd>leader</kbd><kbd>m</kbd><kbd>p</kbd> to open markdown-preview</del> This is not necessary. Just render it in the terminal.</p>
<h2 id="detail-configure">
  <a class="anchor inpage" href="#detail-configure">##</a>Detail Configure</h2>
<h3 id="options">
  <a class="anchor inpage" href="#options">###</a>options</h3>
<p>in /lua/config/options.lua</p>
<h3 id="lsp">
  <a class="anchor inpage" href="#lsp">###</a>lsp</h3>
<p>Config lsp by native nvim. Steal serval functions from nvim-lspconfig.</p>
<h3 id="plugins">
  <a class="anchor inpage" href="#plugins">###</a>plugins</h3>
<p>I am using lazy.nvim as my plugins manager. Plugins are divided in serval
classes, and following are some of mostly used plugins:</p>
<ul>
<li>edit: enhance for editing
<ul>
<li><del>
,</del></li>
<li>
</li>
<li>
,</li>
<li>
, gJ and gK to split or joint</li>
<li>treej</li>
<li>
, 中文输入自动切换</li>
<li>
,</li>
<li><del>
</del> zen mode, focus on editing 
</li>
<li>
, like a temporary git</li>
<li>
, translate words</li>
<li>
, jump anywhere</li>
<li><del>
,</del></li>
<li><del>
, commute ultisnips with cmp</del></li>
<li><del>
, lsp source</del></li>
<li><del>
, source from other buffers</del></li>
<li><del>
, path source</del></li>
<li>
</li>
<li>
, snippets</li>
<li>
, copilot source</li>
</ul>
</li>
<li>editor: enhance for latex and markdown
<ul>
<li>
, for latex</li>
<li>
, preview md in browser</li>
<li>
</li>
<li><del>
,</del> render md in nvim</li>
<li>
, help edit list, table etc in nvim</li>
</ul>
</li>
<li>git: using git in nvim
<ul>
<li>
, show git status at left, jump by hunks</li>
<li>
, show diff with history files</li>
<li>neogit</li>
</ul>
</li>
<li>lsp:
<ul>
<li><del>
, Configure lsp</del></li>
<li><del>
, install lsp</del></li>
<li><del>
, jump by definitions, references etc</del></li>
<li>
, jump by symbols etc</li>
</ul>
</li>
<li>file explorer:
<ul>
<li><del>
, file tree</del></li>
<li>
, yazi (tui file manager) in float terminal</li>
<li>snacks.picker.explorer, part of 
</li>
<li>
</li>
</ul>
</li>
<li>fuzzy finder
<ul>
<li><del>
,</del></li>
<li>snacks.picker, part of 
</li>
</ul>
</li>
<li>ui:
<ul>
<li>
, my theme</li>
<li>
, show color like <code>#123dfe</code></li>
<li>
, modeline, bufferline etc</li>
<li>
, show indent line etc</li>
</ul>
</li>
<li>enhance native functions:
<ul>
<li>
, plugin manager</li>
<li>
, <code>:</code> cmd and <code>/</code> search</li>
<li>
, show leader key sequence</li>
<li>
, search and replace</li>
<li>
, show start up time</li>
<li>
, sudo write files</li>
</ul>
</li>
</ul>
<h2 id="miscellanea">
  <a class="anchor inpage" href="#miscellanea">##</a>miscellanea</h2>
]]></content:encoded></item><item><title>zotero</title><link>https://hiraethecho.github.io/docs/software/zotero/</link><pubDate>Mon, 13 Nov 2023 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/zotero/</guid><description>&lt;h1 id="zotero"&gt;
&lt;a class="anchor inpage" href="#zotero"&gt;#&lt;/a&gt;Zotero&lt;/h1&gt;
&lt;h2 id="install-and-basic-setting"&gt;
&lt;a class="anchor inpage" href="#install-and-basic-setting"&gt;##&lt;/a&gt;Install and basic setting&lt;/h2&gt;
&lt;h2 id="plugins"&gt;
&lt;a class="anchor inpage" href="#plugins"&gt;##&lt;/a&gt;Plugins&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;zotero 7:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;常用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zotero attanger&lt;/li&gt;
&lt;li&gt;Del item with Attachment&lt;/li&gt;
&lt;li&gt;Ethereal Reference&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zotero better notes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;没必要但可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ethereal Style&lt;/li&gt;
&lt;li&gt;Attachment Scanner&lt;/li&gt;
&lt;li&gt;arXiv Workflow for zotero&lt;/li&gt;
&lt;li&gt;Zoplicate&lt;/li&gt;
&lt;li&gt;Linter for zotero&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sync"&gt;
&lt;a class="anchor inpage" href="#sync"&gt;##&lt;/a&gt;Sync&lt;/h2&gt;
&lt;p&gt;using &lt;del&gt;zotmoov&lt;/del&gt; attanger to move files&lt;/p&gt;
&lt;p&gt;zotero 7 to rename:&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;{{ title case=&amp;#34;snake&amp;#34; }}{{ creators case=&amp;#34;snake&amp;#34; prefix=&amp;#34;_&amp;#34; max=&amp;#34;1&amp;#34;}}{{ year prefix=&amp;#34;_&amp;#34; }}&lt;/code&gt;&lt;button onclick="copyCode(this)" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;script&gt;
function copyCode(btn) {
const code = btn.previousElementSibling.textContent.trim();
navigator.clipboard.writeText(code).then(() =&gt; {
btn.innerText = "copied";
setTimeout(() =&gt; (btn.innerText = "copy"), 2000);
});
}
&lt;/script&gt;&lt;p&gt;use any cloud drive to sync. I&amp;rsquo;m using koofr.&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="zotero">
  <a class="anchor inpage" href="#zotero">#</a>Zotero</h1>
<h2 id="install-and-basic-setting">
  <a class="anchor inpage" href="#install-and-basic-setting">##</a>Install and basic setting</h2>
<h2 id="plugins">
  <a class="anchor inpage" href="#plugins">##</a>Plugins</h2>
<p><strong>zotero 7:</strong></p>
<p>常用：</p>
<ul>
<li>Zotero attanger</li>
<li>Del item with Attachment</li>
<li>Ethereal Reference</li>
</ul>
<p>好用：</p>
<ul>
<li>zotero better notes</li>
</ul>
<p>没必要但可以：</p>
<ul>
<li>Ethereal Style</li>
<li>Attachment Scanner</li>
<li>arXiv Workflow for zotero</li>
<li>Zoplicate</li>
<li>Linter for zotero</li>
</ul>
<h2 id="sync">
  <a class="anchor inpage" href="#sync">##</a>Sync</h2>
<p>using <del>zotmoov</del> attanger to move files</p>
<p>zotero 7 to rename:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ title case=&#34;snake&#34; }}{{ creators case=&#34;snake&#34; prefix=&#34;_&#34; max=&#34;1&#34;}}{{ year prefix=&#34;_&#34; }}</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>use any cloud drive to sync. I&rsquo;m using koofr.</p>
<h2 id="zotero-better-notes">
  <a class="anchor inpage" href="#zotero-better-notes">##</a>zotero better notes</h2>
<p>用来
</p>
<p><strong>templates:</strong> you can copy these:</p>
<details open>
    <summary>quickinsert</summary><pre
        class="codeblock"
      ><code class="language-quickinsert" data-lang="quickinsert"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[QuickInsertV2]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T07:59:45.835Z&#34;
content: |-
  // @use-markdown
  &lt;a href=&#34;${link}&#34;&gt;${linkText}&lt;/a&gt; [md](/wiki/math/zotero/${subNoteItem.getNoteTitle ? subNoteItem.getNoteTitle().replace(/[/\\?%*:|&#34;&lt;&gt; ]/g, &#34;-&#34;) &#43; &#34;-&#34;:&#34;&#34;}${subNoteItem.key})</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>quickimport</summary><pre
        class="codeblock"
      ><code class="language-quickimport" data-lang="quickimport"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[QuickImportV2]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T05:54:37.696Z&#34;
content: |-
  &lt;blockquote&gt;
  ${{
    return await Zotero.BetterNotes.api.convert.link2html(link, {noteItem, dryRun: _env.dryRun});
  }}$
  &lt;/blockquote&gt;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>quicknote</summary><pre
        class="codeblock"
      ><code class="language-quicknote" data-lang="quicknote"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[QuickNoteV5]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T05:54:55.255Z&#34;
content: |-
  ${{
    let res = &#34;&#34;;
    if (annotationItem.annotationComment) {
      res &#43;= await Zotero.BetterNotes.api.convert.md2html(
        annotationItem.annotationComment
      );
    } else {
  	res &#43;= &#34;No comment&#34;;
    }
    return res;
  }}$

  // @use-markdown
  ***
  ${{
  	let res = &#34;&#34;;
    res &#43;= await Zotero.BetterNotes.api.convert.annotations2html([annotationItem], {noteItem, ignoreComment: true});
    return res;
  }}$</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>exportmdfilename</summary><pre
        class="codeblock"
      ><code class="language-exportmdfilename" data-lang="exportmdfilename"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[ExportMDFileNameV2]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T05:55:24.890Z&#34;
content: |-
  ${(noteItem.getNoteTitle ? noteItem.getNoteTitle().replace(/[/\\?%*:|&#34;&lt;&gt; ]/g, &#34;-&#34;) &#43; &#34;-&#34; : &#34;&#34;)}${noteItem.key}.md</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>exportmdfileheader</summary><pre
        class="codeblock"
      ><code class="language-exportmdfileheader" data-lang="exportmdfileheader"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[ExportMDFileHeaderV2]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T05:55:34.047Z&#34;
content: |-
  ${{
    let header = {};
    header.tags = noteItem.getTags().map((_t) =&gt; _t.tag);
    header.parent = noteItem.parentItem
      ? noteItem.parentItem.getField(&#34;title&#34;)
      : &#34;&#34;;
    header.collections = (
      await Zotero.Collections.getCollectionsContainingItems([
        (noteItem.parentItem || noteItem).id,
      ])
    ).map((c) =&gt; c.name);
    return JSON.stringify(header);
  }}$</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><details open>
    <summary>exportmdfilecontent</summary><pre
        class="codeblock"
      ><code class="language-exportmdfilecontent" data-lang="exportmdfilecontent"># This template is specifically for importing/sharing, using better
# notes &#39;import from clipboard&#39;: copy the content and
# goto Zotero menu bar, click Tools-&gt;New Template from Clipboard.
# Do not copy-paste this to better notes template editor directly.
name: &#34;[ExportMDFileContent]&#34;
zoteroVersion: &#34;7.0.9.SOURCE.fadbf3d2d&#34;
pluginVersion: &#34;2.0.18&#34;
savedAt: &#34;2024-11-07T05:56:22.434Z&#34;
content: |-
  ${{
    let start = mdContent;
    let rmspan = start.replace(/&lt;\/?span.*?&gt;/g,&#39;&#39;);
    let pdflink = rmspan.replace(/(&lt;a .*?open.*?&gt;)“(.*?)”/g,&#39;$2 $1(pdf)&lt;/a&gt;&#39;);
    let dir2zotero = pdflink.replace(/&lt;a href.*?zhref=&#34;(.*?)&#34; ztype.*?&gt;/g,&#39;&lt;a href=&#34;$1&#34;&gt;&#39;);
    return dir2zotero;
  }}$</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>annotation will be exported as</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">&lt;span class=&#34;highlight&#34; data-annotation=&#34;&lt;data-annotation&gt;&#34; ztype=&#34;zhighlight&#34;&gt;&lt;a href=&#34;zotero://open/library/items/G4BKVA2X?page=2&amp;#x26;annotation=LZLEYYRJ&#34;&gt;“&lt;content&gt;”&lt;/a&gt;&lt;/span&gt; &lt;span class=&#34;citation&#34; data-citation=&#34;&lt;citation&gt;&#34; ztype=&#34;zcitation&#34;&gt;(&lt;span class=&#34;citation-item&#34;&gt;&lt;a href=&#34;zotero://select/library/items/GLXUZZJT&#34;&gt;&lt;/a&gt;&lt;/span&gt;)&lt;/span&gt;</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>the color of annotation is coded as <code>%23&lt;rgb&gt;</code> in <code>&lt;data-annotation&gt;</code>, for
example blue (#2ea8e5) annotation is <code>%232ea8e5</code></p>
]]></content:encoded></item><item><title>obsidian使用与插件</title><link>https://hiraethecho.github.io/docs/software/obsidian/</link><pubDate>Sat, 11 Nov 2023 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/obsidian/</guid><description>&lt;h1 id="obsidian"&gt;
&lt;a class="anchor inpage" href="#obsidian"&gt;#&lt;/a&gt;obsidian&lt;/h1&gt;
&lt;h2 id="plugins"&gt;
&lt;a class="anchor inpage" href="#plugins"&gt;##&lt;/a&gt;plugins&lt;/h2&gt;
&lt;p&gt;常用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;remotely save (using webdav to synchronize files)&lt;/li&gt;
&lt;li&gt;obsidian web clipper 浏览器插件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;digital garden&lt;/li&gt;
&lt;li&gt;share as gist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;没必要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gistr: 和&lt;code&gt;share as gist&lt;/code&gt;比不能添加description&lt;/li&gt;
&lt;li&gt;find orphaned files and broken links&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;about vim:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vim toggle&lt;/li&gt;
&lt;li&gt;vim input method switch&lt;/li&gt;
&lt;li&gt;vimrc&lt;/li&gt;
&lt;li&gt;edit in neovim&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;展示：&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="obsidian">
  <a class="anchor inpage" href="#obsidian">#</a>obsidian</h1>
<h2 id="plugins">
  <a class="anchor inpage" href="#plugins">##</a>plugins</h2>
<p>常用：</p>
<ul>
<li>remotely save (using webdav to synchronize files)</li>
<li>obsidian web clipper 浏览器插件</li>
</ul>
<p>好用：</p>
<ul>
<li>git</li>
<li>digital garden</li>
<li>share as gist</li>
</ul>
<p>没必要：</p>
<ul>
<li>gistr: 和<code>share as gist</code>比不能添加description</li>
<li>find orphaned files and broken links</li>
</ul>
<p>about vim:</p>
<ul>
<li>vim toggle</li>
<li>vim input method switch</li>
<li>vimrc</li>
<li>edit in neovim</li>
</ul>
<p>展示：</p>
<ul>
<li>
</li>
<li>dataview (display files by metadata)</li>
<li>kanban (plan things, especially something with many stages)不习惯</li>
</ul>
<h2 id="theme">
  <a class="anchor inpage" href="#theme">##</a>theme</h2>
<ul>
<li>nord</li>
<li>minimal</li>
</ul>
<h2 id="sync">
  <a class="anchor inpage" href="#sync">##</a>sync</h2>
<p>因为
，所以重点是同步obsidian仓库。云端是github和webdav（koofr），在两台电脑（都是win/linux双系统）和手机、ipad，总计6个仓库同步。要注意的是</p>
<ul>
<li>手机和ipad很难用git</li>
<li>设置需要忽略的文件</li>
<li>考虑用插件还是外部命令</li>
<li>各种方式下的冲突文件处理</li>
</ul>
<h2 id="editor">
  <a class="anchor inpage" href="#editor">##</a>editor</h2>
<p>虽然用obsidian管理markdown文件，但编辑器可以用其他的。比如
.</p>
]]></content:encoded></item><item><title>收集一些工具</title><link>https://hiraethecho.github.io/docs/software/softwares/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/software/softwares/</guid><description>各种地方看到的有趣的工具，还没或不想写详细使用的文档</description><content:encoded><![CDATA[<h1 id="applications-tools-softwares">
  <a class="anchor inpage" href="#applications-tools-softwares">#</a>Applications Tools Softwares</h1>
<h2 id="shell-and-terminal">
  <a class="anchor inpage" href="#shell-and-terminal">##</a>shell and terminal</h2>
<ul>
<li>
<p>zsh</p>
</li>
<li>
<p>starship</p>
</li>
<li>
<p>st</p>
<ul>
<li>tabbed</li>
</ul>
</li>
<li>
<p>foot</p>
</li>
<li>
<p>kitty</p>
</li>
<li>
<p>mtm</p>
</li>
<li>
<p>tmux</p>
</li>
<li>
<p>tuios</p>
</li>
</ul>
<h2 id="wm">
  <a class="anchor inpage" href="#wm">##</a>wm</h2>
<ul>
<li>X
<ul>
<li>dwm</li>
<li>xorg-xeye: help to find xwayland app while running wayland</li>
<li>xev wev: key stroke under X and wayland</li>
</ul>
</li>
<li>wayland
<ul>
<li>
</li>
<li>river</li>
<li>hyprland</li>
<li>mangowc</li>
</ul>
</li>
<li>tty
<ul>
<li>dvtm</li>
</ul>
</li>
</ul>
<p><strong>other</strong>:</p>
<ul>
<li>
</li>
<li>
</li>
</ul>
<p>Related tools</p>
<p>
 is a nested X server that runs as an X application.</p>
<p>If you wish to run a nested X window, you will need to specify a new display:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ Xephyr -br -ac -noreset -screen 800x600 :1</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>This will launch a new Xephyr window with a DISPLAY of &ldquo;:1&rdquo;. In order to launch an application in that window, you would need to specify that display:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ DISPLAY=:1 xterm</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>If you want to launch a specific WM, 
 for example, you would type:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ DISPLAY=:1 spectrwm</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>You can also launch Xephyr with your 
 using startx:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">$ startx -- /usr/bin/Xephyr :1</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><p>Grabbing and un-grabbing user input: Pressing <code>Ctrl+Shift</code> should lock/unlock your mouse pointer and your keystrokes inside Xephyr window exclusively if possible.<br>
If using KDE, create a window rule to ignore global shortcuts. Then you can use <code>Alt+Tab</code> inside Xephyr.</p>
<p>Tips and tricks: Other examples for situations where Xephyr can be useful are:</p>
<ol>
<li>A testing environment for an X application, or feature, in which the tester would like to keep working in their usual X environment, yet defending the other applications from failures of the application under test.</li>
<li>
 emphasize 3 settings in the sshd server configuration file for 
 (over ssh). 2 of these, out of 3, are the default settings. When the ssh client can not influence the ssh server administrator to set the 3rd one, <code>X11Forwarding</code>, to yes, 
 uses Xephyr as a work around to be installed in the ssh client machine.</li>
</ol>
<p>
</p>
<h2 id="de">
  <a class="anchor inpage" href="#de">##</a>DE</h2>
<ul>
<li><strong>launcher</strong>
<ul>
<li>rofi</li>
<li>dmenu</li>
</ul>
</li>
<li><strong>utils</strong>
<ul>
<li>dms</li>
<li>noctalia</li>
<li>iwd, impala</li>
<li>pipewire, wiremix</li>
<li>bluez, bluetui</li>
<li>power-profiles-daemon</li>
</ul>
</li>
<li>pcmanfm, Thunar, yazi</li>
<li>fcitx5</li>
<li>waterfox, brave</li>
</ul>
<p><strong>Editor</strong></p>
<ul>
<li>neovim
<ul>
<li>cbfmt format code blocks inside markdown</li>
</ul>
</li>
<li>latex:
<ul>
<li>languagetool,</li>
<li>hunspell-en_us,</li>
<li>texstudio</li>
</ul>
</li>
<li>word: abiword</li>
<li>pdf: sioyek, zathura, pdfbooklet</li>
<li>markdown: obsidian</li>
</ul>
<p><strong>media</strong>:</p>
<ul>
<li>python-eye3: edit meta data for mp3</li>
<li>mpd
<ul>
<li>frontend for mpd:</li>
<li>cli:mpc</li>
<li><code>easytag</code> to edit metadata of a audio file.</li>
<li>tui:
<ul>
<li>ncmpc</li>
<li>ncmpcpp</li>
<li>mmtc (no, weird config)</li>
<li>rmpc</li>
</ul>
</li>
</ul>
</li>
<li>mpv
<ul>
<li>mpvpaper: wallpaper by mpv in wayland</li>
</ul>
</li>
<li>
 a bilibili downloader</li>
<li>
 wired</li>
<li>ffmpeg</li>
<li>
 A tui video editor. Use <code>mpv</code> to play and <code>ffmpeg</code> to edit.</li>
<li>pic
<ul>
<li>feh</li>
<li>flameshot</li>
<li>picgo</li>
</ul>
</li>
</ul>
<h2 id="system-and-kernal">
  <a class="anchor inpage" href="#system-and-kernal">##</a>system and kernal</h2>
<ul>
<li>
<p>stacer: trash cleaner, monitor</p>
</li>
<li>
<p>btop: usage monitor</p>
</li>
<li>
<p>btrfs-assistant</p>
</li>
<li>
<p>timeshift</p>
</li>
<li>
<p>snapper</p>
</li>
<li>
<p>disk usage 感觉还是dua好用，图示其实用处不大</p>
<ul>
<li>dua: du 的替代品，我一般用<code>dua -i</code>交互式查看</li>
<li>bonsai: gnome的baobab（kde的filelight）的tui版本，旭日图那个</li>
<li>diskonaut: 类似treesize, wiztree的方格划分的</li>
<li>btrfs-heatmap: btrfs usage by hilbert curve</li>
<li>gparted</li>
</ul>
</li>
<li>
<p>systemd</p>
<ul>
<li>
</li>
<li>systemctl-tui</li>
<li>isd</li>
</ul>
</li>
<li>
<p>aconfmgr: A configuration manager for Arch Linux. Kind of like nixOS. 
</p>
</li>
<li>
<p>linux-firmware: Since <code>linux-firmware</code> is departed, only need some of them. Use <code>arch-checkfw</code> to find which.</p>
<p><code>linux-firmware</code> includes</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">Depends On      : linux-firmware-amdgpu  linux-firmware-atheros
                linux-firmware-broadcom  linux-firmware-cirrus  linux-firmware-intel
                linux-firmware-mediatek  linux-firmware-nvidia  linux-firmware-other
                linux-firmware-radeon  linux-firmware-realtek
Optional Deps   : linux-firmware-liquidio: Firmware for Cavium LiquidIO server adapters
                linux-firmware-marvell: Firmware for Marvell devices
                linux-firmware-mellanox: Firmware for Mellanox Spectrum switches
                linux-firmware-nfp: Firmware for Netronome Flow Processors
                linux-firmware-qcom: Firmware for Qualcomm SoCs
                linux-firmware-qlogic: Firmware for QLogic devices</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p>dracut: Alter for mkinitcpio</p>
</li>
<li>
<p>
 Alter for grub not support fo timeshift btrfs snap yet</p>
</li>
<li>
<p>
, another <code>snapper</code>, not support fo timeshift btrfs snap yet</p>
</li>
<li>
<p>kmscon alternative getty and tty, support unicode</p>
</li>
<li>
<p>for arch</p>
<ul>
<li>lostfiles find orphaned files not owned by Arch package</li>
<li>archstatus</li>
<li>arch-wiki-doc wikiman</li>
<li>pacfiles <code>pacman -F</code> alternative</li>
<li>pacman-contrib</li>
<li>
</li>
</ul>
</li>
</ul>
<h2 id="useful-tools">
  <a class="anchor inpage" href="#useful-tools">##</a>useful tools</h2>
<ul>
<li>
<p><strong>calendar, task, email, rss, etc</strong></p>
<ul>
<li>dstask</li>
<li>todo.txt</li>
<li>timewarrior</li>
<li>taskwarrior
<ul>
<li>tasknc</li>
<li>taskwarriortui</li>
</ul>
</li>
<li>todoman</li>
<li>vdirsyncer</li>
<li>khal</li>
<li>todoman</li>
<li>aerc</li>
<li>newsboat</li>
</ul>
</li>
<li>
<p>git and related</p>
<ul>
<li>lazygit: 最常用的</li>
<li>jujustu 
</li>
<li>gitlogue</li>
<li>serie</li>
<li>gitoxide 
 An idiomatic, lean, fast &amp; safe pure Rust implementation of Git</li>
<li>avc 
</li>
<li>github-cli</li>
<li>
</li>
</ul>
</li>
<li>
<p>cronboard :
</p>
</li>
<li>
<p>
 本地一键部署docker，似乎很好用</p>
</li>
<li>
<p>
 is a lightweight tool to locally create containers for multiple Linux distributions.</p>
</li>
<li>
<p>
 is a container wrapping layer that allows the user to install containerised versions of Linux that are different to the host while providing tight integration with the host allowing the use of binaries designed for one distribution to run on another. Distrobox itself is not a container manager and relies on Podman or Docker to create containers.</p>
</li>
<li>
<p>
 is a gui for <code>Distrobox</code>.</p>
</li>
<li>
<p>
</p>
</li>
<li>
<p>surge: tui download manager</p>
</li>
<li>
<p>darkhttpd</p>
</li>
<li>
<p>nginx</p>
</li>
<li>
<p>httrack</p>
</li>
<li>
<p>whois</p>
<details open>
    <summary>tldr</summary><pre
        class="codeblock"
      ><code class="language-tldr" data-lang="tldr">Command-line client for the WHOIS (RFC 3912) protocol.
More information: &lt;https://manned.org/whois&gt;.

Get information about a domain name:

    whois example.com

Get information about an IP address:

    whois 8.8.8.8

Get abuse contact for an IP address:

    whois -b 8.8.8.8</code><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script></li>
<li>
<p>stew-bin: install binary from github</p>
</li>
<li>
<p>for terminal and shell</p>
<ul>
<li>
 cat pdf or other</li>
<li>ripgrep-all: <code>rga</code> to match in pdf</li>
<li>lsix: list pictures by sixel</li>
<li>chafa: show pixels of pictures through sixel</li>
<li>gping: render in tui for ping
<ul>
<li>fv-cli show font in terminal using sixel iterm or kitty</li>
</ul>
</li>
</ul>
</li>
<li>
<p>ffcast</p>
</li>
<li>
<p>fbterm</p>
</li>
<li>
<p>drive</p>
<ul>
<li>
: Filesystem client based on SSH.</li>
<li>koofr</li>
<li>rclone</li>
</ul>
</li>
<li>
<p>hardware</p>
<ul>
<li>zmk-studio</li>
<li>librepod</li>
</ul>
</li>
</ul>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>sshfs username@remote_host:remote_directory mountpoint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>umount mountpoint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Mount remote directory from server with specific port: -p</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Use compression: -C</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Follow symbolic links: -o follow_symlinks</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sshfs -o follow_symlinks username@remote_host:remote_directory mountpoint -p <span style="color:#ae81ff">2222</span> -C</span></span></code
        ><button onclick="copyCode(this)" class="copybtn">copy</button></pre></details>

  <script>
    function copyCode(btn) {
      const code = btn.previousElementSibling.textContent.trim();
      navigator.clipboard.writeText(code).then(() => {
        btn.innerText = "copied";
        setTimeout(() => (btn.innerText = "copy"), 2000);
      });
    }
  </script><h2 id="tui">
  <a class="anchor inpage" href="#tui">##</a>tui</h2>
<h2 id="interesting">
  <a class="anchor inpage" href="#interesting">##</a>Interesting</h2>
<ul>
<li>genect: 假装很忙的shell操作屏幕保护程序</li>
<li>pipes-rs: 屏幕保护程序</li>
<li>cmd-wrapped: summarize shell history</li>
<li>diagon draw things in ascii 
 
</li>
<li>gitmal: generate a site from a git repo</li>
<li>
 generate pictures of code snaps</li>
<li>
 Turn markdown with additional marks to pdf or html, like LaTeX. <figure>
  <a
    href="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-paper.png"
    class="img-link"
    data-sub-html="paper"
    target="_blank"
  >
    <img
      src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-paper.png"
      alt="paper"loading="lazy"
    />
  </a><figcaption>paper</figcaption></figure>
 <figure>
  <a
    href="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-chart.png"
    class="img-link"
    data-sub-html="chart"
    target="_blank"
  >
    <img
      src="https://raw.githubusercontent.com/iamgio/quarkdown/project-files/images/code-chart.png"
      alt="chart"loading="lazy"
    />
  </a><figcaption>chart</figcaption></figure>
</li>
<li>gowall: A tool to convert a wallpaper&rsquo;s colorscheme, like nord or onedark</li>
<li>activate-linux a watermark</li>
</ul>
<h2 id="serves">
  <a class="anchor inpage" href="#serves">##</a>serves</h2>
<ul>
<li>
 A modern, open-source, self-hosted knowledge management and note-taking platform designed for privacy-conscious users and organizations.<br>
但是开发很迅速，导致api乱七八糟，迷茫。而且似乎没有导出功能，只是能把附件存储在cloudflare上。还是要想办法备份一下。包括radicale也是。</li>
<li>
</li>
<li>
</li>
<li>openlist</li>
<li>radicale</li>
</ul>
]]></content:encoded></item></channel></rss>