# datasette-render-markdown
[![PyPI](https://img.shields.io/pypi/v/datasette-render-markdown.svg)](https://pypi.org/project/datasette-render-markdown/)
[![Changelog](https://img.shields.io/github/v/release/simonw/datasette-render-markdown?include_prereleases&label=changelog)](https://github.com/simonw/datasette-render-markdown/releases)
[![Tests](https://github.com/simonw/datasette-render-markdown/workflows/Test/badge.svg)](https://github.com/simonw/datasette-render-markdown/actions?query=workflow%3ATest)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/datasette-render-markdown/blob/main/LICENSE)
[Datasette](https://datasette.io/) plugin for rendering Markdown.
## Installation
Install this plugin in the same environment as Datasette to enable this new functionality:
```bash
datasette install datasette-render-markdown
```
## Usage
You can explicitly list the columns you would like to treat as Markdown using [plugin configuration](https://datasette.readthedocs.io/en/stable/plugins.html#plugin-configuration) in a `metadata.json` file.
Add a `"datasette-render-markdown"` configuration block and use a `"columns"` key to list the columns you would like to treat as Markdown values:
```json
{
"plugins": {
"datasette-render-markdown": {
"columns": ["body"]
}
}
}
```
This will cause any `body` column in any table to be treated as markdown and safely rendered using [Python-Markdown](https://python-markdown.github.io/). The resulting HTML is then run through [Bleach](https://bleach.readthedocs.io/) to avoid the risk of XSS security problems.
Save this to `metadata.json` and run Datasette with the `--metadata` flag to load this configuration:
$ datasette serve mydata.db --metadata metadata.json
The configuration block can be used at the top level, or it can be applied just to specific databases or tables. Here's how to apply it to just the `entries` table in the `news.db` database:
```json
{
"databases": {
"news": {
"tables": {
"entries": {
"plugins": {
"datasette-render-markdown": {
"columns": ["body"]
}
}
}
}
}
}
}
```
And here's how to apply it to every `body` column in every table in the `news.db` database:
```json
{
"databases": {
"news": {
"plugins": {
"datasette-render-markdown": {
"columns": ["body"]
}
}
}
}
}
```
## Columns that match a naming convention
This plugin can also render markdown in any columns that match a specific naming convention.
By default, columns that have a name ending in `_markdown` will be rendered.
You can try this out using the following query:
```sql
select '# Hello there
* This is a list
* of items
[And a link](https://github.com/simonw/datasette-render-markdown).'
as demo_markdown
```
You can configure a different list of wildcard patterns using the `"patterns"` configuration key. Here's how to render columns that end in either `_markdown` or `_md`:
```json
{
"plugins": {
"datasette-render-markdown": {
"patterns": ["*_markdown", "*_md"]
}
}
}
```
To disable wildcard column matching entirely, set `"patterns": []` in your plugin metadata configuration.
## Markdown extensions
The [Python-Markdown library](https://python-markdown.github.io/) that powers this plugin supports extensions, both [bundled](https://python-markdown.github.io/extensions/) and [third-party](https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions). These can be used to enable additional Markdown features such as [table support](https://python-markdown.github.io/extensions/tables/).
You can configure support for extensions using the `"extensions"` key in your plugin metadata configuration.
Since extensions may introduce new HTML tags, you will also need to add those tags to the list of tags that are allowed by the [Bleach](https://bleach.readthedocs.io/) sanitizer. You can do that using the `"extra_tags"` key, and you can allow-list additional HTML attributes using `"extra_attrs"`. See [the Bleach documentation](https://bleach.readthedocs.io/en/latest/clean.html#allowed-tags-tags) for more information on this.
Here's how to enable support for [Markdown tables](https://python-markdown.github.io/extensions/tables/):
```json
{
"plugins": {
"datasette-render-markdown": {
"extensions": ["tables"],
"extra_tags": ["table", "thead", "tr", "th", "td", "tbody"]
}
}
}
```
### GitHub-Flavored Markdown
Enabling [GitHub-Flavored Markdown](https://help.github.com/en/github/writing-on-github) (useful for if you are working with data imported from GitHub using [github-to-sqlite](https://github.com/dogsheep/github-to-sqlite)) is a little more complicated.
First, you will need to install the [py-gfm](https://py-gfm.readthedocs.io) package:
$ pip install py-gfm
Note that `py-gfm` has [a bug](https://github.com/Zopieux/py-gfm/issues/13) that causes it to pin to `Markdown<3.0` - so if you are using it you should install it _before_ installing `datasette-render-markdown` to ensure you get a compatibly version of that dependency.
Now you can configure it like this. Note that the extension name is `mdx_gfm:GithubFlavoredMarkdownExtension` and you need to allow-list several extra HTML tags and attributes:
```json
{
"plugins": {
"datasette-render-markdown": {
"extra_tags": [
"hr",
"br",
"details",
"summary",
"input"
],
"extra_attrs": {
"input": [
"type",
"disabled",
"checked"
],
},
"extensions": [
"mdx_gfm:GithubFlavoredMarkdownExtension"
]
}
}
}
```
The `<input type="" checked disabled>` attributes are needed to support rendering checkboxes in issue descriptions.
## Markdown in templates
The plugin introduces a new template tag: `{% markdown %}...{% endmarkdown %}` - which can be used to render Markdown in your Jinja templates.
```html+jinja
{% markdown %}
# This will be rendered as markdown
{% endmarkdown %}
```
You can use attributes on the `{% markdown %}` tag to enable extensions and allow-list additional tags and attributes:
```html+jinja
{% markdown
extensions="tables"
extra_tags="table thead tr th td tbody"
extra_attrs="p:id,class a:name,href" %}
## Markdown table
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
<a href="https://www.example.com/" name="namehere">Example</a>
<p id="paragraph" class="klass">Paragraph</p>
{% endmarkdown %}
```
The `extensions=` and `extra_tags=` attributes accept a space-separated list of values.
The `extra_attrs=` attribute accepts a space-separated list of `tag:attr1,attr2` values - each tag can specify one or more attributes that should be allowed.
You can also use the `{{ render_markdown(...) }}` function, like this:
```html+jinja
{{ render_markdown("""
## Markdown table
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
""", extensions=["tables"],
extra_tags=["table", "thead", "tr", "th", "td", "tbody"])) }}
```
The `{% markdown %}` tag is recommended, as it avoids the need to `\"` escape quotes in your Markdown content.
Raw data
{
"_id": null,
"home_page": "https://github.com/simonw/datasette-render-markdown",
"name": "datasette-render-markdown",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "Simon Willison",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/4f/99/3074dc4a0129d2dbe12f8492daa392c47d927b380e9d96ffd781b22f887b/datasette-render-markdown-2.2.1.tar.gz",
"platform": null,
"description": "# datasette-render-markdown\n\n[![PyPI](https://img.shields.io/pypi/v/datasette-render-markdown.svg)](https://pypi.org/project/datasette-render-markdown/)\n[![Changelog](https://img.shields.io/github/v/release/simonw/datasette-render-markdown?include_prereleases&label=changelog)](https://github.com/simonw/datasette-render-markdown/releases)\n[![Tests](https://github.com/simonw/datasette-render-markdown/workflows/Test/badge.svg)](https://github.com/simonw/datasette-render-markdown/actions?query=workflow%3ATest)\n[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/datasette-render-markdown/blob/main/LICENSE)\n\n[Datasette](https://datasette.io/) plugin for rendering Markdown.\n\n## Installation\n\nInstall this plugin in the same environment as Datasette to enable this new functionality:\n```bash\ndatasette install datasette-render-markdown\n```\n## Usage\n\nYou can explicitly list the columns you would like to treat as Markdown using [plugin configuration](https://datasette.readthedocs.io/en/stable/plugins.html#plugin-configuration) in a `metadata.json` file.\n\nAdd a `\"datasette-render-markdown\"` configuration block and use a `\"columns\"` key to list the columns you would like to treat as Markdown values:\n\n```json\n{\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"columns\": [\"body\"]\n }\n }\n}\n```\n\nThis will cause any `body` column in any table to be treated as markdown and safely rendered using [Python-Markdown](https://python-markdown.github.io/). The resulting HTML is then run through [Bleach](https://bleach.readthedocs.io/) to avoid the risk of XSS security problems.\n\nSave this to `metadata.json` and run Datasette with the `--metadata` flag to load this configuration:\n\n $ datasette serve mydata.db --metadata metadata.json\n\nThe configuration block can be used at the top level, or it can be applied just to specific databases or tables. Here's how to apply it to just the `entries` table in the `news.db` database:\n\n```json\n{\n \"databases\": {\n \"news\": {\n \"tables\": {\n \"entries\": {\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"columns\": [\"body\"]\n }\n }\n }\n }\n }\n }\n}\n```\n\nAnd here's how to apply it to every `body` column in every table in the `news.db` database:\n\n```json\n{\n \"databases\": {\n \"news\": {\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"columns\": [\"body\"]\n }\n }\n }\n }\n}\n```\n\n## Columns that match a naming convention\n\nThis plugin can also render markdown in any columns that match a specific naming convention.\n\nBy default, columns that have a name ending in `_markdown` will be rendered.\n\nYou can try this out using the following query:\n\n```sql\nselect '# Hello there\n\n* This is a list\n* of items\n\n[And a link](https://github.com/simonw/datasette-render-markdown).'\nas demo_markdown\n```\n\nYou can configure a different list of wildcard patterns using the `\"patterns\"` configuration key. Here's how to render columns that end in either `_markdown` or `_md`:\n\n```json\n{\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"patterns\": [\"*_markdown\", \"*_md\"]\n }\n }\n}\n```\n\nTo disable wildcard column matching entirely, set `\"patterns\": []` in your plugin metadata configuration.\n\n## Markdown extensions\n\nThe [Python-Markdown library](https://python-markdown.github.io/) that powers this plugin supports extensions, both [bundled](https://python-markdown.github.io/extensions/) and [third-party](https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions). These can be used to enable additional Markdown features such as [table support](https://python-markdown.github.io/extensions/tables/).\n\nYou can configure support for extensions using the `\"extensions\"` key in your plugin metadata configuration.\n\nSince extensions may introduce new HTML tags, you will also need to add those tags to the list of tags that are allowed by the [Bleach](https://bleach.readthedocs.io/) sanitizer. You can do that using the `\"extra_tags\"` key, and you can allow-list additional HTML attributes using `\"extra_attrs\"`. See [the Bleach documentation](https://bleach.readthedocs.io/en/latest/clean.html#allowed-tags-tags) for more information on this.\n\nHere's how to enable support for [Markdown tables](https://python-markdown.github.io/extensions/tables/):\n\n```json\n{\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"extensions\": [\"tables\"],\n \"extra_tags\": [\"table\", \"thead\", \"tr\", \"th\", \"td\", \"tbody\"]\n }\n }\n}\n```\n\n### GitHub-Flavored Markdown\n\nEnabling [GitHub-Flavored Markdown](https://help.github.com/en/github/writing-on-github) (useful for if you are working with data imported from GitHub using [github-to-sqlite](https://github.com/dogsheep/github-to-sqlite)) is a little more complicated.\n\nFirst, you will need to install the [py-gfm](https://py-gfm.readthedocs.io) package:\n\n $ pip install py-gfm\n\nNote that `py-gfm` has [a bug](https://github.com/Zopieux/py-gfm/issues/13) that causes it to pin to `Markdown<3.0` - so if you are using it you should install it _before_ installing `datasette-render-markdown` to ensure you get a compatibly version of that dependency.\n\nNow you can configure it like this. Note that the extension name is `mdx_gfm:GithubFlavoredMarkdownExtension` and you need to allow-list several extra HTML tags and attributes:\n\n```json\n{\n \"plugins\": {\n \"datasette-render-markdown\": {\n \"extra_tags\": [\n \"hr\",\n \"br\",\n \"details\",\n \"summary\",\n \"input\"\n ],\n \"extra_attrs\": {\n \"input\": [\n \"type\",\n \"disabled\",\n \"checked\"\n ],\n },\n \"extensions\": [\n \"mdx_gfm:GithubFlavoredMarkdownExtension\"\n ]\n }\n }\n}\n```\n\nThe `<input type=\"\" checked disabled>` attributes are needed to support rendering checkboxes in issue descriptions.\n\n## Markdown in templates\n\nThe plugin introduces a new template tag: `{% markdown %}...{% endmarkdown %}` - which can be used to render Markdown in your Jinja templates.\n\n```html+jinja\n{% markdown %}\n# This will be rendered as markdown\n{% endmarkdown %}\n```\nYou can use attributes on the `{% markdown %}` tag to enable extensions and allow-list additional tags and attributes:\n```html+jinja\n{% markdown\n extensions=\"tables\"\n extra_tags=\"table thead tr th td tbody\" \n extra_attrs=\"p:id,class a:name,href\" %}\n## Markdown table\n\nFirst Header | Second Header\n------------- | -------------\nContent Cell | Content Cell\nContent Cell | Content Cell\n\n<a href=\"https://www.example.com/\" name=\"namehere\">Example</a>\n<p id=\"paragraph\" class=\"klass\">Paragraph</p>\n{% endmarkdown %}\n```\nThe `extensions=` and `extra_tags=` attributes accept a space-separated list of values.\n\nThe `extra_attrs=` attribute accepts a space-separated list of `tag:attr1,attr2` values - each tag can specify one or more attributes that should be allowed.\n\nYou can also use the `{{ render_markdown(...) }}` function, like this:\n\n```html+jinja\n{{ render_markdown(\"\"\"\n## Markdown table\n\nFirst Header | Second Header\n------------- | -------------\nContent Cell | Content Cell\nContent Cell | Content Cell\n\"\"\", extensions=[\"tables\"],\n extra_tags=[\"table\", \"thead\", \"tr\", \"th\", \"td\", \"tbody\"])) }}\n```\n\nThe `{% markdown %}` tag is recommended, as it avoids the need to `\\\"` escape quotes in your Markdown content.\n",
"bugtrack_url": null,
"license": "Apache License, Version 2.0",
"summary": "Datasette plugin for rendering Markdown",
"version": "2.2.1",
"project_urls": {
"Homepage": "https://github.com/simonw/datasette-render-markdown"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c371c504d5fa9786601f6292386bd230a641d64faf891d3d91e8481b4f082937",
"md5": "4f63cf0bd7a48868d97939f655f48c85",
"sha256": "6e72641b11568afd61e10ec2813c07661cdb1f26ce2935982b30860392bf94dc"
},
"downloads": -1,
"filename": "datasette_render_markdown-2.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4f63cf0bd7a48868d97939f655f48c85",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 10326,
"upload_time": "2023-08-15T03:11:41",
"upload_time_iso_8601": "2023-08-15T03:11:41.172862Z",
"url": "https://files.pythonhosted.org/packages/c3/71/c504d5fa9786601f6292386bd230a641d64faf891d3d91e8481b4f082937/datasette_render_markdown-2.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4f993074dc4a0129d2dbe12f8492daa392c47d927b380e9d96ffd781b22f887b",
"md5": "0b4c3ee4593bc7e90cf7fb439c2fefef",
"sha256": "97eca47769ad81a1d225a0c32efe50a2f6f54fbeaa97b883855dd0591ba5b8f5"
},
"downloads": -1,
"filename": "datasette-render-markdown-2.2.1.tar.gz",
"has_sig": false,
"md5_digest": "0b4c3ee4593bc7e90cf7fb439c2fefef",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 11876,
"upload_time": "2023-08-15T03:11:42",
"upload_time_iso_8601": "2023-08-15T03:11:42.739473Z",
"url": "https://files.pythonhosted.org/packages/4f/99/3074dc4a0129d2dbe12f8492daa392c47d927b380e9d96ffd781b22f887b/datasette-render-markdown-2.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-15 03:11:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "simonw",
"github_project": "datasette-render-markdown",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "datasette-render-markdown"
}