## Markdown-2-Dash
.. toc::
:min_level: 3
Markdown-2-Dash or M2D is a standalone package forked out of source code of [official documentation of dash-mantine-components](https://www.dash-mantine-components.com).
Some form of M2D has always existed since the inception of the documentation, but I figured more people can make use of this to document their dash
apps or component libraries.
Have a look [here](https://markdown2dash.onrender.com) to see how this README would look after parsing with M2D. The render also
works perfectly with dark mode without any extra code.
.. admonition::Note
:icon: radix-icons:info-circled
:color: red
The theme switcher has been added only for this demo, its not available as part of markdown2dash.
### Installation
```bash
pip install markdown2dash
```
```bash
poetry add markdown2dash
```
.. admonition::Note
:icon: radix-icons:info-circled
:color: red
Latest dmc is based on REACT 18. You need to set REACT_VERSION=18.2.0 before starting the app.
### Quickstart
#### Parsing M2D's README
Let's start by parsing the readme of this repository with M2D.
.. admonition::Note
:icon: radix-icons:bookmark-filled
:color: yellow
Make sure to include stylesheets for all extensions you are planning to use in your app.
```python
import dash_mantine_components as dmc
from dash import Dash
from markdown2dash import parse
with open("../README.md") as f:
md = f.read()
layout = parse(md)
stylesheets = [
"https://unpkg.com/@mantine/dates@7/styles.css",
"https://unpkg.com/@mantine/code-highlight@7/styles.css",
"https://unpkg.com/@mantine/charts@7/styles.css",
"https://unpkg.com/@mantine/carousel@7/styles.css",
"https://unpkg.com/@mantine/notifications@7/styles.css",
"https://unpkg.com/@mantine/nprogress@7/styles.css",
]
app = Dash(__name__, external_stylesheets=stylesheets)
app.layout = dmc.MantineProvider(
dmc.Container(layout, size="lg", p=20),
theme={
"primaryColor": "indigo",
"colorScheme": "light",
"fontFamily": "'Inter', sans-serif",
"components": {
"Table": {"defaultProps": {"striped": True, "withTableBorder": True, "highlightOnHover": True}},
"Alert": {"styles": {"title": {"fontWeight": 500}}},
},
},
)
if __name__ == "__main__":
app.run()
```
There's no styling by default, so you'll have to provide your own css. You can do that in two ways:
1. Use MantineProvider to style your page (as you can see above)
2. Create CSS files. You can get started with the one provided in this repository: [styles.css]()
Each component rendered by M2D will have a class name attached to it.
#### Available tokens and class names
M2D can render following types of tokens:
| Token | Class Name |
|---------------------|-----------------------|
| Links | .m2d-link |
| Paragraph | .m2d-paragraph |
| Emphasis | .m2d-emphasis |
| Strong | .m2d-strong |
| Code Span | .m2d-codespan |
| Heading | .m2d-heading |
| Thematic Break | .m2d-thematic-break |
| Block Code | .m2d-block-code |
| Block Quote | .m2d-block-quote |
| List Item | .m2d-list-item |
| List | .m2d-list |
| Strikethrough | .m2d-strikethrough |
| Mark | .m2d-mark |
| Table | .m2d-table |
| Table Head | .m2d-table-head |
| Table Body | .m2d-table-body |
| Table Row | .m2d-table-row |
| Table Cell | .m2d-table-cell |
| Spoiler | .m2d-block-spoiler |
| Admonition | .m2d-block-admonition |
| Divider | .m2d-block-divider |
| Executable Block | .m2d-block-exec |
| Image | .m2d-block-image |
| Dash Component Docs | .m2d-block-kwargs |
| Source Code | .m2d-block-source |
| Table of Contents | .m2d-block-toc |
### Special Directives
M2D includes some special directives enabling you to do a lot more than just rendering static markdown into a dash layout.
The directives are all extensible, and you can just overwrite the render method to suit your own needs. The default render method is provided in all directives out of the box.
#### Executable Block
You can use the `exec` directive to embed the output of a python script as well as its source code. This directive expects that
you have stored the output layout in the variable called `component`.
```markdown
.. exec::example.navlink
```
Here's the output if you are viewing this in a dash app:
.. exec::example.navlink
You can hide the source code using the `code` argument, and the border using `border`.
```markdown
.. exec::example.navlink
:code: false
:border: false
```
#### Source Code
You can use SourceCode directive to display code from a file in your project. The path of file is relative to current working directory.
Here's the css used to style this page.
```markdown
.. source::example/assets/styles.css
:language: css
```
.. source::example/assets/styles.css
:language: css
#### Admonition
You can use `admonition` directive to add dmc.Alert components in your page.
Admonition directive uses [DashIconify]() to render icons as well.
```markdown
.. admonition::Alert Title
:icon: radix-icons:github-logo
:variant: outline
This is to show that now you can render alerts directly from the markdown.
```
Here's the output if you are viewing this in a dash app:
.. admonition::Alert Title
:icon: radix-icons:github-logo
:variant: outline
This is to show that now you can render alerts directly from the markdown.
#### Image
Render images using dmc.Image like this:
```markdown
.. image::https://www.dash-mantine-components.com/assets/superman.jpeg
:w: 300px
:h: 300px
```
Here's the output if you are viewing this in a dash app:
.. image::https://www.dash-mantine-components.com/assets/superman.jpeg
:w: 300px
:h: 300px
#### Dash Component API Docs
It's very simple to add API docs of your component using M2D. You just have to specify the package and the component.
Let's create one for DashIconify:
```markdown
.. kwargs::DashIconify
:library: dash_iconify
```
Here's the output if you are viewing this in a dash app:
.. kwargs::DashIconify
:library: dash_iconify
#### Table of Contents
This directive will parse all the headings and create a table of contents like this:
```python
# a placeholder for self and a list of [<level>, <title>, <id>]
[
(4, 'Installation', 'installation'),
(4, 'Quickstart', 'quickstart'),
(5, 'Example App', 'example-app'),
(4, 'Special Directives', 'special-directives'),
(5, 'Dash Component API Docs', 'dash-component-api-docs'),
(5, 'Table of Contents', 'table-of-contents')
]
```
This will then be used to render the TOC using the render method. You can enable TOC like this:
```markdown
.. toc::
:min_level: 3
```
#### Divider
A simple way to add dividers would be to just add `---` in your markdown file.
```markdown
---
```
---
But let's say you to add a label to the divider and also customize it. You can use the divider directive to do that.
```markdown
.. divider::Section Changed!
:labelPosition: left
.. divider::Section Changed!
.. divider::Section Changed!
:labelPosition: right
```
.. divider::Section Changed!
:labelPosition: left
.. divider::Section Changed!
.. divider::Section Changed!
:labelPosition: right
### More Examples
#### Tasks List
You can create tasks list like below and a checkbox list will be rendered automatically in your dash app.
```markdown
- [ ] Create README for library.
- [x] Resolve GitHub issues [here](https://github.com/snehilvj/dash-mantine-components).
```
- [ ] Create README for library.
- [x] Resolve GitHub issues [here](https://github.com/snehilvj/dash-mantine-components).
#### Spoiler
Create spoiler content like this:
```markdown
>! In the final moments of Dune: Part Two...
>! Why does Paul need to marry Princess Irulan...
>! In the book, we learn that a dea...
```
And this is how it will look when rendered (wrapped by dmc.Spoiler):
>! In the final moments of Dune: Part Two, Paul Atreides does two shocking things: he says he’ll marry Princess Irulan (Florence Pugh), and then, he sends his Fremen troops out into the universe to start a holy war against the great houses. This is the horrific future vision that Paul has been seeing since Dune: Part One. The Fremen and House Atreides prevail on Arrakis, but the cost is a massive war that will burn half the universe. Let's break down how this happens.
>! Why does Paul need to marry Princess Irulan to take over the throne from Emperor Shaddam IV? Because he has control of the spice on Arrakis, couldn’t he just kill everyone and marry Chani, his true love? The answer lies in the book. When Paul sees Irulan in the final pages of the book, he thinks, “There’s my key,” and on the very last page of the book, he tells Chani, “We must obey the forms.” This means that he wants to gain power within the system.
>! In the book, we learn that a deal has been made to “place a Bene Gesserit on the throne, and Irulan is the one they’ve groomed for it.” In the movie, before everything goes down in the end, Reverend Mother Gaius Helen Mohiam tells Irulan that “there’s one way your family can remain in power… are you prepared?”
#### Nested Lists
Let's try to render a mix of items in a nested list.
```markdown
1. Ingredients
- spaghetti
- marinara sauce
- salt
2. Cooking
1. Bring water to boil, add a pinch of salt and spaghetti.
2. Cook until pasta is **tender**.
3. Serve: Drain the pasta on a plate. Add heated sauce.
4. No man is lonely eating spaghetti, it requires so much attention.
```
1. Ingredients
- spaghetti
- marinara sauce
- salt
2. Cooking
1. Bring water to boil, add a pinch of salt and spaghetti.
2. Cook until pasta is **tender**.
3. Serve: Drain the pasta on a plate. Add heated sauce.
4. No man is lonely eating spaghetti, it requires so much attention.
#### Charts
You can use the exec block to add charts in your app. The following block will render a BarChart as defined in example/chart.py
```markdown
.. exec::example.chart
:code: false
:border: true
```
.. exec::example.chart
:code: false
:border: false
#### Blockquote
> Life is like npm install – you never know what you are going to get.
### Adding your own directives
You can create a new directive by extending the BaseDirective class and creating a new parser. Here's how you can add a
new directive that adds a scroll to top button in the bottom right of your app.
.. source::example/scroll.py
The associated css class name will be: `m2d-block-scroll`.
Create a new parser using your new directive like below:
```python
from markdown2dash import create_parser, DEFAULT_DIRECTIVES
parse = create_parser(DEFAULT_DIRECTIVES + [ScrollToTop()])
layout = parse(content)
```
And here's how you can use it in the markdown.
```markdown
.. scroll::
```
.. scroll::
.. exec::example.theme
:code: false
:border: false
Raw data
{
"_id": null,
"home_page": "https://github.com/snehilvj/markdown2dash",
"name": "markdown2dash",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "dash, plotly, documentation, markdown, dash-mantine-components, dmc",
"author": "Snehil Vijay",
"author_email": "snehilvj@outlook.com",
"download_url": "https://files.pythonhosted.org/packages/2d/dc/2739f103dcb7bfe9bd8075ff850ada602a445e8287e80552c493b8e9ba90/markdown2dash-0.1.1.tar.gz",
"platform": null,
"description": "## Markdown-2-Dash\n\n.. toc::\n :min_level: 3\n\nMarkdown-2-Dash or M2D is a standalone package forked out of source code of [official documentation of dash-mantine-components](https://www.dash-mantine-components.com).\nSome form of M2D has always existed since the inception of the documentation, but I figured more people can make use of this to document their dash\napps or component libraries.\n\nHave a look [here](https://markdown2dash.onrender.com) to see how this README would look after parsing with M2D. The render also\nworks perfectly with dark mode without any extra code.\n\n.. admonition::Note\n :icon: radix-icons:info-circled\n :color: red\n\n The theme switcher has been added only for this demo, its not available as part of markdown2dash.\n\n### Installation\n\n```bash\npip install markdown2dash\n```\n\n```bash\npoetry add markdown2dash\n```\n\n.. admonition::Note\n :icon: radix-icons:info-circled\n :color: red\n\n Latest dmc is based on REACT 18. You need to set REACT_VERSION=18.2.0 before starting the app. \n\n### Quickstart\n\n#### Parsing M2D's README\n\nLet's start by parsing the readme of this repository with M2D.\n\n.. admonition::Note\n :icon: radix-icons:bookmark-filled\n :color: yellow\n\n Make sure to include stylesheets for all extensions you are planning to use in your app. \n\n```python\nimport dash_mantine_components as dmc\nfrom dash import Dash\n\nfrom markdown2dash import parse\n\nwith open(\"../README.md\") as f:\n md = f.read()\n\nlayout = parse(md)\n\nstylesheets = [\n \"https://unpkg.com/@mantine/dates@7/styles.css\",\n \"https://unpkg.com/@mantine/code-highlight@7/styles.css\",\n \"https://unpkg.com/@mantine/charts@7/styles.css\",\n \"https://unpkg.com/@mantine/carousel@7/styles.css\",\n \"https://unpkg.com/@mantine/notifications@7/styles.css\",\n \"https://unpkg.com/@mantine/nprogress@7/styles.css\",\n]\n\napp = Dash(__name__, external_stylesheets=stylesheets)\n\n\napp.layout = dmc.MantineProvider(\n dmc.Container(layout, size=\"lg\", p=20),\n theme={\n \"primaryColor\": \"indigo\",\n \"colorScheme\": \"light\",\n \"fontFamily\": \"'Inter', sans-serif\",\n \"components\": {\n \"Table\": {\"defaultProps\": {\"striped\": True, \"withTableBorder\": True, \"highlightOnHover\": True}},\n \"Alert\": {\"styles\": {\"title\": {\"fontWeight\": 500}}},\n },\n },\n)\n\nif __name__ == \"__main__\":\n app.run()\n```\n\nThere's no styling by default, so you'll have to provide your own css. You can do that in two ways:\n1. Use MantineProvider to style your page (as you can see above)\n2. Create CSS files. You can get started with the one provided in this repository: [styles.css]()\n\nEach component rendered by M2D will have a class name attached to it. \n\n#### Available tokens and class names\n\nM2D can render following types of tokens:\n\n| Token | Class Name |\n|---------------------|-----------------------|\n| Links | .m2d-link |\n| Paragraph | .m2d-paragraph |\n| Emphasis | .m2d-emphasis |\n| Strong | .m2d-strong |\n| Code Span | .m2d-codespan |\n| Heading | .m2d-heading |\n| Thematic Break | .m2d-thematic-break |\n| Block Code | .m2d-block-code |\n| Block Quote | .m2d-block-quote |\n| List Item | .m2d-list-item |\n| List | .m2d-list |\n| Strikethrough | .m2d-strikethrough |\n| Mark | .m2d-mark |\n| Table | .m2d-table |\n| Table Head | .m2d-table-head |\n| Table Body | .m2d-table-body |\n| Table Row | .m2d-table-row |\n| Table Cell | .m2d-table-cell |\n| Spoiler | .m2d-block-spoiler |\n| Admonition | .m2d-block-admonition |\n| Divider | .m2d-block-divider |\n| Executable Block | .m2d-block-exec |\n| Image | .m2d-block-image |\n| Dash Component Docs | .m2d-block-kwargs |\n| Source Code | .m2d-block-source |\n| Table of Contents | .m2d-block-toc |\n\n### Special Directives\n\nM2D includes some special directives enabling you to do a lot more than just rendering static markdown into a dash layout.\n\nThe directives are all extensible, and you can just overwrite the render method to suit your own needs. The default render method is provided in all directives out of the box.\n\n#### Executable Block\n\nYou can use the `exec` directive to embed the output of a python script as well as its source code. This directive expects that \nyou have stored the output layout in the variable called `component`.\n\n```markdown\n.. exec::example.navlink\n```\n\nHere's the output if you are viewing this in a dash app:\n\n.. exec::example.navlink\n\nYou can hide the source code using the `code` argument, and the border using `border`.\n\n```markdown\n.. exec::example.navlink\n :code: false\n :border: false\n```\n\n#### Source Code\n\nYou can use SourceCode directive to display code from a file in your project. The path of file is relative to current working directory.\n\nHere's the css used to style this page.\n\n```markdown\n.. source::example/assets/styles.css\n :language: css\n```\n\n.. source::example/assets/styles.css\n :language: css\n\n#### Admonition\n\nYou can use `admonition` directive to add dmc.Alert components in your page.\nAdmonition directive uses [DashIconify]() to render icons as well.\n\n```markdown\n.. admonition::Alert Title\n :icon: radix-icons:github-logo\n :variant: outline\n \n This is to show that now you can render alerts directly from the markdown.\n```\n\nHere's the output if you are viewing this in a dash app:\n\n.. admonition::Alert Title\n :icon: radix-icons:github-logo\n :variant: outline\n\n This is to show that now you can render alerts directly from the markdown.\n\n#### Image\n\nRender images using dmc.Image like this:\n\n```markdown\n.. image::https://www.dash-mantine-components.com/assets/superman.jpeg\n :w: 300px\n :h: 300px\n```\n\nHere's the output if you are viewing this in a dash app:\n\n.. image::https://www.dash-mantine-components.com/assets/superman.jpeg\n :w: 300px\n :h: 300px\n\n#### Dash Component API Docs\n\nIt's very simple to add API docs of your component using M2D. You just have to specify the package and the component.\nLet's create one for DashIconify:\n\n```markdown\n.. kwargs::DashIconify\n :library: dash_iconify\n```\n\nHere's the output if you are viewing this in a dash app:\n\n.. kwargs::DashIconify\n :library: dash_iconify\n \n#### Table of Contents\n\nThis directive will parse all the headings and create a table of contents like this:\n\n```python\n\n# a placeholder for self and a list of [<level>, <title>, <id>]\n[\n (4, 'Installation', 'installation'),\n (4, 'Quickstart', 'quickstart'), \n (5, 'Example App', 'example-app'),\n (4, 'Special Directives', 'special-directives'),\n (5, 'Dash Component API Docs', 'dash-component-api-docs'),\n (5, 'Table of Contents', 'table-of-contents')\n]\n```\n\nThis will then be used to render the TOC using the render method. You can enable TOC like this:\n\n```markdown\n.. toc::\n :min_level: 3\n```\n\n#### Divider\n\nA simple way to add dividers would be to just add `---` in your markdown file.\n\n```markdown\n---\n```\n\n---\n\nBut let's say you to add a label to the divider and also customize it. You can use the divider directive to do that.\n\n```markdown\n.. divider::Section Changed!\n :labelPosition: left\n\n.. divider::Section Changed!\n\n.. divider::Section Changed!\n :labelPosition: right\n```\n\n.. divider::Section Changed!\n :labelPosition: left\n\n.. divider::Section Changed!\n\n.. divider::Section Changed!\n :labelPosition: right\n\n### More Examples\n\n#### Tasks List\n\nYou can create tasks list like below and a checkbox list will be rendered automatically in your dash app.\n\n```markdown\n- [ ] Create README for library.\n- [x] Resolve GitHub issues [here](https://github.com/snehilvj/dash-mantine-components).\n```\n\n- [ ] Create README for library.\n- [x] Resolve GitHub issues [here](https://github.com/snehilvj/dash-mantine-components).\n\n#### Spoiler\n\nCreate spoiler content like this:\n\n```markdown\n>! In the final moments of Dune: Part Two...\n>! Why does Paul need to marry Princess Irulan...\n>! In the book, we learn that a dea...\n```\n\nAnd this is how it will look when rendered (wrapped by dmc.Spoiler):\n\n>! In the final moments of Dune: Part Two, Paul Atreides does two shocking things: he says he\u2019ll marry Princess Irulan (Florence Pugh), and then, he sends his Fremen troops out into the universe to start a holy war against the great houses. This is the horrific future vision that Paul has been seeing since Dune: Part One. The Fremen and House Atreides prevail on Arrakis, but the cost is a massive war that will burn half the universe. Let's break down how this happens.\n>! Why does Paul need to marry Princess Irulan to take over the throne from Emperor Shaddam IV? Because he has control of the spice on Arrakis, couldn\u2019t he just kill everyone and marry Chani, his true love? The answer lies in the book. When Paul sees Irulan in the final pages of the book, he thinks, \u201cThere\u2019s my key,\u201d and on the very last page of the book, he tells Chani, \u201cWe must obey the forms.\u201d This means that he wants to gain power within the system.\n>! In the book, we learn that a deal has been made to \u201cplace a Bene Gesserit on the throne, and Irulan is the one they\u2019ve groomed for it.\u201d In the movie, before everything goes down in the end, Reverend Mother Gaius Helen Mohiam tells Irulan that \u201cthere\u2019s one way your family can remain in power\u2026 are you prepared?\u201d\n\n#### Nested Lists\n\nLet's try to render a mix of items in a nested list.\n\n```markdown\n1. Ingredients\n - spaghetti\n - marinara sauce\n - salt\n2. Cooking\n 1. Bring water to boil, add a pinch of salt and spaghetti.\n 2. Cook until pasta is **tender**.\n3. Serve: Drain the pasta on a plate. Add heated sauce.\n4. No man is lonely eating spaghetti, it requires so much attention.\n```\n\n1. Ingredients\n - spaghetti\n - marinara sauce\n - salt\n2. Cooking\n 1. Bring water to boil, add a pinch of salt and spaghetti.\n 2. Cook until pasta is **tender**.\n3. Serve: Drain the pasta on a plate. Add heated sauce.\n4. No man is lonely eating spaghetti, it requires so much attention.\n\n#### Charts\n\nYou can use the exec block to add charts in your app. The following block will render a BarChart as defined in example/chart.py\n\n```markdown\n.. exec::example.chart\n :code: false\n :border: true\n```\n\n.. exec::example.chart\n :code: false\n :border: false\n\n#### Blockquote\n\n> Life is like npm install \u2013 you never know what you are going to get.\n\n### Adding your own directives\n\nYou can create a new directive by extending the BaseDirective class and creating a new parser. Here's how you can add a\nnew directive that adds a scroll to top button in the bottom right of your app.\n\n.. source::example/scroll.py\n\nThe associated css class name will be: `m2d-block-scroll`.\n\nCreate a new parser using your new directive like below:\n\n```python\nfrom markdown2dash import create_parser, DEFAULT_DIRECTIVES\n\nparse = create_parser(DEFAULT_DIRECTIVES + [ScrollToTop()])\nlayout = parse(content)\n```\nAnd here's how you can use it in the markdown.\n\n```markdown\n.. scroll::\n```\n\n.. scroll::\n\n.. exec::example.theme\n :code: false\n :border: false\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Render markdown into a dash layout using dash-mantine-components",
"version": "0.1.1",
"project_urls": {
"Documentation": "https://github.com/snehilvj/markdown2dash",
"Homepage": "https://github.com/snehilvj/markdown2dash",
"Repository": "https://github.com/snehilvj/markdown2dash"
},
"split_keywords": [
"dash",
" plotly",
" documentation",
" markdown",
" dash-mantine-components",
" dmc"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8ea6f5b8181493c17183bbf4094edf221fc7ed6b2348243b17eae272be8faad9",
"md5": "1fba2c9568f846dc8541a108523d429f",
"sha256": "05d2de4021231f26040847c86cc1bfb03e4fd5b80526b1455343203fb7cb200f"
},
"downloads": -1,
"filename": "markdown2dash-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1fba2c9568f846dc8541a108523d429f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 13908,
"upload_time": "2024-04-16T12:10:01",
"upload_time_iso_8601": "2024-04-16T12:10:01.499299Z",
"url": "https://files.pythonhosted.org/packages/8e/a6/f5b8181493c17183bbf4094edf221fc7ed6b2348243b17eae272be8faad9/markdown2dash-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2ddc2739f103dcb7bfe9bd8075ff850ada602a445e8287e80552c493b8e9ba90",
"md5": "3abc9216f82689d323cf82381effc7fd",
"sha256": "611fa095b48a27461751b2c0720bfbb44a188af1ff05bf51eb5bc0f49dd9a075"
},
"downloads": -1,
"filename": "markdown2dash-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "3abc9216f82689d323cf82381effc7fd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 15271,
"upload_time": "2024-04-16T12:10:04",
"upload_time_iso_8601": "2024-04-16T12:10:04.083348Z",
"url": "https://files.pythonhosted.org/packages/2d/dc/2739f103dcb7bfe9bd8075ff850ada602a445e8287e80552c493b8e9ba90/markdown2dash-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-16 12:10:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "snehilvj",
"github_project": "markdown2dash",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "certifi",
"specs": [
[
"==",
"2024.2.2"
]
]
},
{
"name": "charset-normalizer",
"specs": [
[
"==",
"3.3.2"
]
]
},
{
"name": "click",
"specs": [
[
"==",
"8.1.7"
]
]
},
{
"name": "colorama",
"specs": [
[
"==",
"0.4.6"
]
]
},
{
"name": "dash-core-components",
"specs": [
[
"==",
"2.0.0"
]
]
},
{
"name": "dash-html-components",
"specs": [
[
"==",
"2.0.0"
]
]
},
{
"name": "dash-iconify",
"specs": [
[
"==",
"0.1.2"
]
]
},
{
"name": "dash-mantine-components",
"specs": [
[
"==",
"0.14.0"
]
]
},
{
"name": "dash-table",
"specs": [
[
"==",
"5.0.0"
]
]
},
{
"name": "dash",
"specs": [
[
"==",
"2.15.0"
]
]
},
{
"name": "flask",
"specs": [
[
"==",
"2.2.5"
]
]
},
{
"name": "gunicorn",
"specs": [
[
"==",
"21.2.0"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.7"
]
]
},
{
"name": "importlib-metadata",
"specs": [
[
"==",
"6.7.0"
]
]
},
{
"name": "itsdangerous",
"specs": [
[
"==",
"2.1.2"
]
]
},
{
"name": "jinja2",
"specs": [
[
"==",
"3.1.3"
]
]
},
{
"name": "jsonpath",
"specs": [
[
"==",
"0.82.2"
]
]
},
{
"name": "markupsafe",
"specs": [
[
"==",
"2.1.5"
]
]
},
{
"name": "mistune",
"specs": [
[
"==",
"3.0.2"
]
]
},
{
"name": "nest-asyncio",
"specs": [
[
"==",
"1.6.0"
]
]
},
{
"name": "packaging",
"specs": [
[
"==",
"24.0"
]
]
},
{
"name": "plotly",
"specs": [
[
"==",
"5.18.0"
]
]
},
{
"name": "requests",
"specs": [
[
"==",
"2.31.0"
]
]
},
{
"name": "retrying",
"specs": [
[
"==",
"1.3.4"
]
]
},
{
"name": "six",
"specs": [
[
"==",
"1.16.0"
]
]
},
{
"name": "tenacity",
"specs": [
[
"==",
"8.2.3"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
"==",
"4.7.1"
]
]
},
{
"name": "urllib3",
"specs": [
[
"==",
"2.0.7"
]
]
},
{
"name": "werkzeug",
"specs": [
[
"==",
"2.2.3"
]
]
},
{
"name": "zipp",
"specs": [
[
"==",
"3.15.0"
]
]
}
],
"lcname": "markdown2dash"
}