Skip to content

taxis: smart path sanitization #160

@forkwright

Description

@forkwright

Context

`crates/taxis/src/import/template.rs::sanitize_path_segment` currently replaces all of `/ \ : * ? " < > |` with ``. This produces ugly results: `Title: Subtitle` becomes `Title Subtitle`, double-spaced. The canonical layout uses smart per-character rules.

What

Replace the `UNSAFE` constant + the simple character substitution with a per-character smart rule table:

Char Replacement Rationale
`:` ` -` (space-dash) `Title: Subtitle` → `Title - Subtitle`
`/` `-` Slash separator
`\` `-` Same as forward slash
`|` `-` Pipe separator
`*` (removed) Glob char
`?` (removed) Glob char
`<` (removed) Redirection
`>` (removed) Redirection
`"` (removed) Quote
`'` (curly U+2018, U+2019) `'` (straight) Grep consistency
`"` (curly U+201C, U+201D) `"` (straight) Grep consistency

After substitution, collapse whitespace runs to a single space and trim. UTF-8 unicode is preserved (Björk, $uicideboy$, ñ, é all keep their characters).

Files

  • `crates/taxis/src/import/template.rs` — `sanitize_path_segment` function + tests

Acceptance

  • `sanitize_path_segment("Title: Subtitle")` returns `"Title - Subtitle"`
  • `sanitize_path_segment("AC/DC")` returns `"AC-DC"`
  • `sanitize_path_segment("What's Up?")` returns `"What's Up"` (curly apostrophe normalized, question mark removed)
  • `sanitize_path_segment("Björk")` returns `"Björk"` (unicode preserved)
  • `sanitize_path_segment("$uicideboy$")` returns `"$uicideboy$"` (dollar signs preserved)
  • Existing tests updated to assert smart replacements instead of underscore

Reference

Migration plan: 2026-04-09 chat session. Reference implementation in the migration scripts: `~/menos-ops/scratch/migrate-music-canonical.py` (`clean_name` function).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrefactorCode quality and architecture improvementsstorage-canonicalCanonical filesystem storage layout work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions