confpub-cli 1.7.1__tar.gz → 1.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/PKG-INFO +1 -1
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/__init__.py +1 -1
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/reverse_converter.py +15 -7
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_reverse_converter.py +44 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/.github/copilot-instructions.md +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/.github/workflows/publish.yml +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/.gitignore +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/CLAUDE.md +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/LICENSE +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/PRD.md +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/README.md +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/applier.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/assets.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/cli.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/config.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/confluence.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/converter.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/envelope.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/errors.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/front_matter.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/guide.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/lockfile.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/macro_plugin.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/manifest.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/output.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/planner.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/publish.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/puller.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/py.typed +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/validator.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub/verifier.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/confpub.lock +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/pyproject.toml +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/__init__.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/conftest.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_applier.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_assets.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_config.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_confluence.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_converter.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_envelope.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_errors.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_front_matter.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_guide.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_integration.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_lockfile.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_macro_plugin.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_manifest.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_output.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_planner.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_publish.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_puller.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_validator.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/tests/test_verifier.py +0 -0
- {confpub_cli-1.7.1 → confpub_cli-1.7.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: confpub-cli
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: Agent-first CLI to publish Markdown to Confluence
|
|
5
5
|
Project-URL: Homepage, https://github.com/ThomasRohde/confpub-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/ThomasRohde/confpub-cli.git
|
|
@@ -452,14 +452,18 @@ def _preprocess_storage_format(html: str) -> tuple[BeautifulSoup, list[str]]:
|
|
|
452
452
|
if next_sib and next_sib.name == "ol":
|
|
453
453
|
hr.decompose()
|
|
454
454
|
|
|
455
|
-
# 5. Transform ac:layout → div[data-layout-macro]
|
|
455
|
+
# 5. Transform ac:layout → div[data-layout-macro] per section
|
|
456
456
|
for layout in soup.find_all("ac:layout"):
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
457
|
+
sections = layout.find_all("ac:layout-section", recursive=False)
|
|
458
|
+
if not sections:
|
|
459
|
+
layout.decompose()
|
|
460
|
+
continue
|
|
461
|
+
# Build one layout div per section, then replace the ac:layout
|
|
462
|
+
section_divs = []
|
|
463
|
+
for section in sections:
|
|
464
|
+
layout_div = soup.new_tag("div")
|
|
465
|
+
layout_div["data-layout-macro"] = "layout"
|
|
461
466
|
layout_type = section.get("ac:type", "single")
|
|
462
|
-
# Convert underscores back to hyphens
|
|
463
467
|
layout_type = layout_type.replace("_", "-")
|
|
464
468
|
layout_div["data-layout-type"] = layout_type
|
|
465
469
|
for cell in section.find_all("ac:layout-cell", recursive=False):
|
|
@@ -468,7 +472,11 @@ def _preprocess_storage_format(html: str) -> tuple[BeautifulSoup, list[str]]:
|
|
|
468
472
|
for child in list(cell.children):
|
|
469
473
|
cell_div.append(child.extract())
|
|
470
474
|
layout_div.append(cell_div)
|
|
471
|
-
|
|
475
|
+
section_divs.append(layout_div)
|
|
476
|
+
# Insert all section divs after the layout, then remove it
|
|
477
|
+
for div in reversed(section_divs):
|
|
478
|
+
layout.insert_after(div)
|
|
479
|
+
layout.decompose()
|
|
472
480
|
|
|
473
481
|
# 6. Transform ac:link → a
|
|
474
482
|
for link in soup.find_all("ac:link"):
|
|
@@ -355,6 +355,50 @@ class TestLayoutReverse:
|
|
|
355
355
|
assert "Right" in result.markdown
|
|
356
356
|
assert "::::" in result.markdown
|
|
357
357
|
|
|
358
|
+
def test_layout_multiple_sections(self):
|
|
359
|
+
"""Multiple ac:layout-section elements must all be converted (bug fix)."""
|
|
360
|
+
html = (
|
|
361
|
+
'<ac:layout>'
|
|
362
|
+
'<ac:layout-section ac:type="single">'
|
|
363
|
+
'<ac:layout-cell><p>Section one</p></ac:layout-cell>'
|
|
364
|
+
'</ac:layout-section>'
|
|
365
|
+
'<ac:layout-section ac:type="single">'
|
|
366
|
+
'<ac:layout-cell>'
|
|
367
|
+
'<h1>Main heading</h1>'
|
|
368
|
+
'<p>Body paragraph with <strong>bold</strong> text.</p>'
|
|
369
|
+
'<ul><li>Item A</li><li>Item B</li></ul>'
|
|
370
|
+
'</ac:layout-cell>'
|
|
371
|
+
'</ac:layout-section>'
|
|
372
|
+
'</ac:layout>'
|
|
373
|
+
)
|
|
374
|
+
result = convert_storage_to_markdown(html)
|
|
375
|
+
assert "Section one" in result.markdown
|
|
376
|
+
assert "# Main heading" in result.markdown
|
|
377
|
+
assert "Body paragraph" in result.markdown
|
|
378
|
+
assert "**bold**" in result.markdown
|
|
379
|
+
assert "Item A" in result.markdown
|
|
380
|
+
assert "Item B" in result.markdown
|
|
381
|
+
|
|
382
|
+
def test_layout_mixed_section_types(self):
|
|
383
|
+
"""Sections with different layout types preserve their types."""
|
|
384
|
+
html = (
|
|
385
|
+
'<ac:layout>'
|
|
386
|
+
'<ac:layout-section ac:type="single">'
|
|
387
|
+
'<ac:layout-cell><p>Full width</p></ac:layout-cell>'
|
|
388
|
+
'</ac:layout-section>'
|
|
389
|
+
'<ac:layout-section ac:type="two_left_sidebar">'
|
|
390
|
+
'<ac:layout-cell><p>Sidebar</p></ac:layout-cell>'
|
|
391
|
+
'<ac:layout-cell><p>Main content</p></ac:layout-cell>'
|
|
392
|
+
'</ac:layout-section>'
|
|
393
|
+
'</ac:layout>'
|
|
394
|
+
)
|
|
395
|
+
result = convert_storage_to_markdown(html)
|
|
396
|
+
assert ":::: layout single" in result.markdown
|
|
397
|
+
assert ":::: layout two-left-sidebar" in result.markdown
|
|
398
|
+
assert "Full width" in result.markdown
|
|
399
|
+
assert "Sidebar" in result.markdown
|
|
400
|
+
assert "Main content" in result.markdown
|
|
401
|
+
|
|
358
402
|
|
|
359
403
|
class TestPluginRoundTrips:
|
|
360
404
|
"""Test round-trip conversion for new plugin features."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|