Compare commits
3 Commits
v2026.01.1
...
v2026.01.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f304eb7633 | ||
|
|
827204e082 | ||
|
|
641d7ee8c8 |
20
README.md
20
README.md
@@ -10,28 +10,28 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
|
||||
<!-- STATS_START -->
|
||||
## 📊 Community Stats
|
||||
|
||||
> 🕐 Auto-updated: 2026-01-17 17:07
|
||||
> 🕐 Auto-updated: 2026-01-18 00:08
|
||||
|
||||
| 👤 Author | 👥 Followers | ⭐ Points | 🏆 Contributions |
|
||||
|:---:|:---:|:---:|:---:|
|
||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **118** | **108** | **25** |
|
||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **119** | **113** | **25** |
|
||||
|
||||
| 📝 Posts | ⬇️ Downloads | 👁️ Views | 👍 Upvotes | 💾 Saves |
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
| **16** | **1622** | **19716** | **94** | **123** |
|
||||
| **16** | **1659** | **19990** | **99** | **126** |
|
||||
|
||||
### 🔥 Top 6 Popular Plugins
|
||||
|
||||
> 🕐 Auto-updated: 2026-01-17 17:07
|
||||
> 🕐 Auto-updated: 2026-01-18 00:08
|
||||
|
||||
| Rank | Plugin | Version | Downloads | Views | Updated |
|
||||
|:---:|------|:---:|:---:|:---:|:---:|
|
||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.1 | 503 | 4601 | 2026-01-17 |
|
||||
| 🥈 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.4.9 | 217 | 2232 | 2026-01-17 |
|
||||
| 🥉 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 202 | 747 | 2026-01-07 |
|
||||
| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.1.3 | 171 | 1889 | 2026-01-17 |
|
||||
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 0.2.4 | 131 | 2254 | 2026-01-17 |
|
||||
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 130 | 1234 | 2026-01-17 |
|
||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.1 | 507 | 4641 | 2026-01-17 |
|
||||
| 🥈 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.4.9 | 228 | 2285 | 2026-01-17 |
|
||||
| 🥉 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 202 | 751 | 2026-01-07 |
|
||||
| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.1.3 | 174 | 1906 | 2026-01-17 |
|
||||
| 5️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 134 | 1255 | 2026-01-17 |
|
||||
| 6️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 0.2.4 | 132 | 2269 | 2026-01-17 |
|
||||
|
||||
*See full stats in [Community Stats Report](./docs/community-stats.md)*
|
||||
<!-- STATS_END -->
|
||||
|
||||
20
README_CN.md
20
README_CN.md
@@ -7,28 +7,28 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
|
||||
<!-- STATS_START -->
|
||||
## 📊 社区统计
|
||||
|
||||
> 🕐 自动更新于 2026-01-17 17:07
|
||||
> 🕐 自动更新于 2026-01-18 00:08
|
||||
|
||||
| 👤 作者 | 👥 粉丝 | ⭐ 积分 | 🏆 贡献 |
|
||||
|:---:|:---:|:---:|:---:|
|
||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **118** | **108** | **25** |
|
||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **119** | **113** | **25** |
|
||||
|
||||
| 📝 发布 | ⬇️ 下载 | 👁️ 浏览 | 👍 点赞 | 💾 收藏 |
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
| **16** | **1622** | **19716** | **94** | **123** |
|
||||
| **16** | **1659** | **19990** | **99** | **126** |
|
||||
|
||||
### 🔥 热门插件 Top 6
|
||||
|
||||
> 🕐 自动更新于 2026-01-17 17:07
|
||||
> 🕐 自动更新于 2026-01-18 00:08
|
||||
|
||||
| 排名 | 插件 | 版本 | 下载 | 浏览 | 更新日期 |
|
||||
|:---:|------|:---:|:---:|:---:|:---:|
|
||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.1 | 503 | 4601 | 2026-01-17 |
|
||||
| 🥈 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.4.9 | 217 | 2232 | 2026-01-17 |
|
||||
| 🥉 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 202 | 747 | 2026-01-07 |
|
||||
| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.1.3 | 171 | 1889 | 2026-01-17 |
|
||||
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 0.2.4 | 131 | 2254 | 2026-01-17 |
|
||||
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 130 | 1234 | 2026-01-17 |
|
||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.1 | 507 | 4641 | 2026-01-17 |
|
||||
| 🥈 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.4.9 | 228 | 2285 | 2026-01-17 |
|
||||
| 🥉 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 202 | 751 | 2026-01-07 |
|
||||
| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.1.3 | 174 | 1906 | 2026-01-17 |
|
||||
| 5️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 134 | 1255 | 2026-01-17 |
|
||||
| 6️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 0.2.4 | 132 | 2269 | 2026-01-17 |
|
||||
|
||||
*完整统计请查看 [社区统计报告](./docs/community-stats.zh.md)*
|
||||
<!-- STATS_END -->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"label": "downloads",
|
||||
"message": "1.6k",
|
||||
"message": "1.7k",
|
||||
"color": "blue",
|
||||
"namedLogo": "openwebui"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"label": "followers",
|
||||
"message": "118",
|
||||
"message": "119",
|
||||
"color": "blue"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"label": "points",
|
||||
"message": "108",
|
||||
"message": "113",
|
||||
"color": "orange"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"label": "upvotes",
|
||||
"message": "94",
|
||||
"message": "99",
|
||||
"color": "brightgreen"
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"total_posts": 16,
|
||||
"total_downloads": 1622,
|
||||
"total_views": 19716,
|
||||
"total_upvotes": 94,
|
||||
"total_downloads": 1659,
|
||||
"total_views": 19990,
|
||||
"total_upvotes": 99,
|
||||
"total_downvotes": 2,
|
||||
"total_saves": 123,
|
||||
"total_saves": 126,
|
||||
"total_comments": 23,
|
||||
"by_type": {
|
||||
"action": 14,
|
||||
@@ -18,9 +18,9 @@
|
||||
"version": "0.9.1",
|
||||
"author": "Fu-Jie",
|
||||
"description": "Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge.",
|
||||
"downloads": 503,
|
||||
"views": 4601,
|
||||
"upvotes": 13,
|
||||
"downloads": 507,
|
||||
"views": 4641,
|
||||
"upvotes": 14,
|
||||
"saves": 28,
|
||||
"comments": 11,
|
||||
"created_at": "2025-12-30",
|
||||
@@ -34,10 +34,10 @@
|
||||
"version": "1.4.9",
|
||||
"author": "Fu-Jie",
|
||||
"description": "AI-powered infographic generator based on AntV Infographic. Supports professional templates, auto-icon matching, and SVG/PNG downloads.",
|
||||
"downloads": 217,
|
||||
"views": 2232,
|
||||
"upvotes": 10,
|
||||
"saves": 15,
|
||||
"downloads": 228,
|
||||
"views": 2285,
|
||||
"upvotes": 11,
|
||||
"saves": 16,
|
||||
"comments": 2,
|
||||
"created_at": "2025-12-28",
|
||||
"updated_at": "2026-01-17",
|
||||
@@ -51,7 +51,7 @@
|
||||
"author": "Fu-Jie",
|
||||
"description": "Extracts tables from chat messages and exports them to Excel (.xlsx) files with smart formatting.",
|
||||
"downloads": 202,
|
||||
"views": 747,
|
||||
"views": 751,
|
||||
"upvotes": 3,
|
||||
"saves": 5,
|
||||
"comments": 0,
|
||||
@@ -66,8 +66,8 @@
|
||||
"version": "1.1.3",
|
||||
"author": "Fu-Jie",
|
||||
"description": "Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.",
|
||||
"downloads": 171,
|
||||
"views": 1889,
|
||||
"downloads": 174,
|
||||
"views": 1906,
|
||||
"upvotes": 7,
|
||||
"saves": 18,
|
||||
"comments": 0,
|
||||
@@ -75,6 +75,22 @@
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/async_context_compression_b1655bc8"
|
||||
},
|
||||
{
|
||||
"title": "Export to Word (Enhanced)",
|
||||
"slug": "export_to_word_enhanced_formatting_fca6a315",
|
||||
"type": "action",
|
||||
"version": "0.4.3",
|
||||
"author": "Fu-Jie",
|
||||
"description": "Export current conversation from Markdown to Word (.docx) with Mermaid diagrams rendered client-side (Mermaid.js, SVG+PNG), LaTeX math, real hyperlinks, improved tables, syntax highlighting, and blockquote support.",
|
||||
"downloads": 134,
|
||||
"views": 1255,
|
||||
"upvotes": 6,
|
||||
"saves": 15,
|
||||
"comments": 0,
|
||||
"created_at": "2026-01-03",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315"
|
||||
},
|
||||
{
|
||||
"title": "Flash Card",
|
||||
"slug": "flash_card_65a2ea8f",
|
||||
@@ -82,8 +98,8 @@
|
||||
"version": "0.2.4",
|
||||
"author": "Fu-Jie",
|
||||
"description": "Quickly generates beautiful flashcards from text, extracting key points and categories.",
|
||||
"downloads": 131,
|
||||
"views": 2254,
|
||||
"downloads": 132,
|
||||
"views": 2269,
|
||||
"upvotes": 8,
|
||||
"saves": 10,
|
||||
"comments": 2,
|
||||
@@ -92,20 +108,20 @@
|
||||
"url": "https://openwebui.com/posts/flash_card_65a2ea8f"
|
||||
},
|
||||
{
|
||||
"title": "Export to Word (Enhanced)",
|
||||
"slug": "export_to_word_enhanced_formatting_fca6a315",
|
||||
"title": "Markdown Normalizer",
|
||||
"slug": "markdown_normalizer_baaa8732",
|
||||
"type": "action",
|
||||
"version": "0.4.3",
|
||||
"version": "1.2.2",
|
||||
"author": "Fu-Jie",
|
||||
"description": "Export current conversation from Markdown to Word (.docx) with Mermaid diagrams rendered client-side (Mermaid.js, SVG+PNG), LaTeX math, real hyperlinks, improved tables, syntax highlighting, and blockquote support.",
|
||||
"downloads": 130,
|
||||
"views": 1234,
|
||||
"upvotes": 6,
|
||||
"saves": 14,
|
||||
"comments": 0,
|
||||
"created_at": "2026-01-03",
|
||||
"description": "A content normalizer filter that fixes common Markdown formatting issues in LLM outputs, such as broken code blocks, LaTeX formulas, and list formatting.",
|
||||
"downloads": 63,
|
||||
"views": 1746,
|
||||
"upvotes": 9,
|
||||
"saves": 15,
|
||||
"comments": 5,
|
||||
"created_at": "2026-01-12",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315"
|
||||
"url": "https://openwebui.com/posts/markdown_normalizer_baaa8732"
|
||||
},
|
||||
{
|
||||
"title": "导出为 Word (增强版)",
|
||||
@@ -114,31 +130,15 @@
|
||||
"version": "0.4.3",
|
||||
"author": "Fu-Jie",
|
||||
"description": "将对话导出为 Word (.docx),支持 Mermaid 图表 (客户端渲染 SVG+PNG)、LaTeX 数学公式、真实超链接、增强表格格式、代码高亮和引用块。",
|
||||
"downloads": 58,
|
||||
"views": 1246,
|
||||
"upvotes": 9,
|
||||
"downloads": 62,
|
||||
"views": 1262,
|
||||
"upvotes": 10,
|
||||
"saves": 3,
|
||||
"comments": 1,
|
||||
"created_at": "2026-01-04",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0"
|
||||
},
|
||||
{
|
||||
"title": "Markdown Normalizer",
|
||||
"slug": "markdown_normalizer_baaa8732",
|
||||
"type": "action",
|
||||
"version": "1.2.0",
|
||||
"author": "Fu-Jie",
|
||||
"description": "A content normalizer filter that fixes common Markdown formatting issues in LLM outputs, such as broken code blocks, LaTeX formulas, and list formatting.",
|
||||
"downloads": 57,
|
||||
"views": 1681,
|
||||
"upvotes": 8,
|
||||
"saves": 14,
|
||||
"comments": 5,
|
||||
"created_at": "2026-01-12",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/markdown_normalizer_baaa8732"
|
||||
},
|
||||
{
|
||||
"title": "Deep Dive",
|
||||
"slug": "deep_dive_c0b846e4",
|
||||
@@ -146,8 +146,8 @@
|
||||
"version": "1.0.0",
|
||||
"author": "Fu-Jie",
|
||||
"description": "A comprehensive thinking lens that dives deep into any content - from context to logic, insights, and action paths.",
|
||||
"downloads": 57,
|
||||
"views": 597,
|
||||
"downloads": 58,
|
||||
"views": 605,
|
||||
"upvotes": 3,
|
||||
"saves": 5,
|
||||
"comments": 0,
|
||||
@@ -163,8 +163,8 @@
|
||||
"author": "Fu-Jie",
|
||||
"description": "基于 AntV Infographic 的智能信息图生成插件。支持多种专业模板,自动图标匹配,并提供 SVG/PNG 下载功能。",
|
||||
"downloads": 41,
|
||||
"views": 650,
|
||||
"upvotes": 4,
|
||||
"views": 654,
|
||||
"upvotes": 5,
|
||||
"saves": 0,
|
||||
"comments": 0,
|
||||
"created_at": "2025-12-28",
|
||||
@@ -179,7 +179,7 @@
|
||||
"author": "Fu-Jie",
|
||||
"description": "智能分析文本内容,生成交互式思维导图,帮助用户结构化和可视化知识。",
|
||||
"downloads": 22,
|
||||
"views": 389,
|
||||
"views": 392,
|
||||
"upvotes": 2,
|
||||
"saves": 1,
|
||||
"comments": 0,
|
||||
@@ -187,6 +187,22 @@
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b"
|
||||
},
|
||||
{
|
||||
"title": "闪记卡 (Flash Card)",
|
||||
"slug": "闪记卡生成插件_4a31eac3",
|
||||
"type": "action",
|
||||
"version": "0.2.4",
|
||||
"author": "Fu-Jie",
|
||||
"description": "快速将文本提炼为精美的学习记忆卡片,支持核心要点提取与分类。",
|
||||
"downloads": 16,
|
||||
"views": 430,
|
||||
"upvotes": 4,
|
||||
"saves": 1,
|
||||
"comments": 0,
|
||||
"created_at": "2025-12-30",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/闪记卡生成插件_4a31eac3"
|
||||
},
|
||||
{
|
||||
"title": "异步上下文压缩",
|
||||
"slug": "异步上下文压缩_5c0617cb",
|
||||
@@ -195,7 +211,7 @@
|
||||
"author": "Fu-Jie",
|
||||
"description": "通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。",
|
||||
"downloads": 14,
|
||||
"views": 337,
|
||||
"views": 340,
|
||||
"upvotes": 4,
|
||||
"saves": 1,
|
||||
"comments": 0,
|
||||
@@ -203,22 +219,6 @@
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/异步上下文压缩_5c0617cb"
|
||||
},
|
||||
{
|
||||
"title": "闪记卡 (Flash Card)",
|
||||
"slug": "闪记卡生成插件_4a31eac3",
|
||||
"type": "action",
|
||||
"version": "0.2.4",
|
||||
"author": "Fu-Jie",
|
||||
"description": "快速将文本提炼为精美的学习记忆卡片,支持核心要点提取与分类。",
|
||||
"downloads": 13,
|
||||
"views": 423,
|
||||
"upvotes": 4,
|
||||
"saves": 1,
|
||||
"comments": 0,
|
||||
"created_at": "2025-12-30",
|
||||
"updated_at": "2026-01-17",
|
||||
"url": "https://openwebui.com/posts/闪记卡生成插件_4a31eac3"
|
||||
},
|
||||
{
|
||||
"title": "精读",
|
||||
"slug": "精读_99830b0f",
|
||||
@@ -243,7 +243,7 @@
|
||||
"author": "",
|
||||
"description": "",
|
||||
"downloads": 0,
|
||||
"views": 43,
|
||||
"views": 46,
|
||||
"upvotes": 0,
|
||||
"saves": 0,
|
||||
"comments": 0,
|
||||
@@ -259,7 +259,7 @@
|
||||
"author": "",
|
||||
"description": "",
|
||||
"downloads": 0,
|
||||
"views": 1139,
|
||||
"views": 1154,
|
||||
"upvotes": 11,
|
||||
"saves": 7,
|
||||
"comments": 2,
|
||||
@@ -273,10 +273,10 @@
|
||||
"name": "Fu-Jie",
|
||||
"profile_url": "https://openwebui.com/u/Fu-Jie",
|
||||
"profile_image": "https://community.s3.openwebui.com/uploads/users/b15d1348-4347-42b4-b815-e053342d6cb0/profile_d9510745-4bd4-4f8f-a997-4a21847d9300.webp",
|
||||
"followers": 118,
|
||||
"followers": 119,
|
||||
"following": 2,
|
||||
"total_points": 108,
|
||||
"post_points": 92,
|
||||
"total_points": 113,
|
||||
"post_points": 97,
|
||||
"comment_points": 16,
|
||||
"contributions": 25
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# 📊 OpenWebUI Community Stats Report
|
||||
|
||||
> 📅 Updated: 2026-01-17 17:07
|
||||
> 📅 Updated: 2026-01-18 00:08
|
||||
|
||||
## 📈 Overview
|
||||
|
||||
| Metric | Value |
|
||||
|------|------|
|
||||
| 📝 Total Posts | 16 |
|
||||
| ⬇️ Total Downloads | 1622 |
|
||||
| 👁️ Total Views | 19716 |
|
||||
| 👍 Total Upvotes | 94 |
|
||||
| 💾 Total Saves | 123 |
|
||||
| ⬇️ Total Downloads | 1659 |
|
||||
| 👁️ Total Views | 19990 |
|
||||
| 👍 Total Upvotes | 99 |
|
||||
| 💾 Total Saves | 126 |
|
||||
| 💬 Total Comments | 23 |
|
||||
|
||||
## 📂 By Type
|
||||
@@ -22,19 +22,19 @@
|
||||
|
||||
| Rank | Title | Type | Version | Downloads | Views | Upvotes | Saves | Updated |
|
||||
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 503 | 4601 | 13 | 28 | 2026-01-17 |
|
||||
| 2 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.9 | 217 | 2232 | 10 | 15 | 2026-01-17 |
|
||||
| 3 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 202 | 747 | 3 | 5 | 2026-01-07 |
|
||||
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.1.3 | 171 | 1889 | 7 | 18 | 2026-01-17 |
|
||||
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 131 | 2254 | 8 | 10 | 2026-01-17 |
|
||||
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 130 | 1234 | 6 | 14 | 2026-01-17 |
|
||||
| 7 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 58 | 1246 | 9 | 3 | 2026-01-17 |
|
||||
| 8 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.0 | 57 | 1681 | 8 | 14 | 2026-01-17 |
|
||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 57 | 597 | 3 | 5 | 2026-01-08 |
|
||||
| 10 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.9 | 41 | 650 | 4 | 0 | 2026-01-17 |
|
||||
| 11 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 22 | 389 | 2 | 1 | 2026-01-17 |
|
||||
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.1.3 | 14 | 337 | 4 | 1 | 2026-01-17 |
|
||||
| 13 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 13 | 423 | 4 | 1 | 2026-01-17 |
|
||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 507 | 4641 | 14 | 28 | 2026-01-17 |
|
||||
| 2 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.9 | 228 | 2285 | 11 | 16 | 2026-01-17 |
|
||||
| 3 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 202 | 751 | 3 | 5 | 2026-01-07 |
|
||||
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.1.3 | 174 | 1906 | 7 | 18 | 2026-01-17 |
|
||||
| 5 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 134 | 1255 | 6 | 15 | 2026-01-17 |
|
||||
| 6 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 132 | 2269 | 8 | 10 | 2026-01-17 |
|
||||
| 7 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.2 | 63 | 1746 | 9 | 15 | 2026-01-17 |
|
||||
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 62 | 1262 | 10 | 3 | 2026-01-17 |
|
||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 58 | 605 | 3 | 5 | 2026-01-08 |
|
||||
| 10 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.9 | 41 | 654 | 5 | 0 | 2026-01-17 |
|
||||
| 11 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 22 | 392 | 2 | 1 | 2026-01-17 |
|
||||
| 12 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 16 | 430 | 4 | 1 | 2026-01-17 |
|
||||
| 13 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.1.3 | 14 | 340 | 4 | 1 | 2026-01-17 |
|
||||
| 14 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 6 | 254 | 2 | 1 | 2026-01-08 |
|
||||
| 15 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 43 | 0 | 0 | 2026-01-14 |
|
||||
| 16 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1139 | 11 | 7 | 2026-01-10 |
|
||||
| 15 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 46 | 0 | 0 | 2026-01-14 |
|
||||
| 16 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1154 | 11 | 7 | 2026-01-10 |
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# 📊 OpenWebUI 社区统计报告
|
||||
|
||||
> 📅 更新时间: 2026-01-17 17:07
|
||||
> 📅 更新时间: 2026-01-18 00:08
|
||||
|
||||
## 📈 总览
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 📝 发布数量 | 16 |
|
||||
| ⬇️ 总下载量 | 1622 |
|
||||
| 👁️ 总浏览量 | 19716 |
|
||||
| 👍 总点赞数 | 94 |
|
||||
| 💾 总收藏数 | 123 |
|
||||
| ⬇️ 总下载量 | 1659 |
|
||||
| 👁️ 总浏览量 | 19990 |
|
||||
| 👍 总点赞数 | 99 |
|
||||
| 💾 总收藏数 | 126 |
|
||||
| 💬 总评论数 | 23 |
|
||||
|
||||
## 📂 按类型分类
|
||||
@@ -22,19 +22,19 @@
|
||||
|
||||
| 排名 | 标题 | 类型 | 版本 | 下载 | 浏览 | 点赞 | 收藏 | 更新日期 |
|
||||
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 503 | 4601 | 13 | 28 | 2026-01-17 |
|
||||
| 2 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.9 | 217 | 2232 | 10 | 15 | 2026-01-17 |
|
||||
| 3 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 202 | 747 | 3 | 5 | 2026-01-07 |
|
||||
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.1.3 | 171 | 1889 | 7 | 18 | 2026-01-17 |
|
||||
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 131 | 2254 | 8 | 10 | 2026-01-17 |
|
||||
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 130 | 1234 | 6 | 14 | 2026-01-17 |
|
||||
| 7 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 58 | 1246 | 9 | 3 | 2026-01-17 |
|
||||
| 8 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.0 | 57 | 1681 | 8 | 14 | 2026-01-17 |
|
||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 57 | 597 | 3 | 5 | 2026-01-08 |
|
||||
| 10 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.9 | 41 | 650 | 4 | 0 | 2026-01-17 |
|
||||
| 11 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 22 | 389 | 2 | 1 | 2026-01-17 |
|
||||
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.1.3 | 14 | 337 | 4 | 1 | 2026-01-17 |
|
||||
| 13 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 13 | 423 | 4 | 1 | 2026-01-17 |
|
||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 507 | 4641 | 14 | 28 | 2026-01-17 |
|
||||
| 2 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.9 | 228 | 2285 | 11 | 16 | 2026-01-17 |
|
||||
| 3 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 202 | 751 | 3 | 5 | 2026-01-07 |
|
||||
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.1.3 | 174 | 1906 | 7 | 18 | 2026-01-17 |
|
||||
| 5 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 134 | 1255 | 6 | 15 | 2026-01-17 |
|
||||
| 6 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 132 | 2269 | 8 | 10 | 2026-01-17 |
|
||||
| 7 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.2 | 63 | 1746 | 9 | 15 | 2026-01-17 |
|
||||
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 62 | 1262 | 10 | 3 | 2026-01-17 |
|
||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 58 | 605 | 3 | 5 | 2026-01-08 |
|
||||
| 10 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.9 | 41 | 654 | 5 | 0 | 2026-01-17 |
|
||||
| 11 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 22 | 392 | 2 | 1 | 2026-01-17 |
|
||||
| 12 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 16 | 430 | 4 | 1 | 2026-01-17 |
|
||||
| 13 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.1.3 | 14 | 340 | 4 | 1 | 2026-01-17 |
|
||||
| 14 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 6 | 254 | 2 | 1 | 2026-01-08 |
|
||||
| 15 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 43 | 0 | 0 | 2026-01-14 |
|
||||
| 16 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1139 | 11 | 7 | 2026-01-10 |
|
||||
| 15 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 46 | 0 | 0 | 2026-01-14 |
|
||||
| 16 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1154 | 11 | 7 | 2026-01-10 |
|
||||
|
||||
@@ -44,7 +44,7 @@ Filters act as middleware in the message pipeline:
|
||||
|
||||
Fixes common Markdown formatting issues in LLM outputs, including Mermaid syntax, code blocks, and LaTeX formulas.
|
||||
|
||||
**Version:** 1.1.2
|
||||
**Version:** 1.2.3
|
||||
|
||||
[:octicons-arrow-right-24: Documentation](markdown_normalizer.md)
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Filter 充当消息管线中的中间件:
|
||||
|
||||
修复 LLM 输出中常见的 Markdown 格式问题,包括 Mermaid 语法、代码块和 LaTeX 公式。
|
||||
|
||||
**版本:** 1.0.1
|
||||
**版本:** 1.2.3
|
||||
|
||||
[:octicons-arrow-right-24: 查看文档](markdown_normalizer.zh.md)
|
||||
|
||||
|
||||
@@ -51,9 +51,17 @@ A content normalizer filter for Open WebUI that fixes common Markdown formatting
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.2.3
|
||||
|
||||
* **List Marker Protection Enhancement**: Fixed a bug where list markers (`*`) followed by plain text and emphasis were having their spaces incorrectly stripped (e.g., `* U16 forward` became `*U16 forward`).
|
||||
* **Placeholder Support**: Confirmed that 4 or more underscores (e.g., `____`) are correctly treated as placeholders and not modified by the emphasis fix.
|
||||
|
||||
### v1.2.2
|
||||
|
||||
* **Version Bump**: Documentation and metadata updated for the latest release.
|
||||
* **Code Block Indentation Fix**: Fixed an issue where code blocks nested inside lists were having their indentation incorrectly stripped. Now preserves proper indentation for nested code blocks.
|
||||
* **Underscore Emphasis Support**: Extended emphasis spacing fix to support `__` (double underscore for bold) and `___` (triple underscore for bold+italic) syntax.
|
||||
* **List Marker Protection**: Fixed a bug where list markers (`*`) followed by emphasis markers (`**`) were incorrectly merged (e.g., `* **Yes**` became `***Yes**`). Added safeguard to prevent this.
|
||||
* **Test Suite**: Added comprehensive pytest test suite with 56 test cases covering all major features.
|
||||
|
||||
### v1.2.1
|
||||
|
||||
|
||||
@@ -51,9 +51,17 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.2.3
|
||||
|
||||
* **列表标记保护增强**: 修复了列表标记 (`*`) 后跟普通文本和强调标记时,空格被错误剥离的问题(例如 `* U16 前锋` 变成 `*U16 前锋`)。
|
||||
* **占位符支持**: 确认 4 个或更多下划线(如 `____`)会被正确视为占位符,不会被强调修复逻辑修改。
|
||||
|
||||
### v1.2.2
|
||||
|
||||
* **版本更新**: 文档与元数据已同步到最新版本。
|
||||
* **代码块缩进修复**: 修复了列表中嵌套代码块的缩进被错误剥离的问题。现在会正确保留嵌套代码块的缩进。
|
||||
* **下划线强调语法支持**: 扩展强调空格修复以支持 `__` (双下划线加粗) 和 `___` (三下划线加粗斜体) 语法。
|
||||
* **列表标记保护**: 修复了列表标记 (`*`) 后跟强调标记 (`**`) 被错误合并的 Bug(例如 `* **是**` 变成 `***是**`)。添加了保护逻辑防止此问题。
|
||||
* **测试套件**: 新增完整的 pytest 测试套件,包含 56 个测试用例,覆盖所有主要功能。
|
||||
|
||||
### v1.2.1
|
||||
|
||||
|
||||
@@ -53,9 +53,17 @@ A content normalizer filter for Open WebUI that fixes common Markdown formatting
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.2.3
|
||||
|
||||
* **List Marker Protection Enhancement**: Fixed a bug where list markers (`*`) followed by plain text and emphasis were having their spaces incorrectly stripped (e.g., `* U16 forward` became `*U16 forward`).
|
||||
* **Placeholder Support**: Confirmed that 4 or more underscores (e.g., `____`) are correctly treated as placeholders and not modified by the emphasis fix.
|
||||
|
||||
### v1.2.2
|
||||
|
||||
* **Version Bump**: Documentation and metadata updated for the latest release.
|
||||
* **Code Block Indentation Fix**: Fixed an issue where code blocks nested inside lists were having their indentation incorrectly stripped. Now preserves proper indentation for nested code blocks.
|
||||
* **Underscore Emphasis Support**: Extended emphasis spacing fix to support `__` (double underscore for bold) and `___` (triple underscore for bold+italic) syntax.
|
||||
* **List Marker Protection**: Fixed a bug where list markers (`*`) followed by emphasis markers (`**`) were incorrectly merged (e.g., `* **Yes**` became `***Yes**`). Added safeguard to prevent this.
|
||||
* **Test Suite**: Added comprehensive pytest test suite with 56 test cases covering all major features.
|
||||
|
||||
### v1.2.1
|
||||
|
||||
|
||||
@@ -53,9 +53,17 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.2.3
|
||||
|
||||
* **列表标记保护增强**: 修复了列表标记 (`*`) 后跟普通文本和强调标记时,空格被错误剥离的问题(例如 `* U16 前锋` 变成 `*U16 前锋`)。
|
||||
* **占位符支持**: 确认 4 个或更多下划线(如 `____`)会被正确视为占位符,不会被强调修复逻辑修改。
|
||||
|
||||
### v1.2.2
|
||||
|
||||
* **版本更新**: 文档与元数据已同步到最新版本。
|
||||
* **代码块缩进修复**: 修复了列表中嵌套代码块的缩进被错误剥离的问题。现在会正确保留嵌套代码块的缩进。
|
||||
* **下划线强调语法支持**: 扩展强调空格修复以支持 `__` (双下划线加粗) 和 `___` (三下划线加粗斜体) 语法。
|
||||
* **列表标记保护**: 修复了列表标记 (`*`) 后跟强调标记 (`**`) 被错误合并的 Bug(例如 `* **是**` 变成 `***是**`)。添加了保护逻辑防止此问题。
|
||||
* **测试套件**: 新增完整的 pytest 测试套件,包含 56 个测试用例,覆盖所有主要功能。
|
||||
|
||||
### v1.2.1
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Markdown Normalizer
|
||||
author: Fu-Jie
|
||||
author_url: https://github.com/Fu-Jie/awesome-openwebui
|
||||
funding_url: https://github.com/open-webui
|
||||
version: 1.2.2
|
||||
version: 1.2.3
|
||||
openwebui_id: baaa8732-9348-40b7-8359-7e009660e23c
|
||||
description: A content normalizer filter that fixes common Markdown formatting issues in LLM outputs, such as broken code blocks, LaTeX formulas, and list formatting.
|
||||
"""
|
||||
@@ -109,12 +109,13 @@ class ContentNormalizer:
|
||||
"heading_space": re.compile(r"^(#+)([^ \n#])", re.MULTILINE),
|
||||
# Table: | col1 | col2 -> | col1 | col2 |
|
||||
"table_pipe": re.compile(r"^(\|.*[^|\n])$", re.MULTILINE),
|
||||
# Emphasis spacing: ** text ** -> **text**
|
||||
# Emphasis spacing: ** text ** -> **text**, __ text __ -> __text__
|
||||
# Matches emphasis blocks within a single line. We use a recursive approach
|
||||
# in _fix_emphasis_spacing to handle nesting and spaces correctly.
|
||||
# NOTE: We use [^\n] instead of . to prevent cross-line matching.
|
||||
# Supports: * (italic), ** (bold), *** (bold+italic), _ (italic), __ (bold), ___ (bold+italic)
|
||||
"emphasis_spacing": re.compile(
|
||||
r"(?<!\*|_)(\*{1,3}|_)(?P<inner>[^\n]*?)(\1)(?!\*|_)"
|
||||
r"(?<!\*|_)(\*{1,3}|_{1,3})(?P<inner>[^\n]*?)(\1)(?!\*|_)"
|
||||
),
|
||||
}
|
||||
|
||||
@@ -485,6 +486,20 @@ class ContentNormalizer:
|
||||
if symbol in ["*", "_"]:
|
||||
return match.group(0)
|
||||
|
||||
# Safeguard: List marker protection
|
||||
# If symbol is single '*' and inner content starts with whitespace followed by emphasis markers,
|
||||
# this is likely a list item like "* **bold**" - don't merge them.
|
||||
# Pattern: "* **text**" should NOT become "***text**"
|
||||
if symbol == "*" and inner.lstrip().startswith(("*", "_")):
|
||||
return match.group(0)
|
||||
|
||||
# Extended list marker protection:
|
||||
# If symbol is single '*' and inner starts with multiple spaces (list indentation pattern),
|
||||
# this is likely a list item like "* text" - don't strip the spaces.
|
||||
# Pattern: "* U16 forward **Kuang**" should NOT become "*U16 forward **Kuang**"
|
||||
if symbol == "*" and inner.startswith(" "):
|
||||
return match.group(0)
|
||||
|
||||
return f"{symbol}{stripped_inner}{symbol}"
|
||||
|
||||
parts = content.split("```")
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Markdown 格式修复器 (Markdown Normalizer)
|
||||
author: Fu-Jie
|
||||
author_url: https://github.com/Fu-Jie/awesome-openwebui
|
||||
funding_url: https://github.com/open-webui
|
||||
version: 1.2.2
|
||||
version: 1.2.3
|
||||
description: 内容规范化过滤器,修复 LLM 输出中常见的 Markdown 格式问题,如损坏的代码块、LaTeX 公式、Mermaid 图表和列表格式。
|
||||
"""
|
||||
|
||||
@@ -101,12 +101,13 @@ class ContentNormalizer:
|
||||
"heading_space": re.compile(r"^(#+)([^ \n#])", re.MULTILINE),
|
||||
# Table: | col1 | col2 -> | col1 | col2 |
|
||||
"table_pipe": re.compile(r"^(\|.*[^|\n])$", re.MULTILINE),
|
||||
# Emphasis spacing: ** text ** -> **text**
|
||||
# Emphasis spacing: ** text ** -> **text**, __ text __ -> __text__
|
||||
# Matches emphasis blocks within a single line. We use a recursive approach
|
||||
# in _fix_emphasis_spacing to handle nesting and spaces correctly.
|
||||
# NOTE: We use [^\n] instead of . to prevent cross-line matching.
|
||||
# Supports: * (italic), ** (bold), *** (bold+italic), _ (italic), __ (bold), ___ (bold+italic)
|
||||
"emphasis_spacing": re.compile(
|
||||
r"(?<!\*|_)(\*{1,3}|_)(?P<inner>[^\n]*?)(\1)(?!\*|_)"
|
||||
r"(?<!\*|_)(\*{1,3}|_{1,3})(?P<inner>[^\n]*?)(\1)(?!\*|_)"
|
||||
),
|
||||
}
|
||||
|
||||
@@ -464,6 +465,20 @@ class ContentNormalizer:
|
||||
if symbol in ["*", "_"]:
|
||||
return match.group(0)
|
||||
|
||||
# Safeguard: List marker protection
|
||||
# If symbol is single '*' and inner content starts with whitespace followed by emphasis markers,
|
||||
# this is likely a list item like "* **bold**" - don't merge them.
|
||||
# Pattern: "* **text**" should NOT become "***text**"
|
||||
if symbol == "*" and inner.lstrip().startswith(("*", "_")):
|
||||
return match.group(0)
|
||||
|
||||
# Extended list marker protection:
|
||||
# If symbol is single '*' and inner starts with multiple spaces (list indentation pattern),
|
||||
# this is likely a list item like "* text" - don't strip the spaces.
|
||||
# Pattern: "* U16 forward **Kuang**" should NOT become "*U16 forward **Kuang**"
|
||||
if symbol == "*" and inner.startswith(" "):
|
||||
return match.group(0)
|
||||
|
||||
return f"{symbol}{stripped_inner}{symbol}"
|
||||
|
||||
parts = content.split("```")
|
||||
|
||||
1
plugins/filters/markdown_normalizer/tests/__init__.py
Normal file
1
plugins/filters/markdown_normalizer/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Markdown Normalizer Test Suite
|
||||
75
plugins/filters/markdown_normalizer/tests/conftest.py
Normal file
75
plugins/filters/markdown_normalizer/tests/conftest.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
Shared fixtures for Markdown Normalizer tests.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add the parent directory to sys.path for imports
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from markdown_normalizer import ContentNormalizer, NormalizerConfig
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def normalizer():
|
||||
"""Default normalizer with all fixes enabled."""
|
||||
config = NormalizerConfig(
|
||||
enable_escape_fix=True,
|
||||
enable_thought_tag_fix=True,
|
||||
enable_details_tag_fix=True,
|
||||
enable_code_block_fix=True,
|
||||
enable_latex_fix=True,
|
||||
enable_list_fix=False, # Experimental, keep off by default
|
||||
enable_unclosed_block_fix=True,
|
||||
enable_fullwidth_symbol_fix=False,
|
||||
enable_mermaid_fix=True,
|
||||
enable_heading_fix=True,
|
||||
enable_table_fix=True,
|
||||
enable_xml_tag_cleanup=True,
|
||||
enable_emphasis_spacing_fix=True,
|
||||
)
|
||||
return ContentNormalizer(config)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def emphasis_only_normalizer():
|
||||
"""Normalizer with only emphasis spacing fix enabled."""
|
||||
config = NormalizerConfig(
|
||||
enable_escape_fix=False,
|
||||
enable_thought_tag_fix=False,
|
||||
enable_details_tag_fix=False,
|
||||
enable_code_block_fix=False,
|
||||
enable_latex_fix=False,
|
||||
enable_list_fix=False,
|
||||
enable_unclosed_block_fix=False,
|
||||
enable_fullwidth_symbol_fix=False,
|
||||
enable_mermaid_fix=False,
|
||||
enable_heading_fix=False,
|
||||
enable_table_fix=False,
|
||||
enable_xml_tag_cleanup=False,
|
||||
enable_emphasis_spacing_fix=True,
|
||||
)
|
||||
return ContentNormalizer(config)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mermaid_only_normalizer():
|
||||
"""Normalizer with only Mermaid fix enabled."""
|
||||
config = NormalizerConfig(
|
||||
enable_escape_fix=False,
|
||||
enable_thought_tag_fix=False,
|
||||
enable_details_tag_fix=False,
|
||||
enable_code_block_fix=False,
|
||||
enable_latex_fix=False,
|
||||
enable_list_fix=False,
|
||||
enable_unclosed_block_fix=False,
|
||||
enable_fullwidth_symbol_fix=False,
|
||||
enable_mermaid_fix=True,
|
||||
enable_heading_fix=False,
|
||||
enable_table_fix=False,
|
||||
enable_xml_tag_cleanup=False,
|
||||
enable_emphasis_spacing_fix=False,
|
||||
)
|
||||
return ContentNormalizer(config)
|
||||
@@ -0,0 +1,54 @@
|
||||
"""
|
||||
Tests for code block formatting fixes.
|
||||
Covers: prefix, suffix, indentation preservation.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestCodeBlockFix:
|
||||
"""Test code block formatting normalization."""
|
||||
|
||||
def test_code_block_indentation_preserved(self, normalizer):
|
||||
"""Indented code blocks (e.g., in lists) should preserve indentation."""
|
||||
input_str = """
|
||||
* List item 1
|
||||
```python
|
||||
def foo():
|
||||
print("bar")
|
||||
```
|
||||
* List item 2
|
||||
"""
|
||||
# Indentation should be preserved
|
||||
assert " ```python" in normalizer.normalize(input_str)
|
||||
|
||||
def test_inline_code_block_prefix(self, normalizer):
|
||||
"""Code block that follows text on same line should be modified."""
|
||||
input_str = "text```python\ncode\n```"
|
||||
result = normalizer.normalize(input_str)
|
||||
# Just verify the code block markers are present
|
||||
assert "```" in result
|
||||
|
||||
def test_code_block_suffix_fix(self, normalizer):
|
||||
"""Code block with content on same line after lang should be fixed."""
|
||||
input_str = "```python code\nmore code\n```"
|
||||
result = normalizer.normalize(input_str)
|
||||
# Content should be on new line
|
||||
assert "```python\n" in result or "```python " in result
|
||||
|
||||
|
||||
class TestUnclosedCodeBlock:
|
||||
"""Test auto-closing of unclosed code blocks."""
|
||||
|
||||
def test_unclosed_code_block_is_closed(self, normalizer):
|
||||
"""Unclosed code blocks should be automatically closed."""
|
||||
input_str = "```python\ncode here"
|
||||
result = normalizer.normalize(input_str)
|
||||
# Should have closing ```
|
||||
assert result.endswith("```") or result.count("```") == 2
|
||||
|
||||
def test_balanced_code_blocks_unchanged(self, normalizer):
|
||||
"""Already balanced code blocks should not get extra closing."""
|
||||
input_str = "```python\ncode\n```"
|
||||
result = normalizer.normalize(input_str)
|
||||
assert result.count("```") == 2
|
||||
@@ -0,0 +1,48 @@
|
||||
"""
|
||||
Tests for details tag normalization.
|
||||
Covers: </details> spacing, self-closing tags.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestDetailsTagFix:
|
||||
"""Test details tag normalization."""
|
||||
|
||||
def test_details_end_gets_newlines(self, normalizer):
|
||||
"""</details> should be followed by double newline."""
|
||||
input_str = "</details>Content after"
|
||||
result = normalizer.normalize(input_str)
|
||||
assert "</details>\n\n" in result
|
||||
|
||||
def test_self_closing_details_gets_newline(self, normalizer):
|
||||
"""Self-closing <details .../> should get newline after."""
|
||||
input_str = "<details open />## Heading"
|
||||
result = normalizer.normalize(input_str)
|
||||
# Should have newline between tag and heading
|
||||
assert "/>\n" in result or "/> \n" in result
|
||||
|
||||
def test_details_in_code_block_unchanged(self, normalizer):
|
||||
"""Details tags inside code blocks should not be modified."""
|
||||
input_str = "```html\n<details>content</details>more\n```"
|
||||
result = normalizer.normalize(input_str)
|
||||
# Content inside code block should be unchanged
|
||||
assert "</details>more" in result
|
||||
|
||||
|
||||
class TestThoughtTagFix:
|
||||
"""Test thought tag normalization."""
|
||||
|
||||
def test_think_tag_normalized(self, normalizer):
|
||||
"""<think> should be normalized to <thought>."""
|
||||
input_str = "<think>content</think>"
|
||||
result = normalizer.normalize(input_str)
|
||||
assert "<thought>" in result
|
||||
assert "</thought>" in result
|
||||
|
||||
def test_thinking_tag_normalized(self, normalizer):
|
||||
"""<thinking> should be normalized to <thought>."""
|
||||
input_str = "<thinking>content</thinking>"
|
||||
result = normalizer.normalize(input_str)
|
||||
assert "<thought>" in result
|
||||
assert "</thought>" in result
|
||||
@@ -0,0 +1,138 @@
|
||||
"""
|
||||
Tests for emphasis spacing fix.
|
||||
Covers: *, **, ***, _, __, ___ with spaces inside.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestEmphasisSpacingFix:
|
||||
"""Test emphasis spacing normalization."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_str,expected",
|
||||
[
|
||||
# Double asterisk (bold)
|
||||
("** bold **", "**bold**"),
|
||||
("** bold text **", "**bold text**"),
|
||||
("**text **", "**text**"),
|
||||
("** text**", "**text**"),
|
||||
# Triple asterisk (bold+italic)
|
||||
("*** bold italic ***", "***bold italic***"),
|
||||
# Double underscore (bold)
|
||||
("__ bold __", "__bold__"),
|
||||
("__ bold text __", "__bold text__"),
|
||||
("__text __", "__text__"),
|
||||
("__ text__", "__text__"),
|
||||
# Triple underscore (bold+italic)
|
||||
("___ bold italic ___", "___bold italic___"),
|
||||
# Mixed markers
|
||||
("** bold ** and __ also __", "**bold** and __also__"),
|
||||
],
|
||||
)
|
||||
def test_emphasis_with_spaces_fixed(
|
||||
self, emphasis_only_normalizer, input_str, expected
|
||||
):
|
||||
"""Test that emphasis with spaces is correctly fixed."""
|
||||
assert emphasis_only_normalizer.normalize(input_str) == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_str",
|
||||
[
|
||||
# Single * and _ with spaces on both sides - treated as operator (safeguard)
|
||||
"* italic *",
|
||||
"_ italic _",
|
||||
# Already correct emphasis
|
||||
"**bold**",
|
||||
"__bold__",
|
||||
"*italic*",
|
||||
"_italic_",
|
||||
"***bold italic***",
|
||||
"___bold italic___",
|
||||
],
|
||||
)
|
||||
def test_safeguard_and_correct_emphasis_unchanged(
|
||||
self, emphasis_only_normalizer, input_str
|
||||
):
|
||||
"""Test that safeguard cases and already correct emphasis are not modified."""
|
||||
assert emphasis_only_normalizer.normalize(input_str) == input_str
|
||||
|
||||
|
||||
class TestEmphasisSideEffects:
|
||||
"""Test that emphasis fix does NOT affect unrelated content."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_str,description",
|
||||
[
|
||||
# URLs with underscores
|
||||
("https://example.com/path_with_underscore", "URL"),
|
||||
("Visit https://api.example.com/get_user_info for info", "URL in text"),
|
||||
# Variable names (snake_case)
|
||||
("The `my_variable_name` is important", "Variable in backticks"),
|
||||
("Use `get_user_data()` function", "Function name"),
|
||||
# File names
|
||||
("Edit the `config_file_name.py` file", "File name"),
|
||||
("See `my_script__v2.py` for details", "Double underscore in filename"),
|
||||
# Math-like subscripts
|
||||
("The variable a_1 and b_2 are defined", "Math subscripts"),
|
||||
# Single underscores not matching emphasis pattern
|
||||
("word_with_underscore", "Underscore in word"),
|
||||
("a_b_c_d", "Multiple underscores"),
|
||||
# Horizontal rules
|
||||
("---", "HR with dashes"),
|
||||
("***", "HR with asterisks"),
|
||||
("___", "HR with underscores"),
|
||||
# List items
|
||||
("- item_one\n- item_two", "List items"),
|
||||
],
|
||||
)
|
||||
def test_no_side_effects(self, emphasis_only_normalizer, input_str, description):
|
||||
"""Test that various content types are NOT modified by emphasis fix."""
|
||||
assert (
|
||||
emphasis_only_normalizer.normalize(input_str) == input_str
|
||||
), f"Failed for: {description}"
|
||||
|
||||
def test_list_marker_not_merged_with_emphasis(self, emphasis_only_normalizer):
|
||||
"""Test that list markers (*) are not merged with emphasis (**).
|
||||
|
||||
Regression test for: "* **Yes**" should NOT become "***Yes**"
|
||||
"""
|
||||
input_str = """1. **Start**: The user opens the login page.
|
||||
* **Yes**: Login successful.
|
||||
* **No**: Show error message."""
|
||||
result = emphasis_only_normalizer.normalize(input_str)
|
||||
assert (
|
||||
"* **Yes**" in result
|
||||
), "List marker was incorrectly merged with emphasis"
|
||||
assert (
|
||||
"* **No**" in result
|
||||
), "List marker was incorrectly merged with emphasis"
|
||||
assert "***Yes**" not in result, "BUG: List marker merged with emphasis"
|
||||
assert "***No**" not in result, "BUG: List marker merged with emphasis"
|
||||
|
||||
def test_list_marker_with_plain_text_then_emphasis(self, emphasis_only_normalizer):
|
||||
"""Test that list items with plain text before emphasis are preserved.
|
||||
|
||||
Regression test for: "* U16 forward **Kuang**" should NOT become "*U16 forward **Kuang**"
|
||||
"""
|
||||
input_str = "* U16 China forward **Kuang Zhaolei**"
|
||||
result = emphasis_only_normalizer.normalize(input_str)
|
||||
assert "* U16" in result, "List marker spaces were incorrectly stripped"
|
||||
assert (
|
||||
"*U16" not in result or "* U16" in result
|
||||
), "BUG: List marker spaces stripped"
|
||||
|
||||
|
||||
class TestEmphasisInCodeBlocks:
|
||||
"""Test that emphasis inside code blocks is NOT modified."""
|
||||
|
||||
def test_emphasis_in_code_block_unchanged(self, emphasis_only_normalizer):
|
||||
"""Code blocks should be completely skipped."""
|
||||
input_str = "```python\nmy_var = get_data__from_api()\n```"
|
||||
assert emphasis_only_normalizer.normalize(input_str) == input_str
|
||||
|
||||
def test_mixed_emphasis_and_code(self, emphasis_only_normalizer):
|
||||
"""Text outside code blocks should be fixed, inside should not."""
|
||||
input_str = "** bold ** text\n```python\n** not bold **\n```"
|
||||
expected = "**bold** text\n```python\n** not bold **\n```"
|
||||
assert emphasis_only_normalizer.normalize(input_str) == expected
|
||||
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Tests for heading fix.
|
||||
Covers: Missing space after # in headings.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestHeadingFix:
|
||||
"""Test heading space normalization."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_str,expected",
|
||||
[
|
||||
("#Heading", "# Heading"),
|
||||
("##Heading", "## Heading"),
|
||||
("###Heading", "### Heading"),
|
||||
("#中文标题", "# 中文标题"),
|
||||
("#123", "# 123"), # Numbers after # also get space
|
||||
],
|
||||
)
|
||||
def test_missing_space_added(self, normalizer, input_str, expected):
|
||||
"""Headings missing space after # should be fixed."""
|
||||
assert normalizer.normalize(input_str) == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_str",
|
||||
[
|
||||
"# Heading",
|
||||
"## Already Correct",
|
||||
"###", # Just hashes
|
||||
],
|
||||
)
|
||||
def test_correct_headings_unchanged(self, normalizer, input_str):
|
||||
"""Already correct headings should not be modified."""
|
||||
assert normalizer.normalize(input_str) == input_str
|
||||
|
||||
|
||||
class TestTableFix:
|
||||
"""Test table pipe normalization."""
|
||||
|
||||
def test_missing_closing_pipe_added(self, normalizer):
|
||||
"""Tables missing closing | should have it added."""
|
||||
input_str = "| col1 | col2"
|
||||
result = normalizer.normalize(input_str)
|
||||
assert result.endswith("|") or "col2 |" in result
|
||||
|
||||
def test_already_closed_table_unchanged(self, normalizer):
|
||||
"""Tables with closing | should not be modified."""
|
||||
input_str = "| col1 | col2 |"
|
||||
assert normalizer.normalize(input_str) == input_str
|
||||
6
pytest.ini
Normal file
6
pytest.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
[pytest]
|
||||
testpaths = plugins
|
||||
python_files = test_*.py
|
||||
python_classes = Test*
|
||||
python_functions = test_*
|
||||
addopts = -v --tb=short
|
||||
Reference in New Issue
Block a user