CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-markdown-to-jsx

Convert markdown to JSX with ease for React and React-like projects.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

Helper functions for content sanitization, slug generation, and other common markdown processing tasks.

Capabilities

Content Sanitization

Built-in sanitizer function for securing URLs and content against XSS and other security vulnerabilities.

/**
 * Default sanitizer function for URLs and attribute values
 * @param input - The input string to sanitize
 * @returns Sanitized string or null if blocked
 */
function sanitizer(input: string): string | null;

/**
 * Custom sanitizer function type for advanced security controls
 * @param value - The attribute value to sanitize
 * @param tag - The HTML tag containing the attribute
 * @param attribute - The attribute name being sanitized
 * @returns Sanitized value or null to remove the attribute
 */
type SanitizerFunction = (
  value: string,
  tag: HTMLTags,
  attribute: string
) => string | null;

Usage Examples:

import { sanitizer } from "markdown-to-jsx";

// Basic sanitization
const safeUrl = sanitizer("https://example.com"); // "https://example.com"
const blockedJs = sanitizer("javascript:alert('xss')"); // null
const blockedVbs = sanitizer("vbscript:msgbox('xss')"); // null
const blockedData = sanitizer("data:text/html,<script>"); // null

// Safe data URLs are allowed
const safeImage = sanitizer("data:image/png;base64,iVBOR..."); // allowed

// Custom sanitizer implementation
const strictSanitizer = (value, tag, attribute) => {
  // Block all external URLs
  if (attribute === 'href' || attribute === 'src') {
    if (value.startsWith('http://') || value.startsWith('https://')) {
      return null; // Block external resources
    }
  }
  
  // Use default sanitizer for other cases
  return sanitizer(value);
};

// Apply custom sanitizer
const options = {
  sanitizer: strictSanitizer
};

const result = compiler(markdownWithLinks, options);

Slug Generation

Convert text strings to URL-safe slugs for heading IDs and anchor links.

/**
 * Convert string to URL-safe slug for heading IDs
 * @param str - Input string to convert to slug
 * @returns URL-safe slug string
 */
function slugify(str: string): string;

/**
 * Custom slug generation function type
 * @param input - Input string to convert
 * @param defaultFn - Default slugify function to fall back to
 * @returns Custom slug string
 */
type SlugifyFunction = (
  input: string,
  defaultFn: (input: string) => string
) => string;

Usage Examples:

import { slugify } from "markdown-to-jsx";

// Basic slug generation
slugify("Hello World"); // "hello-world"
slugify("Special Characters!@#"); // "special-characters"
slugify("Àccented Tëxt"); // "accented-text"
slugify("Multiple   Spaces"); // "multiple-spaces"
slugify("123 Numbers"); // "123-numbers"

// Custom slugify function
const customSlugify = (input, defaultFn) => {
  // Add timestamp to make unique
  const baseSlug = defaultFn(input);
  return `${baseSlug}-${Date.now()}`;
};

// Custom slugify with prefix
const prefixedSlugify = (input, defaultFn) => {
  const baseSlug = defaultFn(input);
  return `section-${baseSlug}`;
};

// Apply custom slugify
const options = {
  slugify: customSlugify
};

const markdownWithHeadings = `
# Main Title
## Sub Title
### Another Heading
`;

const result = compiler(markdownWithHeadings, options);
// Generates unique IDs: main-title-1634567890123, etc.

Sanitizer Configuration in Options

Configure sanitization behavior through the options system for comprehensive security control.

Usage Examples:

// Disable sanitization (not recommended for untrusted content)
const unsafeOptions = {
  sanitizer: (value) => value // Pass through all values
};

// Strict sanitization
const strictOptions = {
  sanitizer: (value, tag, attribute) => {
    // Only allow specific domains
    const allowedDomains = ['example.com', 'trusted-site.org'];
    
    if (attribute === 'href' || attribute === 'src') {
      try {
        const url = new URL(value);
        if (!allowedDomains.includes(url.hostname)) {
          return null;
        }
      } catch {
        // Invalid URL, allow relative links
        if (!value.startsWith('/') && !value.startsWith('#')) {
          return null;
        }
      }
    }
    
    // Use default sanitizer for validation
    return sanitizer(value);
  }
};

// Content-Security-Policy aware sanitizer
const cspSanitizer = (value, tag, attribute) => {
  // Remove inline styles to comply with CSP
  if (attribute === 'style') {
    return null;
  }
  
  // Only allow relative URLs for images
  if (tag === 'img' && attribute === 'src') {
    if (!value.startsWith('/') && !value.startsWith('./')) {
      return null;
    }
  }
  
  return sanitizer(value);
};

Advanced Utility Patterns

Complex utility function combinations for sophisticated markdown processing.

Usage Examples:

// Utility function factory
const createSecureProcessor = (config) => {
  const customSanitizer = (value, tag, attribute) => {
    // Apply domain whitelist
    if (config.allowedDomains && (attribute === 'href' || attribute === 'src')) {
      try {
        const url = new URL(value);
        if (!config.allowedDomains.includes(url.hostname)) {
          return config.blockExternal ? null : '#blocked';
        }
      } catch {
        // Not a full URL, allow if relative
      }
    }
    
    return sanitizer(value);
  };
  
  const customSlugify = (input, defaultFn) => {
    const baseSlug = defaultFn(input);
    return config.slugPrefix ? `${config.slugPrefix}-${baseSlug}` : baseSlug;
  };
  
  return {
    sanitizer: customSanitizer,
    slugify: customSlugify
  };
};

// Usage
const secureConfig = createSecureProcessor({
  allowedDomains: ['example.com', 'cdn.example.com'],
  blockExternal: true,
  slugPrefix: 'doc'
});

const options = {
  ...secureConfig,
  enforceAtxHeadings: true,
  disableAutoLink: false
};

// Debugging utilities
const debugSanitizer = (value, tag, attribute) => {
  console.log('Sanitizing:', { value, tag, attribute });
  const result = sanitizer(value);
  console.log('Result:', result);
  return result;
};

const debugSlugify = (input, defaultFn) => {
  console.log('Slugifying:', input);
  const result = defaultFn(input);
  console.log('Slug result:', result);
  return result;
};

// Performance monitoring utilities
const performanceSanitizer = (() => {
  let callCount = 0;
  let totalTime = 0;
  
  return (value, tag, attribute) => {
    const start = performance.now();
    const result = sanitizer(value);
    const end = performance.now();
    
    callCount++;
    totalTime += (end - start);
    
    if (callCount % 100 === 0) {
      console.log(`Sanitizer performance: ${callCount} calls, ${totalTime.toFixed(2)}ms total`);
    }
    
    return result;
  };
})();

Security Best Practices

Guidelines and patterns for secure markdown processing with the utility functions.

Usage Examples:

// Secure configuration for user-generated content
const userContentOptions = {
  // Use strict sanitization
  sanitizer: (value, tag, attribute) => {
    // Block all JavaScript
    if (value.toLowerCase().includes('javascript:')) {
      return null;
    }
    
    // Block data URLs except images
    if (value.startsWith('data:') && !value.startsWith('data:image/')) {
      return null;
    }
    
    // Use default sanitizer
    return sanitizer(value);
  },
  
  // Disable HTML parsing for safety
  disableParsingRawHTML: true,
  
  // Use predictable slugs
  slugify: (input, defaultFn) => {
    // Remove potentially problematic characters
    const cleaned = input.replace(/[<>]/g, '');
    return defaultFn(cleaned);
  }
};

// Configuration for trusted content
const trustedContentOptions = {
  // Standard sanitization
  sanitizer: sanitizer,
  
  // Allow HTML parsing
  disableParsingRawHTML: false,
  
  // Enhanced slugs with metadata
  slugify: (input, defaultFn) => {
    const baseSlug = defaultFn(input);
    // Add section prefix for navigation
    return `section-${baseSlug}`;
  }
};

// Apply based on content source
const processMarkdown = (content, isTrusted = false) => {
  const options = isTrusted ? trustedContentOptions : userContentOptions;
  return compiler(content, options);
};

docs

advanced-configuration.md

component-interface.md

component-overrides.md

core-compilation.md

custom-rendering.md

index.md

utility-functions.md

tile.json