diff options
56 files changed, 840 insertions, 130 deletions
diff --git a/about/index.html b/about/index.html index 644063d..072aa77 100644 --- a/about/index.html +++ b/about/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -94,11 +94,26 @@ that's used in the background of this site is by <a class="reference external" h / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/8seg/index.html b/blog/8seg/index.html index 2be0896..793b338 100644 --- a/blog/8seg/index.html +++ b/blog/8seg/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -216,11 +216,26 @@ set of pre-programmed waveform transitions.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/css-only-code-blocks/index.html b/blog/css-only-code-blocks/index.html new file mode 100644 index 0000000..5b15937 --- /dev/null +++ b/blog/css-only-code-blocks/index.html @@ -0,0 +1,259 @@ +<!DOCTYPE html> +<html><head> + <meta charset="utf-8"> + <title>Code listings with nice line wrapping and line numbers from plain CSS | Home</title> + <meta name="description" content=""> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="mobile-web-app-capable" content="yes"> + <meta name="color-scheme" content="dark light"> + <link rel="stylesheet" href="/style.css"> + + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> + <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> +</head> +<body><nav> + <div class="internal"> + + <a href="/" title="Home">Home</a> + <a href="/blog/" title="Blog">Blog</a> + <a href="/projects/" title="Projects">Projects</a> + <a href="/about/" title="About">About</a> + </div> + <div class="search"> + <div id="search"></div> + </div> + <div class="external"> + <a href="https://git.jaseg.de/" title="cgit">cgit</a> + <a href="https://github.com/jaseg" title="Github">Github</a> + <a href="https://gitlab.com/neinseg" title="Gitlab">Gitlab</a> + <a href="https://chaos.social/@jaseg" title="Mastodon">Mastodon</a> + </span> +</nav> + + <header> + <h1>Code listings with nice line wrapping and line numbers from plain CSS</h1> +<ul class="breadcrumbs"> + <li><a href="/">jaseg.de</a></li> + <li><a href="/blog/">Blog</a></li><li><a href="/blog/css-only-code-blocks/">Code listings with nice line wrapping and line numbers from plain CSS</a></li> +</ul> + <strong>2025-07-23</strong> + </header> + <main data-pagefind-body> + <div class="document"> + + +<p>Code listings in web pages are often a bit of a pain to use. Often, they don't wrap on small screens. Also, copy-pasting +code from a code listing often copies the line numbers along with the code. Finally, many implementations use +heavyweight HTML and/or javascript, making them slow to render (looking at you, gitlab).</p> +<p>For this blog, I wrote an implementation that renders HTML code listings entirely without JavaScript, renders line +numbers using plain CSS such that they don't get selected with the code, and that works with the browser to wrap in a +natural way while still supporting the little line continuation arrows that are used to show that a line was soft +wrapped in text editors.</p> +<p>This blog is rendered as a static site using <a class="reference external" href="https://gohugo.io/">Hugo</a> from a pile of <a class="reference external" href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html">RestructuredText</a> documents. RestructuredText renders +code listings using <a class="reference external" href="https://pygments.org/">Pygments</a> by default. Pygments hard-bakes the line numbers into the generated HTML, so I am using a +<a class="reference external" href="https://en.wikipedia.org/wiki/Monkey_patch">monkey-patched</a> hook that changes the line number rendering to just a bunch of empty <tt class="docutils literal"><span></tt> elements. The resulting +HTML for a code block then looks like this:</p> +<pre class="code html literal-block"> +<span class="lineno"></span><span class="line"><span class="p"><</span><span class="nt">pre</span> <span class="na">class</span><span class="o">=</span><span class="s">"code [language] literal-block"</span><span class="p">></span></span> +<span class="lineno"></span><span class="line"> <span class="p"><</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">"lineno"</span><span class="p">></</span><span class="nt">span</span><span class="p">></span></span> +<span class="lineno"></span><span class="line"> <span class="p"><</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">"line"</span><span class="p">></span></span> +<span class="lineno"></span><span class="line"> <span class="p"><</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">"[syntax highlight token]"</span><span class="p">></span>The <span class="p"></</span><span class="nt">span</span><span class="p">><</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">"[other syntax highlight token]"</span><span class="p">></span>code!<span class="p"><</span><span class="nt">span</span><span class="p">></span></span> +<span class="lineno"></span><span class="line"> <span class="p"></</span><span class="nt">span</span><span class="p">></span></span> +<span class="lineno"></span><span class="line"> <span class="cm"><!-- ... repeat once for each source line. --></span></span> +<span class="lineno"></span><span class="line"><span class="p"></</span><span class="nt">pre</span><span class="p">></span> +</span></pre> +<p>You can find the (rather short) source of the <tt class="docutils literal">rst2html</tt> wrapper <a class="reference external" href="#rst2html-wrapper">below</a>.</p> +<div class="section" id="the-css"> +<h2>The CSS</h2> +<p>This modified HTML structure of the code listing gets accompanied by some CSS to make it flow nicely. Here is a listing +of the complete CSS controlling the listing. The only bit that isn't included here is the actual syntax styling rules +for the pygments tokens.</p> +<pre class="code css literal-block"> +<span class="lineno"></span><span class="line"><span class="c">/*****************************************************/</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* Code block formatting / syntax highlighting rules */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/*****************************************************/</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">font-family</span><span class="p">:</span><span class="w"> </span><span class="s2">"Fira Code"</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">font-size</span><span class="p">:</span><span class="w"> </span><span class="mi">13</span><span class="kt">px</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">text-align</span><span class="p">:</span><span class="w"> </span><span class="kc">left</span><span class="p">;</span><span class="w"> </span><span class="c">/* Override default content "justify" alignment */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">white-space</span><span class="p">:</span><span class="w"> </span><span class="kc">pre-wrap</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">word-wrap</span><span class="p">:</span><span class="w"> </span><span class="kc">break-word</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">overflow-x</span><span class="p">:</span><span class="w"> </span><span class="kc">auto</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="k">grid</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">align-items</span><span class="p">:</span><span class="w"> </span><span class="kc">start</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">grid-template-columns</span><span class="p">:</span><span class="w"> </span><span class="n">min-content</span><span class="w"> </span><span class="mi">1</span><span class="n">fr</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">.</span><span class="nc">line</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">padding-left</span><span class="p">:</span><span class="w"> </span><span class="nb">calc</span><span class="p">(</span><span class="mi">2</span><span class="kt">em</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="kt">px</span><span class="p">);</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">text-indent</span><span class="p">:</span><span class="w"> </span><span class="mi">-2</span><span class="kt">em</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">padding-top</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="kt">px</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">min-width</span><span class="p">:</span><span class="w"> </span><span class="mi">15</span><span class="kt">em</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* Make individual syntax tokens wrap anywhere */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">.</span><span class="nc">line</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">overflow-wrap</span><span class="p">:</span><span class="w"> </span><span class="n">anywhere</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">white-space</span><span class="p">:</span><span class="w"> </span><span class="kc">pre-wrap</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* We render line numbers in CSS! */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">.</span><span class="nc">lineno</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">counter-increment</span><span class="p">:</span><span class="w"> </span><span class="n">lineno</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">word-break</span><span class="p">:</span><span class="w"> </span><span class="n">keep-all</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">margin</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">padding-left</span><span class="p">:</span><span class="w"> </span><span class="mi">15</span><span class="kt">px</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">padding-right</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="kt">px</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">overflow</span><span class="p">:</span><span class="w"> </span><span class="kc">clip</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">position</span><span class="p">:</span><span class="w"> </span><span class="kc">relative</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">text-align</span><span class="p">:</span><span class="w"> </span><span class="kc">right</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--c-text-muted</span><span class="p">);</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">border-right</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">px</span><span class="w"> </span><span class="kc">solid</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--c-fg-highlight</span><span class="p">);</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">align-self</span><span class="p">:</span><span class="w"> </span><span class="kc">stretch</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* We also handle line continuation markers in CSS. */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">.</span><span class="nc">lineno</span><span class="p">::</span><span class="nd">after</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">position</span><span class="p">:</span><span class="w"> </span><span class="kc">absolute</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">right</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="kt">px</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">content</span><span class="p">:</span><span class="w"> </span><span class="s2">"\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳"</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">white-space</span><span class="p">:</span><span class="w"> </span><span class="kc">pre</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--c-text-muted</span><span class="p">);</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* Insert the actual line number */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="p">.</span><span class="nc">lineno</span><span class="p">::</span><span class="nd">before</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">content</span><span class="p">:</span><span class="w"> </span><span class="nb">counter</span><span class="p">(</span><span class="n">lineno</span><span class="p">);</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="p">::</span><span class="nd">before</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"> </span><span class="k">counter-reset</span><span class="p">:</span><span class="w"> </span><span class="n">lineno</span><span class="p">;</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="p">.</span><span class="nc">hll</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c">/* Following are about 50 lines that define the styling of each kind of pygments syntax highlight token. These lines</span></span> +<span class="lineno"></span><span class="line"><span class="c"> all look like the following: */</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="p">.</span><span class="nc">code</span><span class="w"> </span><span class="p">.</span><span class="nc">c</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--c-text</span><span class="p">);</span><span class="w"> </span><span class="k">font-weight</span><span class="p">:</span><span class="w"> </span><span class="mi">400</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c">/* Comment */</span> +</span></pre> +<p>This CSS does a few things:</p> +<blockquote> +<ol class="arabic simple"> +<li>It renders the <tt class="docutils literal"><pre></tt> code listing element using a two-column CSS <tt class="docutils literal">display: grid</tt> layout. The left column is +used for the line numbers, and the right column is used for the code lines.</li> +<li>It numbers the lines using a <a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/CSS/counter">CSS Counter</a>. CSS counters are meant for things like numbering headings and such, but +they are a perfect fit for our purpose.</li> +<li>It inserts the counter value as the line number into the <tt class="docutils literal"><span <span class="pre">class="lineno"></span></tt> element's <tt class="docutils literal">::before</tt> +pseudo-element. A side effect of using the <tt class="docutils literal">::before</tt> pseudo-element is that without doing anything extra, the +line numbers will remain outside of the normal text selection so they will neither be highlighted when selecting +listing content, nor will they be copied when copy/pasting the listing content.</li> +<li>It inserts a string of <tt class="docutils literal"><span class="pre">"\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳\a↳"</span></tt> into the line number span's +<tt class="docutils literal">::after</tt> pseudo-element. This string evaluates to a sequence of unicode arrows separated by line breaks, and +starting with an empty line. The <tt class="docutils literal">::after</tt> pseudo-element is positioned using <tt class="docutils literal">position: absolute</tt>, and the +parent <tt class="docutils literal"><span <span class="pre">class="lineno"></span></tt> has <tt class="docutils literal">position: relative</tt> set. This way, the arrow pseudo-element gets placed on +top of the lineno span without affecting the layout at all. By setting <tt class="docutils literal">overflow: clip</tt> on the parent <tt class="docutils literal"><span +<span class="pre">class="lineno"></span></tt>, the arrow pseudo-element gets cut off vertically wherever the parent lineno element naturally +ends.</li> +</ol> +</blockquote> +<p>The line number span is inserted into the parent <tt class="docutils literal"><pre></tt> element's CSS grid using <tt class="docutils literal"><span class="pre">align-self:</span> stretch</tt>, which +causes it to vertically stretch to fill the available space. Since the line number span only contains the line number, +its minimum height is a single line. As a result, it will stretch higher only when the corresponding code line in the +right grid column stretches vertically because of line wrapping. When that happens, part of the arrow pseudo-element +starts showing through from behind the <tt class="docutils literal">overflow: clip</tt> of the line number span, and one arrow gets rendered for each +wrapped listing line.</p> +<p>When the page is too narrow, we don't want the code listing's lines to wrapp into a column of single characters. To +prevent that, we simply set a <tt class="docutils literal"><span class="pre">min-width</span></tt> on the <tt class="docutils literal"><span <span class="pre">class="line"></span></tt> in the right column, and set <tt class="docutils literal"><span class="pre">overflow-x:</span> +auto</tt> on the listing <tt class="docutils literal"><pre></tt>. This results in a horizontal scroll bar appearing whenever the listing gets too narrow.</p> +<p>You can try out the line wrapping by resizing this page!</p> +</div> +<div class="section" id="rst2html-wrapper"> +<h2>rst2html wrapper</h2> +<p>Here is the python <tt class="docutils literal">rst2html</tt> wrapper that monkey-patches code rendering. I made hugo invoke this while building the +page by simply overriding the <tt class="docutils literal">PATH</tt> environment variable.</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># Based on https://gist.github.com/mastbaum/2655700 for the basic plugin scaffolding</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">re</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">docutils.core</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">docutils.transforms</span><span class="w"> </span><span class="kn">import</span> <span class="n">Transform</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">docutils.nodes</span><span class="w"> </span><span class="kn">import</span> <span class="n">TextElement</span><span class="p">,</span> <span class="n">Inline</span><span class="p">,</span> <span class="n">Text</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">docutils.parsers.rst</span><span class="w"> </span><span class="kn">import</span> <span class="n">Directive</span><span class="p">,</span> <span class="n">directives</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">docutils.writers.html4css1</span><span class="w"> </span><span class="kn">import</span> <span class="n">Writer</span><span class="p">,</span> <span class="n">HTMLTranslator</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span><span class="w"> </span><span class="nc">UnfuckedHTMLTranslator</span><span class="p">(</span><span class="n">HTMLTranslator</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">in_literal_block</span> <span class="o">=</span> <span class="kc">False</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="nf">visit_literal_block</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Insert an empty "lineno" span before each line. We insert the line numbers using pure CSS in a ::before</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># pseudo-element. This has the added advantage that the line numbers don't get included in text selection.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># These line number spans are also used to show line continuation markers when a line is wrapped.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">in_literal_block</span> <span class="o">=</span> <span class="kc">True</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">starttag</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="s1">'pre'</span><span class="p">,</span> <span class="n">CLASS</span><span class="o">=</span><span class="s1">'literal-block'</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'<span class="lineno"></span><span class="line">'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="nf">depart_literal_block</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">in_literal_block</span> <span class="o">=</span> <span class="kc">False</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1"></span></pre></span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="nf">visit_Text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">in_literal_block</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">re</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="s1">'([^</span><span class="se">\n</span><span class="s1">]*)(</span><span class="se">\n</span><span class="s1">|$)'</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">astext</span><span class="p">()):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">text</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="n">text</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">visit_Text</span><span class="p">(</span><span class="n">Text</span><span class="p">(</span><span class="n">text</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="n">end</span> <span class="o">==</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">Inline</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">depart_inline</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span></span><span class="se">\n</span><span class="s1"><span class="lineno"></span><span class="line">'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">Inline</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">visit_inline</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">else</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">visit_Text</span><span class="p">(</span><span class="n">node</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">html_writer</span> <span class="o">=</span> <span class="n">Writer</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">html_writer</span><span class="o">.</span><span class="n">translator_class</span> <span class="o">=</span> <span class="n">UnfuckedHTMLTranslator</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">docutils</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">publish_cmdline</span><span class="p">(</span><span class="n">writer</span><span class="o">=</span><span class="n">html_writer</span><span class="p">)</span> +</span></pre> +</div> +</div> + </main><footer> + Copyright © 2025 Jan Sebastian Götte + / <a href="/about/">About</a> + / <a href="/imprint/">Imprint</a> +</footer> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> + <script> + window.addEventListener('DOMContentLoaded', (event) => { + new PagefindUI({element: "#search", showSubResults: true}); + }); + </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> + </body> +</html> diff --git a/blog/hsm-basics/index.html b/blog/hsm-basics/index.html index 66ad297..cfa72b9 100644 --- a/blog/hsm-basics/index.html +++ b/blog/hsm-basics/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -233,11 +233,26 @@ while not providing better sensitivity.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/ihsm-worlds-first-diy-hsm/index.html b/blog/ihsm-worlds-first-diy-hsm/index.html index c61a01b..b393484 100644 --- a/blog/ihsm-worlds-first-diy-hsm/index.html +++ b/blog/ihsm-worlds-first-diy-hsm/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -77,11 +77,26 @@ focusing our effort on the next iteration of the design instead. Stay tuned for / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/index.html b/blog/index.html index 51e985c..3c2bb69 100644 --- a/blog/index.html +++ b/blog/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -40,6 +40,18 @@ </header> <main class="cards"> + <div class="card"><h3><a href="/blog/css-only-code-blocks/">Code listings with nice line wrapping and line numbers from plain CSS</a></h3><strong>2025-07-23</strong> + + <div class="summary"> + <div class="document"> + + +<p>Code listings in web pages are often a bit of a pain to use. Usually, they don't wrap on small screens. Also, copy-pasting code from a code listing often copies the line numbers along with the code. Finally, many implementations use heavyweight HTML and/or javascript, making them slow to render. For this blog, I wrote a little CSS hack that renders nice, wrapping code blocks with line continuation markers in plain CSS without any JS.</p> +</div> + <a href="http://jaseg.de/blog/css-only-code-blocks/">Read more</a> + </div> +</div> + <div class="card"><h3><a href="/blog/jupyterlab-notebook-file-oneliner/">Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</a></h3><strong>2025-06-29</strong> <div class="summary"> @@ -196,11 +208,26 @@ set up your UART to talk to an external hardware USB to serial converter is a ma / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/index.xml b/blog/index.xml index 285b3f8..5ce7d35 100644 --- a/blog/index.xml +++ b/blog/index.xml @@ -7,9 +7,16 @@ <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> - <lastBuildDate>Sun, 29 Jun 2025 23:42:00 +0100</lastBuildDate> + <lastBuildDate>Wed, 23 Jul 2025 23:42:00 +0100</lastBuildDate> <atom:link href="http://jaseg.de/blog/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Code listings with nice line wrapping and line numbers from plain CSS</title> + <link>http://jaseg.de/blog/css-only-code-blocks/</link> + <pubDate>Wed, 23 Jul 2025 23:42:00 +0100</pubDate> + <guid>http://jaseg.de/blog/css-only-code-blocks/</guid> + <description><div class="document">


<p>Code listings in web pages are often a bit of a pain to use. Usually, they don't wrap on small screens. Also, copy-pasting code from a code listing often copies the line numbers along with the code. Finally, many implementations use heavyweight HTML and/or javascript, making them slow to render. For this blog, I wrote a little CSS hack that renders nice, wrapping code blocks with line continuation markers in plain CSS without any JS.</p>
</div></description> + </item> + <item> <title>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</title> <link>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</link> <pubDate>Sun, 29 Jun 2025 23:42:00 +0100</pubDate> diff --git a/blog/jupyterlab-notebook-file-oneliner/index.html b/blog/jupyterlab-notebook-file-oneliner/index.html index 9071c12..9eb93a2 100644 --- a/blog/jupyterlab-notebook-file-oneliner/index.html +++ b/blog/jupyterlab-notebook-file-oneliner/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -60,11 +60,26 @@ ourselves.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/kicad-mesh-plugin/index.html b/blog/kicad-mesh-plugin/index.html index 68762b0..2119817 100644 --- a/blog/kicad-mesh-plugin/index.html +++ b/blog/kicad-mesh-plugin/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -213,11 +213,26 @@ making a copy of the board file first and treating mesh generation as a non-reve / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/led-characterization/index.html b/blog/led-characterization/index.html index 8803537..96fe4ea 100644 --- a/blog/led-characterization/index.html +++ b/blog/led-characterization/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -427,11 +427,26 @@ can view the Jupyter notebook most of the analysis above <a class="reference ext / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/multichannel-led-driver/index.html b/blog/multichannel-led-driver/index.html index 14981e5..0077335 100644 --- a/blog/multichannel-led-driver/index.html +++ b/blog/multichannel-led-driver/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -380,11 +380,26 @@ analyze the brightness measurement data <a class="reference external" href="http / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/private-contact-discovery/index.html b/blog/private-contact-discovery/index.html index 8a15c4b..0ad3659 100644 --- a/blog/private-contact-discovery/index.html +++ b/blog/private-contact-discovery/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -76,11 +76,26 @@ accountability issues by simply not producing as much sensitive data in the firs / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/serial-protocols/index.html b/blog/serial-protocols/index.html index 1fb7aba..562b451 100644 --- a/blog/serial-protocols/index.html +++ b/blog/serial-protocols/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -247,11 +247,26 @@ want to set a large framebuffer in pieces, do it in a <a class="reference extern / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/telekom-gpon-sfp/index.html b/blog/telekom-gpon-sfp/index.html index d83f73e..1351707 100644 --- a/blog/telekom-gpon-sfp/index.html +++ b/blog/telekom-gpon-sfp/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -222,11 +222,26 @@ collected <a class="reference external" href="https://github.com/xvzf/zyxel-gpon / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/thors-hammer/index.html b/blog/thors-hammer/index.html index 8520fa0..366194d 100644 --- a/blog/thors-hammer/index.html +++ b/blog/thors-hammer/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -84,11 +84,26 @@ board as shims between the plunger and the case to limit the plunger's travel in / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/blog/wifi-led-driver/index.html b/blog/wifi-led-driver/index.html index 81713f5..88a4b62 100644 --- a/blog/wifi-led-driver/index.html +++ b/blog/wifi-led-driver/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -142,11 +142,26 @@ violence.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/categories/index.html b/categories/index.html index 1e94a84..cf9cfdd 100644 --- a/categories/index.html +++ b/categories/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -45,11 +45,26 @@ / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/imprint/index.html b/imprint/index.html index e32b045..2eba271 100644 --- a/imprint/index.html +++ b/imprint/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -126,11 +126,26 @@ Schritten verfolgt.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> @@ -9,7 +9,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -96,6 +96,19 @@ pages. If you want to learn more about me, head over to the about page.</p> <h2>Blog</h2> + <div class="card"><h3><a href="/blog/css-only-code-blocks/">Code listings with nice line wrapping and line numbers from plain CSS</a></h3><strong>2025-07-23</strong> + + <div class="summary"> + <div class="document"> + + +<p>Code listings in web pages are often a bit of a pain to use. Usually, they don't wrap on small screens. Also, copy-pasting code from a code listing often copies the line numbers along with the code. Finally, many implementations use heavyweight HTML and/or javascript, making them slow to render. For this blog, I wrote a little CSS hack that renders nice, wrapping code blocks with line continuation markers in plain CSS without any JS.</p> +</div> + <a href="http://jaseg.de/blog/css-only-code-blocks/">Read more</a> + </div> +</div> + + <div class="card"><h3><a href="/blog/jupyterlab-notebook-file-oneliner/">Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</a></h3><strong>2025-06-29</strong> <div class="summary"> @@ -220,19 +233,6 @@ set up your UART to talk to an external hardware USB to serial converter is a ma </div> - <div class="card"><h3><a href="/blog/multichannel-led-driver/">32-Channel LED tape driver</a></h3><strong>2018-05-02</strong> - - <div class="summary"> - <div class="document"> - - -<p>Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. For this installation, I made a 32-channel LED driver that achieves high dynamic range on all 32 channels using a cheap microcontroller by using Binary Code Modulation.</p> -</div> - <a href="http://jaseg.de/blog/multichannel-led-driver/">Read more</a> - </div> -</div> - - <div class="pagination-links"> @@ -245,11 +245,26 @@ set up your UART to talk to an external hardware USB to serial converter is a ma / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> @@ -7,9 +7,16 @@ <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> - <lastBuildDate>Sun, 29 Jun 2025 23:42:00 +0100</lastBuildDate> + <lastBuildDate>Wed, 23 Jul 2025 23:42:00 +0100</lastBuildDate> <atom:link href="http://jaseg.de/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Code listings with nice line wrapping and line numbers from plain CSS</title> + <link>http://jaseg.de/blog/css-only-code-blocks/</link> + <pubDate>Wed, 23 Jul 2025 23:42:00 +0100</pubDate> + <guid>http://jaseg.de/blog/css-only-code-blocks/</guid> + <description><div class="document">


<p>Code listings in web pages are often a bit of a pain to use. Usually, they don't wrap on small screens. Also, copy-pasting code from a code listing often copies the line numbers along with the code. Finally, many implementations use heavyweight HTML and/or javascript, making them slow to render. For this blog, I wrote a little CSS hack that renders nice, wrapping code blocks with line continuation markers in plain CSS without any JS.</p>
</div></description> + </item> + <item> <title>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</title> <link>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</link> <pubDate>Sun, 29 Jun 2025 23:42:00 +0100</pubDate> diff --git a/pagefind/fragment/unknown_1ced448.pf_fragment b/pagefind/fragment/unknown_1ced448.pf_fragment Binary files differdeleted file mode 100644 index e86b6db..0000000 --- a/pagefind/fragment/unknown_1ced448.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_c2c6ec9.pf_fragment b/pagefind/fragment/unknown_27b5ed4.pf_fragment Binary files differindex 08c09f8..1ba5918 100644 --- a/pagefind/fragment/unknown_c2c6ec9.pf_fragment +++ b/pagefind/fragment/unknown_27b5ed4.pf_fragment diff --git a/pagefind/fragment/unknown_26a6593.pf_fragment b/pagefind/fragment/unknown_37a096b.pf_fragment Binary files differindex a356c24..a9bf635 100644 --- a/pagefind/fragment/unknown_26a6593.pf_fragment +++ b/pagefind/fragment/unknown_37a096b.pf_fragment diff --git a/pagefind/fragment/unknown_684b5ee.pf_fragment b/pagefind/fragment/unknown_3babf22.pf_fragment Binary files differindex 278d844..2b82526 100644 --- a/pagefind/fragment/unknown_684b5ee.pf_fragment +++ b/pagefind/fragment/unknown_3babf22.pf_fragment diff --git a/pagefind/fragment/unknown_7aa9d62.pf_fragment b/pagefind/fragment/unknown_59a1d23.pf_fragment Binary files differindex e87ac51..59c5342 100644 --- a/pagefind/fragment/unknown_7aa9d62.pf_fragment +++ b/pagefind/fragment/unknown_59a1d23.pf_fragment diff --git a/pagefind/fragment/unknown_a118647.pf_fragment b/pagefind/fragment/unknown_a118647.pf_fragment Binary files differdeleted file mode 100644 index c51f0b3..0000000 --- a/pagefind/fragment/unknown_a118647.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_b13982d.pf_fragment b/pagefind/fragment/unknown_b13982d.pf_fragment Binary files differnew file mode 100644 index 0000000..8fe21a1 --- /dev/null +++ b/pagefind/fragment/unknown_b13982d.pf_fragment diff --git a/pagefind/fragment/unknown_6aca334.pf_fragment b/pagefind/fragment/unknown_bbd6440.pf_fragment Binary files differindex 5945f47..5335c06 100644 --- a/pagefind/fragment/unknown_6aca334.pf_fragment +++ b/pagefind/fragment/unknown_bbd6440.pf_fragment diff --git a/pagefind/fragment/unknown_83ecd38.pf_fragment b/pagefind/fragment/unknown_c663c09.pf_fragment Binary files differindex e7f2639..391cf4e 100644 --- a/pagefind/fragment/unknown_83ecd38.pf_fragment +++ b/pagefind/fragment/unknown_c663c09.pf_fragment diff --git a/pagefind/fragment/unknown_abc2923.pf_fragment b/pagefind/fragment/unknown_cb8e74a.pf_fragment Binary files differindex c6d3d46..9e7f382 100644 --- a/pagefind/fragment/unknown_abc2923.pf_fragment +++ b/pagefind/fragment/unknown_cb8e74a.pf_fragment diff --git a/pagefind/fragment/unknown_d6a3d77.pf_fragment b/pagefind/fragment/unknown_d6a3d77.pf_fragment Binary files differnew file mode 100644 index 0000000..c584aca --- /dev/null +++ b/pagefind/fragment/unknown_d6a3d77.pf_fragment diff --git a/pagefind/fragment/unknown_e377283.pf_fragment b/pagefind/fragment/unknown_e377283.pf_fragment Binary files differnew file mode 100644 index 0000000..f8892b9 --- /dev/null +++ b/pagefind/fragment/unknown_e377283.pf_fragment diff --git a/pagefind/fragment/unknown_62c6a43.pf_fragment b/pagefind/fragment/unknown_f25260d.pf_fragment Binary files differindex 587431b..8a6acd1 100644 --- a/pagefind/fragment/unknown_62c6a43.pf_fragment +++ b/pagefind/fragment/unknown_f25260d.pf_fragment diff --git a/pagefind/fragment/unknown_f8b69c4.pf_fragment b/pagefind/fragment/unknown_f8b69c4.pf_fragment Binary files differnew file mode 100644 index 0000000..f423185 --- /dev/null +++ b/pagefind/fragment/unknown_f8b69c4.pf_fragment diff --git a/pagefind/fragment/unknown_fd69f69.pf_fragment b/pagefind/fragment/unknown_fd69f69.pf_fragment Binary files differdeleted file mode 100644 index 8e999f6..0000000 --- a/pagefind/fragment/unknown_fd69f69.pf_fragment +++ /dev/null diff --git a/pagefind/index/unknown_1ab1f95.pf_index b/pagefind/index/unknown_1ab1f95.pf_index Binary files differdeleted file mode 100644 index 2f2e7d2..0000000 --- a/pagefind/index/unknown_1ab1f95.pf_index +++ /dev/null diff --git a/pagefind/index/unknown_36d0367.pf_index b/pagefind/index/unknown_36d0367.pf_index Binary files differnew file mode 100644 index 0000000..625667b --- /dev/null +++ b/pagefind/index/unknown_36d0367.pf_index diff --git a/pagefind/index/unknown_7915e0e.pf_index b/pagefind/index/unknown_7915e0e.pf_index Binary files differnew file mode 100644 index 0000000..737ffd6 --- /dev/null +++ b/pagefind/index/unknown_7915e0e.pf_index diff --git a/pagefind/index/unknown_a291bd2.pf_index b/pagefind/index/unknown_a291bd2.pf_index Binary files differdeleted file mode 100644 index 41a4927..0000000 --- a/pagefind/index/unknown_a291bd2.pf_index +++ /dev/null diff --git a/pagefind/index/unknown_cda182c.pf_index b/pagefind/index/unknown_cda182c.pf_index Binary files differnew file mode 100644 index 0000000..f9a58cf --- /dev/null +++ b/pagefind/index/unknown_cda182c.pf_index diff --git a/pagefind/index/unknown_d2a4f9b.pf_index b/pagefind/index/unknown_d2a4f9b.pf_index Binary files differdeleted file mode 100644 index c9d5ddc..0000000 --- a/pagefind/index/unknown_d2a4f9b.pf_index +++ /dev/null diff --git a/pagefind/pagefind-entry.json b/pagefind/pagefind-entry.json index 6ef0a4a..c6c891a 100644 --- a/pagefind/pagefind-entry.json +++ b/pagefind/pagefind-entry.json @@ -1 +1 @@ -{"version":"1.0.4","languages":{"unknown":{"hash":"unknown_9de1ab71d5de9a2","wasm":null,"page_count":21}}}
\ No newline at end of file +{"version":"1.0.4","languages":{"unknown":{"hash":"unknown_7227ffb121ad6b6","wasm":null,"page_count":22}}}
\ No newline at end of file diff --git a/pagefind/pagefind.unknown_7227ffb121ad6b6.pf_meta b/pagefind/pagefind.unknown_7227ffb121ad6b6.pf_meta Binary files differnew file mode 100644 index 0000000..fd2fe24 --- /dev/null +++ b/pagefind/pagefind.unknown_7227ffb121ad6b6.pf_meta diff --git a/pagefind/pagefind.unknown_9de1ab71d5de9a2.pf_meta b/pagefind/pagefind.unknown_9de1ab71d5de9a2.pf_meta Binary files differdeleted file mode 100644 index 6420535..0000000 --- a/pagefind/pagefind.unknown_9de1ab71d5de9a2.pf_meta +++ /dev/null diff --git a/posts/index.html b/posts/index.html index 835af3d..9c21ce9 100644 --- a/posts/index.html +++ b/posts/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -45,11 +45,26 @@ / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/8seg/index.html b/projects/8seg/index.html index 7f165c9..0887902 100644 --- a/projects/8seg/index.html +++ b/projects/8seg/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -59,11 +59,26 @@ variety of spaces, conforming to the space's size and shape through bending and / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/gerbolyze/index.html b/projects/gerbolyze/index.html index e30023f..a4b13c1 100644 --- a/projects/gerbolyze/index.html +++ b/projects/gerbolyze/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -646,11 +646,26 @@ avoid that so the default license is still AGPL.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/gerbonara/index.html b/projects/gerbonara/index.html index 798895c..2326da9 100644 --- a/projects/gerbonara/index.html +++ b/projects/gerbonara/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -161,11 +161,26 @@ some non-standard naming convention.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/index.html b/projects/index.html index f64b0af..e4a6f1f 100644 --- a/projects/index.html +++ b/projects/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -193,11 +193,26 @@ open an issue on the project's issue tracker.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/kimesh/index.html b/projects/kimesh/index.html index cac79b2..9c8e318 100644 --- a/projects/kimesh/index.html +++ b/projects/kimesh/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -100,11 +100,26 @@ higher-numbered pins are.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/lolcat-c/index.html b/projects/lolcat-c/index.html index 175c544..7397c2f 100644 --- a/projects/lolcat-c/index.html +++ b/projects/lolcat-c/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -128,11 +128,26 @@ / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/python-mpv/index.html b/projects/python-mpv/index.html index 7141d48..a692d13 100644 --- a/projects/python-mpv/index.html +++ b/projects/python-mpv/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -404,11 +404,26 @@ For details, see <a class="reference external" href="https://github.com/mpv-play / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/svg-flatten/index.html b/projects/svg-flatten/index.html index 2c09f41..76a21d2 100644 --- a/projects/svg-flatten/index.html +++ b/projects/svg-flatten/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -59,11 +59,26 @@ gerbolyze.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/projects/wsdiff/index.html b/projects/wsdiff/index.html index 812a0f3..ad0467b 100644 --- a/projects/wsdiff/index.html +++ b/projects/wsdiff/index.html @@ -8,7 +8,7 @@ <meta name="color-scheme" content="dark light"> <link rel="stylesheet" href="/style.css"> - <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/woff2" crossorigin /> + <link rel="preload" href="/fonts/roboto_slab/RobotoSlab-VariableFont_wght.ttf" as="font" type="font/ttf" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/nyght-serif-main/fonts/WEB/NyghtSerif-BoldItalic.woff2" as="font" type="font/woff2" crossorigin /> @@ -101,11 +101,26 @@ on available screen space.</p> / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> -<script src="/pagefind/pagefind-ui.js" defer></script> +<script type="text/javascript" src="/pagefind/pagefind-ui.js" defer></script> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({element: "#search", showSubResults: true}); }); </script> + <script type="speculationrules"> + { + "prerender": [ + { + "source": "document", + "where": { + "and": [ + {"href_matches": "/*"} + ] + }, + "eagerness": "moderate" + } + ] + } + </script> </body> </html> diff --git a/sitemap.xml b/sitemap.xml index 7cfe3cf..c0965ab 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -3,12 +3,15 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url> <loc>http://jaseg.de/blog/</loc> - <lastmod>2025-06-29T23:42:00+01:00</lastmod> + <lastmod>2025-07-23T23:42:00+01:00</lastmod> </url><url> - <loc>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</loc> - <lastmod>2025-06-29T23:42:00+01:00</lastmod> + <loc>http://jaseg.de/blog/css-only-code-blocks/</loc> + <lastmod>2025-07-23T23:42:00+01:00</lastmod> </url><url> <loc>http://jaseg.de/</loc> + <lastmod>2025-07-23T23:42:00+01:00</lastmod> + </url><url> + <loc>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</loc> <lastmod>2025-06-29T23:42:00+01:00</lastmod> </url><url> <loc>http://jaseg.de/blog/8seg/</loc> @@ -267,6 +267,14 @@ h3 { font-weight: 700; } +/* Prevent long literals from breaking the page layout's width */ +span.pre { + white-space: pre-wrap; + word-wrap: break-word; + overflow-x: auto; + overflow-wrap: anywhere; +} + body > header { z-index: 1; margin-top: 100px; @@ -471,9 +479,14 @@ img:hover { filter: none; } +/*****************************************************/ +/* Code block formatting / syntax highlighting rules */ +/*****************************************************/ + .code { font-family: "Fira Code"; font-size: 13px; + text-align: left; /* Override default content "justify" alignment */ white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; @@ -495,6 +508,7 @@ img:hover { white-space: pre-wrap; } +/* We render line numbers in CSS! */ .code > .lineno { counter-increment: lineno; word-break: keep-all; @@ -509,6 +523,7 @@ img:hover { align-self: stretch; } +/* We also handle line continuation markers in CSS. */ .code > .lineno::after { position: absolute; right: 5px; @@ -517,6 +532,7 @@ img:hover { color: var(--c-text-muted); } +/* Insert the actual line number */ .code > .lineno::before { content: counter(lineno); } @@ -525,6 +541,64 @@ img:hover { counter-reset: lineno; } +/* Token styling rules for syntax highlighting */ +.code .hll {} +.code .c { color: var(--c-text); font-weight: 400 } /* Comment */ +.code .n { color: var(--c-text); font-weight: 400 } /* Name */ +.code .o { color: var(--c-text); font-weight: 400 } /* Operator */ +.code .cm { color: var(--c-text); font-weight: 400 } /* Comment.Multiline */ +.code .cp { color: var(--c-text); font-weight: 400 } /* Comment.Preproc */ +.code .c1 { color: var(--c-text); font-weight: 400 } /* Comment.Single */ +.code .cs { color: var(--c-text); font-weight: 400 } /* Comment.Special */ +.code .nd { color: var(--c-text); font-weight: 400 } /* Name.Decorator */ +.code .nn { color: var(--c-text); font-weight: 400 } /* Name.Namespace */ +.code .vc { color: var(--c-text); font-weight: 400 } /* Name.Variable.Class */ +.code .vg { color: var(--c-text); font-weight: 400 } /* Name.Variable.Global */ +.code .vi { color: var(--c-text); font-weight: 400 } /* Name.Variable.Instance */ +.code .err { color: var(--c-text-highlight); font-weight: 500 } /* Error */ +.code .k { color: var(--c-text-highlight); font-weight: 500 } /* Keyword */ +.code .l { color: var(--c-text-highlight); font-weight: 500 } /* Literal */ +.code .kc { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Constant */ +.code .kd { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Declaration */ +.code .kn { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Namespace */ +.code .kp { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Pseudo */ +.code .kr { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Reserved */ +.code .kt { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Type */ +.code .na { color: var(--c-text-highlight); font-weight: 500 } /* Name.Attribute */ +.code .nb { color: var(--c-text-highlight); font-weight: 500 } /* Name.Builtin */ +.code .nc { color: var(--c-text-highlight); font-weight: 500 } /* Name.Class */ +.code .no { color: var(--c-text-highlight); font-weight: 500 } /* Name.Constant */ +.code .ni { color: var(--c-text-highlight); font-weight: 500 } /* Name.Entity */ +.code .ne { color: var(--c-text-highlight); font-weight: 500 } /* Name.Exception */ +.code .nf { color: var(--c-text-highlight); font-weight: 500 } /* Name.Function */ +.code .nl { color: var(--c-text-highlight); font-weight: 500 } /* Name.Label */ +.code .nx { color: var(--c-text-highlight); font-weight: 500 } /* Name.Other */ +.code .py { color: var(--c-text-highlight); font-weight: 500 } /* Name.Property */ +.code .nt { color: var(--c-text-highlight); font-weight: 500 } /* Name.Tag */ +.code .nv { color: var(--c-text-highlight); font-weight: 500 } /* Name.Variable */ +.code .ow { color: var(--c-text-highlight); font-weight: 500 } /* Operator.Word */ +.code .bp { color: var(--c-text-highlight); font-weight: 500 } /* Name.Builtin.Pseudo */ +.code .ld { color: var(--c-text); font-weight: 600 } /* Literal.Date */ +.code .m { color: var(--c-text); font-weight: 600 } /* Literal.Number */ +.code .s { color: var(--c-text); font-weight: 600 } /* Literal.String */ +.code .mb { color: var(--c-text); font-weight: 600 } /* Literal.Number.Bin */ +.code .mf { color: var(--c-text); font-weight: 600 } /* Literal.Number.Float */ +.code .mh { color: var(--c-text); font-weight: 600 } /* Literal.Number.Hex */ +.code .mi { color: var(--c-text); font-weight: 600 } /* Literal.Number.Integer */ +.code .mo { color: var(--c-text); font-weight: 600 } /* Literal.Number.Oct */ +.code .sb { color: var(--c-text); font-weight: 600 } /* Literal.String.Backtick */ +.code .sc { color: var(--c-text); font-weight: 600 } /* Literal.String.Char */ +.code .sd { color: var(--c-text); font-weight: 600 } /* Literal.String.Doc */ +.code .s2 { color: var(--c-text); font-weight: 600 } /* Literal.String.Double */ +.code .se { color: var(--c-text); font-weight: 600 } /* Literal.String.Escape */ +.code .sh { color: var(--c-text); font-weight: 600 } /* Literal.String.Heredoc */ +.code .si { color: var(--c-text); font-weight: 600 } /* Literal.String.Interpol */ +.code .sx { color: var(--c-text); font-weight: 600 } /* Literal.String.Other */ +.code .sr { color: var(--c-text); font-weight: 600 } /* Literal.String.Regex */ +.code .s1 { color: var(--c-text); font-weight: 600 } /* Literal.String.Single */ +.code .ss { color: var(--c-text); font-weight: 600 } /* Literal.String.Symbol */ +.code .il { color: var(--c-text); font-weight: 600 } /* Literal.Number.Integer.Long */ + footer { margin-top: 30px; align-self: center; @@ -533,63 +607,6 @@ footer { padding: 5px 25px 5px 25px; } -body .hll {} -body .c { color: var(--c-text); font-weight: 400 } /* Comment */ -body .n { color: var(--c-text); font-weight: 400 } /* Name */ -body .o { color: var(--c-text); font-weight: 400 } /* Operator */ -body .cm { color: var(--c-text); font-weight: 400 } /* Comment.Multiline */ -body .cp { color: var(--c-text); font-weight: 400 } /* Comment.Preproc */ -body .c1 { color: var(--c-text); font-weight: 400 } /* Comment.Single */ -body .cs { color: var(--c-text); font-weight: 400 } /* Comment.Special */ -body .nd { color: var(--c-text); font-weight: 400 } /* Name.Decorator */ -body .nn { color: var(--c-text); font-weight: 400 } /* Name.Namespace */ -body .vc { color: var(--c-text); font-weight: 400 } /* Name.Variable.Class */ -body .vg { color: var(--c-text); font-weight: 400 } /* Name.Variable.Global */ -body .vi { color: var(--c-text); font-weight: 400 } /* Name.Variable.Instance */ -body .err { color: var(--c-text-highlight); font-weight: 500 } /* Error */ -body .k { color: var(--c-text-highlight); font-weight: 500 } /* Keyword */ -body .l { color: var(--c-text-highlight); font-weight: 500 } /* Literal */ -body .kc { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Constant */ -body .kd { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Declaration */ -body .kn { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Namespace */ -body .kp { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Pseudo */ -body .kr { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Reserved */ -body .kt { color: var(--c-text-highlight); font-weight: 500 } /* Keyword.Type */ -body .na { color: var(--c-text-highlight); font-weight: 500 } /* Name.Attribute */ -body .nb { color: var(--c-text-highlight); font-weight: 500 } /* Name.Builtin */ -body .nc { color: var(--c-text-highlight); font-weight: 500 } /* Name.Class */ -body .no { color: var(--c-text-highlight); font-weight: 500 } /* Name.Constant */ -body .ni { color: var(--c-text-highlight); font-weight: 500 } /* Name.Entity */ -body .ne { color: var(--c-text-highlight); font-weight: 500 } /* Name.Exception */ -body .nf { color: var(--c-text-highlight); font-weight: 500 } /* Name.Function */ -body .nl { color: var(--c-text-highlight); font-weight: 500 } /* Name.Label */ -body .nx { color: var(--c-text-highlight); font-weight: 500 } /* Name.Other */ -body .py { color: var(--c-text-highlight); font-weight: 500 } /* Name.Property */ -body .nt { color: var(--c-text-highlight); font-weight: 500 } /* Name.Tag */ -body .nv { color: var(--c-text-highlight); font-weight: 500 } /* Name.Variable */ -body .ow { color: var(--c-text-highlight); font-weight: 500 } /* Operator.Word */ -body .bp { color: var(--c-text-highlight); font-weight: 500 } /* Name.Builtin.Pseudo */ -body .ld { color: var(--c-text); font-weight: 600 } /* Literal.Date */ -body .m { color: var(--c-text); font-weight: 600 } /* Literal.Number */ -body .s { color: var(--c-text); font-weight: 600 } /* Literal.String */ -body .mb { color: var(--c-text); font-weight: 600 } /* Literal.Number.Bin */ -body .mf { color: var(--c-text); font-weight: 600 } /* Literal.Number.Float */ -body .mh { color: var(--c-text); font-weight: 600 } /* Literal.Number.Hex */ -body .mi { color: var(--c-text); font-weight: 600 } /* Literal.Number.Integer */ -body .mo { color: var(--c-text); font-weight: 600 } /* Literal.Number.Oct */ -body .sb { color: var(--c-text); font-weight: 600 } /* Literal.String.Backtick */ -body .sc { color: var(--c-text); font-weight: 600 } /* Literal.String.Char */ -body .sd { color: var(--c-text); font-weight: 600 } /* Literal.String.Doc */ -body .s2 { color: var(--c-text); font-weight: 600 } /* Literal.String.Double */ -body .se { color: var(--c-text); font-weight: 600 } /* Literal.String.Escape */ -body .sh { color: var(--c-text); font-weight: 600 } /* Literal.String.Heredoc */ -body .si { color: var(--c-text); font-weight: 600 } /* Literal.String.Interpol */ -body .sx { color: var(--c-text); font-weight: 600 } /* Literal.String.Other */ -body .sr { color: var(--c-text); font-weight: 600 } /* Literal.String.Regex */ -body .s1 { color: var(--c-text); font-weight: 600 } /* Literal.String.Single */ -body .ss { color: var(--c-text); font-weight: 600 } /* Literal.String.Symbol */ -body .il { color: var(--c-text); font-weight: 600 } /* Literal.Number.Integer.Long */ - @media (max-width: 40em) { nav > div { flex-grow: 1; |