diff --git a/markdown_code_runner.py b/markdown_code_runner.py index b375652..75ce79e 100644 --- a/markdown_code_runner.py +++ b/markdown_code_runner.py @@ -251,7 +251,9 @@ def _process_output_start(self, line: str) -> None: self.output, list, ), f"Output must be a list, not {type(self.output)}, line: {line}" - self.new_lines.extend([line, MARKERS["warning"], *self.output]) + # Trim trailing whitespace from output lines + trimmed_output = [line.rstrip() for line in self.output] + self.new_lines.extend([line, MARKERS["warning"], *trimmed_output]) else: self.original_output.append(line) diff --git a/tests/test_main_app.py b/tests/test_main_app.py index 3941a22..c72fbb1 100644 --- a/tests/test_main_app.py +++ b/tests/test_main_app.py @@ -787,3 +787,91 @@ def test_patterns() -> None: def test_extract_extra(line: str, expected_result: str) -> None: """Test that the _extract_backtick_options function works as expected.""" assert _extract_backtick_options(line) == expected_result + + +def _verify_no_trailing_whitespace(output_section: list[str], label: str = "") -> None: + """Helper to verify no trailing whitespace in output.""" + for line in output_section: + assert line == line.rstrip(), f"{label}Line has trailing whitespace: '{line}'" + + +def test_trailing_whitespace_trimming() -> None: + """Test that trailing whitespace is properly trimmed from output.""" + # Test case 1: Python code with trailing whitespace + input_lines = [ + "# Test trailing whitespace", + "```python markdown-code-runner", + "print('Hello World ')", + "print('Line with spaces ')", + "print('')", + "print('After empty line')", + "print(' ') # This will print only spaces", + "```", + "", + "", + ] + + output = process_markdown(input_lines, backtick_standardize=False) + start_idx = output.index("") + end_idx = output.index("") + output_section = output[start_idx + 2 : end_idx] + + _verify_no_trailing_whitespace(output_section, "Python ") + assert output_section[0] == "Hello World" + assert output_section[1] == "Line with spaces" + assert output_section[2] == "" + assert output_section[3] == "After empty line" + assert output_section[4] == "" # Line with only spaces becomes empty + assert output_section[5] == "" # Trailing empty line preserved + + # Test case 2: Bash code with trailing whitespace + input_lines_bash = [ + "```bash markdown-code-runner", + "echo 'Hello from bash '", + "echo 'Another line '", + "echo ''", + "echo 'After empty'", + "echo ' ' # Only spaces", + "```", + "", + "", + ] + + output_bash = process_markdown(input_lines_bash, backtick_standardize=False) + start_idx_bash = output_bash.index("") + end_idx_bash = output_bash.index("") + output_section_bash = output_bash[start_idx_bash + 2 : end_idx_bash] + + _verify_no_trailing_whitespace(output_section_bash, "Bash ") + assert output_section_bash[0] == "Hello from bash" + assert output_section_bash[1] == "Another line" + assert output_section_bash[2] == "" + assert output_section_bash[3] == "After empty" + assert output_section_bash[4] == "" # Line with only spaces becomes empty + assert output_section_bash[5] == "" # Trailing empty line preserved + + # Test case 3: Hidden code block with trailing whitespace + input_lines_hidden = [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + ] + + output_hidden = process_markdown(input_lines_hidden, backtick_standardize=False) + start_idx_hidden = output_hidden.index("") + end_idx_hidden = output_hidden.index("") + output_section_hidden = output_hidden[start_idx_hidden + 2 : end_idx_hidden] + + _verify_no_trailing_whitespace(output_section_hidden, "Hidden ") + assert output_section_hidden[0] == "Hidden output" + assert output_section_hidden[1] == "With spaces" + assert output_section_hidden[2] == "" + assert output_section_hidden[3] == "Final line" + assert output_section_hidden[4] == "" # Line with only spaces becomes empty + assert output_section_hidden[5] == "" # Trailing empty line preserved