Say adeu to repetitive boilerplate and manual document assembly.
Adeu is a powerful, lightweight templating engine that lets you build complex documents and AI prompts from reusable components. It's designed to bring the principles of modularity, reusability, and composition to your Markdown and prompt authoring workflow.
Stop repeating yourself in complex prompts or documents. If you find yourself copying and pasting the same set of instructions or boilerplate text, Adeu is for you. It allows you to create a library of reusable components (snippets of Markdown) and compose them into complex, data-driven templates.
- Component-Based Architecture: Import Markdown (
.md) or other Adeu (.adeu) files as reusable components. - Parameter Passing (Props): Pass data from a parent template to a child component via
[prop="value"]syntax. - List Rendering: Dynamically render content from data sources (
.csv) using the@@ForEach@@directive. - Conditional Logic: Show or hide blocks of text using the
@@If[condition]@@directive. - Powerful Expressions: Use Jinja2-style expressions (
{{ variable | filter }}) for advanced templating. - Data Injection: Define data in a template's YAML Frontmatter or pass it in from the command line.
- Standalone & CLI-driven: A single, focused Python script that does one thing well.
- Clone this repository.
- Install the required Python dependencies:
pip install -r requirements.txt
Here is a sample requirements.txt:
PyYAML>=6.0
Jinja2>=3.0
The tool is run from the command line. It takes a root template file as input and prints the final, rendered Markdown to standard output.
python adeu_render.py <input_file> [options]Arguments:
input_file: (Required) The path to the root.adeutemplate file.--context '{"key": "value"}': (Optional) A JSON string to pass in as top-priority data.--verbose: (Optional) Enable detailed logging of the rendering process for debugging.
This is the core directive for loading any external resource. It makes a resource available for use within the template.
Name: The alias for the component (e.g.,Disclaimer).from: A relative path to the resource file.
Example:
@@Import[Disclaimer] from="_components/disclaimer.md"
@@Import[examples] from="_data/triage_examples.csv"
Once imported, you invoke a component using its name surrounded by @@.
Static Invocation (.md file):
Simply inserts the raw content of the file.
@@Disclaimer@@
Dynamic Invocation (.adeu file with props):
You can pass parameters (props) to dynamic components to change their output.
@@Import[Panel] from="_components/panel.adeu"
@@Panel[title="My Custom Title"]@@
The @@ForEach@@ directive iterates over a list from your data context (e.g., loaded from a .csv).
item in list: A standardforloop expression.
Example:
@@Import[users] from="user_data.csv"
@@ForEach[user in users]
- User: {{ user.name }} ({{ user.email }})
@@
The @@If@@ directive renders a block of content only if the condition is true.
Example:
@@If[user.is_admin]
**Warning:** This is an administrative command.
@@
Data can be defined at the top of a template file using a YAML block (---). Component files can also have frontmatter to define default values for their props. Variables are rendered using Jinja2 syntax ({{ variable.name }}), which allows for filters like {{ my_list | join(', ') }}.
This showcases all features working together.
.
├── mvp_fixtures/
│ ├── _components/
│ │ ├── disclaimer.md
│ │ └── persona_analyst.adeu
│ ├── _data/
│ │ └── triage_examples.csv
│ └── triage_prompt.adeu
└── adeu_render.py
---
valid_categories: [Bug Report, Feature Request, Performance Issue]
---
@@Import[Persona] from="_components/persona_analyst.adeu"
@@Import[Disclaimer] from="_components/disclaimer.md"
@@Import[examples] from="_data/triage_examples.csv"
@@Persona@@
---
# Instructions
Categorize feedback into: `{{ valid_categories | join(', ') }}`.
---
# Examples
@@ForEach[example in examples]
### Example
**INPUT:** {{ example.feedback_text }}
**EXPECTED CATEGORY:** {{ example.category }}
@@
---
# CONTEXT: New Feedback to Analyze
@@If[new_feedback]
{{ new_feedback }}
@@
@@If[not new_feedback]
No new feedback was provided for analysis.
@@
---
@@Disclaimer@@
python adeu_render.py mvp_fixtures/triage_prompt.adeu --context '{"new_feedback": "The mobile app keeps crashing."}'# Role and Goal
You are a senior product analyst...
---
# Instructions
Categorize feedback into: `Bug Report, Feature Request, Performance Issue`.
---
# Examples
### Example
**INPUT:** The app is so slow when I try to open my project list.
**EXPECTED CATEGORY:** Performance Issue
### Example
**INPUT:** I wish I could export my reports to PDF.
**EXPECTED CATEGORY:** Feature Request
### Example
**INPUT:** The login button doesn't work on Firefox.
**EXPECTED CATEGORY:** Bug Report
---
# CONTEXT: New Feedback to Analyze
The mobile app keeps crashing.
---
*This analysis is auto-generated and should be reviewed by a human.*