<?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>github-pages on S Anand</title>
    <link>https://www.s-anand.net/blog/tag/github-pages/</link>
    <description>Recent content in github-pages on S Anand</description>
    <generator>Hugo -- 0.156.0</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 12 Jul 2026 16:25:50 +0530</lastBuildDate>
    <atom:link href="https://www.s-anand.net/blog/tag/github-pages/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Creating a scrollytelling map</title>
      <link>https://www.s-anand.net/blog/creating-a-scrollytelling-map/</link>
      <pubDate>Sun, 12 Jul 2026 16:25:50 +0530</pubDate>
      <guid>https://www.s-anand.net/blog/creating-a-scrollytelling-map/</guid>
      <description>&lt;p&gt;I had Claude Code with Fable create a small scrollytelling map for my &lt;a href=&#34;https://sanand0.github.io/datastories/security-at-bagmane-capital/&#34;&gt;14-minute walk&lt;/a&gt; experience at &lt;a href=&#34;https://www.s-anand.net/blog/security-at-bagmane-capital/&#34;&gt;Bagmane Capital&lt;/a&gt; in Bangalore.&lt;/p&gt;
&lt;p&gt;I used this as an opportunity to explore the current status of the technology. &lt;a href=&#34;https://chatgpt.com/share/6a537375-5308-83ee-ab03-00e39d8cc05a&#34;&gt;ChatGPT&lt;/a&gt; suggested: &lt;!-- https://chatgpt.com/c/6a520c51-2e08-83e8-8073-a1b703bdd45c --&gt;&lt;/p&gt;
&lt;section ai-disclosure=&#34;ai-generated&#34; data-ai-model=&#34;gpt-5.6-sol&#34; data-ai-provider=&#34;OpenAI&#34;&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Try ArcGIS StoryMaps first&lt;/strong&gt; for a polished scrollytelling story.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Try Google Earth Projects&lt;/strong&gt; if this is primarily something you will present live, like a map-based slide deck.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use MapLibre GL JS with a coding agent&lt;/strong&gt; if you want precise choreography, animated routes, unusual visual effects, or an asset you can continually extend.&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;None of these fit my requirements, which was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hostable, self-contained, on GitHub Pages&lt;/li&gt;
&lt;li&gt;Forever free tiles, to the extent possible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Based on its recommendations, my workflow was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Capture locations in Google Maps&lt;/strong&gt;. Right-click and copy the latitude, longitude.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capture routes in &lt;a href=&#34;https://mymaps.google.com&#34;&gt;Google My Maps&lt;/a&gt;&lt;/strong&gt;. This was insight. MyMaps lets you export driving, walking, and cycling routes as KML. (No bike routes, though.)&lt;/li&gt;
&lt;li&gt;Create a single-page index.html using &lt;strong&gt;MapLibre GL JS with a free OpenFreeMap basemap&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I &lt;a href=&#34;https://www.google.com/maps/d/u/0/edit?mid=1EmnW_jW6nP22MBJAlFg0R66CfBt9Fw8&#34;&gt;created the MyMaps routes&lt;/a&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.google.com/maps/d/u/0/edit?mid=1EmnW_jW6nP22MBJAlFg0R66CfBt9Fw8&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://files.s-anand.net/images/2026-07-12-creating-a-scrollytelling-map-google-mymaps.avif&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip; exported layers as KML files, and meta-prompted Codex with my story written in this form:&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;I was staying at [&lt;span class=&#34;nt&#34;&gt;The Curzon Court, Brigade Road&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://maps.app.goo.gl/ArHn75eAihHzZXcr9&lt;/span&gt;). 12.97454856819103, 77.60788450296555
&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;I needed to be at [&lt;span class=&#34;nt&#34;&gt;Microsoft Luxor North Tower&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://maps.app.goo.gl/Tf5qZGwXogetSJr46&lt;/span&gt;) 12.984402817080221, 77.70407412470264
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;for a 2 pm [&lt;span class=&#34;nt&#34;&gt;workshop&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://hasgeek.com/fifthelephant/when-data-is-for-agents-workshop/&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;So I came over to [&lt;span class=&#34;nt&#34;&gt;Seetharampalya Metro Station&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://maps.app.goo.gl/Z4deFUzZsqamcCZC9&lt;/span&gt;) 12.98116461318051, 77.70872373073122
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;and seated myself at [&lt;span class=&#34;nt&#34;&gt;Fairfield by Marriott&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;https://maps.app.goo.gl/NJqUfFnHL4QW8xa2A&lt;/span&gt;) 12.981961760138114, 77.70869689674738
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;by 11 am.
&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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; and also attached a series of &lt;code&gt;.kml&lt;/code&gt; files for the routes. The generated prompt had some &lt;em&gt;nice&lt;/em&gt; suggestions, such as:&lt;/p&gt;
&lt;section ai-disclosure=&#34;ai-generated&#34; data-ai-model=&#34;gpt-5.6-sol&#34; data-ai-provider=&#34;OpenAI&#34;&gt;
&lt;ul&gt;
&lt;li&gt;Break the story into well-paced scenes, preserving its dry, escalating humour.&lt;/li&gt;
&lt;li&gt;Make time pressure visible through restrained clocks, timestamps, distance and ETA annotations.&lt;/li&gt;
&lt;li&gt;Build tension toward the late arrival, then treat the security confrontation with deadpan repetition.&lt;/li&gt;
&lt;li&gt;End quietly and anticlimactically at Bug &amp;amp; Bean with the peri peri paneer sandwich.&lt;/li&gt;
&lt;li&gt;&amp;hellip; etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;p&gt;But one interesting idea I didn&amp;rsquo;t explore was to &amp;ldquo;Have the coding agent add an authoring mode&amp;rdquo;, specifically:&lt;/p&gt;
&lt;section ai-disclosure=&#34;ai-generated&#34; data-ai-model=&#34;gpt-5.6-sol&#34; data-ai-provider=&#34;OpenAI&#34;&gt;
&lt;p&gt;In authoring mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clicking the map copies &lt;code&gt;[longitude, latitude]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copy camera&lt;/strong&gt; copies the current center, zoom, bearing and pitch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copy visible bounds&lt;/strong&gt; copies southwest and northeast coordinates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import KML/GeoJSON&lt;/strong&gt; previews routes.&lt;/li&gt;
&lt;li&gt;Selecting a route offers &lt;strong&gt;Create fit chapter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Clicking a marker offers &lt;strong&gt;Create point chapter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A panel shows the exact chapter JSON.&lt;/li&gt;
&lt;li&gt;Pressing &lt;code&gt;C&lt;/code&gt; copies the current camera.&lt;/li&gt;
&lt;li&gt;Pressing &lt;code&gt;P&lt;/code&gt; creates a placemark.&lt;/li&gt;
&lt;li&gt;Pressing &lt;code&gt;B&lt;/code&gt; creates a fit-to-bounds instruction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;p&gt;This is a great idea - fairly easy to implement, meaning that I can even do away with map authoring software in the future.&lt;/p&gt;
&lt;p&gt;AI agents write software, but also know &lt;em&gt;what&lt;/em&gt; software features are useful. That makes taste more niche (i.e. I&amp;rsquo;ll use / buy your software if I already know and totally align with your taste, but otherwise, I&amp;rsquo;ll mix-and-match and build my own.)&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Deploying websites over dinner</title>
      <link>https://www.s-anand.net/blog/deploying-websites-over-dinner/</link>
      <pubDate>Mon, 27 Apr 2026 16:30:50 -0400</pubDate>
      <guid>https://www.s-anand.net/blog/deploying-websites-over-dinner/</guid>
      <description>&lt;p&gt;Over dinner with &lt;a href=&#34;https://www.linkedin.com/in/nishka-gattu-32133b339/&#34;&gt;Nishka&lt;/a&gt;, we were trying to deploy a website. The challenge was: How can we deploy this website, just on mobile, &lt;strong&gt;without getting up from the dinner table&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 1: Hosting&lt;/strong&gt;. On my phone, I dictated to ChatGPT (whose transcription is excellent), copy-pasted that to Gemini (which is faster):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I want to publish specifically a static HTML web page on my own domain.&lt;br&gt;
I want the easiest way that I can host it, preferably just by copy-pasting from my mobile without needing to muck around with Git and the likes of it.&lt;br&gt;
What are the most robust, reliable hosting providers that I could use? I can sort out the domain name myself as long as they support an option to map a custom domain name to them.&lt;br&gt;
Ideally, I am looking for something that is free, preferably free forever.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Top answer: &lt;a href=&#34;https://pages.github.com/&#34;&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since Nikki already had a GitHub account, that worked well. Using &lt;a href=&#34;https://github.com/mobile&#34;&gt;GitHub Mobile&lt;/a&gt;, she created a new repository, created a new &lt;code&gt;index.html&lt;/code&gt;, and published it to GitHub Pages - all from the phone, without needing to get up from the dinner table. (The content was vibe-coded later, but the infrastructure was set up during dinner.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 2: Domain Name&lt;/strong&gt;. Next question - again, to Gemini via ChatGPT dictation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Okay, I want to buy a domain name next. What&amp;rsquo;s the cleanest simplest cheap way that I can get a domain?&lt;br&gt;
For now I&amp;rsquo;m not particular about which domain but I should be able to buy this very easily just on a mobile and I should be able to configure the DNS directly on the mobile itself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Top answer: &lt;a href=&#34;https://www.cloudflare.com/products/registrar/&#34;&gt;Cloudflare Registrar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nikki didn&amp;rsquo;t have a Cloudflare account, but was able to sign up for one easily on the phone.&lt;/p&gt;
&lt;p&gt;After searching for a bit, &lt;a href=&#34;https://www.rexgattu.com/&#34;&gt;rexgattu.com&lt;/a&gt; (the future home page for the youngest member of the family) was available for ~$10/year.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Photo of Rex&#34; loading=&#34;lazy&#34; src=&#34;https://files.s-anand.net/images/2026-04-27-rex-gattu.avif&#34;&gt;&lt;/p&gt;
&lt;p&gt;Her sister&amp;rsquo;s credit card photos were available on her phone, so there was no need to get up from the dinner table to get the card details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 3: Setting up DNS&lt;/strong&gt;. The third question was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How do I point a domain name that I purchased on Cloudflare and his managed by Cloudflare to a GitHub Pages page?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It provided step-by-step instructions: Go to DNS &amp;gt; Records. Add an A record pointing &lt;code&gt;@&lt;/code&gt; to &lt;code&gt;185.199.108.153&lt;/code&gt;. Add a CNAME record pointing &lt;code&gt;www&lt;/code&gt; to &lt;code&gt;[username].github.io&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;She did that. Now &lt;a href=&#34;https://www.rexgattu.com/&#34;&gt;&lt;code&gt;www.rexgattu.com&lt;/code&gt;&lt;/a&gt; pointed to the GitHub Pages site.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;That&amp;rsquo;s it! Our infrastructure has gone to the point where we can deploy a website on a custom domain, without even needing to get up from the table.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How to build and deploy custom GitHub Pages</title>
      <link>https://www.s-anand.net/blog/how-to-build-and-deploy-custom-github-pages/</link>
      <pubDate>Tue, 01 Apr 2025 05:59:18 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/how-to-build-and-deploy-custom-github-pages/</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s the &lt;a href=&#34;https://github.com/features/actions&#34;&gt;GitHub Actions&lt;/a&gt; file (&lt;code&gt;.github/workflows/deploy.yaml&lt;/code&gt;) I use to publish to &lt;a href=&#34;https://pages.github.com/&#34;&gt;GitHub pages&lt;/a&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Deploy to GitHub Pages&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Run when pushed. Use { branches: [main, master] } to run only on specific branches&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Allow manual triggering of the workflow&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;workflow_dispatch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# OPTIONAL: Run at a specific cron schedule, e.g. first day of every month at 12:00 UTC (noon)&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cron&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;0 12 1 * *&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;permissions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# To deploy to GitHub Pages&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# To verify that deployment originated from the right source&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id-token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Run as a single build + deploy job to reduce setup time&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;deploy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Specify the deployment environment. Displays the URL in the GitHub Actions UI&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;github-pages&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ steps.deployment.outputs.page_url }}&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Run on the latest Ubuntu LTS&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Checkout the repository&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v4&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Run whatever commands you want&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;echo &amp;#39;&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;&amp;#39; &amp;gt; index.html&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Upload a specific page to GitHub Pages. Defaults to _site&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/upload-pages-artifact@v3&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Deploy the built site to GitHub Pages. The `id:` is required to show the URL in the GitHub Actions UI&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;deployment&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/deploy-pages@v4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is based on &lt;a href=&#34;https://til.simonwillison.net/github-actions/github-pages&#34;&gt;Simon Willison&amp;rsquo;s workflow&lt;/a&gt; and some of my earlier actions.&lt;/p&gt;
&lt;p&gt;This &lt;strong&gt;combines build and deploy&lt;/strong&gt; jobs. For simple sites, that&amp;rsquo;s simpler and more efficient. For complex builds with parallel execution or need for better error recovery, multiple jobs will help.&lt;/p&gt;
&lt;p&gt;I build sites with &lt;a href=&#34;https://github.com/astral-sh/uv&#34;&gt;uv&lt;/a&gt;, &lt;a href=&#34;https://nodejs.org/&#34;&gt;node&lt;/a&gt;, or &lt;a href=&#34;https://deno.com/&#34;&gt;deno&lt;/a&gt;. Here are examples of each&lt;/p&gt;
&lt;p&gt;A sample &lt;a href=&#34;https://github.com/sanand0/webfeatures/blob/main/.github/workflows/deploy.yml&#34;&gt;uv-based deployment&lt;/a&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install uv&lt;/span&gt;&lt;span class=&#34;w&#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;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;astral-sh/setup-uv@v5&lt;/span&gt;&lt;span class=&#34;w&#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;c&#34;&gt;# Run a Python script&lt;/span&gt;&lt;span class=&#34;w&#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;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;uv run scraper.py&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A sample &lt;a href=&#34;https://github.com/gramener/gramex-network/blob/main/.github/workflows/deploy.yml&#34;&gt;node package.json deployment&lt;/a&gt; and an &lt;a href=&#34;https://github.com/sanand0/llmhallucinations/blob/main/.github/workflows/deploy.yml&#34;&gt;npx deployment&lt;/a&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install node&lt;/span&gt;&lt;span class=&#34;w&#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;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/setup-node@v4&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;node-version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;registry-url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://npm.pkg.github.com/&lt;/span&gt;&lt;span class=&#34;w&#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;c&#34;&gt;# Install and build via package.json&lt;/span&gt;&lt;span class=&#34;w&#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;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;npm install&lt;/span&gt;&lt;span class=&#34;w&#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;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;npm run build&lt;/span&gt;&lt;span class=&#34;w&#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;c&#34;&gt;# Or, directly use npx. For example, generate HTML with Marp&lt;/span&gt;&lt;span class=&#34;w&#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;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;npx -y @marp-team/marp-cli@latest README.md -o index.html&lt;/span&gt;&lt;span class=&#34;w&#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;c&#34;&gt;# Update content directly, e.g. add an SVG favicon as a data URL&lt;/span&gt;&lt;span class=&#34;w&#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;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sed -i &amp;#39;s/&amp;lt;\/head&amp;gt;/&amp;lt;link rel=&amp;#34;icon&amp;#34; type=&amp;#34;image\/svg+xml&amp;#34; href=&amp;#34;data:image\/svg+xml;base64,...&amp;#34;\/&amp;gt;&amp;lt;\/head&amp;gt;/g&amp;#39; index.html&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A sample &lt;a href=&#34;https://github.com/sanand0/til/blob/main/.github/workflows/deploy.yml&#34;&gt;deno deployment&lt;/a&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install deno&lt;/span&gt;&lt;span class=&#34;w&#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;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;denoland/setup-deno@v1&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;deno-version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1.x&lt;/span&gt;&lt;span class=&#34;w&#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;c&#34;&gt;# Run a Deno script. Use environment variables if needed&lt;/span&gt;&lt;span class=&#34;w&#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;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.OPENAI_API_KEY }}&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;deno run --allow-read --allow-write --allow-env --allow-net script.js&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Voice Chat to Slides: My New AI-Powered Workflow</title>
      <link>https://www.s-anand.net/blog/voice-chat-to-slides-my-new-ai-powered-workflow/</link>
      <pubDate>Thu, 27 Mar 2025 16:34:53 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/voice-chat-to-slides-my-new-ai-powered-workflow/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Voice Chat to Slides: My New AI-Powered Workflow&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/calvin-2.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my new workflow for creating slide decks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ChatGPT interviews me and creates Markdown slides.&lt;/li&gt;
&lt;li&gt;I use Marp to convert Markdown to slides.&lt;/li&gt;
&lt;li&gt;LLMs create supporting images.&lt;/li&gt;
&lt;li&gt;I deploy on GitHub Pages.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;… and here are 2 decks created this way.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://sanand0.github.io/llmhallucinations/&#34;&gt;Visualizing LLM Hallucinations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sanand0.github.io/llms-in-education/&#34;&gt;LLMs in Education&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s look at how I built the second example, step by step.&lt;/p&gt;
&lt;h3 id=&#34;chatgpt-interviews-me-and-creates-markdown-slides&#34;&gt;ChatGPT interviews me and creates Markdown slides&lt;/h3&gt;
&lt;p&gt;While walking 75 minutes from home to IIT Madras to deliver &lt;a href=&#34;https://sanand0.github.io/llms-in-education/&#34;&gt;this talk&lt;/a&gt;, I had ChatGPT interview me in &lt;a href=&#34;https://help.openai.com/en/articles/8400625-voice-mode-faq&#34;&gt;standard voice mode&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why an interview?&lt;/strong&gt; It&amp;rsquo;s easier when someone asks questions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why voice?&lt;/strong&gt; It&amp;rsquo;s hard to type while walking. Otherwise, I prefer typing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why not advanced voice mode?&lt;/strong&gt; I want to use a reasoning model like &lt;a href=&#34;https://chatgpt.com/?model=o3-mini-high&#34;&gt;O3 Mini High&lt;/a&gt; for better responses, not the GPT-4o-realtime model that advanced voice mode uses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://chatgpt.com/share/67e36f57-01c4-800c-b4fc-5c8b302403f4&#34;&gt;Here&amp;rsquo;s the conversation I had with ChatGPT&lt;/a&gt;. I began by speaking (not typing):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I want to create an insightful deck in Markdown on how I have been using LLMs in education.The audience will be technologists and educators. The slide contents must have information that is useful and surprising to them.&lt;/p&gt;
&lt;p&gt;The slides are formatted in Markdown with each slide title being a level 2 Markdown header and the contents of the slides being crisp bullet points that support the title. The titles are McKinsey style action titles. Just by reading the titles, the audience will understand the message that I am trying to convey.&lt;/p&gt;
&lt;p&gt;In this conversation, I&amp;rsquo;d like you to interview me, asking me questions one by one, and taking my inputs to craft this presentation. I&amp;rsquo;d also like you to review the inputs and the slide content you create to make sure that it is insightful, useful, non-obvious, and very clear and simple for the audience. Interact with me to improve the deck.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s begin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Unsurprisingly, I talk a lot more than I type.)&lt;/p&gt;
&lt;p&gt;There were 3 kinds of interactions I had with ChatGPT:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;. I explained each slide. For example:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Yeah, let&amp;rsquo;s move on to the next topic, which is where we had the students learn prompt engineering as part of the course. One of the questions was convincing an LLM to say yes, even though …&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Correction&lt;/strong&gt;. After ChatGPT read aloud a slide, I corrected it. For example:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Content-wise, it&amp;rsquo;s spot-on. Style-wise, it&amp;rsquo;s almost spot-on. It&amp;rsquo;s far more verbose. Can you retain the exact same style, but shorten the number of words considerably?&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;These feel generic. I&amp;rsquo;d like stuff that comes across as insightful, non-obvious, and specific.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Collation&lt;/strong&gt;. I had ChatGPT put slides in order. For example:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Put all the slides together in sequence. Make sure you don&amp;rsquo;t miss anything.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Move the opening questions as the second slide. Move the final takeaways, which is currently the last slide, to just before the final set of questions.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the end of the interview, I had all the content for the slides.&lt;/p&gt;
&lt;h3 id=&#34;marp-converts-markdown-to-slides&#34;&gt;Marp converts Markdown to slides&lt;/h3&gt;
&lt;p&gt;I use &lt;a href=&#34;https://marp.app/&#34;&gt;Marp&lt;/a&gt;, a JavaScript tool that turns Markdown into slides&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why Markdown?&lt;/strong&gt; It&amp;rsquo;s natural for programmers &lt;strong&gt;and&lt;/strong&gt; LLMs. ChatGPT renders rich text in Markdown.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why not RevealJS?&lt;/strong&gt; Despite a &lt;a href=&#34;https://revealjs.com/markdown/&#34;&gt;Markdown plugin&lt;/a&gt;, RevealJS is built for HTML. Marp is built for Markdown.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I created a &lt;a href=&#34;https://tools.s-anand.net/page2md/&#34;&gt;bookmarklet&lt;/a&gt; that copies text as Markdown. Using this, I converted the ChatGPT slide transcript to Markdown, saving it as &lt;a href=&#34;https://github.com/sanand0/llms-in-education/blob/main/README.md&#34;&gt;README.md&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode&#34;&gt;Marp for VS Code plugin&lt;/a&gt; makes it easy to preview the slides when you adding YAML frontmatter like this:&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#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;marp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#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;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Visualizing LLM Hallucinations&lt;/span&gt;&lt;span class=&#34;w&#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;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://sanand0.github.io/llmhallucinations/&lt;/span&gt;&lt;span class=&#34;w&#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;theme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gaia&lt;/span&gt;&lt;span class=&#34;w&#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;backgroundColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;w&#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;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;llms-create-supporting-images&#34;&gt;LLMs create supporting images&lt;/h3&gt;
&lt;p&gt;I use ChatGPT or Gemini to create images that support the slides. For example &lt;a href=&#34;https://sanand0.github.io/llmhallucinations/#2&#34;&gt;this slide&lt;/a&gt; includes an image of a robot psychologist generated by Gemini&amp;rsquo;s ImageGen 3:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Robopsychologist&#34; loading=&#34;lazy&#34; src=&#34;https://raw.githubusercontent.com/sanand0/llmhallucinations/refs/heads/main/img/robo-psychologist.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;Today, with native image generation in &lt;a href=&#34;https://developers.googleblog.com/en/experiment-with-gemini-20-flash-native-image-generation/&#34;&gt;Gemini 2.0 Flash&lt;/a&gt; and &lt;a href=&#34;https://openai.com/index/introducing-4o-image-generation/&#34;&gt;GPT 4o&lt;/a&gt;, I&amp;rsquo;d likely use those. They have much better character control.&lt;/p&gt;
&lt;h3 id=&#34;deploying-on-github-pages&#34;&gt;Deploying on GitHub Pages&lt;/h3&gt;
&lt;p&gt;I use &lt;a href=&#34;https://github.com/sanand0/llms-in-education/blob/main/.github/workflows/deploy.yml&#34;&gt;GitHub Actions&lt;/a&gt; to render the slides and deploy them on GitHub Pages. Here&amp;rsquo;s what the key steps look like:&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Checkout repository&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v4&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Setup Node.js&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/setup-node@v4&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;node-version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;22&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Generate HTML with Marp&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;npx -y @marp-team/marp-cli@latest README.md -o index.html&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Setup GitHub Pages&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/configure-pages@v4&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Upload artifact&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/upload-pages-artifact@v3&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#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;w&#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;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Deploy to GitHub Pages&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;deployment&lt;/span&gt;&lt;span class=&#34;w&#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;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/deploy-pages@v4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;whats-next&#34;&gt;What&amp;rsquo;s next?&lt;/h3&gt;
&lt;p&gt;I plan to make 3 improvements to this workflow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Adding images directly with voice prompts.&lt;/li&gt;
&lt;li&gt;Adding diagrams (e.g., Mermaid).&lt;/li&gt;
&lt;li&gt;Creating a custom GPT that auto-deploys slides on GitHub when I say &amp;ldquo;Publish these slides.&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If both of these work, I&amp;rsquo;ll be able to create &lt;strong&gt;and publish&lt;/strong&gt; an entire slide deck just by rambling to ChatGPT for an hour.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>My learnings as week notes</title>
      <link>https://www.s-anand.net/blog/my-learnings-as-week-notes/</link>
      <pubDate>Wed, 25 Dec 2024 14:27:11 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/my-learnings-as-week-notes/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;My learnings as week notes&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/things-i-learned.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;One of my &lt;a href=&#34;https://www.s-anand.net/blog/my-year-in-2023/&#34;&gt;goals for 2024&lt;/a&gt; is to &amp;ldquo;Compound long-term goals, daily.&amp;rdquo; Learning is one of those.&lt;/p&gt;
&lt;p&gt;Some people publish their learnings as weekly notes, like &lt;a href=&#34;https://simonwillison.net/tags/weeknotes/&#34;&gt;Simon Willison&lt;/a&gt;, &lt;a href=&#34;https://thejeshgn.com/category/weekly-notes/&#34;&gt;Thejesh GN&lt;/a&gt;, &lt;a href=&#34;https://mvark.blogspot.com/&#34;&gt;Anil Radhakrishna&lt;/a&gt;, and &lt;a href=&#34;https://jvns.ca/til/&#34;&gt;Julia Evans&lt;/a&gt;. I follow their notes.&lt;/p&gt;
&lt;p&gt;I started doing the same, quietly, to see if I could sustain it. It&amp;rsquo;s been a year and it &lt;strong&gt;has sustained&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m finally publishing them. &lt;a href=&#34;https://til.s-anand.net/&#34;&gt;My week notes are at &lt;strong&gt;til.s-anand.net&lt;/strong&gt;&lt;/a&gt;. Here&amp;rsquo;s the &lt;a href=&#34;https://github.com/sanand0/til&#34;&gt;source code&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;capturing-learnings-must-be-frictionless&#34;&gt;Capturing learnings must be frictionless&lt;/h3&gt;
&lt;p&gt;I learn things when I&amp;rsquo;m reading, listening to podcasts, listening to people, or thinking. In every case I&amp;rsquo;m close to my phone or laptop.&lt;/p&gt;
&lt;p&gt;If my laptop is open, I add my notes to a few (long) Markdown files like &lt;a href=&#34;https://github.com/sanand0/til/blob/main/til.md&#34;&gt;this &lt;code&gt;til.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If my phone is easier to access, I type or dictate my notes into &lt;a href=&#34;https://to-do.office.com/tasks/&#34;&gt;Microsoft To Do&lt;/a&gt;, which is currently my most convenient note-taking app. It syncs with my laptop. I transfer it (via OCR on &lt;a href=&#34;https://learn.microsoft.com/en-us/windows/powertoys/text-extractor&#34;&gt;Microsoft Power Toys&lt;/a&gt;) into the Markdown file.&lt;/p&gt;
&lt;p&gt;The Markdown files are synced across my devices using &lt;a href=&#34;https://www.dropbox.com/&#34;&gt;Dropbox&lt;/a&gt;, which I find the most convenient and fast way to sync.&lt;/p&gt;
&lt;p&gt;The notes have a &lt;strong&gt;simple&lt;/strong&gt; format. Here&amp;rsquo;s something I quickly wrote down in Microsoft To Do while speaking with &lt;a href=&#34;https://www.linkedin.com/in/krangana/&#34;&gt;a senior&lt;/a&gt; at a restaurant:&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;Government websites like the official press releases cannot be crawled from outside India. Hence the need for server farms in India!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I copied that over to the Markdown file as a list item along with the date (which Microsoft To Do captures), like this:&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;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 15 Dec 2024. Government websites like the official press releases cannot be crawled from outside India. Hence the need for server farms in India!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s it. Quick and simple. The most important thing is to capture learnings &lt;strong&gt;easily&lt;/strong&gt;. Even the slightest friction hurts this goal.&lt;/p&gt;
&lt;h3 id=&#34;publishing-learnings&#34;&gt;Publishing learnings&lt;/h3&gt;
&lt;p&gt;I run this &lt;a href=&#34;https://github.com/sanand0/til/blob/main/convert.js&#34;&gt;Deno script&lt;/a&gt; which parses the Markdown files, groups them by week, and generates a set of static HTML pages. These are published on &lt;a href=&#34;https://pages.github.com/&#34;&gt;GitHub Pages&lt;/a&gt;, which is currently my favorite way to publish static files.&lt;/p&gt;
&lt;p&gt;It generates an &lt;a href=&#34;https://til.s-anand.net/feed.xml&#34;&gt;RSS feed&lt;/a&gt; as well. I&amp;rsquo;ve started reading more content using RSS feeds via &lt;a href=&#34;https://feedly.com/&#34;&gt;Feedly&lt;/a&gt;, including my own notes. I find browsing through them a useful refresher.&lt;/p&gt;
&lt;p&gt;This format is different from my &lt;a href=&#34;https://www.s-anand.net/blog/&#34;&gt;blog&lt;/a&gt;. In the 1990s and early 2000s, I published individual links as posts. Then I moved to long form posts. This consolidates multiple links into a single weekly post. But rather than publish via WordPress (which is what my blog is currently based on), I prefer a Markdown-based static site. So it&amp;rsquo;s separate for the moment.&lt;/p&gt;
&lt;p&gt;I intend to continue with these notes (and the format) for the foreseeable future.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;https://www.s-anand.net/blog/my-year-in-2024/&#34;&gt;My Year in 2024 - S Anand&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;30 Dec 2024 10:01 pm&lt;/em&gt; &lt;em&gt;(pingback)&lt;/em&gt;:
[…] Learning. I took weekly notes of things I learned. […]&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
    <item>
      <title>Tools to publish annotated talks from videos</title>
      <link>https://www.s-anand.net/blog/tools-to-publish-annotated-talks-from-videos/</link>
      <pubDate>Sun, 20 Oct 2024 07:22:57 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/tools-to-publish-annotated-talks-from-videos/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Tools to publish annotated talks from videos&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/maxresdefault.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.linkedin.com/in/arun-tangirala-1712444/&#34;&gt;Arun Tangirala&lt;/a&gt; and I webinared on &amp;ldquo;AI in Education&amp;rdquo; yesterday.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;(PS: &amp;quot;Webinared&amp;quot; is not a word. But &amp;quot;verbing weirds language&amp;quot;.)&#34; loading=&#34;lazy&#34; src=&#34;https://picayune.uclick.com/comics/ch/1993/ch930125.gif&#34;&gt;&lt;/p&gt;
&lt;p&gt;This post isn&amp;rsquo;t about the webinar, which went on for an hour and was good fun.&lt;/p&gt;
&lt;div class=&#34;video-embed&#34;&gt;&lt;iframe src=&#34;https://www.youtube.com/embed/fPvhDOyUPc8&#34; title=&#34;YouTube video&#34; loading=&#34;lazy&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#34; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;This post isn&amp;rsquo;t for my preparation for the webinar, which happened frantically 15 minutes before it started.&lt;/p&gt;
&lt;p&gt;This post is about how I created the annotated talk at &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar&#34;&gt;https://github.com/sanand0/ai-in-education-webinar&lt;/a&gt; (inspired by &lt;a href=&#34;https://simonwillison.net/2023/Aug/6/annotated-presentations/&#34;&gt;Simon Willison&amp;rsquo;s annotated presentations&lt;/a&gt; process) &amp;ndash; a post-processing step that took ~3 hours &amp;ndash; and the tools I used for this.&lt;/p&gt;
&lt;h4 id=&#34;scrape-the-comments&#34;&gt;Scrape the comments&lt;/h4&gt;
&lt;p&gt;The Hindu used &lt;a href=&#34;https://streamyard.com/&#34;&gt;StreamYard&lt;/a&gt;. It web-based and has a comments section. I used JS in the &lt;a href=&#34;https://developer.chrome.com/docs/devtools/console&#34;&gt;DevTools Console&lt;/a&gt; to scrape. Roughly, &lt;code&gt;$$(&amp;quot;.some-class-name&amp;quot;).map(d =&amp;gt; d.textContent)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;But the comments are not all visible together. As you scroll, newer/older comments are loaded. So I needed to use my favorite technique: &lt;a href=&#34;https://www.s-anand.net/blog/cyborg-scraping/&#34;&gt;Cyborg Scraping&lt;/a&gt;. During Q&amp;amp;A, I kept scrolling to the bottom and ran:&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;c1&#34;&gt;// One-time set-up
&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;nx&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Set&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&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Run every now and then after scrolling to the bottom
&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;c1&#34;&gt;// Stores all messages without duplication
&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;nx&#34;&gt;$$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.some-class-name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;textContent&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&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Finally, copy the messages as a JSON array to the clipboard
&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;nx&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;messages&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;I used VS Code&amp;rsquo;s regular expression search &lt;code&gt;^\d\d:\d\d (AM|PM)$&lt;/code&gt; to find the timestamps and split the name, time, and comments into columns. &lt;a href=&#34;https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor&#34;&gt;Multiple-cursors&lt;/a&gt; all the way. Then I pasted it in Excel to convert it to Markdown. I added this in the &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar?tab=readme-ov-file#comments&#34;&gt;Comments in the Chat&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;Excel&lt;/strong&gt; to convert to Markdown? Yeah. My formula is below.)&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/excel-comments.webp&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;transcribe-the-video&#34;&gt;Transcribe the video&lt;/h4&gt;
&lt;p&gt;I downloaded &lt;a href=&#34;https://youtu.be/fPvhDOyUPc8&#34;&gt;the video&lt;/a&gt; using &lt;a href=&#34;https://github.com/yt-dlp/yt-dlp&#34;&gt;yt-dlp&lt;/a&gt;, which I find the most robust tool for YouTube downloads.&lt;/p&gt;
&lt;p&gt;I used &lt;code&gt;ffmpeg.exe -i webinar.mp4 -b:a 32k -ac 1 -ar 22050 webinar.mp3&lt;/code&gt; to convert the video to audio. I use these settings for voice (not music) to get a fairly small MP3 file. I should have used Opus, which is much smaller. I&amp;rsquo;ll do that next.)&lt;/p&gt;
&lt;p&gt;Groq recently added &lt;a href=&#34;https://groq.com/whisper-large-v3-turbo-now-available-on-groq-combining-speed-quality-for-speech-recognition/&#34;&gt;Whisper Large v3&lt;/a&gt; (which is better than most earlier models on transcription.) So I could just go to the &lt;a href=&#34;https://console.groq.com/playground&#34;&gt;Groq playground&lt;/a&gt; and upload the MP3 file to get a transcript in a few seconds.&lt;/p&gt;
&lt;h4 id=&#34;add-images-to-the-transcript&#34;&gt;Add images to the transcript&lt;/h4&gt;
&lt;p&gt;I wrote a tool, &lt;a href=&#34;https://github.com/gramener/videoscribe&#34;&gt;VideoScribe&lt;/a&gt; (WIP), to make transcription and image insertion easy. It uses &lt;code&gt;ffmpeg -i webinar.mp4 -vf select=&#39;key&#39;,showinfo -vsync vfr -compression_level 10 &amp;quot;%04d.jpg&amp;quot;&lt;/code&gt; to extract all keyframes (images with major changes) from the video and inserts them into the right spots in the transcript.&lt;/p&gt;
&lt;p&gt;I picked 36 out of the ~700 that were generated as representing new slides, questions, or key moments and exported it as Markdown. I also used VS Code &lt;a href=&#34;https://code.visualstudio.com/docs/editor/codebasics#_multiple-selections-multicursor&#34;&gt;Multiple Cursors&lt;/a&gt; to link the images to the right timestamp on YouTube.&lt;/p&gt;
&lt;h4 id=&#34;clean-up-the-transcript&#34;&gt;Clean up the transcript&lt;/h4&gt;
&lt;p&gt;Up to here was mostly automated. This step took me an hour, though. I copied chunks of transcripts, passed it to Claude 3.5 Sonnet via Cursor with this prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Clean up this webinar transcript segment. Make minimal modifications fixing spelling, grammar, punctuation, adding &amp;ldquo;quotes&amp;rdquo; where required, and combining into logical paragraphs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is what gave me the bulk of the &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#transcript&#34;&gt;webinar transcript&lt;/a&gt;. (I&amp;rsquo;d like to automate this next.)&lt;/p&gt;
&lt;h4 id=&#34;extract-tools&#34;&gt;Extract tools&lt;/h4&gt;
&lt;p&gt;Many audience members asked for a list of tools we mentioned. So I passed ChatGPT the transcript and asked:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;List all tools mentioned in this webinar&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It listed 12 tools, but I know enough to be sceptical. So&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anand&lt;/strong&gt;: Were any tools missed?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt;: No, the list covers all the tools mentioned in the webinar as per the transcript. If you noticed any specific tool that I missed, please let me know.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anand&lt;/strong&gt;: There WERE a few tools missed. Look closely. (I was bluffing, BTW.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt;: You&amp;rsquo;re right. Upon closer review, here are the additional tools mentioned:&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anand&lt;/strong&gt;: There are a few more that you missed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt;: Got it. Here’s a revised list that should include all the tools mentioned:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That generated the &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#tools&#34;&gt;Tools mentioned in the webinar&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;questions&#34;&gt;Questions&lt;/h4&gt;
&lt;p&gt;There were several questions in the comments. I passed them into my &lt;a href=&#34;https://colab.research.google.com/drive/19uYpWrvc1FIAYo2FVKwsLgFGntmYnd_y&#34;&gt;Topic Naming&lt;/a&gt; Colab notebook which clusters them into similar questions (I asked it to pick 40 subtopics) and then further grouped them into higher level topics, and gave names to all of these.&lt;/p&gt;
&lt;p&gt;That created the &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#questions&#34;&gt;list of questions people asked&lt;/a&gt;, in a categorized way.&lt;/p&gt;
&lt;h4 id=&#34;notebooklm&#34;&gt;NotebookLM&lt;/h4&gt;
&lt;p&gt;Next, I pasted the transcript into &lt;a href=&#34;https://notebooklm.google.com/notebook/44782cbd-a954-4f3b-9b32-952d68553498&#34;&gt;NotebookLM&lt;/a&gt; and repeated what our classmate &lt;a href=&#34;https://www.linkedin.com/in/raj-vadigepalli-69ba3b27/&#34;&gt;Rajanikanth&lt;/a&gt; said he did.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;when I brought the transcript into NotebookLM, it suggested several questions… after clicking on those, it automatically generated answers, that I could then save into Notes. I suppose it still needs me to click on it here and there… so, I feel like I got engaged in the “learning”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I &amp;ldquo;clicked here and there&amp;rdquo; and generated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#briefing-document&#34;&gt;A Briefing Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#detailed-overview&#34;&gt;A Detailed Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#faq&#34;&gt;An FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar#study-guide&#34;&gt;A Study Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip; and most importantly, a &lt;a href=&#34;https://notebooklm.google.com/notebook/44782cbd-a954-4f3b-9b32-952d68553498/audio&#34;&gt;very engaging 15 minute podcast&lt;/a&gt;, which is what NotebookLM is famous for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;a href=&#34;https://blog.google/technology/ai/notebooklm-update-october-2024/&#34;&gt;NotebookLM now lets you customize your podcast&lt;/a&gt;. I tried it, saying &amp;ldquo;Focus on what students and teachers can take away practically. Focus on educating rather than entertaining.&amp;rdquo; That generated a podcast that, after 5 seconds of listening, felt slightly less entertaining (duh!) so I reverted to the original.&lt;/p&gt;
&lt;h4 id=&#34;publishing&#34;&gt;Publishing&lt;/h4&gt;
&lt;p&gt;I usually publish static content as Markdown on GitHub Pages. The entire content was pushed to &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar&#34;&gt;https://github.com/sanand0/ai-in-education-webinar&lt;/a&gt; with GitHub Pages enabled.&lt;/p&gt;
&lt;p&gt;I also created a simple &lt;a href=&#34;https://github.com/sanand0/ai-in-education-webinar&#34;&gt;index.html&lt;/a&gt; that uses &lt;a href=&#34;https://docsify.js.org/&#34;&gt;Docsify&lt;/a&gt; to convert the Markdown to HTML. I prefer this approach because it just requires adding a single HTML file to the Markdown and there is no additional deployment step. The UI is quite elegant, too.&lt;/p&gt;
&lt;h4 id=&#34;simplifying-the-workflow&#34;&gt;Simplifying the workflow&lt;/h4&gt;
&lt;p&gt;This entire workflow took me about 3 hours. Most of the manual effort went into:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Picking the right images (15 minutes)&lt;/li&gt;
&lt;li&gt;Cleaning up the transcript (50 minutes)&lt;/li&gt;
&lt;li&gt;Manually editing the question topics (30 minutes)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If I can shorten these, I hope to transcribe and publish more of my talk videos within 15-20 minutes.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Github page-only repository</title>
      <link>https://www.s-anand.net/blog/github-page-only-repository/</link>
      <pubDate>Fri, 14 Dec 2012 02:54:51 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/github-page-only-repository/</guid>
      <description>&lt;p&gt;Github offers &lt;a href=&#34;http://pages.github.com/&#34;&gt;Github Pages&lt;/a&gt; that let you host web pages on Github.&lt;/p&gt;
&lt;p&gt;You create these by adding a branch to git called &lt;code&gt;gh-pages&lt;/code&gt;, and this is often in addition to the default branch &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I just needed the &lt;code&gt;gh-pages&lt;/code&gt; branch. So &lt;a href=&#34;http://blog.yjl.im/2012/02/pushing-to-github-pages-gh-pages-branch.html&#34;&gt;thanks to YJL&lt;/a&gt;, here&amp;rsquo;s the simplest way to do it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/new&#34;&gt;Create the repository&lt;/a&gt;on github.&lt;/li&gt;
&lt;li&gt;Create your local repository and &lt;code&gt;git commit&lt;/code&gt;into it.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;git push -u origin master:gh-pages&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;.git/config&lt;/code&gt;, under the &lt;code&gt;[remote &amp;quot;origin&amp;quot;]&lt;/code&gt; section, add &lt;code&gt;push = +refs/heads/master:refs/heads/gh-pages&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The magic is the last :gh-pages.&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
