Centralized Debug System for Markdown Processing
Summary
Implemented a centralized debugging system for markdown processing to reduce console output during builds and provide configurable debug levels through environment variables and URL parameters.
Why Care
Excessive debug output was causing noise during builds and development. This refactoring provides a cleaner, more organized approach to debugging with granular control over what gets logged, making development more efficient and builds cleaner.
Implementation
Changes Made
- Created a new centralized debugging utility in
site/src/utils/debug/markdown-debugger.ts
- Added environment variable configuration in
site/.env.example
- Updated all remark plugins to use the new debugging utility:
site/src/utils/markdown/remarkCitations.ts
site/src/utils/markdown/remark-backlinks.ts
site/src/utils/markdown/remark-images.ts
site/src/utils/markdown/rehype-callout-handler.ts
- Modified layout components to use the new debugging utility:
site/src/layouts/OneArticle.astro
site/src/components/markdown/DebugMarkdown.astro
Technical Details
- Created a
MarkdownDebugger
class with methods for different levels of debugging:typescript// site/src/utils/debug/markdown-debugger.ts class MarkdownDebugger { private isEnabled: boolean = false; private isVerbose: boolean = false; constructor() { // Check for environment variables this.isEnabled = process.env.DEBUG_MARKDOWN === 'true'; this.isVerbose = process.env.DEBUG_MARKDOWN_VERBOSE === 'true'; // Also enable if URL has debug-markdown parameter if (typeof window !== 'undefined') { const url = new URL(window.location.href); if (url.searchParams.has('debug-markdown')) { this.isEnabled = true; } if (url.searchParams.has('debug-markdown-verbose')) { this.isEnabled = true; this.isVerbose = true; } } } log(message: string, ...args: any[]): void { if (!this.isEnabled) return; console.log(`[Markdown Debug] ${message}`, ...args); } verbose(message: string, ...args: any[]): void { if (!this.isEnabled || !this.isVerbose) return; console.log(`[Markdown Debug Verbose] ${message}`, ...args); } // Additional methods for plugin start/end and AST debugging }
- Replaced direct
console.log
calls in remark plugins with the new utility:typescript// Before console.log('Found citation:', trimmedLine); // After markdownDebugger.verbose('Found citation:', trimmedLine);
- Added environment variable configuration for controlling debug output:bash
# site/.env.example # Debug settings # Set to 'true' to enable markdown debug output DEBUG_MARKDOWN=false # Set to 'true' to enable verbose markdown debug output (includes full AST dumps) DEBUG_MARKDOWN_VERBOSE=false # Set to 'true' to enable AST debug file output DEBUG_AST=false
- Updated the DebugMarkdown component to conditionally process ASTs only when debugging is enabled:typescript
// site/src/components/markdown/DebugMarkdown.astro // Only process if debugging is enabled if (enabled) { // Process with our custom remark plugins in discrete steps parsedAst = await unified() .use(remarkParse) .parse(content); markdownDebugger.writeDebugFile('1-parsed-ast', parsedAst); // Additional processing steps... }
Integration Points
- The debug system integrates with the existing AST debugger for file output
- Debug output can be controlled through:
- Environment variables (
DEBUG_MARKDOWN=true
,DEBUG_MARKDOWN_VERBOSE=true
) - URL parameters (
?debug-markdown
,?debug-markdown-verbose
) - The existing
DEBUG_AST=true
for AST file output
Documentation
- Added comments throughout the code explaining the purpose and usage of the debug utility
- Created a
.env.example
file with documentation on the available debug options - Debug output now includes prefixes to clearly identify the source of each log message
Future Considerations
- Consider adding more granular control over which plugins generate debug output
- Implement a debug log file option to capture debug output without console noise
- Add visual indicators in the UI when debugging is enabled
Lessons Learned from Import Path Refactoring
Import Path Patterns
- Remark Plugins: Use relative imports within the
utils/markdown
directorytypescript// In remark plugins import markdownDebugger from './markdownDebugger';
- Astro Components: Use alias paths for imports from utility directoriestypescript
// In Astro components import markdownDebugger from '@utils/markdown/markdownDebugger';
Module Export Patterns
- Provide both default and named exports for maximum flexibility:typescript
// Create a singleton instance const markdownDebugger = new MarkdownDebugger(); // Export as default (consistent with remark plugins) export default markdownDebugger; // Also provide named export for flexibility export { markdownDebugger };
Path Resolution Considerations
- Astro's build process handles alias paths differently from relative paths
- Remark plugins imported in
astro.config.mjs
use relative paths, so their internal imports should follow the same pattern - Components using the
@utils
alias can continue to use alias paths for consistency
Debugging Improvements
- Added client-side URL parameter detection for easier debugging in the browser
- Implemented safeguards to prevent debug code from running during SSG builds
- Created a more structured plugin debugging approach with start/end logging