Text FIELD NOTES · 3 MIN READ
Per-Line Trimming: The Quiet Fix for Messy Pasted Text
Why line-by-line trimming beats a whole-text trim, and what the drop-blank-lines and collapse options decide.
The whitespace you cannot see is the whitespace that breaks things. A trailing space makes two identical-looking lines compare as different; a tab-only "blank" line refuses to behave like an empty one; a PDF paste arrives with indentation on every line. Fixing this needs to happen line by line, because a whole-text trim only touches the first and last characters of the entire block and leaves every interior line edge dirty.
What "trim every line" means
Each line is processed independently: first, optionally, every run of internal spaces and tabs is squeezed down to a single space (the collapse option); then the leading and trailing whitespace of the line is stripped. Whatever remains — including a completely empty remainder — is kept or dropped according to the second option, drop blank lines, which is on by default. Run the tool on this input and the arithmetic looks like this:
input: " alpha " / "" / " beta\tgamma " / "" (4 lines)
result: "alpha" / "beta gamma" (2 lines)
dropped blank lines: 2 collapse: on
Notice what collapse did and did not do. The tab between beta and gamma became one space, but the line break survived untouched — collapse operates inside lines, never across them. The two blank lines were counted (droppedEmpty: 2) and removed, and the trailing blank that came from the final newline went with them, which is why 4 lines became 2.
Blank lines and the drop-blank-lines option
A "blank" line is any line that is empty after trimming — a line of six spaces or two tabs counts as blank, which is exactly what you want, since whitespace-only lines are the ones that cause comparison and parsing surprises. Turn drop blank lines off and those lines are kept as truly empty strings instead. That matters when line positions carry meaning: CSV-style data where a blank row is a record separator, or a diff-friendly file where removing lines would create phantom changes. With dropping off, the same input keeps its 4 lines and produces an empty second line rather than deleting it — the tool reports both line counts so you can tell which mode ran.
The carriage-return problem you cannot see
Line endings are three different things in the wild: \r\n on Windows, \r on classic Mac, \n everywhere else. Text pasted from a Windows editor often carries carriage returns that make each line look fine but compare as dirty. The tool splits on all three and re-joins with plain \n:
input: "a\r\nb\rc\n d "
result: "a\nb\nc\nd" (line endings normalized to \n)
This normalization is a quiet bonus of running text through a line tool: mixed endings become consistent ones even though that was not the goal. Invisible characters that survive trimming — zero-width spaces and the like — are a different beast entirely, covered in Zero-Width Characters.
Where this step belongs in the pipeline
Per-line trimming is the first move in almost every cleanup, because every downstream comparison gets smarter when the padding is gone. Deduplicating apple and apple fails if you dedupe before trimming — they are different strings until the trim makes them the same one. The full story, including why the order of trim → drop empties → dedupe → sort is load-bearing, is in The Text Cleanup Pipeline. One caution: leave collapse off when internal spacing is meaningful. Code indentation, YAML structure, and aligned columns are destroyed by squeezing internal runs, while trimmed edges are always safe.
Try it yourself
Paste a messy multi-line block — indents, trailing spaces, blank lines, a tab or two — into the String Trim Lines tool and toggle both options to see each one's effect on the line counts. Feed the result to the Remove Duplicate Lines tool to watch previously "different" lines collapse into duplicates, and compare it with the Trim Whitespace tool's whole-text modes to see exactly which edges each approach can and cannot reach.