mkdocs2confluence 0.16.0__tar.gz → 0.16.1__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.
- {mkdocs2confluence-0.16.0/src/mkdocs2confluence.egg-info → mkdocs2confluence-0.16.1}/PKG-INFO +1 -1
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/pyproject.toml +1 -1
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1/src/mkdocs2confluence.egg-info}/PKG-INFO +1 -1
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/page.py +4 -2
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/emitter/xhtml.py +3 -3
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/nodes.py +11 -6
- mkdocs2confluence-0.16.1/src/mkdocs_to_confluence/parser/__init__.py +5 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/parser/markdown.py +10 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/abbrevs.py +10 -6
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_abbrevs.py +48 -4
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_emitter.py +18 -2
- mkdocs2confluence-0.16.0/src/mkdocs_to_confluence/parser/__init__.py +0 -5
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/LICENSE +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/README.md +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/setup.cfg +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/SOURCES.txt +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/dependency_links.txt +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/entry_points.txt +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/requires.txt +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/top_level.txt +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/cli.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/models.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/emitter/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/document.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/treeutil.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/config.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/extra_css.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/nav.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/page.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/generator.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/render.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/abbrevs.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/captions.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/fence.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/frontmatter.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/icons.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/includes.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/linkdefs.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/render.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/server.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/changelog.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/client.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/executor.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/http_retry.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/models.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/pipeline.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/planner.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/skill_installer.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/skills/mkdocs-changelog/SKILL.md +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/skills/mkdocs-changelog/scripts/changelog_data.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/anchoring.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/command.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/comments.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/github.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/platform.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/state.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/__init__.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/admonition_titles.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/assets.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/attachment_previews.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/captions.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/editlink.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/footer.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/images.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/internallinks.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/mermaid.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_admonition_titles.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_attachment_previews.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_captions.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_changelog_config.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_changelog_publish.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_children_macro.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_cli.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_editlink.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_exclude_properties_config.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_extra_css.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_footer.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_frontmatter.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_icons.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_images.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_internallinks.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_ir.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_linkdefs.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_loader.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_mermaid.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_page_loader.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_parser.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_pdf.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_preprocess.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_preview.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_publish_client.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_publish_config.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_publish_pipeline.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_server.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_skill_installer.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_sync_anchoring.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_sync_command.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_sync_comments.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_sync_github.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_sync_state.py +0 -0
- {mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_treeutil.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mkdocs2confluence"
|
|
3
|
-
version = "0.16.
|
|
3
|
+
version = "0.16.1"
|
|
4
4
|
description = "Publish MkDocs Material pages to Confluence Cloud — admonitions, Mermaid diagrams, tabs, page properties and more"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "GPL-3.0-or-later" }
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/page.py
RENAMED
|
@@ -8,7 +8,7 @@ from mkdocs_to_confluence.ir.nodes import ChildrenMacro, FrontMatter, SourceFoot
|
|
|
8
8
|
from mkdocs_to_confluence.loader.config import MkDocsConfig
|
|
9
9
|
from mkdocs_to_confluence.loader.nav import NavNode
|
|
10
10
|
from mkdocs_to_confluence.loader.page import load_page
|
|
11
|
-
from mkdocs_to_confluence.parser.markdown import parse
|
|
11
|
+
from mkdocs_to_confluence.parser.markdown import parse, parse_inline
|
|
12
12
|
from mkdocs_to_confluence.preprocess.abbrevs import (
|
|
13
13
|
extract_abbreviations,
|
|
14
14
|
strip_abbreviation_defs,
|
|
@@ -79,7 +79,9 @@ def compile_page(
|
|
|
79
79
|
ir_nodes = strip_links_in_admonition_titles(ir_nodes, node.docs_path or "")
|
|
80
80
|
if is_section_index:
|
|
81
81
|
ir_nodes = ir_nodes + (ChildrenMacro(),)
|
|
82
|
-
|
|
82
|
+
# Parse definitions as inline markdown so links etc. survive into the glossary.
|
|
83
|
+
parsed_abbrevs = {abbr: parse_inline(defn) for abbr, defn in abbrevs.items()}
|
|
84
|
+
ir_nodes = apply_abbreviations(ir_nodes, parsed_abbrevs, page_text=preprocessed)
|
|
83
85
|
ir_nodes, attachments = resolve_local_assets(
|
|
84
86
|
ir_nodes,
|
|
85
87
|
page_path=node.source_path,
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/emitter/xhtml.py
RENAMED
|
@@ -623,11 +623,11 @@ def _emit_abbrev_glossary_block(node: AbbrevGlossaryBlock) -> str:
|
|
|
623
623
|
f"</ac:structured-macro>"
|
|
624
624
|
)
|
|
625
625
|
abbr = html.escape(fn.abbr)
|
|
626
|
-
defn =
|
|
626
|
+
defn = _emit_inlines(fn.definition)
|
|
627
627
|
parts.append(f"<li>{anchor_macro}<strong>{abbr}</strong> — {defn}</li>\n")
|
|
628
|
-
for
|
|
628
|
+
for fn in node.extras:
|
|
629
629
|
# No anchor — these only appeared in headings/titles, no inline superscript links here.
|
|
630
|
-
parts.append(f"<li><strong>{html.escape(abbr)}</strong> — {
|
|
630
|
+
parts.append(f"<li><strong>{html.escape(fn.abbr)}</strong> — {_emit_inlines(fn.definition)}</li>\n")
|
|
631
631
|
parts.append("</ol>\n")
|
|
632
632
|
return "".join(parts)
|
|
633
633
|
|
|
@@ -497,11 +497,16 @@ class AbbrevFootnoteNode(IRNode):
|
|
|
497
497
|
|
|
498
498
|
The emitter renders ``ABBR<sup>[N]</sup>`` where ``[N]`` links to the
|
|
499
499
|
corresponding entry in the end-of-page :class:`AbbrevGlossaryBlock`.
|
|
500
|
+
|
|
501
|
+
``definition`` holds the definition text parsed as inline IR nodes so
|
|
502
|
+
that links and other inline formatting survive into the glossary.
|
|
500
503
|
"""
|
|
501
504
|
|
|
502
505
|
abbr: str
|
|
503
|
-
definition:
|
|
504
|
-
|
|
506
|
+
definition: tuple[IRNode, ...]
|
|
507
|
+
# 1-based, assigned by the transform in order of first encounter.
|
|
508
|
+
# ``None`` for glossary-only entries (no inline superscript, no anchor).
|
|
509
|
+
number: int | None
|
|
505
510
|
|
|
506
511
|
|
|
507
512
|
@dataclass(frozen=True)
|
|
@@ -509,17 +514,17 @@ class AbbrevGlossaryBlock(IRNode):
|
|
|
509
514
|
"""End-of-page abbreviations reference block.
|
|
510
515
|
|
|
511
516
|
Rendered as a numbered list (with Confluence anchor targets for the
|
|
512
|
-
back-links) followed by
|
|
513
|
-
|
|
517
|
+
back-links) followed by entries for abbreviations that only appeared
|
|
518
|
+
in headings or other non-expandable contexts.
|
|
514
519
|
|
|
515
520
|
Attributes:
|
|
516
521
|
footnoted: Abbreviations annotated inline, ordered by first encounter.
|
|
517
|
-
extras: ``
|
|
522
|
+
extras: Entries (``number=None``) for abbreviations that could
|
|
518
523
|
not be annotated inline, sorted alphabetically.
|
|
519
524
|
"""
|
|
520
525
|
|
|
521
526
|
footnoted: tuple[AbbrevFootnoteNode, ...]
|
|
522
|
-
extras: tuple[
|
|
527
|
+
extras: tuple[AbbrevFootnoteNode, ...]
|
|
523
528
|
|
|
524
529
|
|
|
525
530
|
# ── Footnotes ────────────────────────────────────────────────────────────────
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/parser/markdown.py
RENAMED
|
@@ -111,6 +111,16 @@ def parse(text: str) -> tuple[IRNode, ...]:
|
|
|
111
111
|
return _build_tree(tokens)
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
def parse_inline(text: str) -> tuple[IRNode, ...]:
|
|
115
|
+
"""Parse a standalone snippet of inline markdown into IR inline nodes.
|
|
116
|
+
|
|
117
|
+
Used for one-line fragments that live outside the main document flow,
|
|
118
|
+
e.g. abbreviation definitions, where links and other inline formatting
|
|
119
|
+
must still be honoured.
|
|
120
|
+
"""
|
|
121
|
+
return _parse_inline(text)
|
|
122
|
+
|
|
123
|
+
|
|
114
124
|
# ── Internal token types ──────────────────────────────────────────────────────
|
|
115
125
|
|
|
116
126
|
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/abbrevs.py
RENAMED
|
@@ -65,7 +65,7 @@ _BLOCK_TYPES = (
|
|
|
65
65
|
class _State:
|
|
66
66
|
"""Mutable transform state threaded through the recursive walk."""
|
|
67
67
|
|
|
68
|
-
def __init__(self, abbrevs: dict[str,
|
|
68
|
+
def __init__(self, abbrevs: dict[str, tuple[IRNode, ...]]) -> None:
|
|
69
69
|
self.abbrevs = abbrevs
|
|
70
70
|
self._expanded_list: list[str] = [] # ordered by first encounter
|
|
71
71
|
self._expanded_set: set[str] = set() # fast membership test
|
|
@@ -207,7 +207,7 @@ def _transform_inline(node: IRNode, state: _State, safe: bool) -> tuple[IRNode,
|
|
|
207
207
|
# ── Glossary builder ──────────────────────────────────────────────────────────
|
|
208
208
|
|
|
209
209
|
|
|
210
|
-
def _find_mentioned(text: str, abbrevs: dict[str,
|
|
210
|
+
def _find_mentioned(text: str, abbrevs: dict[str, tuple[IRNode, ...]]) -> set[str]:
|
|
211
211
|
"""Return abbreviations that appear as whole words anywhere in *text*."""
|
|
212
212
|
return {
|
|
213
213
|
abbr
|
|
@@ -221,7 +221,7 @@ def _find_mentioned(text: str, abbrevs: dict[str, str]) -> set[str]:
|
|
|
221
221
|
|
|
222
222
|
def apply_abbreviations(
|
|
223
223
|
nodes: tuple[IRNode, ...],
|
|
224
|
-
abbrevs: dict[str,
|
|
224
|
+
abbrevs: dict[str, tuple[IRNode, ...]],
|
|
225
225
|
*,
|
|
226
226
|
page_text: str = "",
|
|
227
227
|
) -> tuple[IRNode, ...]:
|
|
@@ -229,8 +229,12 @@ def apply_abbreviations(
|
|
|
229
229
|
|
|
230
230
|
Args:
|
|
231
231
|
nodes: Top-level IR nodes returned by :func:`parse`.
|
|
232
|
-
abbrevs: ``{abbreviation: definition}`` mapping
|
|
233
|
-
|
|
232
|
+
abbrevs: ``{abbreviation: definition}`` mapping where each
|
|
233
|
+
definition is parsed inline IR nodes (the caller parses
|
|
234
|
+
the raw definition strings from
|
|
235
|
+
:func:`~mkdocs_to_confluence.preprocess.abbrevs.extract_abbreviations`
|
|
236
|
+
with :func:`~mkdocs_to_confluence.parser.parse_inline` so
|
|
237
|
+
links and other inline formatting are preserved).
|
|
234
238
|
page_text: The preprocessed page text (after stripping abbreviation
|
|
235
239
|
definition lines) used to detect which abbreviations are
|
|
236
240
|
actually present on the page.
|
|
@@ -255,7 +259,7 @@ def apply_abbreviations(
|
|
|
255
259
|
for i, abbr in enumerate(state._expanded_list)
|
|
256
260
|
)
|
|
257
261
|
extras = tuple(
|
|
258
|
-
(abbr, abbrevs[abbr])
|
|
262
|
+
AbbrevFootnoteNode(abbr=abbr, definition=abbrevs[abbr], number=None)
|
|
259
263
|
for abbr in sorted(mentioned - state._expanded_set)
|
|
260
264
|
)
|
|
261
265
|
|
|
@@ -8,6 +8,7 @@ from mkdocs_to_confluence.ir.nodes import (
|
|
|
8
8
|
Admonition,
|
|
9
9
|
BoldNode,
|
|
10
10
|
CodeBlock,
|
|
11
|
+
IRNode,
|
|
11
12
|
LinkNode,
|
|
12
13
|
Paragraph,
|
|
13
14
|
Section,
|
|
@@ -16,11 +17,25 @@ from mkdocs_to_confluence.ir.nodes import (
|
|
|
16
17
|
TableRow,
|
|
17
18
|
TextNode,
|
|
18
19
|
)
|
|
20
|
+
from mkdocs_to_confluence.parser import parse_inline
|
|
19
21
|
from mkdocs_to_confluence.preprocess.abbrevs import (
|
|
20
22
|
extract_abbreviations,
|
|
21
23
|
strip_abbreviation_defs,
|
|
22
24
|
)
|
|
23
|
-
from mkdocs_to_confluence.transforms.abbrevs import
|
|
25
|
+
from mkdocs_to_confluence.transforms.abbrevs import (
|
|
26
|
+
apply_abbreviations as _apply_abbreviations,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def apply_abbreviations(
|
|
31
|
+
nodes: tuple[IRNode, ...],
|
|
32
|
+
abbrevs: dict[str, str],
|
|
33
|
+
*,
|
|
34
|
+
page_text: str = "",
|
|
35
|
+
) -> tuple[IRNode, ...]:
|
|
36
|
+
"""Parse string definitions inline (as the compiler does) and apply."""
|
|
37
|
+
parsed = {abbr: parse_inline(defn) for abbr, defn in abbrevs.items()}
|
|
38
|
+
return _apply_abbreviations(nodes, parsed, page_text=page_text)
|
|
24
39
|
|
|
25
40
|
# ── extract_abbreviations ─────────────────────────────────────────────────────
|
|
26
41
|
|
|
@@ -94,7 +109,7 @@ def test_expands_first_occurrence_as_footnote():
|
|
|
94
109
|
fn = children[1]
|
|
95
110
|
assert isinstance(fn, AbbrevFootnoteNode)
|
|
96
111
|
assert fn.abbr == "IAM"
|
|
97
|
-
assert fn.definition == "Identity and Access Management"
|
|
112
|
+
assert fn.definition == (TextNode("Identity and Access Management"),)
|
|
98
113
|
assert fn.number == 1
|
|
99
114
|
# Second occurrence left as plain text
|
|
100
115
|
assert isinstance(children[2], TextNode)
|
|
@@ -141,7 +156,10 @@ def test_glossary_block_appended_for_heading_only_abbrev():
|
|
|
141
156
|
glossary = result[1]
|
|
142
157
|
assert isinstance(glossary, AbbrevGlossaryBlock)
|
|
143
158
|
assert len(glossary.footnoted) == 0
|
|
144
|
-
assert glossary.extras ==
|
|
159
|
+
assert len(glossary.extras) == 1
|
|
160
|
+
assert glossary.extras[0].abbr == "IAM"
|
|
161
|
+
assert glossary.extras[0].definition == (TextNode("Identity and Access Management"),)
|
|
162
|
+
assert glossary.extras[0].number is None
|
|
145
163
|
|
|
146
164
|
|
|
147
165
|
def test_no_glossary_when_abbrev_footnoted_inline():
|
|
@@ -232,7 +250,7 @@ def test_extras_sorted_alphabetically():
|
|
|
232
250
|
result = apply_abbreviations((section,), abbrevs, page_text="IAM and RBAC Overview")
|
|
233
251
|
glossary = result[-1]
|
|
234
252
|
assert isinstance(glossary, AbbrevGlossaryBlock)
|
|
235
|
-
extra_abbrs = [abbr for
|
|
253
|
+
extra_abbrs = [fn.abbr for fn in glossary.extras]
|
|
236
254
|
assert extra_abbrs == sorted(extra_abbrs)
|
|
237
255
|
|
|
238
256
|
|
|
@@ -254,3 +272,29 @@ def test_expands_in_loose_list_item():
|
|
|
254
272
|
result = apply_abbreviations(nodes, abbrevs, page_text="Use the API here.")
|
|
255
273
|
para_children = result[0].items[0].children[0].children # type: ignore[union-attr]
|
|
256
274
|
assert any(isinstance(c, AbbrevFootnoteNode) and c.abbr == "API" for c in para_children)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# ── Markdown in definitions ──────────────────────────────────────────────────
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def test_definition_with_link_parsed_to_link_node():
|
|
281
|
+
abbrevs = {"FB": "The [Foo](http://forr.bar) service"}
|
|
282
|
+
nodes = (_para("Use FB here."),)
|
|
283
|
+
result = apply_abbreviations(nodes, abbrevs, page_text="Use FB here.")
|
|
284
|
+
glossary = result[-1]
|
|
285
|
+
assert isinstance(glossary, AbbrevGlossaryBlock)
|
|
286
|
+
definition = glossary.footnoted[0].definition
|
|
287
|
+
links = [n for n in definition if isinstance(n, LinkNode)]
|
|
288
|
+
assert len(links) == 1
|
|
289
|
+
assert links[0].href == "http://forr.bar"
|
|
290
|
+
assert links[0].children == (TextNode("Foo"),)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def test_extra_definition_with_link_parsed_to_link_node():
|
|
294
|
+
abbrevs = {"FB": "The [Foo](http://forr.bar) service"}
|
|
295
|
+
section = Section(level=2, anchor="fb", title=(TextNode("FB Platform"),), children=())
|
|
296
|
+
result = apply_abbreviations((section,), abbrevs, page_text="FB Platform")
|
|
297
|
+
glossary = result[-1]
|
|
298
|
+
assert isinstance(glossary, AbbrevGlossaryBlock)
|
|
299
|
+
definition = glossary.extras[0].definition
|
|
300
|
+
assert any(isinstance(n, LinkNode) and n.href == "http://forr.bar" for n in definition)
|
|
@@ -474,10 +474,10 @@ class TestFootnoteEmitter:
|
|
|
474
474
|
"""Abbreviations only in headings/titles must appear in <ol>, not <ul>."""
|
|
475
475
|
from mkdocs_to_confluence.emitter.xhtml import emit
|
|
476
476
|
from mkdocs_to_confluence.ir.nodes import AbbrevFootnoteNode, AbbrevGlossaryBlock
|
|
477
|
-
fn = AbbrevFootnoteNode(abbr="API", definition="Application Programming Interface", number=1)
|
|
477
|
+
fn = AbbrevFootnoteNode(abbr="API", definition=(TextNode("Application Programming Interface"),), number=1)
|
|
478
478
|
block = AbbrevGlossaryBlock(
|
|
479
479
|
footnoted=(fn,),
|
|
480
|
-
extras=(("AD", "Active Directory"),),
|
|
480
|
+
extras=(AbbrevFootnoteNode(abbr="AD", definition=(TextNode("Active Directory"),), number=None),),
|
|
481
481
|
)
|
|
482
482
|
out = emit((block,))
|
|
483
483
|
assert "<ol>" in out
|
|
@@ -488,6 +488,22 @@ class TestFootnoteEmitter:
|
|
|
488
488
|
# extras must NOT get an anchor macro
|
|
489
489
|
assert out.count('ac:name="anchor"') == 1 # only for the footnoted entry
|
|
490
490
|
|
|
491
|
+
def test_abbrev_glossary_definition_with_link(self) -> None:
|
|
492
|
+
"""A markdown link in a definition must render as an <a>, not raw text."""
|
|
493
|
+
from mkdocs_to_confluence.ir.nodes import AbbrevFootnoteNode, AbbrevGlossaryBlock
|
|
494
|
+
defn = (
|
|
495
|
+
TextNode("The "),
|
|
496
|
+
LinkNode(href="http://forr.bar", children=(TextNode("Foo"),)),
|
|
497
|
+
TextNode(" service"),
|
|
498
|
+
)
|
|
499
|
+
block = AbbrevGlossaryBlock(
|
|
500
|
+
footnoted=(AbbrevFootnoteNode(abbr="FB", definition=defn, number=1),),
|
|
501
|
+
extras=(AbbrevFootnoteNode(abbr="BZ", definition=defn, number=None),),
|
|
502
|
+
)
|
|
503
|
+
out = emit((block,))
|
|
504
|
+
assert out.count('<a href="http://forr.bar">Foo</a>') == 2
|
|
505
|
+
assert "[Foo]" not in out
|
|
506
|
+
|
|
491
507
|
|
|
492
508
|
# ── Inline HTML emitters ──────────────────────────────────────────────────────
|
|
493
509
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/requires.txt
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs2confluence.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/compiler/models.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/emitter/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/document.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/ir/treeutil.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/config.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/extra_css.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/nav.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/loader/page.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/generator.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/pdf/render.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/abbrevs.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/fence.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preprocess/icons.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/render.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/preview/server.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/client.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/executor.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/models.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/pipeline.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/publisher/planner.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/skill_installer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/anchoring.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/command.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/comments.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/github.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/platform.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/sync/state.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/assets.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/footer.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/images.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/src/mkdocs_to_confluence/transforms/mermaid.py
RENAMED
|
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
|
{mkdocs2confluence-0.16.0 → mkdocs2confluence-0.16.1}/tests/test_exclude_properties_config.py
RENAMED
|
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
|