Skip to content

Commit 2b0c157

Browse files
ShruAgarwalabidlabsgradio-pr-bot
authored
Added an optional height and overflow scrollbar for the Markdown Component (#8528)
* scrollable-markdown-changes-added * made suggested changes * added a new story in Storybook * add changeset * add changeset * tweaks * changes * changes * revert example change * tweaks * demo changes * more tweaks * formatting --------- Co-authored-by: Abubakar Abid <[email protected]> Co-authored-by: gradio-pr-bot <[email protected]>
1 parent fd5aab1 commit 2b0c157

File tree

7 files changed

+36
-7
lines changed

7 files changed

+36
-7
lines changed

.changeset/tasty-coins-share.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@gradio/markdown": minor
3+
"gradio": minor
4+
---
5+
6+
feat:Added an optional `height` and overflow scrollbar for the Markdown Component

demo/markdown_example/run.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: markdown_example"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "css = (\n", " \"footer {display: none !important;} .gradio-container {min-height: 0px !important;}\"\n", ")\n", "\n", "# sample md stolen from https://dillinger.io/\n", "\n", "md = \"\"\"# Dillinger\n", "## _The Last Markdown Editor, Ever_\n", "\n", "This is some `inline code`, it is good.\n", "\n", "[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)](https://travis-ci.org/joemccann/dillinger)\n", "\n", "Dillinger is a cloud-enabled, mobile-ready, offline-storage compatible,\n", "AngularJS-powered HTML5 Markdown editor.\n", "\n", "- Type some Markdown on the left\n", "- See HTML in the right\n", "- \u2728Magic \u2728\n", "\n", "## Features\n", "\n", "- Import a HTML file and watch it magically convert to Markdown\n", "- Drag and drop images (requires your Dropbox account be linked)\n", "- Import and save files from GitHub, Dropbox, Google Drive and One Drive\n", "- Drag and drop markdown and HTML files into Dillinger\n", "- Export documents as Markdown, HTML and PDF\n", "\n", "Markdown is a lightweight markup language based on the formatting conventions\n", "that people naturally use in email.\n", "As [John Gruber] writes on the [Markdown site][df1]\n", "\n", "> The overriding design goal for Markdown's\n", "> formatting syntax is to make it as readable\n", "> as possible. The idea is that a\n", "> Markdown-formatted document should be\n", "> publishable as-is, as plain text, without\n", "> looking like it's been marked up with tags\n", "> or formatting instructions.\n", "\n", "This text you see here is *actually- written in Markdown! To get a feel\n", "for Markdown's syntax, type some text into the left window and\n", "watch the results in the right.\n", "\n", "## Tech\n", "\n", "Dillinger uses a number of open source projects to work properly:\n", "\n", "- [AngularJS] - HTML enhanced for web apps!\n", "- [Ace Editor] - awesome web-based text editor\n", "- [markdown-it] - Markdown parser done right. Fast and easy to extend.\n", "- [Twitter Bootstrap] - great UI boilerplate for modern web apps\n", "- [node.js] - evented I/O for the backend\n", "- [Express] - fast node.js network app framework [@tjholowaychuk]\n", "- [Gulp] - the streaming build system\n", "- [Breakdance](https://breakdance.github.io/breakdance/) - HTML\n", "to Markdown converter\n", "- [jQuery] - duh\n", "\n", "And of course Dillinger itself is open source with a [public repository][dill]\n", " on GitHub.\n", "\n", "## Installation\n", "\n", "Dillinger requires [Node.js](https://nodejs.org/) v10+ to run.\n", "\n", "Install the dependencies and devDependencies and start the server.\n", "\n", "```bash\n", "cd dillinger\n", "npm i\n", "node app\n", "```\n", "\n", "For production environments...\n", "\n", "```bash\n", "npm install --production\n", "NODE_ENV=production node app\n", "```\n", "\n", "## Plugins\n", "\n", "Dillinger is currently extended with the following plugins.\n", "Instructions on how to use them in your own application are linked below.\n", "\n", "| Plugin | README |\n", "| ------ | ------ |\n", "| Dropbox | [plugins/dropbox/README.md][PlDb] |\n", "| GitHub | [plugins/github/README.md][PlGh] |\n", "| Google Drive | [plugins/googledrive/README.md][PlGd] |\n", "| OneDrive | [plugins/onedrive/README.md][PlOd] |\n", "| Medium | [plugins/medium/README.md][PlMe] |\n", "| Google Analytics | [plugins/googleanalytics/README.md][PlGa] |\n", "\n", "## Development\n", "\n", "Want to contribute? Great!\n", "\n", "Dillinger uses Gulp + Webpack for fast developing.\n", "Make a change in your file and instantaneously see your updates!\n", "\n", "Open your favorite Terminal and run these commands.\n", "\n", "First Tab:\n", "\n", "```bash\n", "node app\n", "```\n", "\n", "Second Tab:\n", "\n", "```bash\n", "gulp watch\n", "```\n", "\n", "(optional) Third:\n", "\n", "```bash\n", "karma test\n", "```\n", "\n", "#### Building for source\n", "\n", "For production release:\n", "\n", "```bash\n", "gulp build --prod\n", "```\n", "\n", "Generating pre-built zip archives for distribution:\n", "\n", "```bash\n", "gulp build dist --prod\n", "```\n", "\n", "## Docker\n", "\n", "Dillinger is very easy to install and deploy in a Docker container.\n", "\n", "By default, the Docker will expose port 8080, so change this within the\n", "Dockerfile if necessary. When ready, simply use the Dockerfile to\n", "build the image.\n", "\n", "```bash\n", "cd dillinger\n", "docker build -t <youruser>/dillinger:${package.json.version} .\n", "```\n", "\n", "This will create the dillinger image and pull in the necessary dependencies.\n", "Be sure to swap out `${package.json.version}` with the actual\n", "version of Dillinger.\n", "\n", "Once done, run the Docker image and map the port to whatever you wish on\n", "your host. In this example, we simply map port 8000 of the host to\n", "port 8080 of the Docker (or whatever port was exposed in the Dockerfile):\n", "\n", "```bash\n", "docker run -d -p 8000:8080 --restart=always --cap-add=SYS_ADMIN --name=dillinger <youruser>/dillinger:${package.json.version}\n", "```\n", "\n", "> Note: `--capt-add=SYS-ADMIN` is required for PDF rendering.\n", "\n", "Verify the deployment by navigating to your server address in\n", "your preferred browser.\n", "\n", "```bash\n", "127.0.0.1:8000\n", "```\n", "\n", "```python\n", "import gradio as gr\n", "\n", "gr.Blocks() as demo:\n", " gr.Markdown(value=md)\n", "\n", "demo.launch()\n", "```\n", "\n", "```js\n", "function fancyAlert(arg) {\n", " if(arg) {\n", " $.facebox({div:'#foo'})\n", " }\n", "}\n", "```\n", "\n", "## License\n", "\n", "MIT\n", "\n", "**Free Software, Hell Yeah!**\n", "\n", "[//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)\n", "\n", " [dill]: <https://github.com/joemccann/dillinger>\n", " [git-repo-url]: <https://github.com/joemccann/dillinger.git>\n", " [john gruber]: <http://daringfireball.net>\n", " [df1]: <http://daringfireball.net/projects/markdown/>\n", " [markdown-it]: <https://github.com/markdown-it/markdown-it>\n", " [Ace Editor]: <http://ace.ajax.org>\n", " [node.js]: <http://nodejs.org>\n", " [Twitter Bootstrap]: <http://twitter.github.com/bootstrap/>\n", " [jQuery]: <http://jquery.com>\n", " [@tjholowaychuk]: <http://twitter.com/tjholowaychuk>\n", " [express]: <http://expressjs.com>\n", " [AngularJS]: <http://angularjs.org>\n", " [Gulp]: <http://gulpjs.com>\n", "\n", " [PlDb]: <https://github.com/joemccann/dillinger/tree/master/plugins/dropbox/README.md>\n", " [PlGh]: <https://github.com/joemccann/dillinger/tree/master/plugins/github/README.md>\n", " [PlGd]: <https://github.com/joemccann/dillinger/tree/master/plugins/googledrive/README.md>\n", " [PlOd]: <https://github.com/joemccann/dillinger/tree/master/plugins/onedrive/README.md>\n", " [PlMe]: <https://github.com/joemccann/dillinger/tree/master/plugins/medium/README.md>\n", " [PlGa]: <https://github.com/RahulHP/dillinger/blob/master/plugins/googleanalytics/README.md>\n", "\n", "\"\"\"\n", "with gr.Blocks(css=css) as demo:\n", " gr.Markdown(value=md, header_links=True)\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
1+
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: markdown_example"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "# sample md stolen from https://dillinger.io/\n", "\n", "md = \"\"\"# Dillinger\n", "## _The Last Markdown Editor, Ever_\n", "\n", "This is some `inline code`, it is good.\n", "\n", "[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)](https://travis-ci.org/joemccann/dillinger)\n", "\n", "Dillinger is a cloud-enabled, mobile-ready, offline-storage compatible,\n", "AngularJS-powered HTML5 Markdown editor.\n", "\n", "- Type some Markdown on the left\n", "- See HTML in the right\n", "- \u2728Magic \u2728\n", "\n", "## Features\n", "\n", "- Import a HTML file and watch it magically convert to Markdown\n", "- Drag and drop images (requires your Dropbox account be linked)\n", "- Import and save files from GitHub, Dropbox, Google Drive and One Drive\n", "- Drag and drop markdown and HTML files into Dillinger\n", "- Export documents as Markdown, HTML and PDF\n", "\n", "Markdown is a lightweight markup language based on the formatting conventions\n", "that people naturally use in email.\n", "As [John Gruber] writes on the [Markdown site][df1]\n", "\n", "> The overriding design goal for Markdown's\n", "> formatting syntax is to make it as readable\n", "> as possible. The idea is that a\n", "> Markdown-formatted document should be\n", "> publishable as-is, as plain text, without\n", "> looking like it's been marked up with tags\n", "> or formatting instructions.\n", "\n", "This text you see here is *actually- written in Markdown! To get a feel\n", "for Markdown's syntax, type some text into the left window and\n", "watch the results in the right.\n", "\n", "## Tech\n", "\n", "Dillinger uses a number of open source projects to work properly:\n", "\n", "- [AngularJS] - HTML enhanced for web apps!\n", "- [Ace Editor] - awesome web-based text editor\n", "- [markdown-it] - Markdown parser done right. Fast and easy to extend.\n", "- [Twitter Bootstrap] - great UI boilerplate for modern web apps\n", "- [node.js] - evented I/O for the backend\n", "- [Express] - fast node.js network app framework [@tjholowaychuk]\n", "- [Gulp] - the streaming build system\n", "- [Breakdance](https://breakdance.github.io/breakdance/) - HTML\n", "to Markdown converter\n", "- [jQuery] - duh\n", "\n", "And of course Dillinger itself is open source with a [public repository][dill]\n", " on GitHub.\n", "\n", "## Installation\n", "\n", "Dillinger requires [Node.js](https://nodejs.org/) v10+ to run.\n", "\n", "Install the dependencies and devDependencies and start the server.\n", "\n", "```bash\n", "cd dillinger\n", "npm i\n", "node app\n", "```\n", "\n", "For production environments...\n", "\n", "```bash\n", "npm install --production\n", "NODE_ENV=production node app\n", "```\n", "\n", "## Plugins\n", "\n", "Dillinger is currently extended with the following plugins.\n", "Instructions on how to use them in your own application are linked below.\n", "\n", "| Plugin | README |\n", "| ------ | ------ |\n", "| Dropbox | [plugins/dropbox/README.md][PlDb] |\n", "| GitHub | [plugins/github/README.md][PlGh] |\n", "| Google Drive | [plugins/googledrive/README.md][PlGd] |\n", "| OneDrive | [plugins/onedrive/README.md][PlOd] |\n", "| Medium | [plugins/medium/README.md][PlMe] |\n", "| Google Analytics | [plugins/googleanalytics/README.md][PlGa] |\n", "\n", "## Development\n", "\n", "Want to contribute? Great!\n", "\n", "Dillinger uses Gulp + Webpack for fast developing.\n", "Make a change in your file and instantaneously see your updates!\n", "\n", "Open your favorite Terminal and run these commands.\n", "\n", "First Tab:\n", "\n", "```bash\n", "node app\n", "```\n", "\n", "Second Tab:\n", "\n", "```bash\n", "gulp watch\n", "```\n", "\n", "(optional) Third:\n", "\n", "```bash\n", "karma test\n", "```\n", "\n", "#### Building for source\n", "\n", "For production release:\n", "\n", "```bash\n", "gulp build --prod\n", "```\n", "\n", "Generating pre-built zip archives for distribution:\n", "\n", "```bash\n", "gulp build dist --prod\n", "```\n", "\n", "## Docker\n", "\n", "Dillinger is very easy to install and deploy in a Docker container.\n", "\n", "By default, the Docker will expose port 8080, so change this within the\n", "Dockerfile if necessary. When ready, simply use the Dockerfile to\n", "build the image.\n", "\n", "```bash\n", "cd dillinger\n", "docker build -t <youruser>/dillinger:${package.json.version} .\n", "```\n", "\n", "This will create the dillinger image and pull in the necessary dependencies.\n", "Be sure to swap out `${package.json.version}` with the actual\n", "version of Dillinger.\n", "\n", "Once done, run the Docker image and map the port to whatever you wish on\n", "your host. In this example, we simply map port 8000 of the host to\n", "port 8080 of the Docker (or whatever port was exposed in the Dockerfile):\n", "\n", "```bash\n", "docker run -d -p 8000:8080 --restart=always --cap-add=SYS_ADMIN --name=dillinger <youruser>/dillinger:${package.json.version}\n", "```\n", "\n", "> Note: `--capt-add=SYS-ADMIN` is required for PDF rendering.\n", "\n", "Verify the deployment by navigating to your server address in\n", "your preferred browser.\n", "\n", "```bash\n", "127.0.0.1:8000\n", "```\n", "\n", "```python\n", "import gradio as gr\n", "\n", "gr.Blocks() as demo:\n", " gr.Markdown(value=md)\n", "\n", "demo.launch()\n", "```\n", "\n", "```js\n", "function fancyAlert(arg) {\n", " if(arg) {\n", " $.facebox({div:'#foo'})\n", " }\n", "}\n", "```\n", "\n", "## License\n", "\n", "MIT\n", "\n", "**Free Software, Hell Yeah!**\n", "\n", "[//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)\n", "\n", " [dill]: <https://github.com/joemccann/dillinger>\n", " [git-repo-url]: <https://github.com/joemccann/dillinger.git>\n", " [john gruber]: <http://daringfireball.net>\n", " [df1]: <http://daringfireball.net/projects/markdown/>\n", " [markdown-it]: <https://github.com/markdown-it/markdown-it>\n", " [Ace Editor]: <http://ace.ajax.org>\n", " [node.js]: <http://nodejs.org>\n", " [Twitter Bootstrap]: <http://twitter.github.com/bootstrap/>\n", " [jQuery]: <http://jquery.com>\n", " [@tjholowaychuk]: <http://twitter.com/tjholowaychuk>\n", " [express]: <http://expressjs.com>\n", " [AngularJS]: <http://angularjs.org>\n", " [Gulp]: <http://gulpjs.com>\n", "\n", " [PlDb]: <https://github.com/joemccann/dillinger/tree/master/plugins/dropbox/README.md>\n", " [PlGh]: <https://github.com/joemccann/dillinger/tree/master/plugins/github/README.md>\n", " [PlGd]: <https://github.com/joemccann/dillinger/tree/master/plugins/googledrive/README.md>\n", " [PlOd]: <https://github.com/joemccann/dillinger/tree/master/plugins/onedrive/README.md>\n", " [PlMe]: <https://github.com/joemccann/dillinger/tree/master/plugins/medium/README.md>\n", " [PlGa]: <https://github.com/RahulHP/dillinger/blob/master/plugins/googleanalytics/README.md>\n", "\n", "\"\"\"\n", "with gr.Blocks() as demo:\n", " gr.Markdown(value=md, header_links=True, height=400)\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}

demo/markdown_example/run.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import gradio as gr
22

3-
css = (
4-
"footer {display: none !important;} .gradio-container {min-height: 0px !important;}"
5-
)
6-
73
# sample md stolen from https://dillinger.io/
84

95
md = """# Dillinger
@@ -217,7 +213,7 @@
217213
[PlGa]: <https://github.com/RahulHP/dillinger/blob/master/plugins/googleanalytics/README.md>
218214
219215
"""
220-
with gr.Blocks(css=css) as demo:
221-
gr.Markdown(value=md, header_links=True)
216+
with gr.Blocks() as demo:
217+
gr.Markdown(value=md, header_links=True, height=400)
222218

223219
demo.launch()

gradio/components/markdown.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def __init__(
4040
sanitize_html: bool = True,
4141
line_breaks: bool = False,
4242
header_links: bool = False,
43+
height: int | str | None = None,
4344
):
4445
"""
4546
Parameters:
@@ -57,6 +58,7 @@ def __init__(
5758
sanitize_html: If False, will disable HTML sanitization when converted from markdown. This is not recommended, as it can lead to security vulnerabilities.
5859
line_breaks: If True, will enable Github-flavored Markdown line breaks in chatbot messages. If False (default), single new lines will be ignored.
5960
header_links: If True, will automatically create anchors for headings, displaying a link icon on hover.
61+
height: An optional maximum height of this component, specified in pixels if a number is passed, or in CSS units (e.g., '200px') if a stirng is passed in. If context exceeds this height, a scrollbar is added.
6062
"""
6163
self.rtl = rtl
6264
if latex_delimiters is None:
@@ -65,6 +67,7 @@ def __init__(
6567
self.sanitize_html = sanitize_html
6668
self.line_breaks = line_breaks
6769
self.header_links = header_links
70+
self.height = height
6871

6972
super().__init__(
7073
label=label,

js/markdown/Index.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
display: boolean;
3232
}[];
3333
export let header_links = false;
34+
export let height: number | string | undefined = undefined;
3435
3536
$: label, gradio.dispatch("change");
3637
</script>
@@ -61,6 +62,7 @@
6162
{sanitize_html}
6263
{line_breaks}
6364
{header_links}
65+
{height}
6466
/>
6567
</div>
6668
</Block>

js/markdown/Markdown.stories.svelte

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
description: "Whether to render right-to-left",
1313
control: { type: "boolean" },
1414
defaultValue: false
15+
},
16+
height: {
17+
description: "Maximum height of the Markdown component",
18+
control: { type: "text" },
19+
defaultValue: "200px"
1520
}
1621
}}
1722
/>
@@ -21,6 +26,7 @@
2126
value="Here's some **bold** text. And some *italics* and some `code`"
2227
latex_delimiters={[]}
2328
{...args}
29+
height={args.height}
2430
/>
2531
</Template>
2632

@@ -70,3 +76,11 @@ in two separate lines.`
7076
header_links: true
7177
}}
7278
/>
79+
80+
<Story
81+
name="Markdown with Long Content (Vertical Scrolling)"
82+
args={{
83+
value: `# Heading\n${"This is some text.\n".repeat(100)}`,
84+
height: "200px"
85+
}}
86+
/>

js/markdown/shared/Markdown.svelte

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@
1717
display: boolean;
1818
}[];
1919
export let header_links = false;
20+
export let height: number | string | undefined = undefined;
2021
2122
const dispatch = createEventDispatcher<{ change: undefined }>();
2223
24+
const css_units = (dimension_value: string | number): string => {
25+
return typeof dimension_value === "number"
26+
? dimension_value + "px"
27+
: dimension_value;
28+
};
29+
2330
$: value, dispatch("change");
2431
</script>
2532

@@ -30,6 +37,7 @@
3037
data-testid="markdown"
3138
dir={rtl ? "rtl" : "ltr"}
3239
use:copy
40+
style={height ? `max-height: ${css_units(height)}; overflow-y: auto;` : ""}
3341
>
3442
<MarkdownCode
3543
message={value}

0 commit comments

Comments
 (0)