Skip to content

Instantly share code, notes, and snippets.

@amcgregor
Created November 9, 2021 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amcgregor/29d177f00147b804d91e2c5cfc0840d2 to your computer and use it in GitHub Desktop.
Save amcgregor/29d177f00147b804d91e2c5cfc0840d2 to your computer and use it in GitHub Desktop.
A demonstration of the code transformation that occurs when Python imports a cinje module.
# encoding: cinje
# To use this module:
# : from cinje.std import html
# : using html.page ...
: from collections import Mapping, Set, Sequence, Iterator
: _list = list # We override an important __builtin__ name in this module.
: def default_header title, metadata=[], styles=[], scripts=[]
: """Prepare and generate the HTML <head> section."""
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
: for data in metadata
: if isinstance(data, Iterator)
: _buffer.extend(data)
: elif isinstance(data, Mapping)
<meta&{data}>
: else
<meta&{name=data[0], content=data[1]}>
: end
: end
<title>${title}</title>
: for href in styles
<link&{href=href, rel="stylesheet"}>
: end
: for href in scripts
<script&{src=href}></script>
: end
: end
: def default_footer styles=[], scripts=[]
: """Prepare and generate the HTML body postfix."""
: for href in styles
<link&{href=href, rel="stylesheet"}>
: end
: for href in scripts
<script&{src=href}></script>
: end
: end
: def page title, header=default_header, footer=default_footer, metadata=[], styles=[], scripts=[], **attributes
: """A general HTML page."""
: if attributes is None
: attributes = {}
: end
<!DOCTYPE html>
<html&{lang=attributes.pop('lang', 'en')}>
<head>
: if header
: use header title, metadata=metadata, styles=styles, scripts=[]
: end
</head>
<body&{attributes, role='document'}>
: yield
: if footer
: use footer styles=[], scripts=scripts
: end
</body>
</html>
: end
# TODO: __url__ protocol support, take str() of object, url from __url__,
: def link href, **kwargs
: """HTML5 hypertext reference."""
<a href="${href}"&{kwargs}>\
: yield
</a>\
:end
: def div **kwargs
: """Generic HTML5 block element."""
<div&{kwargs}>
: yield
</div>
: end
: def span content, **kwargs
: """Generic HTML5 inline element."""
<span&{kwargs}>\
: if isinstance(content, Iterator)
: _buffer.extend(content)
: else
${content}\
: end
</span>\
: end
: def heading content, level=1, **kwargs
: """Standard level-specific HTML5 heading."""
<h${level}&{kwargs}>\
: if isinstance(content, Iterator)
: _buffer.extend(content)
: else
${content}\
: end
</h${level}>
: end
: def abbr label, title, **kwargs
: """HTML5 inline abbreviation."""
<abbr&{kwargs, title=title}>${label}</abbr>\
: end
: def list obj, kind='auto', **attributes
: """Generate an HTML5 list, defaulting to type auto-detection."""
: if kind == 'auto'
: if isinstance(obj, Mapping)
: kind = 'dl'
: elif isinstance(obj, Set)
: kind = 'ul'
: elif isinstance(obj, Sequence)
: kind = 'ol'
: end
: end
<${kind}&{attributes}>
: if kind == 'dl'
: for key in obj
<dt>${key}</dt>
<dd>${obj[key]}</dd>
: end
: else
: for element in obj
<li>${element}</li>
: end
: end
</${kind}>
: end
# To use this module:
# : from cinje.std import html
# : using html.page ...
from __future__ import unicode_literals
import cinje
from cinje.helpers import escape as _escape, bless as _bless, iterate, xmlargs as _args, _interrupt, _json
__tmpl__ = [] # Exported template functions.
from collections import Mapping, Set, Sequence, Iterator
_list = list # We override an important __builtin__ name in this module.
def default_header(title, metadata=[], styles=[], scripts=[]):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Prepare and generate the HTML <head> section."""
__w((u'\t\t<meta charset="utf-8">\n',
u'\t\t<meta http-equiv="X-UA-Compatible" content="IE=edge">\n',
u'\t\t<meta name="viewport" content="width=device-width, initial-scale=1">\n'))
for data in metadata:
if isinstance(data, Iterator):
_buffer.extend(data)
elif isinstance(data, Mapping):
__w((u'\t\t<meta',
_args(data),
u'>\n'))
else:
__w((u'\t\t<meta',
_args(name=data[0], content=data[1]),
u'>\n'))
__w((u'\t\t<title>',
_escape(title),
u'</title>\n'))
for href in styles:
__w((u'\t\t<link',
_args(href=href, rel="stylesheet"),
u'>\n'))
for href in scripts:
__w((u'\t\t<script',
_args(src=href),
u'></script>\n'))
yield "".join(_buffer)
def default_footer(styles=[], scripts=[]):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Prepare and generate the HTML body postfix."""
for href in styles:
__w((u'\t\t<link',
_args(href=href, rel="stylesheet"),
u'>\n'))
for href in scripts:
__w((u'\t\t<script',
_args(src=href),
u'></script>\n'))
yield "".join(_buffer)
def page(title, header=default_header, footer=default_footer, metadata=[], styles=[], scripts=[], **attributes):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""A general HTML page."""
if attributes is None:
attributes = {}
__w((u'<!DOCTYPE html>\n',
u'<html',
_args(lang=attributes.pop('lang', 'en')),
u'>\n',
u'\t<head>\n'))
if header:
__w(header(title, metadata=metadata, styles=styles, scripts=[]))
__w((u'\t</head>\n',
u'\n',
u'\t<body',
_args(attributes, role='document'),
u'>\n'))
yield "".join(_buffer)
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
yield
if footer:
__w(footer(styles=[], scripts=scripts))
__w((u'\t</body>\n',
u'</html>\n'))
yield "".join(_buffer)
# TODO: __url__ protocol support, take str() of object, url from __url__,
def link(href, **kwargs):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""HTML5 hypertext reference."""
__w((u'<a href="',
_escape(href),
u'"',
_args(kwargs),
u'>'))
yield "".join(_buffer)
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
yield
__ws(u'</a>')
yield "".join(_buffer)
def div(**kwargs):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Generic HTML5 block element."""
__w((u'<div',
_args(kwargs),
u'>\n'))
yield "".join(_buffer)
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
yield
__ws(u'</div>\n')
yield "".join(_buffer)
def span(content, **kwargs):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Generic HTML5 inline element."""
__w((u'<span',
_args(kwargs),
u'>'))
if isinstance(content, Iterator):
_buffer.extend(content)
else:
__ws(_escape(content))
__ws(u'</span>')
yield "".join(_buffer)
def heading(content, level=1, **kwargs):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Standard level-specific HTML5 heading."""
__w((u'<h',
_escape(level),
_args(kwargs),
u'>'))
if isinstance(content, Iterator):
_buffer.extend(content)
else:
__ws(_escape(content))
__w((u'</h',
_escape(level),
u'>\n'))
yield "".join(_buffer)
def abbr(label, title, **kwargs):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""HTML5 inline abbreviation."""
__w((u'<abbr',
_args(kwargs, title=title),
u'>',
_escape(label),
u'</abbr>'))
yield "".join(_buffer)
def list(obj, kind='auto', **attributes):
_buffer = []
__w, __ws = _buffer.extend, _buffer.append
"""Generate an HTML5 list, defaulting to type auto-detection."""
if kind == 'auto':
if isinstance(obj, Mapping):
kind = 'dl'
elif isinstance(obj, Set):
kind = 'ul'
elif isinstance(obj, Sequence):
kind = 'ol'
__w((u'\t<',
_escape(kind),
_args(attributes),
u'>\n'))
if kind == 'dl':
for key in obj:
__w((u'\t\t<dt>',
_escape(key),
u'</dt>\n',
u'\t\t<dd>',
_escape(obj[key]),
u'</dd>\n'))
else:
for element in obj:
__w((u'\t\t<li>',
_escape(element),
u'</li>\n'))
__w((u'\t</',
_escape(kind),
u'>\n'))
yield "".join(_buffer)
__tmpl__.extend(["default_header", "default_footer", "page", "link", "div", "span", "heading", "abbr", "list"])
__mapping__ = [0,2,3,4,5,6,6,6,6,6,6,6,6,6,7,8,9,10,11,12,12,12,12,13,14,15,16,17,19,20,21,22,23,23,23,24,25,25,25,28,29,29,29,31,32,32,32,34,35,35,35,35,38,39,40,40,40,40,41,42,43,44,44,44,46,47,47,47,47,50,51,52,52,52,52,53,54,55,56,58,59,60,60,60,61,62,63,65,66,67,67,67,68,68,68,68,68,68,69,70,71,73,74,74,76,77,78,79,79,79,79,80,81,81,81,81,81,82,82,82,82,82,82,83,83,85,86,87,87,87,87,88,89,89,89,90,90,90,90,90,90,91,91,93,94,95,95,95,95,96,97,97,97,98,99,100,101,103,103,105,106,107,107,107,107,108,109,109,109,109,110,111,112,113,115,115,115,115,117,118,119,119,119,119,120,121,121,121,121,121,121,123,124,125,125,125,125,126,127,128,129,130,131,132,133,134,137,138,138,138,138,139,140,141,141,141,142,142,142,144,145,146,146,146,149,149,149,149,151,151,151]
__gzmapping__ = b"eJxtTAkOACAIQvz/n/PAais25jgEtAAEM6m6ipIepBhiKo/BftCdzShxdsvqANzex8m/S8vAbR0huFQNVuZZAhZGewCY"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment