Skip to content

Commit d814347

Browse files
authored
Add text file convention (#183)
1 parent ade2590 commit d814347

File tree

7 files changed

+74
-11
lines changed

7 files changed

+74
-11
lines changed

readme.md

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ A collection of minimal binary files.
2020

2121
All files: https://github.com/VerifyTests/EmptyFiles/tree/main/files
2222

23+
2324
<!-- include: extensions. path: /src/extensions.include.md -->
2425
### Archive
2526

@@ -37,7 +38,7 @@ All files: https://github.com/VerifyTests/EmptyFiles/tree/main/files
3738

3839
* .docx (1.9 KB)
3940
* .odt (2.2 KB)
40-
* .pdf (291 bytes)
41+
* .pdf (280 bytes)
4142
* .rtf (6 bytes)
4243

4344
### Image
@@ -54,13 +55,13 @@ All files: https://github.com/VerifyTests/EmptyFiles/tree/main/files
5455
* .ico (70 bytes)
5556
* .j2c (270 bytes)
5657
* .jfif (734 bytes)
57-
* .jp2 (357 bytes)
58+
* .jp2 (354 bytes)
5859
* .jpc (270 bytes)
5960
* .jpe (734 bytes)
6061
* .jpeg (734 bytes)
6162
* .jpg (734 bytes)
6263
* .jxr (300 bytes)
63-
* .pbm (10 bytes)
64+
* .pbm (8 bytes)
6465
* .pcx (131 bytes)
6566
* .pgm (12 bytes)
6667
* .png (119 bytes)
@@ -253,7 +254,7 @@ FileExtensions.AddTextExtension(".ext1");
253254
True(FileExtensions.IsTextExtension(".ext1"));
254255
True(FileExtensions.IsTextFile("file.ext1"));
255256
```
256-
<sup><a href='/src/Tests/ExtensionsTests.cs#L36-L42' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddTextExtension' title='Start of snippet'>anchor</a></sup>
257+
<sup><a href='/src/Tests/ExtensionsTests.cs#L50-L56' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddTextExtension' title='Start of snippet'>anchor</a></sup>
257258
<!-- endSnippet -->
258259

259260

@@ -267,10 +268,40 @@ True(FileExtensions.IsTextExtension(".ext1"));
267268
FileExtensions.RemoveTextExtension(".ext1");
268269
False(FileExtensions.IsTextExtension(".ext1"));
269270
```
270-
<sup><a href='/src/Tests/ExtensionsTests.cs#L52-L59' title='Snippet source file'>snippet source</a> | <a href='#snippet-RemoveTextExtension' title='Start of snippet'>anchor</a></sup>
271+
<sup><a href='/src/Tests/ExtensionsTests.cs#L66-L73' title='Snippet source file'>snippet source</a> | <a href='#snippet-RemoveTextExtension' title='Start of snippet'>anchor</a></sup>
271272
<!-- endSnippet -->
272273

273274

275+
#### AddTextFileConvention
276+
277+
`AddTextFileConvention` allows the use of a convention based text file detection via a callback.
278+
279+
At app startup add a convention using `FileExtensions.AddTextFileConvention`:
280+
281+
<!-- snippet: AddTextFileConvention -->
282+
<a id='snippet-AddTextFileConvention'></a>
283+
```cs
284+
[ModuleInitializer]
285+
public static void AddTextFileConvention() =>
286+
// Treat files ending with .txtViaConvention as text files
287+
FileExtensions.AddTextFileConvention(path => path.EndsWith(".txtViaConvention"));
288+
```
289+
<sup><a href='/src/Tests/ExtensionsTests.cs#L24-L30' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddTextFileConvention' title='Start of snippet'>anchor</a></sup>
290+
<!-- endSnippet -->
291+
292+
Then any call to `FileExtensions.IsTextFile` will, in addition to checking the known text extensions, also check if any of the added text contentions return true.
293+
294+
<!-- snippet: TextViaConvention -->
295+
<a id='snippet-TextViaConvention'></a>
296+
```cs
297+
True(FileExtensions.IsTextFile("c:/path/file.txtViaConvention"));
298+
```
299+
<sup><a href='/src/Tests/ExtensionsTests.cs#L17-L21' title='Snippet source file'>snippet source</a> | <a href='#snippet-TextViaConvention' title='Start of snippet'>anchor</a></sup>
300+
<!-- endSnippet -->
301+
302+
An alternative approach to a text file convention would be to check if a file has a preamble that matches an known text encoding.
303+
304+
274305
## Icon
275306

276307
[Hollow](https://thenounproject.com/term/hollow/51835/) designed by [Michael Senkow](https://thenounproject.com/mhsenkow/) from [The Noun Project](https://thenounproject.com).

src/EmptyFiles.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1111
Directory.Packages.props = Directory.Packages.props
1212
..\readme.md = ..\readme.md
1313
global.json = global.json
14+
mdsnippets.json = mdsnippets.json
1415
EndProjectSection
1516
EndProject
1617
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmptyFiles", "EmptyFiles\EmptyFiles.csproj", "{A017D3FD-7DA5-4DF4-A169-72DE4AF76048}"

src/EmptyFiles/FileExtensions.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ public static bool IsTextExtension(CharSpan extension) =>
1313
IsTextExtension(extension.ToString());
1414

1515
public static bool IsTextFile(string path) =>
16-
IsTextExtension(Path.GetExtension(path));
16+
IsTextFile(path.AsSpan());
1717

1818
public static bool IsTextFile(CharSpan path)
1919
{
20+
foreach (var convention in textFileConventions)
21+
{
22+
if (convention(path))
23+
{
24+
return true;
25+
}
26+
}
27+
2028
#if NET6_0_OR_GREATER
2129
var extension = Path.GetExtension(path);
2230
return IsTextExtension(extension);
2331
#else
24-
return IsTextFile(path.ToString());
32+
var extension = Path.GetExtension(path.ToString());
33+
return IsTextExtension(extension);
2534
#endif
2635
}
2736

@@ -81,6 +90,11 @@ public static void AddTextExtensions(IEnumerable<string> extensions)
8190
}
8291
}
8392

93+
public static void AddTextFileConvention(IsTextFile convention) =>
94+
textFileConventions.Add(convention);
95+
96+
static List<IsTextFile> textFileConventions = [];
97+
8498
//From https://github.com/sindresorhus/text-extensions/blob/master/text-extensions.json
8599
static IReadOnlyCollection<string> textExtensions = new HashSet<string>
86100
{

src/EmptyFiles/IsTextFile.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace EmptyFiles;
2+
3+
public delegate bool IsTextFile(CharSpan path);

src/Tests/ExtensionsTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,22 @@ public void IsText()
1313
False(FileExtensions.IsTextExtension("bin"));
1414

1515
#endregion
16+
17+
#region TextViaConvention
18+
19+
True(FileExtensions.IsTextFile("c:/path/file.txtViaConvention"));
20+
21+
#endregion
1622
}
1723

24+
#region AddTextFileConvention
25+
[ModuleInitializer]
26+
public static void AddTextFileConvention() =>
27+
// Treat files ending with .txtViaConvention as text files
28+
FileExtensions.AddTextFileConvention(path => path.EndsWith(".txtViaConvention"));
29+
30+
#endregion
31+
1832
[Test]
1933
public void IsTextLegacy()
2034
{

src/extensions.include.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
* .docx (1.9 KB)
1717
* .odt (2.2 KB)
18-
* .pdf (291 bytes)
18+
* .pdf (280 bytes)
1919
* .rtf (6 bytes)
2020

2121
### Image
@@ -32,13 +32,13 @@
3232
* .ico (70 bytes)
3333
* .j2c (270 bytes)
3434
* .jfif (734 bytes)
35-
* .jp2 (357 bytes)
35+
* .jp2 (354 bytes)
3636
* .jpc (270 bytes)
3737
* .jpe (734 bytes)
3838
* .jpeg (734 bytes)
3939
* .jpg (734 bytes)
4040
* .jxr (300 bytes)
41-
* .pbm (10 bytes)
41+
* .pbm (8 bytes)
4242
* .pcx (131 bytes)
4343
* .pgm (12 bytes)
4444
* .png (119 bytes)

src/mdsnippets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/SimonCropp/MarkdownSnippets/master/schema.json",
33
"TocExcludes": [ "NuGet package", "Release Notes", "Icon" ],
4-
"MaxWidth": 80,
4+
"MaxWidth": 100,
55
"Convention": "InPlaceOverwrite"
66
}

0 commit comments

Comments
 (0)