fix: plain text code blocks now wrap text properly

This commit is contained in:
Wayne Sutton
2025-12-25 00:31:30 -08:00
parent 27847327fd
commit 01db0a70e2
11 changed files with 137 additions and 16 deletions

View File

@@ -22,7 +22,7 @@ Your content is instantly available to browsers, LLMs, and AI agents.. Write mar
- **Total Posts**: 12
- **Total Pages**: 4
- **Latest Post**: 2025-12-25
- **Last Updated**: 2025-12-25T07:17:44.742Z
- **Last Updated**: 2025-12-25T08:31:10.580Z
## Tech stack

View File

@@ -8,10 +8,13 @@
## Current Status
v1.28.1 ready. Fixed RSS feed validation errors by standardizing all URLs to www.markdown.fast.
v1.28.2 ready. Fixed text wrapping for plain text code blocks.
## Completed
- [x] Plain text code blocks now wrap text properly instead of horizontal overflow
- [x] Updated inline vs block code detection logic in BlogPost.tsx
- [x] Added `pre-wrap` styling for text blocks via SyntaxHighlighter props
- [x] RSS feed validation errors fixed by standardizing URLs to www.markdown.fast
- [x] Updated index.html meta tags (og:url, og:image, twitter:domain, twitter:url, twitter:image, JSON-LD)
- [x] Updated convex/rss.ts and convex/http.ts SITE_URL constants

View File

@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [1.28.2] - 2025-12-25
### Fixed
- Plain text code blocks now wrap text properly
- Code blocks without a language specifier were causing horizontal overflow
- Updated detection logic to distinguish inline code from block code
- Inline code: short content (< 80 chars), no newlines, no language
- Block code: longer content or has language specifier
- Text block wrapping uses `pre-wrap` styling via SyntaxHighlighter `customStyle` and `codeTagProps`
- Long error messages and prose in code blocks now display correctly
### Technical
- Updated `src/components/BlogPost.tsx`: New detection logic for inline vs block code, added `textBlockStyle` with wrapping properties
- Updated `src/styles/global.css`: Added `.code-block-text` class for CSS fallback wrapping
## [1.28.1] - 2025-12-25
### Fixed

View File

@@ -27,6 +27,10 @@ The goal: AI services fetch `/raw/{slug}.md` and parse clean markdown without HT
I attempted to load and read the raw markdown at the URL you provided but was unable to fetch the content from that link. The page could not be loaded directly and I cannot access its raw markdown.
```
```
The page could not be loaded with the tools currently available, so its raw markdown content is not accessible.
```
**Perplexity:**
```
@@ -89,8 +93,14 @@ Added explicit bypass for known AI user agents:
```typescript
const AI_CRAWLERS = [
"gptbot", "chatgpt", "chatgpt-user", "oai-searchbot",
"claude-web", "claudebot", "anthropic", "perplexitybot"
"gptbot",
"chatgpt",
"chatgpt-user",
"oai-searchbot",
"claude-web",
"claudebot",
"anthropic",
"perplexitybot",
];
if (isAICrawler(userAgent)) {
@@ -112,7 +122,7 @@ exports.handler = async (event) => {
return {
statusCode: 200,
headers: { "Content-Type": "text/plain; charset=utf-8" },
body: markdownContent
body: markdownContent,
};
};
```

View File

@@ -8,6 +8,21 @@ layout: "sidebar"
All notable changes to this project.
## v1.28.2
Released December 25, 2025
**Plain text code block wrapping**
- Code blocks without a language specifier now wrap text properly
- Fixed horizontal overflow for long error messages and prose in code blocks
- Updated inline vs block code detection logic
- Inline code: short content (< 80 chars), no newlines, no language class
- Block code: longer content or has language specifier
- Text wrapping uses `pre-wrap` styling applied via SyntaxHighlighter props
Updated files: `src/components/BlogPost.tsx`, `src/styles/global.css`
## v1.28.1
Released December 25, 2025

View File

@@ -53,7 +53,7 @@ A brief description of each file in the codebase.
| `Layout.tsx` | Page wrapper with logo in header (top-left), search button, theme toggle, mobile menu (left-aligned on mobile), and scroll-to-top. Combines Blog link, hardcoded nav items, and markdown pages for navigation. Logo reads from siteConfig.innerPageLogo |
| `ThemeToggle.tsx` | Theme switcher (dark/light/tan/cloud) |
| `PostList.tsx` | Year-grouped blog post list or card grid (supports list/cards view modes) |
| `BlogPost.tsx` | Markdown renderer with syntax highlighting and collapsible sections (details/summary) |
| `BlogPost.tsx` | Markdown renderer with syntax highlighting, collapsible sections (details/summary), and text wrapping for plain text code blocks |
| `CopyPageDropdown.tsx` | Share dropdown with Copy page (markdown to clipboard), View as Markdown (opens raw .md file), Download as SKILL.md (Anthropic Agent Skills format), and Open in AI links (ChatGPT, Claude, Perplexity) using GitHub raw URLs with universal prompt |
| `SearchModal.tsx` | Full text search modal with keyboard navigation |
| `FeaturedCards.tsx` | Card grid for featured posts/pages with excerpts |

View File

@@ -1,12 +1,12 @@
# llms.txt - Information for AI assistants and LLMs
# Learn more: https://llmstxt.org/
# Last updated: 2025-12-25T07:17:44.744Z
# Last updated: 2025-12-25T08:31:10.582Z
> Your content is instantly available to browsers, LLMs, and AI agents.
# Site Information
- Name: markdown
- URL: https://www.markdown.fast
- URL: https://markdown.fast
- Description: Your content is instantly available to browsers, LLMs, and AI agents. Write markdown, sync from the terminal. Your content is instantly available to browsers, LLMs, and AI agents. Built on Convex and Netlify.
- Topics: Markdown, Convex, React, TypeScript, Netlify, Open Source, AI, LLM, AEO, GEO
- Total Posts: 12

View File

@@ -7,6 +7,36 @@ Date: 2025-12-25
All notable changes to this project.
## v1.28.2
Released December 25, 2025
**Plain text code block wrapping**
- Code blocks without a language specifier now wrap text properly
- Fixed horizontal overflow for long error messages and prose in code blocks
- Updated inline vs block code detection logic
- Inline code: short content (< 80 chars), no newlines, no language class
- Block code: longer content or has language specifier
- Text wrapping uses `pre-wrap` styling applied via SyntaxHighlighter props
Updated files: `src/components/BlogPost.tsx`, `src/styles/global.css`
## v1.28.1
Released December 25, 2025
**RSS feed validation fixes**
- Standardized all URLs to `www.markdown.fast` across the application
- Fixed `atom:link rel="self"` attribute mismatch that caused RSS validation failures
- Updated `index.html` meta tags (og:url, og:image, twitter:domain, twitter:url, twitter:image, JSON-LD)
- Updated `convex/rss.ts` and `convex/http.ts` SITE_URL constants to use www.markdown.fast
- Updated `public/robots.txt`, `public/openapi.yaml`, and `public/llms.txt` with www URLs
- RSS exclusions already present in `netlify.toml` for botMeta edge function
All URL references now consistently use `https://www.markdown.fast`. RSS feed `rel="self"` attribute now matches actual feed URL. Build passes successfully.
## v1.28.0
Released December 25, 2025

View File

@@ -27,6 +27,10 @@ The goal: AI services fetch `/raw/{slug}.md` and parse clean markdown without HT
I attempted to load and read the raw markdown at the URL you provided but was unable to fetch the content from that link. The page could not be loaded directly and I cannot access its raw markdown.
```
```
The page could not be loaded with the tools currently available, so its raw markdown content is not accessible.
```
**Perplexity:**
```
@@ -89,8 +93,14 @@ Added explicit bypass for known AI user agents:
```typescript
const AI_CRAWLERS = [
"gptbot", "chatgpt", "chatgpt-user", "oai-searchbot",
"claude-web", "claudebot", "anthropic", "perplexitybot"
"gptbot",
"chatgpt",
"chatgpt-user",
"oai-searchbot",
"claude-web",
"claudebot",
"anthropic",
"perplexitybot",
];
if (isAICrawler(userAgent)) {
@@ -112,7 +122,7 @@ exports.handler = async (event) => {
return {
statusCode: 200,
headers: { "Content-Type": "text/plain; charset=utf-8" },
body: markdownContent
body: markdownContent,
};
};
```

View File

@@ -307,27 +307,55 @@ export default function BlogPost({ content }: BlogPostProps) {
remarkPlugins={[remarkGfm, remarkBreaks]}
rehypePlugins={[rehypeRaw, [rehypeSanitize, sanitizeSchema]]}
components={{
code({ className, children, ...props }) {
code(codeProps) {
const { className, children, node, style, ...restProps } = codeProps as {
className?: string;
children?: React.ReactNode;
node?: { tagName?: string; properties?: { className?: string[] } };
style?: React.CSSProperties;
inline?: boolean;
};
const match = /language-(\w+)/.exec(className || "");
const isInline = !match && !className;
// Detect inline code: no language class AND content is short without newlines
// Fenced code blocks (even without language) are longer or have structure
const codeContent = String(children);
const hasNewlines = codeContent.includes('\n');
const isShort = codeContent.length < 80;
const hasLanguage = !!match || !!className;
// It's inline only if: no language, short content, no newlines
const isInline = !hasLanguage && isShort && !hasNewlines;
if (isInline) {
return (
<code className="inline-code" {...props}>
<code className="inline-code" style={style} {...restProps}>
{children}
</code>
);
}
const codeString = String(children).replace(/\n$/, "");
const language = match ? match[1] : "text";
const isTextBlock = language === "text";
// Custom styles for text blocks to enable wrapping
const textBlockStyle = isTextBlock ? {
whiteSpace: "pre-wrap" as const,
wordWrap: "break-word" as const,
overflowWrap: "break-word" as const,
} : {};
return (
<div className="code-block-wrapper">
<div className={`code-block-wrapper ${isTextBlock ? "code-block-text" : ""}`}>
{match && <span className="code-language">{match[1]}</span>}
<CodeCopyButton code={codeString} />
<SyntaxHighlighter
style={getCodeTheme()}
language={match ? match[1] : "text"}
language={language}
PreTag="div"
customStyle={textBlockStyle}
codeTagProps={isTextBlock ? { style: textBlockStyle } : undefined}
>
{codeString}
</SyntaxHighlighter>

View File

@@ -1388,6 +1388,14 @@ body {
margin: 24px 0;
}
/* Allow text wrapping for plain text code blocks */
.code-block-text pre,
.code-block-text code {
white-space: pre-wrap !important;
word-wrap: break-word !important;
overflow-wrap: break-word !important;
}
.code-language {
position: absolute;
top: 8px;