This commit is contained in:
2025-04-02 08:24:03 +02:00
parent 3606e27e30
commit b2896b206c
11 changed files with 739 additions and 15 deletions

114
src/text/README.md Normal file
View File

@@ -0,0 +1,114 @@
# Text Processing Utilities
A collection of Rust utilities for common text processing operations.
## Overview
This module provides functions for text manipulation tasks such as:
- Removing indentation from multiline strings
- Adding prefixes to multiline strings
- Normalizing filenames and paths
## Functions
### Text Indentation
#### `dedent(text: &str) -> String`
Removes common leading whitespace from multiline strings.
```rust
let indented = " line 1\n line 2\n line 3";
let dedented = dedent(indented);
assert_eq!(dedented, "line 1\nline 2\n line 3");
```
**Features:**
- Analyzes all non-empty lines to determine minimum indentation
- Preserves empty lines but removes all leading whitespace from them
- Treats tabs as 4 spaces for indentation purposes
#### `prefix(text: &str, prefix: &str) -> String`
Adds a specified prefix to each line of a multiline string.
```rust
let text = "line 1\nline 2\nline 3";
let prefixed = prefix(text, " ");
assert_eq!(prefixed, " line 1\n line 2\n line 3");
```
### Filename and Path Normalization
#### `name_fix(text: &str) -> String`
Normalizes filenames by:
- Converting to lowercase
- Replacing whitespace and special characters with underscores
- Removing non-ASCII characters
- Collapsing consecutive special characters into a single underscore
```rust
assert_eq!(name_fix("Hello World"), "hello_world");
assert_eq!(name_fix("File-Name.txt"), "file_name.txt");
assert_eq!(name_fix("Résumé"), "rsum");
```
#### `path_fix(text: &str) -> String`
Applies `name_fix()` to the filename portion of a path while preserving the directory structure.
```rust
assert_eq!(path_fix("/path/to/File Name.txt"), "/path/to/file_name.txt");
assert_eq!(path_fix("./relative/path/to/DOCUMENT-123.pdf"), "./relative/path/to/document_123.pdf");
```
**Features:**
- Preserves paths ending with `/` (directories)
- Only normalizes the filename portion, leaving the path structure intact
- Handles both absolute and relative paths
## Usage
Import the functions from the module:
```rust
use your_crate::text::{dedent, prefix, name_fix, path_fix};
```
## Examples
### Cleaning up indented text from a template
```rust
let template = "
<div>
<h1>Title</h1>
<p>
Some paragraph text
with multiple lines
</p>
</div>
";
let clean = dedent(template);
// Result:
// <div>
// <h1>Title</h1>
// <p>
// Some paragraph text
// with multiple lines
// </p>
// </div>
```
### Normalizing user-provided filenames
```rust
let user_filename = "My Document (2023).pdf";
let safe_filename = name_fix(user_filename);
// Result: "my_document_2023_.pdf"
let user_path = "/uploads/User Files/Report #123.xlsx";
let safe_path = path_fix(user_path);
// Result: "/uploads/User Files/report_123.xlsx"

View File

@@ -81,3 +81,52 @@ pub fn dedent(text: &str) -> String {
.collect::<Vec<String>>()
.join("\n")
}
/**
* Prefix a multiline string with a specified prefix.
*
* This function adds the specified prefix to the beginning of each line in the input text.
*
* # Arguments
*
* * `text` - The multiline string to prefix
* * `prefix` - The prefix to add to each line
*
* # Returns
*
* * `String` - The prefixed string
*
* # Examples
*
* ```
* let text = "line 1\nline 2\nline 3";
* let prefixed = prefix(text, " ");
* assert_eq!(prefixed, " line 1\n line 2\n line 3");
* ```
*/
pub fn prefix(text: &str, prefix: &str) -> String {
text.lines()
.map(|line| format!("{}{}", prefix, line))
.collect::<Vec<String>>()
.join("\n")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dedent() {
let indented = " line 1\n line 2\n line 3";
let dedented = dedent(indented);
assert_eq!(dedented, "line 1\nline 2\n line 3");
}
#[test]
fn test_prefix() {
let text = "line 1\nline 2\nline 3";
let prefixed = prefix(text, " ");
assert_eq!(prefixed, " line 1\n line 2\n line 3");
}
}