Skip to content

Instantly share code, notes, and snippets.

@simonw

simonw/bug.txt Secret

Created March 11, 2025 00:06
Show Gist options
  • Select an option

  • Save simonw/d5ccbca1b530868980609222790a97cb to your computer and use it in GitHub Desktop.

Select an option

Save simonw/d5ccbca1b530868980609222790a97cb to your computer and use it in GitHub Desktop.
tools % claude
╭────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code research preview! │
│ │
│ /help for help │
│ │
│ cwd: /Users/simon/Dropbox/Development/tools │
╰────────────────────────────────────────────────╯
> run python build_colophon.py - this produces a colophon.html page. Inspect the first 100 lines of this page to see a bug where <br> tags
are sometimes included inside links
⏺ Bash(python build_colophon.py)…
⎿ Colophon page built successfully as colophon.html
⏺ Read(file_path: "/Users/simon/Dropbox/Development/tools/colophon.html", limit: 100)…
⎿ <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tools.simonwillison.net colophon</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
max-width: 800px;
margin: 0 auto;
padding: 1rem;
color: #1a1a1a;
}
h1 {
border-bottom: 2px solid #f0f0f0;
padding-bottom: 0.5rem;
margin-top: 2rem;
}
h2 {
margin-top: 2rem;
font-size: 1.4rem;
}
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.tool {
margin-bottom: 2rem;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 1rem;
}
.tool-name {
font-weight: bold;
}
.commit {
background-color: #f8f9fa;
padding: 1rem;
margin: 0.75rem 0;
border-radius: 4px;
border-left: 3px solid #ddd;
}
.commit-hash {
font-family: monospace;
color: #666;
font-size: 0.85rem;
}
.commit-date {
color: #666;
font-size: 0.85rem;
margin-left: 0.5rem;
}
.commit-message {
margin-top: 0.5rem;
}
.urls {
margin-top: 1rem;
}
@media (max-width: 600px) {
body {
padding: 0.5rem;
}
.commit {
padding: 0.75rem;
}
}
</style>
</head>
<body>
<h1>tools.simonwillison.net colophon</h1>
<p>The tools on <a href="https://tools.simonwillison.net/">tools.simonwillison.net</a> were mostly built using <a
href="https://simonwillison.net/tags/ai-assisted-programming/">AI-assisted programming</a>.</p>
<p>This page lists the commit messages for each tool, many of which link to the LLM transcript used to produce the code.</p>
<div class="tool">
<h2 class="tool-name"><a href="https://tools.simonwillison.net/social-media-cropper">social-media-cropper.html</a></h2>
<div class="commit">
<div>
<a href="https://github.com/simonw/tools/commit/
b4a2bc98753c3b6592a7cd86a9510bc6bf552efb" class="commit-hash" target="_blank">
b4a2bc</a>
<span class="commit-date">December 10, 2024 20:35</span>
</div>
<div class="commit-message">Social media cropper<br><br><a
href="https://gist.github.com/simonw/12b8f88932a71450071190e1289a17e9<br>"
target="_blank">https://gist.github.com/simonw/12b8f88932a71450071190e1289a17e9<br></a></div>
</div>
<div class="commit">
<div>
<a href="https://github.com/simonw/tools/commit/
a109547bd328397b4eb7160cd1263f533cce3ea1" class="commit-hash" target="_blank">
a10954</a>
<span class="commit-date">February 28, 2025 16:02</span>
</div>
<div class="commit-message">Support 2:1 and 14:10 ratios<br><br><a
href="https://gist.github.com/simonw/e23917eddcbb368c9b6180d581f8f40a<br>"
target="_blank">https://gist.github.com/simonw/e23917eddcbb368c9b6180d581f8f40a<br></a></div>
</div>
⏺ I found the bug. There are <br> tags inside the link URLs on lines 88 and 98, causing the links to break. The links should be a single
URL without any line breaks inside the <a> tags.
> fix it
⏺ Read(file_path: "/Users/simon/Dropbox/Development/tools/build_colophon.py")…
⎿ #!/usr/bin/env python3
import json
import re
from datetime import datetime
import html
from pathlib import Path
def linkify_urls(text):
"""Convert URLs in text to clickable links."""
url_pattern = r"(https?://[^\s]+)"
return re.sub(url_pattern, r'<a href="\1" target="_blank">\1</a>', text)
def format_commit_message(message):
"""Format commit message with line breaks and linkified URLs."""
# Escape HTML entities
escaped = html.escape(message)
# Convert newlines to <br>
with_breaks = escaped.replace("\n", "<br>")
# Linkify URLs
return linkify_urls(with_breaks)
def build_colophon():
# Load the gathered_links.json file
try:
with open("gathered_links.json", "r") as f:
data = json.load(f)
except FileNotFoundError:
print("Error: gathered_links.json not found. Run gather_links.py first.")
return
pages = data.get("pages", {})
if not pages:
print("No pages found in gathered_links.json")
return
# Sort pages by most recent commit date (newest first)
def get_most_recent_date(page_data):
commits = page_data.get("commits", [])
if not commits:
return "0000-00-00T00:00:00"
# Find the most recent commit date
dates = [commit.get("date", "0000-00-00T00:00:00") for commit in commits]
return max(dates) if dates else "0000-00-00T00:00:00"
sorted_pages = sorted(
pages.items(), key=lambda x: get_most_recent_date(x[1]), reverse=True
)
# Start building the HTML
html_content = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tools.simonwillison.net colophon</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
max-width: 800px;
margin: 0 auto;
padding: 1rem;
color: #1a1a1a;
}
h1 {
border-bottom: 2px solid #f0f0f0;
padding-bottom: 0.5rem;
margin-top: 2rem;
}
h2 {
margin-top: 2rem;
font-size: 1.4rem;
}
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.tool {
margin-bottom: 2rem;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 1rem;
}
.tool-name {
font-weight: bold;
}
.commit {
background-color: #f8f9fa;
padding: 1rem;
margin: 0.75rem 0;
border-radius: 4px;
border-left: 3px solid #ddd;
}
.commit-hash {
font-family: monospace;
color: #666;
font-size: 0.85rem;
}
.commit-date {
color: #666;
font-size: 0.85rem;
margin-left: 0.5rem;
}
.commit-message {
margin-top: 0.5rem;
}
.urls {
margin-top: 1rem;
}
@media (max-width: 600px) {
body {
padding: 0.5rem;
}
.commit {
padding: 0.75rem;
}
}
</style>
</head>
<body>
<h1>tools.simonwillison.net colophon</h1>
<p>The tools on <a href="https://tools.simonwillison.net/">tools.simonwillison.net</a> were mostly built using <a
href="https://simonwillison.net/tags/ai-assisted-programming/">AI-assisted programming</a>.</p>
<p>This page lists the commit messages for each tool, many of which link to the LLM transcript used to produce the code.</p>
"""
# Add each page with its commits
for page_name, page_data in sorted_pages:
tool_url = f"https://tools.simonwillison.net/{page_name.replace('.html', '')}"
commits = page_data.get("commits", [])
# Reverse the commits list to show oldest first
commits = list(reversed(commits))
html_content += f"""
<div class="tool">
<h2 class="tool-name"><a href="{tool_url}">{page_name}</a></h2>
"""
# Add each commit
for commit in commits:
commit_hash = commit.get("hash", "")
short_hash = commit_hash[:7] if commit_hash else "unknown"
commit_date = commit.get("date", "")
# Format the date with time
formatted_date = ""
if commit_date:
try:
dt = datetime.fromisoformat(commit_date)
formatted_date = dt.strftime("%B %d, %Y %H:%M")
except ValueError:
formatted_date = commit_date
commit_message = commit.get("message", "")
formatted_message = format_commit_message(commit_message)
commit_url = f"https://github.com/simonw/tools/commit/{commit_hash}"
html_content += f"""
<div class="commit">
<div>
<a href="{commit_url}" class="commit-hash" target="_blank">{short_hash}</a>
<span class="commit-date">{formatted_date}</span>
</div>
<div class="commit-message">{formatted_message}</div>
</div>
"""
html_content += """
</div>
"""
# Close the HTML
html_content += """
</body>
</html>
"""
# Write the HTML to colophon.html
with open("colophon.html", "w") as f:
f.write(html_content)
print("Colophon page built successfully as colophon.html")
if __name__ == "__main__":
build_colophon()
⏺ Update(file_path: /Users/simon/Dropbox/Development/tools/build_colophon.py)…
⎿ Updated /Users/simon/Dropbox/Development/tools/build_colophon.py with 7 additions and 10 removals
6 from pathlib import Path
7
8
9 def linkify_urls(text):
10 """Convert URLs in text to clickable links."""
11 url_pattern = r"(https?://[^\s]+)"
12 return re.sub(url_pattern, r'<a href="\1" target="_blank">\1</a>', text)
13
14
9 def format_commit_message(message):
10 """Format commit message with line breaks and linkified URLs."""
11 # Escape HTML entities
12 escaped = html.escape(message)
13 # Convert newlines to <br>
14 with_breaks = escaped.replace("\n", "<br>")
15 # Linkify URLs
16 return linkify_urls(with_breaks)
13
14 # Linkify URLs first (before adding breaks)
15 url_pattern = r"(https?://[^\s]+)"
16 linkified = re.sub(url_pattern, r'<a href="\1" target="_blank">\1</a>', escaped)
17
18 # Then convert newlines to <br>
19 return linkified.replace("\n", "<br>")
20
21
22 def build_colophon():
⏺ Bash(python build_colophon.py)…
⎿ Colophon page built successfully as colophon.html
⏺ Read(file_path: "/Users/simon/Dropbox/Development/tools/colophon.html", limit: 100)…
⎿ <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tools.simonwillison.net colophon</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
max-width: 800px;
margin: 0 auto;
padding: 1rem;
color: #1a1a1a;
}
h1 {
border-bottom: 2px solid #f0f0f0;
padding-bottom: 0.5rem;
margin-top: 2rem;
}
h2 {
margin-top: 2rem;
font-size: 1.4rem;
}
a {
color: #0066cc;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.tool {
margin-bottom: 2rem;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 1rem;
}
.tool-name {
font-weight: bold;
}
.commit {
background-color: #f8f9fa;
padding: 1rem;
margin: 0.75rem 0;
border-radius: 4px;
border-left: 3px solid #ddd;
}
.commit-hash {
font-family: monospace;
color: #666;
font-size: 0.85rem;
}
.commit-date {
color: #666;
font-size: 0.85rem;
margin-left: 0.5rem;
}
.commit-message {
margin-top: 0.5rem;
}
.urls {
margin-top: 1rem;
}
@media (max-width: 600px) {
body {
padding: 0.5rem;
}
.commit {
padding: 0.75rem;
}
}
</style>
</head>
<body>
<h1>tools.simonwillison.net colophon</h1>
<p>The tools on <a href="https://tools.simonwillison.net/">tools.simonwillison.net</a> were mostly built using <a
href="https://simonwillison.net/tags/ai-assisted-programming/">AI-assisted programming</a>.</p>
<p>This page lists the commit messages for each tool, many of which link to the LLM transcript used to produce the code.</p>
<div class="tool">
<h2 class="tool-name"><a href="https://tools.simonwillison.net/social-media-cropper">social-media-cropper.html</a></h2>
<div class="commit">
<div>
<a href="https://github.com/simonw/tools/commit/
b4a2bc98753c3b6592a7cd86a9510bc6bf552efb" class="commit-hash" target="_blank">
b4a2bc</a>
<span class="commit-date">December 10, 2024 20:35</span>
</div>
<div class="commit-message">Social media cropper<br><br><a
href="https://gist.github.com/simonw/12b8f88932a71450071190e1289a17e9"
target="_blank">https://gist.github.com/simonw/12b8f88932a71450071190e1289a17e9</a><br></div>
</div>
<div class="commit">
<div>
<a href="https://github.com/simonw/tools/commit/
a109547bd328397b4eb7160cd1263f533cce3ea1" class="commit-hash" target="_blank">
a10954</a>
<span class="commit-date">February 28, 2025 16:02</span>
</div>
<div class="commit-message">Support 2:1 and 14:10 ratios<br><br><a
href="https://gist.github.com/simonw/e23917eddcbb368c9b6180d581f8f40a"
target="_blank">https://gist.github.com/simonw/e23917eddcbb368c9b6180d581f8f40a</a><br></div>
</div>
⏺ Fixed! The order of operations was the issue. I changed the code to:
1. First escape HTML entities
2. Then link the URLs
3. Finally replace newlines with <br> tags
This way, the URL linking happens before newline replacement, preventing <br> tags from being included inside the URL links.
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ > │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Press Ctrl-C again to exit \⏎ for newline
Total cost: $0.1144
Total duration (API): 30.5s
Total duration (wall): 1m 18.2s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment