This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

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.

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

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:

@("Hello World!")

The rendered text is:

Hello World!

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:

i = 0
i = 1
i = 2
i = 3

3 - API Directory

Modules

NameDescription
AnnotationTypeProvides an enumeration of annotations that can be used in template design files with the .pymd extension.

Classes

NameDescription
PositionUsed to locate positions in the original template string.
TemplateBaseBackend class for Pymaidol templates, serves as the base class for all Pymaidol template classes.
TemplateRendererClass that renders template strings into strings.

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

NameDescription
AnnotationTypeEnum EnumerationThe AnnotationTypeEnum enumeration is the base class for all annotation type enumerations. It does not contain any enumeration values and is only used for inheritance.
SingleLineAnnotationTypeEnum EnumerationContains the types of single-line annotations that can be used in template design files with the .pymd extension.
MultiLineAnnotationTypeEnum EnumerationContains the types of multi-line annotations that can be used in template design files with the .pymd extension.

Static Variables

NameTypeDescription
FULL_ANNOTATION_TYPElist[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

NameValueDescription
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

NameValueDescription
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.