Getting Started¶
Installation¶
Paxter language package can be installed from PyPI via pip
command
(or any other methods of your choice):
$ pip install paxter
Programmatic Usage¶
This package is mainly intended to be utilized as a library. To get started, let’s assume that we have a document source text written using Paxter language syntax.
# Of course, input text of a document may be read from any source,
# such as from a text file loaded from the filesystem, from user input, etc.
source_text = """\
@python##"
from datetime import datetime
name = "Ashley"
year_of_birth = 1987
current_age = datetime.now().year - year_of_birth
"##\\
My name is @name and my current age is @current_age.
My shop opens Monday@,-@,Friday.
"""
Note
Learn more about Paxter language grammar and features.
Parsing¶
First and foremost, we use a parser
(implemented by the class ParseContext
)
to transform the source input into an intermediate parsed tree.
from paxter.core import ParseContext
parsed_tree = ParseContext(source_text).tree
Note: We can see the structure of the parsed tree in full by printing out its content as shown below (output reformatted for clarify).
>>> parsed_tree
FragmentList(
start_pos=0,
end_pos=236,
children=[
Command(
start_pos=1,
end_pos=148,
starter="python",
starter_enclosing=EnclosingPattern(left="", right=""),
option=None,
main_arg=Text(
start_pos=10,
end_pos=145,
inner='\n from datetime import datetime\n\n name = "Ashley"\n year_of_birth = 1987\n current_age = datetime.now().year - year_of_birth\n',
enclosing=EnclosingPattern(left='##"', right='"##'),
),
),
Text(
start_pos=148,
end_pos=161,
inner="\\\nMy name is ",
enclosing=EnclosingPattern(left="", right=""),
),
Command(
start_pos=162,
end_pos=166,
starter="name",
starter_enclosing=EnclosingPattern(left="", right=""),
option=None,
main_arg=None,
),
Text(
start_pos=166,
end_pos=189,
inner=" and my current age is ",
enclosing=EnclosingPattern(left="", right=""),
),
Command(
start_pos=190,
end_pos=201,
starter="current_age",
starter_enclosing=EnclosingPattern(left="", right=""),
option=None,
main_arg=None,
),
Text(
start_pos=201,
end_pos=223,
inner=".\nMy shop opens Monday",
enclosing=EnclosingPattern(left="", right=""),
),
SymbolCommand(start_pos=224, end_pos=225, symbol=","),
Text(
start_pos=225,
end_pos=226,
inner="-",
enclosing=EnclosingPattern(left="", right=""),
),
SymbolCommand(start_pos=227, end_pos=228, symbol=","),
Text(
start_pos=228,
end_pos=236,
inner="Friday.\n",
enclosing=EnclosingPattern(left="", right=""),
),
],
enclosing=GlobalEnclosingPattern(),
)
Notice how the source text above also contains what seems like a Python code. This has nothing to do with Paxter core grammar in any way; it simply uses the Paxter command syntax to embed Python code to which we will give a meaningful interpretation later.
Rendering¶
Next step, we use a built-in renderer to transform the intermediate parsed tree into its final output. It is important to remember that the semantics of the documents depends on which renderer we are choosing.
We will adopt the Python authoring mode whose renderer
(implemented by RenderContext
)
is already pre-defined by the Paxter library package
to transform the parsed tree into the desired final form.
One of its very useful features is that it will execute python code
under the @python
command.
from paxter.pyauthor import RenderContext, create_unsafe_env
# This dictionary data represents the initial global dict state
# for the interpretation the document tree in python authoring mode.
env = create_unsafe_env({
'_symbols_': {',': ' '},
})
result = RenderContext(source_text, env, parsed_tree).rendered
print(result) # or write to a file, etc.
The above code will output the following.
My name is Ashley and my current age is 33.
My shop opens Monday - Friday.
Note
Learn more about how to use Python authoring mode and how to write custom renderer.
Create your own function¶
We recommend Paxter library users to by themselves write a utility function to connect all of the toolchains provided Paxter package. This is the minimal example of a function to get you started.
from paxter.core import ParseContext
from paxter.pyauthor import RenderContext, create_unsafe_env
def interp(source_text: str) -> str:
parsed_tree = ParseContext(source_text).tree
result = RenderContext(source_text, create_unsafe_env(), tree).rendered
return result
Command-Line Usage¶
As a shortcut, Paxter library package also provided some utilities via command-line program. To get started, red the help message using the following command:
$ paxter --help
To play around with the parser, you may use parse
subcommand with an input.
Suppose that we have the following input file.
$ cat intro.paxter
@python##"
from datetime import datetime
_symbols_ = {
',': ' ',
}
name = "Ashley"
year_of_birth = 1987
current_age = datetime.now().year - year_of_birth
"##\
My name is @name and my current age is @current_age.
My shop opens Monday@,-@,Friday.
Then we can see the intermediate parsed tree using this command:
$ paxter parse -i intro.paxter
If we wish to also render the document written in Paxter language under the Python authoring mode with the default environment, then use the following command:
$ paxter pyauthor -i intro.paxter -o result.txt
$ cat result.txt
My name is Ashley and my current age is 33.
My shop opens Monday - Friday.
However, this command-line option does not provide a lot of flexibility. So we recommend users to dig deeper with a more programmatic usage. It may require a lot of time and effort to setup the entire toolchain, but it will definitely pay off in the long run.