<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>html on S Anand</title>
    <link>https://www.s-anand.net/blog/tag/html/</link>
    <description>Recent content in html on S Anand</description>
    <generator>Hugo -- 0.164.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 05 Jun 2026 17:14:17 +0800</lastBuildDate>
    <atom:link href="https://www.s-anand.net/blog/tag/html/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>When the prompt is longer than the code</title>
      <link>https://www.s-anand.net/blog/when-the-prompt-is-longer-than-the-code/</link>
      <pubDate>Fri, 05 Jun 2026 17:14:17 +0800</pubDate>
      <guid>https://www.s-anand.net/blog/when-the-prompt-is-longer-than-the-code/</guid>
      <description>&lt;p&gt;I used &lt;a href=&#34;https://pi.dev/&#34;&gt;pi&lt;/a&gt; to create a compact home page for &lt;a href=&#34;https://media.s-anand.net/&#34;&gt;media.s-anand.net&lt;/a&gt; using these prompts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Create &lt;code&gt;index.html&lt;/code&gt; - a simple, elegant page that says that this page (media.s-anand.net) serves large media files for &lt;a href=&#34;https://www.s-anand.net/&#34;&gt;Anand&lt;/a&gt; - that&amp;rsquo;s where they should look instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;hellip; followed by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Skip the part that says &amp;ldquo;Please visit &amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;hellip; then:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Shorten index.html to just 2-3 elegant rules of CSS. I want it MUCH smaller and simpler.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;hellip; and finally:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Center vertically and horizontally.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These prompts ended up being larger than the 471-byte &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;html&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;lang&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;viewport&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;width=device-width, initial-scale=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;media.s-anand.net&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;min-height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;vh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;grid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;place-content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;center&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;margin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;font&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.25&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;rem&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system-ui&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;sans-serif&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;h1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;font-size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;clamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;rem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;vw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;rem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;h1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;media.s-anand.net&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;h1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;This domain serves large media files for &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://www.s-anand.net/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;Anand&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;.&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Not that this matters, because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I didn&amp;rsquo;t know what I wanted and having an AI coding agent generate a first draft helped with starting trouble and ideation.&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t know how to center on the screen and this did it for me.&lt;/li&gt;
&lt;li&gt;I am practicing the skill that matters - reviewing - and not the skill AI is taking over - writing code.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    <item>
      <title>Things I Learned - 19 Oct 2025</title>
      <link>https://www.s-anand.net/blog/things-i-learned-19-oct-2025/</link>
      <pubDate>Sun, 19 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/things-i-learned-19-oct-2025/</guid>
      <description>&lt;p&gt;This week, I learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⭐ &amp;ldquo;&amp;hellip; most engineers don’t have public commits. Senior engineers at large tech companies don’t work on open-source projects for the most part.&amp;rdquo; &lt;a href=&#34;https://interviewing.io/blog/why-ai-cant-do-hiring&#34;&gt;Why AI Can&amp;rsquo;t Do Hiring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cloudflare&amp;rsquo;s &lt;a href=&#34;https://sandbox.cloudflare.com/&#34;&gt;Sandbox&lt;/a&gt; feature in their Workers looks impressive. It supports streaming, web access to the container, and long-running processes. So we can spawn off a task and have it run a server (at least for a while) or a scraper.&lt;/li&gt;
&lt;li&gt;Gemini API has a Google Maps tool that it can refer to - like Google Search. &lt;a href=&#34;https://ai.google.dev/gemini-api/docs/maps-grounding&#34;&gt;Maps Grounding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Earlier we needed humans to label data for RLHF. Now we don&amp;rsquo;t since AI can simulate it. This is a pattern. Once AI learns from a human, that human skill can be automated. &lt;a href=&#34;https://youtu.be/RqWIvvv3SnQ&#34;&gt;How GPT-5 Thinks — OpenAI VP of Research Jerry Tworek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/output&#34;&gt;&lt;code&gt;&amp;lt;output&amp;gt;&lt;/code&gt;&lt;/a&gt; element has a &lt;code&gt;for=&lt;/code&gt; attribute indicating which &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements it is linked to and a &lt;code&gt;form=&lt;/code&gt; attribute indicating which form it belongs to. This &lt;a href=&#34;https://denodell.com/blog/html-best-kept-secret-output-tag&#34;&gt;works well with screen readers&lt;/a&gt;. A good reason to use it more. &lt;a href=&#34;https://rud.is/drop/output.html&#34;&gt;Examples&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Meta built a &lt;a href=&#34;https://ai.meta.com/research/publications/cwm-an-open-weights-llm-for-research-on-code-generation-with-world-models/&#34;&gt;Code World Model&lt;/a&gt;. Basically an LLM that acts like a Python interpreter!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt install moreutils&lt;/code&gt; installs a set of useful packages:
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;chronic&lt;/strong&gt;. Runs a command quietly (suppressing output) unless it fails — good for cron jobs where you only want noise on errors. &lt;code&gt;chronic backup.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;combine&lt;/strong&gt;. Combines lines from two input streams/files using boolean operations (AND, OR, XOR). &lt;code&gt;combine AND fileA fileB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;errno&lt;/strong&gt;. Look up symbolic names, numeric codes, and descriptions for standard errno values. &lt;code&gt;errno -l; errno ENOENT; errno 2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ifdata&lt;/strong&gt;. Query network interface properties (IP, byte counts, errors) in a script-friendly format. &lt;code&gt;ifdata -sip eth0; ifdata -bops eth0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ifne&lt;/strong&gt;. Run a command only if stdin is not empty, passing the input through. &lt;code&gt;find . -name core | ifne mail -s &amp;quot;Core files found&amp;quot; admin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;isutf8&lt;/strong&gt;. Check whether a file or stdin is valid UTF-8. &lt;code&gt;isutf8 somefile.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lckdo&lt;/strong&gt;. Run a command while holding an exclusive lock to prevent concurrent runs. &lt;code&gt;lckdo /var/run/mylockfile.cmd myscript.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mispipe&lt;/strong&gt;. Pipe two commands, but return the exit status of the first one (useful in pipelines). &lt;code&gt;cmd1 mispipe cmd2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;parallel&lt;/strong&gt;. Run multiple commands in parallel, reading them from stdin or arguments. &lt;code&gt;parallel &amp;lt; jobs.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pee&lt;/strong&gt;. Like &lt;code&gt;tee&lt;/code&gt;, but sends stdin to multiple commands in parallel. &lt;code&gt;echo &amp;quot;foo&amp;quot; | pee cmd1 cmd2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;sponge&lt;/strong&gt;. Soak up all input before writing to output — enables in-place edits safely. &lt;code&gt;sort file | sponge file&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;ts&lt;/strong&gt;. Prefix each input line with a timestamp. &lt;code&gt;tail -f logfile | ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vidir&lt;/strong&gt;. Edit a directory listing in your editor to rename, move, or delete files in bulk. &lt;code&gt;vidir ~/myfolder&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vipe&lt;/strong&gt;. Insert a text editor into a pipeline to manually edit streamed input before output. &lt;code&gt;cat file | vipe | wc -l&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;zrun&lt;/strong&gt;. Transparently decompress compressed files before passing them to a command. &lt;code&gt;zrun cat file.gz&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Despite 20 years of SVG experience, I learnt new things from &lt;a href=&#34;https://www.joshwcomeau.com/svg/friendly-introduction-to-svg/&#34;&gt;A Friendly Introduction to SVG&lt;/a&gt; and &lt;a href=&#34;https://www.joshwcomeau.com/svg/interactive-guide-to-paths/&#34;&gt;A Friendly Introduction to Paths&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Setting a &lt;code&gt;&amp;lt;rect&amp;gt;&lt;/code&gt; width/height or a &lt;code&gt;&amp;lt;circle&amp;gt;&lt;/code&gt; radius to zero &lt;em&gt;removes&lt;/em&gt; the element instead of drawing a point.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s no option to draw the stroke on the inside or outside of a shape/path. Only the center.&lt;/li&gt;
&lt;li&gt;You can override a path&amp;rsquo;s &lt;code&gt;pathLength&lt;/code&gt; attribute to create a new internal scale for its length. It&amp;rsquo;s unclear where I can use this.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; arcs have this syntax: &lt;code&gt;A [rx],[ry] [rotation] [large-arc-flag] [sweep-flag] [end-x],[end-y]&lt;/code&gt;. SVG first fits an ellipse to these parameters and then draws the arc.
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;rx&lt;/code&gt; and &lt;code&gt;ry&lt;/code&gt; of an arc is too small to connect the points, the SVG spec scales up &lt;code&gt;rx&lt;/code&gt; and &lt;code&gt;ry&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[large-arc-flag]=1&lt;/code&gt; literally uses the larger arc of the fitting ellipse. This is less common.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[sweep-flag]=1&lt;/code&gt; its the ellipse to make the connecting arc go clockwise. &lt;code&gt;0&lt;/code&gt; is anti-clockwise.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[rotation]&lt;/code&gt; is rarely used because we usually draw arcs and &lt;em&gt;then&lt;/em&gt; rotate them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stroke-linejoin&lt;/code&gt; automatically flips from &lt;code&gt;miter&lt;/code&gt; (sharp) to &lt;code&gt;bevel&lt;/code&gt; (cut) if the sharp edge protrudes too long (e.g. small angles). Increasing &lt;code&gt;stroke-miterlimit&lt;/code&gt; increases the cutoff (default: 4)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;⭐ Always include a thoughtful gallery of examples with tools / libraries. This does more than showing what a tool can do.
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s use-case / domain transfer: showing &lt;strong&gt;what&lt;/strong&gt; it&amp;rsquo;s useful for in real life - opening ideas, suggesting workflows.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s style transfer: showing &lt;strong&gt;how&lt;/strong&gt; to use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;⭐ Here&amp;rsquo;s what expert AI coders increasingly focus on. &lt;a href=&#34;https://ashtom.github.io/developers-reinvented&#34;&gt;Thomas Dohmke&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Delegation: context engineering agents for success; parallelizing.&lt;/li&gt;
&lt;li&gt;Verification: efficiently reviewing and testing code/output; setting stop-points.&lt;/li&gt;
&lt;li&gt;Expanding scope: instead of time saved as the metric.&lt;/li&gt;
&lt;li&gt;Education: teaching AI-based coding, debugging, reviewing/testing.&lt;/li&gt;
&lt;li&gt;Product management: combining requirements + UI design + architecture + engineering + deployment.&lt;/li&gt;
&lt;li&gt;Cross-discipline: blending code with design, governance, finance, marketing, &amp;hellip; (&amp;ldquo;computational creators&amp;rdquo;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Notes from Taylor&amp;rsquo;s &lt;a href=&#34;https://heytaylor.dev/posts/202510052056_how-i-m-using-coding-agents-october-2025/&#34;&gt;How I&amp;rsquo;m using coding agents: October 2025&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Left monitor: 2-4 desktops (e.g. work, side-project). Right monitor: things I always want available&lt;/li&gt;
&lt;li&gt;Plan next task while first executes.&lt;/li&gt;
&lt;li&gt;Use plan mode to write to a plan file.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t start big tasks if you have meetings scheduled soon.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Recent open source package hack methods seem to work more because of people/process than systems (&lt;a href=&#34;https://words.filippo.io/compromise-survey/&#34;&gt;Filippo&lt;/a&gt;):
&lt;ol&gt;
&lt;li&gt;Phishing the author&lt;/li&gt;
&lt;li&gt;Pull requests running unsafe code in CI&lt;/li&gt;
&lt;li&gt;Taking over expired domain / user ID&lt;/li&gt;
&lt;li&gt;Stealing long-lived tokens&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uv run --python 3.14 --isolated --with-editable &#39;.[test]&#39; pytest&lt;/code&gt; runs pytest on a local project with a specific Python version. &lt;a href=&#34;https://til.simonwillison.net/python/uv-tests&#34;&gt;Simon Willison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Notes from the &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit&#34;&gt;State of AI Report 2025&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;Reasoning models are more fragile. Irrelevant phrases make reasoning models spend &lt;em&gt;FAR&lt;/em&gt; more tokens and get wrong answers &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g36532dfa542_1_5&#34;&gt;#21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AI systems are able to teach experts new concepts &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38724ed57c0_1_0#slide=id.g38724ed57c0_1_0&#34;&gt;#41&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;An environment providing feedback / rewards enables continuous learning &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g379a362bd85_0_132#slide=id.g379a362bd85_0_132&#34;&gt;#52&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;E.g. Multi-robot chemical labs at U.Liverpool and NCSU &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g37cf129d69d_2_44#slide=id.g37cf129d69d_2_44&#34;&gt;#60&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RLHF has a fundamental flaw: humans reward sycophancy &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g34531ae1448_0_79#slide=id.g34531ae1448_0_79&#34;&gt;#71&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We can read what people are typing from brain signals outside the skull &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g377f1927a71_0_0#slide=id.g377f1927a71_0_0&#34;&gt;#73&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Model intelligence-to-price ratio doubles every ~6 months &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38918b607ca_0_426#slide=id.g38918b607ca_0_426&#34;&gt;#94&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The AI companies&amp;rsquo; valuations are also roughly doubling every ~6 months &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38918b607ca_0_750#slide=id.g38918b607ca_0_750&#34;&gt;#181&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI is offering Governments giga-watt campuses to run OpenAI models for citizens &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38918b607ca_0_199#slide=id.g38918b607ca_0_199&#34;&gt;#122&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A 1GW clusters costs $50bn capex and $11bn per annum &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g3668e08c71a_0_66#slide=id.g3668e08c71a_0_66&#34;&gt;#130&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;China has added ~10X the energy capacity as the US in 2024 &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g34898aa15b3_0_0#slide=id.g34898aa15b3_0_0&#34;&gt;#146&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NVIDIA challengers are still far away &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g3747fb01779_1_100#slide=id.g3747fb01779_1_100&#34;&gt;#161&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LLMs can &amp;ldquo;read between the lines&amp;rdquo; even if training data is censored &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38409c5a29e_1_1097#slide=id.g38409c5a29e_1_1097&#34;&gt;#268&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LLMs can pass information via hidden signals &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g379453733bb_0_59#slide=id.g379453733bb_0_59&#34;&gt;#270&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Prediction: A major retailer reports &amp;gt;5% of online sales from agentic checkout. AI agent advertising spend hits $5B. &lt;a href=&#34;https://docs.google.com/presentation/d/1xiLl0VdrlNMAei8pmaX4ojIOfej6lhvZbOIK7Z6C-Go/edit?slide=id.g38918b607ca_4_400#slide=id.g38918b607ca_4_400&#34;&gt;#304&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://cdn.openai.com/pdf/ae250928-4029-4f26-9e23-afac1fcee14c/staying-ahead-in-the-age-of-ai.pdf&#34;&gt;OpenAI&amp;rsquo;s leadership guide&lt;/a&gt; says:
&lt;ul&gt;
&lt;li&gt;Align
&lt;ul&gt;
&lt;li&gt;Explain &lt;strong&gt;WHY&lt;/strong&gt; AI thoughtfully.&lt;/li&gt;
&lt;li&gt;Set a goal, e.g. everyone uses ChatGPT 20 times/day (Moderna).&lt;/li&gt;
&lt;li&gt;Use it yourself. Show how.&lt;/li&gt;
&lt;li&gt;Have &lt;strong&gt;business&lt;/strong&gt; leaders run AI sessions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Activate
&lt;ul&gt;
&lt;li&gt;Launch an AI skills proram&lt;/li&gt;
&lt;li&gt;Set up an AI champions network&lt;/li&gt;
&lt;li&gt;Encourage experimentation (dedicated time, workshops, hackathons, &amp;hellip;)&lt;/li&gt;
&lt;li&gt;Link to performance evaluations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Amplify
&lt;ul&gt;
&lt;li&gt;Create an AI knowledge base&lt;/li&gt;
&lt;li&gt;Share success stories (weekly)&lt;/li&gt;
&lt;li&gt;Create internal groups (Teams, Slack, &amp;hellip;)&lt;/li&gt;
&lt;li&gt;Celebrate AI wins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Accelerate
&lt;ul&gt;
&lt;li&gt;Unblock AI tools and data access&lt;/li&gt;
&lt;li&gt;Simplify project selection. Quick feedback, clear priorities&lt;/li&gt;
&lt;li&gt;Unblock projects with a cross-functional council&lt;/li&gt;
&lt;li&gt;Give resources to successful teams&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Govern
&lt;ul&gt;
&lt;li&gt;Publish a responsible AI playbook (what&amp;rsquo;s safe to try)&lt;/li&gt;
&lt;li&gt;Audit AI practices quarterly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Things I Learned - 03 Mar 2024</title>
      <link>https://www.s-anand.net/blog/things-i-learned-03-mar-2024/</link>
      <pubDate>Sun, 03 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/things-i-learned-03-mar-2024/</guid>
      <description>&lt;p&gt;This week, I learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://lamplightdev.com/blog/2024/01/10/streaming-html-out-of-order-without-javascript/&#34;&gt;You can use slots to stream HTML out of order&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;Shane Parrish. Short-term patience podcast
&lt;ul&gt;
&lt;li&gt;have a frame of reference to relate EVERY experience to. That helps you evaluate (measure) and learn. That&amp;rsquo;s part of what Charlie Munger&amp;rsquo;s lattice of frameworks is about&lt;/li&gt;
&lt;li&gt;when there is a very high or very low interest scenario, low interest scenario then go ultra long term. Issued hundred years when the interest rate regime was very low&lt;/li&gt;
&lt;li&gt;short term optimal is rally long term optimal. So you need to learn to take a loss and look like an idiot to play the long-term game&lt;/li&gt;
&lt;li&gt;grit is a behavior that enables long-term thinking. Short term success gives you the luxury to think about long term&lt;/li&gt;
&lt;li&gt;#IMP power is about optionality. It&amp;rsquo;s about being in a position where you have the options that can affect the positive change rather than circumstances controlling you. Read Robert greene&amp;rsquo;s book on the 48 laws of Power&lt;/li&gt;
&lt;li&gt;low leverage enables that&lt;/li&gt;
&lt;li&gt;begin with the end in mind. Always&lt;/li&gt;
&lt;li&gt;how do you think about risk? Well, things do happen. It&amp;rsquo;s as simple as that&lt;/li&gt;
&lt;li&gt;autonomy and decentralization helps derisk&lt;/li&gt;
&lt;li&gt;do more and more of what works. That&amp;rsquo;s a powerful way of compounding&lt;/li&gt;
&lt;li&gt;long-term investments are better than frequent trading because you get to reinvest the tax you otherwise would have paid. So unless the alternative is super compelling, stay invested&lt;/li&gt;
&lt;li&gt;if you need to be the person who DOES the thing, you delegate less, leverage list, compound less, because you have to DO. BE A PERSON WHO SETS THE FIELD INSTEAD. The coach, the chess master, the director, patient strategist who Waits for the good hit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Being in Control motivates #Lesson. my cycle tires were flat. I thought it was someone pulling out the air and felt very demotivated. But once I carried my cycle pump, I felt so much more in control and power and felt a whole lot better&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sourcegraph.com/&#34;&gt;SourceGraph&lt;/a&gt; is the default platform for private code completion &amp;amp; search&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.geeky-gadgets.com/ai-voice-cloning-and-creation/&#34;&gt;MetaVoice 1B&lt;/a&gt; offers voice cloning on American &amp;amp; British accents with 30s training&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://qwenlm.github.io/blog/qwen1.5/&#34;&gt;Qwen 1.5 72B&lt;/a&gt; appears to outperform Mistral Medium, making it one of the top non-proprietary models&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://llava-vl.github.io/blog/2024-01-30-llava-1-6/&#34;&gt;Llava 1.6&lt;/a&gt; is a substantial improvement over Llava 1.5 and slightly better than CogVLM, Qwen-VL&lt;/li&gt;
&lt;li&gt;AI scams are growing. &lt;a href=&#34;https://www.straitstimes.com/asia/east-asia/hk-firm-scammed-of-34-million-after-employee-is-duped-by-video-call-with-deepfake-of-cfo&#34;&gt;Deepfakes scammed $34m&lt;/a&gt;. But &lt;a href=&#34;https://www.sfchronicle.com/bayarea/article/ai-phone-scam-18561537.php?sid=64ffe30738148943ca040a9b&amp;amp;ss=A&amp;amp;st_rid=40d8ca22-ad29-44d1-bcfa-45dcd33455f0&#34;&gt;voice fake for kidnapping&lt;/a&gt; is scarier.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/u9dZd4jIxL0&#34;&gt;Buildspace&amp;rsquo;s demo&lt;/a&gt; is a great demo of how voice and actions can be used effectively.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/adefossez/demucs&#34;&gt;demucs&lt;/a&gt; does an EXCELLENT job of splitting songs into drums, bass, vocals and others&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Always use value= for dynamic HTML options</title>
      <link>https://www.s-anand.net/blog/always-use-value-for-dynamic-html-options/</link>
      <pubDate>Mon, 31 Jul 2023 06:45:48 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/always-use-value-for-dynamic-html-options/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Always use value= for dynamic HTML options&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/html-code.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;Even after 30 years of HTML, I learn new things about it.&lt;/p&gt;
&lt;p&gt;This Monday morning, I woke up to a mail from &lt;a href=&#34;https://www.linkedin.com/in/sundeeprm/&#34;&gt;Sundeep&lt;/a&gt; saying requests for a &lt;code&gt;Data Engineer - AWS/Azure/GCP&lt;/code&gt; in our internal fulfilment portal raised an error.&lt;/p&gt;
&lt;p&gt;My guess was one of these:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &amp;ldquo;/&amp;rdquo; in the role is causing a problem. (Developer mistake.)&lt;/li&gt;
&lt;li&gt;The role exists in one table but not the other. (Recruitment team mistake.)&lt;/li&gt;
&lt;li&gt;The application wasn&amp;rsquo;t set up / restarted properly. (IT mistake.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;All three were wrong&lt;/strong&gt;. So I dug deeper.&lt;/p&gt;
&lt;p&gt;The role was defined as &lt;code&gt;Data Engineer  - AWS/Azure/GCP&lt;/code&gt; (note the 2 spaces before the hyphen). But the form kept sending &lt;code&gt;Data Engineer - AWS/Azure/GCP&lt;/code&gt; (spaces were condensed).&lt;/p&gt;
&lt;p&gt;I swear there was &lt;strong&gt;NOTHING&lt;/strong&gt; in the code that changes the options. The relevant line just picked up the role and rendered it inside the &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;```markup
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;{{ row[&amp;#39;Role&amp;#39;] }}&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I used the browser&amp;rsquo;s developer tools to inspect the &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element. It showed the options with the 2 spaces:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-markup&#34; data-lang=&#34;markup&#34;&gt;&amp;lt;option&amp;gt;Data Engineer  - AWS/Azure/GCP&amp;lt;/option&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But, when I selected it and printed the value, it had only one space.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#role&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;br&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Data Engineer - AWS/Azure/GCP&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s when it hit me. &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace&#34;&gt;HTML condenses whitespaces&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Till date, I only ever used &lt;code&gt;&amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt; when specifying a value &lt;strong&gt;different&lt;/strong&gt; from what&amp;rsquo;s displayed. I never thought of using it to &lt;strong&gt;preserve&lt;/strong&gt; the value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LESSON&lt;/strong&gt;: If you&amp;rsquo;re dynamically generating &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;s, &lt;strong&gt;ALWAYS&lt;/strong&gt; use &lt;code&gt;value=&lt;/code&gt; with the same value as the text.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How to extend Markdown with custom blocks</title>
      <link>https://www.s-anand.net/blog/how-to-extend-markdown-with-custom-blocks/</link>
      <pubDate>Fri, 08 Jan 2021 09:37:48 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/how-to-extend-markdown-with-custom-blocks/</guid>
      <description>&lt;p&gt;One problem I&amp;rsquo;ve had in Markdown is rendering a content in columns.&lt;/p&gt;
&lt;p&gt;On Bootstrap, the markup would look like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-markup&#34; data-lang=&#34;markup&#34;&gt;&amp;lt;div class=&amp;#34;row&amp;#34;&amp;gt;
  &amp;lt;div class=&amp;#34;col&amp;#34;&amp;gt;...&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;#34;col&amp;#34;&amp;gt;...&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;How do we get that into Markdown without writing HTML?&lt;/p&gt;
&lt;p&gt;On Python, the &lt;a href=&#34;https://python-markdown.github.io/extensions/attr_list/&#34;&gt;attribute lists extension&lt;/a&gt; lets you add a class. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This is some content
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{: .row}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; renders &lt;code&gt;&amp;lt;p class=&amp;quot;row&amp;quot;&amp;gt;This is some content&amp;lt;/p&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But I can&amp;rsquo;t do that to multiple paragraphs. Nor can I next content, i.e. add a &lt;code&gt;.col&lt;/code&gt; inside the &lt;code&gt;.row&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Enter &lt;a href=&#34;https://pypi.org/project/markdown-customblocks/&#34;&gt;markdown-customblocks&lt;/a&gt;. It&amp;rsquo;s a Python module that extends &lt;a href=&#34;https://python-markdown.github.io/&#34;&gt;Python Markdown&lt;/a&gt;. This lets me write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: row
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: col
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Content in column 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: col
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Content in column 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: row
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: col
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Content in column 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;::: col
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Content in column 2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This translates to:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-markup&#34; data-lang=&#34;markup&#34;&gt;&amp;lt;div class=&amp;#34;row&amp;#34;&amp;gt;
  &amp;lt;div class=&amp;#34;col&amp;#34;&amp;gt;Content in column 1&amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;#34;col&amp;#34;&amp;gt;Content in column 2&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Better yet, we can create our own custom HTML block types. For example, this code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;markdown&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Markdown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;customblocks&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CustomBlocksExtension&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;audio&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;audio/mp3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;&amp;lt;audio src=&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#34; type=&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;lt;/audio&amp;gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;md&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Markdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;CustomBlocksExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generators&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s1&#34;&gt;&amp;#39;audio&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;audio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; lets you convert this piece of Markdown:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;md&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;::: audio src=&amp;#34;mymusic.ogg&amp;#34; type=&amp;#34;audio/ogg&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    Your browser does not support `audio`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; into this HTML:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-markup&#34; data-lang=&#34;markup&#34;&gt;&amp;lt;audio src=&amp;#34;mymusic.ogg&amp;#34; type=&amp;#34;audio/ogg&amp;#34;&amp;gt;
  Your browser does not support &amp;lt;code&amp;gt;audio&amp;lt;/code&amp;gt;.
&amp;lt;/audio&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://pypi.org/project/markdown-customblocks/&#34;&gt;markdown-customblocks&lt;/a&gt; is easily the most useful Python module I discovered last quarter.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Google web authoring statistics</title>
      <link>https://www.s-anand.net/blog/google-web-authoring-statistics/</link>
      <pubDate>Wed, 25 Jan 2006 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/google-web-authoring-statistics/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://code.google.com/webstats/index.html&#34;&gt;Google web authoring statistics&lt;/a&gt;. An analysis of over a billion pages to see how people use HTML markup.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>PDF to HTML via Gmail</title>
      <link>https://www.s-anand.net/blog/pdf-to-html-via-gmail/</link>
      <pubDate>Sun, 18 Dec 2005 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/pdf-to-html-via-gmail/</guid>
      <description>&lt;p&gt;Convert &lt;a href=&#34;http://labnol.blogspot.com/2005/12/convert-doc-xls-ppt-rtf-pdf-to-html.html&#34;&gt;PDF to HTML via Gmail&lt;/a&gt;. This is the only way I know of converting something from PDF into another format. Unfortunately, it doesn&amp;rsquo;t work for GoogleMail in the UK.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>HTML keyboard shortcuts</title>
      <link>https://www.s-anand.net/blog/html-keyboard-shortcuts/</link>
      <pubDate>Wed, 30 Nov 2005 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/html-keyboard-shortcuts/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://diveintoaccessibility.org/day_15_defining_keyboard_shortcuts.html&#34;&gt;HTML keyboard shortcuts&lt;/a&gt; using the &amp;ldquo;accesskey&amp;rdquo; attribute.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Convert pictures to ASCII</title>
      <link>https://www.s-anand.net/blog/convert-pictures-to-ascii/</link>
      <pubDate>Thu, 24 Jan 2002 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/convert-pictures-to-ascii/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://pic3html.vvv.tf/&#34;&gt;Convert pictures to ASCII&lt;/a&gt;. In colour. Quite impressive.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>w3schools</title>
      <link>https://www.s-anand.net/blog/w3schools/</link>
      <pubDate>Fri, 12 Jan 2001 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/w3schools/</guid>
      <description>&lt;p&gt;Learn web-development at &lt;a href=&#34;http://www.w3schools.com/&#34;&gt;w3schools&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
