首页
AndyYan's DN42 Network
友链
关于
Search
1
MaiBot+AstrBot+Napcat分离部署,实用、稳定且拟人化的QQBot部署方案
201 阅读
2
Linux环境下的Silly Tavern 云酒馆 AI 搭建与美化完善(几乎0基础?)
91 阅读
3
解决OMV登陆WebUI时400 Bad Request错误
62 阅读
4
IOS系统解压.lz4格式压缩包
62 阅读
5
搭建Grafana监测Bird运行状态
21 阅读
所有文章
NAS
BOT
登录
Search
AndyYan
累计撰写
8
篇文章
累计收到
0
条评论
首页
栏目
所有文章
NAS
BOT
页面
AndyYan's DN42 Network
友链
关于
搜索到
8
篇与
的结果
2026-06-04
LinuxDo邀请码
本人linuxdo已三级,现在每天在博客上免费公开本帐号生成的邀请码一枚(今日暂无)3h后妥善使用,申请前请阅读linuxdo的置顶帖子和社区规则!
2026年06月04日
7 阅读
0 评论
0 点赞
2026-04-05
Typecho + JOE 主题下 Mermaid 渲染的解决方案
阅前须知:由于博主现在 并没有太多自己写代码甚至脚本的能力 ,本篇文章在我和AI共同解决了这个问题之后 直接由AI生成 ,若你对此感到反感,可以现在 关闭该帖 ( 我是废物 )一、问题背景在 Typecho 中使用 Mermaid 一直不算难,但一旦换成 JOE 主题,问题就开始变得复杂:写好的 `mermaid 代码块被当成普通代码高亮插件明明启用了,但图表不渲染翻页(PJAX)后 Mermaid 直接失效我一开始也尝试用常规方案(正则替换 HTML),结果发现:👉 根本不稳定二、问题的本质JOE 主题做了很多“增强”,包括:自定义代码高亮(Prism / Highlight.js)改写 Markdown 输出结构使用 PJAX(局部刷新页面)这导致一个核心问题:你在后端生成的 HTML,很可能在前端被再次修改甚至覆盖例如你期望的是:<pre><code class="language-mermaid"></code></pre>但实际可能变成:<pre class="language-mermaid"></pre>甚至:<div class="joe_code"> <pre>...</pre> </div>👉 结构不稳定 → 正则必炸三、传统方案为什么不行?常见插件思路:Markdown → HTML → 正则替换 → <pre class="mermaid">问题在于:依赖 HTML 结构(不可靠)容易被主题覆盖PJAX 后不会重新执行结论:后端改 HTML,在 JOE 这种强主题下是错误方向四、最终解决方案:前端接管我最后采用的是:✅ 完全绕过后端,前端动态解析 Mermaid核心流程:页面加载 ↓ 扫描所有 language-mermaid 代码块 ↓ 替换为 .mermaid DOM ↓ 调用 Mermaid 渲染五、核心实现解析1. 扫描代码块const blocks = document.querySelectorAll( 'pre code.language-mermaid, pre.language-mermaid' );为什么这样写?👉 兼容两种结构:<pre><code class="language-mermaid"></code></pre><pre class="language-mermaid"></pre>2. 提取原始代码let code = codeBlock.textContent;👉 直接拿文本,不依赖 HTML 结构3. 重建 DOMconst container = document.createElement('div'); container.className = 'mermaid-container'; const mermaidDiv = document.createElement('div'); mermaidDiv.className = 'mermaid'; mermaidDiv.textContent = code; container.appendChild(mermaidDiv);最终结构:<div class="mermaid-container"> <div class="mermaid">...</div> </div>4. 替换原代码块pre.replaceWith(container);👉 关键点:删除原代码高亮 DOM避免主题再次干扰5. 渲染 Mermaidmermaid.initialize({ startOnLoad: false, theme: getTheme() }); mermaid.init(undefined, document.querySelectorAll('.mermaid'));为什么不用自动加载?👉 因为 DOM 是动态生成的6. 防止重复渲染if (codeBlock.dataset.mermaidDone) return;👉 防止:PJAX 重复执行多次渲染报错7. 适配 PJAX(关键)document.addEventListener('pjax:complete', run);👉 没有这行:❌ 翻页后 Mermaid 全部失效六、主题适配(暗黑模式)function getTheme() { if (document.body.classList.contains('dark')) { return 'dark'; } return 'default'; }👉 自动跟随主题切换七、为什么这个方案最稳?对比一下:方案稳定性原因后端正则替换❌依赖 HTML修改 Markdown 解析❌被主题覆盖前端接管(本方案)✅直接操作 DOM八、核心设计思想这次优化本质上是一次“架构调整”:1️⃣ 不和主题抢控制权JOE 已经接管了渲染链:👉 你再插手,只会冲突2️⃣ 前端才是最终执行层只要页面上存在:language-mermaid👉 就一定能识别3️⃣ 幂等设计data-mermaidDone👉 保证多次执行不会出问题九、最终效果✅ 支持所有 Mermaid 图✅ 支持 PJAX✅ 不受代码高亮影响✅ 自动暗黑模式✅ 主题无关(通用)十、一句话总结与其试图修补被主题打乱的 HTML,不如直接绕过它,在前端重建渲染链。十一、源码附上{collapse}{collapse-item label="过长,已折叠,点击查看" close}<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; /** * Mermaid 插件(JOE终极兼容版 / 前端解析) * * @package MermaidUltimate * @version 2.0.0 */ class Mermaid_Plugin implements Typecho_Plugin_Interface { public static function activate() { Typecho_Plugin::factory('Widget_Archive')->header = array('Mermaid_Plugin', 'header'); Typecho_Plugin::factory('Widget_Archive')->footer = array('Mermaid_Plugin', 'footer'); } public static function deactivate() {} public static function config(Typecho_Widget_Helper_Form $form) { $cdn = new Typecho_Widget_Helper_Form_Element_Text( 'cdn', null, 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js', _t('Mermaid CDN'), _t('推荐 jsdelivr 或 npmmirror') ); $form->addInput($cdn); $theme = new Typecho_Widget_Helper_Form_Element_Select( 'theme', array( 'default' => 'Default', 'dark' => 'Dark', 'forest' => 'Forest', 'neutral' => 'Neutral', ), 'default', _t('主题'), _t('Mermaid 渲染主题') ); $form->addInput($theme); $autoDark = new Typecho_Widget_Helper_Form_Element_Radio( 'autoDark', array( '1' => '开启', '0' => '关闭' ), '1', _t('自动暗黑模式'), _t('根据 JOE 主题自动切换') ); $form->addInput($autoDark); } public static function personalConfig(Typecho_Widget_Helper_Form $form) {} public static function header() { echo '<style> .mermaid-container { text-align: center; margin: 1em 0; } </style>'; } public static function footer() { $options = Helper::options()->plugin('Mermaid'); $cdn = $options->cdn ?: 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js'; $theme = $options->theme ?: 'default'; $autoDark = $options->autoDark; echo <<<HTML <script src="{$cdn}"></script> <script> (function () { function getTheme() { if ({$autoDark} == 1) { if (document.documentElement.classList.contains('dark') || document.body.classList.contains('dark')) { return 'dark'; } } return '{$theme}'; } function convertMermaid() { // 找到所有 mermaid 代码块 const blocks = document.querySelectorAll( 'pre code.language-mermaid, pre.language-mermaid' ); blocks.forEach(function(codeBlock) { // 防重复处理 if (codeBlock.dataset.mermaidDone) return; codeBlock.dataset.mermaidDone = "1"; let code = codeBlock.textContent; // 创建容器 const container = document.createElement('div'); container.className = 'mermaid-container'; const mermaidDiv = document.createElement('div'); mermaidDiv.className = 'mermaid'; mermaidDiv.textContent = code; container.appendChild(mermaidDiv); // 替换整个 pre let pre = codeBlock.closest('pre'); if (pre) { pre.replaceWith(container); } else { codeBlock.replaceWith(container); } }); } function renderMermaid() { if (typeof mermaid === 'undefined') { console.warn('Mermaid not loaded'); return; } try { mermaid.initialize({ startOnLoad: false, theme: getTheme() }); mermaid.init(undefined, document.querySelectorAll('.mermaid')); } catch (e) { console.error('Mermaid error:', e); } } function run() { convertMermaid(); renderMermaid(); } // 首次加载 document.addEventListener('DOMContentLoaded', run); // JOE PJAX document.addEventListener('pjax:complete', function () { run(); }); })(); </script> HTML; } }{/collapse-item}{/collapse}十二、使用方法:把这个文件放到:/usr/plugins/Mermaid/Plugin.php进入 Typecho 后台: 控制台 → 插件 → 启用 Mermaid 写文章时使用 Mermaid就直接在 Markdown 里写:发布后就会自动渲染成图。
2026年04月05日
21 阅读
0 评论
0 点赞
2026-04-05
使用screen/tmux命令实现SSH中任务后台运行
前言:在我们使用ssh的时候正常情况下,如果我们退出ssh,进程会被杀掉,导致一些需要运行较长时间(比如 rsync/cp )的命令中断,十分的难受,这里提供两种解决办法:1.使用screen1.1开启 screen:screen -S upload1.2执行命令##举例 rsync -avh --progress /data/myfolder/ /mnt/myfolder/1.3退出SSH保持后台运行:按:Ctrl + A 然后按 D1.4重新连接后恢复screen -r upload2.使用tmux2.1启动tmuxtmux new -s upload2.2执行命令后,退出保持后台Ctrl + B 然后按 D2.3重新连接后恢复tmux attach -t upload
2026年04月05日
14 阅读
0 评论
0 点赞
2026-03-13
Linux环境下的Silly Tavern 云酒馆 AI 搭建与美化完善(几乎0基础?)
{alert type="info"}感谢McD大佬的指导{/alert}前言Silly Tavern Chat(云酒馆) 是一个强大的AI Role Play网站,依赖于庞大的社区资源,可以实现多样化的角色互动。 支持国内外多种AI模型,有着比较直观 但一点也不好看 的用户界面。其实酒馆ai可以直接部署在很多设备上(安卓,Windows),但是不便于多端同步等等,将酒馆部署在云端可以使用WebUI方便的使用任何设备访问酒馆。下面是从0开始的云端Silly Tavern部署教程。前期准备{x} 一台至少1核2G的云服务器(推荐JP区域){x} 本地SSH工具(我使用的是termius){x} 一点点linux基本使用技巧{x} 已对Silly Tavern有一定了解{x} 最好加入了类脑ΟΔΥΣΣΕΙΑ社区,截至2026/03/12仍然是开放状态开始部署0.SSH的连接0.1打开Termius(这里以电脑版举例)0.2点击 NEW HOST,在红框内填写IDC商家提供给你的信息( Lable 就是你给vps起的名字)0.3点击 Connect 连接1.安装1panel面板为了方便萌新进行后续反代等等的搭建,建议先安装1p。输入下方这串命令,按提示操作(提示是否安装docker时直接按enter键)bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)"{alert type="warning"}安装完之后一定要记住访问地址与端口号!{/alert}2.获取项目2.1首先安装gitsudo apt update ##一行一行执行 sudo apt install git2.2从github拉取项目git clone https://github.com/SillyTavern/SillyTavern等待一会拉取3.启动容器,调整参数3.1启动容器cd SillyTavern/docker docker compose up -d3.2编辑配置文件sudo nano config/config.yaml此时进入到你 config 配置文件点击向下,直到看到 whitelistMode 把后面的 true 改为 false 再往下找到basicAuthMode把false改为true最后在下方设置你的账号密码按 ctrl+O ,再按 enter 接着按 ctrl+X 保存退出nano编辑器3.3重启容器,使改动生效docker compose restart sillytavern到此处恭喜你酒馆AI搭建已经完成。打开浏览器输入 http://<你的ip>:8000 访问界面4.基础参数设置打开WebUI跟随它的提示进行填写,这里不多提。5.美化先贴一张效果图我使用的是类脑频道里面这位大佬的美化方案这个美化很重要的一点就是对手机端非常友好:在滑动 正则 时不会误触改变顺序没有进频道的我这里提供下载链接修改方式如下:6.优化与增强在最上面一栏从右往左第三个里可以安装拓展,从而增强酒馆游玩的舒适度主要是下面这几个:6.1酒馆助手这是项目地址6.2提示词模板这是项目地址6.3文生图插件这是项目地址7.域名反代{ } 待完成
2026年03月13日
91 阅读
0 评论
0 点赞
2026-03-13
IOS系统解压.lz4格式压缩包
前言大家可能会遇到lz4格式的压缩包(多见于防止用户 手贱 在线解压的网盘资源),这时安卓可以使用ZArchiver方便的解压,但是ios就不行了,这里分享一个基于iSH的解压教程。开整1.下载iSH这里用到了一个叫做iSH的工具,这是一个适用于 iOS 设备的开源终端模拟器,相当于一个轻量化的linux环境。直接打开AppStore搜索 iSH 下载 2.打开 iSH,安装 lz4apk add lz43.把.lz4文件导入iSH通过“文件”App分享 → iSH)4.开始解压lz4 -d <XXX.lz4> <输出文件名> #注:自行替换尖括号里面的内容为实际名称{collapse}{collapse-item label="example" close}lz4 -d test.lz4 test.rar{/collapse-item}{/collapse}5.验证解压结果ls -a
2026年03月13日
62 阅读
0 评论
0 点赞
1
2