Skip to content

Commit

Permalink
Make the file name safe function less restrictive
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Jun 11, 2024
1 parent 6d54902 commit 556caea
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
5 changes: 2 additions & 3 deletions novelwriter/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,11 @@ def readTextFile(path: str | Path) -> str:


def makeFileNameSafe(text: str) -> str:
"""Return a filename safe string.
"""Return a filename-safe string.
See: https://unicode.org/reports/tr15/#Norm_Forms
"""
text = unicodedata.normalize("NFKC", text).strip()
allowed = (" ", ".", "-", "_")
return "".join(c for c in text if c.isalnum() or c in allowed)
return "".join(c for c in text if c.isprintable() and c not in r'\/:*?"<>|')


def getFileSize(path: Path) -> int:
Expand Down
37 changes: 32 additions & 5 deletions tests/test_base/test_base_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,13 +621,40 @@ def testBaseCommon_readTextFile(monkeypatch, fncPath, ipsumText):
@pytest.mark.base
def testBaseCommon_makeFileNameSafe():
"""Test the makeFileNameSafe function."""
assert makeFileNameSafe(" aaaa ") == "aaaa"
assert makeFileNameSafe("aaaa,bbbb") == "aaaabbbb"
assert makeFileNameSafe("aaaa\tbbbb") == "aaaabbbb"
assert makeFileNameSafe("aaaa bbbb") == "aaaa bbbb"
assert makeFileNameSafe("æøå") == "æøå"
# Trim edges
assert makeFileNameSafe(" Name ") == "Name"

# Normalise Unicode
assert makeFileNameSafe("Stuff œfi2⁵") == "Stuff œfi25"

# No control characters
assert makeFileNameSafe("One\tTwo") == "OneTwo"
assert makeFileNameSafe("One\nTwo") == "OneTwo"
assert makeFileNameSafe("One\rTwo") == "OneTwo"

# Invalid special characters
assert makeFileNameSafe("One\\Two") == "OneTwo"
assert makeFileNameSafe("One/Two") == "OneTwo"
assert makeFileNameSafe("One:Two") == "OneTwo"
assert makeFileNameSafe("One*Two") == "OneTwo"
assert makeFileNameSafe("One?Two") == "OneTwo"
assert makeFileNameSafe('One"Two') == "OneTwo"
assert makeFileNameSafe("One<Two") == "OneTwo"
assert makeFileNameSafe("One>Two") == "OneTwo"
assert makeFileNameSafe("One|Two") == "OneTwo"

# Names that are valid
assert makeFileNameSafe("One Two") == "One Two"
assert makeFileNameSafe("One,Two") == "One,Two"
assert makeFileNameSafe("One-Two") == "One-Two"
assert makeFileNameSafe("One–Two") == "One–Two"
assert makeFileNameSafe("One—Two") == "One—Two"
assert makeFileNameSafe("Bob's Story") == "Bob's Story"

# Unicode
assert makeFileNameSafe("æøå") == "æøå"
assert makeFileNameSafe("ßÜ") == "ßÜ"


@pytest.mark.base
def testBaseCommon_getFileSize(fncPath):
Expand Down

0 comments on commit 556caea

Please sign in to comment.