gtext is a universal text processor with a pluggable extension system. Transform any text file through customizable plugins:
- π Include files (static, dynamic, glob patterns)
- π€ AI processing (summarization, translation)
- π» Code generation (headers, boilerplate)
- β Validation (links, spelling)
- π And much more...
Created by the Genro Team. Universal and standalone.
pip install gtextgtext uses the .gtext extension to identify source files:
# Double extension (auto-detect output format)
document.md.gtext β document.md
script.py.gtext β script.py
config.yaml.gtext β config.yamlSource file (report.md.gtext):
# Monthly Report
## Company Stats
```include
cli: python scripts/get_stats.py --format markdown
```
## Team Structure
```include
docs/team-structure.md
```
## All Project Docs
```include
glob: projects/**/README.md
```Generate expanded document:
# Auto-detect output (strip .gtext extension)
gtext render report.md.gtext
# Or specify output file/directory
gtext render report.md.gtext report.md
gtext render report.md.gtext output/
# Process multiple files or patterns
gtext render "docs/**/*.gtext" output/Re-render after changes (using saved metadata):
# Modify report.md.gtext, then refresh
gtext refresh report.md.gtext
# Or refresh all .gtext files with saved outputs
gtext refreshResult (report.md):
# Monthly Report
## Company Stats
| Metric | Value |
|--------|-------|
| Revenue | $1.2M |
| Users | 10,453 |
## Team Structure
[content from docs/team-structure.md]
## All Project Docs
[all README.md files from projects/**/]π New in v0.2.0: The
rendercommand now intelligently handles single files, multiple files, and patterns. The oldcastandcast-allcommands are deprecated (but still work) and will be removed in v0.3.0.
The best way to learn gtext is through our hands-on Jupyter notebooks.
Click the badge above to launch an interactive Jupyter environment in your browser. Ready in ~2 minutes!
# 1. Install Jupyter
pip install jupyter notebook
# 2. Navigate to notebooks directory
cd notebooks
# 3. Launch Jupyter
jupyter notebook
# 4. Open 01_rag_prompt_engineering.ipynb and start learning!| Notebook | Topic | Duration | Level |
|---|---|---|---|
| 01 - RAG & Prompt Engineering | AI/LLM integration, composable prompts | 30 min | Intermediate |
More tutorials coming soon! See notebooks/README.md for the complete learning guide.
```include
path/to/file.md
### 2. Include Command Output
```markdown
```include
cli: genro project list --format markdown
### 3. Include Multiple Files with Glob
```markdown
```include
glob: docs/**/*.md
### 4. Mix All Types
```markdown
```include
header.md
cli: python get_stats.py
glob: sections/*.md
footer.md
---
## π Security
gtext implements a **secure-by-default** policy for all includes and command executions. Everything is **denied unless explicitly allowed** through configurable rules.
### Quick Security Setup
```bash
# Allow safe read-only commands (global)
gtext config :cli add_rule "date" allow --global
gtext config :cli add_rule "git status" allow --global
gtext config :cli add_rule "ls*" allow --global
# Allow markdown file includes
gtext config :static add_rule "*.md" allow --global
# Block dangerous commands (explicitly deny)
gtext config :cli add_rule "rm *" deny --global
# View your security configuration
gtext config show
- π‘οΈ Secure by Default: Nothing runs without explicit permission
- π Ordered Rules: First-match wins pattern (like firewall rules)
- π― Protocol-Specific: Independent rules for
cli:,static:,glob:protocols - π Global & Project: System-wide rules + project-specific overrides
β οΈ Dangerous Characters: Metacharacters (;,&,|,$) always blocked
Rules are checked in order and stop at the first match:
Configuration:
0: git push* β deny # Block pushes
1: git * β allow # Allow other git commands
Command: git push β DENIED by rule 0 (stops here)
Command: git status β ALLOWED by rule 1
Critical: Order matters! Put specific rules before general ones.
New to gtext security? Start here: QUICKSTART-SECURITY.md (5-minute guide)
Full security documentation: SECURITY.md
Topics covered:
- Complete CLI command reference
- Rule management (add, remove, reorder)
- Pattern matching with wildcards
- Global vs project configuration
- Best practices and examples
- Troubleshooting guide
- Living docs that update from real data
- Multi-file documentation aggregation
- Auto-generated API docs from code
- License headers across codebase
- Boilerplate injection
- Shared imports and configs
- Dynamic reports with live database queries
- System monitoring snapshots
- Business dashboards in Markdown
- Blog post templates with includes
- Multi-language content
- Reusable content blocks
# Render single file (auto-detect output)
gtext render document.md.gtext
# Explicit output path
gtext render document.md.gtext output.md
# Render to output directory
gtext render document.md.gtext output/
# Render multiple files or patterns
gtext render "docs/**/*.gtext" output/
# Refresh using saved metadata
gtext refresh document.md.gtext
# Refresh all files with metadata
gtext refresh
# Dry run (preview without writing)
gtext render document.md.gtext --dry-run
# Live preview server (auto-refresh on file changes)
gtext serve document.md.gtext
gtext serve document.md.gtext --port 8000Note: The serve command requires installing the optional dependency:
pip install 'gtext[serve]'# View security configuration
gtext config show # Merged (global + project)
gtext config show --json # JSON format
gtext config :cli list_rules --global # List global rules
# Add security rules
gtext config :cli add_rule "date" allow --global
gtext config :cli add_rule "git *" allow --name "allow_git" --global
gtext config :static add_rule "*.md" allow
# Remove rules (by index or name)
gtext config :cli remove_rule 0 --global
gtext config :cli remove_rule "allow_git" --global
# Reorder rules (critical for first-match evaluation!)
gtext config :cli rule 2 up --global # Move rule up
gtext config :cli rule 0 down --global # Move rule down
gtext config :cli rule 3 top --global # Move to top
gtext config :cli rule 0 bottom --global # Move to bottom
# Clear all rules for a protocol
gtext config :cli clear_rules --globalSee SECURITY.md for complete documentation.
gtext is built on a pluggable architecture. Extensions are easy to create:
from gtext.extensions import BaseExtension
class MyExtension(BaseExtension):
name = "my-plugin"
def process(self, content: str, context: dict) -> str:
# Your transformation logic
return transformed_contentBuilt-in extensions:
include- Include static filesinclude-cli- Include command outputinclude-glob- Include files matching patterns
Future extensions:
ai-summarize- AI-powered summarizationai-translate- Multi-language translationvalidate-links- Check for broken linksgenerate-toc- Auto table of contents- And more...
Full documentation available at: gtext.readthedocs.io
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
If gtext helps your project, consider showing support:
Add a badge:
[](https://github.com/genropy/gtext)Or mention in your docs:
*Documentation generated with [gtext](https://github.com/genropy/gtext)*See docs/attribution.md for more options.
β Star us on GitHub to show support!
MIT License - see LICENSE for details.
No attribution required - but appreciated! π
gtext is created by Giovanni Porcari with contributions from the Genro Team.
Like a weaverbird πͺΆ that masterfully weaves materials together, gtext weaves different content sources into unified documents.
gtext is:
- β Standalone - No dependencies on other frameworks
- β Universal - Works with any text format
- β Open - MIT licensed and community-driven
- GitHub: github.com/genropy/gtext
- PyPI: pypi.org/project/gtext
- Documentation: gtext.readthedocs.io
- Issues: github.com/genropy/gtext/issues
- Genro Project: github.com/genropy/genro-next-generation
Made with β¨ by the Genro Team
