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
# Copy to clipboard
jexpand template.md -c
jexpand template.md --clipboard
# 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
# CLI mode: Include entire directory contents
jexpand /path/to/directory --mode cli -o output.md
CLI Mode for Directory Processing
JExpand includes a special CLI mode that allows you to quickly include all files from a directory without writing a template:
# Include all files from a directory
jexpand /path/to/docs --mode cli -o documentation.md
# This is equivalent to creating a template with:
# {{ include_folder('/path/to/docs') }}
The CLI mode automatically:
- Creates a temporary template with
{{ include_folder('directory_path') }} - Processes all files in the specified directory
- Outputs them in XML format with file paths and contents
- Cleans up the temporary template file
This is particularly useful for:
- Quick documentation generation from source directories
- Exporting entire project structures
- Creating backups of directory contents in readable format
Clipboard Support
JExpand can copy the expanded template directly to your system clipboard:
# Copy expanded template to clipboard
jexpand template.md --clipboard
jexpand template.md -c
# Also works with CLI mode
jexpand /path/to/docs --mode cli --clipboard
This is useful for:
- Quickly sharing expanded content
- Pasting into documents or editors
- Working with templates without creating intermediate files
Python Module
# Run as module
python -m jexpand template.md -o expanded.md
# Copy to clipboard via module
python -m jexpand template.md --clipboard
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")
# Copy to clipboard
expander.expand_file(
template_path="template.md",
copy_to_clipboard=True
)
# 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 lineline_numbers(format='short')- Add line numbers to contentformat='short': outputs as "1 | content"format='full': outputs as "line 1 | content"
Example Template
# My Project Documentation
## Source Implementation
{{ include_file('src/main.py') | code_block('python') }}
## Source with Line Numbers
{{ include_file('src/main.py') | line_numbers | 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.11.tar.gz.
File metadata
- Download URL: jexpand-1.0.11.tar.gz
- Upload date:
- Size: 22.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90517420efee068d5447f160b23ff44a6b25d3e8fc827d03add085422ab734a3
|
|
| MD5 |
692c15d85643825379448c95c1d8beb8
|
|
| BLAKE2b-256 |
82f54db2a4d6393e8f3f9986860af2d32cda18f39651a5cdcfbffc2413b71177
|
File details
Details for the file jexpand-1.0.11-py3-none-any.whl.
File metadata
- Download URL: jexpand-1.0.11-py3-none-any.whl
- Upload date:
- Size: 23.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cac97a6740acd0c722322bd10b2a1b7fda7f1b49d87249f4fa50bf8b7f9e4ae
|
|
| MD5 |
3c6cd832dea12fd30e0df30046b39daf
|
|
| BLAKE2b-256 |
7907994e28e93619d03d054bc91a4a8319b0d08bb2763a0f5d43b422a1b89a3e
|