...
This commit is contained in:
114
src/text/README.md
Normal file
114
src/text/README.md
Normal 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"
|
@@ -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");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user