Source code for dsw_document_template_tool._template_transform.rewrite_rules

"""Small helpers for exact, reversible source rewrites."""

from __future__ import annotations

from dataclasses import dataclass

from .markers import encode_marker_payload
from .profile import TransformTrace

ReversibleReplacement = tuple[str, str]
ReversibleReplacements = tuple[ReversibleReplacement, ...]

__all__ = [
    "ReversibleReplacement",
    "ReversibleReplacementGroup",
    "ReversibleReplacements",
    "apply_reversible_replacement_groups",
    "apply_reversible_replacements",
    "wrap_reversible_branch_sentence_rewrite",
]


[docs] @dataclass(frozen=True) class ReversibleReplacementGroup: """A named group of exact source rewrites. The group ID is intentionally diagnostic-only. It gives template-specific rewrite modules a place to document why a set of replacements exists without changing the generated template output. """ group_id: str replacements: ReversibleReplacements rationale: str = ""
[docs] def apply_reversible_replacements( source_text: str, replacements: ReversibleReplacements, ) -> str: """Apply exact replacements and preserve the original text for compaction.""" rewritten_text, _match_count = _apply_reversible_replacements(source_text, replacements) return rewritten_text
def _apply_reversible_replacements( source_text: str, replacements: ReversibleReplacements, ) -> tuple[str, int]: """Apply exact replacements and return the number of matched rules.""" rewritten_text = source_text match_count = 0 for original, replacement in replacements: if original not in rewritten_text: continue rewritten_text = rewritten_text.replace( original, wrap_reversible_branch_sentence_rewrite( original=original, replacement=replacement, ), 1, ) match_count += 1 return rewritten_text, match_count
[docs] def apply_reversible_replacement_groups( source_text: str, groups: tuple[ReversibleReplacementGroup, ...], *, source_file: str = "", trace: TransformTrace | None = None, ) -> str: """Apply named exact replacement groups in order.""" rewritten_text = source_text for group in groups: rewritten_text, match_count = _apply_reversible_replacements( rewritten_text, group.replacements, ) if trace is not None: trace.record( group_id=group.group_id, rationale=group.rationale, source_file=source_file, match_count=match_count, ) return rewritten_text
[docs] def wrap_reversible_branch_sentence_rewrite(*, original: str, replacement: str) -> str: """Wrap replacement text with a marker containing the exact original text.""" encoded_original = encode_marker_payload(original) return ( f"{{# __tr_branch_sentence_original:{encoded_original} #}}" f"{replacement}" "{# __tr_branch_sentence_original:end #}" )