texdiff 0.2.4__tar.gz → 0.2.5__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.
Files changed (40) hide show
  1. {texdiff-0.2.4/src/texdiff.egg-info → texdiff-0.2.5}/PKG-INFO +1 -1
  2. {texdiff-0.2.4 → texdiff-0.2.5}/pyproject.toml +1 -1
  3. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/__init__.py +1 -1
  4. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/align.py +5 -1
  5. {texdiff-0.2.4 → texdiff-0.2.5/src/texdiff.egg-info}/PKG-INFO +1 -1
  6. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_align.py +38 -0
  7. {texdiff-0.2.4 → texdiff-0.2.5}/LICENSE +0 -0
  8. {texdiff-0.2.4 → texdiff-0.2.5}/README.md +0 -0
  9. {texdiff-0.2.4 → texdiff-0.2.5}/setup.cfg +0 -0
  10. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/api.py +0 -0
  11. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/check.py +0 -0
  12. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/cli.py +0 -0
  13. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/emit.py +0 -0
  14. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/flatten.py +0 -0
  15. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/newlines.py +0 -0
  16. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/nodes.py +0 -0
  17. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/oldlines.py +0 -0
  18. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/parse.py +0 -0
  19. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/preamble.py +0 -0
  20. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/tables.py +0 -0
  21. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff/textdiff.py +0 -0
  22. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff.egg-info/SOURCES.txt +0 -0
  23. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff.egg-info/dependency_links.txt +0 -0
  24. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff.egg-info/entry_points.txt +0 -0
  25. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff.egg-info/requires.txt +0 -0
  26. {texdiff-0.2.4 → texdiff-0.2.5}/src/texdiff.egg-info/top_level.txt +0 -0
  27. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_alignment.py +0 -0
  28. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_api.py +0 -0
  29. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_check.py +0 -0
  30. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_cli.py +0 -0
  31. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_corpus.py +0 -0
  32. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_emit.py +0 -0
  33. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_flatten.py +0 -0
  34. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_parse.py +0 -0
  35. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_preamble.py +0 -0
  36. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_table_head_order.py +0 -0
  37. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_tables.py +0 -0
  38. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_tables_render.py +0 -0
  39. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_textdiff.py +0 -0
  40. {texdiff-0.2.4 → texdiff-0.2.5}/tests/test_verbatim.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: texdiff
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: AST-driven semantic diff for LaTeX documents
5
5
  Author: GoBobr
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "texdiff"
7
- version = "0.2.4"
7
+ version = "0.2.5"
8
8
  description = "AST-driven semantic diff for LaTeX documents"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -42,4 +42,4 @@ __all__ = [
42
42
  "word_diff",
43
43
  ]
44
44
 
45
- __version__ = "0.2.4"
45
+ __version__ = "0.2.5"
@@ -690,8 +690,12 @@ def _sibling_swap_rescue(edits: list[Edit], _pair) -> list[Edit]:
690
690
  for i, j in swaps.items():
691
691
  swap_new[i] = edits[j].new
692
692
  edits[j] = Insert(new=modifies[i].new)
693
+ # pair through _pair, NOT raw Modify: the swapped-in sibling can
694
+ # be verbatim-equal to the old node (the rescue often trades a
695
+ # mis-pairing for the node's TRUE counterpart). A raw Modify then
696
+ # renders an unchanged table as wholesale retired + reinserted.
693
697
  return [
694
- Modify(old=modifies[idx].old, new=swap_new[idx])
698
+ _pair(modifies[idx].old, swap_new[idx])
695
699
  if idx in swaps
696
700
  else e
697
701
  for idx, e in enumerate(edits)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: texdiff
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: AST-driven semantic diff for LaTeX documents
5
5
  Author: GoBobr
6
6
  License: MIT License
@@ -89,3 +89,41 @@ class TestSameSignatureDifferentText:
89
89
  new = [group(text_node("schemas")), group(text_node("handlers")), text_node("tail\n\n")]
90
90
  edits = align(old, new)
91
91
  assert [type(e).__name__ for e in edits] == ["Insert", "Match", "Match"]
92
+
93
+
94
+ def test_sibling_swap_rescue_pairs_verbatim_equal_swap_as_match():
95
+ """A swap that lands on a verbatim-equal sibling must Match.
96
+
97
+ The sibling-swap rescue re-pairs a Modify with the same-signature
98
+ Insert the old side actually resembles. When the swapped-in
99
+ sibling is byte-identical to the old node - an unchanged table
100
+ re-inserted next to a new sibling table (PGS "consumed
101
+ variables" band table) - the rescue used to construct a raw
102
+ Modify. Emit then rendered the IDENTICAL table as a wholesale
103
+ retired (red, unstruck) copy followed by a blue re-inserted
104
+ copy. The swap must go through _pair so equal text degrades to
105
+ a plain Match.
106
+ """
107
+ from texdiff.align import _sibling_swap_rescue
108
+ from texdiff.parse import parse
109
+
110
+ def _env(body: str):
111
+ return parse(f"\\begin{{savenotes}}\n{body}\n\\end{{savenotes}}\n")[0]
112
+
113
+ def _pair(o, n):
114
+ if o.text == n.text:
115
+ return Match(node=o)
116
+ return Modify(old=o, new=n)
117
+
118
+ old_node = _env("alpha beta gamma delta epsilon zeta")
119
+ wrong_new = _env("an unrelated climatology tail with other words")
120
+ right_new = _env("alpha beta gamma delta epsilon zeta")
121
+
122
+ edits = [Modify(old=old_node, new=wrong_new), Insert(new=right_new)]
123
+ out = _sibling_swap_rescue(edits, _pair)
124
+ # the identical counterpart matches: renders black, not retired
125
+ assert type(out[0]).__name__ == "Match"
126
+ assert out[0].node is old_node
127
+ # the previously (wrongly) chosen sibling stays visible as insert
128
+ assert type(out[1]).__name__ == "Insert"
129
+ assert out[1].new is wrong_new
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