Sanity HTML Renderer for Python
This package generates HTML from Portable Text.
For the most part, it mirrors Sanity's own block-content-to-html NPM library.
Installation
pip install sanity-html
Usage
Instantiate the SanityBlockRenderer class with your content and call the render method.
The following content
from sanity_html import SanityBlockRenderer
renderer = SanityBlockRenderer({
"_key": "R5FvMrjo",
"_type": "block",
"children": [
{"_key": "cZUQGmh4", "_type": "span", "marks": ["strong"], "text": "A word of"},
{"_key": "toaiCqIK", "_type": "span", "marks": ["strong"], "text": " warning;"},
{"_key": "gaZingsA", "_type": "span", "marks": [], "text": " Sanity is addictive."}
],
"markDefs": [],
"style": "normal"
})
renderer.render()
Generates this HTML
<p><strong>A word of warning;</strong> Sanity is addictive.</p>
Supported types
The block and span types are supported out of the box.
Custom types
Beyond the built-in types, you have the freedom to provide
your own serializers to render any custom _type the way you
would like to.
To illustrate, if you passed this data to the renderer class:
from sanity_html import SanityBlockRenderer
renderer = SanityBlockRenderer({
"_type": "block",
"_key": "foo",
"style": "normal",
"children": [
{
"_type": "span",
"text": "Press, "
},
{
"_type": "button",
"text": "here"
},
{
"_type": "span",
"text": ", now!"
}
]
})
renderer.render()
The renderer would actually throw an error here, since button
does not have a corresponding built-in type serializer by default.
To render this text you must provide your own serializer, like this:
from sanity_html import SanityBlockRenderer
def button_serializer(node: dict, context: Optional[Block], list_item: bool):
return f'<button>{node["text"]}</button>'
renderer = SanityBlockRenderer(
...,
custom_serializers={'button': button_serializer}
)
output = renderer.render()
With the custom serializer provided, the renderer would now successfully output the following HTML:
<p>Press <button>here</button>, now!</p>
Supported mark definitions
The package provides several built-in marker definitions and styles:
decorator marker definitions
emstrongcodeunderlinestrike-through
annotation marker definitions
linkcomment
Custom mark definitions
Like with custom type serializers, additional serializers for marker definitions and styles can be passed in like this:
from sanity_html import SanityBlockRenderer
renderer = SanityBlockRenderer(
...,
custom_marker_definitions={'em': ComicSansEmphasis}
)
renderer.render()
The primary difference between a type serializer and a mark definition serializer is that the latter uses a class structure, and has three required methods.
Here's an example of a custom style, adding an extra font to the built-in equivalent serializer:
from sanity_html.marker_definitions import MarkerDefinition
class ComicSansEmphasis(MarkerDefinition):
tag = 'em'
@classmethod
def render_prefix(cls, span: Span, marker: str, context: Block) -> str:
return f'<{cls.tag} style="font-family: "Comic Sans MS", "Comic Sans", cursive;">'
@classmethod
def render_suffix(cls, span: Span, marker: str, context: Block) -> str:
return f'</{cls.tag}>'
@classmethod
def render(cls, span: Span, marker: str, context: Block) -> str:
result = cls.render_prefix(span, marker, context)
result += str(span.text)
result += cls.render_suffix(span, marker, context)
return result
Since the render_suffix and render methods here are actually identical to the base class,
they do not need to be specified, and the whole example can be reduced to:
from sanity_html.marker_definitions import MarkerDefinition # base
from sanity_html import SanityBlockRenderer
class ComicSansEmphasis(MarkerDefinition):
tag = 'em'
@classmethod
def render_prefix(cls, span: Span, marker: str, context: Block) -> str:
return f'<{cls.tag} style="font-family: "Comic Sans MS", "Comic Sans", cursive;">'
renderer = SanityBlockRenderer(
...,
custom_marker_definitions={'em': ComicSansEmphasis}
)
renderer.render()
Supported styles
Blocks can optionally define a style tag. These styles are supported:
h1h2h3h4h5h6blockquotenormal
Missing features
For anyone interested, we would be happy to see a
default built-in serializer for the image type added.
In the meantime, users should be able to serialize image types by passing a custom serializer.
Contributing
Contributions are always appreciated 👏
For details, see the CONTRIBUTING.md.
Metadata
Release files for sanity-html 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sanity-html-1.0.0.tar.gz | 14.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sanity_html-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.5 kB
Release files / sanity-html-1.0.0.tar.gz
| Download URL | sanity-html-1.0.0.tar.gz |
|---|---|
| Size | 14.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80b579366119ce3e90fb4fc1b2b9158a5b467e49ec4908d9a917649f25885bbf
|
|
BLAKE2b-256 checksum How to use checksums |
c2033d2f58210f258a39da786d66bf212519fd96deadeadbf004115c71b54a85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.6 CPython/3.9.9 Linux/5.11.0-1021-azure
|
Release files / sanity_html-1.0.0-py3-none-any.whl
| Download URL | sanity_html-1.0.0-py3-none-any.whl |
|---|---|
| Size | 14.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f3a805a0d523c8dd9bc14f173f41a126e6094f4bc03e55841799bfa97a81e4b8
|
|
BLAKE2b-256 checksum How to use checksums |
6d9ecb065bbb4836c3523b8153643418bce94831572bc3f99cb5518e18a6a58a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.6 CPython/3.9.9 Linux/5.11.0-1021-azure
|
Security for sanity-html 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.