or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-highlighting.mdindex.mdlanguage-management.mdmodes-patterns.mdplugin-system.mdutilities.md
tile.json

utilities.mddocs/

Utilities

Utility functions, debugging tools, and legacy API support for advanced usage and troubleshooting. These functions provide additional capabilities for customization, debugging, and backward compatibility.

Capabilities

Inherit Function

Performs shallow merge of multiple objects into a single object. Commonly used for extending mode definitions and configuration objects.

/**
 * Performs shallow merge of multiple objects into a single object
 * @param original - Base object to extend
 * @param args - Objects to merge into the original
 * @returns New object with merged properties
 */
function inherit<T>(original: T, ...args: Record<string, any>[]): T;

Usage Examples:

import hljs from "highlight.js";

// Basic object merging
const baseMode = {
  className: 'string',
  begin: '"',
  relevance: 0
};

const enhancedMode = hljs.inherit(baseMode, {
  end: '"',
  contains: [hljs.BACKSLASH_ESCAPE]
});

// Result: {className: 'string', begin: '"', relevance: 0, end: '"', contains: [...]}

// Multiple object merging
const baseConfig = {classPrefix: 'hljs-', useBR: false};
const userConfig = {classPrefix: 'code-'};
const devConfig = {debug: true};

const finalConfig = hljs.inherit(baseConfig, userConfig, devConfig);
// Result: {classPrefix: 'code-', useBR: false, debug: true}

// Language definition extension
function createLanguage(hljs) {
  const baseLanguage = {
    name: 'Base',
    contains: [hljs.C_LINE_COMMENT_MODE]
  };

  const extendedLanguage = hljs.inherit(baseLanguage, {
    name: 'Extended',
    keywords: 'if else while for',
    contains: baseLanguage.contains.concat([hljs.QUOTE_STRING_MODE])
  });

  return extendedLanguage;
}

Fix Markup Function (Deprecated)

Fixes markup in highlighted HTML by cleaning up whitespace and formatting. Deprecated in v10.2.0 and will be removed in v11.0.

/**
 * Fixes markup in highlighted HTML
 * @deprecated Will be removed in v11.0 - see https://github.com/highlightjs/highlight.js/issues/2534
 * @param html - HTML string to fix
 * @returns Fixed HTML string
 */
function fixMarkup(html: string): string;

Usage Examples:

import hljs from "highlight.js";

// Legacy usage (deprecated)
const messyHtml = '<span class="hljs-keyword">  function  </span>';
const cleanHtml = hljs.fixMarkup(messyHtml);

// Migration path - handle whitespace manually
function cleanupMarkup(html) {
  return html
    .replace(/(\n)( )+/g, '$1') // Remove leading spaces after newlines
    .replace(/\s+/g, ' ')       // Normalize multiple spaces
    .trim();                    // Remove leading/trailing whitespace
}

// Modern approach - configure highlighting to avoid markup issues
hljs.configure({
  tabReplace: '  ',  // Consistent tab replacement
  useBR: false       // Use newlines instead of <br> tags
});

Debug Mode

Enables debug mode where highlight.js throws errors instead of silencing them. Useful for development and troubleshooting.

/**
 * Enables debug mode - throws errors instead of silencing them
 * Useful for development and troubleshooting
 */
function debugMode(): void;

Usage Examples:

import hljs from "highlight.js";

// Enable debug mode for development
if (process.env.NODE_ENV === 'development') {
  hljs.debugMode();
}

// Debug mode helps catch issues
hljs.debugMode();

try {
  // This will throw an error in debug mode if there are issues
  const result = hljs.highlight('invalid syntax', {language: 'nonexistent'});
} catch (error) {
  console.error('Highlighting error:', error);
  // Handle error appropriately
}

// Conditional debug mode
function enableDebugging(enable = true) {
  if (enable) {
    hljs.debugMode();
    console.log('Highlight.js debug mode enabled');
  } else {
    hljs.safeMode();
    console.log('Highlight.js safe mode enabled');
  }
}

Safe Mode

Enables safe mode where highlight.js silences errors and continues processing. This is the default mode for production use.

/**
 * Enables safe mode - silences errors and continues processing
 * This is the default mode, useful for production environments
 */
function safeMode(): void;

Usage Examples:

import hljs from "highlight.js";

// Explicitly enable safe mode (default)
hljs.safeMode();

// Production configuration
if (process.env.NODE_ENV === 'production') {
  hljs.safeMode();
  hljs.configure({
    classPrefix: 'hljs-',
    languages: ['javascript', 'python', 'html', 'css'] // Limit to known languages
  });
}

// Error handling in safe mode
const result = hljs.highlight('some code', {language: 'unknown'});
if (result.illegal || result.relevance < 1) {
  // Handle low-quality highlighting gracefully
  console.warn('Highlighting may be inaccurate');
}

// Toggle between modes
function setMode(debug = false) {
  if (debug) {
    hljs.debugMode();
  } else {
    hljs.safeMode();
  }
}

Version String

String constant containing the version of highlight.js. Useful for compatibility checks and debugging.

/**
 * Version string of the highlight.js library
 */
const versionString: string;

Usage Examples:

import hljs from "highlight.js";

// Check version
console.log('Highlight.js version:', hljs.versionString); // "10.7.3"

// Version compatibility check
function checkCompatibility() {
  const version = hljs.versionString;
  const majorVersion = parseInt(version.split('.')[0]);
  
  if (majorVersion < 10) {
    console.warn('This code requires highlight.js v10 or later');
    return false;
  }
  
  return true;
}

// Feature detection based on version
function hasFeature(feature) {
  const version = hljs.versionString;
  const [major, minor, patch] = version.split('.').map(Number);
  
  switch (feature) {
    case 'highlightElement':
      return major >= 10 && minor >= 7;
    case 'newHighlightAPI':
      return major >= 10;
    default:
      return false;
  }
}

// Version reporting for debugging
function getEnvironmentInfo() {
  return {
    highlightjs: hljs.versionString,
    languages: hljs.listLanguages().length,
    userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'Node.js',
    timestamp: new Date().toISOString()
  };
}

Advanced Usage Patterns

Utility Composition

import hljs from "highlight.js";

// Create enhanced mode with multiple inheritances
function createEnhancedStringMode(hljs) {
  const baseString = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE]
  };

  const quotedString = hljs.inherit(baseString, {
    begin: '"',
    end: '"'
  });

  const interpolatedString = hljs.inherit(quotedString, {
    contains: baseString.contains.concat([
      {
        className: 'subst',
        begin: /\${/,
        end: /}/
      }
    ])
  });

  return interpolatedString;
}

// Multi-level configuration inheritance
function createConfiguration(baseConfig, environmentConfig, userConfig) {
  return hljs.inherit(
    {
      // Defaults
      classPrefix: 'hljs-',
      useBR: false,
      tabReplace: undefined
    },
    baseConfig || {},
    environmentConfig || {},
    userConfig || {}
  );
}

Development vs Production Utilities

class HighlightManager {
  constructor(options = {}) {
    this.options = options;
    this.isProduction = process.env.NODE_ENV === 'production';
    this.setupMode();
  }

  setupMode() {
    if (this.isProduction) {
      hljs.safeMode();
    } else {
      hljs.debugMode();
    }
  }

  highlight(code, options) {
    const startTime = this.isProduction ? null : performance.now();
    
    try {
      const result = hljs.highlight(code, options);
      
      if (!this.isProduction) {
        const duration = performance.now() - startTime;
        console.log(`Highlighted ${options.language} in ${duration.toFixed(2)}ms`);
        
        if (result.relevance < 5) {
          console.warn(`Low relevance score: ${result.relevance}`);
        }
      }
      
      return result;
    } catch (error) {
      if (this.isProduction) {
        // Graceful fallback
        return {
          value: `<pre>${code}</pre>`,
          relevance: 0,
          illegal: false,
          language: options.language
        };
      } else {
        throw error; // Let debug mode handle it
      }
    }
  }

  getInfo() {
    return {
      version: hljs.versionString,
      mode: this.isProduction ? 'production' : 'development',
      languages: hljs.listLanguages().length,
      options: this.options
    };
  }
}

// Usage
const highlighter = new HighlightManager({
  classPrefix: 'code-',
  preferredLanguages: ['javascript', 'python']
});

console.log(highlighter.getInfo());

Custom Error Handling

class SafeHighlighter {
  constructor() {
    this.fallbacks = new Map([
      ['javascript', 'js'],
      ['typescript', 'javascript'], 
      ['jsx', 'javascript'],
      ['unknown', 'plaintext']
    ]);
    
    // Always use safe mode for this class
    hljs.safeMode();
  }

  highlight(code, language) {
    let result = null;
    let attempts = [language];
    
    // Add fallback languages
    if (this.fallbacks.has(language)) {
      attempts.push(this.fallbacks.get(language));
    }
    attempts.push('plaintext');

    for (const lang of attempts) {
      try {
        if (lang === 'plaintext') {
          // Manual plaintext fallback
          result = {
            value: `<pre class="hljs">${this.escapeHtml(code)}</pre>`,
            relevance: 0,
            illegal: false,
            language: 'plaintext'
          };
        } else if (hljs.getLanguage(lang)) {
          result = hljs.highlight(code, {language: lang});
          
          // Accept if relevance is reasonable
          if (result.relevance > 1 || !result.illegal) {
            break;
          }
        }
      } catch (error) {
        console.warn(`Failed to highlight as ${lang}:`, error.message);
        continue;
      }
    }

    return result;
  }

  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
}

// Usage
const safeHighlighter = new SafeHighlighter();
const result = safeHighlighter.highlight('console.log("test")', 'javascript');

Version-Aware Feature Detection

class FeatureDetector {
  constructor() {
    this.version = hljs.versionString;
    this.features = this.detectFeatures();
  }

  detectFeatures() {
    const [major, minor, patch] = this.version.split('.').map(Number);
    
    return {
      highlightElement: major >= 10 && minor >= 7,
      newHighlightAPI: major >= 10,
      pluginSystem: major >= 10,
      vuePlugin: major >= 10,
      fixMarkupDeprecated: major >= 10 && minor >= 2,
      highlightBlockDeprecated: major >= 10 && minor >= 7
    };
  }

  hasFeature(feature) {
    return this.features[feature] || false;
  }

  getCompatibleAPI() {
    if (this.hasFeature('highlightElement')) {
      return {
        highlightElement: hljs.highlightElement.bind(hljs),
        highlightBlock: this.hasFeature('highlightBlockDeprecated') 
          ? hljs.highlightElement.bind(hljs)  // Use new API
          : hljs.highlightBlock.bind(hljs)    // Use old API
      };
    }
    
    return {
      highlightElement: hljs.highlightBlock.bind(hljs), // Fallback
      highlightBlock: hljs.highlightBlock.bind(hljs)
    };
  }

  warnDeprecated() {
    if (this.hasFeature('fixMarkupDeprecated')) {
      console.warn('fixMarkup is deprecated and will be removed in v11');
    }
    
    if (this.hasFeature('highlightBlockDeprecated')) {
      console.warn('highlightBlock is deprecated, use highlightElement instead');
    }
  }
}

// Usage
const detector = new FeatureDetector();
console.log('Available features:', detector.features);

const api = detector.getCompatibleAPI();
api.highlightElement(document.querySelector('code'));