Basic Markup eXpressions
Project description
BMX - Basic Markup eXpressions
A DSL for representing HTML/XML in Python using an expression-like syntax. Why? You get to use the Python syntax you already know.
Example
This example from the Jinja2 website can be represented in BMX like so:
mydoc = (
DOCTYPE.html
+html(lang='en')
+head
+title +"My Webpage" -title
-head
+body
+ul('#navigation')
+(
+li
+a(href=item.href) +item.caption -a
-li
for item in navigation)
-ul
+h1 +"My Webpage" -h1
+a_variable
# a comment
-body
-html)
Note: Just as with ordinary Python expressions, multi-line BMX expressions must be surrounded by parentheses.
Installation and Dependencies
bmx
is tested on CPython versions 3.6-3.9. It has 2 dependencies: singledispatchmethod (backported from 3.8) and MarkupSafe - to escape html in strings.
pip install bmx
Usage
An example using Flask (available in the top-level source directory):
# flask_greeter.py
from bmx.htmltags import (
html,
head,
title,
body,
p
)
from flask import Flask
app = Flask(__name__)
@app.route('/<name>')
def greeter(name: str):
return str(
# fmt: off
+html
+head
+title +"Flask Greeter" -title
-head
+body
+p +f"Hello {name}" -p
-body
-html
# fmt: on
)
Install Flask then run it as:
FLASK_APP=flask_greeter.py flask run
Go to https://127.0.0.1:5000/<your_name>
in your browser (eg. https://127.0.0.1:5000/Stuart
) and you will see the message.
Table of Conversions
Type | HTML | BMX | Comment/Mnemonic |
---|---|---|---|
Opening tag | <div> |
+div |
Mnemonic: Adding content |
Closing tag | </div> |
-div |
Mnemonic: opposite of adding content |
Self-closing tag | <input/> |
+input |
Self-closing tag are pre-defined |
Attributes | <a href="/">Home</a> |
+a(href="/") +"Home" -a |
Mnemonic: attributes are keyword arguments. |
Attributes | <button aria-label="Close">X</button> |
+button(aria_label="Close") +"X" -button |
Note: Underscores in keyword arguments are replaced with dashes |
Attributes | <input type="text"> |
+input_(type_="text") |
Note: Append an underscore to avoid conflicts with Python keywords |
Attributes: shorthand for id and class |
<div id="userinput" class="credentials" > |
+div('#userinput.credentials') |
#id .classname |
Attributes: shorthand for class |
<div class="col-sm-8 col-md-7 py-4"> |
+div .col_sm_8 .col_md_7 .py_4 |
.classname Underscores are replaced with dashes |
Composing tags and content | <h1>The Title</h1> |
+h1 +"The Title" -h1 |
Mnemonic: think string concatenation ie. "Hello " + "World!" |
How does it work?
We define a Tag
class which overrides the unary +/- and binary +/- operators to model the opening and closing tags of HTML. We provide a __call__
method to model HTML attributes as keyword arguments and a __getattr__
method to provide a shorthand for HTML classes (see above). A Tag
is instantiated for every HTML tag and is available with a from bmx.htmltags import html, head, body, span
.
MarkupSafe
bmx
uses MarkupSafe to escape HTML from strings. If you are sure that you don't want to escape the HTML in a string, you can wrap it in a Markup object and the string will be included as-is.
Autoformatters
Black
To use the Black uncompromising autoformatter, surround your BMX markup with #fmt: off
and #fmt: on
comments like this:
result = (
# fmt: off
+html
+body
+h1 +"My Page" -h1
-body
-html
# fmt: on
)
Autopep8
To use autopep8, you can use the #fmt: off
and #fmt: on
comments as above or turn off 2 fixes:
- E225 - Fix missing whitespace around operator.
- E131 - Fix hanging indent for unaligned continuation line.
whereever you put your autopep8 configuration
ignore = E225,E131
Changelog
0.0.3
Fixes for:
- Class list can only be created once #4
- Keyword arguments in snake_case should be translated to kebab-case #3
- README improvements/fixes
0.0.2
- default to using MarkupSafe for strings
- include DOCTYPE in htmltags module
- README improvements/fixes
0.0.1
- Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file bmx-0.0.3.tar.gz
.
File metadata
- Download URL: bmx-0.0.3.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.2 CPython/3.6.9 Linux/4.19.128-microsoft-standard
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 179a1a93d5a8da2ec022d0db820a382b950c356173dbb741e422487a1b1203fd |
|
MD5 | a8a26bf81654332842fc4a4f43f20519 |
|
BLAKE2b-256 | 8eaacc9cbdd2a2f59fdc046299cef3416cc33b53335ba7fcadac501978dabff8 |
File details
Details for the file bmx-0.0.3-py3-none-any.whl
.
File metadata
- Download URL: bmx-0.0.3-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.2 CPython/3.6.9 Linux/4.19.128-microsoft-standard
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 699e7c2b47b3a4f5c2be6f735663c84f37e956c94c8181d3f87193408deb2e32 |
|
MD5 | 6c0a32d18d62f763e8e63f437a64f089 |
|
BLAKE2b-256 | 1653e7ce2adf7dc265329576093673f9a9c49e124ce5a2d36bb7d79b0e24c192 |