Transform a single prose line, leaving protected segments untouched.
(line, opts, counts)
| 64 | |
| 65 | |
| 66 | def _transform_line(line, opts, counts): |
| 67 | """Transform a single prose line, leaving protected segments untouched.""" |
| 68 | # Preserve leading indentation; only operate on the content after it. |
| 69 | stripped_lead = len(line) - len(line.lstrip(" ")) |
| 70 | indent, body = line[:stripped_lead], line[stripped_lead:] |
| 71 | |
| 72 | # Split into protected / unprotected pieces and only transform unprotected. |
| 73 | pieces = [] |
| 74 | pos = 0 |
| 75 | for m in _PROTECTED_RE.finditer(body): |
| 76 | if m.start() > pos: |
| 77 | pieces.append(("text", body[pos:m.start()])) |
| 78 | pieces.append(("keep", m.group(0))) |
| 79 | pos = m.end() |
| 80 | if pos < len(body): |
| 81 | pieces.append(("text", body[pos:])) |
| 82 | rebuilt = "".join( |
| 83 | _transform_prose_text(seg, opts, counts) if kind == "text" else seg |
| 84 | for kind, seg in pieces |
| 85 | ) |
| 86 | line = indent + rebuilt |
| 87 | |
| 88 | if opts["trailing_ws"]: |
| 89 | m = re.search(r"[ \t]+$", line) |
| 90 | if m: |
| 91 | run = m.group(0) |
| 92 | # A trailing run of 2+ spaces is a Markdown hard line break (<br>). |
| 93 | # Preserve it. Only a lone trailing space, or a run ending in a tab |
| 94 | # (tabs don't form a break), render identically when stripped. |
| 95 | is_hard_break = run.endswith(" ") and run.count(" ") >= 2 |
| 96 | if not is_hard_break: |
| 97 | line = line[:m.start()] |
| 98 | counts["trailing-whitespace"] += 1 |
| 99 | return line |
| 100 | |
| 101 | |
| 102 | def transform_body(body, opts, counts): |
no test coverage detected