Created
September 24, 2025 12:35
-
-
Save jpic/179ff6f2256fbe46c9e418f0880ee6ab to your computer and use it in GitHub Desktop.
Simple ansi to html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import re | |
| # 256-color to hex mapping (simplified xterm-256color palette) | |
| def ansi_256_to_hex(n): | |
| try: | |
| n = int(n) | |
| if 0 <= n <= 7: # Standard colors | |
| colors = ['#000000', '#FF0000', '#00FF00', '#FFFF00', '#0000FF', '#FF00FF', '#00FFFF', '#FFFFFF'] | |
| return colors[n] | |
| elif 8 <= n <= 15: # Bright colors (approximated to standard) | |
| colors = ['#000000', '#FF0000', '#00FF00', '#FFFF00', '#0000FF', '#FF00FF', '#00FFFF', '#FFFFFF'] | |
| return colors[n - 8] | |
| elif 16 <= n <= 231: # 6x6x6 RGB cube | |
| n -= 16 | |
| r = (n // 36) * 51 | |
| g = ((n // 6) % 6) * 51 | |
| b = (n % 6) * 51 | |
| return f'#{r:02x}{g:02x}{b:02x}' | |
| elif 232 <= n <= 255: # Grayscale (24 steps from #080808 to #EEEEEE) | |
| v = 8 + (n - 232) * 10 | |
| return f'#{v:02x}{v:02x}{v:02x}' | |
| return '#000000' # Fallback for invalid indices | |
| except (ValueError, IndexError): | |
| return '#000000' | |
| # Convert ANSI-colored text to HTML | |
| def ansi_to_html(ansi_text): | |
| # Current state | |
| current_style = {'fg': None, 'bg': None, 'bold': False} | |
| output = [] | |
| # Split text by ANSI escape sequences | |
| parts = re.split(r'(\033\[[0-9;]*[m])', ansi_text) | |
| for part in parts: | |
| if not part: | |
| continue | |
| # Handle ANSI escape codes | |
| if part.startswith('\033['): | |
| code = part[2:-1] # Remove \033[ and m | |
| if code == '0': # Reset | |
| current_style = {'fg': None, 'bg': None, 'bold': False} | |
| elif code == '1': # Bold on | |
| current_style['bold'] = True | |
| elif code == '22': # Bold off | |
| current_style['bold'] = False | |
| elif code.startswith('38;5;'): # 256-color foreground | |
| n = code[5:] | |
| current_style['fg'] = ansi_256_to_hex(n) | |
| elif code.startswith('48;5;'): # 256-color background | |
| n = code[5:] | |
| current_style['bg'] = ansi_256_to_hex(n) | |
| # Ignore other codes | |
| continue | |
| # Handle text content | |
| # Escape HTML special characters | |
| part = (part.replace('&', '&') | |
| .replace('<', '<') | |
| .replace('>', '>') | |
| .replace('"', '"') | |
| .replace('\n', '<br>')) | |
| # Build CSS style | |
| styles = [] | |
| if current_style['fg']: | |
| styles.append(f'color: {current_style["fg"]}') | |
| if current_style['bg']: | |
| styles.append(f'background: {current_style["bg"]}') | |
| if current_style['bold']: | |
| styles.append('font-weight: bold') | |
| style_attr = f' style="{";".join(styles)}"' if styles else '' | |
| output.append(f'<span{style_attr}>{part}</span>') | |
| # Wrap in HTML document | |
| html = f"""<!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>ANSI to HTML</title> | |
| <style> | |
| body {{ font-family: monospace; white-space: pre; background: #000000; color: #FFFFFF; }} | |
| </style> | |
| </head> | |
| <body> | |
| {"".join(output)} | |
| </body> | |
| </html>""" | |
| return html | |
| # Example usage with your pip install output | |
| ansi_output = """ | |
| 24/09 2025 14:33:24 jpic@jpic ~/.local/lib/python3.13/site-packages/pygments | |
| $ pip install -U pygments --user | |
| Requirement already satisfied: pygments in /home/jpic/.local/lib/python3.13/site-packages (2.19.1) | |
| Collecting pygments | |
| Downloading pygments-2.19.2-py3-none-any.whl.metadata (2.5 kB) | |
| Downloading pygments-2.19.2-py3-none-any.whl (1.2 MB) | |
| \033[38;5;33m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m 1.2/1.2 MB 6.7 MB/s 0:00:00 | |
| Installing collected packages: pygments | |
| Attempting uninstall: pygments | |
| Found existing installation: Pygments 2.19.1 | |
| Uninstalling Pygments-2.19.1: | |
| Successfully uninstalled Pygments-2.19.1 | |
| Successfully installed pygments-2.19.2 | |
| """ | |
| # Convert to HTML and save | |
| html_output = ansi_to_html(ansi_output) | |
| with open("output.html", "w") as f: | |
| f.write(html_output) | |
| print("HTML output saved to output.html") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment