Maintain a Proprietary Extended Markdown Flavor Rendering Pipeline
Current Tasks:
Add Internal Embeds:
We will probably need to add
content/visuals
as a collection....content/visuals
contains images and svg files that are sometimes or often used throughout the content.The extended markdown is Obsidian flavored, and the internal links are in the form:
![[Visuals/v2__Data Model Database--In-Action.png]]
Internal links can come with width and height, like:
![[Visuals/Engelbart.jpg|100x145]]
content/visuals
is the directory in the monorepo, content submodule that is connected to Obsidan through a symbolic link to "Visuals" collection.These are differentiated from externally hosted images, which are in the form:

We may have code in the file:
site/src/utils/markdown/remark-images.ts
Extended Markdown Rendering Pipeline Specification
1. System Overview
Our extended markdown rendering pipeline is built on top of Astro's markdown processing capabilities, utilizing the Unified ecosystem (Remark for markdown, Rehype for HTML) to handle various custom extensions. The pipeline is designed to be modular, type-safe, and maintainable, with clear separation of concerns between different processing stages.
graph TD
A[Markdown Content] --> B[Remark Parser]
B --> C[AST]
C --> D[Remark Plugins]
D --> E[Rehype]
E --> F[Rehype Plugins]
F --> G[HTML]
G --> H[Astro Components]
1.1 Core Technologies
- Astro: Primary framework and build system
- Unified: Text processing framework
- Remark: Markdown processor and plugin system
- remark-gfm: GitHub Flavored Markdown support
- Tables with alignment
- Task lists (
- [ ]
and- [x]
) - Strikethrough (
~~text~~
) - URL autolinking
- Footnotes
- Rehype: HTML processor and plugin system
- TypeScript: Type system and development language
1.2 Key Architecture
An example entry point that is working well is:
site/src/pages/read/essays/[...slug].astro
text
site/src/layouts/OneArticle.astro
site/src/components/markdown/AstroMarkdown.astro
Important Component Files
text
site/src/components/markdown/TableOfContents.astro
site/src/components/markdown/ImageGallery.astro
site/src/components/markdown/ToolingGallery.astro
Important Utility Files
text
site/src/utils/markdown/
├── remark-callout.ts # Callout block processing
├── remark-citations.ts # Citation handling
├── remark-images.ts # Image processing
├── remark-backlinks.ts # Wiki-link processing
├── remark-codeblocks.ts # Custom code block handling
├── remark-toc.ts # Table of contents generation
├── normalizeShellLangs.ts # Shell language normalization
└── remark-mermaid.ts # Mermaid diagram support
2. Custom Markdown Extensions
2.1 Callouts
- Syntax:
> [!NOTE]
or> [!WARNING]
- Processed by:
remark-callout.ts
- Rendered by: Custom callout components
- Features:
- Multiple callout types (NOTE, WARNING, TIP, etc.)
- Nested content support
- Custom styling per callout type
2.2 Citations
- Syntax:
[^1]
or[^citation-key]
- Processed by:
remark-citations.ts
- Rendered as: Interactive footnotes with backlinks
- Features:
- Automatic numbering
- Reference list generation
- Backlink support
2.3 iFrames
- Processed by: Custom iframe handling
- Features:
- Responsive embeds
- Lazy loading
- Custom aspect ratios
2.4 Wiki-Links
- Syntax:
[[Page Name]]
or[[Display Text|Page Name]]
- Processed by:
remark-backlinks.ts
- Features:
- Automatic path resolution
- Backlink generation
- Custom display text support
2.5 Custom Code Blocks
- Processed by:
remark-codeblocks.ts
- Features:
- Syntax highlighting
- Line numbers
- Copy-to-clipboard
- Special handling for:
- Mermaid diagrams
- Image galleries
- Tooling galleries
2. Extension Types and Processing Order
2.1 Processing Pipeline Order
- Container Elements (First Pass)
- Callouts
- Alert blocks
- Custom containers
- Inline Elements (Second Pass)
- Wiki-links (backlinks)
- Citations
- Custom inline syntax
- Rich Content (Third Pass)
- iFrames
- Images
- Code blocks
- Final Processing (Fourth Pass)
- HTML generation
- Component mapping
- Style application
2.2 Supported Extensions
- Callouts
- Syntax:
> [!NOTE]
or similar - Types: NOTE, WARNING, INFO, etc.
- Nested content support
- Citation compatibility
- Citations
- Inline:
[1]
,[2]
, etc. - Section:
Citations:
header - URL support
- Automatic collection and rendering
- iFrames
- Raw HTML support
- YouTube/Loom optimizations
- Responsive containers
- Attribute preservation
- Wiki-Links
- Double bracket syntax:
[[page]]
- Title support:
[[page|title]]
- Automatic backlink generation
- Path resolution
- Custom Code Blocks
- Language-specific highlighting
- Custom block types
- Metadata support
- Component mapping
Custom Codeblocks in Production
imageGallery
toolingGallery
Ideas for Custom Codeblocks
Much Smaller Tooling Gallery
ImageGrid
3. Implementation Details
3.1 AST Processing Strategy
- Detection Phasetypescript
// Example for callouts visit(tree, 'blockquote', (node, index, parent) => { if (isCallout(node)) { const calloutNode = transformToCallout(node); replaceNode(parent, index, calloutNode); } });
- Transformation Phasetypescript
// Common node transformation pattern interface TransformedNode extends Parent { type: string; data: { hName: string; hProperties: Record<string, unknown>; }; }
- Component Mappingtypescript
// In AstroMarkdown.astro const HANDLED_TYPES = { callout: ArticleCallout, citation: ArticleCitations, html: Fragment, // ... other mappings };
3.2 Type Safety
- Node Type Definitionstypescript
// In site/src/types/mdast.d.ts declare module 'mdast' { interface StaticPhrasingContent { type: string; value?: string; data?: { hName?: string; hProperties?: Record<string, unknown>; }; } }
- Plugin Optionstypescript
interface PluginOptions { debug?: boolean; preserveOriginal?: boolean; // Extension-specific options }
3.3 Error Handling
- Graceful Degradationtypescript
try { // Process extension return transformedNode; } catch (error) { console.error(`Error processing ${type}:`, error); return originalNode; // Preserve original content }
- Debug Outputtypescript
if (options.debug) { astDebugger.writeDebugFile( `${phase}-${type}`, JSON.stringify(node, null, 2) ); }
4. Component Architecture
4.1 Base Components
- AstroMarkdown
- Entry point for rendering
- Node type routing
- Error boundary
- Extension Components
- Specialized rendering
- Prop validation
- Style encapsulation
4.2 Style Management
- CSS Modulescss
/* Extension-specific styles */ .extension-container { width: 100%; box-sizing: border-box; } .text-wrapper { display: inline-block; width: 100%; word-wrap: break-word; word-break: break-word; overflow-wrap: break-word; hyphens: auto; }
- Responsive Designcss
/* Common responsive patterns */ .responsive-container { position: relative; padding-bottom: 56.25%; height: 0; } .responsive-iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
5. Configuration
5.1 Astro Config
javascript
// astro.config.mjs
export default defineConfig({
markdown: {
remarkPlugins: [
remarkGfm, // GitHub Flavored Markdown support
remarkCalloutHandler,
remarkBacklinks,
remarkImages,
remarkCitations
],
remarkRehype: {
allowDangerousHtml: true,
handlers: defListHastHandlers
},
rehypePlugins: [
rehypeRaw
]
}
});
5.2 Plugin Registration
typescript
// Plugin registration pattern
export default function remarkExtension(options: Options = {}) {
return (tree: Root) => {
// 1. Detection
const nodes = detectNodes(tree);
// 2. Transformation
const transformed = transformNodes(nodes);
// 3. Insertion
return insertNodes(tree, transformed);
};
}
6. Testing and Validation
6.1 Test Files
- Basic Features
content/vocabulary/agile.md
- Tests common extensions
- Complex Cases
- Nested extensions
- Mixed content types
- Edge cases
6.2 Debug Process
- AST Inspection
- Debug files per phase
- Node structure validation
- Type checking
- Visual Validation
- Component rendering
- Style application
- Responsive behavior
7. References
File Structure of Working Code
Core Processing
text
site/src/utils/markdown/
├── debug/
│ └── markdown-debugger.ts # AST debugging utilities
├── plugins/
│ ├── remark-callout.ts # Callout processing
│ ├── remark-backlinks.ts # Wiki-link handling
│ ├── remark-citations.ts # Citation processing
│ └── remark-images.ts # Image handling
└── types/
├── mdast.d.ts # Core AST types
├── mdast-callout.d.ts # Callout types
└── mdast-citation.d.ts # Citation types
Component Structure
text
site/src/components/markdown/
├── AstroMarkdown.astro # Main renderer
├── callouts/
│ └── ArticleCallout.astro # Callout component
├── citations/
│ └── ArticleCitations.astro # Citations component
└── common/
└── ResponsiveContainer.astro # Shared components
Image Handling
Wiki-Style Image Syntax
While we initially attempted to support wiki-style image syntax (e.g.
![[image.png]]
) using custom remark plugins and AST transformations, we encountered several challenges:- Complex path normalization between assets/ and visuals/ directories
- AST transformation issues with maintaining proper node types
- Performance concerns with local image serving
- Lack of image optimization capabilities
Decision: Instead of maintaining a complex local image handling pipeline, we will transition to using a remote image hosting service (e.g. ImageKit). This will provide:
- Simplified markdown processing
- CDN-based image delivery
- Built-in image optimization
- Automatic format conversion
- Responsive images support
The wiki-style image syntax implementation will be revisited after establishing a robust remote image hosting workflow.
This specification serves as a living document for our extended markdown rendering pipeline. It should be updated as new extensions are added or existing ones are modified.