Skip to content

Commit 9ab9b35

Browse files
raifdmuellerclaude
authored andcommitted
fix: Insert --position before now adds blank line before heading (#216)
When inserting content before a section, a blank line was missing between the inserted content and the following section heading. This violated AsciiDoc/Markdown formatting conventions. The issue was that the blank line was only added when the inserted content did NOT start with a heading, but we always need a blank line before a heading regardless of the inserted content type. Fixes #216 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent dd700f8 commit 9ab9b35

File tree

6 files changed

+210
-5
lines changed

6 files changed

+210
-5
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Development Plan: Fix #216 - Insert --position before missing blank line
2+
3+
*Generated on 2026-01-31 by Vibe Feature MCP*
4+
*Workflow: [bugfix](https://mrsimpson.github.io/responsible-vibe-mcp/workflows/bugfix)*
5+
6+
## Goal
7+
Fix the missing blank line between inserted section and following section when using `insert --position before`.
8+
9+
## Key Decisions
10+
- Ensure consistent spacing behavior between `--position before` and `--position after`
11+
12+
## Notes
13+
- Issue: https://github.com/docToolchain/dacli/issues/216
14+
- Branch: fix/insert-before-blank-line-216
15+
- Related: #223 (insert after - already fixed), same code location in cli.py
16+
17+
## Reproduce
18+
19+
### Phase Entrance Criteria:
20+
- [x] Issue #216 has been reviewed and understood
21+
22+
### Tasks
23+
- [ ] Create test document with multiple sections
24+
- [ ] Run insert --position before command
25+
- [ ] Verify missing blank line in output
26+
27+
### Completed
28+
- [x] Created development plan file
29+
30+
## Analyze
31+
32+
### Phase Entrance Criteria:
33+
- [ ] Bug has been successfully reproduced
34+
- [ ] Steps to reproduce are documented
35+
36+
### Tasks
37+
- [ ] Find the insert code in cli.py
38+
- [ ] Compare before/after position handling
39+
- [ ] Identify why blank line is missing
40+
41+
### Completed
42+
*None yet*
43+
44+
## Fix
45+
46+
### Phase Entrance Criteria:
47+
- [ ] Root cause identified
48+
- [ ] Solution approach confirmed
49+
50+
### Tasks
51+
- [ ] Write failing test
52+
- [ ] Implement blank line handling for --position before
53+
- [ ] Verify existing tests pass
54+
55+
### Completed
56+
*None yet*
57+
58+
## Verify
59+
60+
### Phase Entrance Criteria:
61+
- [ ] Fix implemented
62+
- [ ] All tests pass
63+
64+
### Tasks
65+
- [ ] Run full test suite
66+
- [ ] Manual verification
67+
- [ ] Test edge cases
68+
69+
### Completed
70+
*None yet*
71+
72+
## Finalize
73+
74+
### Phase Entrance Criteria:
75+
- [ ] All tests pass
76+
- [ ] No regressions
77+
78+
### Tasks
79+
- [ ] Update version
80+
- [ ] Create commit
81+
- [ ] Create PR
82+
83+
### Completed
84+
*None yet*
85+
86+
---
87+
*This plan is maintained by the LLM.*

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "dacli"
3-
version = "0.4.11"
3+
version = "0.4.12"
44
description = "Documentation Access CLI - Navigate and query large documentation projects"
55
readme = "README.md"
66
license = { text = "MIT" }

src/dacli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
through hierarchical, content-aware access via the Model Context Protocol (MCP).
55
"""
66

7-
__version__ = "0.4.11"
7+
__version__ = "0.4.12"

src/dacli/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,9 +729,9 @@ def ensure_trailing_blank_line(content: str) -> str:
729729

730730
if position == "before":
731731
insert_line = start_line
732-
# Check if the line we're inserting before is a heading
732+
# Issue #216: Always add blank line before a heading
733733
next_line_idx = start_line - 1 # 0-based index
734-
if next_line_is_heading(lines, next_line_idx) and not starts_with_heading:
734+
if next_line_is_heading(lines, next_line_idx):
735735
insert_content = ensure_trailing_blank_line(insert_content)
736736
new_lines = lines[: start_line - 1] + [insert_content] + lines[start_line - 1 :]
737737
elif position == "after":
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""Tests for Issue #216: Insert --position before missing blank line.
2+
3+
When inserting content before a section, there should be a blank line
4+
between the inserted content and the following section.
5+
"""
6+
7+
from pathlib import Path
8+
9+
import pytest
10+
from click.testing import CliRunner
11+
12+
from dacli.cli import cli
13+
14+
15+
@pytest.fixture
16+
def temp_doc_dir(tmp_path: Path) -> Path:
17+
"""Create a temporary directory with test document."""
18+
doc_file = tmp_path / "test.adoc"
19+
doc_file.write_text(
20+
"""= Document
21+
22+
== Section A
23+
24+
Content A
25+
26+
== Section B
27+
28+
Content B
29+
""",
30+
encoding="utf-8",
31+
)
32+
return tmp_path
33+
34+
35+
class TestInsertBeforeBlankLine:
36+
"""Test that insert --position before adds blank line correctly."""
37+
38+
def test_insert_section_before_adds_blank_line(self, temp_doc_dir: Path):
39+
"""Issue #216: Inserting a section before another should add blank line."""
40+
runner = CliRunner()
41+
result = runner.invoke(
42+
cli,
43+
[
44+
"--docs-root",
45+
str(temp_doc_dir),
46+
"insert",
47+
"test:section-b",
48+
"--position",
49+
"before",
50+
"--content",
51+
"== Before B\n\nContent before B",
52+
],
53+
)
54+
55+
assert result.exit_code == 0
56+
57+
# Check the file content
58+
doc_file = temp_doc_dir / "test.adoc"
59+
file_content = doc_file.read_text(encoding="utf-8")
60+
61+
# There should be a blank line between "Content before B" and "== Section B"
62+
assert "Content before B\n\n== Section B" in file_content, (
63+
f"Missing blank line before Section B. Content:\n{file_content}"
64+
)
65+
66+
def test_insert_content_before_heading_adds_blank_line(self, temp_doc_dir: Path):
67+
"""Insert plain content before a heading should add blank line."""
68+
runner = CliRunner()
69+
result = runner.invoke(
70+
cli,
71+
[
72+
"--docs-root",
73+
str(temp_doc_dir),
74+
"insert",
75+
"test:section-b",
76+
"--position",
77+
"before",
78+
"--content",
79+
"Some plain content without heading",
80+
],
81+
)
82+
83+
assert result.exit_code == 0
84+
85+
doc_file = temp_doc_dir / "test.adoc"
86+
file_content = doc_file.read_text(encoding="utf-8")
87+
88+
# There should be a blank line between the content and Section B
89+
assert "Some plain content without heading\n\n== Section B" in file_content, (
90+
f"Missing blank line before Section B. Content:\n{file_content}"
91+
)
92+
93+
def test_insert_before_preserves_existing_blank_lines(self, temp_doc_dir: Path):
94+
"""Don't add extra blank lines if content already ends with them."""
95+
runner = CliRunner()
96+
result = runner.invoke(
97+
cli,
98+
[
99+
"--docs-root",
100+
str(temp_doc_dir),
101+
"insert",
102+
"test:section-b",
103+
"--position",
104+
"before",
105+
"--content",
106+
"== Before B\n\nContent before B\n\n", # Already has trailing blank line
107+
],
108+
)
109+
110+
assert result.exit_code == 0
111+
112+
doc_file = temp_doc_dir / "test.adoc"
113+
file_content = doc_file.read_text(encoding="utf-8")
114+
115+
# Should have exactly one blank line (not extra)
116+
assert "Content before B\n\n== Section B" in file_content
117+
# Should NOT have triple newlines
118+
assert "Content before B\n\n\n== Section B" not in file_content

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)