diff --git a/README.md b/README.md
index 005653a..258fb8e 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,8 @@
-[![deploy status](https://github.com/doocs/md/workflows/Build%20and%20Deploy/badge.svg)](https://github.com/doocs/md/actions) [![users](https://badgen.net/badge/Who's/using/green)](#谁在使用) [![PRs Welcome](https://badgen.net/badge/PRs/welcome/green)](../../pulls)
[![license](https://badgen.net/github/license/doocs/md)](./LICENSE) [![github](https://badgen.net/badge/⭐/GitHub/blue)](https://github.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/Gitee/blue)](https://gitee.com/doocs/md) [![gitee](https://badgen.net/badge/⭐/GitCode/blue)](https://gitcode.com/doocs/md) [![release](https://img.shields.io/github/v/release/doocs/md.svg)](../../releases)
+[![status](https://img.shields.io/github/actions/workflow/status/doocs/md/build.yml?style=flat-square&labelColor=564341&color=42cc23
+)](https://github.com/doocs/md/actions) [![node](https://img.shields.io/badge/node-%3E%3D20-42cc23?style=flat-square&labelColor=564341)](https://nodejs.org/en/about/previous-releases) [![release](https://img.shields.io/github/v/release/doocs/md?style=flat-square&labelColor=564341&color=42cc23)](https://github.com/doocs/md/releases) [![license](https://img.shields.io/github/license/doocs/md?style=flat-square&labelColor=564341&color=42cc23)](./LICENSE) [![pr](https://img.shields.io/badge/prs-welcome-42cc23?style=flat-square&labelColor=564341)](https://github.com/doocs/md/pulls)
[![stars](https://img.shields.io/github/stars/doocs/md?style=flat-square&labelColor=564341&color=42cc23)](https://github.com/doocs/md/stargazers) [![forks](https://img.shields.io/github/forks/doocs/md?style=flat-square&labelColor=564341&color=42cc23)](https://github.com/doocs/md)
@@ -97,7 +98,7 @@ util.axios
// util: {
// axios, // axios 实例
// CryptoJS, // 加密库
-// OSS, // ali-oss
+// OSS, // tiny-oss
// COS, // cos-js-sdk-v5
// Buffer, // buffer-from
// uuidv4, // uuid
diff --git a/src/assets/example/markdown.md b/src/assets/example/markdown.md
index b686fed..da7e21d 100644
--- a/src/assets/example/markdown.md
+++ b/src/assets/example/markdown.md
@@ -1,95 +1,88 @@
-# 示例文章:Google 搜索的即时自动补全功能究竟是如何“工作”的?
+# 微信 Markdown 编辑器 @doocs/md
-> Google 搜索**自动补全功能**的强大,相信不少朋友都能感受到,它帮助我们更快地“补全”我们所要输入的搜索关键字。那么,它怎么知道我们要输入什么内容?它又是如何工作的?在这篇文章里,我们一起来看看。
+## 项目介绍
-## 使用自动补全
+Markdown 文档自动即时渲染为微信图文,让你不再为微信文章排版而发愁!只要你会基本的 Markdown 语法,就能做出一篇样式简洁而又美观大方的微信图文。
-Google 搜索的自动补全功能可以在 Google 搜索应用的大多数位置使用,包括 [Google](https://www.google.com/) 主页、适用于 IOS 和 Android 的 Google 应用,我们只需要在 Google 搜索框上开始键入关键字,就可以看到联想词了。
-![](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/1648303019705-c161ce00-d245-446a-b81c-42ec91474a40.gif)
+## 功能特性
-在上图示例中,我们可以看到,输入关键字 `juej`,Google 搜索会联想到“掘金”、“掘金小册”、“绝句”等等,好处就是,我们无须输入完整的关键字即可轻松完成针对这些 topics 的搜索。
+- [x] 支持自定义 CSS 样式
+- [x] 支持 Markdown 所有基础语法、数学公式、Mermaid 图表
+- [x] 支持浅色、深色两种编辑器外观
+- [x] 支持 Alt + Shift + F 快速格式化文档
+- [x] 支持色盘取色,快速替换文章整体色调
+- [x] 支持多图上传,可自定义配置图床
+- [x] 支持自定义上传逻辑
+- [x] 支持在编辑框右键弹出功能选项卡
+- [x] 支持批量转换本地图片为线上图片
-谷歌搜索的自动补全功能对于使用移动设备的用户来说特别有用,用户可以轻松在难以键入的小屏幕上完成搜索。当然,对于移动设备用户和台式机用户而言,这都节省了大量的时间。根据 Google 官方报告,自动补全功能可以减少大约 25% 的打字,累积起来,预计每天可以节省 200 多年的打字时间。是的,每天!
+![demo1](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/demo1.gif)
-> 注意,本文所提到的“**联想词**”与“**预测**”,是同一个意思。
+![demo2](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/demo2.gif)
-## 基于“预测”而非“建议”
+![demo3](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/demo3.gif)
-Google 官方将自动补全功能称之为“预测”,而不是“建议”,为什么呢?其实是有充分理由的。自动补全功能是为了**帮助用户完成他们打算进行的搜索**,而不是建议用户要执行什么搜索。
+![demo4](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/demo4.gif)
-那么,Google 是如何确定这些“预测”的?其实,Google 会根据趋势搜索 [trends](https://trends.google.com/trends/?geo=US) 给到我们这些“预测”。简单来说,哪个热门、哪个搜索频率高,就更可能推给我们。当然,这也与我们当前所处的位置以及我们的搜索历史相关。
+## 如何开发和部署
-另外,这些“预测”也会随着我们键入的关键字的变更而更改。例如,当我们把键入的关键字从 `juej` 更改为 `juex` 时,与“掘金”相关的预测会“消失”,同时,与“觉醒”、“决心”相关联的词会出现。
+```sh
+# 安装依赖
+npm i
-![](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/1648303068169-386a99cb-143b-4ded-a859-1b7a4c4b5bd3.gif)
+# 启动开发模式
+npm start
-## 为什么看不到某些联想词?
+# 部署在 /md 目录
+npm run build
+# 访问 http://127.0.0.1:9000/md
-如果我们在输入某个关键字时看不到联想词,那么表明 Google 的算法可能检测到:
+# 部署在根目录
+npm run build:h5-netlify
+# 访问 http://127.0.0.1:9000/
+```
-- 这个关键字不是热门字词;
-- 搜索的字词太新了,我们可能需要等待几天或几周才能看到联想词;
-- 这是一个侮辱性或敏感字词,这个搜索字词违反了 Google 的相关政策。更加详细的情况,可以了解 [Google 搜索自动补全政策](https://support.google.com/websearch/answer/7368877)。
+## 快速搭建私有服务
-## 为什么会看到某些不当的联想词?
+### 方式 1. 使用 npm cli
-Google 拥有专门设计的系统,可以自动捕获不适当的预测结果而不显示出来。然而,Google 每天需要处理数十亿次搜索,这意味着 Google 每天会显示数十亿甚至上百亿条预测。再好的系统,也可能存在缺陷,不正确的预测也可能随时会出现。
+通过我们的 npm cli 你可以轻易搭建属于自己的微信 Markdown 编辑器。
-我们作为 Google 搜索的用户,如果认定某条预测违反了相关的搜索自动补全政策,可以进行举报反馈,点击右下角“**举报不当的联想查询**”并勾选相关选项即可。
+```sh
+# 安装
+npm i -g @doocs/md-cli
-![](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/1648303098026-cac215dc-42c9-462a-a359-dcfb12ed3234.gif)
+# 启动
+md-cli
-## 如何实现自动补全算法?
+# 访问
+open http://127.0.0.1:8800/md/
-目前,Google 官方似乎并没有公开搜索自动补全的算法实现,但是业界在这方面已经有了不少研究。
+# 启动并指定端口
+md-cli port=8899
-一个好的自动补全器必须是快速的,并且在用户键入下一个字符后立即更新联想词列表。**自动补全器的核心是一个函数,它接受输入的前缀,并搜索以给定前缀开头的词汇或语句列表**。通常来说,只需要返回少量的数目即可。
+# 访问
+open http://127.0.0.1:8899/md/
+```
-接下来,我们先从一个简单且低效的实现开始,并在此基础上逐步构建更高效的方法。
+md-cli 支持以下命令行参数:
-### 词汇表实现
+- `port` 指定端口号,默认 8800,如果被占用会随机使用一个新端口。
+- `spaceId` dcloud 服务空间配置
+- `clientSecret` dcloud 服务空间配置
-一个**简单粗暴的实现方式**是:顺序查找词汇表,依次检查每个词汇,看它是否以给定的前缀开头。
+### 方式 2. 使用 Docker 镜像
-但是,此方法需要将前缀与每个词汇进行匹配检查,若词汇量较少,这种方式可能勉强行得通。但是,如果词汇量规模较大,效率就太低了。
+如果你是 Docker 用户,也可以直接使用一条命令,启动完全属于你的、私有化运行的实例。
-一个**更好的实现方式是**:让词汇按字典顺序排序。借助二分搜索算法,可以快速搜索有序词汇表中的前缀。由于二分搜索的每一步都会将搜索的范围减半,因此,总的搜索时间与词汇表中单词数量的对数成正比,即时间复杂度是 `O(log N)`。二分搜索的性能很好,但有没有更好的实现呢?当然有,往下看。
+```sh
+docker run -d -p 8080:80 doocs/md:latest
+```
-### 前缀树实现
+容器运行起来之后,打开浏览器,访问 http://localhost:8080 即可。
-通常来说,许多词汇都以相同的前缀开头,比如 `need`、`nested` 都以 `ne` 开头,`seed`、`speed` 都以 `s` 开头。要是为每个单词分别存储公共前缀似乎很浪费。
-
-![](https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/doocs/md/images/1648303128008-93cf798d-2662-4eec-8f80-2e07436aebfe.png)
-
-前缀树是一种利用公共前缀来加速补全速度的数据结构。前缀树在节点树中排列一组单词,单词沿着从根节点到叶子节点的路径存储,树的层次对应于前缀的字母位置。
-
-前缀的补全是顺着前缀定义的路径来查找的。例如,在上图的前缀树中,前缀 `ne` 对应于从子节点取左边缘 `N` 和唯一边缘 `E` 的路径。然后可以通过继续遍历从 `E` 节点可以达到的所有叶节点来生成补全列表。在图中,`ne` 的补全可以是两个分支:`-ed` 和 `-sted`。如果在数中找不到由前缀定义的路径,则说明词汇表中不包含以该前缀开头的单词。
-
-### 有限状态自动机(DFA)实现
-
-前缀树可以有效处理公共前缀,但是,对于其他共享词部分,仍会分别存储在每个分支中。比如,后缀 `ed`、`ing`、`tion` 在英文单词中特别常见。在上一个例子中,`e`、`d` 分别存放在了每一个分支上。
-
-有没有一种方法可以更加节省存储空间呢?有的,那就是 DFA。
-
-
-
-
-在上面的例子中,单词 `need`、`nested`、`seed` 和 `speed` 仅由 9 个节点组成,而上一张图中的前缀树包含了 17 个节点。
-
-可以看出,最小化前缀树 DFA 可以在很大程度上减少数据结构的大小。即使词汇量很大,最小化 DFA 通常也适合在内存中存储,避免昂贵的磁盘访问是实现快速自动补全的关键。
-
-### 一些扩展
-
-上面介绍了如何利用合理的数据结构实现基本的自动补全功能。这些数据结构可以通过多种方式进行扩展,从而改善用户体验。
-
-通常,满足特定前缀的词汇可能很多,而用户界面上能够显示的却不多,我们更希望能显示最常搜索或者最有价值的词汇。这通常可以通过为词汇表中的每个单词增加一个代表单词值的**权重** `weight`,并且按照权重高低来排序自动补全列表。
-
-- 对于排序后的词汇表来说,在词汇表每个元素上增加 `weight` 属性并不难;
-- 对于前缀树来说,将 `weight` 存储在叶子节点中,也是很简单的一个实现;
-- 对于 `DFA` 来说,则较为复杂。因为一个叶子节点可以通过多条路径到达。一种解决方案是将权重关联到路径而不是叶子节点。
-
-目前有不少开源库都提供了这个功能,比如主流的搜索引擎框架 [Elasticsearch](https://www.elastic.co/products/elasticsearch)、[Solr](https://lucene.apache.org/solr/) 等,基于此,我们可以实现高效而强大的自动补全功能。
+关于本项目 Docker 镜像的更多详细信息,可以关注 https://github.com/doocs/docker-md
#### 推荐阅读
@@ -105,3 +98,257 @@ Google 拥有专门设计的系统,可以自动捕获不适当的预测结果
+
+
+
+
+----
+
+# Markdown 语法教程
+
+Markdown 是一种轻量级标记语言,常用于撰写格式简单的文本文件,如文档、博客、和 README 文件。它通过简单的语法将普通文本转换为格式化的 HTML 文档。下面是 Markdown 的基本语法介绍。
+
+## 标题
+
+Markdown 使用 `#` 来表示标题。标题等级从 1 到 4,对应 HTML 的 `` 到 `` 标签。
+
+```markdown
+# 一级标题
+## 二级标题
+### 三级标题
+#### 四级标题
+```
+
+效果:
+
+# 一级标题
+## 二级标题
+### 三级标题
+#### 四级标题
+
+## 段落和换行
+
+普通文本直接书写即可形成段落。段落之间空一行即可。使用两个或多个空格加回车来实现换行。
+
+```markdown
+这是第一段文字。
+
+这是第二段文字。
+这是同一段中的换行。
+```
+
+效果:
+
+这是第一段文字。
+
+这是第二段文字。
+这是同一段中的换行。
+
+## 字体样式
+
+- **加粗**:使用 `**` 或 `__` 包裹文本。
+- *斜体*:使用 `*` 或 `_` 包裹文本。
+- ~~删除线~~:使用 `~~` 包裹文本。
+
+```markdown
+**加粗**
+*斜体*
+~~删除线~~
+```
+
+效果:
+
+**加粗**
+*斜体*
+~~删除线~~
+
+## 列表
+
+### 无序列表
+
+使用 `-`、`+` 或 `*` 加空格来创建无序列表。
+
+```markdown
+- 项目一
+- 项目二
+ - 子项目
+- 项目三
+```
+
+效果:
+
+- 项目一
+- 项目二
+ - 子项目
+- 项目三
+
+### 有序列表
+
+使用数字加点来创建有序列表。
+
+```markdown
+1. 项目一
+2. 项目二
+ 1. 子项目
+3. 项目三
+```
+
+效果:
+
+1. 项目一
+2. 项目二
+ 1. 子项目
+3. 项目三
+
+## 链接
+
+### 行内链接
+
+使用 `[显示文本](链接地址)` 创建行内链接。
+
+```markdown
+[百度](https://www.baidu.com)
+```
+
+效果:
+
+[百度](https://www.baidu.com)
+
+## 图片
+
+使用 `![替代文本](图片地址)` 插入图片。
+
+```markdown
+![Markdown Logo](https://markdown-here.com/img/icon256.png)
+```
+
+效果:
+
+![Markdown Logo](https://markdown-here.com/img/icon256.png)
+
+## 代码
+
+### 行内代码
+
+使用反引号 `` ` `` 包裹行内代码。
+
+```markdown
+使用 `print('Hello World')` 来输出文本。
+```
+
+效果:
+
+使用 `print('Hello World')` 来输出文本。
+
+### 代码块
+
+使用三个反引号 ``` 包裹代码块,可以指定语言来高亮代码。
+
+```markdown
+```python
+def hello():
+ print("Hello, World!")
+```
+```
+
+效果:
+
+```python
+def hello():
+ print("Hello, World!")
+```
+
+## 流程图
+
+
+```mermaid
+pie
+ title Key elements in Product X
+ "Calcium" : 42.96
+ "Potassium" : 50.05
+ "Magnesium" : 10.01
+ "Iron" : 5
+```
+
+```mermaid
+classDiagram
+Class01 <|-- AveryLongClass : Cool
+Class03 *-- Class04
+Class05 o-- Class06
+Class07 .. Class08
+Class09 --> C2 : Where am i?
+Class09 --* C3
+Class09 --|> Class07
+Class07 : equals()
+Class07 : Object[] elementData
+Class01 : size()
+Class01 : int chimp
+Class01 : int gorilla
+Class08 <--> C2: Cool label
+```
+
+
+```mermaid
+pie
+ title Key elements in Product X
+ "Calcium" : 42.96
+ "Potassium" : 50.05
+ "Magnesium" : 10.01
+ "Iron" : 5
+```
+
+
+```mermaid
+pie
+ title 为什么总是宅在家里?
+ "喜欢宅" : 45
+ "天气太热" : 70
+ "穷" : 500
+ "关你屁事" : 95
+```
+
+## 表格
+
+使用 `|` 分隔列,使用 `-` 分隔表头和内容。
+
+```markdown
+| 名称 | 年龄 | 城市 |
+|--------|------|--------|
+| 小明 | 20 | 北京 |
+| 小红 | 22 | 上海 |
+```
+
+效果:
+
+| 名称 | 年龄 | 城市 |
+|--------|------|--------|
+| 小明 | 20 | 北京 |
+| 小红 | 22 | 上海 |
+
+## 引用
+
+使用 `>` 创建引用。
+
+```markdown
+> 这是一段引用文本。
+```
+
+效果:
+
+> 这是一段引用文本。
+
+## 分割线
+
+使用三个或更多的 `-`、`*`、`_` 创建分割线。
+
+```markdown
+---
+```
+
+效果:
+
+---
+
+### 结束语
+
+Markdown 简洁易学,适合用于各种简单的文本格式需求。如果想要深入了解更多语法,推荐查阅 [Markdown 官方文档](https://daringfireball.net/projects/markdown/)。
diff --git a/src/stores/index.js b/src/stores/index.js
index 6dace7b..e6df745 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -39,7 +39,7 @@ export const useStore = defineStore(`store`, () => {
// 文本颜色
const fontColor = useStorage(`color`, colorOptions[0].value)
// 代码块主题
- const codeBlockTheme = useStorage(`codeBlockTheme`, codeBlockThemeOptions[2].value)
+ const codeBlockTheme = useStorage(`codeBlockTheme`, codeBlockThemeOptions[23].value)
// 图注格式
const legend = useStorage(`legend`, legendOptions[3].value)
diff --git a/src/utils/file.js b/src/utils/file.js
index 9a2a249..96c5993 100644
--- a/src/utils/file.js
+++ b/src/utils/file.js
@@ -291,7 +291,7 @@ async function formCustomUpload(content, file) {
util: {
axios: fetch, // axios 实例
CryptoJS, // 加密库
- OSS, // ali-oss(tiny-oss)
+ OSS, // tiny-oss
COS, // cos-js-sdk-v5
Buffer, // buffer-from
uuidv4, // uuid