<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://luis.emlin.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://luis.emlin.me/" rel="alternate" type="text/html" /><updated>2026-03-30T15:49:18+00:00</updated><id>https://luis.emlin.me/feed.xml</id><title type="html">Luis E. Linares</title><subtitle>Website of Luis E. Linares.</subtitle><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><entry><title type="html">LaTeX in VS Code</title><link href="https://luis.emlin.me/latex-in-vscode/" rel="alternate" type="text/html" title="LaTeX in VS Code" /><published>2025-02-01T08:00:00+00:00</published><updated>2025-02-01T08:00:00+00:00</updated><id>https://luis.emlin.me/latex-in-vscode</id><content type="html" xml:base="https://luis.emlin.me/latex-in-vscode/"><![CDATA[<p>VS Code is a powerful LaTeX editor.
In this post, I outline my setup for creating LaTeX documents in VS Code, leveraging various extensions, tools, and settings to enhance document creation, collaboration, and organization.</p>

<p>In this document, I describe how to use and configure VS Code to achieve the following:</p>
<ul>
  <li>Compilation of LaTeX documents in VS Code with SyncTeX to jump between locations in the code and the PDF.</li>
  <li>Spell checking and grammar checking with support for LaTeX syntax.</li>
  <li>Pasting images into LaTeX documents.</li>
  <li>Collaboratively editing documents hosted on Overleaf.</li>
  <li>LaTeX “snippets” for actions like toggling between inline equations (i.e., <code class="language-plaintext highlighter-rouge">$...$</code>) and display equations (<code class="language-plaintext highlighter-rouge">\[...\]</code>).</li>
  <li>Custom linting tools for quickly identifying syntax errors (before compiling), and highlighting formatting or coding errors.</li>
</ul>

<h1 id="vs-code-settings">VS Code Settings</h1>
<p>This section describes the VS Code settings I use, along with the VS Code Extensions described below, for my LaTeX editing environment.
<!-- In addition to VS Code extensions, there are several built-in VS Code settings and features that improve LaTeX editing. --></p>

<p>To In my LaTeX projects, I use the following settings to help VS Code handle LaTeX-related file formats correctly.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="c1">// Treat new files (before first save) as LaTeX files.</span><span class="w">
  </span><span class="nl">"files.defaultLanguage"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex"</span><span class="err">,</span><span class="w">
  </span><span class="c1">// Treat LaTeX package (.sty) and class (.cls) files as LaTeX files.</span><span class="w">
  </span><span class="nl">"files.associations"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"*.sty"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"*.cls"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex"</span><span class="w">
  </span><span class="p">}</span><span class="err">,</span><span class="w">
  </span><span class="c1">// Hide the following file types from the VS Code folder list.</span><span class="w">
  </span><span class="nl">"files.exclude"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"**/*.4ct"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.4tc"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.fdb_latexmk"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.idv"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.lg"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.lof"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.synctex.gz"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.synctex(busy)"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.tmp"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.xref"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.fls"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.loc"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.run.xml"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.soc"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.snm"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*.blg"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"**/*-SAVE-ERROR"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<!-- I also disable GitHub Copilot on all LaTeX documents. 
GitHub Copilot is a combination of annoying and dangerous when writing math documents, so I disable it for all LaTeX documents.
```json
  "github.copilot.enable": {
      "latex": false
  },
``` -->

<!-- # Project Structure and Formatting
Organizing files systematically is helpful for maintaining a clean and efficient workspace.
The typical structure of my LaTeX projects is shown here: 

- `.vscode/`: # VS Code workspace settings
- `main.tex`: 
- `images/`: # Images for the document
- `out_dir/`: # Output directory containing files generated by compiling documents 
- `packages/`: # Custom or downloaded LaTeX packages
- `biblio.bib`: # Bibliography file (Exported from Zotero)

You can see a template LaTeX Git repository I made [here](https://github.com/pwintz/hsl_templates). -->

<h1 id="vs-code-extensions">VS Code Extensions</h1>

<p>VS Code has many excellent extensions for writing LaTeX documents. 
My favorites are listed here, with descriptions of my settings for each extension included in the subsections below.</p>

<!-- When writing LaTeX code in VS Code, the following extensions provide essential baseline functionality, such as  -->
<!-- Essential Extensions: -->
<ul>
  <li><strong><a href="https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop">LaTeX Workshop</a>:</strong> Comprehensive support for LaTeX projects, including auto-completion, document compiling, syntax highlighting, and PDF preview.</li>
  <li><strong><a href="https://marketplace.visualstudio.com/items/?itemName=ltex-plus.vscode-ltex-plus">LTeX+</a>:</strong> Grammar and spell-checking with support for LaTeX syntax.</li>
  <li><strong><a href="https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image">Paste Image</a>:</strong> Simplifies inserting images into your project, allowing images to be directly pasted into LaTeX documents.
<!-- - **[Latex-formatter](https://github.com/nfode/latex-formatter)** with [latexindent.pl](https://github.com/cmhughes/latexindent.pl): Provide automatic code reformatting for LaTeX code with customizable style.  --></li>
  <li><strong><a href="https://marketplace.visualstudio.com/items?itemName=iamhyc.overleaf-workshop">Overleaf Workshop</a>:</strong> Allows editing Overleaf Projects in VS Code. 
<!-- - **[Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments):** Provides customizable code highlighting for comments that match certain strings, such as "`TODO`", "`!!`", or "`??`". -->
<!-- - **[Tomorrow and Tomorrow Night Theme Kit](https://marketplace.visualstudio.com/items?itemName=ms-vscode.Theme-TomorrowKit)**: Provides my preferred color theme "Tomorrow Night Bright," which uses a pallet of clearly distinguishable and aesthetically-pleasing colors while achieving high contrast.  --></li>
  <li><strong><a href="https://marketplace.visualstudio.com/items?itemName=pwintz.dryer-lint&amp;ssr=false#overview">Dryer Lint</a></strong>: Allows for defining custom linting rules to highlighting writing errors that are specific to your context.
<!-- - **[Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens):** Displays error and warning messages in the editor at the end of the line where the error occurs. --></li>
</ul>

<h2 id="latex-workshop"><em>LaTeX Workshop</em></h2>

<p>The <em>LaTeX Workshop</em> extension is the backbone of editing LaTeX in VS Code. 
I’ve listed the most useful features below—see the <a href="https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop">documentation</a> for a full list of features and usage directions.</p>

<h3 id="latex-compilation">LaTeX Compilation</h3>

<p>Automatic PDF compilation on edits or saves.</p>

<p>By default, LaTeX Workshop rebuilds each time a build fails.
This is horrendously annoying, in my experience, since a build failure almost always requires manual intervention. 
To turn of auto re-building, use the following setting:</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"latex-workshop.latex.autoBuild.cleanAndRetry.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>LaTeX Workshop recompiles your document each time it is saved.
By default, VS Code saves only when you do so manually. 
I prefer more frequent saves, namely each time I move my cursor out of the code editor:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"files.autoSave"</span><span class="p">:</span><span class="w"> </span><span class="s2">"onFocusChange"</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>In addition to compiling on saves, I also use the following <a href="https://code.visualstudio.com/docs/getstarted/keybindings">VS Code keybinding</a> to compile when I hit CTRL+Enter:
<!-- TODO: Check if this matches the behavior on Overleaf. --></p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ctrl+enter"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex-workshop.build"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"when"</span><span class="p">:</span><span class="w"> </span><span class="s2">"editorLangId =~ /latex/"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>By default, LaTeX builds with LaTeX Workshop puts output files in the directory containing your <code class="language-plaintext highlighter-rouge">.tex</code> file.
This quickly creates a cluttered mess, due to the numerous auxiliary files generated by the LaTeX build process.
To avoid clutter and allow for build files to be quickly deleted, change the out directory. 
I use the following setting:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"latex-workshop.latex.outDir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"%DIR%/out_dir"</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>After changing <code class="language-plaintext highlighter-rouge">"latex-workshop.latex.outDir"</code>, LaTeX Workshop’s <code class="language-plaintext highlighter-rouge">"Clean up auxiliary files"</code> command no longer deletes auxiliary files unless you also change this setting:</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"latex-workshop.latex.clean.subfolder.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>(Note: The “Clean up auxiliary files” command misses some file types, so for a full clean you should just delete all of the files in the folder manually.)</p>

<h3 id="pdf-viewing-and-syncing">PDF Viewing and Syncing</h3>

<p>For viewing PDFs, I configure LaTeX Workshop to open PDFs in a VS Code tab.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"latex-workshop.view.pdf.viewer"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tab"</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>The built-in PDF viewer supports SyncTeX that for navigating back and forth between locations source code and the matching location in the PDF.
If you are compiling a document that uses some specialized PDF features, such as animations in a Beamer animation, you may want to change <code class="language-plaintext highlighter-rouge">"latex-workshop.view.pdf.viewer"</code> to use an appropriate viewer.</p>

<p>By default, CTRL+Clicking (CMD+Clicking on macOS) on a PDF activates SyncTeX to navigate select the location in the code that was clicked on the document. 
I change the setting to make the behaviors match Overleaf, which uses double-clicking to jump to the code location:</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"latex-workshop.view.pdf.internal.synctex.keybinding"</span><span class="p">:</span><span class="w"> </span><span class="s2">"double-click"</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>To jump from the Code to the PDF, open the command pallet (<code class="language-plaintext highlighter-rouge">CTRL</code>+<code class="language-plaintext highlighter-rouge">SHIFT</code>+<code class="language-plaintext highlighter-rouge">P</code>) and run <code class="language-plaintext highlighter-rouge">LaTeX Workshop: SyncTeX from cursor</code>.</p>

<p>I also make some aesthetic changes to the PDF viewer.
In particular, I change the background color beyond the border of pages to a shade of green that I find relaxing and make the page border the same color so it does not appear as a line (this helps prevent <em>actual</em> lines in the document from being overlooked if they happen to be at the edge of the page):</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"latex-workshop.view.pdf.color.dark.backgroundColor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#809080"</span><span class="err">,</span><span class="w">
  </span><span class="nl">"latex-workshop.view.pdf.color.light.backgroundColor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#809080"</span><span class="err">,</span><span class="w">
  </span><span class="nl">"latex-workshop.view.pdf.color.dark.pageBorderColor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#809080"</span><span class="err">,</span><span class="w">
  </span><span class="nl">"latex-workshop.view.pdf.color.light.pageBorderColor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"#809080"</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>You can also display PDFs in “dark mode” by setting <code class="language-plaintext highlighter-rouge">"latex-workshop.view.pdf.color.dark.pageColorsForeground"</code> and <code class="language-plaintext highlighter-rouge">"latex-workshop.view.pdf.color.dark.pageColorsBackground"</code>, but I find the resulting appearance hard to read.</p>

<h3 id="code-editor-and-autocompletion">Code Editor and Autocompletion</h3>

<p>LaTeX Workshop has many built-in snippets that can be used for autocompletion, and enables syntax-aware autocompletion using VS Code’s IntelliSense feature.</p>

<p>For IntelliSense to work on LaTeX non-standard packages you have downloaded or written, you need to tell LaTeX Workshop where to find the packages.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"latex-workshop.intellisense.package.dirs"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// List any folders that contain additional LaTeX package (.sty) </span><span class="w">
    </span><span class="c1">// or class (.cls) files, so that intellisense will use them </span><span class="w">
    </span><span class="c1">// for auto-complete suggestions.</span><span class="w">
    </span><span class="s2">"packages"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"%WORKSPACE_FOLDER%/packages"</span><span class="w">
  </span><span class="p">]</span><span class="err">,</span><span class="w">
  </span><span class="nl">"latex-workshop.intellisense.package.extra"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"examplepackage1"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"examplepackage2"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<p>To make IntelliSense to update more frequently, enable this setting:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"latex-workshop.intellisense.update.aggressive.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>In the code editor, LaTeX Workshop displays equation previews by default when you hover over an equation. 
I dislike these previews so I disable them.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"latex-workshop.hover.preview.cursor.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="err">,</span><span class="w">
  </span><span class="nl">"latex-workshop.hover.preview.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<h2 id="ltex-spell-checking-and-grammar-checking-for-latex"><em>LTeX+</em>: Spell-checking and Grammar Checking for LaTeX</h2>

<p>In LaTeX documents, standard document spell checkers and grammar checkers don’t work well due to the presence of non-text content, like equations and macros.
For example, the sentence “<code class="language-plaintext highlighter-rouge">The function $f : \mathbb{R} \to \mathbb{R}$ are \emph{continuous}.</code>” will confuse most checkers, which will show false positive for <code class="language-plaintext highlighter-rouge">$f</code>, <code class="language-plaintext highlighter-rouge">\mathbb</code>, etc., and will likely not identify the mismatched pluralization of “The function … are continuous”.</p>

<p>Fortunately, there is a checker called <a href="https://marketplace.visualstudio.com/items/?itemName=ltex-plus.vscode-ltex-plus"><em>LTeX+</em></a> that is built specifically to handle LaTeX documents (<a href="https://marketplace.visualstudio.com/items/?itemName=ltex-plus.vscode-ltex-plus"><em>LTeX+</em></a> is based on the now deprecated extension <a href="https://marketplace.visualstudio.com/items?itemName=valentjn.vscode-ltex"><em>LTeX</em></a>).
In VS Code, the LTeX+ extension performs spell checking and grammar checking that is (mostly) aware of LaTeX syntax. 
LTeX+ does a pretty good job of catching mistakes “out of the box”, with its default settings, but adjusting the settings can allow it to catch more mistakes and have less false-positives.</p>

<!-- The following sections describe the changes that I make to the defaults regardless of documents. -->

<h3 id="increase-ltex-pickiness">Increase LTeX+ Pickiness</h3>
<p>By default, LTeX+ only highlights spelling and grammar errors, but it also can provide a broader range of suggestions for <a href="https://ltex-plus.github.io/ltex-plus/settings.html#ltexadditionalrulesenablepickyrules">“picky”</a> rules. 
Many of the picky rules regard writing style, such as alerting you to sentences that are too long, or when several sentences in a row start with the same word. 
The following setting enables “picky” rules:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"ltex.additionalRules.enablePickyRules"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></code></pre></div></div>

<p>Using picky rules produces more false-positives. 
To resolve false positives, you can disable specific rules by selecting text that violates the rule and selecting “Disable Rule” from the quick suggestions panel:</p>

<p><img src="/assets/images/ltex_disable_rule.png" alt="screen show showing the Quick Suggestions panel with 'Disable rule' selected." /></p>

<p>Alternatively, you can select “hide false positive”, as described <a href="#hiding-false-positives">below</a> (see below), although I rarely use this feature.</p>

<h3 id="adjusting-severity-levels">Adjusting Severity Levels</h3>

<p>By default, LTeX+ displays all problems using VS Code’s “Information” formatting, which results in serious issues, such as misspelled words, being lost in the shuffle of minor problems, like using a passive voice. 
The severity of type of issue is set via the <a href="https://ltex-plus.github.io/ltex-plus/settings.html#ltexdiagnosticseverity"><code class="language-plaintext highlighter-rouge">"ltex.diagnosticSeverity"</code></a> setting. 
I keep the default as <code class="language-plaintext highlighter-rouge">"information"</code>, increase spelling errors to a <code class="language-plaintext highlighter-rouge">"warning"</code> level, and decrease the severity of some stylistic suggestions to “hints”. 
For spelling, the name of the rule is <code class="language-plaintext highlighter-rouge">"MORFOLOGIK_RULE_EN_US"</code>.
I use the following values for my <code class="language-plaintext highlighter-rouge">"ltex.diagnosticSeverity"</code> setting:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"ltex.diagnosticSeverity"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"default"</span><span class="p">:</span><span class="w"> </span><span class="s2">"information"</span><span class="p">,</span><span class="w"> 
        </span><span class="nl">"MORFOLOGIK_RULE_EN_US"</span><span class="p">:</span><span class="w"> </span><span class="s2">"warning"</span><span class="p">,</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">Spelling</span><span class="w"> </span><span class="err">errors.</span><span class="w">
        </span><span class="nl">"PASSIVE_VOICE"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hint"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"ENGLISH_WORD_REPEAT_BEGINNING_RULE"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hint"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"TOO_LONG_SENTENCE"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hint"</span><span class="w">
    </span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>
<p>A full list of LTeX rules is available <a href="https://community.languagetool.org/rule/list">here</a>.</p>

<h3 id="defining-how-ltex-parses-user-defined-latex-commands">Defining How LTeX+ Parses User-Defined LaTeX Commands</h3>
<p>LTeX has built-in knowledge of some LaTeX macros or environments, but for LTeX+ to correctly check code with less common or user-defined macros or environments, we need to provide additional information via the <a href="https://ltex-plus.github.io/ltex-plus/settings.html#ltexdiagnosticseverity"><code class="language-plaintext highlighter-rouge">"ltex.latex.commands"</code></a> and <a href="https://ltex-plus.github.io/ltex-plus/settings.html#ltexlatexenvironments">“<code class="language-plaintext highlighter-rouge">ltex.latex.environments</code>”</a> settings.
<!-- Although LTeX handles built-in LaTeX macros, it does not know how to interpret user-defined macros. In particular, for some macros, you want the contents of the macro's arguments to be checked where other they should be ignored. Other times, a macro should be interpreted as a word that is either plural or singular, and either starts with a vowel or a constant.   --></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"ltex.latex.commands"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"\\tableofcontents[]"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\@ifclassloaded{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\includeonly{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\texttt{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dummy"</span><span class="p">,</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">Inline</span><span class="w"> </span><span class="err">formatting</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">code.</span><span class="w">
  </span><span class="nl">"\\newbool{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\setbool{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\setbool{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Macros</span><span class="w"> </span><span class="err">and</span><span class="w"> </span><span class="err">environments</span><span class="w"> </span><span class="err">definitions</span><span class="w">
  </span><span class="nl">"\\newcommand{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\renewcommand{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\newenvironment{}[][]{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\newenvironment{}[]{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\newenvironment{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\NewDocumentCommand{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\NewEnviron{}[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\newtheoremstyle{}{}{}{}{}{}{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\DeclarePairedDelimiterX{}[]{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\DeclarePairedDelimiter{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="err">//</span><span class="w"> </span><span class="err">Beamer</span><span class="w">
  </span><span class="nl">"\\setbeamertemplate{}[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\setbeamercolor{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\setbeamerfont{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\usebeamercolor[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\usebeamertemplate{}[]"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\setbeamertemplate{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\setbeamertemplate{}[]"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\usebeamertemplate{}[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\setbeamerfont{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\addtolength{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\movie{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\movie[]{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Citations</span><span class="w"> </span><span class="err">and</span><span class="w"> </span><span class="err">references</span><span class="w">
  </span><span class="nl">"\\cite{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dummy"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\nocite{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\cref[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dummy"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\crefformat{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\Crefformat{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\crefmultiformat{}{}{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">  
  </span><span class="nl">"\\Crefmultiformat{}{}{}{}{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"\\crtcrefreference{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dummy"</span><span class="p">,</span><span class="w">  
  </span><span class="err">//</span><span class="w"> </span><span class="err">Changes</span><span class="w"> </span><span class="err">annotations</span><span class="w">
  </span><span class="nl">"\\deleted{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\todo{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\todo[]{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="hiding-false-positives">Hiding False Positives</h3>
<p>LTeX+ has a mechanism for <a href="https://ltex-plus.github.io/ltex-plus/advanced-usage.html">hiding false positives</a>, but it is fragile, requiring you to either re-mark each false positive whenever any part of the sentence changes or try to <a href="https://ltex-plus.github.io/ltex-plus/advanced-usage.html#hiding-false-positives-with-regular-expressions">write a regular expression</a> to match the false positive.
I don’t recommend either of those methods.
Instead, I define several <code class="language-plaintext highlighter-rouge">dummy</code> LaTeX macros to the values <code class="language-plaintext highlighter-rouge">"ignore"</code>, <code class="language-plaintext highlighter-rouge">"dummy"</code>, and <code class="language-plaintext highlighter-rouge">"voweldummy"</code> from the <code class="language-plaintext highlighter-rouge">"that I include in the </code>“ltex.latex.commands”` setting:</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">% Definitions for telling LTeX to ignore certain parts of the LaTeX code.</span>
<span class="c">% Example: "This is a \ltexdummy{miskate}."</span>
<span class="k">\newcommand</span><span class="p">{</span><span class="k">\ltexignore</span><span class="p">}</span>[1]<span class="p">{</span>#1<span class="p">}</span>
<span class="k">\newcommand</span><span class="p">{</span><span class="k">\ltexdummy</span><span class="p">}</span>[1]<span class="p">{</span>#1<span class="p">}</span>
<span class="k">\newcommand</span><span class="p">{</span><span class="k">\ltexvoweldummy</span><span class="p">}</span>[1]<span class="p">{</span>#1<span class="p">}</span>
</code></pre></div></div>
<p>Then, I mark each macro in <code class="language-plaintext highlighter-rouge">"ltex.latex.commands"</code> as follows:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"ltex.latex.commands"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">...</span><span class="w"> 
  </span><span class="err">//</span><span class="w"> </span><span class="err">Macros</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">hide</span><span class="w"> </span><span class="err">LTeX</span><span class="w"> </span><span class="kc">false</span><span class="err">-positive</span><span class="w">
  </span><span class="nl">"\\ltexignore{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ignore"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\ltexdummy{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dummy"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"\\ltexvoweldummy{}"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vowelDummy"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<!-- TODO: Add an example of how I use theses. -->

<p>It is also sometimes useful to include text that LTeX reads but is not included in the output.</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">% Insert a piece of hidden text that is parsed by LTex but is not displayed.</span>
<span class="k">\newcommand</span><span class="p">{</span><span class="k">\ltexhidden</span><span class="p">}</span>[1]<span class="p">{}</span>
</code></pre></div></div>

<!-- **Example (Using LTeX Macros to Hide False Positives).** 
Below is a LaTeX snippet demonstrating how to use the macros `\ltexignore`, `\ltexdummy`, and `\ltexvoweldummy` to hide or adjust LTeX+ warnings:

```latex
% Example usage in your document:
The function $\mathbb{R}$ is \ltexdummy{contnuous}. % "contnuous" is a false positive, so we hide it.
We define the set $\mathcal{A}$ as \ltexignore{fllows}. % "fllows" is ignored by LTeX+.
An \ltexvoweldummy{exmple} of this is shown below. % "exmple" is treated as starting with a vowel for grammar checks.
```

- Use `\ltexignore{...}` to completely ignore the contents for grammar and spelling.
- Use `\ltexdummy{...}` to treat the contents as a regular word (for hiding false positives).
- Use `\ltexvoweldummy{...}` to treat the contents as a word starting with a vowel (for correct article suggestions). -->

<h3 id="ignoring-irrelevant-bibtex-fields">Ignoring Irrelevant BibTeX Fields</h3>
<p>In BibTeX files, I typically have entries automatically generated by Zotero. Typically, each entry has an abstract and these tend to have a lot of false positives but are not included in the output. Instead of handling each issue individually, I use the <code class="language-plaintext highlighter-rouge">"ltex.bibtex.fields"</code> setting to disable LTeX+-checking of bibliography abstracts.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="nl">"ltex.bibtex.fields"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="err">#</span><span class="w"> </span><span class="err">Abstracts</span><span class="w"> </span><span class="err">in</span><span class="w"> </span><span class="err">bibliography</span><span class="w"> </span><span class="err">entries</span><span class="w"> </span><span class="err">typically</span><span class="w"> </span><span class="err">are</span><span class="w"> </span><span class="err">not</span><span class="w"> 
    </span><span class="err">#</span><span class="w"> </span><span class="err">typed</span><span class="w"> </span><span class="err">by</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">user</span><span class="w"> </span><span class="err">and</span><span class="w"> </span><span class="err">are</span><span class="w"> </span><span class="err">rarely</span><span class="w"> </span><span class="err">inserted</span><span class="w"> </span><span class="err">into</span><span class="w"> </span><span class="err">the</span><span class="w"> 
    </span><span class="err">#</span><span class="w"> </span><span class="err">document</span><span class="p">,</span><span class="w"> </span><span class="err">but</span><span class="w"> </span><span class="err">tend</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">have</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">lot</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">LTeX+</span><span class="w"> </span><span class="err">warnings</span><span class="p">,</span><span class="w"> 
    </span><span class="err">#</span><span class="w"> </span><span class="err">so</span><span class="w"> </span><span class="err">I</span><span class="w"> </span><span class="err">disable</span><span class="w"> </span><span class="err">warnings</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">abstracts.</span><span class="w">
    </span><span class="nl">"abstract"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="paste-image-image-pasting-into-latex-code"><em>Paste Image</em>: Image Pasting into LaTeX Code</h2>
<p>One of my biggest complaints about using LaTeX used to be the difficulty of doing some basic tasks, such as adding an image to a document, that can be done immediately in other document editors.
Adding a picture required saving the file to a particular location, creating a <code class="language-plaintext highlighter-rouge">figure</code> environment with <code class="language-plaintext highlighter-rouge">\includegraphics</code> inside, and typing or copy/pasting the path to the image. 
That’s no longer the case! 
In my current setup I can copy-and-paste an image into a LaTeX document using the <a href="https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image"><strong>Paste Image</strong></a> extension.
This extension is not designed for LaTeX in particular, however, so you need to do some specific configuration so that pasted images are placed in a reasonable directory and are properly referenced and formatted within the <code class="language-plaintext highlighter-rouge">.tex</code> file.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">//</span><span class="w"> </span><span class="err">In</span><span class="w"> </span><span class="err">.vscode/settings.json</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">/path/to/global/settings/settings.json</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">Where</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">place</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">files</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">pasted</span><span class="w"> </span><span class="err">images.</span><span class="w">
</span><span class="nl">"pasteImage.path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileDir}/pasted-images"</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">The</span><span class="w"> </span><span class="err">code</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">insert</span><span class="w"> </span><span class="err">into</span><span class="w"> </span><span class="err">LaTeX.</span><span class="w"> </span><span class="err">(Since</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">images</span><span class="w"> </span><span class="err">are</span><span class="w"> </span><span class="err">placed</span><span class="w"> </span><span class="err">in</span><span class="w"> 
</span><span class="err">//</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">directory</span><span class="w"> </span><span class="err">named</span><span class="w"> </span><span class="err">pasted-images/</span><span class="w"> </span><span class="err">that</span><span class="w"> </span><span class="err">is</span><span class="w"> </span><span class="err">in</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">same</span><span class="w"> </span><span class="err">directory</span><span class="w"> 
</span><span class="err">//</span><span class="w"> </span><span class="err">as</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">current</span><span class="w"> </span><span class="err">TeX</span><span class="w"> </span><span class="err">file,</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">relative</span><span class="w"> </span><span class="err">path</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">file</span><span class="w"> </span><span class="err">is</span><span class="w"> 
</span><span class="err">//</span><span class="w"> </span><span class="err">pasted-images/$</span><span class="p">{</span><span class="err">imageFileName</span><span class="p">}</span><span class="err">.)</span><span class="w">
</span><span class="nl">"pasteImage.insertPattern"</span><span class="p">:</span><span class="w"> 
  </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}</span><span class="se">\n\t\t\\</span><span class="s2">includegraphics[width=</span><span class="se">\\</span><span class="s2">linewidth]{pasted-images/${imageFileName}}</span><span class="se">\n\t\\</span><span class="s2">end{center}"</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">Make</span><span class="w"> </span><span class="err">Paste</span><span class="w"> </span><span class="err">Images</span><span class="w"> </span><span class="err">ask</span><span class="w"> </span><span class="err">you</span><span class="w"> </span><span class="err">what</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">name</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">file</span><span class="w"> </span><span class="err">so</span><span class="w"> </span><span class="err">you</span><span class="w"> </span><span class="err">don't</span><span class="w"> 
</span><span class="err">//</span><span class="w"> </span><span class="err">end</span><span class="w"> </span><span class="err">up</span><span class="w"> </span><span class="err">with</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">bunch</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">files</span><span class="w"> </span><span class="err">named</span><span class="w"> </span><span class="err">things</span><span class="w"> </span><span class="err">like</span><span class="w"> </span><span class="s2">"12-03-2024-12-44-23.png"</span><span class="w">
</span><span class="nl">"pasteImage.showFilePathConfirmInputBox"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">Only</span><span class="w"> </span><span class="err">ask</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">name</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">created</span><span class="w"> </span><span class="err">file,</span><span class="w"> </span><span class="err">instead</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">full</span><span class="w"> </span><span class="err">path.</span><span class="w">
</span><span class="nl">"pasteImage.filePathConfirmInputBoxMode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"onlyName"</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">Default</span><span class="w"> </span><span class="err">name.</span><span class="w">
</span><span class="nl">"pasteImage.defaultName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileNameWithoutExt}-HH-mm-ss"</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">Don't</span><span class="w"> </span><span class="err">encode</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">path</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">HTML.</span><span class="w"> 
</span><span class="nl">"pasteImage.encodePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"none"</span><span class="err">,</span><span class="w">
</span><span class="err">//</span><span class="w"> </span><span class="err">I</span><span class="w"> </span><span class="err">don't</span><span class="w"> </span><span class="err">remember</span><span class="w"> </span><span class="err">what</span><span class="w"> </span><span class="err">this</span><span class="w"> </span><span class="err">does</span><span class="w"> 
</span><span class="nl">"pasteImage.basePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileDir}"</span><span class="err">,</span><span class="w">
</span><span class="err">...</span><span class="w">
</span></code></pre></div></div>
<!-- TODO: Figure out what pasteImage.basePath does and if it is important. -->

<h2 id="pasting-images-into-latex">Pasting Images into LaTeX</h2>

<p>The <code class="language-plaintext highlighter-rouge">Paste Images</code> extension simplifies inserting images into LaTeX documents. 
In particular, you can insert images from your clipboard into a LaTeX documents and <code class="language-plaintext highlighter-rouge">Paste Images</code> will create an image file in a specified directory and insert LaTeX code that references it.</p>

<p>Since the <code class="language-plaintext highlighter-rouge">Paste Image</code> extension is not designed for LaTeX, specifically, you need to modify the configuration to make to it work correctly.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="p">{</span><span class="w">
    </span><span class="nl">"pasteImage.insertPattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}</span><span class="se">\n\t\t\\</span><span class="s2">includegraphics[width=</span><span class="se">\\</span><span class="s2">linewidth]{pasted-images/${imageFileName}}</span><span class="se">\n\t\\</span><span class="s2">end{center}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.filePathConfirmInputBoxMode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"onlyName"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.encodePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"none"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.basePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileDir}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.showFilePathConfirmInputBox"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.defaultName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileNameWithoutExt}-HH-mm-ss"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pasteImage.path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${currentFileDir}/pasted-images"</span><span class="p">,</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<!-- ## _LaTex-Formatter_ extension

The _LaTex-Formatter_ extension allows for automatic formatting of LaTeX files, especially indentation.

- Tabs vs. spaces
- custom indentation rules -->

<h2 id="dryer-lint-extension"><em>Dryer Lint</em> Extension</h2>

<p>The <a href="https://marketplace.visualstudio.com/items?itemName=pwintz.dryer-lint"><em>Dryer Lint</em></a> extension allows you to define custom <a href="https://en.wikipedia.org/wiki/Lint_(software)">linting</a> patterns using regular expressions.
I created the Dryer Lint based on the <a href="https://marketplace.visualstudio.com/items?itemName=n0brain3r.relint"><em>relint</em></a> by <a href="https://github.com/n0bra1n3r">Ryan Blonna</a>. 
<!-- to perform static code analysis, such as checking for  -->
In the subsections below, I list the lint rules that I developed to 1) identify syntax errors before compiling, 2) highlight formatting faux pas, and 3) enforce my preferred coding style. 
Some other uses you might consider on a project-by-project basis are rules to check for</p>
<ul>
  <li>A word that should not appear in your document but is similar to a word that you use.
<!-- - Check that every `\cite` command is preceded by a non-breaking space---if you are using a short inline citation style, such as IEEE bracket style (e.g., "[13]"). --></li>
  <li>Check for expressions that you commonly mix up, such as <code class="language-plaintext highlighter-rouge">$\distA{z}$</code> instead of <code class="language-plaintext highlighter-rouge">$\distA{x}$</code></li>
  <li>Check that you use a semantically important macro instead of its definition.</li>
</ul>

<p>All Dryer Lint rules are defined by JavaScript style regular expressions. 
They should be placed in your <code class="language-plaintext highlighter-rouge">settings.json</code> file, in the following entry:</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"dryer-lint"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"language"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"rules"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="c1">/// Place rules here...</span><span class="w">

          </span><span class="p">}</span><span class="w">
      </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>For writing and testing regular expressions, I recommend using <a href="https://regex101.com/">regex101.com</a>.</p>

<p>When writing multi-line rules, the regular expression for line breaks varies between platforms. 
On Windows, a line break is <code class="language-plaintext highlighter-rouge">\r\n</code> and on Linux it is just <code class="language-plaintext highlighter-rouge">\n</code>. 
Thus, to get a platform-independent line break, use <code class="language-plaintext highlighter-rouge">\r?\n</code>.</p>

<h3 id="linting-rules-for-syntax-errors">Linting Rules for Syntax Errors</h3>
<p>This section contains rules that check for syntax errors that will cause LaTeX builds to fail. 
Since linting happens much faster than compilation, this allows you to catch the mistake quicker.</p>

<!-- Check for extraneous content before the first "`\item`" in `itemize` and `enumerate` environments. -->
<p>Check that <code class="language-plaintext highlighter-rouge">\cref{}</code>, <code class="language-plaintext highlighter-rouge">\cite{}</code>, <code class="language-plaintext highlighter-rouge">\ref{}</code>, and <code class="language-plaintext highlighter-rouge">\eqref{}</code> do not occur without arguments. 
This is particularly helpful for <code class="language-plaintext highlighter-rouge">\cref{}</code> because a missing argument generates a cryptic compilation error message.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Check</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">\cref</span><span class="p">{},</span><span class="w"> </span><span class="err">\cite</span><span class="p">{},</span><span class="w"> </span><span class="err">\ref</span><span class="p">{},</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">\eqref</span><span class="p">{}</span><span class="w"> </span><span class="err">occurring</span><span class="w"> </span><span class="err">without</span><span class="w"> </span><span class="err">arguments.</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Empty Reference or Citation"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Missing argument to </span><span class="se">\\</span><span class="s2">cref, </span><span class="se">\\</span><span class="s2">cite, </span><span class="se">\\</span><span class="s2">ref, or </span><span class="se">\\</span><span class="s2">eqref."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\\\</span><span class="s2">(cref|eqref|ref|cite)</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\</span><span class="s2">}"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Error"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>For <code class="language-plaintext highlighter-rouge">\cite</code> and <code class="language-plaintext highlighter-rouge">\cref</code>, which can take comma separated lists of labels, a space after a comma typically indicates a mistake, so the following rule checks that this does not occur:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Check</span><span class="w"> </span><span class="err">that</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">comma-separated</span><span class="w"> </span><span class="err">list</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">labels</span><span class="w"> </span><span class="err">passed</span><span class="w"> </span><span class="err">to</span><span class="w"> 
  </span><span class="err">//</span><span class="w"> </span><span class="err">\cref</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">\cite</span><span class="w"> </span><span class="err">does</span><span class="w"> </span><span class="err">have</span><span class="w"> </span><span class="err">spaces</span><span class="w"> </span><span class="err">after</span><span class="w"> </span><span class="err">any</span><span class="w"> </span><span class="err">commas.</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Although</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">trailing</span><span class="w"> </span><span class="err">space</span><span class="w"> </span><span class="err">is</span><span class="w"> </span><span class="err">permitted</span><span class="w"> </span><span class="err">in</span><span class="w"> </span><span class="err">labels</span><span class="p">,</span><span class="w"> </span><span class="err">it</span><span class="w"> 
  </span><span class="err">//</span><span class="w"> </span><span class="err">would</span><span class="w"> </span><span class="err">be</span><span class="w"> </span><span class="err">better</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">revise</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">label</span><span class="w"> </span><span class="err">by</span><span class="w"> </span><span class="err">removing</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">space.</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Reference has a space after the comma"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The argument to </span><span class="se">\\</span><span class="s2">cref or </span><span class="se">\\</span><span class="s2">cite has a comma followed by a space. This typically indicates an error because the space will be read as a part of the label."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"(</span><span class="se">\\\\</span><span class="s2">(?:cref|cite)</span><span class="se">\\</span><span class="s2">{[^</span><span class="se">\\</span><span class="s2">}]*)</span><span class="se">\\</span><span class="s2">,</span><span class="se">\\</span><span class="s2"> "</span><span class="p">,</span><span class="w">
  </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Warning"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>Putting a comma or backslash into a LaTeX label causes problems, so this rule checks that the argument to <code class="language-plaintext highlighter-rouge">\label{...}</code> does not contain “,” or “".<br />
<!-- (A comma is technically permitted, but it prevents a label from being used in a comma-separated list so it should be avoided.) --></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Check</span><span class="w"> </span><span class="err">that</span><span class="w"> </span><span class="err">\label</span><span class="p">{}</span><span class="w"> </span><span class="err">does</span><span class="w"> </span><span class="err">not</span><span class="w"> </span><span class="err">contain</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">comma</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">backslash.</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Illegal Character in </span><span class="se">\\</span><span class="s2">label{}"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">label{...} must not contain </span><span class="se">\"</span><span class="s2">,</span><span class="se">\"</span><span class="s2"> or </span><span class="se">\"\\\"</span><span class="s2">."</span><span class="p">,</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Unescaped</span><span class="w"> </span><span class="err">Regex:</span><span class="w"> </span><span class="err">\\label\</span><span class="p">{[</span><span class="err">^\}</span><span class="p">]</span><span class="err">*</span><span class="p">[,</span><span class="err">\\</span><span class="p">][</span><span class="err">^\}</span><span class="p">]</span><span class="err">*\</span><span class="p">}</span><span class="w">
  </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\\\</span><span class="s2">label</span><span class="se">\\</span><span class="s2">{[^</span><span class="se">\\</span><span class="s2">}]*[</span><span class="se">\\\\</span><span class="s2">,][^</span><span class="se">\\</span><span class="s2">}]*</span><span class="se">\\</span><span class="s2">}"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Error"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>The following two rules assume that you use <code class="language-plaintext highlighter-rouge">$...$</code> for inline equations and <code class="language-plaintext highlighter-rouge">\[...\]</code> for display equations.
One significant advantage of avoiding <code class="language-plaintext highlighter-rouge">$$...$$</code> for display equations, is that we can define the following linting rule that immediately identifies <code class="language-plaintext highlighter-rouge">$$</code> as an error—most likely an inline equation was intended, but the lack of code between the dollar signs cause them to be interpreted as the start of a display equation that inevitably leads to cascading errors through the rest of the document.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">This</span><span class="w"> </span><span class="err">rule</span><span class="w"> </span><span class="err">assumes</span><span class="w"> </span><span class="err">that</span><span class="w"> </span><span class="err">you</span><span class="w"> </span><span class="err">write</span><span class="w"> </span><span class="err">display</span><span class="w"> </span><span class="err">equations</span><span class="w"> </span><span class="err">using</span><span class="w"> </span><span class="s2">"</span><span class="se">\[</span><span class="s2">...</span><span class="se">\]</span><span class="s2">"</span><span class="p">,</span><span class="w"> 
  </span><span class="err">//</span><span class="w"> </span><span class="err">which</span><span class="w"> </span><span class="err">means</span><span class="w"> </span><span class="err">that</span><span class="w"> </span><span class="s2">"$$"</span><span class="w"> </span><span class="err">should</span><span class="w"> </span><span class="err">never</span><span class="w"> </span><span class="err">appear</span><span class="w"> </span><span class="err">in</span><span class="w"> </span><span class="err">your</span><span class="w"> </span><span class="err">document.</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Inline equation with empty contents: </span><span class="se">\"</span><span class="s2">$$</span><span class="se">\"</span><span class="s2">."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">$</span><span class="se">\\</span><span class="s2">$"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Error"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$ $"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\"</span><span class="s2">$$</span><span class="se">\"</span><span class="s2"> should not be used. To insert a display equation, use </span><span class="se">\"\\</span><span class="s2">[...</span><span class="se">\\</span><span class="s2">]</span><span class="se">\"</span><span class="s2">."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>We also highlight when an inline equation is empty, since this typically indicates an omission.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Inline equation with empty contents: </span><span class="se">\"</span><span class="s2">$ $</span><span class="se">\"</span><span class="s2">."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">$[ ]+</span><span class="se">\\</span><span class="s2">$"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Warning"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Inline equation with empty contents: </span><span class="se">\"</span><span class="s2">$ $</span><span class="se">\"</span><span class="s2">."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>In LaTeX, every <code class="language-plaintext highlighter-rouge">itemize</code> or <code class="language-plaintext highlighter-rouge">enumerate</code> environment must begin with <code class="language-plaintext highlighter-rouge">\item</code> (not counting spaces or comments).
The following rule displays an error when <code class="language-plaintext highlighter-rouge">\item</code> is missing or preceded by other code.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Itemize must start with an item"</span><span class="p">,</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Regex</span><span class="mi">101</span><span class="err">.com</span><span class="w"> </span><span class="err">link:</span><span class="w"> </span><span class="err">https://regex</span><span class="mi">101</span><span class="err">.com/r/</span><span class="mi">9</span><span class="err">Ck</span><span class="mi">04</span><span class="err">q/</span><span class="mi">2</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Regular</span><span class="w"> </span><span class="err">expression</span><span class="w"> </span><span class="err">(unescaped):</span><span class="w">
  </span><span class="err">//</span><span class="w">      </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin</span><span class="se">\{</span><span class="s2">itemize</span><span class="se">\}</span><span class="s2">(?:[ </span><span class="se">\t</span><span class="s2">]*(?:%[^</span><span class="se">\n</span><span class="s2">]*)?</span><span class="se">\r</span><span class="s2">?</span><span class="se">\n</span><span class="s2">)*[ </span><span class="se">\t</span><span class="s2">]*(</span><span class="se">\S</span><span class="s2">(?&lt;!%|</span><span class="se">\\</span><span class="s2">).*|</span><span class="se">\\</span><span class="s2">(?!item).*)"</span><span class="w">
  </span><span class="err">//</span><span class="w"> </span><span class="err">Explanation:</span><span class="w">
  </span><span class="err">//</span><span class="w">  </span><span class="mi">1</span><span class="err">.</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin</span><span class="se">\{</span><span class="s2">(?:itemize|enumerate|description)</span><span class="se">\}</span><span class="s2">"</span><span class="w"> </span><span class="err">matches</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">start</span><span class="w"> 
  </span><span class="err">//</span><span class="w">     </span><span class="err">of</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">itemize</span><span class="p">,</span><span class="w"> </span><span class="err">enumerate</span><span class="p">,</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">description</span><span class="w"> </span><span class="err">environment.</span><span class="w">
  </span><span class="err">//</span><span class="w">  </span><span class="mi">2</span><span class="err">.</span><span class="w"> </span><span class="s2">"(?:[ </span><span class="se">\t</span><span class="s2">]*(?:%[^</span><span class="se">\n</span><span class="s2">]*)?</span><span class="se">\r</span><span class="s2">?</span><span class="se">\n</span><span class="s2">)*"</span><span class="w"> </span><span class="err">matches</span><span class="w"> </span><span class="err">any</span><span class="w"> </span><span class="err">number</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">comment</span><span class="w"> </span><span class="err">lines</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">empty</span><span class="w"> </span><span class="err">lines.</span><span class="w">
  </span><span class="err">//</span><span class="w">  </span><span class="mi">3</span><span class="err">.</span><span class="w"> </span><span class="s2">"[ </span><span class="se">\t</span><span class="s2">]*(</span><span class="se">\S</span><span class="s2">(?&lt;!%|</span><span class="se">\\</span><span class="s2">).*|</span><span class="se">\\</span><span class="s2">(?!item).*)"</span><span class="w"> </span><span class="err">matches</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">first</span><span class="w"> </span><span class="err">non-empty</span><span class="w"> 
  </span><span class="err">//</span><span class="w">     </span><span class="err">non-comment</span><span class="w"> </span><span class="err">line</span><span class="w"> </span><span class="err">unless</span><span class="w"> </span><span class="err">it</span><span class="w"> </span><span class="err">starts</span><span class="w"> </span><span class="err">with</span><span class="w"> </span><span class="err">\item.</span><span class="w"> </span><span class="err">More</span><span class="w"> </span><span class="err">precisely:</span><span class="w">
  </span><span class="err">//</span><span class="w">     </span><span class="mf">3.1</span><span class="w"> </span><span class="s2">"[ </span><span class="se">\t</span><span class="s2">]*"</span><span class="w"> </span><span class="err">matches</span><span class="w"> </span><span class="err">any</span><span class="w"> </span><span class="err">leading</span><span class="w"> </span><span class="err">whitespace.</span><span class="w">
  </span><span class="err">//</span><span class="w">     </span><span class="mf">3.2</span><span class="w"> </span><span class="s2">"</span><span class="se">\S</span><span class="s2">(?&lt;!%|</span><span class="se">\\</span><span class="s2">).*"</span><span class="w"> </span><span class="err">matches</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">non-white</span><span class="w"> </span><span class="err">space</span><span class="p">,</span><span class="w"> </span><span class="err">expect</span><span class="w"> </span><span class="err">for</span><span class="w"> </span><span class="err">comment</span><span class="w"> 
  </span><span class="err">//</span><span class="w">         </span><span class="err">tokens</span><span class="w"> </span><span class="err">(</span><span class="s2">"%"</span><span class="err">)</span><span class="w"> </span><span class="err">or</span><span class="w"> </span><span class="err">the</span><span class="w"> </span><span class="err">start</span><span class="w"> </span><span class="err">of</span><span class="w"> </span><span class="err">a</span><span class="w"> </span><span class="err">command</span><span class="w"> </span><span class="err">sequence</span><span class="w"> </span><span class="err">(</span><span class="s2">"</span><span class="se">\"</span><span class="s2">). 
  //         The "</span><span class="err">.*</span><span class="s2">" causes the error to be displayed extending to the end 
  //         of the line.
  //  4. "</span><span class="err">\\(?!item).*</span><span class="s2">" matches a command sequence (i.e., starting with "</span><span class="err">\</span><span class="s2">") except for "</span><span class="err">\item</span><span class="s2">", 
  //     which is excluded by the negated lookbehind "</span><span class="err">(?!item)</span><span class="s2">".
  "</span><span class="err">pattern</span><span class="s2">": "</span><span class="err">\\\\begin\\</span><span class="p">{</span><span class="err">(?:itemize|enumerate|description)\\</span><span class="p">}</span><span class="err">(?:</span><span class="p">[</span><span class="w"> </span><span class="err">\\t</span><span class="p">]</span><span class="err">*(?:%</span><span class="p">[</span><span class="err">^\\n</span><span class="p">]</span><span class="err">*)?\\r?\\n)*</span><span class="p">[</span><span class="w"> </span><span class="err">\\t</span><span class="p">]</span><span class="err">*(\\S(?&lt;!%|\\\\).*|\\\\(?!item).*)</span><span class="s2">",
  "</span><span class="err">message</span><span class="s2">": "</span><span class="err">List</span><span class="w"> </span><span class="err">environments</span><span class="w"> </span><span class="err">must</span><span class="w"> </span><span class="err">start</span><span class="w"> </span><span class="err">with</span><span class="w"> </span><span class="err">\\item.</span><span class="s2">",
  "</span><span class="err">severity</span><span class="s2">": "</span><span class="err">Error</span><span class="s2">",
  "</span><span class="err">maxLines</span><span class="s2">": 5
},
</span></code></pre></div></div>

<h3 id="linting-rules-for-document-style">Linting Rules for Document Style</h3>
<p>These rules enforce syntax that affect the appearance of the rendered document.</p>

<p>The following rules check that <a href="/writing-tips/nonbreaking-spaces">non-breaking spaces</a> are used before <code class="language-plaintext highlighter-rouge">\cite{...}</code>, <code class="language-plaintext highlighter-rouge">\ref{}</code>, and <code class="language-plaintext highlighter-rouge">\eqref{}</code>, and before <code class="language-plaintext highlighter-rouge">\cref{}</code> when referencing an equation.
The <code class="language-plaintext highlighter-rouge">\cite{}</code> rule is suitable for numerical in-line citation formats, such as IEEE citations that look like “[12]”.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Missing non-breaking space before </span><span class="se">\\</span><span class="s2">cite"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Use </span><span class="se">\"</span><span class="s2">~</span><span class="se">\"</span><span class="s2"> (non-breaking space) before `</span><span class="se">\\</span><span class="s2">cite` to prevent awkward line breaks."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[ ]</span><span class="se">\\\\</span><span class="s2">cite</span><span class="se">\\</span><span class="s2">{"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~</span><span class="se">\\</span><span class="s2">cite</span><span class="se">\\</span><span class="s2">{"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">\cref{}</code> rule requires that you are using the <code class="language-plaintext highlighter-rouge">cleveref</code> package and label equations using labels starting with “eq:”. 
You should also have <code class="language-plaintext highlighter-rouge">cleveref</code> configured to reference equations using a number inside a parenthesis, e.g., “(12)” rather than “Eq. 12”.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="c1">// Check for a space before the reference to an equation. </span><span class="w">
    </span><span class="c1">// This rule requires that you label all equations with a prefix "eq:".</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Missing non-breaking space before cleveref equation reference"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Use </span><span class="se">\"</span><span class="s2">~</span><span class="se">\"</span><span class="s2"> (non-breaking space) before referencing an equation to prevent awkward line breaks."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[ ]</span><span class="se">\\\\</span><span class="s2">cref</span><span class="se">\\</span><span class="s2">{eq:"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~</span><span class="se">\\</span><span class="s2">cref{eq:"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Missing non-breaking space before references"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Use </span><span class="se">\"</span><span class="s2">~</span><span class="se">\"</span><span class="s2"> (non-breaking space) before </span><span class="se">\"\\</span><span class="s2">eqref{}</span><span class="se">\"</span><span class="s2"> and </span><span class="se">\"\\</span><span class="s2">ref{}</span><span class="se">\"</span><span class="s2"> to prevent awkward line breaks before the inserted number."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"[ ]</span><span class="se">\\\\</span><span class="s2">(eqref|ref)</span><span class="se">\\</span><span class="s2">{"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~</span><span class="se">\\</span><span class="s2">$1{:"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>The <a href="/writing-tips/punctuation-in-equations">punctuation at the end of a display equation</a> should be placed inside the equation delimiters (“<code class="language-plaintext highlighter-rouge">\[...\]</code>”). 
Otherwise, the punctuation will be displayed incorrectly below the equation:</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
-->\[a^2 + b^2 = c^2\].<!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td>$$a^2 + b^2 = c^2$$.</td>
    </div>
  
</div>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Punctuation outside Display Equation"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\\\</span><span class="s2">][.,;]"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Warning"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Place punctuation inside display equation, before </span><span class="se">\"\\</span><span class="s2">]</span><span class="se">\"</span><span class="s2">."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<p>The following rule checks for extra line breaks at the end of <code class="language-plaintext highlighter-rouge">align</code>, <code class="language-plaintext highlighter-rouge">aligned</code>, and <code class="language-plaintext highlighter-rouge">cases</code> environments.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Multiline equation environment has extra line at end"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"(?:</span><span class="se">\\\\</span><span class="s2">){2}[ </span><span class="se">\\</span><span class="s2">t]*</span><span class="se">\\</span><span class="s2">r?</span><span class="se">\\</span><span class="s2">n[ </span><span class="se">\\</span><span class="s2">t]*</span><span class="se">\\\\</span><span class="s2">end{(?:align[*]?|aligned|cases)}"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Warning"</span><span class="p">,</span><span class="w"> 
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Extra line break at the end of environment."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"maxLines"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<h3 id="linting-rules-for-code-style">Linting Rules for Code Style</h3>
<p>This section has linting rules I use to enforce my preferred LaTeX code style. 
Adapt them to match your preferences.</p>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Display equation starts on new line unless the preceding line is short"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Display equations (</span><span class="se">\"\\</span><span class="s2">[....</span><span class="se">\\</span><span class="s2">]</span><span class="se">\"</span><span class="s2">) should start on a new line unless the preceding text is shorter than 15 characters."</span><span class="p">,</span><span class="w">
    </span><span class="c1">// The length of the non-leading-whitespace string is 15 or more because </span><span class="w">
    </span><span class="c1">// "[^ \\t%]" is 1 character and ".{14,}" is 14 or more characters.</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^([ </span><span class="se">\\</span><span class="s2">t]*)([^ </span><span class="se">\\</span><span class="s2">t%].{14,}) </span><span class="se">\\\\\\</span><span class="s2">["</span><span class="p">,</span><span class="w">
    </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$1$2</span><span class="se">\n</span><span class="s2">$1</span><span class="se">\\</span><span class="s2">["</span><span class="p">,</span><span class="w"> 
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Display equations should be followed by a new line"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Display equations (</span><span class="se">\"\\</span><span class="s2">[....</span><span class="se">\\</span><span class="s2">]</span><span class="se">\"</span><span class="s2">) should be followed by a new line."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\\\\\</span><span class="s2">][ </span><span class="se">\\</span><span class="s2">t]*(</span><span class="se">\\</span><span class="s2">S)"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Use spaces for indentation"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^[ ]*[</span><span class="se">\\</span><span class="s2">t][</span><span class="se">\\</span><span class="s2">t ]*"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Use spaces for indentation instead of tabs. Run </span><span class="se">\"</span><span class="s2">Convert indentation to spaces</span><span class="se">\"</span><span class="s2"> to fix."</span><span class="p">,</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="p">{</span><span class="w">
    </span><span class="c1">// The pattern matches a line that contains a sentence that ends </span><span class="w">
    </span><span class="c1">// with a period and the next line starts with a word character. </span><span class="w">
    </span><span class="c1">// The fix inserts a newline between the two lines.</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Start each sentence on a new line"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Code style: Start each sentence on a new line."</span><span class="p">,</span><span class="w">
    </span><span class="c1">// Regex: ^([ \t]*)((?:[^%]|(?&lt;=\\)%).*\w\.)[ ]+(\w)</span><span class="w">
    </span><span class="c1">// Parts: </span><span class="w">
    </span><span class="c1">// 1. Leading whitespace: ^([ \t]*)</span><span class="w">
    </span><span class="c1">// 2. Any character except an unescaped comment character </span><span class="w">
    </span><span class="c1">//    ("%" but not "\%"): (?:[^%]|(?&lt;=\\)%)</span><span class="w">
    </span><span class="c1">// 2. Check that the "period" is not preceded by \big or \Big, </span><span class="w">
    </span><span class="c1">//    indicating that it is actually </span><span class="w">
    </span><span class="c1">//    being used to increase the size of delimiters: (?&lt;!\\big|\\Big)</span><span class="w">
    </span><span class="c1">// 3. Sentence ending with a period, but not in a comment: ((?:[^%]|(?&lt;=\\)%)*\.)</span><span class="w">
    </span><span class="c1">// 4. Whitespace between sentences: [ ]+</span><span class="w">
    </span><span class="c1">// 5. First letter of the next sentence: (\w)</span><span class="w">
    </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^([ </span><span class="se">\\</span><span class="s2">t]*)((?:[^%]|(?&lt;=</span><span class="se">\\\\</span><span class="s2">)%)*(?&lt;!</span><span class="se">\\\\</span><span class="s2">big|</span><span class="se">\\\\</span><span class="s2">Big)</span><span class="se">\\</span><span class="s2">.)[ ]+(</span><span class="se">\\</span><span class="s2">w)"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"severity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Information"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"fix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$1$2</span><span class="se">\n</span><span class="s2">$1$3"</span><span class="p">,</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<h2 id="overleaf-workshop-extension"><em>Overleaf Workshop</em> Extension</h2>
<p>The <em>Overleaf Workshop</em> extension allows editing Overleaf Projects in VS Code.</p>

<p>Once you have VS Code nicely set up, you may find that you are occasionally collaborating with coauthors who wish to use Overleaf. 
While Overleaf is great for synchronized editing, the loss of VS Code features can be jarring once you are accustomed to them.</p>

<p>The Overleaf Workshop extension bridges this gap by allowing you to sync Overleaf projects with VS Code, but it comes with some major caveats. 
Overleaf Workshop provides two methods for opening projects:</p>
<ol>
  <li>Open the project with a virtual workspace that continually syncs with Overleaf, or</li>
  <li>“Open Project Locally”, which creates a local copy.</li>
</ol>

<p>Both methods have major drawbacks.
The virtual workspace approach does not support LaTeX Workshop, so you lose all the nice features from that extension.
On the other hand,</p>

<div class="warning-box">
  <b>Warning:</b> Do <emph>not</emph> use the Overleaf Workshop "Open Projects Locally" feature.
  Using a local version leads to major issues, including edit conflicts and data loss. See this <a href="https://github.com/iamhyc/Overleaf-Workshop/issues/180">GitHub issue</a>.
</div>

<h3 id="alternative-syncing-with-overleaf-projects-with-git">Alternative: Syncing with Overleaf Projects with Git</h3>

<p>If you have a premium Overleaf account, you can use <a href="https://www.overleaf.com/learn/how-to/Git_integration">Git integration</a> to sync an Overleaf project to your computer, allowing you to <em>safely</em> modify the project and then push the changes back to Overleaf.</p>

<p>Using Git incurs some overhead with pushing, pushing, and (possibly) merging, but it may be worth the upsides of editing Overleaf documents with the exact same tools as any of your local LaTeX documents.</p>

<!-- ## _Better Comments_ Extension

The _Better Comments_ extension enables highlighting for comments that start with certain text, such as "TODO" or "??", as shown in this screenshot:
<img src="/assets/images/better_comments_screenshot.png" alt="alt text"/>

_Better Comments_ allows you to customize the highlighting, but I just use the default settings. -->

<!-- ## _Error Lens_ Extension

The _Error Lens_ extension displays code errors, warnings, hints, and info in the editor. 
This saves you some time opening the Problems pane or hovering over underlined text.  -->

<!-- ## _Tomorrow and Tomorrow Night Theme Kit_

The _Tomorrow and Tomorrow Night Theme Kit_ provides my preferred color theme "Tomorrow Night Bright," which uses a pallet of clearly distinguishable and aesthetically-pleasing colors while achieving high contrast.  

Here is a screenshot:
<img src="/assets/images/tomorrow-night-bright.png" alt="alt text"/> -->

<h2 id="code-formatting">Code Formatting</h2>

<p>In any programming languages, adopting a sensible and consistent coding style improves readability and maintainability, and sometimes highlights errors that would otherwise go unnoticed.</p>

<p>Previous sources have written at length about LaTeX coding style (see <a href="https://www.tug.org/TUGboat/tb32-3/tb102verna.pdf">“Towards LATEX coding standards”</a> by Didier Verna). 
I will add my two cents for a piece of code style that substantially improves tracking changes in Git. 
When I first started writing LaTeX, I would put entire paragraphs on a single line of code, with line wrapping turned on in the editor. 
While editing, this was …fine, but caused difficulties in version control. 
In particular, when I was committing or merging changes in Git, it would be difficult to see where in a line changes were made. 
Later, I switched to adding line breaks after every 80 characters or so (without regards to sentences), so that the entirety of each line code would be visible line wrapping off.
This fixed the difficulty with seeing diff’s, but required a lot of effort to keep each line roughly my desired width.</p>

<p>To fix both problems, I now write every sentence on its own line. 
As an added benefit, having a one sentence per line allows for easily checking the lengths of sentence to see if any are too long and if there is a nice variation lengths.</p>

<p>To make word-wrapping appear nicely in the editor, I use the following settings:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">  </span><span class="nl">"editor.wordWrap"</span><span class="p">:</span><span class="w"> </span><span class="s2">"on"</span><span class="err">,</span><span class="w">
  </span><span class="nl">"editor.wrappingIndent"</span><span class="p">:</span><span class="w"> </span><span class="s2">"indent"</span><span class="w">
</span></code></pre></div></div>

<p>Sometimes, word wrap in the editor makes certain tasks more difficult (especially when using multi-cursors on aligned text), in which case you can use the command pallet (or the shortcut shown therein) to toggle word wrap:</p>
<ol>
  <li>Open command pallet (<code class="language-plaintext highlighter-rouge">CTRL+SHIFT+P</code> on Windows)</li>
  <li>Select <code class="language-plaintext highlighter-rouge">View: Toggle Word Wrap</code> (<code class="language-plaintext highlighter-rouge">CTRL+SHIRT+P</code> on Windows)</li>
</ol>

<p>I published the Dryer Lint extension, described above, to help (among other things) enforce a consistent code style.</p>

<!-- # VS Code Settings -->

<!-- 
# General VS Code Preferences
```jsonc
{
  "editor.renderWhitespace": "all",
  "editor.guides.bracketPairs": "active",
  // If a line gets too long, then wrap it to the next line, but include an indentation to visually suggest the line continuation.
  "editor.wordWrap": "on",
  "editor.wrappingIndent": "indent",
    
  # Set the minimum distance of the cursor from edge of window before VS Code starts scrolling
  "editor.cursorSurroundingLines": 4, 
  "editor.quickSuggestions": {
      "other": "off"
  },
  "editor.tabSize": 2,
  "workbench.editor.alwaysShowEditorActions": true,
  "workbench.editor.highlightModifiedTabs": true,
  "workbench.editor.pinnedTabsOnSeparateRow": true,
  "window.density.editorTabHeight": "compact",
  "editor.comments.ignoreEmptyLines": false,
}
``` -->

<h1 id="vs-code-snippets">VS Code Snippets</h1>

<p>The following code contains snippets I’ve developed for LaTeX. 
For a description of VS Code snippets, see <a href="https://code.visualstudio.com/docs/editor/userdefinedsnippets">here</a>. 
I have provided the snippets largely without explanation, here, except for some documentation of the more complicated regular expressions.
For experimenting with regular expressions, I recommend <a href="https://regex101.com/">regex101.com</a>.
You can find all of my snippets in a GitHub repository <a href="https://github.com/pwintz/vs-code-snippets">here</a>.</p>

<p>To add these snippets to your VS Code environment,</p>
<ol>
  <li>Open the Command Pallet</li>
  <li>Run <code class="language-plaintext highlighter-rouge">Snippets: Configure Snippets</code></li>
  <li>Select <code class="language-plaintext highlighter-rouge">latex.json</code> (for global snippets) or <code class="language-plaintext highlighter-rouge">latex.code-snippets</code> (for workspace snippets). In my setup, <code class="language-plaintext highlighter-rouge">latex.code-snippets</code> says “global” after it, but it actually is only for defining snippets in the current workspace.</li>
</ol>

<h2 id="equations">Equations</h2>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="c1">// Equations</span><span class="w">
</span><span class="nl">"Display Equation"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">["</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// If the current line is not empty, then insert an empty line.</span><span class="w">
    </span><span class="s2">"${TM_CURRENT_LINE/(?:^(</span><span class="se">\\</span><span class="s2">s*)</span><span class="se">\\</span><span class="s2">S.*$|(^</span><span class="se">\\</span><span class="s2">s*$))/${1:+</span><span class="se">\n</span><span class="s2">}$1/}</span><span class="se">\\</span><span class="s2">["</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$1"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">] $0"</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Insert block equation with line-breaks and indentation."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Inline Equation"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"$$TM_SELECTED_TEXT$1$$0"</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Insert inline equation."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Equation Environment"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">equation"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{equation}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">label{eq:$RANDOM_HEX}"</span><span class="p">,</span><span class="w">
      </span><span class="c1">// Regex (unescaped): \s*(?:\\\[\s*((?:.(?:\s*)??)*)\s*\\\]|((?:.|\s)+))\s*</span><span class="w">
      </span><span class="c1">//   Match either "  \[ \n .... \] " or just the entire contents and insert it as the body of the equation.</span><span class="w">
      </span><span class="c1">//   Explanation:</span><span class="w">
      </span><span class="c1">//      (?:\s*)??: Match any number of spaces *including line breaks* but </span><span class="w">
      </span><span class="c1">//								 only if needed to allow for subsequent non-space characters.</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">${TM_SELECTED_TEXT/</span><span class="se">\\</span><span class="s2">s*(?:</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\\\\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">s*((?:.(?:</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\</span><span class="s2">S)?)*)</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\\\\\</span><span class="s2">]</span><span class="se">\\</span><span class="s2">s*|((?:.|</span><span class="se">\\</span><span class="s2">s)+))</span><span class="se">\\</span><span class="s2">s*/$1$2/}$1$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{equation}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">""</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Insert equation environment with a random hexadecimal label."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Generate Equation Label"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">eqlabel"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// Automatically generate a label from the contents of the equation, deleting any backslashes or ambersands.</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">label{eq:${TM_SELECTED_TEXT/[</span><span class="se">\\\\</span><span class="s2">&amp;,]//g}${1/[</span><span class="se">\\\\</span><span class="s2">&amp;,]//g}$1}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$TM_SELECTED_TEXT$0"</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Create an equation label that is automatically generated from the selected text."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Display Equation to Equation Environment"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// Group 1: Before text. "(.*?)"</span><span class="w">
    </span><span class="c1">// Group 2: Tab spaces before equation delimiter. "(\\h*)"</span><span class="w">
    </span><span class="c1">// Group 3: Equation contents "(.*?)"</span><span class="w">
    </span><span class="c1">// Group 4: After text "(.*)"</span><span class="w">
    </span><span class="s2">"${TM_SELECTED_TEXT/(.*?)(</span><span class="se">\\</span><span class="s2">h*)</span><span class="se">\\\\\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">s*(.*?)</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\\\\\</span><span class="s2">](.*)/$1$2</span><span class="se">\\</span><span class="s2">begin{equation}</span><span class="se">\n</span><span class="s2">$2</span><span class="se">\t</span><span class="s2">$3</span><span class="se">\n</span><span class="s2">$2</span><span class="se">\\</span><span class="s2">end{equation}</span><span class="se">\n</span><span class="s2">/s}"</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Convert a display equation to an equation environment."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Convert inline to display equation"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// Unescaped RegEx: ([\S\s]*)\$\s*(.*?)\s*\$([,.]{0,1})([\S\s]*)</span><span class="w">
    </span><span class="c1">// Group 1: Content before equation. ("[\S\s]" matches any character)</span><span class="w">
    </span><span class="c1">// Group 2: Contents of equation, stripping white space.</span><span class="w">
    </span><span class="c1">// Group 3: Punctuation after equation ("[,.]{0,1}" matches "," or "." zero or one times)</span><span class="w">
    </span><span class="c1">// Group 4: Content after equation</span><span class="w">
    </span><span class="c1">// We duplicate the Regex for each line so that VS code automatically inserts the correct indentation for us, instead of handling it in the regex.</span><span class="w">
    </span><span class="s2">"${TM_SELECTED_TEXT/([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)</span><span class="se">\\</span><span class="s2">$</span><span class="se">\\</span><span class="s2">s*(.*?)</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\</span><span class="s2">$([,.]{0,1})</span><span class="se">\\</span><span class="s2">s*([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)/$1/s}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">["</span><span class="p">,</span><span class="w">
    </span><span class="c1">// It's important to put "\t" before "${TM_SELECTED_TEXT...}" instead of inside it so that VS code inserts tabs or spaces according to you configuration. If it's inside the regex, then it inserts a tab character.</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">${TM_SELECTED_TEXT/([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)</span><span class="se">\\</span><span class="s2">$</span><span class="se">\\</span><span class="s2">s*(.*?)</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\</span><span class="s2">$([,.]{0,1})</span><span class="se">\\</span><span class="s2">s*([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)/$2$3/s}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">]"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"${TM_SELECTED_TEXT/([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)</span><span class="se">\\</span><span class="s2">$</span><span class="se">\\</span><span class="s2">s*(.*?)</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\</span><span class="s2">$([,.]{0,1})</span><span class="se">\\</span><span class="s2">s*([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)/$4/s}"</span><span class="p">,</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Convert an inline equation to a display equation."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Convert display to inline equation"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="c1">// Regular expression (unescaped): (.*)\\\[\s*\n*\s*(.*?)\s*\n*\s*\\\](.*)</span><span class="w">
    </span><span class="c1">// - "\s*" matches any number of spaces and line breaks around it.</span><span class="w">
    </span><span class="c1">// - "[\s\S]" matches any character, including line breaks and spaces.</span><span class="w">
    </span><span class="c1">// - "\\\[" Matches "\[" (there are three backslashes because "\\" matches "\" and "\[" matches "[").</span><span class="w">
    </span><span class="c1">// Group 1: All the content before the equation.</span><span class="w">
    </span><span class="c1">// Group 2: All the content in the equation, except for final punctuation  </span><span class="w">
    </span><span class="c1">// Group 3: Final punctuation ("[,.]{0,1}").</span><span class="w">
    </span><span class="c1">// Group 4: All the content after the equation.</span><span class="w">
    </span><span class="s2">"${TM_SELECTED_TEXT/([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)</span><span class="se">\\\\\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">s*([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*?)</span><span class="se">\\</span><span class="s2">s*([,.]{0,1})</span><span class="se">\\</span><span class="s2">s*</span><span class="se">\\\\\\</span><span class="s2">]([</span><span class="se">\\</span><span class="s2">S</span><span class="se">\\</span><span class="s2">s]*)/$1$$2$$3$4/s}"</span><span class="p">,</span><span class="w">
    
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Convert a display equation to an inline equation."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">

</span><span class="nl">"Subequations"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">subequations"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{subequations}"</span><span class="p">,</span><span class="w"> </span><span class="s2">"equations group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"equation group"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Insert a group of equations that share the number, e.g., (3a), (3b), (3c)."</span><span class="p">,</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{subequations}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">label{eq:${1:equation block label}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{align}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{align}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{subequations}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="lists">Lists</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="c1">// Lists: Enumerate, Itemize, and Description</span><span class="w">
</span><span class="nl">"Add \\item after each line break"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">itemafterlines"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"${TM_SELECTED_TEXT/(</span><span class="se">\\</span><span class="s2">n)(</span><span class="se">\\</span><span class="s2">s*)/$1$2</span><span class="se">\\</span><span class="s2">item /g}"</span><span class="w">
  </span><span class="p">],</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Insert a citation."</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Itemize with \\item after each line"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">itemize"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{itemize}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">item ${TM_SELECTED_TEXT/(</span><span class="se">\\</span><span class="s2">n)(</span><span class="se">\\</span><span class="s2">s*)/$1$2</span><span class="se">\\</span><span class="s2">item /g}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{itemize}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">""</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="section-headers">Section Headers</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="nl">"Section Labeled"</span><span class="p">:{</span><span class="w">
  </span><span class="c1">// "prefix": ["\\sectionlabeled"],</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">section"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">""</span><span class="p">,</span><span class="w">
    </span><span class="s2">"%==================================="</span><span class="p">,</span><span class="w">
    </span><span class="s2">"%==================================="</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">section{$TM_SELECTED_TEXT${1:Header}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">label{sec:${TM_SELECTED_TEXT/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\</span><span class="s2">v</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}${1/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Subsection"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">subsection"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">""</span><span class="p">,</span><span class="w">
    </span><span class="s2">"%================================"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">subsection{$TM_SELECTED_TEXT${1:Header}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">label{sec:${TM_SELECTED_TEXT/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\</span><span class="s2">v</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}${1/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\</span><span class="s2">v</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Subsubsction"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">subsubsection"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">""</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">subsubsection{$TM_SELECTED_TEXT${1:Header}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">label{sec:${TM_SELECTED_TEXT/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\</span><span class="s2">v</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}${1/[</span><span class="se">\\\\</span><span class="s2">&amp;</span><span class="se">\\</span><span class="s2">v</span><span class="se">\\</span><span class="s2">{</span><span class="se">\\</span><span class="s2">}</span><span class="se">\\</span><span class="s2">[</span><span class="se">\\</span><span class="s2">]$]//g}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="math-function-macros-with-arguments">Math Function Macros with Arguments</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="nl">"Inner product"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">ip"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">ip{$TM_SELECTED_TEXT$1}{$2}$0 "</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Absolute value"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">abs"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">abs{$TM_SELECTED_TEXT$1}$0 "</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Norm"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">norm"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">norm{$TM_SELECTED_TEXT$1}$0 "</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="text-formatting">Text formatting</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="nl">"Emphasis"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"epmh"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">emph"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">emph{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Bold"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"bold"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">bold"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">textbf{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Teletype"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"t"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">tt"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">texttt{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
    </span><span class="nl">"Hyperlink (includes link)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">href"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">hyperlink"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">url"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">href{${1:url}}{$TM_SELECTED_TEXT$2}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Hyperlink (no link)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">url"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">url{$TM_SELECTED_TEXT$2}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>
<h2 id="environments">Environments</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="nl">"Definition (labeled)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">definition (labeled)"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{definition}[${1:Name of Defined Term}]"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">label{def:${1:label}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{definition}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Example (labeled)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">example (labeled)"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{example}[${2:Example Name}]"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">label{example:${1:Example Name}}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{example}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="changes-annotations">Changes Annotations</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="nl">"Added"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">added"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">added{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Added Multi-line"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">added%"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">added{%%%%%%%%%% ADDED %%%%%"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"}%%%% END ADDED %%%%"</span><span class="w">
    </span><span class="c1">// "" // Ensure there is a new line at end</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Deleted"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">deleted"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">deleted{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Deleted Multiline"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">deleted%"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">deleted{%%%%%%%%%% DELETED %%%%%"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"}%%%%%%%%%% END DELETED %%%%%"</span><span class="p">,</span><span class="w">
    </span><span class="c1">// "" // Ensure there is a new line at end</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Replaced"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">replaced"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">replaced{$TM_SELECTED_TEXT$1}{$TM_SELECTED_TEXT}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Replaced Multiline"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">replaced%"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">replaced (block)"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">replaced{% New Text"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"}{% Old Text"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"}% End </span><span class="se">\\</span><span class="s2">replaced block"</span><span class="p">,</span><span class="w">
    </span><span class="c1">// "" // Ensure there is a new line at end</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<!-- TODO: Requires defining "addedblock" and "deletedblock" environments. -->
<!-- ```
"Added Block Environment":{
  "prefix": ["\\addedblock"],
  "body": [
    "\\begin{addedblock}%",
    "$TM_SELECTED_TEXT$0",
    "\\end{addedblock}%"
    // "" // Ensure there is a new line at end
  ]
},
"Deleted Block Environment":{
  "prefix": ["\\deleted%", "\\deletedblock"],
  "body": [
    "\\begin{deletedblock}%",
    "\t$TM_SELECTED_TEXT$0",
    "\\end{deletedblock}%"
    // "" // Ensure there is a new line at end
  ]
},
``` -->

<h2 id="tables-and-columns">Tables and Columns</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="c1">// ======== COLUMNS =========</span><span class="w">
</span><span class="nl">"Inline Table"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"table"</span><span class="p">,</span><span class="w"> </span><span class="s2">"tabular"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{tabular}{$1}"</span><span class="p">,</span><span class="w">
            </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{tabular}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{center}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Two Columns"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">columns (2)"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">twocolumns"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{columns}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.48</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.48</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$2"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{columns}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Three Columns"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">columns (3)"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">threecolumns"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{columns}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.31</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.31</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$2"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.31</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$3"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{columns}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Four Columns"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">columns (4)"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">fourcolumns"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{columns}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.23</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.23</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$2"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.23</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$3"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{column}[T]{0.23</span><span class="se">\\</span><span class="s2">textwidth}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$4"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{column}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{columns}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Full-width Minipage (no page breaks)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">minipage"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">nopagebreak"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{minipage}{</span><span class="se">\\</span><span class="s2">linewidth}%"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">centering"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{minipage}%"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="c1">// Insert columns</span><span class="w">
</span><span class="nl">"Two Columns (Minipages)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">minipage columns (2)"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">twominipages"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{minipage}{0.49</span><span class="se">\\</span><span class="s2">linewidth}%"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">centering"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$1"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{minipage}%"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">hfill"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{minipage}{0.49</span><span class="se">\\</span><span class="s2">linewidth}%"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">centering"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$2"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{minipage}%"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Two Columns (Table)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">table columns (2)"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">twocolumntable"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{tabular}{p{0.47</span><span class="se">\\</span><span class="s2">linewidth}p{0.47</span><span class="se">\\</span><span class="s2">linewidth}}"</span><span class="p">,</span><span class="w">
          </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1 &amp; $0"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{tabular}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{center}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Three Columns (Table)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">table columns (3)"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">threecolumntable"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{tabular}{p{0.31</span><span class="se">\\</span><span class="s2">linewidth}p{0.31</span><span class="se">\\</span><span class="s2">linewidth}p{0.31</span><span class="se">\\</span><span class="s2">linewidth}}"</span><span class="p">,</span><span class="w">
          </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1 &amp; $2 &amp; $0"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{tabular}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{center}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Four Columns (Table)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">table columns (4)"</span><span class="p">,</span><span class="s2">"</span><span class="se">\\</span><span class="s2">fourcolumntable"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{center}"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">begin{tabular}{p{0.23</span><span class="se">\\</span><span class="s2">linewidth}p{0.23</span><span class="se">\\</span><span class="s2">linewidth}p{0.23</span><span class="se">\\</span><span class="s2">linewidth}p{0.23</span><span class="se">\\</span><span class="s2">linewidth}}"</span><span class="p">,</span><span class="w">
          </span><span class="s2">"</span><span class="se">\t\t</span><span class="s2">$TM_SELECTED_TEXT$1 &amp; $2 &amp; $3 &amp; $0"</span><span class="p">,</span><span class="w">
        </span><span class="s2">"</span><span class="se">\t\\</span><span class="s2">end{tabular}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{center}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="c1">...</span><span class="w">
</span></code></pre></div></div>

<h2 id="beamer-slides">Beamer Slides</h2>

<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">...</span><span class="w">
</span><span class="c1">// ======== BEAMER ==========</span><span class="w">
</span><span class="nl">"Beamer Frame"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">frame"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{frame}"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{frame}{${1:title}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{frame}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Beamer Frame (Top aligned)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">frametop"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{frame}[t]"</span><span class="p">,</span><span class="w"> </span><span class="s2">"frame top"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{frame}[t]{${1:title}}"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{frame}"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Structure"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">structure"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">structure{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Structure (Math)"</span><span class="p">:{</span><span class="w">
  </span><span class="c1">// Requires "\newcommand{\mstructure}[1]{{\color{structure} #1}}"</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">mstructure"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">structure (math)"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">mstructure{$TM_SELECTED_TEXT$1}$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Only Exist on Slide"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">only"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">only&lt;${1:overlay specification}&gt;{$TM_SELECTED_TEXT$0}"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Only Exist on Slide (Block)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">onlyblock"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">only&lt;${1:overlay specification}&gt;{%"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w"> 
    </span><span class="s2">"}% End only block"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Only Shown on Slide"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">onslide"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">onslide&lt;${1:overlay specification}&gt;{$TM_SELECTED_TEXT$0}"</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Only Shown on Slide (Block)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">onslideblock"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">onslide&lt;${1:overlay specification}&gt;{%"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT$0"</span><span class="p">,</span><span class="w"> 
    </span><span class="s2">"}% End only block"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Pause After Itemize or &lt;+-&gt;"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">pauseafter&lt;+-&gt;"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">pauseAfterItemize"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="s2">"</span><span class="se">\\</span><span class="s2">pause[</span><span class="se">\\</span><span class="s2">thebeamerpauses]"</span><span class="p">,</span><span class="w">
    </span><span class="s2">"$0"</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="snippets-for-vs-code-multi-cursor">Snippets for VS Code Multi-cursor</h2>

<p>One feature of VS Code that includes 
Here are some snippets that can be used in any language.</p>

<p>To set global snippets, for all languages:</p>

<ol>
  <li>Open the command pallet (<code class="language-plaintext highlighter-rouge">CTRL+SHIFT+P</code> by default on Windows).</li>
  <li>Type and select <code class="language-plaintext highlighter-rouge">Snippets: Configure Snippets</code>.</li>
  <li>Select <code class="language-plaintext highlighter-rouge">all_languages.json.code-snippets (global)</code>.</li>
</ol>

<p>I have two groups of snippets. One group contains snippets for inserting enumerations when using multi-cursors and the other group has snippets for inserting duplicated information (producing multi-cursors).</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"Cursor index (starts at 0)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursorindex"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">ndx"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"$CURSOR_INDEX"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Cursor number (starts at 1)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursornum"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">num"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"$CURSOR_NUMBER"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Cursor uppercase Alphabet (A, B, C, ..., I)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursorAlph"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">Alph"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${CURSOR_NUMBER/(^1$)?(^2$)?(^3$)?(^4$)?(^5$)?(^6$)?(^7$)?(^8$)?(^9$)?(^10$)?(^11$)?(^12$)?(^13$)?(^14$)?(^15$)?(^16$)?(^17$)?(^18$)?(^19$)?(^20$)?(^21$)?(^22$)?(^23$)?(^24$)?(^25$)?(^26$)?/${1:+A}${2:+B}${3:+C}${4:+D}${5:+E}${6:+F}${7:+G}${8:+H}${9:+I}${10:+J}${11:+K}${12:+L}${13:+M}${14:+N}${15:+O}${16:+P}${17:+Q}${18:+R}${19:+S}${20:+T}${21:+U}${22:+V}${23:+W}${24:+X}${25:+Y}${26:+Z}/}"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Cursor lowercase alphabet (a, b, c, ..., i)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursoralph"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">alph"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${CURSOR_NUMBER/(^1$)?(^2$)?(^3$)?(^4$)?(^5$)?(^6$)?(^7$)?(^8$)?(^9$)?(^10$)?(^11$)?(^12$)?(^13$)?(^14$)?(^15$)?(^16$)?(^17$)?(^18$)?(^19$)?(^20$)?(^21$)?(^22$)?(^23$)?(^24$)?(^25$)?(^26$)?/${1:+a}${2:+b}${3:+c}${4:+d}${5:+e}${6:+f}${7:+g}${8:+h}${9:+i}${10:+j}${11:+k}${12:+l}${13:+m}${14:+n}${15:+o}${16:+p}${17:+q}${18:+r}${19:+s}${20:+t}${21:+u}${22:+v}${23:+w}${24:+x}${25:+y}${26:+z}/}"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Cursor lowercase Roman (i, ii, iii, ..., xx)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">roman"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursorroman"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${CURSOR_NUMBER/(^1$)?(^2$)?(^3$)?(^4$)?(^5$)?(^6$)?(^7$)?(^8$)?(^9$)?(^10$)?(^11$)?(^12$)?(^13$)?(^14$)?(^15$)?(^16$)?(^17$)?(^18$)?(^19$)?(^20$)?/${1:+i}${2:+ii}${3:+iii}${4:+iv}${5:+v}${6:+vi}${7:+vii}${8:+viii}${9:+ix}${10:+x}${11:+xi}${12:+xii}${13:+xiii}${14:+xiv}${15:+xv}${16:+xvi}${17:+xvii}${18:+xviii}${19:+xix}${20:+xx}/}"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Cursor uppercase Roman (I, II, III, ..., XX)"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">Roman"</span><span class="p">,</span><span class="w"> </span><span class="s2">"</span><span class="se">\\</span><span class="s2">cursorRoman"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${CURSOR_NUMBER/(^1$)?(^2$)?(^3$)?(^4$)?(^5$)?(^6$)?(^7$)?(^8$)?(^9$)?(^10$)?(^11$)?(^12$)?(^13$)?(^14$)?(^15$)?(^16$)?(^17$)?(^18$)?(^19$)?(^20$)?/${1:+I}${2:+II}${3:+III}${4:+IV}${5:+V}${6:+VI}${7:+VII}${8:+VIII}${9:+IX}${10:+X}${11:+XI}${12:+XII}${13:+XIII}${14:+XIV}${15:+XV}${16:+XVI}${17:+XVII}${18:+XVIII}${19:+XIX}${20:+XX}/}"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">//</span><span class="w"> </span><span class="err">Duplicated</span><span class="w"> </span><span class="err">text</span><span class="w"> </span><span class="err">entry</span><span class="w"> </span><span class="err">with</span><span class="w"> </span><span class="err">multi-cursors.</span><span class="w">
</span><span class="nl">"2x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">2x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${4:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"3x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">3x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${2:, }$1${2:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"4x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">4x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${2:, }$1${2:, }$1${2:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"5x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">5x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${2:, }$1${2:, }$1${2:, }$1${2:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"6x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">6x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${2:, }$1${2:, }$1${2:, }$1${2:, }$1${2:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"7x"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">7x"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}${2:, }$1${2:, }$1${2:, }$1${2:, }$1${2:, }$1${2:, }$1$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"nx"</span><span class="p">:{</span><span class="w">
  </span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">nx"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"body"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"${1:$TM_SELECTED_TEXT}1${5:, }${1}2${5}${2|</span><span class="se">\\</span><span class="s2">cdots,</span><span class="se">\\</span><span class="s2">vdots,</span><span class="se">\\</span><span class="s2">dots|}${5}${1}${6:n}$0"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<!-- # Find and Replace using RegEx -->

<!-- ### Additional Tools -->
<!-- - **[Zotero](https://www.zotero.org/):** Reference manager for organizing and citing sources, which can be exported to a BibTeX or BibLaTeX file. -->
<!-- Recent versions support automatic exports so   -->
<!-- - **Git:** Version control for collaborative and personal projects. -->
<!-- - **Meld:** Visual diff and merge tool for comparing file changes. -->

<!-- # Other tools

There are several other LaTeX tools that can be useful: -->

<!-- latexindent.pl looks useful for auto-formatting LaTeX files. [latex-formatter](https://github.com/nfode/latex-formatter) is a VS Code extension for calling latexindent.pl. -->

<!-- - https://www.nongnu.org/chktex/ linter for checking that LaTeX code doesn't have certain types of typographical and formatting mistakes. Does not provide binaries for Windows, so you have to build them yourself. -->

<h1 id="latex-development">LaTeX Development</h1>
<p>This section contains info about setting up VS Code for development of LaTeX packages or classes. 
I don’t expect the suggestions to be useful if you are just writing documents in LaTeX without writing your own packages or classes.</p>

<h2 id="code-spell-extension">Code Spell Extension</h2>
<p>When writing LaTeX packages or classes, it is nice to have a spell checker that is designed for code rather than documents. 
The <a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker"><em>Code Spell</em></a> extension serves this purpose. 
In contrast to LTeX+, Code Spell will check variable names that are formed from the conjunction of multiple words such as <code class="language-plaintext highlighter-rouge">is_ready</code> or <code class="language-plaintext highlighter-rouge">MyVariable</code>, and allows for defining language specific dictionaries to avoid false positives when you use predefined names such as <code class="language-plaintext highlighter-rouge">includegraphics</code> in LaTeX.</p>

<p>My LaTeX dictionary (incomplete) is available <a href="/assets/example_code/cspell-dictionaries/latex.txt">here</a>.
To create the dictionary file, you can use the Command <code class="language-plaintext highlighter-rouge">Spell: Create a Custom Dictionary</code> in the VS Code Command Pallet (<code class="language-plaintext highlighter-rouge">CTRL + SHIFT + P</code> or <code class="language-plaintext highlighter-rouge">CMD + SHIFT + P</code>, by default).</p>

<p>My Code Spell settings in <code class="language-plaintext highlighter-rouge">settings.json</code> are shown here:</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"cSpell.customDictionaries"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"latex"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"addWords"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"latex"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"C:/path/to/dictionary/latex.txt"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"scope"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"custom"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="c1">// Enable the `custom` dictionary</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"cSpell.languageSettings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
  </span><span class="p">{</span><span class="w">
    </span><span class="nl">"dictionaries"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">"latex"</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"languageId"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"tex"</span><span class="p">,</span><span class="w"> </span><span class="s2">"latex-expl3"</span><span class="p">]</span><span class="w">
  </span><span class="p">},</span><span class="w">
</span><span class="p">]</span><span class="err">,</span><span class="w">
</span><span class="c1">// Add names and other words to the dictionary </span><span class="w">
</span><span class="c1">// that are specific to your work, but not language specific.</span><span class="w">
</span><span class="nl">"cSpell.userWords"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
  </span><span class="s2">"Wintz"</span><span class="p">,</span><span class="w">
  </span><span class="c1">// ...</span><span class="w">
</span><span class="p">]</span><span class="w">
</span></code></pre></div></div>

<h1 id="conclusion">Conclusion</h1>
<p>Using VS Code for LaTeX development can be highly efficient with the right tools and configurations. 
By integrating extensions like LaTeX Workshop, LTeX+, and Paste Image, alongside structured project organization, you can significantly streamline your workflow. 
Explore these configurations to tailor a setup that works best for you!</p>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="typesetting" /><category term="latex" /><category term="vscode" /><summary type="html"><![CDATA[Explore how to effectively write LaTeX documents using VS Code with the right extensions, configurations, and project structure.]]></summary></entry><entry><title type="html">Theorem-like Environments in LaTeX</title><link href="https://luis.emlin.me/mathematical-writing/theorem-like-environments-in-latex/" rel="alternate" type="text/html" title="Theorem-like Environments in LaTeX" /><published>2024-07-02T20:00:00+00:00</published><updated>2024-07-02T20:00:00+00:00</updated><id>https://luis.emlin.me/mathematical-writing/theorem-like-environments-in-latex</id><content type="html" xml:base="https://luis.emlin.me/mathematical-writing/theorem-like-environments-in-latex/"><![CDATA[<style>
  .theorem {
  display: block;
  font-style: italic;
  }
  .theorem:before {
  content: "Theorem. ";
  font-weight: bold;
  font-style: normal;
  }
  .theorem[name]:before {
  content: "Theorem (" attr(name) ") ";
  }
</style>

<p>In this post, I will describe the setup I use for theorem-type environments in LaTeX (includes theorems, definitions, etc.).</p>

<p>A basic example of the code and output for a Theorem in a LaTeX document is shown here:</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
-->\begin{theorem}[Pythagorean]
  For a right triangle with sides $a$ and $b$, 
  and hypotenuse $c,$
  \[ a^2 + b^2 = c^2. \]
\end{theorem}
<!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><div class="theorem" name="Pythagorean">
Given a right triangle with sides $a$ and $b$, and hypotenuse $c$,
$$a^2 + b^2 = c^2.$$
</div></td>
    </div>
  
</div>
<p>The remainder of this document shows how to</p>
<ul>
  <li>Setup the <code class="language-plaintext highlighter-rouge">amsthm</code>, <code class="language-plaintext highlighter-rouge">hyperref</code>, and <code class="language-plaintext highlighter-rouge">cleveref</code> packages for inserting and referencing Theorems, Definitions, and the like.</li>
  <li>Modify the style of Theorem environments to use slanted text instead of italics to improve readability in certain fonts (most notably, Times New Roman).</li>
  <li>Modify the QED mark or “Halmos Tombstone” (i.e., “$\square$”) that appears at the end of proofs and other environments.</li>
  <li>Define new theorem-like environments.</li>
  <li>Change the Theorem numbering scheme to include the chapter numbers.</li>
  <li>Create unnumbered theorem environments.</li>
  <li>Insert proofs, including modifying the introductory “<em>Proof.</em>” and moving the QED mark.
<!-- TODO: Add "Unified numbering", "labels in margins", and "discouraging page breaks". --></li>
</ul>

<h1 id="packages">Packages</h1>

<!-- To set up theorem-like environments, we load several packages in the preamble of the document.  -->

<h2 id="amsthm-package">amsthm Package</h2>
<p>The <a href="https://ctan.org/pkg/amsthm"><code class="language-plaintext highlighter-rouge">amsthm</code></a> package defines macros and environments for creating theorem-like environments.</p>

<pre class="language-latex">
\usepackage{amsthm}
</pre>

<h2 id="hyperref-package">hyperref Package</h2>
<p>The <a href="https://ctan.org/pkg/hyperref"><code class="language-plaintext highlighter-rouge">hyperref</code></a> package provides hyperlinking. 
When <code class="language-plaintext highlighter-rouge">hyperref</code> is loaded, all references to theorem-like environments (inserted using <code class="language-plaintext highlighter-rouge">\ref</code> or <code class="language-plaintext highlighter-rouge">\cref</code>) automatically include links to the location where the environment is displayed.
You will likely want to modify some of the <code class="language-plaintext highlighter-rouge">hyperref</code> options.</p>

<pre class="language-latex">
% Enable hyperlinks
\usepackage{hyperref}
\hypersetup{
    final,                   % Include links even if document is in 'draft' mode.
    hidelinks,               % Prevent boxes from being drawn around links in some viewers.
    breaklinks=true,         % Allow line breaks in the middle of links
    colorlinks=true,
    linkcolor=black,         % TOC, links to labeled equations and environments
    urlcolor=black!30!blue,  % URLS including links in references  
    anchorcolor=blue,        % I'm not sure what this does.
    citecolor=black!30!blue, % In-line citations  
}
</pre>

<h2 id="cleveref-package">cleveref Package</h2>
<p>The <a href="https://ctan.org/pkg/cleveref"><code class="language-plaintext highlighter-rouge">cleveref</code></a> package defines the <code class="language-plaintext highlighter-rouge">\cref</code> macro for inserting internal references to labeled object. 
In contrast to <code class="language-plaintext highlighter-rouge">\ref</code>, <code class="language-plaintext highlighter-rouge">\cref</code> inserts the type of environment referenced, so a reference <code class="language-plaintext highlighter-rouge">\cref{my first theorem}</code> will appear as “Theorem 1”, whereas <code class="language-plaintext highlighter-rouge">\ref{my first theorem}</code> only appears as “1”.</p>

<pre class="language-latex">
% Display "Theorem 1", "Lemma 2", etc. in cross references.  
% It's important to load this last after all the other packages!
\usepackage[
    noabbrev,   % E.g., "Figure" instead of "Fig."
    capitalise, % E.g., "Figure" instead of "figure"
    nameinlink  % Make "Figure 1" linked instead of just "1".
  ]{cleveref} 
</pre>

<h1 id="changing-theorem-body-text-from-italic-to-slanted">Changing Theorem Body Text From Italic To Slanted</h1>

<p>By default, the body <code class="language-plaintext highlighter-rouge">amsthm</code> theorem environments are italicized.
I find large chunks of italic text hard to read, so I create and use a different theorem style that uses slanted text instead.
This way, theorems are differentiated from surrounding text without compromising readability.</p>

<pre class="language-latex">
% Create a new amsthm theorem style that uses slanted text 
% instead of italics. I find this makes the text easier to read.
% See https://tex.stackexchange.com/a/417959/153678.
\usepackage{amssymb} % Provides \slshape
\newtheoremstyle{sltheorem}
                {}          % Space above
                {}          % Space below
                {\slshape}  % Body font
                {}          % Indent amount
                {\bfseries} % Head font
                {.}         % Punctuation after head
                { }         % Space after theorem head
                {}          % Theorem head spec
% Enable the new "sltheorem" theorem style.
\theoremstyle{sltheorem}
</pre>

<h1 id="discouraging-page-breaks-in-theorems">Discouraging Page Breaks in Theorems</h1>

<p>By default, LaTeX will insert page breaks into the middle of a theorem statement just as readily as anywhere else in the document. 
This leads to unfortunate cases where one or two lines are on a separate page. 
LaTeX visual processor decides where to insert page breaks by a collection of penalties, with the goal of total minimizing the sum of the penalties. 
Thus, to discourage LaTeX from putting page breaks in a theorem, we can increase the penalties for page breaks between lines, and before and after display equations, which are stored in these macros:</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\interlinepenalty</span>   <span class="c">% Page break between lines.</span>
<span class="k">\predisplaypenalty</span>  <span class="c">% Page breaks before a display equation.</span>
<span class="k">\postdisplaypenalty</span> <span class="c">% Page break after equations.</span>
</code></pre></div></div>
<p>To check the default values of these penalties, you can print them in your document by prefixing each macro with <a href="https://tex.stackexchange.com/a/38680/153678"><code class="language-plaintext highlighter-rouge">\the</code></a>, such as,</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  interlinepenalty=<span class="k">\the\interlinepenalty</span>  <span class="k">\\</span>
 predisplaypenalty=<span class="k">\the\predisplaypenalty</span> <span class="k">\\</span>
postdisplaypenalty=<span class="k">\the\postdisplaypenalty</span>
</code></pre></div></div>
<p>For the document I used to the above code, the results were <code class="language-plaintext highlighter-rouge">interlinepenalty=0</code>, <code class="language-plaintext highlighter-rouge">predisplaypenalty=10000</code>, and <code class="language-plaintext highlighter-rouge">postdisplaypenalty=0</code>.</p>

<p>To modify the penalties use the syntax <code class="language-plaintext highlighter-rouge">\interlinepenalty=&lt;whole number&gt;</code>. 
You don’t want to manually set the penalties within in each theorem, however, so use a theorem style to set the values, as follows:</p>

<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\newtheoremstyle</span><span class="p">{</span>breakResistantTheorem<span class="p">}</span>
     <span class="p">{}</span>          <span class="c">% Space above</span>
     <span class="p">{}</span>          <span class="c">% Space below</span>
     <span class="p">{</span><span class="c">%          % Theorem body font (default is "\upshape")</span>
         <span class="k">\interlinepenalty</span>=100<span class="c">%    Discourage breaking between lines.</span>
         <span class="k">\predisplaypenalty</span>=10000<span class="c">% Never break right before a display equation.</span>
         <span class="k">\postdisplaypenalty</span>=100<span class="c">%  Discourage breaking after equations.</span>
         <span class="k">\slshape</span><span class="c">% Use slanted font for Theorem body</span>
     <span class="p">}</span>           
     <span class="p">{}</span>          <span class="c">% Indent amount</span>
     <span class="p">{</span><span class="k">\bfseries</span><span class="p">}</span> <span class="c">% Theorem head font % (default is \mdseries)</span>
     <span class="p">{</span>.<span class="p">}</span>         <span class="c">% Punctuation after theorem head % default: no punctuation</span>
     <span class="p">{</span> <span class="p">}</span>         <span class="c">% Space after theorem head</span>
     <span class="p">{}</span>          <span class="c">% Theorem head spec</span>
</code></pre></div></div>

<p>My initial testing has shown that these penalties value seem to work well, but you can increase them if you find LaTeX is still inserting page breaks in theorems more often then you like or decrease them if your document ends up with a lot of extra vertical space.
The range of valid penalties are <code class="language-plaintext highlighter-rouge">0</code> (no penalty) to <code class="language-plaintext highlighter-rouge">10000</code> (max penalty).</p>

<p>After creating the new theorem style, you must enable it before using <code class="language-plaintext highlighter-rouge">\newtheorem</code>, namely,</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\theoremstyle</span><span class="p">{</span>breakResistantTheorem<span class="p">}</span>
<span class="k">\newtheorem</span><span class="p">{</span>theorem<span class="p">}{</span>Theorem<span class="p">}</span>
<span class="k">\newtheorem</span><span class="p">{</span>lemma<span class="p">}{</span>Lemma<span class="p">}</span>
<span class="c">% etc...</span>
</code></pre></div></div>

<h1 id="custom-qed-marks-at-end-of-environments">Custom QED Marks at End of Environments</h1>

<p>For long environments that are in upright font, I prefer to include a mark at the end of the environment to notify readers where the section ends.
The following command, <code class="language-plaintext highlighter-rouge">\setEnvironmentQed</code> allows for defining the QED-like symbol to automatically insert at the end of all environments of a given type. 
For example, <code class="language-plaintext highlighter-rouge">\setEnvironmentQed{definition}{\ensuremath{\blacksquare}}</code> causes a black square to be inserted at the end of every <code class="language-plaintext highlighter-rouge">definition</code> environment.</p>

<pre class="language-latex">
% Define a macro for changing the QED symbol at the
% end of environments. This command allows for the
% use of \qedhere to insert the QED into, e.g., 
% equations or lists. 
\newcommand{\setEnvironmentQed}[2]{
  % #1: Environment name
  % #2: QED Symbol. Must be OK in text or math mode. 
  %     Use \ensuremath, if math is desired.
  \AtBeginEnvironment{#1}{%
    \pushQED{\qed}\renewcommand{\qedsymbol}{#2}%
  }
  \AtEndEnvironment{#1}{\popQED}
}
</pre>

<p>Here are several options for symbols that can be used to end environments:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: center">Symbol</th>
      <th style="text-align: center">LaTeX Code</th>
      <th style="text-align: center">Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: center">\(\square\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\square</code></td>
      <td style="text-align: center">Traditionally used for the end of proofs</td>
    </tr>
    <tr>
      <td style="text-align: center">\(\blacksquare\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\blacksquare</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\triangle\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\triangle</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\blacktriangle\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\blacktriangle</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\triangledown\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\triangledown</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\blacktriangledown\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\blacktriangledown</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\circ\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\circ</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\bullet\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\bullet</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\diamond\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\diamond</code></td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\blackdiamond</code> is not a built-in macro, nor provided by the <code class="language-plaintext highlighter-rouge">amssym</code> package.</td>
    </tr>
    <tr>
      <td style="text-align: center">\(\lozenge\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\lozenge</code></td>
      <td style="text-align: center"> </td>
    </tr>
    <tr>
      <td style="text-align: center">\(\blacklozenge\)</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\blacklozenge</code></td>
      <td style="text-align: center"> </td>
    </tr>
  </tbody>
</table>

<h1 id="environment-definitions">Environment Definitions</h1>

<h2 id="providetheorem-definition"><code class="language-plaintext highlighter-rouge">\providetheorem</code> definition</h2>

<p>In my LaTeX setup, I prefer to use the same preamble file for all of my documents, but I’ve found that some document classes or packages define the <code class="language-plaintext highlighter-rouge">theorem</code> environment and other related environments, which causes compilation errors. 
To avoid errors when trying to define to new theorem-like environments, <code class="language-plaintext highlighter-rouge">\providetheorem</code> first checks whether the environment is defined.</p>

<pre class="language-latex">
% Create a new macro analogous to "\providecommand", which 
% defines the given amsthm theorem-like environment only if 
% it does not already exist.
\newcommand{\providetheorem}[2]{
  % #1: Environment name.
  % #2: Display name
  \ifcsdef{#1}{
    % The #1 environment is already defined. 
    \ifcsdef{end#1}{}{
      \PackageError{providetheorem}{%
        % Error message:
        The command "#1" was already defined, but "#1end" was 
        undefined, indicating that "#1" is not an environment.
      }{}
    }
  }{
    % The #1 environment is not defined, yet, so we define it.
    \newtheorem{#1}{#2}
  }
}
</pre>

<h2 id="theorem-style">Theorem Style</h2>
<p>There are three default theorem styles: <code class="language-plaintext highlighter-rouge">plain</code>, <code class="language-plaintext highlighter-rouge">definition</code>, and <code class="language-plaintext highlighter-rouge">remark</code>, but I have replaced the <code class="language-plaintext highlighter-rouge">plain</code> style with <code class="language-plaintext highlighter-rouge">sltheorem</code> to use slanted text instead of italics.</p>

<p>The <code class="language-plaintext highlighter-rouge">sltheorem</code> (or <code class="language-plaintext highlighter-rouge">plain</code>) style displays a boldface label and slanted (or italic) body text.</p>

<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">\begin{theorem}[Pythagorean Theorem]
  \label{result:pythagorean}
  The sum of the squares of the legs of a right 
  triangle equals the square of the hypotenuse.
\end{theorem}</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/theoremstyle-sltheorem.png" alt="Screenshot of a theorem rendered using the sltheorem style" /></td>
    </div>
  
</div>

<p>I use the theorem style for any environments that make truth claims, namely <code class="language-plaintext highlighter-rouge">theorem</code>, <code class="language-plaintext highlighter-rouge">proposition</code>, <code class="language-plaintext highlighter-rouge">lemma</code>, <code class="language-plaintext highlighter-rouge">corollary</code>, and <code class="language-plaintext highlighter-rouge">conjecture</code>.</p>

<pre class="language-latex">
%%--------------------------------------------------%%
%| Define environments that use the sltheorem style |%
%%--------------------------------------------------%%
\theoremstyle{sltheorem}%

%%% Define theorem environment %%%
\providetheorem{theorem}{Theorem}
\crefname{theorem}{Theorem}{Theorems}%

%%% Define proposition environment %%%
\providetheorem{proposition}{Proposition}
\crefname{proposition}{Proposition}{Propositions}%

%%% Define lemma environment %%%
\providetheorem{lemma}{Lemma}
\crefname{lemma}{Lemma}{Lemmas}%

%%% Define corollary environment %%%
\providetheorem{corollary}{Corollary}
\crefname{corollary}{Corollary}{Corollaries}%

%%% Define conjecture environment %%%
\providetheorem{conjecture}{Conjecture}
\crefname{conjecture}{Conjecture}{Conjectures}%
</pre>

<h2 id="definition-style">Definition Style</h2>

<p>The <code class="language-plaintext highlighter-rouge">definition</code> style displays a boldface label and upright body text.</p>

<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{definition}
  \label{def:ring center}
  Let $R$ be a ring.
  The \emph{center} of $R$ is the subring of $R$ 
  that contains all elements $c \in R$ such that 
  $c x = x c$ for every $x$ in $R$.
\end{definition}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/theoremstyle-definition.png" alt="Screenshot of an environment using the definition theorem style" /></td>
    </div>
  
</div>

<p>I use the <code class="language-plaintext highlighter-rouge">definition</code> style define the following environments: <code class="language-plaintext highlighter-rouge">definition</code>, <code class="language-plaintext highlighter-rouge">problem</code>, <code class="language-plaintext highlighter-rouge">example</code>, and <code class="language-plaintext highlighter-rouge">assumption</code>.</p>
<pre class="language-latex">
%%---------------------------------------------------%%
%| Define environments that use the definition style |%
%%---------------------------------------------------%%
\theoremstyle{definition}%

%%% Define definition environment %%%
\providetheorem{definition}{Definition}
\crefname{definition}{Definition}{Definitions}%

%%% Define problem environment %%%
\providetheorem{problem}{Problem}
\crefname{problem}{Problem}{Problems}%

%%% Define example environment %%%
\providetheorem{example}{Example}

% Add a mark at the end of each example.
\setEnvironmentQed{example}{\ensuremath{\blacksquare}}

%%% Define assumption environment %%%
% Note: We use singular "Assumption" even when there are 
% multiple assumptions within a particular block.
\providetheorem{assumption}{Assumption}
\crefname{assumption}{Assumption}{Assumptions}

% Add a mark at the end of each assumption.
\setEnvironmentQed{assumption}{\ensuremath{\blacksquare}}
</pre>

<p>In definitions, you should emphasize the defined term to make it stand out.
The preferred way to do this is to surround the term with <code class="language-plaintext highlighter-rouge">\emph{}</code>, which will typically typeset the text in italics.
Unlike <code class="language-plaintext highlighter-rouge">\textit{}</code>, however, the <code class="language-plaintext highlighter-rouge">\emph</code> macro will switch to upright text if the surrounding text is already italicized, ensuring that the term highlighted even if you use italic text in your definition environments.</p>

<h2 id="remark-style">Remark Style</h2>

<p>The <code class="language-plaintext highlighter-rouge">remark</code> style displays an italic label and upright body text.</p>

<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{remark}
  Here is a remark.
\end{remark}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/theoremstyle-remark.png" alt="Screenshot of an environment using the remark theorem style" /></td>
    </div>
  
</div>

<p>I use the <code class="language-plaintext highlighter-rouge">remark</code> style only for the <code class="language-plaintext highlighter-rouge">remark</code> environment.</p>

<pre class="language-latex">
%%-----------------------------------------------%%
%| Define environments that use the remark style |%
%%-----------------------------------------------%%
\theoremstyle{remark}%

%%% Define remark environment %%%
\providetheorem{remark}{Remark}
</pre>

<h1 id="theorem-like-environment-numbering">Theorem-like Environment Numbering</h1>
<p>This section describes how to modify the automatic numbering of Theorem-like environments, such as using unified numbering for multiple types of environments, chapter-based numbering, and using no numbering at all.</p>

<h2 id="unified-numbering-of-different-environment-types">Unified Numbering of Different Environment Types</h2>
<p>Some authors prefer to use one counter for all the results in their document, so instead of</p>

<ul>
  <li>Theorem 1</li>
  <li>Theorem 2</li>
  <li>Lemma 1</li>
  <li>Theorem 3</li>
  <li>Proposition 1</li>
</ul>

<p>the numbering would be</p>

<ul>
  <li>Theorem 1</li>
  <li>Theorem 2</li>
  <li>Lemma 3</li>
  <li>Theorem 4</li>
  <li>Proposition 5</li>
</ul>

<p>The benefit of this method is that it is easier for the reader navigate to a particular result via bisection, but it may confuse readers who try to find “Lemma 1” and “Lemma 2”.</p>

<p>To make LaTeX use a unified numbering, you create the first environment, such as <code class="language-plaintext highlighter-rouge">theorem</code>, and then pass the name <code class="language-plaintext highlighter-rouge">theorem</code> as an optional argument when creating the other environments:</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\newtheorem</span><span class="p">{</span>theorem<span class="p">}{</span>Theorem<span class="p">}</span>
<span class="k">\newtheorem</span><span class="p">{</span>lemma<span class="p">}</span>[theorem]<span class="p">{</span>Lemma<span class="p">}</span>
<span class="k">\newtheorem</span><span class="p">{</span>proposition<span class="p">}</span>[theorem]<span class="p">{</span>Proposition<span class="p">}</span>
<span class="c">%                          ^--- optional argument.</span>
</code></pre></div></div>

<h2 id="chapter-based-numbering">Chapter-based Numbering</h2>

<p>For document classes that use chapters, I prefer to number the theorem-like environments on a chapter-by-chapter basis (e.g., “Theorem 1.1”, “Theorem 1.2” in Chapter 1 and “Theorem 2.1”, “Theorem 2.2” in Chapter 2.) 
The following code automatically enables chapter-based numbering when the <code class="language-plaintext highlighter-rouge">chapter</code> <a href="https://www.overleaf.com/learn/latex/Counters">counter</a> is defined.</p>

<pre class="language-latex">
\ifcsname thechapter\endcsname
    % If the document class uses chapters, 
    % then update numbering to use chapters.
    \numberwithin{assumption}{chapter}
    \numberwithin{definition}{chapter}
    \numberwithin{remark}{chapter}
    \numberwithin{example}{chapter}
    \numberwithin{proposition}{chapter}
    \numberwithin{theorem}{chapter}
    \numberwithin{lemma}{chapter}
    \numberwithin{corollary}{chapter}
    \numberwithin{conjecture}{chapter}
    \numberwithin{application}{chapter}
\fi
</pre>

<h2 id="unnumbered-environments">Unnumbered Environments</h2>
<p>In some contexts, such as presentations, you may wish to use unnumbered environments (e.g., “Theorem” instead “Theorem 1”).
To omit theorem numbering, define theorem environments using <code class="language-plaintext highlighter-rouge">\newtheorem*</code> macro instead of <code class="language-plaintext highlighter-rouge">\newtheorem</code>. 
If you already have <code class="language-plaintext highlighter-rouge">theorem</code> defined, you must use a different name for the unnumbered theorem environment, such as <code class="language-plaintext highlighter-rouge">theorem*</code>.</p>

<pre class="language-latex">
\newtheorem*{theorem*}{Theorem}
</pre>

<p>It is a bad idea, however, to have mixture of numbered and unnumbered theorems in the same document, so you may wish to simply replace <code class="language-plaintext highlighter-rouge">\newtheorem{theorem}{Theorem}</code> with <code class="language-plaintext highlighter-rouge">\newtheorem*{theorem}{Theorem}</code> so that <code class="language-plaintext highlighter-rouge">\begin{theorem}...\end{theorem}</code> inserts unnumbered theorems.</p>

<h1 id="proof-environment">Proof Environment</h1>

<p>The <code class="language-plaintext highlighter-rouge">amsthm</code> package also defines a <code class="language-plaintext highlighter-rouge">proof</code> environment. 
I’ve found the default definition to be exactly how I want it, with a white square inserted at the end of the proof.</p>

<p>The usage is as follows:</p>

<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{proof}
  It is true because I say so.
\end{proof}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/proof-example.png" alt="Screenshot of a basic proof environment." /></td>
    </div>
  
</div>

<p>You can change the “proof” label by using an optional environment argument.</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{proof}[Proof Sketch]
  This example is too small to contain the proof.
\end{proof}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/proof-sketch.png" alt="Screenshot of a proof environment that is labeled as Proof Sketch instead of Proof." /></td>
    </div>
  
</div>

<p>Using the optional argument is particularly useful if a theorem and its proof are separated by other text:</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{proof}[Proof of \cref{result:an earlier theorem}]
  This proof does not occur immediately 
  after \cref{result:an earlier theorem}.
\end{proof}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/proof-separated-from-theorem.png" alt="LaTeX output shows a proof that references a theorem from earlier in the document." /></td>
    </div>
  
</div>
<p>Note that the QED symbol in above example appears at the end of the next line because the first line fills the text width.</p>

<p>If the proof ends with an equation or a list, then the QED symbol will be placed below the equation or list, even if there is space to the side, which wastes space and looks bad:</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{proof}
  The conclusion follow directly from this equation:
  \[
    1 + 1 = 2.
  \] 
\end{proof}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/theorem-like-environments-in-latex/proof-qed-after-equation.png" alt="Screenshot of a proof environment that ends with an equation, resulting in the QED mark placed below the equation." /></td>
    </div>
  
</div>

<p>To fix this problem, place <code class="language-plaintext highlighter-rouge">\qedhere</code> inside the equation or list (at the end) to display the QED symbol at the correct location:</p>
<style>
  .code-output-container {
      display: flex;
      flex-direction: column;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 10px;
      background-color: #f9f9f9;
      /* font-family: 'Courier New', Courier, monospace; */
      margin: 10px 0;
  }

  .code-output-container .code-block,
  .code-output-container .output-block {
      margin-bottom: 10px;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
  }

  .code-output-container .output-block {
      background-color: #fff;
  }

</style>

<div class="code-output-container">
  <!-- <strong>Code:</strong> -->
  <pre class="language-latex"><!-- Use comments to prevent line breaks from appearing in output.
--><pre class="language-latex">
\begin{proof}
  The conclusion follow directly from this equation:
  \[
    1 + 1 = 2. \qedhere
  \] 
\end{proof}
</pre><!--
--></pre>
   
    <!-- <strong>Output:</strong> -->
    <div class="output-block">
        <td><img src="/assets/images/theorem-like-environments-in-latex/proof-qedhere-within-equation.png" alt="Screenshot of a proof environment that ends with an equation using \qedhere so that the QED mark is placed next to the equation." /></td>
    </div>
  
</div>

<h1 id="displaying-environment-labels-in-the-margin">Displaying Environment Labels in the Margin</h1>

<p>When working on a draft, it is convenient to have the labels assigned to an theorem-like environment (via <code class="language-plaintext highlighter-rouge">\label</code>) in the document itself.<br />
To show these labels, along with labels for equations, figures, tables, and whatnot, use the <a href="https://ctan.org/pkg/showlabels"><code class="language-plaintext highlighter-rouge">showlabels</code></a> package.
By default, <code class="language-plaintext highlighter-rouge">showlabels</code> displays each label in the right margin with somewhat unfortunate formatting. 
In particular, labels use inconsistent text weight (some labels are bold while others are not)and long labels extend off the page, without line breaks, even between words.</p>

<p><img src="/assets/images/theorem-like-environments-in-latex/showlabels_with_default_settings.png" alt="Screenshot of labels using the default settings of the showlabels package" /></p>

<p>The following configuration fixes all of these problems by showing each label using a small teletype font in a box that is the width of the right margin, with line breaks after words, as needed. 
Some extra care is taken to avoid warnings from underfull and overfull boxes.</p>

<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\usepackage</span><span class="na">[right]</span><span class="p">{</span>showlabels<span class="p">}</span>
<span class="c">% Using "\upshape" ensures that the label is displayed without italics (e.g., if inside a theorem), and "\ttfamily" displays label with a    font, since it is essentially code.</span>
<span class="k">\renewcommand</span><span class="p">{</span><span class="k">\showlabelfont</span><span class="p">}{</span><span class="k">\scriptsize\upshape\ttfamily</span><span class="p">}</span>
<span class="k">\renewcommand</span><span class="p">{</span><span class="k">\showlabelsetlabel</span><span class="p">}</span>[1]<span class="p">{</span><span class="c">%</span>
  <span class="c">% We use 95% of the marginparwidth because it looks slightly nicer to not have the box extend to the edge of the page.</span>
  <span class="c">% "\raggedright" prevents underfull hbox warnings when the label doesn't fit nicely in a line.</span>
  <span class="k">\fbox</span><span class="p">{</span><span class="k">\parbox</span><span class="p">{</span>0.95<span class="k">\marginparwidth</span><span class="p">}{</span><span class="c">%</span>
    <span class="k">\raggedright</span><span class="c">% Prevent underfull box warnings.</span>
    <span class="k">\hfuzz</span>=1000em<span class="c">% Prevent overfull box warnings (unless more than 1000em too wide!) </span>
    <span class="k">\showlabelfont</span> #1<span class="p">}}</span><span class="c">%</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The result looks like this:
<img src="/assets/images/theorem-like-environments-in-latex/showlabels_with_my_settings.png" alt="Screenshot of labels displayed by showlabels using my settings instead of the defaults." />
<!-- The overlap between the boxes, but it is a compromise that I accept because the labels are easily legible. --></p>

<p>Of course, the labels should typically be hidden from the final version of the document (e.g., before publication). 
Fortunately, <code class="language-plaintext highlighter-rouge">showlabels</code> automatically hides the labels when the document is compiled with the <code class="language-plaintext highlighter-rouge">final</code> option passed to the document class, such as</p>
<div class="language-latex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">\documentclass</span><span class="na">[final]</span><span class="p">{</span>article<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="mathematical-writing" /><category term="typesetting" /><category term="latex" /><summary type="html"><![CDATA[Description of various configurations for LaTeX theorem environments using the amsthm package. Includes descriptions of how to enable internal hyperlinking and cleveref references, change theorem body text from italic to slanted, define custom QED marks, and number theorems by chapter.]]></summary></entry><entry><title type="html">Speaking Mathematical Equations</title><link href="https://luis.emlin.me/speaking-mathematics/" rel="alternate" type="text/html" title="Speaking Mathematical Equations" /><published>2023-12-19T07:43:51+00:00</published><updated>2023-12-19T07:43:51+00:00</updated><id>https://luis.emlin.me/speaking-mathematics</id><content type="html" xml:base="https://luis.emlin.me/speaking-mathematics/"><![CDATA[<p>A common difficulty encountered by math students is the difficulty of translating equations into words.
Such translations are unavoidable when verbally discussing mathematics, and being a fluent translator is also a powerful aid to a student’s understanding.
<!-- Throughout mathematical literature, many mathematical statements written are as equations rather than as natural language.  -->
<!-- The motivations for using equations are clear.  -->
Equations are, of course, ubiquitous in mathematics (although this was not the case in antiquity; cf. <a href="https://philomatica.org/wp-content/uploads/2024/04/Elements.pdf">Euclid’s Elements</a>).
Compared to an English sentence, an equation is often more compact, less ambiguous, and allows information to be arranged on the page in ways that aids clarity.</p>

<!-- There are three sources of difficulties when translating an equation:

1. Identifying the name and meaning of each symbol. (e.g., "$\int$" means "integral", and "$\mathbb{R}$" means the set of real numbers). -->

<p>Even simple equations can be difficult to put into words accurately.
One example is the use of parentheses to indicate grouping.
 <!-- of a mathematical notation that is easy to write in an equation but often cumbersome to translate into words.  -->
Consider the equation,</p>

\[a (b + c) = 1 / (b + c).\]

<p>A naive translation into English would lose the groupings imposed by the parentheses: “a times b plus c equals one over b plus c”.
Indeed, this sentence erroneous translation indicates a different equation:</p>

\[ab + c = 1/b + c.\]

<p>This example illustrates how a speaker must be careful to indicate the groupings in their speech.
It is not self-evident how to do this and the remainder of this document describes how to translate specific mathematical expressions into English.
For this example, a precise translation is “a times the sum of b plus c equals one over the sum of b plus c”.</p>

<h1 id="math-to-english-translation-recipes">Math to English Translation Recipes</h1>

<p>This section contains recipes for how to translate from various mathematical expressions into English.
Since any mathematical expression can be translated multiple ways, several translations are given in the right column of each table.</p>

<!-- When all else fails, one may resot -->
<h2 id="parentheses-and-grouping">Parentheses and Grouping</h2>

<table>
<tr>
  <th></th>
  <th>Mathematical Expression</th>
  <th>English Translation</th>
</tr>
<tr>
  <td>Arithmetic Grouping</td>
  <td>$a(b+c)$</td>
  <td>
      "a times open parentheses b plus c close parentheses." (avoid this!)<br />
      "a times the sum of b and c." <br />
      "a times the quantity b plus c."<br />
      "The product of a and the quantity b plus c."<br />
  </td>
</tr>
<tr>
  <td>Arithmetic Grouping</td>
  <td>$(a+b)c$</td>
  <td>
      "a plus b <b>all</b> times c." <br />
      "The product of a plus b times c."<br />
      "The quantity a plus b multiplied by c."
  </td>
</tr>
<tr>
  <td>Division</td>
  <td>$(a + b)/c$</td>
  <td>
    "a plus b all divided by c"<br />
    "The sum of a and b <b>all</b> divided by c"<br />
    "The fraction a plus b over c"<br />
  </td>
</tr>
</table>

<h2 id="sets">Sets</h2>

<table>
<tr>
  <th></th>
  <th>Equation</th>
  <th>English Translation</th>
</tr>
<tr>
  <td>Set</td>
  <td>$\{1, 2, 3\}$</td>
  <td>
      "The set containing one, two, and three."<br />
      "The set of one, two, and three."
  </td>
</tr>
<tr>
  <td>Set-builder Notation</td>
  <td>$\{x \in \mathbb{R} \mid P(x)\}$</td>
  <td>
      "The set of all 'x' in 'R' such that 'P' of 'x' is satisfied."<br />
      "The set of 'x' in 'R' such that 'P' of 'x'."
  </td>
</tr>
<tr>
  <td>Element of</td>
  <td>$x \in A$</td>
  <td>
      "'x' is an element of 'A'."<br />
      "'x' is in 'A'."<br />
  </td>
</tr>
<tr>
  <td>Subset of</td>
  <td>$A \subset B$</td>
  <td>
      "(The set) 'A' is a subset of 'B'."<br />
      "(The set) 'A' is contained in 'B'."<br />
  </td>
</tr>
<tr>
  <td>Superset of</td>
  <td>$A \supset B$</td>
  <td>
      "(The set) 'A' is a super set of 'B'."<br />
      "(The set) 'A' contains 'B'."<br />
  </td>
</tr>
<tr>
  <td>Strict Subset of</td>
  <td>$A \subsetneq B$</td>
  <td>
      "(The set) 'A' is a strict subset of 'B'."<br />
      "(The set) 'A' is a proper subset of 'B'."<br />
      "(The set) 'A' is a subset of 'B', but not equal to 'B'."<br />
  </td>
</tr>
<tr>
  <td>Union</td>
  <td>$A \cup B$</td>
  <td>
      "The union of 'A' and 'B'."<br />
      "'A' union 'B'."
  </td>
</tr>
<tr>
  <td>Intersection</td>
  <td>$A \cap B$</td>
  <td>
      "The intersection of 'A' and 'B'."<br />
      "'A' intersection 'B'."<br />
      "'A' intersect 'B'."
  </td>
</tr>
</table>

<h2 id="calculus">Calculus</h2>

<table>
<tr>
  <th></th>
  <th>Equation</th>
  <th>English Translation</th>
</tr>
<tr>
  <td>Integrals</td>
  <td>$$\int_a^b f(x) dx$$</td>
  <td>
    "The integral of f of x over x from a to b."<br />
    "The integral of f of x, dee-x with lower limit a and upper limit b."<br />
  </td>
</tr>
<tr>
  <td>Total Derivatives</td>
  <td>$$\frac{df}{dx}$$</td>
  <td>
    "dee-f, dee-x."<br />
    "The derivative of f with respect to x."<br />
  </td>
</tr>
<tr>
  <td>Second Derivatives</td>
  <td>$$\frac{d^2f}{dx^2}$$</td>
  <td>
    <!-- "dee-f, dee-x."<br> -->
    "The second derivative of f with respect to x."<br />
    (If you have a shorter or alternative way to say this, please let me know).<br />
  </td>
</tr>
<tr>
  <td>Second Derivatives</td>
  <td>$$\frac{d^2f}{dxdy}$$</td>
  <td>
    <!-- "dee-f, dee-x."<br> -->
    "The second derivative of f with respect to x and y."<br />
    (If you have a shorter or alternative way to say this, please let me know).<br />
  </td>
</tr>
<tr>
  <td>Total Derivatives (Evaluated)</td>
  <td>$$\frac{df}{dx}\Big\rvert_{x_0}$$</td>
  <td>
    "dee-f, dee-x at x-zero."<br />
    "The derivative of f with respect to x evaluated at x-zero."<br />
  </td>
</tr>
<tr>
  <td>Total Derivatives (Evaluated)</td>
  <td>$$f'(x)$$</td>
  <td>
    "f-prime of x."<br />
    "The derivative of f at x."<br />
  </td>
</tr>
<tr>
  <td>Partial Derivative</td>
  <td>$$\frac{\partial f}{\partial x}$$</td>
  <td>
    "partial f, partial x."<br />
    "The partial derivative of f with respect to x."<br />
  </td>
</tr>
</table>

<h2 id="linear-algebra">Linear Algebra</h2>
<table>
<tr>
  <th></th>
  <th>Equation</th>
  <th>English Translation</th>
</tr>
<tr>
  <td>Matrix Element</td>
  <td>$$A_{ij}$$</td>
  <td>
    "The $i$,$j$ element of $A$."<br />
  </td>
</tr>
<tr>
  <td>Matrix Multiplication</td>
  <td>$$Ax$$</td>
  <td>
    "$A$ times $x$."<br />
    "$A$ $x$."<br />
  </td>
</tr>
<tr>
  <td>Transpose</td>
  <td>$$A^\top$$</td>
  <td>
    "$A$ transpose."<br />
    "The transpose of $A$."<br />
  </td>
</tr>
<tr>
  <td>Inverse</td>
  <td>$$A^{-1}$$</td>
  <td>
    "$A$ inverse."<br />
    "The inverse of $A$."<br />
  </td>
</tr>
<tr>
  <td>Dot Product</td>
  <td>$$x \cdot y$$</td>
  <td>
    "$x$ dot $y$."<br />
    "The dot product of $x$ and $y$."<br />
  </td>
</tr>
<tr>
  <td>Inner Product</td>
  <td>$$\langle x, y\rangle$$</td>
  <td>
    "The inner product of $x$ and $y$."<br />
  </td>
</tr>
<tr>
  <td>Null space</td>
  <td>$$\operatorname{null} A$$</td>
  <td>
    "The null space of matrix $A$."<br />
  </td>
</tr>
<tr>
  <td>Column space</td>
  <td>$$\operatorname{col} A$$</td>
  <td>
    "The column space of matrix $A$."<br />
  </td>
</tr>
<tr>
  <td>Coordinate</td>
  <td>$$[x]_{\mathcal{B}}$$</td>
  <td>
    "The coordinate vector of (vector) $x$ relative to (basis) $\mathcal{B}$."<br />
    "The $\mathcal{B}$-coordinate vector of $x$."<br />
  </td>
</tr>
</table>

<p>This is document is a work in progress that will continue to grow as I find examples that are worthy of inclusion. If you have suggestions, please <a href="mailto:info+ws@emlin.me">contact me</a>.</p>

<p>For more on this topic, see <a href="https://people.eecs.berkeley.edu/~fateman/papers/speakmath.pdf">“How can we speak math?”</a> by Richard Fateman.</p>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><summary type="html"><![CDATA[A guide to translating mathematics into English sentences.]]></summary></entry><entry><title type="html">Sums-of-Squares Programming: Introduction</title><link href="https://luis.emlin.me/research/intro-to-SOS/" rel="alternate" type="text/html" title="Sums-of-Squares Programming: Introduction" /><published>2023-08-27T16:00:00+00:00</published><updated>2023-08-27T16:00:00+00:00</updated><id>https://luis.emlin.me/research/intro-to-SOS</id><content type="html" xml:base="https://luis.emlin.me/research/intro-to-SOS/"><![CDATA[<p>$
% Define macros.
\def\reals{\mathbb{R}}
\def\realsn{\reals^n}
\def\Safe{{\mathbf{Safe}}}
\def\Unsafe{{\mathbf{Unsafe}}}
\def\Init{{\mathbf{Init}}}
\def\ip[2]{\left\langle #1, #2\right\rangle}
\newcommand{\ip}[2]{\left\langle #1, #2 \right\rangle}
\newcommand{\SOSpolys}{\Sigma}%{\mathcal P_{SOS}}
\newcommand{\maximize}{\operatorname*{maximize}}
\newcommand{\subjectto}{\textup{subject to}}
$</p>

<p>In dynamical systems and mathematical control theory, it is often useful to show that a given function has a particular sign for all inputs in given sets. 
For example, given $f : \realsn \to \reals$ and $S\subset \realsn$, we may want to show $f(x) \geq 0$ for all $x \in S$.
Prominent examples include Lyapunov functions, which are used to prove stability, and barrier functions which are used to prove set invariance.</p>

<p>As a simple example, consider a dynamical system with state vector \(x \in \realsn\), vector field \(f : \realsn \to \realsn\), and dynamics given by</p>

<p>\begin{equation}
  \label{eq:ode}
  \dot x = f(x).
\end{equation}</p>

<p>Suppose we want to show that the origin \(0 \in \realsn\) is stable for (\ref{eq:ode}). 
Roughly speaking, this means that all solutions that start near the origin remain near it for all time.
A common approach to show stability is to pick a neighborhood \(U\) of the origin and construct a differentiable function $V : U \to \reals$, called a <em>Lypunov function</em> that satisfies the following criteria:</p>

<ol>
  <li>$V(0) = 0$</li>
  <li>$V(x) &gt; 0 $ for all $x \in U $ such that $x \neq 0 $</li>
  <li>$\dot V(0) = 0$</li>
  <li>$\dot V(x) \leq 0$ for all $x \in U $ such that $x \neq 0 $</li>
</ol>

<p>where \(\dot V(x)\) is the rate of change of \(V(x(t))\) as \(t \mapsto x(t)\) evolves according to (\ref{eq:ode}).
The existence of a Lyapunov function proves that the origin is stable <a class="citation" href="#khalil_nonlinear_2014">[1, Theorem 4.1]</a>.</p>

<p>Constructing a Lyapunov is often difficult because it requires finding a function that satisfies multiple inequalities at every point in a set, and the inequalities depend on the function itself, its derivative, and the dynamics of the system.
The purpose of this page is to introduce sum-of-squares (SOS) programming, which can be used to automatically generate Lyapunov functions and solve other similar problems.</p>

<!-- If $$V$$ satisfies criteria 1 and 2, it is said to be _positive definite_ (relative to the origin,) and if $\dot V(0)$ satisfies criteria 3 and 4, then $\dot V(0)$ is said to be _negative semi-definite_ (relative to the origin). More is said aboue positive/negative (semi-)definite functions later. -->
<!-- TODO: Add link to 'later'. -->

<p><em>Remark.</em> There are actually many different variants of Lyapunov functions for showing…</p>
<ul>
  <li>…different types of stability (asymptotic, input-to-state, global, etc.),</li>
  <li>…the stability of some set \(\mathcal A \subset \realsn\) rather than the single point at the origin</li>
  <li>…stability in continuous-time, discrete-time, and hybrid systems.</li>
</ul>

<p>Most of these variants can be handled by SOS programming, so long as the data of the system are given in terms of polynomials.</p>

<h1 id="mathematical-fundamentals">Mathematical Fundamentals</h1>
<!-- # Function Sign Property Definitions  -->
<!-- Let $$f : \realsn \to \reals$$ be a function. -->
<!-- We begin with an explaination of sum of squares programming.  -->

<p>The basis for SOS programming lies in the following fact:
For any function $f : \realsn \to \reals,$ let $f^2$ indicate the function $x \mapsto (f(x))^2$. 
Then, for any choice of functions \(f_1,\ f_2,\ \dots,\ f_N : \realsn \to \reals\),</p>

\[f_1^2(x) + f_2^2(x) + \cdots + f_N^2(x) \geq 0 \quad \forall x \in \realsn\]

<p>and the sum is zero if and only if \(f_1(x) = f_2(x) = \cdots = f_N(x) = 0.\)</p>

<p>Working with general functions is difficult, so we restrict the choices for \(f_1,\ f_2,\ \dots,\ f_N\) to polynomials. 
In particular, we allow for multivariate polynomials, such as  $(x, y) \mapsto x^2 + xy + 3y^2 $ or $(x, y, z) \mapsto 1 + x^3 - 2xyz^2$.
<!-- (Recall that polynomials are functions of one or more variables similar to $x \mapsto 1 + x^2$ and $ (x, y, z) \mapsto 1 + x^3 - 2xyz^2$.)  --></p>

<p>We say that a polynomial \(p : \reals^n \to \reals\) is a <em>sum of squares</em> if there exist polynomials \(p_1, p_2, \dots, p_m : \reals^n \to \reals\) such that</p>

<p>\begin{equation}
  \label{eq:sos}
  p(x) = \sum_{i=1}^m p_i^2(x).
\end{equation}</p>

<p>Note that the argument $x$ for $p$ is a vector $x \in \realsn$, so we may write it as  $x = (x_1, x_2, \dots, x_n)$. 
We denote the set of all SOS polynomials over $x$ by $\SOSpolys[x]$ or $\SOSpolys[x_1, x_2, \dots, x_n]$.
(This notation is used in <a class="citation" href="#tobenkin_invariant_2011">[2]</a>, but there does not appear to be a prevailing standard.
Other notations used in the literature include 
  <!-- $\Sigma[x]$ <a class="citation" href="#tobenkin_invariant_2011">[2]</a>, -->
  $\mathscr{P}^{\mathup{SOS}}$ <a class="citation" href="#wang_permissive_2018">[3]</a>, and simply $\mathup{SOS}$.)</p>

<p>To solve problems using SOS polynomials, we need to put problems into a standard problem format, described in the next section, which can be solved algorithmically using a computer.</p>

<h2 id="sos-optimization-problem-formulation">SOS Optimization Problem Formulation</h2>

<p>In general, an SOS optimization problem (also called an <em>SOS program</em>) has a linear cost function and one or more SOS constraints—that is, the constraints of the optimization problem require that certain polynomials are sums of squares.</p>

<p>To give a general formulation of an SOS problem, we denote the decision variables as $u = (u_1, u_2, \dots, u_n) \in \reals^m$. 
The linear cost function is defined by $c^\top u$ for some vector $c\in \reals^m$.
To specify an SOS problem with $N$ constraints requires picking $N(m+1)$ polynomials, which we write $p_{i,j}$ for $i = 1, 2, \dots, N$ and $j = 0, 1, \dots, m$. 
An SOS problem is then written</p>

<div>
\begin{equation}
  \label{eq:sos program}
  \begin{aligned}
    \maximize_{u\in\reals^m}\quad &amp; c^\top u \\
    \subjectto \quad 
      &amp; p_{1,0} + u_1 p_{1,1} + \cdots + u_m p_{1,m} \in \SOSpolys[x] \\
      &amp; p_{2,0} + u_1 p_{2,1} + \cdots + u_m p_{2,m} \in \SOSpolys[x] \\
      &amp; \hspace{7em} \vdots \\
      &amp; p_{N,0} + u_1 p_{N,1} + \cdots + u_m p_{N,m} \in \SOSpolys[x] \\
      &amp; A_{\text{eq}} u = b_{\text{eq}} \\
      &amp; A_{\text{ieq}} u \leq b_{\text{ieq}} 
      %&amp; \textup{Equality constraints on $u_1$, $u_2$, ..., $u_m$} \\ 
      %&amp; \textup{Inequality constraints on $u_1$, $u_2$, ..., $u_m$}
  \end{aligned}
\end{equation}
</div>

<p>Thus, a solution to (\ref{eq:sos program}) is a vector $u^*\in\reals^m$ that minimizes $c^\top u^*$ while satisfying the requirement that for each $i = 1, 2, \dots, N$, the function</p>

\[x \mapsto p_{i,0}(x) + u^*_1 p_{i,1}(x) + \cdots + u^*_m p_{i,m}(x)\]

<p>is a sum of squares.</p>

<p><em>Remark.</em> At this point, you might be concerned about how to compute a solution to (\ref{eq:sos program}). 
It turns out that (\ref{eq:sos program}) can be reformulated into a semidefinite program (SDP), which is a type of convex optimization problem that can be efficiently and reliably solved using numerical solvers (assuming a solution exists). 
We plan to describe how to solve SOS problems in a later post.</p>

<h3 id="example-lyapunov-function">Example: Lyapunov Function</h3>

<p>Consider a 2D continuous-time dynamical system with state vector $x = (x_1, x_2) \in \reals^2$ and dynamics given by</p>

<div>
\begin{equation}
  \label{eq:lyapunov}
  \dot x = f(x) := \begin{bmatrix} 
                    x_2 \\ 
                    (-x_1 - 2x_2)(x_1 + x_2)^2
                  \end{bmatrix}   
\end{equation}
</div>

<p>We can guess the form of a Lyapunov function to be</p>

\[V(x) = u_1 p_1(x_1, x_2) + u_2 p_2(x_1, x_2) + \cdots + u_m p_m(x_1, x_2)\]

<p>where each $p_i$ is a polynomial function.
<!-- Your choices for $m$ and each $p_i$ will depend on the particular problem you are trying to solve.  -->
Picking $m$ and each $p_i$ is typically a process of trial and error using intuitive guesses based on the structure and complexity of the problem.
We will use $m = 3$ and</p>

\[\begin{aligned}
p_1(x_1, x_2) := x_1^2 \\
p_2(x_1, x_2) := x_2^2  \\
p_3(x_1, x_2) := x_1x_2
\end{aligned}\]

<p>Therefore, the general form of $V$ is 
\(V(x) = u_1 x_1^2 + u_2 x_2^2 + u_3 x_1x_2.\) 
Calculating $\dot V,$ we find</p>

\[\begin{aligned}
x \mapsto \dot V(x) 
&amp;= \ip{\nabla V(x)}{f(x)} \\
&amp;= \ip{\begin{bmatrix}2u_1x_1 +u_3 x_2 \\ 2u_2x_2 + u_3 x_1\end{bmatrix}}
     {\begin{bmatrix}x_2 \\ (-x_1 - 2x_2)(x_1 + x_2)^2 \end{bmatrix}} \\
&amp;= 2u_1x_1x_2 + u_3 x_2^2 \\ 
&amp;\quad {} + 2u_2x_2(-x_1 - 2x_2)(x_1 + x_2)^2 \\ 
&amp;\quad {} + u_3 x_1(-x_1 - 2x_2)(x_1 + x_2)^2 
\end{aligned}\]

<p>We want $V$ to be positive definite relative to the origin, so it is necessary that $V(x) \in \SOSpolys[x]$, but this is not sufficient because an SOS polynomial can be only positive <em>semidefinite</em> rather than positive <em>definite</em>. 
You can add constraints on $u_1$, $u_2$, and $u_3$ to ensure $V$ is positive definite. 
The simplest choice is to require that $u_1$ and $u_2$ are positive and $u_3$ is zero, so $V$ is a bowl shaped function:</p>

\[V(x) = u_1 x_1^2 + u_2 x_2^2.\]

<p>The constraints are then,</p>

\[\begin{aligned}
u_1 &amp;&gt; 0 \\ 
u_2 &amp;&gt; 0 \\ 
u_3 &amp;= 0.
\end{aligned}\]

<p>For numerical reasons, strict inequalities don’t work well in optimization problems, we instead pick some $\epsilon &gt; 0$ and change the constraints to</p>

\[\begin{aligned}
u_1 &amp;\geq \epsilon \\ 
u_2 &amp;\geq \epsilon \\ 
u_3 &amp;= 0.
\end{aligned}\]

<p>Rewriting these constraints using matrices, we have</p>

\[\begin{aligned}
\begin{bmatrix}
-1 &amp;  0 &amp; 0 \\ 
 0 &amp; -1 &amp; 0
\end{bmatrix} u
  &amp;\leq \begin{bmatrix}
  -\epsilon \\ 
  -\epsilon
  \end{bmatrix} 
\\
\begin{bmatrix}
 0 &amp; 0 &amp; 1
\end{bmatrix} u
  &amp;= 0.
\end{aligned}\]

<p>Becuase we won’t know a good choice of $\epsilon$ beforehand, we can make it one of the decision variables and make the cost function $(u, \epsilon) \mapsto \epsilon$ so that the optimizer tries to find the largest value of $\epsilon$ such that the problem has solution. 
<!-- We also add a constraint that $\epsilon \geq 0$.  -->
We must check the value of $\epsilon$ for the solution to the optmization problem to ensure $\epsilon &gt; 0$.</p>

<p>An unfortunate side effect of this choice is that it removes a degree of freedom by setting $u_3=0$. 
This can be avoided by instead partitioning $V$ into the sum of a positive semidefinite function and a positive definite function, such as</p>

\[V(x) := \underbrace{u_1 x_1^2 + u_2 x_2^2 + u_3 x_1x_2}_{\textup{positive semidefinite}} + \underbrace{u_4 x_1^2 + u_4 x_2^2}_{\textup{positive definite}}.\]

<p>The corresponding constraints are then</p>

\[\begin{aligned}
(x \mapsto u_1 x_1^2 + u_2 x_2^2 + u_3 x_1x_2) &amp;\in \SOSpolys[x] \\ 
\begin{bmatrix}
0 &amp; 0 &amp; 0 &amp; -1 &amp;  0 \\ 
0 &amp; 0 &amp; 0 &amp;  0 &amp; -1
\end{bmatrix} u
  &amp;\leq \begin{bmatrix}
  -\epsilon \\ 
  -\epsilon
  \end{bmatrix} 
\end{aligned}\]

<p>Conversely, we want $\dot V$ to be negative semidefinite relative to the origin. 
Thus,</p>

\[\begin{aligned}
x \mapsto -\dot V(x) \in \SOSpolys[x].
\end{aligned}\]

<p>Therefore, the SOS problem formulation is</p>
<div>
\begin{equation}
  \label{eq:lyapunov sos problem}
  \begin{aligned}
    \maximize \quad &amp; \epsilon \\
    \subjectto \quad 
      &amp;x \mapsto u_1 x_1^2 + u_2 x_2^2 + u_3 x_1x_2 \in \SOSpolys[x] \\ 
      &amp;\begin{bmatrix}
      0 &amp; 0 &amp; 0 &amp; -1 &amp;  0 \\ 
      0 &amp; 0 &amp; 0 &amp;  0 &amp; -1
      \end{bmatrix} u
        \leq \begin{bmatrix}
        -\epsilon \\ 
        -\epsilon
        \end{bmatrix} \\
      &amp; {-}\dot{V} \in \SOSpolys[x] 
  \end{aligned}
\end{equation}
</div>

<!-- A couple notes: -->
<!-- * There is no cost function because we are trying to solve a feasibility problem rather than minimize a value. You can make the  -->
<!-- * We have tightened the conditions given for stability by requiring $V$ is positive definite and $\dot V$ is negative semidefinite on $\realsn$ instead of only on a neighborhood $U$.  -->

<h3 id="definitions-of-positive-definite-and-positive-semidefinite-functions">Definitions of positive definite and positive semidefinite functions.</h3>

<p>A function \(f : \realsn \to \reals\) is said to be <i>positive semi-definite</i> if</p>

\[f(x) \geq 0 \quad \forall x \in \realsn\]

<p>and \(f(0) = 0.\)</p>

<p>A function \(f : \realsn \to \reals\) is said to be <i>positive definite</i> if</p>

\[f(x) &gt; 0 \quad \forall x \in \realsn \setminus\{0\}\]

<p>and \(f(0) = 0.\)</p>

<p>Negative semidefinite and negative definite functions are defined similarly, except with the inequality signs flipped.</p>

<p><strong>Example.</strong> The parabola \(x \mapsto x^2\) is positive definite.</p>

<p><strong>Non-example.</strong> The parabola \(x \mapsto x^2 + 1\) is not positive definite because the value at \(x=0\) is \(1\).</p>

<p><strong>Non-example.</strong> In two variables, the function \((x, y) \mapsto x^2\) is not positive definite because the value at \((0, 1)\) is \(0\).</p>

<h1 id="further-reading">Further Reading</h1>
<ul>
  <li><a class="citation" href="#kevin_hartnett_classical_2018">[4]</a> gives an introduction to SOS programming targeted at a non-technical audience.</li>
  <li><a class="citation" href="#duan_computational_2023">[5]</a> provides a way to generate control barrier functions for control-affine feedback systems.</li>
  <li><a class="citation" href="#prajna_safety_2004">[6]</a> describes how to use sum of squares programming to generate barrier functions barrier functions for hybrid systems.</li>
  <li><a class="citation" href="#sloth_existence_2012">[7]</a> introduces a way to simplify complicated systems with multiple components so that barrier functions can be found for individual subcomponents separately.</li>
  <li><a class="citation" href="#wang_permissive_2018">[3]</a> introduces techniques that allow for synthesizing better barrier functions.</li>
  <li><a class="citation" href="#noauthor_getting_nodate">[8]</a> contains links to various tools for working with SOS’s in various programming languages.</li>
</ul>

<h1 id="bibliography">Bibliography</h1>
<ol class="bibliography"><li><span id="khalil_nonlinear_2014">[1] H. K. Khalil, <i>Nonlinear Systems</i>, Third. Pearson, 2014.</span></li>
<li><span id="tobenkin_invariant_2011">[2] M. M. Tobenkin, I. R. Manchester, and R. Tedrake, “Invariant Funnels around Trajectories using Sum-of-Squares Programming,” <i>IFAC Proceedings Volumes</i>, vol. 44, no. 1, pp. 9218–9223, Jan. 2011, doi: 10.3182/20110828-6-IT-1002.03098.</span></li>
<li><span id="wang_permissive_2018">[3] L. Wang, D. Han, and M. Egerstedt, “Permissive barrier certificates for safe stabilization using sum-of-squares,” in <i>Proceedings of the 2018 American Control Conference</i>, Jun. 2018, pp. 585–590. doi: 10.23919/ACC.2018.8431617.</span></li>
<li><span id="kevin_hartnett_classical_2018">[4] Kevin Hartnett, “A Classical Math Problem Gets Pulled Into the Modern World,” <i>Quanta Magazine</i>, May 2018, Accessed: August 28, 2023. [Online ]. Available at: https://www.quantamagazine.org/a-classical-math-problem-gets-pulled-into-the-modern-world-20180523/</span></li>
<li><span id="duan_computational_2023">[5] Y. Duan and X. Zeng, “Computational synthesis of control barrier functions with applications in automotive lane keeping supervisory control,” <i>IET Control Theory &amp; Applications</i>, vol. n/a, no. n/a, 2023, doi: 10.1049/cth2.12422.</span></li>
<li><span id="prajna_safety_2004">[6] S. Prajna and A. Jadbabaie, “Safety verification of hybrid systems using barrier certificates,” in <i>Hybrid Systems: Computation and Control</i>, R. Alur and G. J. Pappas, Eds., in Lecture Notes in Computer Science. Berlin, Heidelberg: Springer, 2004, pp. 477–492. doi: 10.1007/978-3-540-24743-2_32.</span></li>
<li><span id="sloth_existence_2012">[7] C. Sloth, R. Wisniewski, and G. J. Pappas, “On the existence of compositional barrier certificates,” in <i>Proceedings  of the 51st IEEE Conference  on Decision and Control</i>, Dec. 2012, pp. 4580–4585. doi: 10.1109/CDC.2012.6426178.</span></li>
<li><span id="noauthor_getting_nodate">[8] “Getting started with Sum of Squares.” Accessed: March 13, 2023. [Online ]. Available at: https://sums-of-squares.github.io/sos/</span></li></ol>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="research" /><summary type="html"><![CDATA[Introduction to the theory and use of SOS programming.]]></summary></entry><entry><title type="html">Tracking Revisions in LaTeX</title><link href="https://luis.emlin.me/permalink/tracking-revisions-in-latex" rel="alternate" type="text/html" title="Tracking Revisions in LaTeX" /><published>2023-04-02T16:00:00+00:00</published><updated>2023-04-02T16:00:00+00:00</updated><id>https://luis.emlin.me/permalink/tracking-revisions-in-latex</id><content type="html" xml:base="https://luis.emlin.me/permalink/tracking-revisions-in-latex"><![CDATA[<p>As a PhD student, an essential part of my job is sending drafts to my advisor for his feedback. 
Because his time is limited, it is crucial that I direct his attention to the parts of the document that I modified.
A useful tool for tracking changes is the <a href="https://www.ctan.org/pkg/changes"><code class="language-plaintext highlighter-rouge">changes</code></a> LaTeX package. 
To import the package, add <code class="language-plaintext highlighter-rouge">\usepackage{changes}</code> to your document’s preamble. 
The <code class="language-plaintext highlighter-rouge">changes</code> package defines four types of annotations: <code class="language-plaintext highlighter-rouge">\added</code>, <code class="language-plaintext highlighter-rouge">\deleted</code>, <code class="language-plaintext highlighter-rouge">\replaced</code>, and <code class="language-plaintext highlighter-rouge">\comment</code> and also imports the <code class="language-plaintext highlighter-rouge">\todo</code> macro from the <a href="https://www.ctan.org/pkg/todo"><code class="language-plaintext highlighter-rouge">todo</code></a> package.</p>

<p><strong>Example:</strong></p>
<pre class="language-latex">Here is \added{added}, \deleted{deleted} 
and \replaced{replaced}{replaysed} text.
\comment{Maybe I shouldn't have written this?}
\todo[inline]{To-do: Write something worthwhile.}</pre>
<p><strong>Output:</strong></p>

<p><img src="/assets/images//changes_example.png" alt="Rendered LaTeX document shows annotations." /></p>

<h2 id="workflow">Workflow</h2>
<p>In order for annotations to be useful they must be up-to-date.
This raises the question of when to remove annotations.
The best workflow depends on the way your reviewer gives feedback. 
If your reviewer will read the entire document, then you can delete annotations immediately after sending them a draft.
In my case, however, my advisor only reads a portion of each draft I send, so I leave annotations until he has given feedback. 
To this motivates the following workflow:</p>
<ol>
  <li>Annotate each change to the PDF.</li>
  <li>Compile PDF and share with reviewer.</li>
  <li>Commit changes to the source code into Git or another source control management software. (If you aren’t tracking the changes to your source code, then start!)</li>
  <li>Wait for reviewer to give comments or continue editing the document (as in step 1).</li>
</ol>

<p>Once the reviewer gives you comments:</p>
<ol>
  <li>Commit current version to Git.</li>
  <li>Delete the annotations <em>only from the sections of the document that were reviewed</em>.</li>
  <li>Commit the new version, without the deleted annotations.</li>
</ol>

<h2 id="annotating-blocks-of-text">Annotating Blocks of Text</h2>
<p>When annotating a sentence or more, I format my LaTeX code with <code class="language-plaintext highlighter-rouge">\added{</code> and <code class="language-plaintext highlighter-rouge">}</code> on their own lines. 
Including <code class="language-plaintext highlighter-rouge">%</code> immediately after <code class="language-plaintext highlighter-rouge">\added{</code> and after <code class="language-plaintext highlighter-rouge">}</code> prevents LaTeX from inserting extra spaces (LaTeX treats a new line in the code the same as a space).</p>

<pre class="language-latex">\added{%
  Lorem ipsum dolor sit amet, consectetur 
  adipiscing elit, sed do eiusmod tempor 
  incididunt ut labore et dolore magna aliqua. 
}% End \added block
</pre>

<p>If you use Visual Studio Code, see <a href="#visual-studio-configuration">below</a> for snippets that will wrap selected text in annotation commands.</p>

<p>The commands <code class="language-plaintext highlighter-rouge">\added</code>, <code class="language-plaintext highlighter-rouge">\deleted</code>, and <code class="language-plaintext highlighter-rouge">\replaced</code> cannot contain a paragraph break.
This precludes empty lines, such as</p>
<pre class="language-latex">\added{  
  % Paragraph 1
  Lorem ipsum dolor sit amet, consectetur 
  adipiscing elit, sed do eiusmod tempor 
  incididunt ut labore et dolore magna aliqua. 

  % Paragraph 2 (Causes error!)
  Duis aute irure dolor in reprehenderit 
  in voluptate velit esse cillum dolore 
  eu fugiat nulla pariatur.
}</pre>

<p>To mark multiple paragraphs as changed, I define a new color called <code class="language-plaintext highlighter-rouge">added</code> using the <a href="https://www.ctan.org/pkg/xcolor"><code class="language-plaintext highlighter-rouge">xcolor</code></a> package</p>
<pre class="language-latex">
\usepackage{xcolor}
\colorlet{added}{blue!80!black} 
</pre>
<p>Then, add <code class="language-plaintext highlighter-rouge">\color{added}</code> before a multiple paragraph change, and add <code class="language-plaintext highlighter-rouge">\color{black}</code> afterward.</p>
<pre class="language-latex">\color{added} 
% Paragraph 1 (Added)
Lorem ipsum dolor sit amet, consectetur 
adipiscing elit, sed do eiusmod tempor 
incididunt ut labore et dolore magna aliqua. 

% Paragraph 2 (Added)
Duis aute irure dolor in reprehenderit 
in voluptate velit esse cillum dolore 
eu fugiat nulla pariatur.
\color{black} 

% Paragraph 3 (No change)
Excepteur sint occaecat cupidatat non 
proident, sunt in culpa qui officia 
deserunt mollit anim id est laborum.
</pre>
<p><strong>Output:</strong></p>

<p><img src="/assets/images//changes_example_multiple_paragraphs.png" alt="Rendered LaTeX document shows annotations." /></p>

<h2 id="package-configuration">Package Configuration</h2>
<p>There are various package options. For my documents, I use the following:</p>

<pre class="language-latex">\usepackage[ % import "changes" package
    % If any of the changes commands are already defined, then the option "commandnameprefix=ifneeded" 
    % tells changes to append "ch" to the name of the changes command in order to avoid a name collision.
    % Commonly, "\comment" will be changed to "\chcomment".
    commandnameprefix=ifneeded, 
    % Changes imports the "todo" package. The following options are passed to the "todo" package.
    todonotes={colorinlistoftodos,
                prependcaption,
                textsize=small,
                backgroundcolor=orange!10,
                textcolor=black,
                linecolor=orange,
                bordercolor=orange} % 
    % draft, % &lt;- enable line to show annotations regardless of the document being in 'final' mode.
    % final, % &lt;- enable line to hide annotations regardless of the document being in 'draft' mode.
]{changes}
</pre>

<p>For comments in the margin, the margin size for many document classes is too narrow, so it is necessary to adjust it. 
One way to this is with the <a href="https://www.ctan.org/pkg/geometry"><code class="language-plaintext highlighter-rouge">geometry</code></a> package.
In the following snippet, we also use the <a href="https://www.ctan.org/pkg/ifdraft"><code class="language-plaintext highlighter-rouge">ifdraft</code></a> package so that our changes to the margins only apply in draft mode.</p>

<pre class="language-latex">
% Create \ifdraft{}{} conditional 
% that switches based on whether "draft" 
% is passed to document class.
\usepackage{ifdraft} 
\ifdraft{
    % Adjust spacing to fit margin notes.
    \usepackage[inner=20mm, outer=40mm,
            marginparwidth=34mm]{geometry} 
}{}
</pre>

<p>My full LaTeX configuration file is available <a href="https://github.com/pwintz/hsl_templates/blob/main/pwintz_configuration.sty">here</a>.</p>

<h3 id="resolve-name-conflict-for-comment-command">Resolve Name Conflict For <code class="language-plaintext highlighter-rouge">\comment</code> Command</h3>
<p>There are several packages that define a <code class="language-plaintext highlighter-rouge">\comment</code> command that would clash with the one defined by <code class="language-plaintext highlighter-rouge">changes</code>. 
If the <code class="language-plaintext highlighter-rouge">prependcaption</code> is included in the options for <code class="language-plaintext highlighter-rouge">changes</code>, then <code class="language-plaintext highlighter-rouge">\comment</code> is automatically renamed to <code class="language-plaintext highlighter-rouge">\chcomment</code> and a warning is shown. 
I would prefer to use <code class="language-plaintext highlighter-rouge">\comment</code> for the <code class="language-plaintext highlighter-rouge">changes</code> command, however. 
To do this, you can redefine the existing <code class="language-plaintext highlighter-rouge">\comment</code> command. 
If <code class="language-plaintext highlighter-rouge">comment</code> is an <em>environment</em>, as is defined by the <code class="language-plaintext highlighter-rouge">verbatim</code> package, then you must redefine both <code class="language-plaintext highlighter-rouge">\comment</code> and <code class="language-plaintext highlighter-rouge">\endcomment</code>, prior to importing <code class="language-plaintext highlighter-rouge">changes</code>, as follows:</p>

<pre class="language-latex">% Redefine "comment" environment (from "verbatim" package) 
% to "commentsection" so that \comments{} can be defined 
% by the `changes` package.
\makeatletter
\let\commentsection\comment
\let\endcommentsection\endcomment
\let\comment\@undefined
\let\endcomment\@undefined
\makeatother
</pre>

<h2 id="defining-addeddeleted-environment-blocks">Defining Added/Deleted Environment Blocks</h2>

<p>The <code class="language-plaintext highlighter-rouge">changes</code> package only defines macros for added, deleted, and replaced text, but not environments. 
Although macros are fine for short text, they have downsides for long blocks of text. 
For example, you cannot put empty lines of code, e.g., to write multiple paragraphs, in the argument of <code class="language-plaintext highlighter-rouge">\added{}</code> (the result is a cryptic <code class="language-plaintext highlighter-rouge">Paragraph ended before \addcontentsline was complete.</code> error).
Furthermore, any errors that occur with the argument of <code class="language-plaintext highlighter-rouge">\added{}</code> are marked at the end of <code class="language-plaintext highlighter-rouge">\added{}</code>, making it difficult the source of errors if the text inside <code class="language-plaintext highlighter-rouge">\added{}</code> is long, possibly including several sentences or equations. 
Similarly, SyncTeX does not locate specific code with an <code class="language-plaintext highlighter-rouge">\added{}</code> macro, making it more difficult to navigate between your code and PDF.</p>

<p>To fix all of these problems, I define environment versions of <code class="language-plaintext highlighter-rouge">\added{}</code> and <code class="language-plaintext highlighter-rouge">\deleted{}</code> as follows:
<!-- We need this raw block to block Liquid from misinterpreting "{%".--></p>
<pre class="language-latex">% Define environments for blocks of deleted text. 
\usepackage{ifdraft}% Provides macros for testing if in draft or final mode. 
\usepackage{xcolor}% 
% We use \NewEnviron from environ to create environments that do not show their contents.
\RequirePackage{environ}
\definecolor{deletedColor}{rgb}{0.760, 0.000, 0.000}% Hex: #C20000FF (dark red)
\definecolor{addedColor}  {rgb}{0.169, 0.243, 0.714}% Hex: #2B3EB6FF (dark blue)
\NewEnviron{addedblock}{%
    \ifoptionfinal{%
        \BODY% Added content is inserted without modification in final version.
    }{% If not final, then show color
        {\color{addedColor}\BODY}%
    }%
}
\NewEnviron{deletedblock}{%
    \ifoptionfinal{%
        % Deleted content is omitted in final version.
    }{% If not final, then show color
        {\color{deletedColor}\BODY}%
    }%
}
</pre>

<p>An example of the usage is</p>
<pre class="language-latex">\begin{addedblock}%
    Here is some text. 

		Here is a new paragraph. 
\end{addedblock}
</pre>
<p>I have not defined a <code class="language-plaintext highlighter-rouge">replacedblock</code> environment because there is not a straightforward way to give the added and deleted text. 
To indicate deleted text, I simply combine an <code class="language-plaintext highlighter-rouge">addedblock</code> and a `deletedblock:</p>
<pre class="language-latex">\begin{addedblock}% Start of replacement text
This is new text.
\end{addedblock}% End of replacement text
\begin{deletedblock}% Start of replaced text
    This is old text.
\end{deletedblock}% End of replaced text
</pre>

<p>I wrote the several snippets to make these environments easy to use in VS Code.
See the section on “Visual Studio Configuration”, below for more info about defining snippets.</p>
<div class="language-jsonc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"Added Block Environment"</span><span class="p">:{</span><span class="w">
	</span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">addedblock"</span><span class="p">],</span><span class="w">
	</span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{addedblock}%"</span><span class="p">,</span><span class="w">
		</span><span class="c1">// Do not indent the added text because we want to </span><span class="w">
		</span><span class="c1">// eventually delete \begin{added} and \end{added} </span><span class="w">
		</span><span class="c1">// without needing to reformat the code.</span><span class="w">
		</span><span class="s2">"${0:$TM_SELECTED_TEXT}"</span><span class="p">,</span><span class="w"> 
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{addedblock}%"</span><span class="w">
	</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Deleted Block Environment"</span><span class="p">:{</span><span class="w">
	</span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">deletedblock"</span><span class="p">],</span><span class="w">
	</span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{deletedblock}%"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{deletedblock}%"</span><span class="p">,</span><span class="w"> 
		</span><span class="s2">"$0"</span><span class="w">
	</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span><span class="nl">"Replaced Block Environment"</span><span class="p">:{</span><span class="w">
	</span><span class="nl">"prefix"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"</span><span class="se">\\</span><span class="s2">replacedblock"</span><span class="p">],</span><span class="w">
	</span><span class="nl">"body"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{addedblock}% Start of replacement text"</span><span class="p">,</span><span class="w">
		</span><span class="c1">// Do not indent the added text because we want to </span><span class="w">
		</span><span class="c1">// eventually delete \begin{added} and \end{added} </span><span class="w">
		</span><span class="c1">// without needing to reformat the code.</span><span class="w">
		</span><span class="s2">"${0:$TM_SELECTED_TEXT}"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{addedblock}% End of replacement text"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">begin{deletedblock}% Start of replaced text"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\t</span><span class="s2">$TM_SELECTED_TEXT"</span><span class="p">,</span><span class="w">
		</span><span class="s2">"</span><span class="se">\\</span><span class="s2">end{deletedblock}% End of replaced text"</span><span class="w">
	</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="err">,</span><span class="w">
</span></code></pre></div></div>

<h2 id="visual-studio-configuration">Visual Studio Configuration</h2>

<p>When writing <a href="https://github.com/James-Yu/LaTeX-Workshop">LaTeX with Visual Studio Code</a>, you can define <a href="https://code.visualstudio.com/docs/editor/userdefinedsnippets">snippets</a> that are automatically inserted when you type particular text. 
To set up snippets, type <code class="language-plaintext highlighter-rouge">CTRL+SHIFT+P</code>, type <code class="language-plaintext highlighter-rouge">Preferences: Configure User Snippets</code>, and select <code class="language-plaintext highlighter-rouge">latex.json</code>. 
Add the following code to <code class="language-plaintext highlighter-rouge">latex.json</code>:</p>

<pre class="language-json">
{
	"Added":{
		"prefix": ["\\added"],
		"body": [
			"\\added{$TM_SELECTED_TEXT$1}$0"
		]
	},
	"Added Block":{
		"prefix": ["\\added%", "\\addedblock"],
		"body": [
			"\\added{%",
			"\t$TM_SELECTED_TEXT$0",
			"}% End \\added block",
			"" // Ensure there is a new line at end
		]
	},
	"Deleted":{
		"prefix": ["\\deleted"],
		"body": [
			"\\deleted{$TM_SELECTED_TEXT$1}$0"
		]
	},
	"Deleted Block":{
		"prefix": ["\\deleted%", "\\deletedblock"],
		"body": [
			"\\deleted{%",
			"\t$TM_SELECTED_TEXT$0",
			"}% End \\deleted block",
			"" // Ensure there is a new line at end
		]
	},
	"Replaced":{
		"prefix": ["\\replaced"],
		"body": [
			"\\replaced{$TM_SELECTED_TEXT$1}{$TM_SELECTED_TEXT}$0"
		]
	},
	"Replaced Block":{
		"prefix": ["\\replaced%", "\\replacedblock"],
		"body": [
			"\\replaced{% New Text",
			"\t$TM_SELECTED_TEXT$0",
			"}{% Old Text",
			"\t$TM_SELECTED_TEXT",
			"}% End \\replaced block",
			"" // Ensure there is a new line at end
		]
	}
}
</pre>

<p>For each command <code class="language-plaintext highlighter-rouge">\added</code>, <code class="language-plaintext highlighter-rouge">\deleted</code>, and <code class="language-plaintext highlighter-rouge">\replaced</code>, there are two versions of snippets an “inline” version and a “block” version.
To use the block version append <code class="language-plaintext highlighter-rouge">%</code> or <code class="language-plaintext highlighter-rouge">block</code>.
For example, to add a <code class="language-plaintext highlighter-rouge">\replaced</code> block:</p>
<ol>
  <li>Select the text you are replacing.</li>
  <li>Type <code class="language-plaintext highlighter-rouge">\replaced%</code> or <code class="language-plaintext highlighter-rouge">\replacedblock</code>. The selected text will temporarily disappear as you type.</li>
  <li>Select “Replaced Block” from the drop-down menu. At this point, the text you had selected reappears in both arguments of <code class="language-plaintext highlighter-rouge">\replaced</code>.</li>
  <li>Modify the first argument to the new version.</li>
</ol>

<p>I find the <code class="language-plaintext highlighter-rouge">\replaced</code> block snippet particularly useful because the comments <code class="language-plaintext highlighter-rouge">% New Text</code> and <code class="language-plaintext highlighter-rouge">% Old Text</code> remind me of the order of the arguments, which I always forget.</p>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="latex" /><category term="collaboration" /><category term="changes" /><summary type="html"><![CDATA[Introduction to the \changes package for annotating chnages.]]></summary></entry><entry><title type="html">What I Study, Part 1: Control Theory</title><link href="https://luis.emlin.me/research/what-is-control-theory/" rel="alternate" type="text/html" title="What I Study, Part 1: Control Theory" /><published>2023-03-04T16:00:00+00:00</published><updated>2023-03-04T16:00:00+00:00</updated><id>https://luis.emlin.me/research/what-is-control-theory</id><content type="html" xml:base="https://luis.emlin.me/research/what-is-control-theory/"><![CDATA[<p>My research as a PhD student is in the field of control theory. 
When I say this, most people don’t know what it means. 
I am often asked if that means I am learning “the psychology of how to manipulate people” (I’m not). 
This page provides a brief introduction to the topic that doesn’t require any prior knowledge about math or engineering.</p>

<p>In order to understand control theory, it’s helpful to first introduce the concept of a dynamical system.
A <em>dynamical system</em> is a system that changes over time. 
Some examples of dynamical systems are a pendulum (mechanical), a power transformer (electronic), a stock market (economic), and populations of predators and prey (ecological).
A dynamical system is described using a list of numbers that change over time. 
We call the list of numbers the <em>state</em> of the system. 
The main questions we ask about a dynamical system is how it behaves over time.</p>
<ul>
  <li>Is the state attracted to a particular point?</li>
  <li>Does state periodically return to the same point?</li>
  <li>Does the state remain in a particular region?</li>
</ul>

<p>Consider, for example, an ecosystem with a population of a predator species and the population of its prey. The state of the system has two values at each moment in time: the population of the predator and the population of the prey. If either of these values goes to zero, then that species goes extinct.</p>

<p>In some dynamical systems, there are <em>inputs</em> that affect the behavior of the system. 
An input is a value that can be directly chosen at each moment in time. 
For a car, the inputs are the throttle (gas pedal), the brake, and the steering wheel. The position and velocity of the car cannot be controlled directly—to move the car to a new location, one must use the throttle and steering wheel to maneuver there.
A dynamical system with inputs is a <em>control system</em> and the study of how to pick the inputs achieve various goals is called <em>control theory</em>. In general, our goal is to design the inputs so that the system</p>
<ul>
  <li>goes where we want it,</li>
  <li>avoids obstacles, and</li>
  <li>minimizes energy use.</li>
</ul>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="research" /><summary type="html"><![CDATA[A brief introduction to my field of research.]]></summary></entry><entry><title type="html">Book Summary: Making Numbers Count</title><link href="https://luis.emlin.me/mathematical-writing/making-numbers-count/" rel="alternate" type="text/html" title="Book Summary: Making Numbers Count" /><published>2023-02-21T07:43:51+00:00</published><updated>2023-02-21T07:43:51+00:00</updated><id>https://luis.emlin.me/mathematical-writing/making-numbers-count</id><content type="html" xml:base="https://luis.emlin.me/mathematical-writing/making-numbers-count/"><![CDATA[<p>By Chip Heath and Karla Starr.
Available at <a href="https://www.barnesandnoble.com/w/making-numbers-count-chip-heath/1139505135?ean=9781982165444&amp;st=AFF&amp;2sid=Simon%20&amp;%20Schuster_7567305_NA&amp;sourceId=AFFSimon%20&amp;%20Schuster">Barnes &amp; Noble</a> (and <a href="https://www.simonandschuster.com/books/Making-Numbers-Count/Chip-Heath/9781982165444">elsewhere</a>.)</p>

<ul>
  <li>Avoid using numbers, if possible</li>
  <li>Provide a yardstick that people are familiar with to compare quantities to (e.g., the Empire State Building, for length).</li>
  <li>Focus on one item or event at a time (e.g., state the number of points scored by a player per game instead of over entire career).</li>
  <li>Describe a representative case study instead of presenting statistics. The presented case could be fictional, in which case it is called a <em>prototype</em>.</li>
  <li>Round aggressively. Prefer simple fractions (people will remember 1/2 longer—and therefore more accurately—than 9/17).</li>
  <li>Use whole numbers if possible. It’s easy for people to understand “1 out of 3” than “33.3%”.</li>
  <li>If you can make a number “human scale”, then your audience will be able to picture it. Example: to give people a sense of the height of Mt. Everest, scale it down to a size we can understand: “If you were the height of a stack of six cards, Mt. Everest would be the height of a 2-story building.”</li>
  <li>To give exceptionally large or small values an emotional kick, give a comparison to a value that you would expect to be a totally different ballpark. For example, compare the size of California’s economy with the size of the world’s largest countries’ economies.</li>
  <li>Make numbers personal to the audience. Tell a story that includes each audience member as a (possibly hypothetical) participant. Example: if presenting the share of income that an average Kenyan spends on food, state how much that would equal scaled to the income of a typical person in the audience.</li>
  <li>Present your numbers with physical demonstrations in the room. Pick people in the room to represent population statistics (“Look to the two people next to you. It is statistically most likely that one of you will die of heart disease”).</li>
  <li>Convert numbers into periods of time. How long would it take to reach X at a rate that the audience can picture?</li>
  <li>To make exceptional numbers pack a stronger emotional punch, present them as a (surprise) encore. Begin by describing the number in a way that makes them sound significant, then add a modification that shows that the number is actually more extreme than the initial description.</li>
  <li>Set up a pattern then break it. Example: present the thickness of the thinnest laptops on the market, then show your company’s new laptop that is half as thin.</li>
</ul>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="mathematical-writing" /><summary type="html"><![CDATA[A guide to talking about numbers in a way that helps the audience remember and understand them.]]></summary></entry><entry><title type="html">Choosing Mathematical Symbols</title><link href="https://luis.emlin.me/mathematical-writing/choosing-mathematical-symbols/" rel="alternate" type="text/html" title="Choosing Mathematical Symbols" /><published>2023-01-10T07:48:51+00:00</published><updated>2023-01-10T07:48:51+00:00</updated><id>https://luis.emlin.me/mathematical-writing/choosing-mathematical-symbols</id><content type="html" xml:base="https://luis.emlin.me/mathematical-writing/choosing-mathematical-symbols/"><![CDATA[<p><em>A guide to choosing clear, memorable notation in mathematical writing.</em></p>

<p>When choosing symbols for mathematical objects (variables, sets, etc.), the best choices are</p>

<ul>
  <li>descriptive</li>
  <li>consistent with conventions</li>
  <li>easily distinguished from other notation in use</li>
</ul>

<p>Regarding the choice of symbols, Paul R. Halmos wrote [1]:</p>
<blockquote>
  <p>Good notation has a kind of alphabetical harmony and avoids dissonance. Example: either $a x+b y$ or $a_1 x_1+a_2 x_2$ is preferable to $a x_1+b x_1.$ Or: if you must use $\Sigma$ for an index set, make sure you don’t run into $\sum_{\sigma \in \Sigma} \sigma.$</p>
</blockquote>

<p>This document contains guidelines for picking good symbols and examples to shorten the process.</p>

<h2 id="choosing-a-symbol-based-on-the-starting-sound">Choosing a Symbol Based on the Starting Sound</h2>

<p>When choosing a symbol, it is helpful to choose it such that there is a connection between the symbol and its meaning. The most basic approach is to use the Latin character that starts a word related to the symbol’s meaning, such as $g$ or $G$ for gravity. After exhausting the Latin alphabet, the Greek alphabet can be used. The name of each Greek letter generally starts with the sound it makes. For instance, gamma ($\gamma$ and $\Gamma$) makes a “g” sound, so it would be a reasonable choice for a gravity symbol if $g$  and $G$  are already used elsewhere. In the following table, the second column lists possible choices of symbols to represent a object that has a name or description that starts with the sound or letter given in the first column.</p>

<table>
<tr>
  <th> First letter/sound </th><th> Symbols </th>
</tr>
<tr>
    <td>
‘a’ as in “ape” or “apple” 
  </td>
    <td>
$a, A, \alpha$ (<code>\alpha</code>), $\aleph$ (<code>\aleph</code>) 
  </td>
  </tr>
<tr>
    <td>
‘b’ 
  </td>
    <td>
$b, B$, $\beta$ (<code>\beta</code>) 
  </td>
  </tr>
<tr>
    <td>
‘d’ (’distance’) 
  </td>
    <td>
$d, D$, $\delta$ (<code>\delta</code>), $\Delta$ (<code>\Delta</code>). Avoid $d$ for quantities that might appear in derivatives (for a quantity $d$, the notation "$dd/dt$ is confusing). 
  </td>
  </tr>
<tr>
    <td>
‘e’ as in “eat” or “egg” 
  </td>
    <td>
$e, E$, $\eta$ (<code>\eta</code>) 
  </td>
  </tr>
<tr>
    <td>
‘f’, 'ph’ as in “first” 
  </td>
    <td>
$\phi$ (<code>\phi</code>), $\varphi$ (<code>\varphi</code>), $\Phi$ (<code>\Phi</code>), $f$, $F$ 
  </td>
  </tr>
<tr>
    <td>
‘g’ (‘good’) 
  </td>
    <td>
$g$, $G$, $\gamma$ (<code>\gamma</code>), $\Gamma$ (<code>\Gamma</code>) 
  </td>
  </tr>
<tr>
    <td>
‘j’ (’James’, ‘gee’) 
  </td>
    <td>
$j, J$, $g$, $G$ 
  </td>
  </tr>
<tr>
    <td>
‘k’ (’king’, ‘compact’) 
  </td>
    <td>
$k, K, c, C$, $\chi$ (<code>\chi</code>. Makes a hard "k" sound in Greek) 
  </td>
  </tr>
<tr>
    <td>
‘l’ (’lemma’, “Lie”) 
  </td>
    <td>
$l, L$, $\ell$ (<code>\ell</code>), $\lambda$ (<code>\lambda</code>), $\Lambda$ (<code>\Lambda</code>). The symbol $\ell$ (<code>\ell</code>) is generally preferable to $l$ (<code>l</code>), as it’s less likely to mistaken for a $1$ (<code>1</code>) and vice versa. 
  </td>
  </tr>
<tr>
    <td>
‘m’ 
  </td>
    <td>
$m$, $M$, $\mu$ (<code>\mu</code>) 
  </td>
  </tr>
<tr>
    <td>
‘n’ 
  </td>
    <td>
$n$, $N$, $\nu$ (<code>\nu</code>) 
  </td>
  </tr>
<tr>
    <td>
‘o’ 
  </td>
    <td>
$o$, $O$, $\omega$ (<code>\omega</code>), $\Omega$ (<code>\Omega</code>) 
  </td>
  </tr>
<tr>
    <td>
‘p’ 
  </td>
    <td>
$p, P$, $\pi$ (<code>\pi</code>), $\Pi$ (<code>\Pi</code>) 
  </td>
  </tr>
<tr>
    <td>
‘r’ (’radius’) 
  </td>
    <td>
$r, R$, $\rho$  (<code>\rho</code>), $\varrho$ (<code>\varrho</code>) 
  </td>
  </tr>
<tr>
    <td>
‘s’ (’see’, ‘psychic’, ‘cease’) 
  </td>
    <td>
$s, S$, $\psi$ (<code>\psi</code>), $\Psi$ (<code>\Psi</code>), $\sigma$ (<code>\sigma</code>), $\varsigma$ (<code>\varsigma</code>), $\Sigma$ (<code>\Sigma</code>), $c$, $C$, $\xi$ (<code>\xi</code>), $\Xi$ (<code>\Xi</code>) 
  </td>
  </tr>
<tr>
    <td>
‘t’ (’tensor’, ‘time’) 
  </td>
    <td>
$t, \tau$ (<code>\tau</code>), $T$ 
  </td>
  </tr>
<tr>
    <td>
‘th’ 
  </td>
    <td>
$\theta$ (<code>\theta</code>), $\Theta$ (<code>\Theta</code>), $t, T$, $\mathrm{Th}, \mathrm{th}$, $\vartheta$ (<code>\vartheta</code>) 
  </td>
  </tr>
<tr>
    <td>
‘u’ (’you’, ‘young’) 
  </td>
    <td>
$u, U$, $y$, $Y$. Lowercase upsilon "$\upsilon$" should be avoided due to the similarity to lowercase vee "$v$".
  </td>
  </tr>
<tr>
    <td>
‘v’ 
  </td>
    <td>
$v, V$ 
  </td>
  </tr>
<tr>
    <td>
‘w’ 
  </td>
    <td>
$w, W$ 
  </td>
  </tr>
<tr>
    <td>z 
  </td>
    <td>$z, Z, \zeta$ (<code>\zeta</code>)
  </td>
  </tr>
</table>

<h2 id="modifying-a-symbol-to-create-a-new-related-symbol">Modifying a Symbol to Create a New, Related Symbol</h2>

<p>Suppose we are using the symbol $x$ and want to introduce a second symbol that is strongly related to $x.$  The following modifications can be used to create a new symbol.</p>

<table>
<tr>
    <th>Example</th>
    <th>Description</th>
  </tr>
<tr>
    <td> $x^1, x^{(2)}, x^a, x^*, x^\circ$ 
  </td>
    <td>Superscript. Numbers should be avoided when they could be confused with exponents. 
  </td>
  </tr>
<tr>
    <td>$x_1, x_a, ...$ 
  </td>
    <td>Subscripts. Having more than two layers of subscripts should be avoided to preserve readability. 
  </td>
  </tr>
<tr>
    <td>$x', x'', x'''$ 
  </td>
    <td>Prime notation. Commonly used for derivatives, so avoid when there may be confusion. Use at most three tick marks. 
  </td>
  </tr>
<tr>
    <td>$x_{I}, x_{II}, x_{III}, x_{IV}$ 
  </td>
    <td>Annotate with Roman Numerals. I’ve never seen this notation in a publication, but I use it within my scratch work to keep track of different iterations while I develop my work. If, say, I’m trying to find a set that satisfies some properties, I might notation them $A_I, A_{II}, ...$, until I find one that works. Then, I would simply call the final choice $A$. 
  </td>
  </tr>
<tr>
    <td>$x \mapsto \hat{x}, \tilde{x}, \overline{x}, \underline{x}$ 
  </td>
    <td>Add annotations above or below. 
  </td>
  </tr>
<tr>
    <td>$x \mapsto X$<br />
 $F \mapsto f$ 
  </td>
    <td>Change capitalization 
  </td>
  </tr>
<tr>
    <td>$x \mapsto \mathrm{x}, \mathbf{x}$<br />
 $X \mapsto \mathcal{X}, \mathbb{X}, \mathbf{X}, \mathscr{X} , \mathfrak{X}$  
  </td>
    <td>Change the font. This should be used with caution because the difference between certain fonts will not be obvious to all readers, especially in handwritten text. See note below. 
  </td>
  </tr>
<tr>
    <td>$x_{\textrm{label}}$, $x^{\textrm{label}}$ 
  </td>
    <td>Include text labels. This is a heavy-handed approach that is tedious to write, but it does not require remembering another piece of notation so it might be desirable in presentations where the audience cannot go back to review the notation. Avoid for symbols that occur often. 
  </td>
  </tr>
<tr>
    <td>$a \mapsto b, \text{or } x\mapsto y$ 
  </td>
    <td>Use letters that are adjacent in the alphabet. 
  </td>
  </tr>
<tr>
    <td>$x \mapsto p_x, A_x$ 
  </td>
    <td>Juxtaposition with another symbol. Use $x$ as a label for another symbol 
  </td>
  </tr>
<tr>
    <td>$V \mapsto \Lambda$ 
  </td>
    <td>Change the [orientation of the symbol](https://tex.stackexchange.com/questions/18157/rotating-a-letter). (This doesn’t work for symmetric symbols, such as $x$). 
  </td>
  </tr>
<tr>
    <td>$x \mapsto \Delta x, dx, \delta x$ 
  </td>
    <td>Prefix with another symbol (typically, $\Delta x$ represents a change in $x$; $\delta x$ represents a small but finite change in $x$, and $dx$ is used to represent the change in $x $ in the limit as the change goes to zero.) 
  </td>
  </tr>
<tr>
    <td>$x \mapsto [x]$, $\{x\}$, $\|x\|$ 
  </td>
    <td>Brackets. Use with caution as most brackets have existing meanings. 
  </td>
  </tr>
<tr>
    <td>$x \mapsto f(x)$ 
  </td>
    <td>Function notation.  
  </td>
  </tr>
<tr>
    <td>$1 + x^2$ 
  </td>
    <td>Sometimes, a new symbol is not actually necessary. For instance, if the new symbol depends on $x,$ you can simply write it as a function of $x$. 
  </td>
  </tr>
</table>

<h3 id="using-different-fonts">Using Different Fonts</h3>

<p>In addition to the default capital Latin characters ($A$, $B$, $C$), etc., LaTeX provides script (<code class="language-plaintext highlighter-rouge">\mathscr</code>) characters $\mathscr{A}$, $\mathscr{B}$, $\mathscr{C}$; calligraphy (<code class="language-plaintext highlighter-rouge">\mathcal</code>) characters ($\mathcal{A}$, $\mathcal{B}$, $\mathcal{C}$); and Fraktur (<code class="language-plaintext highlighter-rouge">\mathfrak</code>) characters $\mathfrak{A}$, $\mathfrak{B}$, $\mathfrak{C}$. Many letters are different enough in each style that readers can be expected to recognize them as distinct symbols. For example, one can safely use $L, \mathcal{L}$, and $\mathfrak{L}$ in the same document without much risk of confusion (although, if you are writing these characters by hand, that is a different story!).
However, many of the Fraktur characters are easily confused with each other so care should be used to avoid mixing, say $\mathfrak{I}$ and $\mathfrak{J}$ in the same document.</p>

<p><img src="/assets/images/fraktur_alphabet.png" alt="Fraktur Characters" /></p>

<h3 id="placing-modifiers-over-i-and-j">Placing Modifiers Over $i$ and $j$</h3>

<p>When placing modifiers over $i$ and $j$, such as $\hat{i}$ or $\bar{j}$, the dots in the letters creates a crowded appearance with the modifier. 
To fix this, replace <code class="language-plaintext highlighter-rouge">i</code> and <code class="language-plaintext highlighter-rouge">j</code> with <code class="language-plaintext highlighter-rouge">\imath</code> and <code class="language-plaintext highlighter-rouge">\jmath</code>, which renders the respective letters without dots, e.g., $\imath$ and $\jmath$. 
The resulting combination with hats and bars is more pleasing: $\hat{\imath}$ (<code class="language-plaintext highlighter-rouge">\hat{\imath}</code>) and $\bar{\jmath}$ (<code class="language-plaintext highlighter-rouge">\bar{\jmath}</code>).</p>

<p>In this context, I prefer <code class="language-plaintext highlighter-rouge">\bar{\jmath}</code>, which is rendered as $\bar{\jmath}$, instead of <code class="language-plaintext highlighter-rouge">\overline{\jmath}</code>, which is rendered as $\overline{\jmath}$, because the line is better aligned with the top of the character.</p>

<h2 id="choosing-symbols-based-on-type-of-mathematical-object">Choosing Symbols Based on Type of Mathematical Object</h2>

<p>There are conventions for notating certain types of mathematical objects. The following rules are not universally accepted, but are merely taken from my personal observations.</p>

<table>
<tr>
  <th>Type of Object</th>
  <th>Common Notation Classes</th>
</tr>
<tr>
  <td>Set</td>
  <td>
  Capital Latin or Greek ($A, B, C, \Lambda$);<br />
  Calligraphy ($\mathcal{A, B, C}$);<br />
  Blackboard bold ($\mathbb{R, N, Z}$)—typically reserved for well-known sets;<br />
  Script ($\mathscr{A, B, C}$)—commonly used for sets of sets;<br />
  Set-builder notation: $\{a, b, c\}$
  </td>
</tr>
<tr>
  <td>Function</td>
  <td>
    Lowercase Latin: $d, f, g, h, u, v, w, x, y, z$<br />
    Lowercase Greek: $\alpha, \beta, \gamma$<br />
    Capital Latin: $F, G, H$<br />
    Capital Greek: $\Gamma, \Theta, \Phi, \Psi, \Omega, \Xi$<br />
    Often the choice of symbol for a function matches the convention used for objects in the function’s codomain (range).
  </td>
</tr>
<tr>
  <td>Vector</td>
  <td>$x$ (<code>x</code>), $\boldsymbol{x}$ (<code>\boldsymbol{x}</code>), $\mathbf{x}$ (<code>\mathbf{x}</code>), $\vec{x}$ (<code>\vec{x}</code>), $\underline{x}$ (<code>\underline{x}</code>). In texts where students are newly acquainted to vectors, $\mathbf{x}$ or $\vec x$ is commonly used. The notation $\vec x$ has the advantage that it can easily be written by hand, but it makes equations more cluttered, especially when other annotations are added, such as $\dot{\vec{\widetilde{x}}}$. In advanced texts, $x$ is almost always used.
  </td>
</tr>
<tr>
  <td>Scalar</td>
  <td>$a, b, c, x, y, z, \alpha, \beta, \gamma$. See notes on real numbers and integers, below.
  </td>
</tr>
<tr>
  <td>Unitary Operation</td>
  <td>
    Prefix: $x\mapsto -x$, $f \mapsto \partial f$<br />
    Annotations: $f\mapsto \hat f, f\mapsto \tilde f, x\mapsto x^*$<br />
    Function notation: $x\mapsto f(x), f\mapsto \mathcal{L}\{f\}, x\mapsto \sin x$<br />
    Capitalization: $f \mapsto F$<br />
    Sub/superscripts: $x \mapsto x_{\text{new}}$ 
  </td>
</tr>
<tr>
  <td>Binary Operation</td>
  <td>infix: $a+b$, $A\cup B$, $p \wedge q;$<br />
 function: $f(x, y);$<br />

 juxtaposition: $xy, \overset{x}{y}, \underset{x}{y}, x^y;$<br />
 brackets: $(x, y), \langle x, y\rangle.$
  </td>
</tr>
<tr>
  <td>n-ary Operation</td>
  <td>
    Prefix: $\Pi_{i=1}^n x_i$<br />
    (Abbreviated) infix: $x_1 + x_2 + \cdots + x_n$<br />
    Function: $f(x_1, x_2, \dots, x_n)$<br />
    Einstein Summation Convention: $v^i\frac{\partial}{\partial x_i}$
  </td>
</tr>
<tr>
  <td>Matrix</td>
  <td>
    Capital Latin or Greek: $A, B, C, \Gamma;$<br />
    Upright Capital Latin: $\mathrm{A, B, C, M}$;<br />
    Bold Capital Latin: $\mathbf{A, B, C, M};$<br />
    Element-wise notation: $[a_{ij}]$, $[\sin(i\pi)\cos(j\pi)].$ 
  </td>
</tr>
<tr>
  <td>Sequence</td>
  <td>
    Abbreviated: $1, 1/2, 1/3, \dots;$<br />
    Sequence notation: $\{s_j\}_{j=1}^\infty;$<br />
    Juxtaposition (as a squence of heads/tails is represented in probability): $\text{HHTHT};$<br />
    Recursive: $x_{k+1} = r(1-x_k),$<br />
    Function: $i \mapsto 1/i.$ 
  </td>
</tr>
</table>

<h3 id="real-numbers">Real Numbers</h3>

<p>Typically, lowercase Latin or Greek letters are used to represent real numbers. Less commonly, uppercase letters are used as well.</p>

<p>Several symbols, namely $\pi$ and $e$, have well-established meanings, so they should be avoided when there is any risk of ambiguity. The letters $\varepsilon$ and $\delta$ are frequently used to represent small positive numbers and capital letters such as $M$ or $R$ are sometimes used for large values.</p>

<p>For Latin letters, note that $e$ has a well-established usage as Euler’s constant. Be judicious in the use of $f, g, h$, which are commonly used for functions.</p>

<p>Avoid $i, j, k, m, n$ because they are commonly used for integers and avoid $l, o$ due to potential confusion with $1$ and $0$—the symbol $\ell$ can be used instead of $l$.</p>

<h3 id="integers-and-natural-numbers">Integers (and Natural Numbers)</h3>

<p>Typically, lowercase and (less frequently) uppercase Latin letters are used to represent integers. The letters $i, j, k, m, n$  are common choices, especially for indices. Choosing one of them offers a hint to the reader that the variable is an integer when they encounter it after its introduction. In some contexts, $i$ or $j$ is reserved for the imaginary unit $\sqrt{-1}$. The letters $a, b, c, d, p, q$ are also commonly used for integers but are also used as real numbers. Avoid $l, o$ (due to potential confusion with $1$  and $0$—$\ell$ can be used instead of $l$). A capital letter is useful to convey that an integer will be “large”, e.g., defining a sequence $x_i$ in $\mathbb{R}$ to be unbounded if “for every $M &gt; 0$, there exists $i \in \mathbb{N}$ such that $x_i &gt; M$.”</p>

<h2 id="variables-vs-constants">Variables vs. Constants</h2>

<p>When it comes to variables and constants, I prefer to use the beginning of the alphabet for constants and the end for variables. 
In particular, I tend to use $a,$ $b,$ $c,$ $d,$ $p,$ $q,$ $r$ for constants and $t,$ $u,$ $v,$ $w,$ $x,$ $y,$ $z$ are for variables.</p>

<h2 id="example-picking-notation-for-upper-and-lower-bounds">Example: Picking Notation for Upper and Lower Bounds</h2>
<p>In this section we present a case study of picking symbols for the upper and lower bounds on a real number $x$.
At first, we can simply take the first two letter of the alphabet.</p>

\[a \leq x \leq b\]

<p>Using $a$ and $b$ is fine, but the connection of $a$ and $b$ with $x$ is not implied symbolically. We also have to pick two new symbols if we need to set bounds on another value, say $y$.
To show the connection between $x$ and the bounds, we might instead pick</p>

\[x_{lb} \leq x \leq x_{ub}.\]

<p>The use of italicized text for $lb$ and $ub$ is bad form, however. A better choice is</p>

\[x_{\mathrm{lb}} \leq x \leq x_{\mathrm{ub}}.\]

<p>This choice is pretty good, but writing letter subscripts can get tedious and makes equations somewhat messy. y
For this reason, I prefer to simply underline $x$ for the lower bound and overline $x$ for the upper bound.</p>

\[\underline{x} \leq x \leq \overline{x}.\]

<p>This notation is (1) simple, (2) visually descriptive, and (3) does not require choosing new symbols for every upper and lower bound that is introduced. There are cases where $\overline{x}$ can cause confusing, however. Namely, if $x$ is a complex number, then $\overline{x}$ could be read as the complex conjugate.</p>

<h1 id="finding-symbols-based-on-appearance">Finding Symbols Based on Appearance</h1>
<p>There are far too many symbols to possibly know all of them. 
In cases when you know how symbol looks and wish to recover the LaTeX code, you can use <a href="https://detexify.kirelabs.org/classify.html">Detexify</a> and the <a href="https://mathpix.com/">Mathpix Snipping Tool</a>.
To browse through available symbols, the <a href="https://www.ctan.org/tex-archive/info/symbols/comprehensive/">Comprehensive Latex Symbol List</a> provides a massive list of symbols.</p>

<h1 id="references">References</h1>
<p>[1] Norman E. Steenrod, Paul R. Halmos, Menahem M. Schiffer, and Jean A. Dieudonné, <em>How to Write Mathematics</em>. 1973.
[2] N. J. Higham, Handbook of writing for the mathematical sciences, 2nd ed. Philadelphia: Society for Industrial and Applied Mathematics, 1998.</p>]]></content><author><name>Luis E. Linares</name><email>info+ws@emlin.me</email></author><category term="mathematical-writing" /><category term="notation" /><summary type="html"><![CDATA[A guide to choosing clear, memorable notation in mathematical writing.]]></summary></entry></feed>