60行Python代码开发在线markdown编辑器

本文转载自公众号【python大数据分析】,详情可以点击上方卡片,关注该公众号,获取更多好文推荐。

本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes

1 简介

这是我的系列教程**「Python+Dash快速web应用开发」的第六期,在上一期的文章中,我们完成了对Dash中回调交互高级特性的探讨,在今后陆续推出的教程内容中,我们将一起来学习Dash生态中那些丰富的「页面部件」**,从而赋予我们打造各种强大交互式web应用的能力。

而在今天的教程内容中,我将带大家学习Dash中实用的一些基础性的**「静态部件」,它们可以帮助我们打造更加正式的web应用,并在最后教大家如何仅仅60行代码就开发出一个在线markdown编辑器**。

图1

2 Dash中的基础静态部件

我们在这里所说的静态页面部件,主要指的是其本身不具备直接的交互功能,而是以**「呈现内容」**为主要功能,就像下面的简单对比一样:

app1.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4import dash_core_components as dcc 5 6app = dash.Dash(__name__) 7 8app.layout = html.Div( 9    dbc.Container( 10        [ 11            html.Br(), 12            html.H1('静态部件示例'), 13            html.Hr(), 14            html.H2('这是二级标题'), 15            html.H3('这是三级标题'), 16            html.H4('这是四级标题'), 17            html.P( 18                [ 19                    '这是一个', 20                    html.A('链接', href='#'), 21                    ',而这是一段', 22                    html.Strong('加粗文字'), 23                    ',这是一段带上下标的文字:', 24                    '测试', 25                    html.Sup('上标'), 26                    ',测试', 27                    html.Sub('下标') 28                ] 29            ), 30 31            html.Br(), 32            html.H1('交互部件示例'), 33            html.Br(), 34            dcc.Dropdown( 35                options=[ 36                    {'label': '测试1', 'value': '测试1'}, 37                    {'label': '测试2', 'value': '测试2'}, 38                    {'label': '测试3', 'value': '测试3'}, 39                ]), 40            html.Br(), 41            dcc.Checklist( 42                options=[ 43                    {'label': '测试1', 'value': '测试1'}, 44                    {'label': '测试2', 'value': '测试2'}, 45                    {'label': '测试3', 'value': '测试3'}, 46                ], 47                value=['测试1'] 48            ), 49            html.Br(), 50            dcc.RangeSlider( 51                min=0, 52                max=20, 53                step=0.5, 54                value=[5, 15] 55            ) 56        ] 57    ) 58) 59 60if __name__ == '__main__': 61    app.run_server(debug=True) 62

图2

可以看到,静态部件其实就是我们平时浏览网页看到的各种内容元素,他们本身不直接承担回调交互功能,只能配合其他交互部件来实现交互功能。

2.1 Dash中常用的基础静态部件

Dash中所集成的一些常用基础性静态部件,其实就是对一些常见html元素的迁移,对应着dash_html_components中封装的众多类,这里我们只介绍部分比较常用的:

2.1.1 与文字格式相关的常用部件

首先我们来介绍Dash众多基础静态部件中,与组织页面或文字格式相关的一些:

  • 「H1()到H6()」

dash_html_components中,H1()H6()分别对应着1级到6级标题。

  • 「Br()与Hr()」

dash_html_components中的Br()表示换行,而Hr()则表示水平分割线,这在我们布局元素时经常使用到。

  • 「P()」

P()用于表示一段文字或内容,典型如我们在博客中看到的每一段落内容都是由P()标签所组织的,配合css中的text-indent属性可以用来设置首行缩进。

  • 「A()」

A()用于表示一个可点击的链接,其参数href用于填入对应跳转的地址,也可以配合id,实现点击重新定位到页面内的其它元素,其target参数用于设置跳转方式,譬如target="_blank"会在新标签页跳转打开,具体内容可参考(https://www.w3school.com.cn/tags/att\_a\_target.asp)。

  • 「I()、Code()、U()、Mark()」

I()主要用于在段落中将包裹的文字内容变为斜体,Code()用于在一段文字中表示代码片段U()用于给所包含内容添加下划线,Mark()则用于高亮标注文字。

以上所介绍的这些静态部件可以通过下面的小例子直观的感受一下:

app2.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        [ 10            html.H1('一级标题', id='demo1'), 11            html.H2('二级标题'), 12            html.H3('三级标题'), 13            html.H4('四级标题'), 14            html.H5('五级标题'), 15            html.H6('六级标题'), 16            html.Br(), # 换行 17            html.Hr(), # 水平分割线 18            html.P('这是一段文字。'*20), 19            html.P('这是另一段带有首行缩进的文字。'*10, style={'text-indent': '3rem'}), 20            html.A('跳转到费弗里的Github仓库', 21                   target='_blank', 22                   href='https://github.com/CNFeffery/DataScienceStudyNotes'), # 跳转到外部链接 23            html.Br(), 24            html.A('跳转到六级标题', href='#demo2'), 25            html.P( 26                [ 27                    '一段文字中出现了', 28                    html.I('斜体'), 29                    ',以及代码片段', 30                    html.Code('import dash'), 31                    ',还有一段', 32                    html.U('带下划线的文字'), 33                    ',一段', 34                    html.Mark('高亮标注文字'), 35                    ',以及另一段', 36                    html.Mark('不同颜色的高亮标注文字。', style={'background-color': 'lightblue'}) 37                 ] 38            ) 39        ] + [html.Br()] * 50 + [html.A('回到顶端一级标题', href='#demo1'), 40                                html.H1('页内元素跳转示例标题', id='demo2')] 41    ) 42) 43 44 45if __name__ == '__main__': 46    app.run_server(debug=True)

图3

2.1.2 与内容组织相关的常用部件

前面我们针对常用的一些与文字格式相关的静态部件进行了介绍,而在实际应用中我们不仅要展示文字内容,还需要展示图片、音频、视频等多媒体内容,下面我们来学习如何在Dash中构造更加丰富的内容展示形式:

  • 「基于Blockquote()实现块引用」

利用dash_html_components中的Blockquote(),我们可以直接传入字符串,或嵌套其他元素,从而构造出块引用,就像markdown中的>所包含渲染的内容那样,参考下面的例子:

app3.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        html.Blockquote( 10            html.P('这是一段由块引用包裹的文字内容' * 10), 11            style={ 12                'background-color': 'rgba(211, 211, 211, 0.25)', 13                'text-indent': '3rem' 14            } 15        ) 16    ) 17) 18 19if __name__ == "__main__": 20    app.run_server(debug=True) 21

图4

  • 「基于Ol()与Li()渲染有序列表」

利用Ol()嵌套多个Li(),可以自动渲染出带序号的有序列表,就像下面这个简单的例子:

app4.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        html.Ol( 10            [ 11                html.Br(), 12                html.Br(), 13                html.Li('待办事项1'), 14                html.Li('待办事项2'), 15                html.Li('待办事项3'), 16                html.Li('待办事项4') 17            ] 18        ) 19    ) 20) 21 22if __name__ == "__main__": 23    app.run_server(debug=True) 24

图5

  • 「基于Ul()与Li()渲染层级列表」

而除了与Ol()相互配合之外,Li()还可以嵌套在Ul()中渲染带层级关系的列表:

app5.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        html.Ul( 10            [ 11                html.Br(), 12                html.Br(), 13                html.Li('1'), 14                html.Li('2'), 15                html.Ul( 16                    [ 17                        html.Li('2.1'), 18                        html.Li('2.2'), 19                        html.Li('2.3'), 20                        html.Ul( 21                            [ 22                                html.Li('2.1.1'), 23                                html.Li('2.1.2'), 24                                html.Li('2.1.3'), 25                            ] 26                        ) 27                    ] 28                ), 29                html.Li('3'), 30                html.Li('4') 31            ] 32        ) 33    ) 34) 35 36if __name__ == "__main__": 37    app.run_server(debug=True) 38

图6

  • 「利用Img()渲染图片」

Img()等价于html中的img标签,我们通过src参数传入图片地址来渲染出图片,以我以前一篇博客的作品图片为例:

app6.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        [ 10            html.H5('(在模仿中精进数据可视化05)疫情期间市值增长top25公司'), 11            html.Img(src='https://img2020.cnblogs.com/blog/1344061/202011/1344061-20201129183046286-1089258422.png', 12                     style={'width': '100%'}) 13        ] 14    ) 15) 16 17if __name__ == "__main__": 18    app.run_server(debug=True) 19

图7

  • 「利用Audio()与Video()播放音频与视频」

利用Audio()Video(),我们可以通过参数src传入对应音频与视频文件的url地址,从而实现在网页中嵌入音频与视频,其中参数controls必须设置为True否则不会正常渲染:

app7.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        [ 10            html.H5('音频示例:'), 11            html.Audio(src='https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3', 12                       controls=True), 13            html.H5('视频示例:'), 14            html.Video(src='https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4', 15                       controls=True, 16                       style={'width': '100%'}), 17        ] 18    ) 19) 20 21if __name__ == "__main__": 22    app.run_server(debug=True) 23

图8

  • 「利用Iframe()嵌入其他网页」

类似iframe标签,我们也可以利用Iframe()来在网页中嵌入其他网页,可以通过src参数直接传入目标网页url,也可以通过srcDoc参数传入整个网页的html源码字符串:

app8.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4 5app = dash.Dash(__name__) 6 7app.layout = html.Div( 8    dbc.Container( 9        [ 10            html.Iframe(src='https://www.baidu.com/', 11                        style={'width': '100%', 'height': '800px'}) 12        ] 13    ) 14) 15 16if __name__ == "__main__": 17    app.run_server(debug=True) 18

图9

  • 「利用Textarea()构造输入框」

有时候我们需要构造出一个能供用户输入大段文字的输入框,譬如很多的在线编辑器,而在Dash中我们可以使用dash_core_components中的Textarea()来实现这个功能,并且dcc.Textarea()同样具有valueplaceholder属性,可以配合回调函数实现很多功能。

譬如下面的例子中我们编写了一个简单的脏话和谐工具,会将用户输入的所有他妈替换为“**”😁:

app9.py

1import dash 2import dash_html_components as html 3import dash_bootstrap_components as dbc 4import dash_core_components as dcc 5from dash.dependencies import Input, Output 6 7app = dash.Dash(__name__) 8 9app.layout = html.Div( 10    dbc.Container( 11        [ 12            html.Br(), 13            dcc.Textarea(style={'width': '100%', 'height': '300px'}, 14                         id='input', 15                         value='', 16                         placeholder='请输入文字内容!'), 17            html.P(id='output') 18        ] 19    ) 20) 21 22@app.callback( 23    Output('output', 'children'), 24    Input('input', 'value') 25) 26def mask_dirty_talk(value): 27 28    return value.replace('他妈', '**') 29 30 31if __name__ == "__main__": 32    app.run_server(debug=True) 33

图10

2.2 dcc.Markdown()——Dash中特殊的静态部件

Dash中还存在一个比较特别的用于呈现静态内容的部件——dcc.Markdown(),它的children参数接受markdown代码,并自动在网页中呈现出渲染后的效果,其主要参数如下:

「children」:字符型markdown源码

「dangerously_allow_html」:bool型,用于设置是否允许解析出markdown源码中的html代码并渲染,默认为False即不进行渲染

「dedent」:bool型,用于设置是否忽略每行文字开头的代码,默认为True

效果如下:

app10.py

1import dash 2import dash_core_components as dcc 3import dash_html_components as html 4import dash_bootstrap_components as dbc 5 6app = dash.Dash(__name__) 7 8app.layout = html.Div( 9    dbc.Container( 10        [ 11            dcc.Markdown(''' 12> 本文示例代码已上传至我的`Github`仓库[https://github.com/CNFeffery/DataScienceStudyNotes](https://github.com/CNFeffery/DataScienceStudyNotes) 13 141 简介 15 16   这是我的系列教程**Python+Dash快速web应用开发**的第五期,在上一期的文章中,我们针对`Dash`中有关回调的一些技巧性的特性进行了介绍,使得我们可以更愉快地为`Dash`应用编写回调交互功能。 17 18  而今天的文章作为**回调交互**系统性内容的最后一期,我将带大家get一些`Dash`中实际应用效果惊人的**高级回调特性**,系好安全带,我们起飞~ 19 20<p align="center"><img src="https://img2020.cnblogs.com/blog/1344061/202102/1344061-20210207194037614-808613819.png" style="zoom:100%;" /></p> 21 22''', 23                         dangerously_allow_html=True, 24                         dedent=False) 25        ] 26    ) 27) 28 29if __name__ == "__main__": 30    app.run_server(debug=True) 31

图11

有了Markdown()部件的加持,我们就可以在某些情况下直接利用markdown快速编写网页,譬如编写在线文档说明页面~

3 利用Dash自制在线Markdown编辑器

在掌握了今天的教程所涉及知识之后,我们就可以自己动手书写一些具有实际交互功能的界面,譬如自制一个在线Markdown编辑器。

思路很简单,利用今天所学的Textarea()部件的value属性作为回调的Input(),再将Markdown()部件的children元素作为回调的Output(),再略微美化一下布局,便实现了如下的效果~

图12

对应的代码如下:

app11.py

1import dash 2import dash_html_components as html 3import dash_core_components as dcc 4import dash_bootstrap_components as dbc 5from dash.dependencies import Input, Output 6 7app = dash.Dash(__name__) 8 9app.layout = html.Div( 10    dbc.Container( 11        dbc.Row( 12            [ 13                dbc.Col( 14                    dcc.Textarea( 15                        id='md-input', 16                        placeholder='请输入你的markdown源码!', 17                        style={ 18                            'width': '100%', 19                            'height': '100%' 20                        } 21                    ), 22                    width=6, 23                    style={ 24                        'padding-right': 0, 25                        'border': 'border:5px solid red' 26                    } 27                ), 28                dbc.Col( 29                    dcc.Markdown(id='md-output', 30                                 dangerously_allow_html=True, 31                                 style={ 32                                     'position': 'absolute', 33                                     'width': '100%', 34                                     'height': '100%' 35                                 }), 36                    width=6, 37                    style={ 38                        'position': 'relative', 39                        'overflow': 'auto', 40                        'padding-left': 0 41                    } 42                ), 43            ], 44            style={ 45                'position': 'fixed', 46                'top': 0, 47                'bottom': 0, 48                'left': 0, 49                'right': 0 50            } 51        ) 52    ), 53    style={ 54        'font-size': '2rem' 55    } 56) 57 58@app.callback( 59    Output('md-output', 'children'), 60    Input('md-input', 'value') 61) 62def online_markdown(raw_text): 63    return raw_text 64 65if __name__ == '__main__': 66    app.run_server(debug=True) 67

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/B1PMlshXkF9jkBfgWUCeqg,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )