A minimalistic macro processor written in Rust that helps with text transformation and code generation.
Azadi is a simple macro processor that helps you automate repetitive text transformations. It supports basic macro definitions, file inclusion, and conditional processing.
Add Azadi to your project dependencies:
[dependencies]
azadi-macros = "0.1.0"
Or install the CLI tool:
cargo install azadi
Here are some basic examples to get you started:
%def(hello, World)
Hello %hello()!
Output: Hello World!
%def(greet, name, Hello, %(name)!)
%greet(Alice)
Output: Hello, Alice!
%def(template, content, %{
====
%(content)
====
%})
%template(Some text here)
Output:
====
Some text here
====
azadi-macro-cli [OPTIONS] <INPUT_FILES>...
OPTIONS:
--out-dir <DIR> Output directory [default: .]
--special <CHAR> Special character for macros [default: %]
--work-dir <DIR> Working directory for backups [default: _azadi_work]
--include <PATHS> Colon-separated list of include paths [default: .]
--pathsep <SEP> Path separator (':' on Unix, ';' on Windows)
--pydef Enable Python macro definitions
--input-dir <DIR> Base directory for input files [default: .]
# Process a file
azadi-macro-cli input.txt
# Use stdin/stdout
cat input.txt | azadi-macro-cli -
# Process multiple files
azadi-macro-cli file1.txt file2.txt
Configuration can be specified in several files:
input_dir = "src"
output_dir = "gen"
special = "%"
[tool.azadi]
work_dir = "_work"
open_delim = "<["
close_delim = "]>"
Here are some practical examples taken from the test suite:
%def(inner, x, inner(%(x)))
%def(outer, y, outer(%inner(%(y))))
%outer(test)
Output: outer(inner(test))
%def(greet, name, %{
%if(%(name), %{
Hello, %(name)!
%}, %{
Hello, stranger!
%})
%})
%greet(World)
%greet()
Output:
Hello, World!
Hello, stranger!
Here's a template for creating Rust files with a specific structure:
%def(rust_tpl, name, dir, content, %{
%def(the_file, name, dir, %{%if(%(dir),%(dir),.)/%(name).rs%})
[,rust]
----
// <[@file %the_file(%(name), %(dir))]>=
// %the_file(%(name), %(dir))
%(content)
// <[%the_file(%(name), %(dir))_content]>
// $$
// <[%the_file(%(name), %(dir))_content]>=
// $$
----
%})
Usage example:
%rust_tpl(my_module, src/modules, %{
pub fn hello() {
println!("Hello from module!");
}
%})
%def(bold, text, **%(text)**)
%def(greet, name, %{
%bold(Hello), %(name)!
Welcome to our project.
%})
%greet(Alice)
%def(set_x, val, %(val))
%def(message, %{
Value is: %(set_x(hello))
%})
%message()
%// Line comment
%/*
Block comment
%*/
%# Hash comment
%-- Dash comment
%def(example, %{
%// This is inside a macro definition
Some content
%})
%// config.txt contains: PORT=8080
%include(config.txt)
Server port: %(PORT)
Azadi provides several built-in macros for common operations. Leading spaces in macro parameters are ignored.
Defines a new macro.
%def(greet, name, Hello %(name)!)
%greet( World ) // spaces before "World" are ignored
Conditional processing. The condition is considered true if it's non-empty.
%def(debug, true)
%if(%(debug),
Debug mode is on,
Debug mode is off
)
Returns a if a and b match exactly, otherwise returns empty string.
%equal(abc, abc) // returns "abc"
%equal(abc, def) // returns ""
Evaluates a macro by name.
%def(say, Hello!)
%eval(say) // same as %say()
Includes content from another file. Detects circular includes.
%include(header.txt)
Modifies the current file at the macro's position by evaluating the macro with the given parameters, then terminates processing. Often used to insert generated content into the source file itself.
// File: example.rs
%def(struct_fields, type, %{
name: String,
count: %(type),
enabled: bool
%})
struct Example {
// Generated fields will go here:
%here(struct_fields, i32)
}
After processing, the file will contain:
struct Example {
// Generated fields will go here:
%name: String,
count: i32,
enabled: bool
}
Note the special character (%) is automatically added before the inserted content.
Makes first letter uppercase.
%capitalize(hello) // returns "Hello"
Makes first letter lowercase.
%decapitalize(Hello) // returns "hello"
- Basic macro processing
- Basic conditional processing with
%if
- File inclusion
- Multiple comment styles
- Text blocks using
%{...%}
- Standard input/output support
- Backup file generation
- UTF-8 text processing
- Clone the repository
- Build:
cargo build
- Run tests:
cargo test
.
├── Cargo.toml
└── crates
└── azadi-macros
├── src/
└── tests/
This project is licensed under the MIT License - see the LICENSE-MIT file for details.