Skip to content

ANSI Colors in Jupyter Output Not Copy-Paste Friendly #14

@lwgray

Description

@lwgray

Problem Description

When using ThinkPy in Jupyter notebooks with color output mode (--style color), the ANSI color codes appear as raw escape sequences in copied text, making it difficult to share or document output.

Current Behavior

When copying output from a ThinkPy cell with color formatting:

[94m[1mPROGRAM[0m: Test float operations
[94m[1mTASK[0m: Executing FloatMath

Expected Behavior

Clean, formatted text without ANSI escape sequences:

PROGRAM: Test float operations
TASK: Executing FloatMath

Reproduction Steps

  1. Run ThinkPy code with color style:
%%thinkpy --explain --style color
objective "Test float operations"

task "FloatMath" {
    step "Basic arithmetic" {
        a = 10.5
        b = -1e-1
        result = a / b
        print(result)
    }
}

run "FloatMath"
  1. The output
    image

  2. Observe ANSI escape sequences in copied text
    �[94m�[1mPROGRAM�[0m: Test float operations
    �[94m�[1mTASK�[0m: Executing FloatMath
    �[93m�[1mSTEP�[0m: Executing Basic arithmetic
    �[91m�[1mVARIABLE�[0m: Assigned 10.5 to a
    �[91m�[1mVARIABLE�[0m: Assigned -0.1 to b
    �[91m�[1mVARIABLE�[0m: Assigned -105.0 to result
    �[92m�[1mOUTPUT�[0m: -105

Proposed Solutions

Primary Solution: HTML-based Rendering

Convert ANSI color sequences to HTML/CSS for Jupyter display:

  1. Create a new output formatter that:
    • Intercepts the colored output
    • Converts ANSI sequences to HTML/CSS classes
    • Returns rich HTML output for Jupyter
def format_output_html(text):
    # Convert ANSI to HTML classes
    ansi_to_html = {
        '\033[94m': '<span class="thinkpy-task">',
        '\033[93m': '<span class="thinkpy-step">',
        '\033[0m': '</span>'
        # ... other mappings
    }
    # Replace ANSI sequences with HTML
    for ansi, html in ansi_to_html.items():
        text = text.replace(ansi, html)
    return f'<div class="thinkpy-output">{text}</div>'

Alternative Solutions

  1. Dual Output Mode

    • Keep ANSI colors for terminal use
    • Add --format html option for Jupyter
    • Let users choose based on context
  2. Rich Library Integration

    • Utilize the rich library's HTML export
    • Provides consistent formatting across platforms
    • Built-in ANSI-to-HTML conversion
  3. Copy-Paste Enhancement

    • Add custom clipboard handler
    • Strip ANSI sequences on copy
    • Preserve visual formatting in notebook

ANSI Preservation Option

For users who need ANSI colors (e.g., for terminal tools):

def preserve_ansi_output(text):
    from IPython.display import HTML
    # Encode ANSI sequences for display
    html_safe = text.replace('\033', '\\033')
    return HTML(f'<pre>{html_safe}</pre>')

Implementation Impact

  • Difficulty: Master level
  • Components Affected:
    • Interpreter output handling
    • Jupyter integration
    • Display formatting
  • Testing Required:
    • Cross-platform compatibility
    • Various Jupyter environments
    • Output capturing methods

Additional Notes

  • Should maintain backward compatibility
  • Consider performance impact of HTML conversion
  • May need to document both ANSI and HTML modes
  • Consider accessibility implications

/label ~"Master" ~bug ~needs-design
/cc @project-maintainers

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions