Convert WordPress [caption] shortcodes to proper HTML figures

- Add convertCaptionShortcodes() to transform [caption]...[/caption] into
  <figure class="wp-caption"> with <figcaption>
- Handle both plain images and linked images (wrapped in <a> tags)
- Add CSS styling for figure captions in prose content
- All 17 posts with captions now display properly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-05 13:59:15 +00:00
parent 204679b740
commit 64da557836
4 changed files with 81 additions and 21 deletions

View File

@ -99,12 +99,53 @@ function extractImages(content) {
return images; return images;
} }
// Convert WordPress [caption] shortcodes to HTML figure/figcaption
function convertCaptionShortcodes(html) {
// Pattern: [caption id="" align="..." width="..."]<a>...<img>...</a> or <img.../> Caption text [/caption]
// The caption text is after the img/a tag and before [/caption]
return html.replace(
/\[caption[^\]]*\]([\s\S]*?)\[\/caption\]/gi,
(match, content) => {
// Try to match either <a><img></a> or just <img>
let imgMatch = content.match(/(<a[^>]*>[\s\S]*?<\/a>)/i);
if (!imgMatch) {
// No link wrapping, try just img tag
imgMatch = content.match(/(<img[^>]*\/?>)/i);
}
if (!imgMatch) {
// No image found, just return the content without shortcode
return content.trim();
}
const imgTag = imgMatch[1];
// Caption text is everything after the image/link tag
const afterImg = content.substring(content.indexOf(imgTag) + imgTag.length);
let captionText = afterImg.trim();
// Clean up the caption text
captionText = captionText
.replace(/^\s+|\s+$/g, '') // Trim whitespace
.replace(/\s+/g, ' '); // Normalize spaces
if (captionText) {
return `<figure class="wp-caption">${imgTag}<figcaption>${captionText}</figcaption></figure>`;
} else {
return `<figure class="wp-caption">${imgTag}</figure>`;
}
}
);
}
// Clean HTML content - convert to simpler format // Clean HTML content - convert to simpler format
function cleanContent(html) { function cleanContent(html) {
if (!html) return ''; if (!html) return '';
// First convert WordPress caption shortcodes to proper HTML
let clean = convertCaptionShortcodes(html);
// Remove Squarespace-specific attributes and classes // Remove Squarespace-specific attributes and classes
let clean = html clean = clean
.replace(/data-sqsp[^=]*="[^"]*"/g, '') .replace(/data-sqsp[^=]*="[^"]*"/g, '')
.replace(/class="[^"]*sqs[^"]*"/g, '') .replace(/class="[^"]*sqs[^"]*"/g, '')
.replace(/style="white-space:pre-wrap;"/g, '') .replace(/style="white-space:pre-wrap;"/g, '')

View File

@ -141,6 +141,25 @@ a:hover {
text-underline-offset: 2px; text-underline-offset: 2px;
} }
/* Figure captions for blog images */
.prose figure.wp-caption {
margin: 2em 0;
text-align: center;
}
.prose figure.wp-caption img {
max-width: 100%;
height: auto;
margin-bottom: 0.5em;
}
.prose figure.wp-caption figcaption {
font-size: 0.875rem;
color: var(--muted);
font-style: italic;
padding: 0 1rem;
}
/* Image hover zoom effect */ /* Image hover zoom effect */
.img-zoom { .img-zoom {
overflow: hidden; overflow: hidden;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long