fetchit-engine 0.1.1__tar.gz → 0.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fetchit-engine
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Deterministic text cleanup and AI-writing heuristics. Runs entirely in your process; text never leaves it.
5
5
  Author: Outta Work Solutions
6
6
  License-Expression: Apache-2.0
@@ -15,7 +15,7 @@ import json
15
15
  import os
16
16
  import re
17
17
 
18
- ENGINE_VERSION = "0.1.1"
18
+ ENGINE_VERSION = "0.1.2"
19
19
 
20
20
  # --- ruleset (single source of truth, shared with the JS package) -----------
21
21
  _RULESET_PATH = os.path.join(
@@ -245,16 +245,28 @@ def _clean_cells(text, disabled=frozenset()):
245
245
  dash pass plus multi-space collapse and space-before-punct tidy. A disabled
246
246
  rule id skips its pass entirely, so cleaned text and the edit list agree."""
247
247
  cells = _build_cells(text, disabled)
248
- rebuilt = "".join(c.text for c in cells)
249
- if _EM_DASH.search(rebuilt):
248
+ current = "".join(c.text for c in cells)
249
+ # Run the dash/space passes to a FIXED POINT, not once. A single pass is
250
+ # not idempotent: removing an em dash can manufacture the spacing that arms
251
+ # the spaced-en-dash rule ("X—– Y" -> "X – Y", and only a second clean
252
+ # reached "X Y"), which broke the documented clean(clean(x)) == clean(x)
253
+ # contract. Each enabled dash pass strictly reduces the dash count, so this
254
+ # terminates; the equality check breaks when the dash rule is disabled.
255
+ # Mirrors cleanCells() in the JS engine exactly.
256
+ for _guard in range(8):
257
+ if not _EM_DASH.search(current):
258
+ break
250
259
  if _DASH_RULE[0] not in disabled:
251
260
  cells, _ = _regex_pass(cells, _EM_DASH, " ", _DASH_RULE)
252
261
  if _COLLAPSE_RULE[0] not in disabled:
253
262
  cells, _ = _regex_pass(cells, _MULTI_SPACE, " ", _COLLAPSE_RULE)
254
263
  if _SPACE_BEFORE_RULE[0] not in disabled:
255
264
  cells, _ = _regex_pass(cells, _SPACE_BEFORE_PUNCT, "\\1", _SPACE_BEFORE_RULE)
256
- cleaned = "".join(c.text for c in cells)
257
- return cleaned, cells
265
+ nxt = "".join(c.text for c in cells)
266
+ if nxt == current:
267
+ break
268
+ current = nxt
269
+ return current, cells
258
270
 
259
271
 
260
272
  # --- public building blocks --------------------------------------------------
@@ -485,7 +497,9 @@ def clean(text, options=None):
485
497
 
486
498
  invisible_n = _count_consumed(lambda cp: _invisible_rule(cp) is not None)
487
499
  oddspace_n = _count_consumed(_is_odd_space)
488
- dashes_n = sum(1 for e in edits if e["ruleId"] == "dash.spaced")
500
+ # Dashes count by consumed CHARACTER too: with the fixed-point dash pass, a
501
+ # chain like "—– " merges into one edit that removed two dashes.
502
+ dashes_n = _count_consumed(lambda cp: cp in (0x2014, 0x2015, 0x2013))
489
503
 
490
504
  return {
491
505
  "engineVersion": ENGINE_VERSION,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fetchit-engine
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Deterministic text cleanup and AI-writing heuristics. Runs entirely in your process; text never leaves it.
5
5
  Author: Outta Work Solutions
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fetchit-engine"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Deterministic text cleanup and AI-writing heuristics. Runs entirely in your process; text never leaves it."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes
File without changes
File without changes