Simon Willison’s Weblog

Subscribe

Tuesday, 4th February 2025

Tool SQL Pretty Printer — Format and beautify SQL queries with customizable styling options. This tool supports multiple SQL dialects including SQLite, PostgreSQL, and MySQL, allowing you to control indentation width, keyword capitalization, and indentation style. The formatted output can be easily copied to your clipboard with a single click.

Build a link blog (via) Xuanwo started a link blog inspired by my article My approach to running a link blog, and in a delightful piece of recursion his first post is a link blog entry about my post about link blogging, following my tips on quoting liberally and including extra commentary.

I decided to follow simon's approach to creating a link blog, where I can share interesting links I find on the internet along with my own comments and thoughts about them.

# 4:14 pm / blogging

Animating Rick and Morty One Pixel at a Time (via) Daniel Hooper says he spent 8 months working on the post, the culmination of which is an animation of Rick from Rick and Morty, implemented in 240 lines of GLSL - the OpenGL Shading Language which apparently has been directly supported by browsers for many years.

The result is a comprehensive GLSL tutorial, complete with interactive examples of each of the steps used to generate the final animation which you can tinker with directly on the page. It feels a bit like Logo!

Animated demo - as I edit the shader code Rick's half-drawn eye pupils move from side to side live with my edits

Shaders work by running code for each pixel to return that pixel's color - in this case the color_for_pixel() function is wired up as the core logic of the shader.

Here's Daniel's code for the live shader editor he built for this post. It looks like this is the function that does the most important work:

function loadShader(shaderSource, shaderType) {
    const shader = gl.createShader(shaderType);
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compiled) {
        const lastError = gl.getShaderInfoLog(shader);
        gl.deleteShader(shader);
        return lastError;
    }
    return shader;
}

Where gl is a canvas.getContext("webgl2") WebGL2RenderingContext object, described by MDN here.

# 8:53 pm / animation, canvas, javascript, webgl

TIL Running pytest against a specific Python version with uv run — While [working on this issue](https://github.com/simonw/datasette/issues/2461) I figured out a neat pattern for running the tests for my project locally against a specific Python version using [uv run](https://docs.astral.sh/uv/guides/scripts/):
TIL Running pytest against a specific Python version with uv run — While [working on this issue](https://github.com/simonw/datasette/issues/2461) I figured out a neat pattern for running the tests for my project locally against a specific Python version using [uv run](https://docs.astral.sh/uv/guides/scripts/):
Monday, 3rd February 2025
Wednesday, 5th February 2025