Enhanced file expansion using Jinja2 templates
Project description
JExpand - Jinja2 Template File Expander
Enhanced file expansion using Jinja2 templates with flexible functionality for including files, conditional content, and more.
Installation
pip install jexpand
Usage
Command Line Interface
JExpand now uses a modern argparse-based CLI with explicit input/output handling:
# Print to stdout
jexpand template.md
# Write to file
jexpand template.md -o expanded.md
jexpand template.md --output expanded.md
# Non-strict mode (don't fail on missing files)
jexpand template.md --no-strict
# Specify template directory
jexpand template.md --template-dir /path/to/templates
# Show help
jexpand --help
Python Module
# Run as module
python -m jexpand template.md -o expanded.md
Python API
from jexpand import JinjaFileExpander
# Create expander
expander = JinjaFileExpander(strict_mode=True)
# Expand to file
expander.expand_file(
template_path="template.md",
output_path="output.md"
)
# Expand to string
result = expander.expand_file("template.md")
# Simple expansion with {file} syntax
result = expander.simple_expand("simple_template.md")
Template Features
JExpand supports powerful Jinja2 templates with custom functions and filters:
Custom Functions
include_file(path)- Include the contents of a filefile_exists(path)- Check if a file existsfile_size(path)- Get file size in bytesfile_extension(path)- Get file extensionbasename(path)- Get basename of filedirname(path)- Get directory name of file
Custom Filters
code_block(language)- Wrap content in markdown code blockindent(spaces)- Indent each line with specified spacescomment_out(comment_char)- Comment out each line
Example Template
# My Project Documentation
## Source Implementation
{{ include_file('src/main.py') | code_block('python') }}
## Configuration
{% if file_exists('config.yaml') %}
{{ include_file('config.yaml') | code_block('yaml') }}
{% else %}
No configuration file found.
{% endif %}
## Multiple Files
{% for file_path in ['file1.py', 'file2.py'] %}
### {{ basename(file_path) }}
{{ include_file(file_path) | indent(4) }}
{% endfor %}
## File Information
{% for file in ['app.py', 'utils.py'] %}
{% if file_exists(file) %}
- **{{ file }}**: {{ file_size(file) }} bytes
{% endif %}
{% endfor %}
Simple Syntax (Backward Compatibility)
JExpand also supports a simpler {file_path} syntax that gets converted to Jinja2:
from jexpand import JinjaFileExpander
expander = JinjaFileExpander()
# Converts {/path/to/file} to {{ include_file('/path/to/file') }}
expander.simple_expand("simple_template.md")
Advanced Usage
Programmatic Generation
You can use jexpand programmatically to generate documentation:
#!/usr/bin/env python3
from jexpand import JinjaFileExpander
from pathlib import Path
def generate_docs(source_dir, output_dir):
"""Generate documentation for all source files."""
expander = JinjaFileExpander(strict_mode=True)
for source_file in Path(source_dir).glob("*.py"):
template_content = f"""
# {source_file.name} Documentation
## Source Code
{{{{ include_file('{source_file}') | code_block('python') }}}}
## Analysis
**File:** {source_file.name}
**Size:** {{{{ file_size('{source_file}') }}}} bytes
"""
# Expand template
result = expander.expand_string(template_content)
# Write to output
output_file = Path(output_dir) / f"{source_file.stem}_docs.md"
with open(output_file, 'w') as f:
f.write(result)
# Usage
generate_docs("src/", "docs/")
Recent Improvements (v1.0.2)
Enhanced CLI Interface
- Modern argparse-based CLI replacing the previous fire-based interface
- Explicit input/output handling with
-o/--outputflags - Better error messages and help text
- Proper exit codes for scripting
Bug Fixes
- Fixed double printing issue that caused duplicated output
- Improved absolute path handling for template files
- Fixed Template constructor compatibility issues
- Removed subprocess overhead in programmatic usage
Performance Improvements
- Direct import support - no subprocess calls needed
- Cleaner output handling - no extra newlines or duplication
- Reduced dependencies - removed fire dependency
Backward Compatibility
- Simple expansion syntax still supported via
simple_expand() - Legacy
expand_file()function remains available - All existing templates continue to work
Development
Local Installation
# Install in development mode
pip install -e .
# Test the command
jexpand --help
Package Structure
jexpand/
├── jexpand/
│ ├── __init__.py # Package exports and main entry point
│ ├── __main__.py # Module entry point for python -m jexpand
│ └── main.py # Core functionality and CLI
├── setup.py # Package configuration
├── README.md # This file
└── .gitignore # Git ignore rules
Examples
See the examples/ directory (if present) or check the GitHub repository for real-world usage examples.
License
MIT License
Links
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jexpand-1.0.2.tar.gz.
File metadata
- Download URL: jexpand-1.0.2.tar.gz
- Upload date:
- Size: 6.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b848bb34d2aaae2719d78f94492b8c589dff922ac240c2eadfc534dfd27f92e8
|
|
| MD5 |
b3da67637e83ef7ef5260076a49764bc
|
|
| BLAKE2b-256 |
0efae571572ff8236dc7d14a4e5127c85593ac5e4c04c3d0541d69037cebe542
|
File details
Details for the file jexpand-1.0.2-py3-none-any.whl.
File metadata
- Download URL: jexpand-1.0.2-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b993eb8c78b079061e24995dca2b4cafd6391d6a95b5ce34288c98c7dc2825ca
|
|
| MD5 |
590a70ee7a432f0d38cd318430ed8222
|
|
| BLAKE2b-256 |
e968f3179dc025d5a463f5eecc2aa0fa465d6d5a6e280bfd3cd4ddeb51174fb2
|