Skip to content

Rewriting a CRLF document (or an LF one on Windows) produces mixed line endings: header uses Environment.NewLine, body keeps the original #158

Description

@matt-edmondson

What's wrong

The parser accepts CRLF, LF and CR input, but every writer builds delimiters, the YAML join and the trailing newline from Environment.NewLine, while copying the body through verbatim:

  • CombineFrontmatter — Frontmatter/Frontmatter.cs ~L116
  • AddFrontmatter — ~L203
  • ReplaceFrontmatter — ~L225
  • RemoveFrontmatter — ~L245 (body.Trim() + Environment.NewLine)

Failure scenario (reproduced with an MSTest probe on Linux, current main)

Input: "---\r\ntitle: A\r\n---\r\n---\r\nauthor: B\r\n---\r\nline1\r\nline2\r\n"

  • CombineFrontmatter → "---\ntitle: A\nauthor: B\n---\nline1\r\nline2\r\n" — LF header, CRLF body.
  • ReplaceFrontmatter, RemoveFrontmatter, and AddFrontmatter("line1\r\nline2\r\n", …) trim the body and append Environment.NewLine, so the body itself ends up mixed: line1\r\nline2\n.
  • On Windows the mirror happens: an LF document (the normal state of a git checkout with autocrlf=false or .gitattributes eol=lf) comes back with a CRLF header and final line.

Consequences: noisy whole-file diffs, .gitattributes/editorconfig end_of_line violations, and linters flagging mixed endings — for a library whose typical use is batch-rewriting files in a repo.

Suggested fix

Detect the input's newline once (first \r\n, \n or \r found; fall back to Environment.NewLine when the input has none) and use it for the delimiters, the YAML line join and the trailing newline; normalize the serialized YAML's line endings to match.

Acceptance criteria

  • For CRLF input, all four writers emit only \r\n; for LF input, only \n — regardless of the host OS.
  • Tests cover CRLF and LF inputs for CombineFrontmatter, AddFrontmatter, ReplaceFrontmatter, RemoveFrontmatter.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreadyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions