...
This commit is contained in:
parent
88e4a2a4b1
commit
e9a73327e3
237
src/docs/docs/sal/text.md
Normal file
237
src/docs/docs/sal/text.md
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
# Text Manipulation Tools
|
||||||
|
|
||||||
|
The SAL text module provides powerful text manipulation capabilities that can be used from Rhai scripts. These include text replacement (with regex support), template rendering, string normalization, and text formatting utilities.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Text Replacement](#text-replacement)
|
||||||
|
- [Template Rendering](#template-rendering)
|
||||||
|
- [String Normalization](#string-normalization)
|
||||||
|
- [Text Formatting](#text-formatting)
|
||||||
|
|
||||||
|
## Text Replacement
|
||||||
|
|
||||||
|
The text replacement tools allow you to perform simple or complex text replacements, with support for regular expressions, case-insensitive matching, and file operations.
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a new text replacer
|
||||||
|
let replacer = text_replacer_new()
|
||||||
|
.pattern("foo") // Set the pattern to search for
|
||||||
|
.replacement("bar") // Set the replacement text
|
||||||
|
.build(); // Build the replacer
|
||||||
|
|
||||||
|
// Apply the replacer to a string
|
||||||
|
let result = replacer.replace("foo bar foo");
|
||||||
|
// Result: "bar bar bar"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
|
||||||
|
#### Regular Expressions
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a replacer with regex support
|
||||||
|
let replacer = text_replacer_new()
|
||||||
|
.pattern("\\bfoo\\b") // Use regex pattern (word boundary)
|
||||||
|
.replacement("bar")
|
||||||
|
.regex(true) // Enable regex mode
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Apply the replacer to a string
|
||||||
|
let result = replacer.replace("foo foobar");
|
||||||
|
// Result: "bar foobar" (only replaces whole "foo" words)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Case-Insensitive Matching
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a replacer with case-insensitive matching
|
||||||
|
let replacer = text_replacer_new()
|
||||||
|
.pattern("foo")
|
||||||
|
.replacement("bar")
|
||||||
|
.regex(true)
|
||||||
|
.case_insensitive(true) // Enable case-insensitive matching
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Apply the replacer to a string
|
||||||
|
let result = replacer.replace("FOO foo Foo");
|
||||||
|
// Result: "bar bar bar"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Multiple Replacements
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Chain multiple replacements
|
||||||
|
let replacer = text_replacer_new()
|
||||||
|
.pattern("foo")
|
||||||
|
.replacement("bar")
|
||||||
|
.and() // Add another replacement operation
|
||||||
|
.pattern("baz")
|
||||||
|
.replacement("qux")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Apply the replacer to a string
|
||||||
|
let result = replacer.replace("foo baz");
|
||||||
|
// Result: "bar qux"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### File Operations
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a replacer
|
||||||
|
let replacer = text_replacer_new()
|
||||||
|
.pattern("foo")
|
||||||
|
.replacement("bar")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Replace in a file and get the result as a string
|
||||||
|
let result = replacer.replace_file("input.txt");
|
||||||
|
|
||||||
|
// Replace in a file and write back to the same file
|
||||||
|
replacer.replace_file_in_place("input.txt");
|
||||||
|
|
||||||
|
// Replace in a file and write to a new file
|
||||||
|
replacer.replace_file_to("input.txt", "output.txt");
|
||||||
|
```
|
||||||
|
|
||||||
|
## Template Rendering
|
||||||
|
|
||||||
|
The template rendering tools allow you to create and render templates with variables, using the powerful Tera template engine.
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a template builder with a template file
|
||||||
|
let template = template_builder_open("template.txt")
|
||||||
|
.add_var("name", "John") // Add a string variable
|
||||||
|
.add_var("age", 30) // Add a numeric variable
|
||||||
|
.add_var("items", ["a", "b", "c"]); // Add an array variable
|
||||||
|
|
||||||
|
// Render the template
|
||||||
|
let result = template.render();
|
||||||
|
|
||||||
|
// Render to a file
|
||||||
|
template.render_to_file("output.txt");
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template Variables
|
||||||
|
|
||||||
|
You can add variables of various types:
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let template = template_builder_open("template.txt")
|
||||||
|
.add_var("name", "John") // String
|
||||||
|
.add_var("age", 30) // Integer
|
||||||
|
.add_var("height", 1.85) // Float
|
||||||
|
.add_var("is_active", true) // Boolean
|
||||||
|
.add_var("items", ["a", "b", "c"]); // Array
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Map for Variables
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
// Create a map of variables
|
||||||
|
let vars = #{
|
||||||
|
name: "Alice",
|
||||||
|
place: "Wonderland"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add all variables from the map
|
||||||
|
let template = template_builder_open("template.txt")
|
||||||
|
.add_vars(vars);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template Syntax
|
||||||
|
|
||||||
|
The template engine uses Tera, which supports:
|
||||||
|
|
||||||
|
- Variable interpolation: `{{ variable }}`
|
||||||
|
- Conditionals: `{% if condition %}...{% endif %}`
|
||||||
|
- Loops: `{% for item in items %}...{% endfor %}`
|
||||||
|
- Filters: `{{ variable | filter }}`
|
||||||
|
|
||||||
|
Example template:
|
||||||
|
|
||||||
|
```
|
||||||
|
Hello, {{ name }}!
|
||||||
|
|
||||||
|
{% if show_greeting %}
|
||||||
|
Welcome to {{ place }}.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Your items:
|
||||||
|
{% for item in items %}
|
||||||
|
- {{ item }}{% if not loop.last %}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
```
|
||||||
|
|
||||||
|
## String Normalization
|
||||||
|
|
||||||
|
The string normalization tools help convert strings to consistent formats for use as file names or paths.
|
||||||
|
|
||||||
|
### name_fix
|
||||||
|
|
||||||
|
Converts a string to a safe, normalized name by:
|
||||||
|
- Converting to lowercase
|
||||||
|
- Replacing spaces and special characters with underscores
|
||||||
|
- Removing non-alphanumeric characters
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let fixed_name = name_fix("Hello World!");
|
||||||
|
// Result: "hello_world"
|
||||||
|
|
||||||
|
let fixed_name = name_fix("File-Name.txt");
|
||||||
|
// Result: "file_name.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
### path_fix
|
||||||
|
|
||||||
|
Similar to name_fix, but preserves path separators:
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let fixed_path = path_fix("/path/to/Hello World!");
|
||||||
|
// Result: "/path/to/hello_world"
|
||||||
|
|
||||||
|
let fixed_path = path_fix("./relative/path/to/DOCUMENT-123.pdf");
|
||||||
|
// Result: "./relative/path/to/document_123.pdf"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Text Formatting
|
||||||
|
|
||||||
|
Tools to help with text formatting and indentation.
|
||||||
|
|
||||||
|
### dedent
|
||||||
|
|
||||||
|
Removes common leading whitespace from multi-line strings:
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let indented_text = " line 1
|
||||||
|
line 2
|
||||||
|
line 3";
|
||||||
|
|
||||||
|
let dedented = dedent(indented_text);
|
||||||
|
// Result: "line 1
|
||||||
|
// line 2
|
||||||
|
// line 3"
|
||||||
|
```
|
||||||
|
|
||||||
|
### prefix
|
||||||
|
|
||||||
|
Adds a prefix to every line in a multi-line string:
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let text = "line 1
|
||||||
|
line 2
|
||||||
|
line 3";
|
||||||
|
|
||||||
|
let prefixed = prefix(text, " ");
|
||||||
|
// Result: " line 1
|
||||||
|
// line 2
|
||||||
|
// line 3"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
See the [text_tools.rhai](https://github.com/ourworld-tf/herocode/blob/main/sal/src/rhaiexamples/text_tools.rhai) example script for more detailed examples of using these text manipulation tools.
|
@ -56,8 +56,8 @@ fn register_bah_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_get("container_id", get_builder_container_id);
|
engine.register_get("container_id", get_builder_container_id);
|
||||||
engine.register_get("name", get_builder_name);
|
engine.register_get("name", get_builder_name);
|
||||||
engine.register_get("image", get_builder_image);
|
engine.register_get("image", get_builder_image);
|
||||||
engine.register_get("debug", get_builder_debug);
|
engine.register_get("debug_mode", get_builder_debug);
|
||||||
engine.register_set("debug", set_builder_debug);
|
engine.register_set("debug_mode", set_builder_debug);
|
||||||
|
|
||||||
// Register Image type and methods (same as before)
|
// Register Image type and methods (same as before)
|
||||||
engine.register_type_with_name::<Image>("BuildahImage");
|
engine.register_type_with_name::<Image>("BuildahImage");
|
||||||
|
@ -14,6 +14,9 @@ println(`Creating container '${container_name}' from base image '${base_image}'.
|
|||||||
// Create a new buildah container using the builder pattern
|
// Create a new buildah container using the builder pattern
|
||||||
let builder = bah_new(container_name, base_image);
|
let builder = bah_new(container_name, base_image);
|
||||||
|
|
||||||
|
println("Enabling debug mode...");
|
||||||
|
builder.debug_mode = true;
|
||||||
|
|
||||||
// Update package lists and install golang and nginx
|
// Update package lists and install golang and nginx
|
||||||
println("Installing packages (this may take a while)...");
|
println("Installing packages (this may take a while)...");
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ let builder = bah_new(container_name, base_image);
|
|||||||
|
|
||||||
// Enable debug mode
|
// Enable debug mode
|
||||||
println("Enabling debug mode...");
|
println("Enabling debug mode...");
|
||||||
builder.debug = true;
|
builder.debug_mode = true;
|
||||||
|
|
||||||
// Run a simple command to see debug output
|
// Run a simple command to see debug output
|
||||||
println("Running a command with debug enabled...");
|
println("Running a command with debug enabled...");
|
||||||
@ -22,7 +22,7 @@ let result = builder.run("echo 'Hello from debug mode'");
|
|||||||
|
|
||||||
// Disable debug mode
|
// Disable debug mode
|
||||||
println("Disabling debug mode...");
|
println("Disabling debug mode...");
|
||||||
builder.debug = false;
|
builder.debug_mode = false;
|
||||||
|
|
||||||
// Run another command without debug
|
// Run another command without debug
|
||||||
println("Running a command with debug disabled...");
|
println("Running a command with debug disabled...");
|
||||||
@ -30,7 +30,7 @@ let result2 = builder.run("echo 'Hello without debug'");
|
|||||||
|
|
||||||
// Enable debug mode again
|
// Enable debug mode again
|
||||||
println("Enabling debug mode again...");
|
println("Enabling debug mode again...");
|
||||||
builder.debug = true;
|
builder.debug_mode = true;
|
||||||
|
|
||||||
// Remove the container with debug enabled
|
// Remove the container with debug enabled
|
||||||
println("Removing the container with debug enabled...");
|
println("Removing the container with debug enabled...");
|
||||||
|
@ -34,7 +34,8 @@ impl ContentOperations {
|
|||||||
|
|
||||||
// Copy the temporary file to the container
|
// Copy the temporary file to the container
|
||||||
let temp_path = temp_file.path().to_string_lossy().to_string();
|
let temp_path = temp_file.path().to_string_lossy().to_string();
|
||||||
execute_buildah_command(&["copy", container_id, &temp_path, dest_path])
|
// Use add instead of copy for better handling of paths
|
||||||
|
execute_buildah_command(&["add", container_id, &temp_path, dest_path])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read content from a file in the container
|
/// Read content from a file in the container
|
||||||
@ -55,7 +56,18 @@ impl ContentOperations {
|
|||||||
let temp_path = temp_file.path().to_string_lossy().to_string();
|
let temp_path = temp_file.path().to_string_lossy().to_string();
|
||||||
|
|
||||||
// Copy the file from the container to the temporary file
|
// Copy the file from the container to the temporary file
|
||||||
execute_buildah_command(&["copy", container_id, source_path, &temp_path])?;
|
// Use mount to access the container's filesystem
|
||||||
|
let mount_result = execute_buildah_command(&["mount", container_id])?;
|
||||||
|
let mount_point = mount_result.stdout.trim();
|
||||||
|
|
||||||
|
// Construct the full path to the file in the container
|
||||||
|
let full_source_path = format!("{}{}", mount_point, source_path);
|
||||||
|
|
||||||
|
// Copy the file from the mounted container to the temporary file
|
||||||
|
execute_buildah_command(&["copy", container_id, &full_source_path, &temp_path])?;
|
||||||
|
|
||||||
|
// Unmount the container
|
||||||
|
execute_buildah_command(&["umount", container_id])?;
|
||||||
|
|
||||||
// Read the content from the temporary file
|
// Read the content from the temporary file
|
||||||
let mut file = File::open(temp_file.path())
|
let mut file = File::open(temp_file.path())
|
||||||
|
Loading…
Reference in New Issue
Block a user