# html URL: /api/formatters/html/ Section: formatters -------------------------------------------------------------------------------- html - Rosettes window.BENGAL_THEME_DEFAULTS = { appearance: 'light', palette: 'brown-bengal' }; window.Bengal = window.Bengal || {}; window.Bengal.enhanceBaseUrl = '/rosettes/assets/js/enhancements'; window.Bengal.watchDom = true; window.Bengal.debug = false; window.Bengal.enhanceUrls = { 'toc': '/rosettes/assets/js/enhancements/toc.632a9783.js', 'docs-nav': '/rosettes/assets/js/enhancements/docs-nav.57e4b129.js', 'tabs': '/rosettes/assets/js/enhancements/tabs.aac9e817.js', 'lightbox': '/rosettes/assets/js/enhancements/lightbox.1ca22aa1.js', 'interactive': '/rosettes/assets/js/enhancements/interactive.fc077855.js', 'mobile-nav': '/rosettes/assets/js/enhancements/mobile-nav.d991657f.js', 'action-bar': '/rosettes/assets/js/enhancements/action-bar.d62417f4.js', 'copy-link': '/rosettes/assets/js/enhancements/copy-link.7d9a5c29.js', 'data-table': '/rosettes/assets/js/enhancements/data-table.1f5bc1eb.js', 'lazy-loaders': '/rosettes/assets/js/enhancements/lazy-loaders.a5c38245.js', 'holo': '/rosettes/assets/js/enhancements/holo.ee13c841.js', 'link-previews': '/rosettes/assets/js/enhancements/link-previews.8d906535.js' }; (function () { try { var defaults = window.BENGAL_THEME_DEFAULTS || { appearance: 'system', palette: '' }; var defaultAppearance = defaults.appearance; if (defaultAppearance === 'system') { defaultAppearance = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } var storedTheme = localStorage.getItem('bengal-theme'); var storedPalette = localStorage.getItem('bengal-palette'); var theme = storedTheme ? (storedTheme === 'system' ? defaultAppearance : storedTheme) : defaultAppearance; var palette = storedPalette ?? defaults.palette; document.documentElement.setAttribute('data-theme', theme); if (palette) { document.documentElement.setAttribute('data-palette', palette); } } catch (e) { document.documentElement.setAttribute('data-theme', 'light'); } })(); { "prerender": [ { "where": { "and": [ { "href_matches": "/docs/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ], "prefetch": [ { "where": { "and": [ { "href_matches": "/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ] } Skip to main content Magnifying Glass ESC Recent Clear Magnifying Glass No results for "" Start typing to search... ↑↓ Navigate ↵ Open ESC Close Powered by Lunr ⌾⌾⌾ DocumentationInfoAboutArrow ClockwiseGet StartedCodeHighlightingPaletteStylingStarburstExtendingFormattersNoteTutorialsBookmarkReferenceReleasesDevGitHubAPI Reference Magnifying Glass Search ⌘K Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal List ⌾⌾⌾ Magnifying Glass Search X Close Documentation Caret Down Info About Arrow Clockwise Get Started Code Highlighting Palette Styling Starburst Extending Formatters Note Tutorials Bookmark Reference Releases Dev Caret Down GitHub API Reference Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal Rosettes API Reference Caret Right Formatters html null terminal Caret Right Lexers _scanners _state_machine bash_sm c_sm clojure_sm cpp_sm css_sm csv_sm cuda_sm cue_sm dart_sm diff_sm dockerfile_sm elixir_sm gleam_sm go_sm graphql_sm groovy_sm haskell_sm hcl_sm html_sm ini_sm java_sm javascript_sm jinja_sm json_sm julia_sm kida_sm kotlin_sm lua_sm makefile_sm markdown_sm mojo_sm nginx_sm nim_sm perl_sm php_sm pkl_sm plaintext_sm powershell_sm protobuf_sm python_sm r_sm ruby_sm rust_sm scala_sm sql_sm stan_sm swift_sm toml_sm tree_sm triton_sm typescript_sm v_sm xml_sm yaml_sm zig_sm Caret Right Themes _mapping _palette _roles palettes _config _escape _formatter_registry _parallel _protocol _registry _types delegate rosettes Rosettes API ReferenceFormatters ᗢ Caret Down Link Copy URL External Open LLM text Copy Copy LLM text Share with AI Ask Claude Ask ChatGPT Ask Gemini Ask Copilot Module formatters.html HTML formatter for Rosettes. Generates HTML output with semantic or Pygments-compatible CSS classes. Thread-safe by design — no mutable shared state. Features: Dual CSS class output: semantic (.syntax-function) or Pygments (.nf) CSS custom properties for runtime theming Line highlighting (hl_lines parameter) Streaming output (generator-based) Design Philosophy: The HTML formatter is optimized for the common case while supporting advanced features when needed: Fast path: format_fast() for simple highlighting (~50µs/block) Slow path: format() for line highlighting, line numbers Immutable: Frozen dataclass ensures thread-safety Streaming: Yields chunks for memory-efficient processing CSS Class Styles: semantic (default): Human-readable class names like .syntax-function, .syntax-keyword. Better for custom themes and debugging. pygments: Pygments-compatible names like .nf, .k. Works with existing Pygments CSS themes. Performance Optimizations: Fast path when no line highlighting needed Pre-computed escape table (C-level str.translate) Pre-built span templates (avoid f-string in loop) Direct token type value access (StrEnum) Streaming output (generator, no intermediate list) Benchmarks (100-line Python file): format_fast(): ~50µs format() with hl_lines: ~80µs format() with line numbers: ~100µs Common Mistakes: # ❌ WRONG: Calling format() and ignoring streaming html = "" for chunk in formatter.format(tokens): html += chunk # O(n²) string concatenation # ✅ CORRECT: Use format_string() or join() html = formatter.format_string(tokens) # or html = "".join(formatter.format(tokens)) See Also: rosettes.formatters.terminal: ANSI terminal output formatter rosettes.formatters.null: No-op formatter for testing rosettes.themes: CSS generation for HTML themes rosettes._escape: HTML entity escaping (used internally) 1Class Classes HtmlFormatter 8 ▼ HTML formatter with streaming output. Thread-safe: all state is immutable or local to method calls… HTML formatter with streaming output. Thread-safe: all state is immutable or local to method calls. Instances are frozen dataclasses and can be safely shared across threads. Output Structure: def ... Attributes Name Type Description config HighlightConfig Highlight configuration for line highlighting, line numbers. css_class_style CssClassStyle "semantic" for .syntax-* or "pygments" for .k, .nf Methods name 0 str ▼ property def name(self) -> str Returns str container_class 0 str ▼ Get the container CSS class based on style. property def container_class(self) -> str Returns str format_fast 2 Iterator[str] ▼ Ultra-fast formatting without line highlighting. Uses role-based class names f… def format_fast(self, tokens: Iterator[tuple[TokenType, str]], config: FormatConfig | None = None) -> Iterator[str] Ultra-fast formatting without line highlighting. Uses role-based class names for semantic mode. Optimizations: Pre-built span templates (no f-string per token) Direct dict lookup (O(1)) Minimal branching in hot path Parameters Name Type Description tokens — config — Default: None Returns Iterator[str] format 2 Iterator[str] ▼ Format tokens as HTML with streaming output. def format(self, tokens: Iterator[Token], config: FormatConfig | None = None) -> Iterator[str] Parameters Name Type Description tokens — config — Default: None Returns Iterator[str] format_string 2 str ▼ def format_string(self, tokens: Iterator[Token], config: FormatConfig | None = None) -> str Parameters Name Type Description tokens — config — Default: None Returns str format_string_fast 2 str ▼ def format_string_fast(self, tokens: Iterator[tuple[TokenType, str]], config: FormatConfig | None = None) -> str Parameters Name Type Description tokens — config — Default: None Returns str ← Previous formatters Next → null List © 2026 Rosettes built in ᓚᘏᗢ { "linkPreviews": { "enabled": true, "hoverDelay": 200, "hideDelay": 150, "showSection": true, "showReadingTime": true, "showWordCount": true, "showDate": true, "showTags": true, "maxTags": 3, "includeSelectors": [".prose"], "excludeSelectors": ["nav", ".toc", ".breadcrumb", ".pagination", ".card", "[class*='-card']", ".tab-nav", "[class*='-widget']", ".child-items", ".content-tiles"], "allowedHosts": [], "allowedSchemes": ["https"], "hostFailureThreshold": 3 } } window.BENGAL_LAZY_ASSETS = { tabulator: '/rosettes/assets/js/tabulator.min.js', dataTable: '/rosettes/assets/js/data-table.js', mermaidToolbar: '/rosettes/assets/js/mermaid-toolbar.9de5abba.js', mermaidTheme: '/rosettes/assets/js/mermaid-theme.344822c5.js', graphMinimap: '/rosettes/assets/js/graph-minimap.ff04e939.js', graphContextual: '/rosettes/assets/js/graph-contextual.355458ba.js' }; window.BENGAL_ICONS = { close: '/rosettes/assets/icons/close.911d4fe1.svg', enlarge: '/rosettes/assets/icons/enlarge.652035e5.svg', copy: '/rosettes/assets/icons/copy.3d56e945.svg', 'download-svg': '/rosettes/assets/icons/download.04f07e1b.svg', 'download-png': '/rosettes/assets/icons/image.c34dfd40.svg', 'zoom-in': '/rosettes/assets/icons/zoom-in.237b4a83.svg', 'zoom-out': '/rosettes/assets/icons/zoom-out.38857c77.svg', reset: '/rosettes/assets/icons/reset.d26dba29.svg' }; Arrow Up -------------------------------------------------------------------------------- Metadata: - Word Count: 1001 - Reading Time: 5 minutes