Pymaidol Docs
Welcome to Pymaidol!
All English docs are translated by Chat-GPT. Feel free to submit a PR to improve the translation.
Pymaidol is a markup syntax for embedding Python code into text, allowing the content to be dynamically changed at runtime.
Compared to ProMaid, Pymaidol not only embeds data into corresponding positions in templates, but also allows complex processing logic to be presented in templates. It can even use functions defined in templates to process data.
Warning
Pymaidol is currently in the development stage, and the syntax and some handling logic for whitespace and line breaks are not yet finalized and may be subject to change in the future. It is strongly recommended not to use it in a production environment.1 - Getting Started
Requirements and Installation
python >= 3.10
pip install Pymaidol -i https://pypi.python.org/simple
The First Pymaidol Template
Creating a Template File
First, assume you have created a folder named pymaidol_test
. Open the folder as the working directory using an editor or IDE.
Open the command line in the pymaidol_test
folder and enter the following command:
python -m pymaidol -n FirstTemplate
FirstTemplate
is the class name of the template. The command line will output the following content, and two files, FirstTemplate.pymd
and FirstTemplate.py
, will be generated in the folder:
Success: file "FirstTemplate.pymd" created
Success: file "FirstTemplate.py" created
Writing the Template Design File
First, replace all the contents in FirstTemplate.pymd
with the following code:
from pymaidol import TemplateBase
from pymaidol.AnnotationType import FULL_ANNOTATION_TYPE, AnnotationTypeEnum
class FirstTemplate(TemplateBase):
def __init__(self,
package_name:str,
template: str | None = None,
template_file_path: str | None = None,
supported_annotation_types: list[AnnotationTypeEnum] = FULL_ANNOTATION_TYPE,
disable_annotation_types: list[AnnotationTypeEnum] = []) -> None:
super().__init__(template, template_file_path, supported_annotation_types, disable_annotation_types)
self.package_name = package_name
def main():
template = FirstTemplate("Pymaidol")
string = template.Render({"says": "Hello World"})
print(string)
if __name__ == "__main__":
main()
This code mainly modifies the following parts:
- Adds the
package_name
attribute to the FirstTemplate
class. - Adds the
main
function to instantiate the FirstTemplate
class. The package_name
parameter is passed to the constructor of the FirstTemplate
class with a value of Pymaidol
. - Calls the
Render
method and passes a dictionary {"says": "Hello World"}
to it.
Then, replace all the contents in the FirstTemplate
class with the following code:
@{import time}
Now (@(time.ctime())), Say "@(says)" using @(self.package_name)!
Run FirstTemplate.py
, and the command line will output the following content:
Now (Tue May 23 19:21:19 2023), Say "Hello World" using Pymaidol!
See Also
2 - Syntax Reference
Creating and Structure of Pymaidol Template Files
Creating Template Files Using Command Line (Recommended)
Use the following command to create a template file:
python -m pymaidol -n <class_name> [-d <directory>]
This will generate two files, <class_name>.pymd
and <class_name>.py
, in the current directory.
Composition of Pymaidol Template Files
A template file consists of a template design file .pymd
and a template backend file .py
.
Template design file .pymd
: Contains the design content of the template, such as strings and Python code/render expressions embedded with Pymaidol syntax.
Template backend file .py
: Contains the backend logic of the template, such as the definition of the template class.
Variables and methods defined in the backend file can be accessed in the design file, but elements defined in the design file cannot be accessed in the backend file. In addition, the import
statements in both files are independent.
If manually creating Pymaidol template files, the file names of the template design file .pymd
and the template backend file .py
must be the same and located in the same folder. The file name of the template backend file must be the same as the class name of the template.
Pymaidol Syntax
Pymaidol uses @
as a marker to indicate Pymaidol expressions, keywords, and code blocks. To use @
in text, please use @@
instead.
Pymaidol Expressions
Pymaidol expressions are used to embed/render data into the template. The format of a Pymaidol expression is @(<expression>)
, for example:
The rendered text is:
Pymaidol Keywords
The format of keywords is @<keyword>;
, for example:
@break; # Exit the current loop
@continue; # Skip the current iteration
Pymaidol Code Blocks
Pymaidol code blocks are used to execute Python code during template rendering. The format is @{<code_block>}
, for example:
@{answer = 42}
The answer of this universe is @(answer)
The rendered text is:
The answer of this universe is 42
Because rendering Pymaidol code blocks is done in the order from top to bottom and from left to right, you can use Pymaidol code blocks to define variables, functions, etc., and use them in subsequent expressions or code blocks.
if, elif, else Code Blocks
The usage is @if (<conditional_expression>){<template_design_statement>}
, for example:
@{answer = 42}
@if (answer > 0) {answer == @(answer), and it is positive.}
@elif (answer < 0) {answer == @(answer), and it is negative.}
@else {answer == @(answer), and it is zero.}
The rendered text is:
answer == 42, and it is positive.
while Code Blocks
The usage is @while (<conditional_expression>){<template_design_statement>}
, for example:
@{i = 0}
@while (i < 5){
i = @(i)
@{i += 1}
}
The rendered text is:
i = 0
i = 1
i = 2
i = 3
i = 4
for Code Blocks
The usage is @for (<variable> in <iterable_object>){<template_design_statement>}
, for example:
@for (i in range(5)){
i = @(i)
@if (i == 3) {@break;}
}
The rendered text is:
3.1 - AnnotationType Module
Overview
The AnnotationType
module provides an enumeration of annotations that can be used in template design files with the .pymd
extension.
Module: pymaidol
Import
from pymaidol import AnnotationType
Classes
Static Variables
Name | Type | Description |
---|
FULL_ANNOTATION_TYPE | list[AnnotationTypeEnum] | A list that contains all the enumeration values of the annotation type enumerations. |
3.1.1 - AnnotationTypeEnum Enumeration
Overview
The AnnotationTypeEnum
enumeration is the base class for all annotation type enumerations. It has no internal enumeration values and is only used for inheritance.
Module: pymaidol.AnnotationType
Inherits from: enum.Enum
Import
from pymaidol import AnnotationTypeEnum
or
from pymaidol.AnnotationType import AnnotationTypeEnum
3.1.2 - MultiLineAnnotationTypeEnum Enumeration
Overview
Contains the types of multiline annotations that can be used in template design files .pymd
.
Module: pymaidol.AnnotationType
Inherits from: pymaidol.AnnotationType.AnnotationTypeEnum
Import
from pymaidol import MultiLineAnnotationTypeEnum
or
from pymaidol.AnnotationType import MultiLineAnnotationTypeEnum
Enum Items
Name | Value | Description |
---|
Python | ’'' | Multiline comment in Python, which starts and ends with ''' . |
C | /* | Multiline comment in C, which starts with /\* and ends with */ . |
HTML | <!– | Multiline comment in HTML, which starts with <!-- and ends with --> . |
3.1.3 - SingleLineAnnotationTypeEnum Enumeration
Overview
Contains the types of single-line annotations that can be used in template design files .pymd
.
Module: pymaidol.AnnotationType
Inherits from: pymaidol.AnnotationType.AnnotationTypeEnum
Import
from pymaidol import SingleLineAnnotationTypeEnum
or
from pymaidol.AnnotationType import SingleLineAnnotationTypeEnum
Enum Items
Name | Value | Description |
---|
Python | # | Single-line comment for Python, which starts with # . |
C | // | Single-line comment for C, which starts with // . |
See Also
AnnotationTypeEnum Enumeration
3.2 - Position Class
Overview
The Position
class is used to locate positions in the original template string.
The properties of the Position
object are read-only and cannot be modified after initialization.
Note: When the Position
class is used for the end position, it includes the character at that position. For example, if start.total = 20
and end.total = 30
, the slice of the original template string should be template[20:31]
.
Module: pymaidol.Positions
Import
from pymaidol import Position
or
from pymaidol.Positions import Position
Constructor
Position(line_index, char_index, total)
Parameters
line_index
(int): Line index. Starting from 0.char_index
(int): Character index of the current line. Starting from 0.total
(int): Total character index. Starting from 0.
Properties
line_index
(int, readonly)
Line index. Starting from 0.
char_index
(int, readonly)
Character index of the current line. Starting from 0.
total
(int, readonly)
Total character index. Starting from 0.
full_description
(str, readonly)
Complete and human-readable position description.
Methods
Position.Default()
@ classmethod
Create and return a default Position
object with all properties set to 0.
Parameters
None.
Returns (Position
)
Default Position
object.
Copy()
Copy and return a new Position
object.
Parameters
None.
Returns (Position
)
New Position
object with the same properties as the original object.
3.3 - TemplateBase Class
Overview
The TemplateBase
class is the backend class for Pymaidol templates and serves as the base class for all Pymaidol template classes. It is an abstract class that cannot be instantiated and needs to be inherited for use.
Module: pymaidol.TemplateBase
Inherits from: abc.ABC
Import
from pymaidol import TemplateBase
or
from pymaidol.TemplateBase import TemplateBase
Constructor
TemplateBase(template, template_file_path, supported_annotation_types, disable_annotation_types)
(virtual)
Parameters
template
(str, optional): The template string. Default is None
.template_file_path
(str, optional): The template file path. Default is None
.supported_annotation_types
(list[AnnotationTypeEnum], optional): The list of supported annotation types. Default is all annotation types (Python, C single-line and multi-line comments, HTML comments).disable_annotation_types
(list[AnnotationTypeEnum], optional): The list of disabled annotation types, making these annotations appear in the rendered text. Default is empty. Disabled annotations take precedence over supported annotations. For example, if AnnotationTypeEnum.SingleLineAnnotationTypeEnum.Python
(Python single-line comments) is included in disable_annotation_types
, it will be disabled regardless of whether it is included in supported_annotation_types
.
When both template
and template_file_path
are None
, the TemplateBase
class and its subclasses will attempt to read the template file .pymd
with the same name in the same directory as itself. If both are not empty, template
will be used as a priority.
Attributes
rendered
(str, readonly)
The rendered string. If Render()
method has not been called since self-initialization or calling HotReload()
method, it will be None
.
template
(str, readonly)
The template string.
Methods
HotReload(template, template_file_path)
(final)
Reloads the template.
Parameters
template
(str, optional): The template string. Default is None
.template_file_path
(str, optional): The template file path. Default is None
.
When both template
and template_file_path
are None
, the TemplateBase
class and its subclasses will attempt to read the template file .pymd
with the same name in the same directory as itself. If both are not empty, template
will be used as a priority.
Returns (None
)
None.
Render(inject_kwargs)
(final)
Renders the template string with the given data.
Parameters
inject_kwargs
(dict, Optional): The externally injected variables used for rendering the template string. Default is None
. The injected variables will be treated as local variables.
Returns (str
)
The rendered string.
3.4 - TemplateRenderer Class
Overview
A class that renders template strings into strings.
Module: pymaidol.TemplateRenderer
Import
from pymaidol import TemplateRenderer
or
from pymaidol.TemplateRenderer import TemplateRenderer
Constructor
TemplateRenderer(template, supported_annotation_types)
Parameters
template
(str): The template string.supported_annotation_types
(list[AnnotationTypeEnum], optional): The list of supported annotation types. Defaults to all annotation types (Python, C single-line and multi-line comments, HTML comments).
Attributes
template
(str, readonly)
The template string.
Methods
TemplateRenderer.ReadFromFile(template_file_path, supported_annotation_types)
(classmethod)
Given a template file path, returns a TemplateRenderer
object.
Parameters
template_file_path
(str): The template file path.supported_annotation_types
(list[AnnotationTypeEnum]): The list of supported annotation types.
Returns
TemplateRenderer
: The TemplateRenderer
object.
Render(local_vars, global_vars)
(final)
Renders the template string with the given data.
Parameters
local_vars
(dict): The local variables used for rendering the template string.global_vars
(dict, optional): The global variables used for rendering the template string. Defaults to None
.
Returns
str
: The rendered string.