diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-05 09:25:25 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-05 09:25:25 +0000 |
commit | c34682a9dab600dbc6ee7334102111752c0c1ff1 (patch) | |
tree | e67d65220ed40fc3fa5826ec6346047a1357e25f | |
parent | d0c68e1159b7d82d65d7d5a1d751c2ff1ee3486b (diff) |
automatic import of python-airiumopeneuler20.03
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-airium.spec | 1656 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 1658 insertions, 0 deletions
@@ -0,0 +1 @@ +/airium-0.2.5.tar.gz diff --git a/python-airium.spec b/python-airium.spec new file mode 100644 index 0000000..3434ee0 --- /dev/null +++ b/python-airium.spec @@ -0,0 +1,1656 @@ +%global _empty_manifest_terminate_build 0 +Name: python-airium +Version: 0.2.5 +Release: 1 +Summary: Easy and quick html builder with natural syntax correspondence (python->html). No templates needed. Serves pure pythonic library with no dependencies. +License: MIT license +URL: https://gitlab.com/kamichal/airium +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/82/68/302bb6ec2597060c0e7bc8c6ffdf0678206ae26eb539427943b2378326c2/airium-0.2.5.tar.gz +BuildArch: noarch + +Requires: python3-pdbpp +Requires: python3-pytest +Requires: python3-pytest-cov +Requires: python3-pytest-mock +Requires: python3-requests +Requires: python3-beautifulsoup4 + +%description +## Airium + +Bidirectional `HTML`-`python` translator. + +[](https://pypi.python.org/pypi/airium/) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://pypi.org/project/airium/) +[](https://pypi.python.org/pypi/airium/) +[](https://pypi.python.org/pypi/airium/) + +Key features: + +- simple, straight-forward +- template-less (just the python, you may say goodbye to all the templates) +- DOM structure is strictly represented by python indentation (with context-managers) +- gives much cleaner `HTML` than regular templates +- equipped with reverse translator: `HTML` to python +- can output either pretty (default) or minified `HTML` code + +# Generating `HTML` code in python using `airium` + +#### Basic `HTML` page (hello world) + +```python +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang="pl"): + with a.head(): + a.meta(charset="utf-8") + a.title(_t="Airium example") + + with a.body(): + with a.h3(id="id23409231", klass='main_header'): + a("Hello World.") + +html = str(a) # casting to string extracts the value +# or directly to UTF-8 encoded bytes: +html_bytes = bytes(a) # casting to bytes is a shortcut to str(a).encode('utf-8') + +print(html) +``` + +Prints such a string: + +```html +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +``` + +In order to store it as a file, just: + +```python +with open('that/file/path.html', 'wb') as f: + f.write(bytes(html)) +``` + +#### Simple image in a div + +```python +from airium import Airium + +a = Airium() + +with a.div(): + a.img(src='source.png', alt='alt text') + a('the text') + +html_str = str(a) +print(html_str) +``` + +```html + +<div> + <img src="source.png" alt="alt text"/> + the text +</div> +``` + +#### Table + +```python +from airium import Airium + +a = Airium() + +with a.table(id='table_372'): + with a.tr(klass='header_row'): + a.th(_t='no.') + a.th(_t='Firstname') + a.th(_t='Lastname') + + with a.tr(): + a.td(_t='1.') + a.td(id='jbl', _t='Jill') + a.td(_t='Smith') # can use _t or text + + with a.tr(): + a.td(_t='2.') + a.td(_t='Roland', id='rmd') + a.td(_t='Mendel') + +table_str = str(a) +print(table_str) + +# To store it to a file: +with open('/tmp/airium_www.example.com.py') as f: + f.write(table_str) +``` + +Now `table_str` contains such a string: + +```html + +<table id="table_372"> + <tr class="header_row"> + <th>no.</th> + <th>Firstname</th> + <th>Lastname</th> + </tr> + <tr> + <td>1.</td> + <td id="jbl">Jill</td> + <td>Smith</td> + </tr> + <tr> + <td>2.</td> + <td id="rmd">Roland</td> + <td>Mendel</td> + </tr> +</table> +``` + +### Chaining shortcut for elements with only one child + +_New in version 0.2.2_ + +Having a structure with large number of `with` statements: + +```python +from airium import Airium + +a = Airium() + +with a.article(): + with a.table(): + with a.thead(): + with a.tr(): + a.th(_t='Column 1') + a.th(_t='Column 2') + with a.tbody(): + with a.tr(): + with a.td(): + a.strong(_t='Value 1') + a.td(_t='Value 2') + +table_str = str(a) +print(table_str) +``` + +You may use a shortcut that is equivalent to: + +```python +from airium import Airium + +a = Airium() + +with a.article().table(): + with a.thead().tr(): + a.th(_t="Column 1") + a.th(_t="Column 2") + with a.tbody().tr(): + a.td().strong(_t="Value 1") + a.td(_t="Value 2") + +table_str = str(a) +print(table_str) +``` + +```html + +<article> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <strong>Value 1</strong> + </td> + <td>Value 2</td> + </tr> + </tbody> + </table> +</article> +``` + +# Options + +### Pretty or Minify + +By default, airium biulds `HTML` code indented with spaces and with line breaks being line feed `\n` characters. +It can be changed while creating an `Airium` instance. In general all avaliable arguments whit their default values are: + +```python +a = Airium( + base_indent=' ', # str + current_level=0, # int + source_minify=False, # bool + source_line_break_character="\n", # str +) +``` + +#### minify + +That's a mode when size of the code is minimized, i.e. contains as less whitespaces as it's possible. +The option can be enabled with `source_minify` argument, i.e.: + +```python +a = Airium(source_minify=True) +``` + +In case if you need to explicitly add a line break in the source code (not the `<br/>`): + +```python +a = Airium(source_minify=True) +a.h1(_t="Here's your table") +with a.table(): + with a.tr(): + a.break_source_line() + a.th(_t="Cell 11") + a.th(_t="Cell 12") + with a.tr(): + a.break_source_line() + a.th(_t="Cell 21") + a.th(_t="Cell 22") + a.break_source_line() +a.p(_t="Another content goes here") +``` + +Will result with such a code: + +```html +<h1>Here's your table</h1><table><tr> +<th>Cell 11</th><th>Cell 12</th></tr><tr> +<th>Cell 21</th><th>Cell 22</th></tr> +</table><p>Another content goes here</p> +``` + +Note that the `break_source_line` cannot be used +in [context manager chains](#chaining-shortcut-for-elements-with-only-one-child). + +#### indent style + +The default indent of the generated HTML code has two spaces per each indent level. +You can change it to `\t` or 4 spaces by setting `Airium` constructor argument, e.g.: + +```python +a = Airium(base_indent="\t") # one tab symbol +a = Airium(base_indent=" ") # 4 spaces per each indentation level +a = Airium(base_indent=" ") # 1 space per one level +# pick one of the above statements, it can be mixed with other arguments +``` + +Note that this setting is ignored when `source_minify` argument is set to `True` (see above). + +There is a special case when you set the base indent to empty string. It would disable indentation, +but line breaks will be still added. In order to get rid of line breaks, check the `source_minify` argument. + +#### indent level + +The `current_level` being an integer can be set to non-negative +value, wich will cause `airium` to start indentation with level offset given by the number. + +#### line break character + +By default, just a line feed (`\n`) is used for terminating lines of the generated code. +You can change it to different style, e.g. `\r\n` or `\r` by setting `source_line_break_character` to the desired value. + +```python +a = Airium(source_line_break_character="\r\n") # windows' style +``` + +Note that the setting has no effect when `source_minify` argument is set to `True` (see above). + +# Using airium with web-frameworks + +Airium can be used with frameworks like Flask or Django. It can completely replace +template engines, reducing code-files scater, which may bring better code organization, and some other reasons. + +Here is an example of using airium with django. It implements reusable `basic_body` and a view called `index`. + +```python +# file: your_app/views.py +import contextlib +import inspect + +from airium import Airium +from django.http import HttpResponse + + +@contextlib.contextmanager +def basic_body(a: Airium, useful_name: str = ''): + """Works like a Django/Ninja template.""" + + a('<!DOCTYPE html>') + with a.html(lang='en'): + with a.head(): + a.meta(charset='utf-8') + a.meta(content='width=device-width, initial-scale=1', name='viewport') + # do not use CSS from this URL in a production, it's just for an educational purpose + a.link(href='https://unpkg.com/@picocss/pico@1.4.1/css/pico.css', rel='stylesheet') + a.title(_t=f'Hello World') + + with a.body(): + with a.div(): + with a.nav(klass='container-fluid'): + with a.ul(): + with a.li(): + with a.a(klass='contrast', href='./'): + a.strong(_t="⌨ Foo Bar") + with a.ul(): + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'auto'}, _t='Auto') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'light'}, _t='Light') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'dark'}, _t='Dark') + + with a.header(klass='container'): + with a.hgroup(): + a.h1(_t=f"You're on the {useful_name}") + a.h2(_t="It's a page made by our automatons with a power of steam engines.") + + with a.main(klass='container'): + yield # This is the point where main content gets inserted + + with a.footer(klass='container'): + with a.small(): + margin = 'margin: auto 10px;' + a.span(_t='© Airium HTML generator example', style=margin) + + # do not use JS from this URL in a production, it's just for an educational purpose + a.script(src='https://picocss.com/examples/js/minimal-theme-switcher.js') + + +def index(request) -> HttpResponse: + a = Airium() + with basic_body(a, f'main page: {request.path}'): + with a.article(): + a.h3(_t="Hello World from Django running Airium") + with a.p().small(): + a("This bases on ") + with a.a(href="https://picocss.com/examples/company/"): + a("Pico.css / Company example") + + with a.p(): + a("Instead of a HTML template, airium has been used.") + a("The whole body is generated by a template " + "and the article code looks like that:") + + with a.code().pre(): + a(inspect.getsource(index)) + + return HttpResponse(bytes(a)) # from django.http import HttpResponse +``` + +Route it in `urls.py` just like a regular view: + +```python +# file: your_app/urls.py +from django.contrib import admin +from django.urls import path + +import your_app + +urlpatterns = [ + path('index/', your_app.views.index), + path('admin/', admin.site.urls), +] +``` + +The result ing web page on my machine looks like that: + + + +# Reverse translation + +Airium is equipped with a transpiler `[HTML -> py]`. +It generates python code out of a given `HTML` string. + +### Using reverse translator as a binary: + +Ensure you have [installed](#installation) `[parse]` extras. Then call in command line: + +```bash +airium http://www.example.com +``` + +That will fetch the document and translate it to python code. +The code calls `airium` statements that reproduce the `HTML` document given. +It may give a clue - how to define `HTML` structure for a given +web page using `airium` package. + +To store the translation's result into a file: + +```bash +airium http://www.example.com > /tmp/airium_example_com.py +``` + +You can also parse local `HTML` files: + +```bash +airium /path/to/your_file.html > /tmp/airium_my_file.py +``` + +You may also try to parse your Django templates. I'm not sure if it works, +but there will be probably not much to fix. + +### Using reverse translator as python code: + +```python +from airium import from_html_to_airium + +# assume we have such a page given as a string: +html_str = """\ +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +""" + +# to convert the html into python, just call: + +py_str = from_html_to_airium(html_str) + +# airium tests ensure that the result of the conversion is equal to the string: +assert py_str == """\ +#!/usr/bin/env python +# File generated by reverse AIRIUM translator (version 0.2.5). +# Any change will be overridden on next run. +# flake8: noqa E501 (line too long) + +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang='pl'): + with a.head(): + a.meta(charset='utf-8') + a.title(_t='Airium example') + with a.body(): + a.h3(klass='main_header', id='id23409231', _t='Hello World.') +""" +``` + +### <a name="transpiler_limitations">Transpiler limitations</a> + +> so far in version 0.2.2: + +- result of translation does not keep exact amount of leading whitespaces + within `<pre>` tags. They come over-indented in python code. + +This is not however an issue when code is generated from python to `HTML`. + +- although it keeps the proper tags structure, the transpiler does not + chain all the `with` statements, so in some cases the generated + code may be much indented. + +- it's not too fast + +# <a name="installation">Installation</a> + +If you need a new virtual environment, call: + +```bash +virtualenv venv +source venv/bin/activate +``` + +Having it activated - you may install airium like this: + +```bash +pip install airium +``` + +In order to use reverse translation - two additional packages are needed, run: + +```bash +pip install airium[parse] +``` + +Then check if the transpiler works by calling: + +```bash +airium --help +``` + +> Enjoy! + + +%package -n python3-airium +Summary: Easy and quick html builder with natural syntax correspondence (python->html). No templates needed. Serves pure pythonic library with no dependencies. +Provides: python-airium +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-airium +## Airium + +Bidirectional `HTML`-`python` translator. + +[](https://pypi.python.org/pypi/airium/) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://pypi.org/project/airium/) +[](https://pypi.python.org/pypi/airium/) +[](https://pypi.python.org/pypi/airium/) + +Key features: + +- simple, straight-forward +- template-less (just the python, you may say goodbye to all the templates) +- DOM structure is strictly represented by python indentation (with context-managers) +- gives much cleaner `HTML` than regular templates +- equipped with reverse translator: `HTML` to python +- can output either pretty (default) or minified `HTML` code + +# Generating `HTML` code in python using `airium` + +#### Basic `HTML` page (hello world) + +```python +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang="pl"): + with a.head(): + a.meta(charset="utf-8") + a.title(_t="Airium example") + + with a.body(): + with a.h3(id="id23409231", klass='main_header'): + a("Hello World.") + +html = str(a) # casting to string extracts the value +# or directly to UTF-8 encoded bytes: +html_bytes = bytes(a) # casting to bytes is a shortcut to str(a).encode('utf-8') + +print(html) +``` + +Prints such a string: + +```html +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +``` + +In order to store it as a file, just: + +```python +with open('that/file/path.html', 'wb') as f: + f.write(bytes(html)) +``` + +#### Simple image in a div + +```python +from airium import Airium + +a = Airium() + +with a.div(): + a.img(src='source.png', alt='alt text') + a('the text') + +html_str = str(a) +print(html_str) +``` + +```html + +<div> + <img src="source.png" alt="alt text"/> + the text +</div> +``` + +#### Table + +```python +from airium import Airium + +a = Airium() + +with a.table(id='table_372'): + with a.tr(klass='header_row'): + a.th(_t='no.') + a.th(_t='Firstname') + a.th(_t='Lastname') + + with a.tr(): + a.td(_t='1.') + a.td(id='jbl', _t='Jill') + a.td(_t='Smith') # can use _t or text + + with a.tr(): + a.td(_t='2.') + a.td(_t='Roland', id='rmd') + a.td(_t='Mendel') + +table_str = str(a) +print(table_str) + +# To store it to a file: +with open('/tmp/airium_www.example.com.py') as f: + f.write(table_str) +``` + +Now `table_str` contains such a string: + +```html + +<table id="table_372"> + <tr class="header_row"> + <th>no.</th> + <th>Firstname</th> + <th>Lastname</th> + </tr> + <tr> + <td>1.</td> + <td id="jbl">Jill</td> + <td>Smith</td> + </tr> + <tr> + <td>2.</td> + <td id="rmd">Roland</td> + <td>Mendel</td> + </tr> +</table> +``` + +### Chaining shortcut for elements with only one child + +_New in version 0.2.2_ + +Having a structure with large number of `with` statements: + +```python +from airium import Airium + +a = Airium() + +with a.article(): + with a.table(): + with a.thead(): + with a.tr(): + a.th(_t='Column 1') + a.th(_t='Column 2') + with a.tbody(): + with a.tr(): + with a.td(): + a.strong(_t='Value 1') + a.td(_t='Value 2') + +table_str = str(a) +print(table_str) +``` + +You may use a shortcut that is equivalent to: + +```python +from airium import Airium + +a = Airium() + +with a.article().table(): + with a.thead().tr(): + a.th(_t="Column 1") + a.th(_t="Column 2") + with a.tbody().tr(): + a.td().strong(_t="Value 1") + a.td(_t="Value 2") + +table_str = str(a) +print(table_str) +``` + +```html + +<article> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <strong>Value 1</strong> + </td> + <td>Value 2</td> + </tr> + </tbody> + </table> +</article> +``` + +# Options + +### Pretty or Minify + +By default, airium biulds `HTML` code indented with spaces and with line breaks being line feed `\n` characters. +It can be changed while creating an `Airium` instance. In general all avaliable arguments whit their default values are: + +```python +a = Airium( + base_indent=' ', # str + current_level=0, # int + source_minify=False, # bool + source_line_break_character="\n", # str +) +``` + +#### minify + +That's a mode when size of the code is minimized, i.e. contains as less whitespaces as it's possible. +The option can be enabled with `source_minify` argument, i.e.: + +```python +a = Airium(source_minify=True) +``` + +In case if you need to explicitly add a line break in the source code (not the `<br/>`): + +```python +a = Airium(source_minify=True) +a.h1(_t="Here's your table") +with a.table(): + with a.tr(): + a.break_source_line() + a.th(_t="Cell 11") + a.th(_t="Cell 12") + with a.tr(): + a.break_source_line() + a.th(_t="Cell 21") + a.th(_t="Cell 22") + a.break_source_line() +a.p(_t="Another content goes here") +``` + +Will result with such a code: + +```html +<h1>Here's your table</h1><table><tr> +<th>Cell 11</th><th>Cell 12</th></tr><tr> +<th>Cell 21</th><th>Cell 22</th></tr> +</table><p>Another content goes here</p> +``` + +Note that the `break_source_line` cannot be used +in [context manager chains](#chaining-shortcut-for-elements-with-only-one-child). + +#### indent style + +The default indent of the generated HTML code has two spaces per each indent level. +You can change it to `\t` or 4 spaces by setting `Airium` constructor argument, e.g.: + +```python +a = Airium(base_indent="\t") # one tab symbol +a = Airium(base_indent=" ") # 4 spaces per each indentation level +a = Airium(base_indent=" ") # 1 space per one level +# pick one of the above statements, it can be mixed with other arguments +``` + +Note that this setting is ignored when `source_minify` argument is set to `True` (see above). + +There is a special case when you set the base indent to empty string. It would disable indentation, +but line breaks will be still added. In order to get rid of line breaks, check the `source_minify` argument. + +#### indent level + +The `current_level` being an integer can be set to non-negative +value, wich will cause `airium` to start indentation with level offset given by the number. + +#### line break character + +By default, just a line feed (`\n`) is used for terminating lines of the generated code. +You can change it to different style, e.g. `\r\n` or `\r` by setting `source_line_break_character` to the desired value. + +```python +a = Airium(source_line_break_character="\r\n") # windows' style +``` + +Note that the setting has no effect when `source_minify` argument is set to `True` (see above). + +# Using airium with web-frameworks + +Airium can be used with frameworks like Flask or Django. It can completely replace +template engines, reducing code-files scater, which may bring better code organization, and some other reasons. + +Here is an example of using airium with django. It implements reusable `basic_body` and a view called `index`. + +```python +# file: your_app/views.py +import contextlib +import inspect + +from airium import Airium +from django.http import HttpResponse + + +@contextlib.contextmanager +def basic_body(a: Airium, useful_name: str = ''): + """Works like a Django/Ninja template.""" + + a('<!DOCTYPE html>') + with a.html(lang='en'): + with a.head(): + a.meta(charset='utf-8') + a.meta(content='width=device-width, initial-scale=1', name='viewport') + # do not use CSS from this URL in a production, it's just for an educational purpose + a.link(href='https://unpkg.com/@picocss/pico@1.4.1/css/pico.css', rel='stylesheet') + a.title(_t=f'Hello World') + + with a.body(): + with a.div(): + with a.nav(klass='container-fluid'): + with a.ul(): + with a.li(): + with a.a(klass='contrast', href='./'): + a.strong(_t="⌨ Foo Bar") + with a.ul(): + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'auto'}, _t='Auto') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'light'}, _t='Light') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'dark'}, _t='Dark') + + with a.header(klass='container'): + with a.hgroup(): + a.h1(_t=f"You're on the {useful_name}") + a.h2(_t="It's a page made by our automatons with a power of steam engines.") + + with a.main(klass='container'): + yield # This is the point where main content gets inserted + + with a.footer(klass='container'): + with a.small(): + margin = 'margin: auto 10px;' + a.span(_t='© Airium HTML generator example', style=margin) + + # do not use JS from this URL in a production, it's just for an educational purpose + a.script(src='https://picocss.com/examples/js/minimal-theme-switcher.js') + + +def index(request) -> HttpResponse: + a = Airium() + with basic_body(a, f'main page: {request.path}'): + with a.article(): + a.h3(_t="Hello World from Django running Airium") + with a.p().small(): + a("This bases on ") + with a.a(href="https://picocss.com/examples/company/"): + a("Pico.css / Company example") + + with a.p(): + a("Instead of a HTML template, airium has been used.") + a("The whole body is generated by a template " + "and the article code looks like that:") + + with a.code().pre(): + a(inspect.getsource(index)) + + return HttpResponse(bytes(a)) # from django.http import HttpResponse +``` + +Route it in `urls.py` just like a regular view: + +```python +# file: your_app/urls.py +from django.contrib import admin +from django.urls import path + +import your_app + +urlpatterns = [ + path('index/', your_app.views.index), + path('admin/', admin.site.urls), +] +``` + +The result ing web page on my machine looks like that: + + + +# Reverse translation + +Airium is equipped with a transpiler `[HTML -> py]`. +It generates python code out of a given `HTML` string. + +### Using reverse translator as a binary: + +Ensure you have [installed](#installation) `[parse]` extras. Then call in command line: + +```bash +airium http://www.example.com +``` + +That will fetch the document and translate it to python code. +The code calls `airium` statements that reproduce the `HTML` document given. +It may give a clue - how to define `HTML` structure for a given +web page using `airium` package. + +To store the translation's result into a file: + +```bash +airium http://www.example.com > /tmp/airium_example_com.py +``` + +You can also parse local `HTML` files: + +```bash +airium /path/to/your_file.html > /tmp/airium_my_file.py +``` + +You may also try to parse your Django templates. I'm not sure if it works, +but there will be probably not much to fix. + +### Using reverse translator as python code: + +```python +from airium import from_html_to_airium + +# assume we have such a page given as a string: +html_str = """\ +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +""" + +# to convert the html into python, just call: + +py_str = from_html_to_airium(html_str) + +# airium tests ensure that the result of the conversion is equal to the string: +assert py_str == """\ +#!/usr/bin/env python +# File generated by reverse AIRIUM translator (version 0.2.5). +# Any change will be overridden on next run. +# flake8: noqa E501 (line too long) + +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang='pl'): + with a.head(): + a.meta(charset='utf-8') + a.title(_t='Airium example') + with a.body(): + a.h3(klass='main_header', id='id23409231', _t='Hello World.') +""" +``` + +### <a name="transpiler_limitations">Transpiler limitations</a> + +> so far in version 0.2.2: + +- result of translation does not keep exact amount of leading whitespaces + within `<pre>` tags. They come over-indented in python code. + +This is not however an issue when code is generated from python to `HTML`. + +- although it keeps the proper tags structure, the transpiler does not + chain all the `with` statements, so in some cases the generated + code may be much indented. + +- it's not too fast + +# <a name="installation">Installation</a> + +If you need a new virtual environment, call: + +```bash +virtualenv venv +source venv/bin/activate +``` + +Having it activated - you may install airium like this: + +```bash +pip install airium +``` + +In order to use reverse translation - two additional packages are needed, run: + +```bash +pip install airium[parse] +``` + +Then check if the transpiler works by calling: + +```bash +airium --help +``` + +> Enjoy! + + +%package help +Summary: Development documents and examples for airium +Provides: python3-airium-doc +%description help +## Airium + +Bidirectional `HTML`-`python` translator. + +[](https://pypi.python.org/pypi/airium/) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://gitlab.com/kamichal/airium/-/commits/master) +[](https://pypi.org/project/airium/) +[](https://pypi.python.org/pypi/airium/) +[](https://pypi.python.org/pypi/airium/) + +Key features: + +- simple, straight-forward +- template-less (just the python, you may say goodbye to all the templates) +- DOM structure is strictly represented by python indentation (with context-managers) +- gives much cleaner `HTML` than regular templates +- equipped with reverse translator: `HTML` to python +- can output either pretty (default) or minified `HTML` code + +# Generating `HTML` code in python using `airium` + +#### Basic `HTML` page (hello world) + +```python +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang="pl"): + with a.head(): + a.meta(charset="utf-8") + a.title(_t="Airium example") + + with a.body(): + with a.h3(id="id23409231", klass='main_header'): + a("Hello World.") + +html = str(a) # casting to string extracts the value +# or directly to UTF-8 encoded bytes: +html_bytes = bytes(a) # casting to bytes is a shortcut to str(a).encode('utf-8') + +print(html) +``` + +Prints such a string: + +```html +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +``` + +In order to store it as a file, just: + +```python +with open('that/file/path.html', 'wb') as f: + f.write(bytes(html)) +``` + +#### Simple image in a div + +```python +from airium import Airium + +a = Airium() + +with a.div(): + a.img(src='source.png', alt='alt text') + a('the text') + +html_str = str(a) +print(html_str) +``` + +```html + +<div> + <img src="source.png" alt="alt text"/> + the text +</div> +``` + +#### Table + +```python +from airium import Airium + +a = Airium() + +with a.table(id='table_372'): + with a.tr(klass='header_row'): + a.th(_t='no.') + a.th(_t='Firstname') + a.th(_t='Lastname') + + with a.tr(): + a.td(_t='1.') + a.td(id='jbl', _t='Jill') + a.td(_t='Smith') # can use _t or text + + with a.tr(): + a.td(_t='2.') + a.td(_t='Roland', id='rmd') + a.td(_t='Mendel') + +table_str = str(a) +print(table_str) + +# To store it to a file: +with open('/tmp/airium_www.example.com.py') as f: + f.write(table_str) +``` + +Now `table_str` contains such a string: + +```html + +<table id="table_372"> + <tr class="header_row"> + <th>no.</th> + <th>Firstname</th> + <th>Lastname</th> + </tr> + <tr> + <td>1.</td> + <td id="jbl">Jill</td> + <td>Smith</td> + </tr> + <tr> + <td>2.</td> + <td id="rmd">Roland</td> + <td>Mendel</td> + </tr> +</table> +``` + +### Chaining shortcut for elements with only one child + +_New in version 0.2.2_ + +Having a structure with large number of `with` statements: + +```python +from airium import Airium + +a = Airium() + +with a.article(): + with a.table(): + with a.thead(): + with a.tr(): + a.th(_t='Column 1') + a.th(_t='Column 2') + with a.tbody(): + with a.tr(): + with a.td(): + a.strong(_t='Value 1') + a.td(_t='Value 2') + +table_str = str(a) +print(table_str) +``` + +You may use a shortcut that is equivalent to: + +```python +from airium import Airium + +a = Airium() + +with a.article().table(): + with a.thead().tr(): + a.th(_t="Column 1") + a.th(_t="Column 2") + with a.tbody().tr(): + a.td().strong(_t="Value 1") + a.td(_t="Value 2") + +table_str = str(a) +print(table_str) +``` + +```html + +<article> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <strong>Value 1</strong> + </td> + <td>Value 2</td> + </tr> + </tbody> + </table> +</article> +``` + +# Options + +### Pretty or Minify + +By default, airium biulds `HTML` code indented with spaces and with line breaks being line feed `\n` characters. +It can be changed while creating an `Airium` instance. In general all avaliable arguments whit their default values are: + +```python +a = Airium( + base_indent=' ', # str + current_level=0, # int + source_minify=False, # bool + source_line_break_character="\n", # str +) +``` + +#### minify + +That's a mode when size of the code is minimized, i.e. contains as less whitespaces as it's possible. +The option can be enabled with `source_minify` argument, i.e.: + +```python +a = Airium(source_minify=True) +``` + +In case if you need to explicitly add a line break in the source code (not the `<br/>`): + +```python +a = Airium(source_minify=True) +a.h1(_t="Here's your table") +with a.table(): + with a.tr(): + a.break_source_line() + a.th(_t="Cell 11") + a.th(_t="Cell 12") + with a.tr(): + a.break_source_line() + a.th(_t="Cell 21") + a.th(_t="Cell 22") + a.break_source_line() +a.p(_t="Another content goes here") +``` + +Will result with such a code: + +```html +<h1>Here's your table</h1><table><tr> +<th>Cell 11</th><th>Cell 12</th></tr><tr> +<th>Cell 21</th><th>Cell 22</th></tr> +</table><p>Another content goes here</p> +``` + +Note that the `break_source_line` cannot be used +in [context manager chains](#chaining-shortcut-for-elements-with-only-one-child). + +#### indent style + +The default indent of the generated HTML code has two spaces per each indent level. +You can change it to `\t` or 4 spaces by setting `Airium` constructor argument, e.g.: + +```python +a = Airium(base_indent="\t") # one tab symbol +a = Airium(base_indent=" ") # 4 spaces per each indentation level +a = Airium(base_indent=" ") # 1 space per one level +# pick one of the above statements, it can be mixed with other arguments +``` + +Note that this setting is ignored when `source_minify` argument is set to `True` (see above). + +There is a special case when you set the base indent to empty string. It would disable indentation, +but line breaks will be still added. In order to get rid of line breaks, check the `source_minify` argument. + +#### indent level + +The `current_level` being an integer can be set to non-negative +value, wich will cause `airium` to start indentation with level offset given by the number. + +#### line break character + +By default, just a line feed (`\n`) is used for terminating lines of the generated code. +You can change it to different style, e.g. `\r\n` or `\r` by setting `source_line_break_character` to the desired value. + +```python +a = Airium(source_line_break_character="\r\n") # windows' style +``` + +Note that the setting has no effect when `source_minify` argument is set to `True` (see above). + +# Using airium with web-frameworks + +Airium can be used with frameworks like Flask or Django. It can completely replace +template engines, reducing code-files scater, which may bring better code organization, and some other reasons. + +Here is an example of using airium with django. It implements reusable `basic_body` and a view called `index`. + +```python +# file: your_app/views.py +import contextlib +import inspect + +from airium import Airium +from django.http import HttpResponse + + +@contextlib.contextmanager +def basic_body(a: Airium, useful_name: str = ''): + """Works like a Django/Ninja template.""" + + a('<!DOCTYPE html>') + with a.html(lang='en'): + with a.head(): + a.meta(charset='utf-8') + a.meta(content='width=device-width, initial-scale=1', name='viewport') + # do not use CSS from this URL in a production, it's just for an educational purpose + a.link(href='https://unpkg.com/@picocss/pico@1.4.1/css/pico.css', rel='stylesheet') + a.title(_t=f'Hello World') + + with a.body(): + with a.div(): + with a.nav(klass='container-fluid'): + with a.ul(): + with a.li(): + with a.a(klass='contrast', href='./'): + a.strong(_t="⌨ Foo Bar") + with a.ul(): + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'auto'}, _t='Auto') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'light'}, _t='Light') + with a.li(): + a.a(klass='contrast', href='#', **{'data-theme-switcher': 'dark'}, _t='Dark') + + with a.header(klass='container'): + with a.hgroup(): + a.h1(_t=f"You're on the {useful_name}") + a.h2(_t="It's a page made by our automatons with a power of steam engines.") + + with a.main(klass='container'): + yield # This is the point where main content gets inserted + + with a.footer(klass='container'): + with a.small(): + margin = 'margin: auto 10px;' + a.span(_t='© Airium HTML generator example', style=margin) + + # do not use JS from this URL in a production, it's just for an educational purpose + a.script(src='https://picocss.com/examples/js/minimal-theme-switcher.js') + + +def index(request) -> HttpResponse: + a = Airium() + with basic_body(a, f'main page: {request.path}'): + with a.article(): + a.h3(_t="Hello World from Django running Airium") + with a.p().small(): + a("This bases on ") + with a.a(href="https://picocss.com/examples/company/"): + a("Pico.css / Company example") + + with a.p(): + a("Instead of a HTML template, airium has been used.") + a("The whole body is generated by a template " + "and the article code looks like that:") + + with a.code().pre(): + a(inspect.getsource(index)) + + return HttpResponse(bytes(a)) # from django.http import HttpResponse +``` + +Route it in `urls.py` just like a regular view: + +```python +# file: your_app/urls.py +from django.contrib import admin +from django.urls import path + +import your_app + +urlpatterns = [ + path('index/', your_app.views.index), + path('admin/', admin.site.urls), +] +``` + +The result ing web page on my machine looks like that: + + + +# Reverse translation + +Airium is equipped with a transpiler `[HTML -> py]`. +It generates python code out of a given `HTML` string. + +### Using reverse translator as a binary: + +Ensure you have [installed](#installation) `[parse]` extras. Then call in command line: + +```bash +airium http://www.example.com +``` + +That will fetch the document and translate it to python code. +The code calls `airium` statements that reproduce the `HTML` document given. +It may give a clue - how to define `HTML` structure for a given +web page using `airium` package. + +To store the translation's result into a file: + +```bash +airium http://www.example.com > /tmp/airium_example_com.py +``` + +You can also parse local `HTML` files: + +```bash +airium /path/to/your_file.html > /tmp/airium_my_file.py +``` + +You may also try to parse your Django templates. I'm not sure if it works, +but there will be probably not much to fix. + +### Using reverse translator as python code: + +```python +from airium import from_html_to_airium + +# assume we have such a page given as a string: +html_str = """\ +<!DOCTYPE html> +<html lang="pl"> + <head> + <meta charset="utf-8" /> + <title>Airium example</title> + </head> + <body> + <h3 id="id23409231" class="main_header"> + Hello World. + </h3> + </body> +</html> +""" + +# to convert the html into python, just call: + +py_str = from_html_to_airium(html_str) + +# airium tests ensure that the result of the conversion is equal to the string: +assert py_str == """\ +#!/usr/bin/env python +# File generated by reverse AIRIUM translator (version 0.2.5). +# Any change will be overridden on next run. +# flake8: noqa E501 (line too long) + +from airium import Airium + +a = Airium() + +a('<!DOCTYPE html>') +with a.html(lang='pl'): + with a.head(): + a.meta(charset='utf-8') + a.title(_t='Airium example') + with a.body(): + a.h3(klass='main_header', id='id23409231', _t='Hello World.') +""" +``` + +### <a name="transpiler_limitations">Transpiler limitations</a> + +> so far in version 0.2.2: + +- result of translation does not keep exact amount of leading whitespaces + within `<pre>` tags. They come over-indented in python code. + +This is not however an issue when code is generated from python to `HTML`. + +- although it keeps the proper tags structure, the transpiler does not + chain all the `with` statements, so in some cases the generated + code may be much indented. + +- it's not too fast + +# <a name="installation">Installation</a> + +If you need a new virtual environment, call: + +```bash +virtualenv venv +source venv/bin/activate +``` + +Having it activated - you may install airium like this: + +```bash +pip install airium +``` + +In order to use reverse translation - two additional packages are needed, run: + +```bash +pip install airium[parse] +``` + +Then check if the transpiler works by calling: + +```bash +airium --help +``` + +> Enjoy! + + +%prep +%autosetup -n airium-0.2.5 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-airium -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 0.2.5-1 +- Package Spec generated @@ -0,0 +1 @@ +4bfc79e4a427438954d8397f7a53ac4e airium-0.2.5.tar.gz |