uncenter.dev
Articles about programming, software development, and other interests of mine.
2026-03-02T00:00:00Z
https://uncenter.dev
uncenter
My new Learn Eleventy course
2026-03-02T00:00:00Z
https://uncenter.dev/posts/learn-eleventy-update/
<p>If you're familiar with the <a href="https://www.11ty.dev/" rel="noreferrer">Eleventy</a> community, you've likely come across <a href="https://bell.bz/" rel="noreferrer">Andy Bell</a>'s excellent free course, <a href="https://learneleventyfromscratch.com/" rel="noreferrer">Learn Eleventy from Scratch</a>. Learn Eleventy from Scratch has been an invaluable resource to the community since it was published. Unforunately, time inevitably moves on. Originally written in 2021 — before the release of Eleventy v1.0.0! — parts of the course have gradually become outdated as Eleventy evolved.</p><p>As an avid user of Eleventy — you might have seen me in GitHub issues, on the Discord support channels, or used one of my plugins — I decided to create a fork of the course, titled "Learn Eleventy", in April of 2023. Initially, with my limited time for it, the fork focused on modernizing the foundation: it was rebuilt with a newer Eleventy-based site (huge thanks to <a href="https://sandroroth.com/" rel="noreferrer">Sandro Roth</a> for the <a href="https://eleventy-notes.sandroroth.com/" rel="noreferrer">Eleventy Notes framework</a>!) and accumulated various fixes and updates.</p><p>In late 2024, I noticed a sizeable jump — over a six-fold increase — in visitors to the course! As it turns out, a random contributor had suggested a change that Andy had merged, adding a link to my fork in a note at the top of the course. With so many new learners, I felt a new responsibility to work on the course and keep it up to date — especially since Eleventy itself had been evolving, reaching v3.0.0 in the time since the fork began. Although it took until June for me to find enough time to devote to the course, I began to work in the background on more substantial content updates.</p><p>I had hoped to complete the content overhaul before the new year, and I got pretty close! On January <em>2nd</em> of this year, I finally <a href="https://github.com/uncenter/learn-eleventy/pull/19" rel="noreferrer">merged the dev branch</a> and removed the original Gulp-based asset pipeline, teaching instead Eleventy's native asset pipeline techniques (the official Eleventy Image plugin, Sass via Custom Template Languages, and more), as well as migrating all of the code samples to modern ESM syntax.</p><p>Several other updates arrived at the same time or since. The course has switched to the latest version — v2 — of the official Eleventy RSS plugin, and Moment has been replaced with Luxon for date formatting. I'm also excited to introduce a personal favorite, downloadable lesson files! A <a href="https://github.com/uncenter/learn-eleventy-completed" rel="noreferrer">separate repository</a> tracks all content changes in the course repository and compiles per-lesson ZIP archives of what the course expects you to have built by that point.</p><p>And one final update: this weekend, after <a href="https://bsky.app/profile/did:plc:rkm6m4dsc4da2yzdlvxorhf3/post/3luxg4ilp2c2k" rel="noreferrer">much</a> <a href="https://bsky.app/profile/did:plc:rkm6m4dsc4da2yzdlvxorhf3/post/3mbijlczalc22" rel="noreferrer">deliberation</a>, I officially purchased and launched a new domain for the course — welcome to <a href="https://learneleventy.dev" rel="noreferrer">learneleventy.dev</a>!<br>The course's "Issue 33" completed project site also now has it's own home, separate from the original course demo, at <a href="https://issue33.learneleventy.dev/" rel="noreferrer">issue33.learneleventy.dev</a>.</p><div class="container note"><p>The domain for the course previously — <a href="https://learn-eleventy.pages.dev" rel="noreferrer">learn-eleventy.pages.dev</a> — is still active and up to date, though this might change to redirect to the new domain soon.</p></div><p>If you are an Eleventy user, or want to learn to become one, I hope this course can be a valuable resource for you! ❤️</p>
Learning the oldest programming language
2024-01-31T00:00:00Z
https://uncenter.dev/posts/learning-fortran/
<p>While I probably should be learning a language like C, Go, or whatever new trendy language the <a href="https://twitter.com/ThePrimeagen" rel="noreferrer">ThePrimeagen</a> mentions on Twitter (OCaml?), I'm going to attempt to learn Fortran<sup class="footnote-ref"><a href="https://uncenter.dev/posts/learning-fortran/#fn1" id="fnref1" rel="noreferrer">[1]</a></sup>.</p><h2 id="a-quick-history" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/learning-fortran/#a-quick-history" rel="noreferrer"><span>A quick history</span></a></h2><p>Fortran, which stands for FORmula TRANslator<sup class="footnote-ref"><a href="https://uncenter.dev/posts/learning-fortran/#fn2" id="fnref2" rel="noreferrer">[2]</a></sup>, was created at IBM by <a href="https://en.wikipedia.org/wiki/John_Backus" rel="noreferrer">John Backus</a> in 1957 for scientific applications and has apparently been popular for high-performance computing and benchmarking supercomputers in recent years. Fortran has had several subsequent releases since then; FORTRAN 77, Fortran 90, Fortran 95, Fortran 2003, Fortran 2008, and the latest Fortran 2018.</p><h2 id="which-version-of-fortran%3F" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/learning-fortran/#which-version-of-fortran%3F" rel="noreferrer"><span>Which version of Fortran?</span></a></h2><p>To understand what version of Fortran to learn/use, we first must understand the difference between <em>fixed form</em> and <em>free form</em> Fortran. The <a href="https://fortranwiki.org/fortran/show/Fixed+form+layout" rel="noreferrer">fixed form layout</a> comes from the very beginning of Fortran, inherited from punch cards, and has odd restrictions about the column in which comments and statements are placed. The free form layout, first introduced in Fortran 90, removed special columns and added the ability to write comments wherever, and is what we'll be learning in this article. The compiler we'll be using is GNU Fortran, or <code>gfortran</code>. You can install it via Homebrew (macOS) with the <a href="https://formulae.brew.sh/formula/gcc#default" rel="noreferrer"><code>gcc</code></a> formula, or <a href="https://gcc.gnu.org/wiki/GFortranDistros" rel="noreferrer">install it using a package manager for your OS</a>. To tell <code>gfortran</code> that your code uses the free form layout, set the file extension to <code>.f90</code> or newer. The following <a href="https://fortran-lang.discourse.group/t/is-there-a-standard-file-suffix-for-modern-fortran-code/3550/2" rel="noreferrer">comment on the Fortran discussion board</a> explains this well.</p><blockquote><p>The .f90 suffix means that the source code is free format, not that<br>the code conforms to the Fortran 90 standard. Code that uses the .f90<br>suffix can use features from any Fortran standard. All Fortran<br>compilers recognize .f90 as a suffix indicating free source form, but<br>some may not recognize a suffix such as .f95, .f03, .f08, or .f18.<br>Some users may have build tools that do not recognize suffixes other<br>than .f90. Most Fortran source code on GitHub that uses features from<br>a standard more recent than Fortran 90 still uses the .f90 suffix.</p></blockquote><h2 id="understanding-the-syntax" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/learning-fortran/#understanding-the-syntax" rel="noreferrer"><span>Understanding the syntax</span></a></h2><p>Coming from TypeScript, and before that, Python, I'm very used to (and comfortable with) modern — you might say "aesthetic" — syntax . Although I wouldn't say Fortran syntax is quite <em>modern</em>, it seems to avoid the syntactic sugar nightmares that plague beginners in other languages<sup class="footnote-ref"><a href="https://uncenter.dev/posts/learning-fortran/#fn3" id="fnref3" rel="noreferrer">[3]</a></sup>. Take a look at this <code>helloworld.f90</code> example below.</p><div class="code-block" id="99a4ec86"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">program</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> helloworld</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Hello, world!'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end program</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> helloworld</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><script>window.addEventListener("DOMContentLoaded", () => {
const screamingCaseToggle = document.querySelector('#toggle-screaming-case');
let screamingCaseEnabled = JSON.parse(localStorage.getItem("screaming-case-mode-enabled")) || false;
function updateScreamingCaseStatus() {
localStorage.setItem("screaming-case-mode-enabled", screamingCaseEnabled)
screamingCaseToggle.textContent = screamingCaseEnabled ? 'Disable SCREAMING_CASE mode' : 'Enable SCREAMING_CASE mode';
for (const token of document.querySelectorAll('.code-block span.line span')) {
if (token.getAttribute('style') === '--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7') {
token.textContent = screamingCaseEnabled ? token.textContent.toUpperCase() : token.textContent.toLowerCase();
}
}
}
updateScreamingCaseStatus();
screamingCaseToggle.addEventListener('click', () => {
screamingCaseEnabled = !screamingCaseEnabled;
updateScreamingCaseStatus();
});
});</script><div class="container note"><p>Older Fortran programs required the use of <a href="https://en.wiktionary.org/wiki/screaming_snake_case" rel="noreferrer">SCREAMING_CASE</a> for all keywords, but in modern Fortran you can and <a href="https://fortran-lang.org/learn/best_practices/style_guide/" rel="noreferrer">it is recommended</a> to use <a href="https://en.wiktionary.org/wiki/snake_case#English" rel="noreferrer">snake_case</a> (you can still use SCREAMING_CASE or any other case you want though).</p><p><button id="toggle-screaming-case">Enable SCREAMING_CASE mode</button></p></div><p>Just from this small example we can gather that...</p><ul><li>Every Fortran program begins with <code>program <program-name></code> and ends with <code>end program <program-name></code>.</li><li>To display text on the terminal we use <code>print *, '<message>'</code>.</li></ul><p>The syntax for printing is a little funky though. What is that asterisk doing there? The asterisk, aside from being used as a mathematical operator, indicates the "default". So for <code>print</code>, <code>*</code> means "print to the default output channel" (or "print to the default output file unit" to be precise), which is typically going to be STDOUT.</p><div class="container note"><p>I can't find exactly where this is documented but you don't actually need the start and end <code>program <program-name></code>; you could write a hello world program like this, though as I just mentioned this doesn't seem to be a common practice and isn't really very useful in any practical scenario.</p><div class="code-block" id="61dddff9"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Hello, world!'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">; end</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div></div><p>Here's another, slightly more complicated example.</p><div class="code-block" id="b6625820"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">program</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> calculator</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> implicit</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> none</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> real</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> ::</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x, y, answer</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> character</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">(</span><span style="--shiki-latte:#FE640B;--shiki-frappe:#EF9F76;--shiki-macchiato:#F5A97F;--shiki-mocha:#FAB387">1</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> ::</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> choice</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'x:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, x</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'y:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'+, -, *, /:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, choice</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '+'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">+</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '-'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">-</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '*'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '/'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x / y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Answer:'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, answer</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end program</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> calculator</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Starting right at the top, we have something new: <code>implicit none</code>. Added in Fortran 90, <code>implicit none</code> disables implicit typing defaults and all variables must be explicitly declared. In Fortran, implicit typing is the practice of assigning default types to variables based on the character a variable name begins with. Variables starting with <code>I</code> through <code>N</code> are <code>INTEGER</code>s, everything else is <code>REAL</code>. It is "a legacy of the past" and usage of an <code>implicit none</code> statement is "strongly advised" (<a href="https://fortranwiki.org/fortran/show/implicit+none" rel="noreferrer">implicit none - Fortran Wiki</a>).</p><div class="container note"><p>A common Fortran joke goes along the lines of “GOD is REAL, unless declared INTEGER"<sup class="footnote-ref"><a href="https://uncenter.dev/posts/learning-fortran/#fn4" id="fnref4" rel="noreferrer">[4]</a></sup> because of implicit typing!</p></div><p>Moving on, we declare our first variables in this program.</p><div class="code-block" id="8fb1f820"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">real</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> ::</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x, y, answer</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">character</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">(</span><span style="--shiki-latte:#FE640B;--shiki-frappe:#EF9F76;--shiki-macchiato:#F5A97F;--shiki-mocha:#FAB387">1</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> ::</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> choice</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Here we are declaring <code>x</code>, <code>y</code>, and <code>answer</code> with the <code>REAL</code> type, and <code>choice</code> with the <code>CHARACTER</code> type. The <code>REAL</code> type stores floating point numbers<sup class="footnote-ref"><a href="https://uncenter.dev/posts/learning-fortran/#fn5" id="fnref5" rel="noreferrer">[5]</a></sup>, and <code>CHARACTER</code>... stores characters.</p><p>Next, we prompt the user for our <code>x</code> and <code>y</code> values.</p><div class="code-block" id="80835a27"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'x:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, x</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'y:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, y</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Notice how we can take input from the user with <code>read</code> and assign it to a value with the <code>read *, <variable></code> syntax. The asterisk here means <em>read</em> from the default input channel/file unit, which would be STDIN.</p><p>We do the same for prompting the user to select an operation.</p><div class="code-block" id="78a4f9a5"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'+, -, *, /:'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">read</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, choice</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Finally, we use a series of basic if-statements to calculate our answer and display it in the terminal.</p><div class="code-block" id="16d64b01"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '+'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">+</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '-'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">-</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '*'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '/'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x / y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Answer:'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, answer</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>If we run this, we- wait. Did I even tell you how to compile a Fortran program yet?</p><h2 id="how-do-i-actually-run-this%3F" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/learning-fortran/#how-do-i-actually-run-this%3F" rel="noreferrer"><span>How do I actually run this?</span></a></h2><p>First, compile our calculator program with <code>gfortran -o calculator calculator.f90</code> . Then you can run it with <code>./calculator</code>. If you only instruct <code>gfortran</code> of the input file (<code>gfortran calculator.f90</code>), the default output executable will be named <code>a.out</code>.</p><p>Let's run our program now.</p><div class="code-block" id="08f86b99"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-text"><span class="line"><span>$ gfortran -o calculator calculator.f90</span></span>
<span class="line"><span>$ ./calculator</span></span>
<span class="line"><span> x:</span></span>
<span class="line"><span>10</span></span>
<span class="line"><span> y:</span></span>
<span class="line"><span>2</span></span>
<span class="line"><span> +, -, *, /:</span></span>
<span class="line"><span>*</span></span>
<span class="line"><span> Answer: 20.0000000</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Pretty cool, huh?</p><h2 id="a-few-improvements" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/learning-fortran/#a-few-improvements" rel="noreferrer"><span>A few improvements</span></a></h2><p>Our calculator isn't perfect yet though. What if the user tries to divide by zero?</p><div class="code-block" id="fcd7a75b"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-text"><span class="line"><span> x:</span></span>
<span class="line"><span>10</span></span>
<span class="line"><span> y:</span></span>
<span class="line"><span>0</span></span>
<span class="line"><span> +, -, *, /:</span></span>
<span class="line"><span>/</span></span>
<span class="line"><span> Answer: Infinity</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Probably not the answer you expected. Let's try to fix that.</p><div class="code-block" id="3d4d8d1e"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">==</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '/'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">y </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">/=</span><span style="--shiki-latte:#FE640B;--shiki-frappe:#EF9F76;--shiki-macchiato:#F5A97F;--shiki-mocha:#FAB387"> 0.0</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x / y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> else</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Error: Division by zero is not allowed.'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> stop</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end if</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Here we use the inequality operator, <code>/=</code>, to check if the <code>y</code> value is zero. Now, if the user tries to divide by zero, we'll print an error message and use the <code>stop</code> statement to end the program.</p><p>Great. We got rid of the zero division mess, but our code isn't pretty at all. Who wants a bunch of if statements? We can simplify this using the <code>select case</code> statement (also known as the <code>case</code> statement).</p><div class="code-block" id="ed7d0003"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-f90"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">select case</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">choice</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> case</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'+'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">+</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> case</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'-'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">-</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> case</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'*'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> case</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'/'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> (</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">y </span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">/=</span><span style="--shiki-latte:#FE640B;--shiki-frappe:#EF9F76;--shiki-macchiato:#F5A97F;--shiki-mocha:#FAB387"> 0.0</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> then</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> answer </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> x / y</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> else</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Error: Division by zero is not allowed.'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> stop</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> end if</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> case</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> default</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> print</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> *</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">, </span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Invalid choice. Please choose +, -, *, or /.'</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> stop</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">end select</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>This also has the handy benefit of telling the user if they made an invalid choice while selecting the operation.</p><p>That’s just a quick introduction to a few modern Fortran features: declaring variables, printing and reading to and from the terminal, <code>if</code> and <code>select case</code>, and <code>stop</code>. Next time, we’ll talk more about where Fortran is actually used, cooler things <em>you</em> can build with it, and how the Fortran language & community are rapidly modernizing!</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Ironically, in the ~3-ish months since I started writing this article, ThePrimagen has recently said he <a href="https://x.com/ThePrimeagen/status/1745542049284423973" rel="noreferrer">"take[s] back everything i said about FORTRAN"</a> — apparently having some interest in the language! <a href="https://uncenter.dev/posts/learning-fortran/#fnref1" class="footnote-backref" rel="noreferrer">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>According to sources listed on <a href="https://en.wikipedia.org/wiki/Fortran" rel="noreferrer">Fortran's Wikipedia</a>, the name might also have stood for <em>Formula Translating System</em> or just <em>Formula Translation</em>. <a href="https://uncenter.dev/posts/learning-fortran/#fnref2" class="footnote-backref" rel="noreferrer">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>See <a href="https://www.reddit.com/r/rust/comments/12b7p2p/the_rust_programming_language_absolutely/" rel="noreferrer">The Rust programming language absolutely positively sucks : r/rust</a> and <a href="https://users.rust-lang.org/t/rust-is-a-nightmare-to-learn-coming-from-java/37650" rel="noreferrer">Rust is a nightmare to learn coming from Java - community - The Rust Programming Language Forum</a>. <a href="https://uncenter.dev/posts/learning-fortran/#fnref3" class="footnote-backref" rel="noreferrer">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>The first letter of "GOD", a "G", is not within I through N and is therefore of the <code>REAL</code> type ("GOD is REAL"). <a href="https://uncenter.dev/posts/learning-fortran/#fnref4" class="footnote-backref" rel="noreferrer">↩︎</a></p></li><li id="fn5" class="footnote-item"><p>You can also use <code>double precision</code> for larger (more precise) floating point numbers. <a href="https://uncenter.dev/posts/learning-fortran/#fnref5" class="footnote-backref" rel="noreferrer">↩︎</a></p></li></ol></section>
The package that broke npm (accidentally)
2024-01-03T00:00:00Z
https://uncenter.dev/posts/npm-install-everything/
<div class="container note"><h2 data-toc-exclude="" id="an-update!" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#an-update!" rel="noreferrer"><span>An update!</span></a></h2><details><summary>You might want to read the rest of the article first...</summary><p>GitHub has now, a day after writing this, fully "disabled" (whatever that means) our <code>everything-registry</code> organization on NPM and GitHub; you can see the email they sent to me below. While I may not agree entirely with the reasoning they provided, I am very thankful that our personal accounts are still intact!</p><details><summary>Email from GitHub Trust & Safety</summary><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/-bclRKWftB-640.avif 640w, https://uncenter.dev/assets/images/-bclRKWftB-750.avif 750w, https://uncenter.dev/assets/images/-bclRKWftB-828.avif 828w, https://uncenter.dev/assets/images/-bclRKWftB-914.avif 914w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/-bclRKWftB-640.webp 640w, https://uncenter.dev/assets/images/-bclRKWftB-750.webp 750w, https://uncenter.dev/assets/images/-bclRKWftB-828.webp 828w, https://uncenter.dev/assets/images/-bclRKWftB-914.webp 914w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/-bclRKWftB-640.png?v=92f75685b3c2" alt="Email from GitHub Trust & Safety (GitHub Support), dated Jan 4, 2024, 1:01PM UTC. Part of the email reads: Your GitHub and npm everything-registry orgs were disabled following reports of activity that may have been in violation of our Open Source Terms and GitHub Acceptable Use Policies." width="914" height="898" srcset="https://uncenter.dev/assets/images/-bclRKWftB-640.png?v=92f75685b3c2 640w, https://uncenter.dev/assets/images/-bclRKWftB-750.png?v=22fc413a89e2 750w, https://uncenter.dev/assets/images/-bclRKWftB-828.png?v=c63aa19ce5af 828w, https://uncenter.dev/assets/images/-bclRKWftB-914.png?v=b9fc5ee4e3b0 914w" sizes="auto"></picture></p></details><p>All of <a href="https://www.npmjs.com/org/everything-registry" rel="noreferrer">our scoped packages</a> have been deleted, so unpublishing packages should no longer be an issue.</p><p>Another note; this story was picked up by some media outlets in the cybersecurity world! <a href="https://www.scmagazine.com/news/npm-registry-prank-leaves-developers-unable-to-unpublish-packages" rel="noreferrer">SC Media</a>, <a href="https://checkmarx.com/blog/when-everything-goes-wrong-npm-dependency-hell-campaign-2024-edition/" rel="noreferrer">Checkmarx</a>, and <a href="https://www.bleepingcomputer.com/news/security/everything-blocks-devs-from-removing-their-own-npm-packages/" rel="noreferrer">BleepingComputer</a>.</p><details><summary>The aforementioned articles</summary><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/KDQ1HU3h51-640.avif 640w, https://uncenter.dev/assets/images/KDQ1HU3h51-750.avif 750w, https://uncenter.dev/assets/images/KDQ1HU3h51-828.avif 828w, https://uncenter.dev/assets/images/KDQ1HU3h51-1080.avif 1080w, https://uncenter.dev/assets/images/KDQ1HU3h51-1200.avif 1200w, https://uncenter.dev/assets/images/KDQ1HU3h51-1920.avif 1920w, https://uncenter.dev/assets/images/KDQ1HU3h51-2048.avif 2048w, https://uncenter.dev/assets/images/KDQ1HU3h51-2880.avif 2880w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/KDQ1HU3h51-640.webp 640w, https://uncenter.dev/assets/images/KDQ1HU3h51-750.webp 750w, https://uncenter.dev/assets/images/KDQ1HU3h51-828.webp 828w, https://uncenter.dev/assets/images/KDQ1HU3h51-1080.webp 1080w, https://uncenter.dev/assets/images/KDQ1HU3h51-1200.webp 1200w, https://uncenter.dev/assets/images/KDQ1HU3h51-1920.webp 1920w, https://uncenter.dev/assets/images/KDQ1HU3h51-2048.webp 2048w, https://uncenter.dev/assets/images/KDQ1HU3h51-2880.webp 2880w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/KDQ1HU3h51-640.png?v=cb2816028695" alt="Screenshot of SC Media's article titled 'NPM registry prank leaves developers unable to unpublish packages'" width="2880" height="1580" srcset="https://uncenter.dev/assets/images/KDQ1HU3h51-640.png?v=cb2816028695 640w, https://uncenter.dev/assets/images/KDQ1HU3h51-750.png?v=fbe2490ec1b6 750w, https://uncenter.dev/assets/images/KDQ1HU3h51-828.png?v=866ea5947c4a 828w, https://uncenter.dev/assets/images/KDQ1HU3h51-1080.png?v=2c4a37cd3c5e 1080w, https://uncenter.dev/assets/images/KDQ1HU3h51-1200.png?v=bd8b31d5fd01 1200w, https://uncenter.dev/assets/images/KDQ1HU3h51-1920.png?v=3a861d201c48 1920w, https://uncenter.dev/assets/images/KDQ1HU3h51-2048.png?v=796ae97e39be 2048w, https://uncenter.dev/assets/images/KDQ1HU3h51-2880.png?v=e58a58d4b39d 2880w" sizes="auto"></picture><br><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/iJAHvNG36M-640.avif 640w, https://uncenter.dev/assets/images/iJAHvNG36M-750.avif 750w, https://uncenter.dev/assets/images/iJAHvNG36M-828.avif 828w, https://uncenter.dev/assets/images/iJAHvNG36M-1080.avif 1080w, https://uncenter.dev/assets/images/iJAHvNG36M-1200.avif 1200w, https://uncenter.dev/assets/images/iJAHvNG36M-1920.avif 1920w, https://uncenter.dev/assets/images/iJAHvNG36M-2048.avif 2048w, https://uncenter.dev/assets/images/iJAHvNG36M-2880.avif 2880w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/iJAHvNG36M-640.webp 640w, https://uncenter.dev/assets/images/iJAHvNG36M-750.webp 750w, https://uncenter.dev/assets/images/iJAHvNG36M-828.webp 828w, https://uncenter.dev/assets/images/iJAHvNG36M-1080.webp 1080w, https://uncenter.dev/assets/images/iJAHvNG36M-1200.webp 1200w, https://uncenter.dev/assets/images/iJAHvNG36M-1920.webp 1920w, https://uncenter.dev/assets/images/iJAHvNG36M-2048.webp 2048w, https://uncenter.dev/assets/images/iJAHvNG36M-2880.webp 2880w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/iJAHvNG36M-640.png?v=e431dbff20e6" alt="Screenshot of Checkmarx's article titled 'When Everything Goes Wrong: NPM Dependency-Hell Campaign - 2024 Edition'" width="2880" height="1580" srcset="https://uncenter.dev/assets/images/iJAHvNG36M-640.png?v=e431dbff20e6 640w, https://uncenter.dev/assets/images/iJAHvNG36M-750.png?v=af4da182b8e4 750w, https://uncenter.dev/assets/images/iJAHvNG36M-828.png?v=16d2fcb65e2b 828w, https://uncenter.dev/assets/images/iJAHvNG36M-1080.png?v=6deb995b1b74 1080w, https://uncenter.dev/assets/images/iJAHvNG36M-1200.png?v=a834f5edca14 1200w, https://uncenter.dev/assets/images/iJAHvNG36M-1920.png?v=5bdfa600ade7 1920w, https://uncenter.dev/assets/images/iJAHvNG36M-2048.png?v=04ebec1f3c07 2048w, https://uncenter.dev/assets/images/iJAHvNG36M-2880.png?v=acde19333cb1 2880w" sizes="auto"></picture><br><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/AFslG5xcRs-640.avif 640w, https://uncenter.dev/assets/images/AFslG5xcRs-750.avif 750w, https://uncenter.dev/assets/images/AFslG5xcRs-828.avif 828w, https://uncenter.dev/assets/images/AFslG5xcRs-1080.avif 1080w, https://uncenter.dev/assets/images/AFslG5xcRs-1200.avif 1200w, https://uncenter.dev/assets/images/AFslG5xcRs-1920.avif 1920w, https://uncenter.dev/assets/images/AFslG5xcRs-2048.avif 2048w, https://uncenter.dev/assets/images/AFslG5xcRs-2880.avif 2880w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/AFslG5xcRs-640.webp 640w, https://uncenter.dev/assets/images/AFslG5xcRs-750.webp 750w, https://uncenter.dev/assets/images/AFslG5xcRs-828.webp 828w, https://uncenter.dev/assets/images/AFslG5xcRs-1080.webp 1080w, https://uncenter.dev/assets/images/AFslG5xcRs-1200.webp 1200w, https://uncenter.dev/assets/images/AFslG5xcRs-1920.webp 1920w, https://uncenter.dev/assets/images/AFslG5xcRs-2048.webp 2048w, https://uncenter.dev/assets/images/AFslG5xcRs-2880.webp 2880w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/AFslG5xcRs-640.png?v=93109dbaa886" alt="Screenshot of BleepingComputer's article titled 'everything blocks devs from removing their own npm packages'" width="2880" height="1580" srcset="https://uncenter.dev/assets/images/AFslG5xcRs-640.png?v=93109dbaa886 640w, https://uncenter.dev/assets/images/AFslG5xcRs-750.png?v=50186aaee2e8 750w, https://uncenter.dev/assets/images/AFslG5xcRs-828.png?v=2f6a8b95c559 828w, https://uncenter.dev/assets/images/AFslG5xcRs-1080.png?v=35e085daaacf 1080w, https://uncenter.dev/assets/images/AFslG5xcRs-1200.png?v=878fe566e095 1200w, https://uncenter.dev/assets/images/AFslG5xcRs-1920.png?v=58c252734043 1920w, https://uncenter.dev/assets/images/AFslG5xcRs-2048.png?v=da232a8a82e4 2048w, https://uncenter.dev/assets/images/AFslG5xcRs-2880.png?v=b1cee680864d 2880w" sizes="auto"></picture></p></details><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/cGtSSgHLbz-640.avif 640w, https://uncenter.dev/assets/images/cGtSSgHLbz-750.avif 750w, https://uncenter.dev/assets/images/cGtSSgHLbz-828.avif 828w, https://uncenter.dev/assets/images/cGtSSgHLbz-848.avif 848w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/cGtSSgHLbz-640.webp 640w, https://uncenter.dev/assets/images/cGtSSgHLbz-750.webp 750w, https://uncenter.dev/assets/images/cGtSSgHLbz-828.webp 828w, https://uncenter.dev/assets/images/cGtSSgHLbz-848.webp 848w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/cGtSSgHLbz-640.png?v=e93185577add" alt="A meme with an angry man standing behind huge flames with the text: Now all of tech Twitter knows you broke NPM" width="848" height="500" srcset="https://uncenter.dev/assets/images/cGtSSgHLbz-640.png?v=e93185577add 640w, https://uncenter.dev/assets/images/cGtSSgHLbz-750.png?v=cc43b6055027 750w, https://uncenter.dev/assets/images/cGtSSgHLbz-828.png?v=69085159e58f 828w, https://uncenter.dev/assets/images/cGtSSgHLbz-848.png?v=851624f5bd7e 848w" sizes="auto"></picture></p></details></div><p>Ten years ago, <a href="https://github.com/PatrickJS" rel="noreferrer">PatrickJS</a> created the <code>everything</code> package on NPM, containing every package on the NPM registry in the first 5 years of the registry's existence. The package remained the same for years, but that all changed just a few days ago with <a href="https://twitter.com/trashh_dev/status/1740756965905875311" rel="noreferrer">a single tweet</a>.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/q9nH2mElED-640.avif 640w, https://uncenter.dev/assets/images/q9nH2mElED-750.avif 750w, https://uncenter.dev/assets/images/q9nH2mElED-828.avif 828w, https://uncenter.dev/assets/images/q9nH2mElED-1080.avif 1080w, https://uncenter.dev/assets/images/q9nH2mElED-1200.avif 1200w, https://uncenter.dev/assets/images/q9nH2mElED-1920.avif 1920w, https://uncenter.dev/assets/images/q9nH2mElED-2048.avif 2048w, https://uncenter.dev/assets/images/q9nH2mElED-2160.avif 2160w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/q9nH2mElED-640.webp 640w, https://uncenter.dev/assets/images/q9nH2mElED-750.webp 750w, https://uncenter.dev/assets/images/q9nH2mElED-828.webp 828w, https://uncenter.dev/assets/images/q9nH2mElED-1080.webp 1080w, https://uncenter.dev/assets/images/q9nH2mElED-1200.webp 1200w, https://uncenter.dev/assets/images/q9nH2mElED-1920.webp 1920w, https://uncenter.dev/assets/images/q9nH2mElED-2048.webp 2048w, https://uncenter.dev/assets/images/q9nH2mElED-2160.webp 2160w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/q9nH2mElED-640.png?v=3c4e092af188" alt="Screenshot of trash's tweet saying 'the perfect repo doesn’t exi…' followed by a link to Patrick's node-everything repository" width="2160" height="1282" srcset="https://uncenter.dev/assets/images/q9nH2mElED-640.png?v=3c4e092af188 640w, https://uncenter.dev/assets/images/q9nH2mElED-750.png?v=5b4ad263f7c4 750w, https://uncenter.dev/assets/images/q9nH2mElED-828.png?v=bd7b19b132d2 828w, https://uncenter.dev/assets/images/q9nH2mElED-1080.png?v=6dc03e3f2e27 1080w, https://uncenter.dev/assets/images/q9nH2mElED-1200.png?v=aacffa78f41c 1200w, https://uncenter.dev/assets/images/q9nH2mElED-1920.png?v=ac42d8b9ae8f 1920w, https://uncenter.dev/assets/images/q9nH2mElED-2048.png?v=68227dfca5ae 2048w, https://uncenter.dev/assets/images/q9nH2mElED-2160.png?v=18166d28119a 2160w" sizes="auto"></picture></p><p>I saw the tweet on my timeline and <a href="https://github.com/everything-registry/everything/pull/6" rel="noreferrer">made a quick PR</a> to clean up a few things and help bring the repository up to speed. At the same time, Patrick had started an attempt to publish a <code>2.0.0</code> version of the package, but he discovered that there was now a <code>10</code> megabyte limit for the uncompressed size of a package. I <a href="https://github.com/everything-registry/everything/pull/6#issuecomment-1872278630" rel="noreferrer">made a comment</a> about the issue and we quickly <a href="https://github.com/everything-registry/everything/pull/6#issuecomment-1872294994" rel="noreferrer">began brainstorming</a> a solution.</p><h2 id="brainstorming..." tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#brainstorming..." rel="noreferrer"><span>Brainstorming...</span></a></h2><p>We moved to Twitter DMs, and by this time others who saw Trash's tweet wanted to join — <a href="https://hacksore.com/" rel="noreferrer">Hacksore</a>, and Trash himself. We came up with a plan to divide the ~2.5m packages into "scoped" groups of packages; a group for packages starting with the letter "a", the letter "b", and the rest of the alphabet, and then the numbers "0" to "9", and finally an "other" category for anything else. Since each of these scoped packages would only be a subset of the total, they would easily pass the size limit, and the main <code>everything</code> package could just depend on each of these scoped packages.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/keyro9piyk-640.avif 640w, https://uncenter.dev/assets/images/keyro9piyk-750.avif 750w, https://uncenter.dev/assets/images/keyro9piyk-828.avif 828w, https://uncenter.dev/assets/images/keyro9piyk-1080.avif 1080w, https://uncenter.dev/assets/images/keyro9piyk-1200.avif 1200w, https://uncenter.dev/assets/images/keyro9piyk-1346.avif 1346w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/keyro9piyk-640.webp 640w, https://uncenter.dev/assets/images/keyro9piyk-750.webp 750w, https://uncenter.dev/assets/images/keyro9piyk-828.webp 828w, https://uncenter.dev/assets/images/keyro9piyk-1080.webp 1080w, https://uncenter.dev/assets/images/keyro9piyk-1200.webp 1200w, https://uncenter.dev/assets/images/keyro9piyk-1346.webp 1346w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/keyro9piyk-640.png?v=cdb214938caa" alt="A diagram of the core 'everything' package depending on many other scoped packages" width="1346" height="810" srcset="https://uncenter.dev/assets/images/keyro9piyk-640.png?v=cdb214938caa 640w, https://uncenter.dev/assets/images/keyro9piyk-750.png?v=ef768537ef38 750w, https://uncenter.dev/assets/images/keyro9piyk-828.png?v=243537987cc5 828w, https://uncenter.dev/assets/images/keyro9piyk-1080.png?v=3323c98358f1 1080w, https://uncenter.dev/assets/images/keyro9piyk-1200.png?v=2d3531bc979d 1200w, https://uncenter.dev/assets/images/keyro9piyk-1346.png?v=ac1690f64a9c 1346w" sizes="auto"></picture></p><h2 id="unforeseen-issues" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#unforeseen-issues" rel="noreferrer"><span>Unforeseen issues</span></a></h2><p><a href="https://github.com/everything-registry/everything/pull/7" rel="noreferrer">I began implementing some code</a> to generate the required packages, and a few hours later we were ready to go- except we forget one thing. Or, rather, NPM didn't tell us one thing. It turns out that NPM has a limit for how many dependencies a package can have. And we were apparently <em>way</em> over it. NPM has no apparent documentation on this and the limit wasn't visible in any public source code (the registry is private), so Hacksore <a href="https://github.com/Hacksore/max-npm-package-deps" rel="noreferrer">did some testing</a> and discovered the limit to be 800 dependencies. At the current range of 90k to 300k dependencies per scoped package... we needed a new plan.</p><h2 id="back-to-the-drawing-board" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#back-to-the-drawing-board" rel="noreferrer"><span>Back to the drawing board</span></a></h2><p>I suggested a new, very basic plan: just split them into "chunks" (groups) of 800 dependencies.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/LEx0WYNyFz-640.avif 640w, https://uncenter.dev/assets/images/LEx0WYNyFz-750.avif 750w, https://uncenter.dev/assets/images/LEx0WYNyFz-828.avif 828w, https://uncenter.dev/assets/images/LEx0WYNyFz-1080.avif 1080w, https://uncenter.dev/assets/images/LEx0WYNyFz-1200.avif 1200w, https://uncenter.dev/assets/images/LEx0WYNyFz-1413.avif 1413w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/LEx0WYNyFz-640.webp 640w, https://uncenter.dev/assets/images/LEx0WYNyFz-750.webp 750w, https://uncenter.dev/assets/images/LEx0WYNyFz-828.webp 828w, https://uncenter.dev/assets/images/LEx0WYNyFz-1080.webp 1080w, https://uncenter.dev/assets/images/LEx0WYNyFz-1200.webp 1200w, https://uncenter.dev/assets/images/LEx0WYNyFz-1413.webp 1413w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/LEx0WYNyFz-640.png?v=207a75ed47dc" alt="A diagram of the core 'everything' package with arrows toward many 'chunked' packages" width="1413" height="810" srcset="https://uncenter.dev/assets/images/LEx0WYNyFz-640.png?v=207a75ed47dc 640w, https://uncenter.dev/assets/images/LEx0WYNyFz-750.png?v=e59410efb3bc 750w, https://uncenter.dev/assets/images/LEx0WYNyFz-828.png?v=60cccd9cf874 828w, https://uncenter.dev/assets/images/LEx0WYNyFz-1080.png?v=8714f17d9d3c 1080w, https://uncenter.dev/assets/images/LEx0WYNyFz-1200.png?v=67fc102f3848 1200w, https://uncenter.dev/assets/images/LEx0WYNyFz-1413.png?v=edf916fb0472 1413w" sizes="auto"></picture></p><p>This leaves 3246 groups though, and 3246 is still too many for our main <code>everything</code> package to hold. So we simply "chunk" the 3246 groups of 800 into groups of 800 again.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/I3OJA523Us-640.avif 640w, https://uncenter.dev/assets/images/I3OJA523Us-750.avif 750w, https://uncenter.dev/assets/images/I3OJA523Us-828.avif 828w, https://uncenter.dev/assets/images/I3OJA523Us-1080.avif 1080w, https://uncenter.dev/assets/images/I3OJA523Us-1200.avif 1200w, https://uncenter.dev/assets/images/I3OJA523Us-1920.avif 1920w, https://uncenter.dev/assets/images/I3OJA523Us-2048.avif 2048w, https://uncenter.dev/assets/images/I3OJA523Us-2288.avif 2288w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/I3OJA523Us-640.webp 640w, https://uncenter.dev/assets/images/I3OJA523Us-750.webp 750w, https://uncenter.dev/assets/images/I3OJA523Us-828.webp 828w, https://uncenter.dev/assets/images/I3OJA523Us-1080.webp 1080w, https://uncenter.dev/assets/images/I3OJA523Us-1200.webp 1200w, https://uncenter.dev/assets/images/I3OJA523Us-1920.webp 1920w, https://uncenter.dev/assets/images/I3OJA523Us-2048.webp 2048w, https://uncenter.dev/assets/images/I3OJA523Us-2288.webp 2288w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/I3OJA523Us-640.png?v=64559f220af8" alt="A diagram of the core 'everything' package with arrows toward many 'chunked' packages, each of which in turn has arrows toward more 'sub-chunked' packages" width="2288" height="1293" srcset="https://uncenter.dev/assets/images/I3OJA523Us-640.png?v=64559f220af8 640w, https://uncenter.dev/assets/images/I3OJA523Us-750.png?v=c78fc0b3504a 750w, https://uncenter.dev/assets/images/I3OJA523Us-828.png?v=a48960f7c563 828w, https://uncenter.dev/assets/images/I3OJA523Us-1080.png?v=5466e75687d1 1080w, https://uncenter.dev/assets/images/I3OJA523Us-1200.png?v=8a9e7e2d957f 1200w, https://uncenter.dev/assets/images/I3OJA523Us-1920.png?v=513a85f9561c 1920w, https://uncenter.dev/assets/images/I3OJA523Us-2048.png?v=6f519fcaebfe 2048w, https://uncenter.dev/assets/images/I3OJA523Us-2288.png?v=96c59f053b3d 2288w" sizes="auto"></picture></p><h2 id="3...2...1...-go!" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#3...2...1...-go!" rel="noreferrer"><span>3...2...1... go!</span></a></h2><p>Set on our new plan, we updated the code and triggered <a href="https://github.com/everything-registry/everything/blob/1aef5aa3aa5e3d0e2107063cad6ce63f9cba9b0b/.github/workflows/release.yml" rel="noreferrer">our GitHub Actions workflow</a>...</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/MamIYMGQ-W-640.avif 640w, https://uncenter.dev/assets/images/MamIYMGQ-W-750.avif 750w, https://uncenter.dev/assets/images/MamIYMGQ-W-828.avif 828w, https://uncenter.dev/assets/images/MamIYMGQ-W-848.avif 848w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/MamIYMGQ-W-640.webp 640w, https://uncenter.dev/assets/images/MamIYMGQ-W-750.webp 750w, https://uncenter.dev/assets/images/MamIYMGQ-W-828.webp 828w, https://uncenter.dev/assets/images/MamIYMGQ-W-848.webp 848w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/MamIYMGQ-W-640.png?v=0cda42449955" alt="Screenshot of chat messages in a Discord channel counting down before I triggered the workflow to publish our packages" width="848" height="1576" srcset="https://uncenter.dev/assets/images/MamIYMGQ-W-640.png?v=0cda42449955 640w, https://uncenter.dev/assets/images/MamIYMGQ-W-750.png?v=553555776163 750w, https://uncenter.dev/assets/images/MamIYMGQ-W-828.png?v=0509151ae11e 828w, https://uncenter.dev/assets/images/MamIYMGQ-W-848.png?v=9866444f1854 848w" sizes="auto"></picture></p><p>It worked! The <a href="https://github.com/everything-registry/everything/actions/runs/7361935655/job/20039814620" rel="noreferrer">GitHub Action logs</a> rolled in, one after another, as the packages slowly got published. We had a brief scare after realizing that <a href="https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration" rel="noreferrer">GitHub Actions jobs and workflows have a maximum time</a> that we might reach, but some quick calculations revealed that we had no cause for worry. Workflow jobs time out after 6 hours, and at the current rate of one package published every ~4.5 seconds, we could comfortably publish 4,800+ packages in that time.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/UJpXv7gwkz-640.avif 640w, https://uncenter.dev/assets/images/UJpXv7gwkz-750.avif 750w, https://uncenter.dev/assets/images/UJpXv7gwkz-828.avif 828w, https://uncenter.dev/assets/images/UJpXv7gwkz-1080.avif 1080w, https://uncenter.dev/assets/images/UJpXv7gwkz-1200.avif 1200w, https://uncenter.dev/assets/images/UJpXv7gwkz-1310.avif 1310w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/UJpXv7gwkz-640.webp 640w, https://uncenter.dev/assets/images/UJpXv7gwkz-750.webp 750w, https://uncenter.dev/assets/images/UJpXv7gwkz-828.webp 828w, https://uncenter.dev/assets/images/UJpXv7gwkz-1080.webp 1080w, https://uncenter.dev/assets/images/UJpXv7gwkz-1200.webp 1200w, https://uncenter.dev/assets/images/UJpXv7gwkz-1310.webp 1310w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/UJpXv7gwkz-640.png?v=d3fc40def1ae" alt="Screenshot of Discord chat messages where I sent the link of the first chunk package on NPM followed by excited reactions" width="1310" height="802" srcset="https://uncenter.dev/assets/images/UJpXv7gwkz-640.png?v=d3fc40def1ae 640w, https://uncenter.dev/assets/images/UJpXv7gwkz-750.png?v=ae6ab58bc9ec 750w, https://uncenter.dev/assets/images/UJpXv7gwkz-828.png?v=cc4509d5167d 828w, https://uncenter.dev/assets/images/UJpXv7gwkz-1080.png?v=43ef5fd13d4a 1080w, https://uncenter.dev/assets/images/UJpXv7gwkz-1200.png?v=0567beade70b 1200w, https://uncenter.dev/assets/images/UJpXv7gwkz-1310.png?v=d8cd28e79cbd 1310w" sizes="auto"></picture></p><p>We all went back to doing other things, and I checked the logs occasionally. Half an hour later though, we ran into a different problem... we had been rate limited. In 32 minutes, we had published 454 packages: the main <code>everything</code> package, all five "chunks", but only 448 "sub-chunks". It was only a fraction (roughly 14%) of everything (hah, pun intended) we needed to publish.</p><h2 id="what-next%3F%3F" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#what-next%3F%3F" rel="noreferrer"><span>What next??</span></a></h2><p>I <a href="https://github.com/everything-registry/everything/commit/1aef5aa3aa5e3d0e2107063cad6ce63f9cba9b0b" rel="noreferrer">made a quick fix</a> before heading to bed to skip the packages we had already published, but we still didn't have any sort of plan to deal with rate limiting. Overnight between the 29<sup>th</sup> and the 30<sup>th</sup>, we settled on a new plan. We would periodically run a workflow that publishes as many packages as it can, and then the workflow saves the work it did to the repository so the next run can pick up where the last one left off. I replaced the sketchy manual intervention from the night before with a proper <code>published.json</code> file to keep track of the published packages, and <a href="https://github.com/everything-registry/everything/commit/fafc0ccf92b74eb994136c49b3ae87a7016d6e77" rel="noreferrer">initialized it</a>. I <a href="https://github.com/everything-registry/everything/commit/3bd649ab3bd74a6d7933b8e4ad5116b9b987889d" rel="noreferrer">wrote a release script</a> that wrote back to <code>published.json</code> after publishing each package (I know, I know, this could be better) and <a href="https://github.com/everything-registry/everything/commit/85c8bed75a15e81c66a750e3ea36a4f3bb166fcc" rel="noreferrer">added a step to the workflow</a> to commit the changes after each run. After a few hiccups, it finally worked!</p><p>So it began. Throughout the day I (very irregularly) manually dispatched the workflow. For a while, we sat and waited. We even began an effort to actually run <code>npm install everything</code> (well, <code>yarn add everything</code>) and put up a Twitch stream of the installation on a virtual machine.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/zl_BKf-kqB-640.avif 640w, https://uncenter.dev/assets/images/zl_BKf-kqB-750.avif 750w, https://uncenter.dev/assets/images/zl_BKf-kqB-828.avif 828w, https://uncenter.dev/assets/images/zl_BKf-kqB-1080.avif 1080w, https://uncenter.dev/assets/images/zl_BKf-kqB-1200.avif 1200w, https://uncenter.dev/assets/images/zl_BKf-kqB-1920.avif 1920w, https://uncenter.dev/assets/images/zl_BKf-kqB-2048.avif 2048w, https://uncenter.dev/assets/images/zl_BKf-kqB-2740.avif 2740w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/zl_BKf-kqB-640.webp 640w, https://uncenter.dev/assets/images/zl_BKf-kqB-750.webp 750w, https://uncenter.dev/assets/images/zl_BKf-kqB-828.webp 828w, https://uncenter.dev/assets/images/zl_BKf-kqB-1080.webp 1080w, https://uncenter.dev/assets/images/zl_BKf-kqB-1200.webp 1200w, https://uncenter.dev/assets/images/zl_BKf-kqB-1920.webp 1920w, https://uncenter.dev/assets/images/zl_BKf-kqB-2048.webp 2048w, https://uncenter.dev/assets/images/zl_BKf-kqB-2740.webp 2740w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/zl_BKf-kqB-640.png?v=4e090c053556" alt="Screenshot of a Twitch.tv live stream under the account BuildFailedTV, with the stream description 'install everything and chill'" width="2740" height="1538" srcset="https://uncenter.dev/assets/images/zl_BKf-kqB-640.png?v=4e090c053556 640w, https://uncenter.dev/assets/images/zl_BKf-kqB-750.png?v=33e618f55e95 750w, https://uncenter.dev/assets/images/zl_BKf-kqB-828.png?v=578cf93d6bed 828w, https://uncenter.dev/assets/images/zl_BKf-kqB-1080.png?v=f2a16f7d99dc 1080w, https://uncenter.dev/assets/images/zl_BKf-kqB-1200.png?v=6ded8e1b37ef 1200w, https://uncenter.dev/assets/images/zl_BKf-kqB-1920.png?v=f08d7a4f25be 1920w, https://uncenter.dev/assets/images/zl_BKf-kqB-2048.png?v=d62d5308594b 2048w, https://uncenter.dev/assets/images/zl_BKf-kqB-2740.png?v=ec35e7968e71 2740w" sizes="auto"></picture></p><p>We also <a href="https://everything.npm.lol/" rel="noreferrer">made a website</a>! Many thanks to the rest of the contributors I have mentioned so far, but notably <a href="https://boehs.org/" rel="noreferrer">Evan Boehs</a> for leading the charge and <a href="https://github.com/PickleNik" rel="noreferrer">PickleNik</a> made it look nice.</p><h2 id="finale" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#finale" rel="noreferrer"><span>Finale</span></a></h2><p>Finally, at 11:27PM, <a href="https://github.com/everything-registry/everything/actions/runs/7368358420" rel="noreferrer">the final workflow run</a> completed publishing the last 20 sub-chunks. All 5 chunks, 3246 sub-chunks, and the main <code>everything</code> package. In total, depending on over 2.5 million NPM packages!</p><h2 id="a-vulnerability%3F" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/npm-install-everything/#a-vulnerability%3F" rel="noreferrer"><span>A vulnerability?</span></a></h2><p>The initial response to our endeavour was... not positive. People began coming to the repository, complaining about not being able to unpublish. What?! We looked into it, and it turns out that the issue was our usage of "star" versions; that is, specifying the version not as a typical semantic version in the format of <code>X.Y.Z</code>, but as <code>*</code>. The star means "any and all" versions of a package - here is where the issue lies. NPM blocks package authors from unpublishing packages if another package depends on that version of the package. But since the star is <em>all</em> versions, all versions of a package cannot be unpublished. This is usually harmless, but us (unintentionally) doing this on a large scale prevented <em>anyone</em> from unpublishing. We immediately reached out to GitHub; Patrick used his network and contacts to speak to people at GitHub, and we sent multiple emails to the support and security teams on NPM. Unfortunately, these events transpired over the holidays and the NPM/GitHub teams were not responding (likely out of the office). We continued to get harsh and rude comments from random people with a little too much time on their hands... one person even <a href="https://github.com/everything-registry/everything/issues/21" rel="noreferrer">wrote a 1400 word rant</a> about the unpublishing issue, despite us repeatedly telling them we could do nothing further.</p><p>Thankfully, on the night of January 2<sup>nd</sup>, GitHub reached out and let us know they were aware of the problem. On the 3<sup>rd</sup> of January, we received a notice that our GitHub organization had been "flagged" and our organization and repositories were hidden. Not what we wanted to see, but progress nonetheless.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/guuDcwLwFU-640.avif 640w, https://uncenter.dev/assets/images/guuDcwLwFU-750.avif 750w, https://uncenter.dev/assets/images/guuDcwLwFU-828.avif 828w, https://uncenter.dev/assets/images/guuDcwLwFU-1080.avif 1080w, https://uncenter.dev/assets/images/guuDcwLwFU-1200.avif 1200w, https://uncenter.dev/assets/images/guuDcwLwFU-1920.avif 1920w, https://uncenter.dev/assets/images/guuDcwLwFU-2048.avif 2048w, https://uncenter.dev/assets/images/guuDcwLwFU-2837.avif 2837w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/guuDcwLwFU-640.webp 640w, https://uncenter.dev/assets/images/guuDcwLwFU-750.webp 750w, https://uncenter.dev/assets/images/guuDcwLwFU-828.webp 828w, https://uncenter.dev/assets/images/guuDcwLwFU-1080.webp 1080w, https://uncenter.dev/assets/images/guuDcwLwFU-1200.webp 1200w, https://uncenter.dev/assets/images/guuDcwLwFU-1920.webp 1920w, https://uncenter.dev/assets/images/guuDcwLwFU-2048.webp 2048w, https://uncenter.dev/assets/images/guuDcwLwFU-2837.webp 2837w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/guuDcwLwFU-640.png?v=f1da0b4e3700" alt="Screenshot of GitHub's permanent warning banner on my account. The text reads: The everything-registry organization has been flagged. Because of that, your organization is hidden from the public. If you believe this is a mistake, contact support to have your organization's status reviewed" width="2837" height="199" srcset="https://uncenter.dev/assets/images/guuDcwLwFU-640.png?v=f1da0b4e3700 640w, https://uncenter.dev/assets/images/guuDcwLwFU-750.png?v=7939bd0cb92b 750w, https://uncenter.dev/assets/images/guuDcwLwFU-828.png?v=0bbbea2f4bb1 828w, https://uncenter.dev/assets/images/guuDcwLwFU-1080.png?v=bfe782309d48 1080w, https://uncenter.dev/assets/images/guuDcwLwFU-1200.png?v=2666c510d8ba 1200w, https://uncenter.dev/assets/images/guuDcwLwFU-1920.png?v=3ec41932e83b 1920w, https://uncenter.dev/assets/images/guuDcwLwFU-2048.png?v=2cfbd0d46956 2048w, https://uncenter.dev/assets/images/guuDcwLwFU-2837.png?v=3462f0ead4b9 2837w" sizes="auto"></picture></p><p>They also began removing our organization's scoped packages on NPM, as we had suggested. The initial problem had been solved, but we are still waiting to see how NPM prevents this issue in the future. My two cents are that NPM should either a) prevent folks from publishing packages with star versions in the package.json entirely, or b) don't consider a dependent of a package if it uses a star version when tallying how many packages depend on a package for unpublishing.</p><p>Lastly, I want to apologize for anyone frustrated, annoyed, or just angry at us. We made a mistake, and we've owned up to it. This all started as a harmless joke and we had no intentions of breaking, abusing, or doing any sort of damage to the registry. In short we, uhh... fucked around and found out.</p><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/XSj_t7jhn2-500.avif 500w"><source type="image/webp" srcset="https://uncenter.dev/assets/images/XSj_t7jhn2-500.webp 500w"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/XSj_t7jhn2-500.png?v=7938f765c74b" alt="A man standing next to a whiteboard with a marker pointed towards a graph illustrating how if you fuck around, you find out" width="500" height="500"></picture></p><p>Thanks for reading this, and have a lovely day!</p><p><em>Now</em> you can <a href="https://uncenter.dev/posts/npm-install-everything/#an-update!" rel="noreferrer">read the update</a> if you haven't already!</p>
Spell-checking blog posts with cSpell
2023-03-23T00:00:00Z
https://uncenter.dev/posts/spellchecking-with-eleventy/
<p>Though I haven't written much on this blog, I wanted to add some basic spell-checking to my posts. I looked up "spell-checking markdown" and found <a href="https://tjaddison.com/blog/2021/02/spell-checking-your-markdown-blog-posts-with-cspell/" rel="noreferrer">an article by TJ Addison</a> that explained how to do this with a tool called <code>cSpell</code> (the backbone of the somewhat popular <a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker" rel="noreferrer">Code Spell Checker VS Code extension</a>). Definitely check out TJ's article for a more in-depth explanation of <code>cSpell</code> and how to use it, but here I'll explain how I set it up for my Eleventy blog.</p><h2 id="installing-cspell" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/spellchecking-with-eleventy/#installing-cspell" rel="noreferrer"><span>Installing cSpell</span></a></h2><p>You can use <code>cSpell</code> without installing it as a dependency by running it with <code>npx</code>:</p><div class="code-block" id="03ba2f07"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-sh"><span class="line"><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">npx</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> cspell</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> src/posts/</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">**</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">/</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">*</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">.md</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>But I opted for installing it permanently as a dev dependency and using an npm script to run it:</p><div class="code-block" id="52d78c9e"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-sh"><span class="line"><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">npm</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> install</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> cspell</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> --save-dev</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><div class="code-block" id="92385192"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha has-focused" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-json"><span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">{</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-latte-font-style:italic;--shiki-frappe:#949CBB;--shiki-frappe-font-style:italic;--shiki-macchiato:#939AB7;--shiki-macchiato-font-style:italic;--shiki-mocha:#9399B2;--shiki-mocha-font-style:italic"> // ...</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> "</span><span style="--shiki-latte:#1E66F5;--shiki-frappe:#8CAAEE;--shiki-macchiato:#8AADF4;--shiki-mocha:#89B4FA">scripts</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">"</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-latte-font-style:italic;--shiki-frappe:#949CBB;--shiki-frappe-font-style:italic;--shiki-macchiato:#939AB7;--shiki-macchiato-font-style:italic;--shiki-mocha:#9399B2;--shiki-mocha-font-style:italic"> // ...</span></span>
<span class="line focused"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> "</span><span style="--shiki-latte:#1E66F5;--shiki-frappe:#8CAAEE;--shiki-macchiato:#8AADF4;--shiki-mocha:#89B4FA">spell</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">"</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "cspell src/posts/**/*.md"</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> }</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">}</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><h2 id="configuration" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/spellchecking-with-eleventy/#configuration" rel="noreferrer"><span>Configuration</span></a></h2><p><code>cSpell</code> <a href="http://cspell.org/configuration/#configuration" rel="noreferrer">allows multiple filenames</a> for its configuration but I went with <code>cspell.config.js</code> for consistency with my other config files (like <code>eleventy.config.js</code> and <code>tailwind.config.js</code>).</p><p>To start, set the version to <code>0.2</code> (currently always 0.2) and the language to either <code>en</code> or <code>en-GB</code> (both are included by default).</p><div class="code-block" id="d11cbfb7"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-js"><span class="line"><span style="--shiki-latte:#8839EF;--shiki-latte-font-style:italic;--shiki-frappe:#CA9EE6;--shiki-frappe-font-style:italic;--shiki-macchiato:#C6A0F6;--shiki-macchiato-font-style:italic;--shiki-mocha:#CBA6F7;--shiki-mocha-font-style:italic">module</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#8839EF;--shiki-latte-font-style:italic;--shiki-frappe:#CA9EE6;--shiki-frappe-font-style:italic;--shiki-macchiato:#C6A0F6;--shiki-macchiato-font-style:italic;--shiki-mocha:#CBA6F7;--shiki-mocha-font-style:italic">exports</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> =</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> version</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '0.2'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> language</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'en'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">};</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>There are over 26 <a href="https://github.com/streetsidesoftware/cspell-dicts" rel="noreferrer">other language dictionaries</a> available, but I'm only writing in English so I didn't need to add any others.</p><p>An important step is to define specific words to exclude or flag. I told <code>cSpell</code> to ignore some 11ty-specific terminology and a few other words I use occasionally.</p><div class="code-block" id="09b43a74"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-js"><span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> words</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> [</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'eleventy'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> '11ty'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'shortcodes'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'webc'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> ]</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> flagWords</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> []</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><h3 id="dictionaries" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/spellchecking-with-eleventy/#dictionaries" rel="noreferrer"><span>Dictionaries</span></a></h3><p>In addition to the <code>words</code> property, you can also define dictionaries - just longer lists of words. I added a dictionary for my GitHub repositories to prevent those from being spell-checked if I ever write about them.</p><div class="code-block" id="0dbef79a"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-js"><span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> dictionaries</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> [</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">"repos"</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">]</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> dictionaryDefinitions</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> [</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "name"</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "repos"</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "path"</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "./utils/dicts/repos.txt"</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> },</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> ]</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>Instead of manually updating my <code>repos.txt</code> dict, I wrote a script to fetch my repositories from the GitHub API and write them to the file.</p><div class="code-block" id="e561a453"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-js"><span class="line"><span style="--shiki-latte:#EA76CB;--shiki-latte-font-style:italic;--shiki-frappe:#F4B8E4;--shiki-frappe-font-style:italic;--shiki-macchiato:#F5BDE6;--shiki-macchiato-font-style:italic;--shiki-mocha:#F5C2E7;--shiki-mocha-font-style:italic">#!/usr/bin/env node</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">const</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> fs </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> require</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'node:fs/promises'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">const</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> join </span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">}</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5"> =</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> require</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'node:path'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">async</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> function</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> getRepos</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">()</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> try</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> const</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> response </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> await</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> fetch</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'https://api.github.com/users/uncenter/repos'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> )</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> const</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> json </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> await</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> response</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">json</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">()</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> if</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> (Array</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">isArray</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(json)) </span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">{</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> fs</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">writeFile</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span></span>
<span class="line"><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> join</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(__dirname</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> './dicts/repos.txt'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> json</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">map</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">(</span><span style="--shiki-latte:#E64553;--shiki-latte-font-style:italic;--shiki-frappe:#EA999C;--shiki-frappe-font-style:italic;--shiki-macchiato:#EE99A0;--shiki-macchiato-font-style:italic;--shiki-mocha:#EBA0AC;--shiki-mocha-font-style:italic">repo</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">)</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> =></span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> repo</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">name)</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">join</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\n</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> )</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> }</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> else</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> throw</span><span style="--shiki-latte:#8839EF;--shiki-latte-font-weight:bold;--shiki-frappe:#CA9EE6;--shiki-frappe-font-weight:bold;--shiki-macchiato:#C6A0F6;--shiki-macchiato-font-weight:bold;--shiki-mocha:#CBA6F7;--shiki-mocha-font-weight:bold"> new</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic"> TypeError</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'Invalid response content.'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> }</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> }</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7"> catch</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> console</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">.</span><span style="--shiki-latte:#1E66F5;--shiki-latte-font-style:italic;--shiki-frappe:#8CAAEE;--shiki-frappe-font-style:italic;--shiki-macchiato:#8AADF4;--shiki-macchiato-font-style:italic;--shiki-mocha:#89B4FA;--shiki-mocha-font-style:italic">error</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">(</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">'[cspell:update] Something went wrong.'</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">)</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">;</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> }</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">}</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>If you're using Netlify, you can run this script and the spell-check script during the build process by adding it to the <code>build</code> command in your <code>netlify.toml</code> file (or the GUI on Netlify's website):</p><div class="code-block" id="1b77cec9"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-toml"><span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">[</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">build</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">]</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">command </span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">=</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> "node ./utils/get-repos.js && npm run spell && npm run build"</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p><picture><source type="image/avif" srcset="https://uncenter.dev/assets/images/fg8M8kcs50-640.avif 640w, https://uncenter.dev/assets/images/fg8M8kcs50-750.avif 750w, https://uncenter.dev/assets/images/fg8M8kcs50-828.avif 828w, https://uncenter.dev/assets/images/fg8M8kcs50-1080.avif 1080w, https://uncenter.dev/assets/images/fg8M8kcs50-1200.avif 1200w, https://uncenter.dev/assets/images/fg8M8kcs50-1638.avif 1638w" sizes="auto"><source type="image/webp" srcset="https://uncenter.dev/assets/images/fg8M8kcs50-640.webp 640w, https://uncenter.dev/assets/images/fg8M8kcs50-750.webp 750w, https://uncenter.dev/assets/images/fg8M8kcs50-828.webp 828w, https://uncenter.dev/assets/images/fg8M8kcs50-1080.webp 1080w, https://uncenter.dev/assets/images/fg8M8kcs50-1200.webp 1200w, https://uncenter.dev/assets/images/fg8M8kcs50-1638.webp 1638w" sizes="auto"><img loading="lazy" decoding="async" src="https://uncenter.dev/assets/images/fg8M8kcs50-640.png?v=1f3e49bcd65a" alt="Screenshot of our new build command in the Netlify GUI" width="1638" height="652" srcset="https://uncenter.dev/assets/images/fg8M8kcs50-640.png?v=1f3e49bcd65a 640w, https://uncenter.dev/assets/images/fg8M8kcs50-750.png?v=648463734409 750w, https://uncenter.dev/assets/images/fg8M8kcs50-828.png?v=0210ae64f7fe 828w, https://uncenter.dev/assets/images/fg8M8kcs50-1080.png?v=4fdc897a9770 1080w, https://uncenter.dev/assets/images/fg8M8kcs50-1200.png?v=33fd24b0ca92 1200w, https://uncenter.dev/assets/images/fg8M8kcs50-1638.png?v=a50a7c1fd5c7 1638w" sizes="auto"></picture></p><h3 id="ignore-patterns" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/spellchecking-with-eleventy/#ignore-patterns" rel="noreferrer"><span>Ignore patterns</span></a></h3><p>Finally, the config file allows you to define regular expression patterns to ignore. I added patterns to ignore words in Nunjucks expressions, Markdown code blocks and inline code, and proper nouns (words that start with a capital letter).</p><div class="code-block" id="fded8d4a"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-js"><span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> ignoreRegExpList</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> [</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'nunjucksExpression'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'markdownCodeBlock'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'markdownInlineCode'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'properNouns'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> ]</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> patterns</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">:</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> [</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">{</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">% raw %</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">}</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> name</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'nunjucksExpression'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> pattern</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7"> /</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">{%</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">.</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*?</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">%}</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">/</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">gis</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> },</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> name</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'markdownCodeBlock'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> pattern</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7"> /</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">`</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">{3}</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">[</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\s\S</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">]</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*?</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">`</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">{3}</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">(</span><span style="--shiki-latte:#1E66F5;--shiki-frappe:#8CAAEE;--shiki-macchiato:#8AADF4;--shiki-mocha:#89B4FA">?=</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\n</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">|</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">$</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">)</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">/</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">gi</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> },</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> name</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'markdownInlineCode'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> pattern</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7"> /</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">`</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">[</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">^</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">`</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">]</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">*</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">`</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">/</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">gi</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> },</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> {</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> name</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1"> 'properNouns'</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> pattern</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">:</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7"> /</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">(</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">?<=</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\s</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">|</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">^</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">|</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">[</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">^</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\w\s</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">]</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">)</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">[</span><span style="--shiki-latte:#DC8A78;--shiki-frappe:#F2D5CF;--shiki-macchiato:#F4DBD6;--shiki-mocha:#F5E0DC">A-Z</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">][</span><span style="--shiki-latte:#DC8A78;--shiki-frappe:#F2D5CF;--shiki-macchiato:#F4DBD6;--shiki-mocha:#F5E0DC">a-z</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">]</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">+</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">(</span><span style="--shiki-latte:#1E66F5;--shiki-frappe:#8CAAEE;--shiki-macchiato:#8AADF4;--shiki-mocha:#89B4FA">?=</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\s</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">|</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">$</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">|</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">[</span><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">^</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">\w\s</span><span style="--shiki-latte:#DF8E1D;--shiki-frappe:#E5C890;--shiki-macchiato:#EED49F;--shiki-mocha:#F9E2AF">]</span><span style="--shiki-latte:#40A02B;--shiki-frappe:#A6D189;--shiki-macchiato:#A6DA95;--shiki-mocha:#A6E3A1">)</span><span style="--shiki-latte:#EA76CB;--shiki-frappe:#F4B8E4;--shiki-macchiato:#F5BDE6;--shiki-mocha:#F5C2E7">/</span><span style="--shiki-latte:#8839EF;--shiki-frappe:#CA9EE6;--shiki-macchiato:#C6A0F6;--shiki-mocha:#CBA6F7">g</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,</span></span>
<span class="line"><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2"> },</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4"> ]</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">,{</span><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">% endraw %</span><span style="--shiki-latte:#7C7F93;--shiki-frappe:#949CBB;--shiki-macchiato:#939AB7;--shiki-mocha:#9399B2">}</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><p>I'm surprised that there isn't a pattern for Markdown code blocks by default; I was having issues with common JavaScript libraries and methods being flagged as typos. Additionally, I use a few <a href="https://www.11ty.dev/docs/shortcodes/" rel="noreferrer">custom shortcodes</a> that kept getting flagged as a typo, so the <code>nunjucksExpression</code> pattern was a must.</p><h3 id="ignore-words-in-front-matter" tabindex="-1"><a class="header-anchor" href="https://uncenter.dev/posts/spellchecking-with-eleventy/#ignore-words-in-front-matter" rel="noreferrer"><span>Ignore words in front matter</span></a></h3><p>One other neat thing about cSpell is that you can define words to ignore per file. For example, you could ignore the word <code>supercalifragilisticexpialidocious</code> in just one file by adding <code>cSpell:ignore supercalifragilisticexpialidocious</code> as a comment at the top of the file:</p><div class="code-block" id="bfff11fa"><pre class="shiki shiki-themes catppuccin-latte catppuccin-frappe catppuccin-macchiato catppuccin-mocha has-focused" style="--shiki-latte:#4c4f69;--shiki-frappe:#c6d0f5;--shiki-macchiato:#cad3f5;--shiki-mocha:#cdd6f4;--shiki-latte-bg:#eff1f5;--shiki-frappe-bg:#303446;--shiki-macchiato-bg:#24273a;--shiki-mocha-bg:#1e1e2e" tabindex="0"><code class="language-md"><span class="line"><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">---</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">tags: </span><span style="--shiki-latte:#7287FD;--shiki-frappe:#BABBF1;--shiki-macchiato:#B7BDF8;--shiki-mocha:#B4BEFE">[</span><span style="--shiki-latte:#7287FD;--shiki-frappe:#BABBF1;--shiki-macchiato:#B7BDF8;--shiki-mocha:#B4BEFE">...</span><span style="--shiki-latte:#7287FD;--shiki-frappe:#BABBF1;--shiki-macchiato:#B7BDF8;--shiki-mocha:#B4BEFE">]</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">title: Magna voluptate officia cillum Lorem proident.</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">description: Cupidatat excepteur ullamco laboris in veniam qui officia tempor aliquip et commodo.</span></span>
<span class="line"><span style="--shiki-latte:#4C4F69;--shiki-frappe:#C6D0F5;--shiki-macchiato:#CAD3F5;--shiki-mocha:#CDD6F4">date: 2000-01-01</span></span>
<span class="line focused"><span style="--shiki-latte:#D20F39;--shiki-frappe:#E78284;--shiki-macchiato:#ED8796;--shiki-mocha:#F38BA8"># cSpell:ignore supercalifragilisticexpialidocious</span></span>
<span class="line"><span style="--shiki-latte:#179299;--shiki-frappe:#81C8BE;--shiki-macchiato:#8BD5CA;--shiki-mocha:#94E2D5">---</span></span></code></pre><div class="toolbar"><button title="Copy code to clipboard" aria-label="Copy code to clipboard" class="copy-code"><svg class="copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button> <button title="Copy link to code block" aria-label="Copy link to code block" class="copy-link"><svg class="link" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg><svg class="check" aria-hidden="true" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg></button></div></div><div class="container tip"><p>You can also use <code>spell-checker:ignore</code> instead of <code>cSpell:ignore</code>. For more information on per document settings, see <a href="https://cspell.org/configuration/document-settings/#in-document-settings" rel="noreferrer">https://cspell.org/configuration/document-settings/#in-document-settings</a>.</p></div><p>You don't have to put it in the front matter, but I like to keep my posts as clean & organized as possible and it looks nice there.</p><p>Let me know if you have any questions or suggestions!</p>