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

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

1 简介

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

图1

2 Dash中的基础静态部件

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

app1.py

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_core_components as dcc

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        [
            html.Br(),
            html.H1('静态部件示例'),
            html.Hr(),
            html.H2('这是二级标题'),
            html.H3('这是三级标题'),
            html.H4('这是四级标题'),
            html.P(
                [
                    '这是一个',
                    html.A('链接', href='#'),
                    ',而这是一段',
                    html.Strong('加粗文字'),
                    ',这是一段带上下标的文字:',
                    '测试',
                    html.Sup('上标'),
                    ',测试',
                    html.Sub('下标')
                ]
            ),

html.Br(),
            html.H1('交互部件示例'),
            html.Br(),
            dcc.Dropdown(
                options=[
                    {'label': '测试1', 'value': '测试1'},
                    {'label': '测试2', 'value': '测试2'},
                    {'label': '测试3', 'value': '测试3'},
                ]),
            html.Br(),
            dcc.Checklist(
                options=[
                    {'label': '测试1', 'value': '测试1'},
                    {'label': '测试2', 'value': '测试2'},
                    {'label': '测试3', 'value': '测试3'},
                ],
                value=['测试1']
            ),
            html.Br(),
            dcc.RangeSlider(
                min=0,
                max=20,
                step=0.5,
                value=[5, 15]
            )
        ]
    )
)

if __name__ == '__main__':
    app.run_server(debug=True)

图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

import dashimport dash_html_components as htmlimport dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(    dbc.Container(        [            html.H1('一级标题', id='demo1'),            html.H2('二级标题'),            html.H3('三级标题'),            html.H4('四级标题'),            html.H5('五级标题'),            html.H6('六级标题'),            html.Br(), # 换行            html.Hr(), # 水平分割线            html.P('这是一段文字。'*20),            html.P('这是另一段带有首行缩进的文字。'*10, style={'text-indent': '3rem'}),            html.A('跳转到费弗里的Github仓库',                   target='_blank',                   href='https://github.com/CNFeffery/DataScienceStudyNotes'), # 跳转到外部链接            html.Br(),            html.A('跳转到六级标题', href='#demo2'),            html.P(                [                    '一段文字中出现了',                    html.I('斜体'),                    ',以及代码片段',                    html.Code('import dash'),                    ',还有一段',                    html.U('带下划线的文字'),                    ',一段',                    html.Mark('高亮标注文字'),                    ',以及另一段',                    html.Mark('不同颜色的高亮标注文字。', style={'background-color': 'lightblue'})                 ]            )        ] + [html.Br()] * 50 + [html.A('回到顶端一级标题', href='#demo1'),                                html.H1('页内元素跳转示例标题', id='demo2')]    ))

if __name__ == '__main__':    app.run_server(debug=True)

图3

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

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

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

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

app3.py

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        html.Blockquote(
            html.P('这是一段由块引用包裹的文字内容' * 10),
            style={
                'background-color': 'rgba(211, 211, 211, 0.25)',
                'text-indent': '3rem'
            }
        )
    )
)

if __name__ == '__main__':
    app.run_server(debug=True)

图4

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

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

app4.py

import dashimport dash_html_components as htmlimport dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(    dbc.Container(        html.Ol(            [                html.Br(),                html.Br(),                html.Li('待办事项1'),                html.Li('待办事项2'),                html.Li('待办事项3'),                html.Li('待办事项4')            ]        )    ))

if __name__ == '__main__':    app.run_server(debug=True)

图5

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

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

app5.py

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        html.Ul(
            [
                html.Br(),
                html.Br(),
                html.Li('1'),
                html.Li('2'),
                html.Ul(
                    [
                        html.Li('2.1'),
                        html.Li('2.2'),
                        html.Li('2.3'),
                        html.Ul(
                            [
                                html.Li('2.1.1'),
                                html.Li('2.1.2'),
                                html.Li('2.1.3'),
                            ]
                        )
                    ]
                ),
                html.Li('3'),
                html.Li('4')
            ]
        )
    )
)

if __name__ == '__main__':
    app.run_server(debug=True)

图6

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

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

app6.py

import dashimport dash_html_components as htmlimport dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(    dbc.Container(        [            html.H5('(在模仿中精进数据可视化05)疫情期间市值增长top25公司'),            html.Img(src='https://img2020.cnblogs.com/blog/1344061/202011/1344061-20201129183046286-1089258422.png',                     style={'width': '100%'})        ]    ))

if __name__ == '__main__':    app.run_server(debug=True)

图7

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

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

app7.py

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        [
            html.H5('音频示例:'),
            html.Audio(src='https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3',
                       controls=True),
            html.H5('视频示例:'),
            html.Video(src='https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4',
                       controls=True,
                       style={'width': '100%'}),
        ]
    )
)

if __name__ == '__main__':
    app.run_server(debug=True)

图8

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

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

app8.py

import dashimport dash_html_components as htmlimport dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(    dbc.Container(        [            html.Iframe(src='https://www.baidu.com/',                        style={'width': '100%', 'height': '800px'})        ]    ))

if __name__ == '__main__':    app.run_server(debug=True)

图9

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

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

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

app9.py

import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_core_components as dcc
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        [
            html.Br(),
            dcc.Textarea(style={'width': '100%', 'height': '300px'},
                         id='input',
                         value='',
                         placeholder='请输入文字内容!'),
            html.P(id='output')
        ]
    )
)

@app.callback(
    Output('output', 'children'),
    Input('input', 'value')
)
def mask_dirty_talk(value):

return value.replace('他妈', '**')

if __name__ == '__main__':
    app.run_server(debug=True)

图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

import dashimport dash_core_components as dccimport dash_html_components as htmlimport dash_bootstrap_components as dbc

app = dash.Dash(__name__)

app.layout = html.Div(    dbc.Container(        [            dcc.Markdown('''> 本文示例代码已上传至我的`Github`仓库[https://github.com/CNFeffery/DataScienceStudyNotes](https://github.com/CNFeffery/DataScienceStudyNotes)

# 1 简介

   这是我的系列教程**Python+Dash快速web应用开发**的第五期,在上一期的文章中,我们针对`Dash`中有关回调的一些技巧性的特性进行了介绍,使得我们可以更愉快地为`Dash`应用编写回调交互功能。

  而今天的文章作为**回调交互**系统性内容的最后一期,我将带大家get一些`Dash`中实际应用效果惊人的**高级回调特性**,系好安全带,我们起飞~

<p align='center'><img src='https://img2020.cnblogs.com/blog/1344061/202102/1344061-20210207194037614-808613819.png' style='zoom:100%;' /></p>

''',                         dangerously_allow_html=True,                         dedent=False)        ]    ))

if __name__ == '__main__':    app.run_server(debug=True)

图11

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

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

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

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

图12

对应的代码如下:

app11.py

import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.layout = html.Div(
    dbc.Container(
        dbc.Row(
            [
                dbc.Col(
                    dcc.Textarea(
                        id='md-input',
                        placeholder='请输入你的markdown源码!',
                        style={
                            'width': '100%',
                            'height': '100%'
                        }
                    ),
                    width=6,
                    style={
                        'padding-right': 0,
                        'border': 'border:5px solid red'
                    }
                ),
                dbc.Col(
                    dcc.Markdown(id='md-output',
                                 dangerously_allow_html=True,
                                 style={
                                     'position': 'absolute',
                                     'width': '100%',
                                     'height': '100%'
                                 }),
                    width=6,
                    style={
                        'position': 'relative',
                        'overflow': 'auto',
                        'padding-left': 0
                    }
                ),
            ],
            style={
                'position': 'fixed',
                'top': 0,
                'bottom': 0,
                'left': 0,
                'right': 0
            }
        )
    ),
    style={
        'font-size': '2rem'
    }
)

@app.callback(
    Output('md-output', 'children'),
    Input('md-input', 'value')
)
def online_markdown(raw_text):
    return raw_text

if __name__ == '__main__':
    app.run_server(debug=True)


以上就是本文的全部内容,我们将在下一篇教程中继续探讨Dash中那些更加好用且功能更加丰富的静态部件,敬请期待~ 也欢迎大家在评论区与我进行讨论~

----------  END  ----------

教授个人微信

一个值得探索的地方

(0)

相关推荐

  • 30行Python代码实现蚂蚁森林自动偷能量(附源码)

    虽然我支付宝加了好多好友,平时有很多能量可以偷,但由于太懒,至今一棵树都没种成,所以心心念念把偷能量这事自动化.之前通过用代码模拟手机点按的方式,实现了 朋友圈自动点赞,但当时蚂蚁森林的操作流程要比朋 ...

  • 什么,3行Python代码就能获取海量数据?

    Python爬虫与数据挖掘 1周前 以下文章来源于法纳斯特 ,作者小F 本文转载自公众号[法纳斯特],详情可以点击上方卡片,关注该公众号,获取更多好文推荐. 一谈起数据分析,首先想到的就是数据,没有数 ...

  • 6行python代码的爱心线

    前些日子在做绩效体系的时候,遇到了一件囧事,居然忘记怎样在Excel上拟合正态分布了,尽管在第二天重新拾起了Excel中那几个常见的函数和图像的做法,还是十分的惭愧.实际上,当时有效偏颇了,忽略了问题 ...

  • 10行Python代码的词云

    什么是词云呢? 词云又叫文字云,是对文本数据中出现频率较高的"关键词"在视觉上的突出呈现,形成关键词的渲染形成类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思. 现在 ...

  • 再见PDF提取收费!我用100行Python代码搞定!

    第471篇原创干货,第一时间送达 大家在日常的工作和学习过程中,都少不了与PDF文件打交道,很多的小伙伴都面临着将PDF文件中的文字.图片和表格数据提取出来的问题.能够对PDF文件中的文字.表格等数据 ...

  • 不到70行Python代码,轻松玩转RFM用户分析模型(附案例数据和代码)

    本文从RFM模型概念入手,结合实际案例,详解Python实现模型的每一步操作,并提供案例同款源数据,以供同学们知行合一. 注:想直接下载代码和数据的同学可以空降文末 看这篇文章前源数据长这样: 学完后 ...

  • 女友半夜加班发自拍,IT男友用30行python代码发现惊天秘密

    点击上方"机器学习爱好者社区" 选择"星标"公众号,重磅干货,第一时间送达 这是一个悲伤的故事 昨天,我司的python开发小哥刚准备下班陪女友共进晚餐,满心期 ...

  • 用几行python代码偷偷复制U盘文件

    https://www.cnblogs.com/dawning666/articles/9433907.html 前言 上大学的时候有老师不给上课的PPT,就总想有个程序能偷偷复制老师的U盘....一 ...

  • 不到 100 行 Python 代码写个计算器

    来源:Python 技术「ID: pythonall」 我们常见的计算辅助工具有两种,一种是古人发明的算盘,另一种就是我们现代人发明的计算器,与算盘相比,计算器无论是便利性还是计算速度都是优于算盘的, ...