一、实现背景
最近作者的电脑操作系统进行了还原,浏览器中的收藏夹找不回来。
以前收藏的其他网友开发的Markdown编辑器链接找不回来了,
同时市面上的其他编辑器有些都是收费的。因此小编想了下:
为何我不能自己构建一个用来写公众号文章的Markdown编辑器呢?
因此,经过查询Markdown语法,构思了下工具实现形式,也就有了如下的成果。
二、实现效果
微信公众号文章Markdown网页编辑器
三、实现代码
import streamlit as st
from streamlit_ace import st_ace
import time
import pyautogui
st.set_page_config(page_title="Markdown编辑器", layout="wide", page_icon="💡")
markdown_table = """
## Markdown 语法参考
| 语法类型 | 说明 | 示例 |
|----------|------------------|----------------------------------|
| 标题 | 创建标题 | `# 一级标题` `## 二级标题` |
| 强调 | 斜体、粗体、删除线 | `*斜体*` **粗体** `~~删除线~~` |
| 列表 | 无序和有序列表 | `- 项目1` `1. 第一项` |
| 链接 | 插入链接 | `[标题](https://example.com)` |
| 图片 | 插入图片 | `` |
| 引用 | 引用文本 | `> 引用内容` |
| 代码 | 显示代码 | ```python行内代码```|
| 分隔线 | 插入分隔线 | `---` |
| 任务列表 | 创建任务列表 | `- [x] 完成任务` `- [ ] 待完成` |
| HTML元素 | 使用HTML元素 | `<div>HTML元素</div>` |
| 转义字符 | 转义Markdown字符 | `\*这不是斜体\*` |
| 换行 | 隔开上下内容 | `在要隔开的内容之间输入<br>` |
<br>
## Markdown 表格语法示例
```markdown
| 表头1 | 表头2 | 表头3 |
|-------|:-----:|------:|
| 左对齐 | 居中对齐 | 右对齐 |
| 文本 | 文本 | 文本 |
"""
with st.sidebar:
st.markdown(markdown_table, unsafe_allow_html=True)
# 创建两个并行的列
c1, c2, c3, c4, c5 = st.columns([0.5,2,0.5,2,0.5])
# 添加全局CSS来改变一级和二级标题的样式和代码块背景色
st.markdown(
"""
<style>
h1, h2 {
background-image: linear-gradient(to right, #00ccff, #1aff1a, #ffffff);
border-radius: 3px;
color: white !important;
padding: 5px;
}
pre {
background-color: #E0FFF0 !important;
}
</style>
""",
unsafe_allow_html=True,
)
# 使用左侧列来获取用户输入的Markdown文本
with c1:
st.empty()
with c2:
st.header("Markdown输入")
markdown_text = st_ace(
language="markdown",
value="",
height=400,
theme="monokai",
show_gutter=True,
key="markdown_editor",
)
with c3:
st.empty()
# 使用右侧列来显示Markdown文本的渲染效果
with c4:
st.header("操作区域")
# 用户提交内容后,显示滚动幅度输入框和复制按钮
# 默认隐藏复制区域的相关控件
copy_button = None
scroll_value = None
# 当用户提交内容后,显示滚动幅度输入框和复制按钮
if markdown_text is not None:
# 设置向下滚动的幅度,用户可以调整
scroll_value = st.number_input('设置向下滚动的幅度(单位:行数)',
min_value=1, value=10, step=1)
copy_button = st.button('开始复制')
# 如果已经设置了滚动值并且按下了复制按钮,执行复制操作
if copy_button:
# 执行复制区域的函数
# 定义复制区域的函数
# 矩形区域的两个顶点坐标
first_point = (1012, 500) # 左上角
second_point = (1798, 500) # 右上角
def select_and_copy_area(scroll_amount):
# 移动到第一个点并点击以确保焦点在正确的窗口
pyautogui.click(first_point)
# 按下鼠标左键准备拖动
pyautogui.mouseDown()
time.sleep(0.2) # 短暂延迟确保按键被注册
# 移动到第二个点,此处不改变y坐标
pyautogui.moveTo(second_point[0], first_point[1])
time.sleep(0.2) # 短暂延迟以完成横向选择
# 根据用户输入的滚动幅度计算滚动
pyautogui.scroll(-scroll_amount * 100) # 假设每行滚动100像素
time.sleep(0.2) # 短暂延迟以完成滚动
# 松开鼠标左键完成选择
pyautogui.mouseUp()
time.sleep(0.2) # 短暂延迟以完成选择操作
# 执行 Ctrl+C 复制操作
pyautogui.hotkey('ctrl', 'c') # 对于 macOS 使用 'command', 'c'
# 执行滚动并复制
select_and_copy_area(scroll_value)
st.toast("右侧区域复制成功!")
st.markdown(markdown_text, unsafe_allow_html=True)
with c5:
st.empty()
四、实现原理
1、作者构建的公众号Markdown网页编辑器,分为3块区域。
最左侧的侧边栏,总结了Markdown相关语法,供使用者参考。
右侧主要区域的左侧部分为使用Markdown语法的编辑区域,
右侧部分为Markdown语法的预览、复制区域。
2、Markdown语法的编辑区域,采用了streamlit-ace组件,
这个组件有行号显示,背景色为黑色,提供了良好的编辑环境。
下方的APPLY按钮提供了应用按钮,用户点击了应用按钮后,
会将编辑器中的内容,自动使用Markdown语法渲染并呈现出来。
3、右侧区域的功能由3部分功能构成,第一部分是复制按钮,
第二部分是要复制的行号范围,具体要复制多少行,可以根据
左侧的streamlit-ace显示的行号进行相应设置。
4、复制方法:作者最初尝试使用js脚本形式操作,最后发现都失败了。
后来采用pyautogui模块,通过用户按下复制按钮,模拟用户选择右侧
区域并按下“Ctrl+C”复制快捷键的方式,经过尝试,这种方式可以达到预期目标。
五、项目依赖清单
streamlit==1.32.0
pyautogui==0.9.54
streamlit-ace==0.1.1
六、Streamlit交流群
欢迎全渠道
搜索Streamlit, 加入我们的交流群!