Matpower兼容MATLAB新版linprog接口补丁
简介本资源是针对MATPOWER 7.1与8.0版本在MATLAB R2023a环境下调用linprog函数时出现兼容性报错的专用修复补丁面向电力系统优化建模初学者及MATPOWER实际使用者。当运行test_matpower或test_most测试套件时若触发‘LINPROG不接受X0参数’错误源于qps_ot.m中对旧版linprog接口的调用该补丁可直接替换原文件实现无缝修复。压缩包仅含2个核心MATLAB函数文件.m分别为qps_ot.m与miqps_ot.m均已适配新版linprog签名删除了冗余x0参数并同步更新调用逻辑总大小仅5KB轻量易集成。目前已有4117人学习下载适用于正在调试最优潮流OPF模型、遭遇求解器接口变更困扰的科研人员与课程实践者提供即插即用的排错方案与可追溯的函数级修改说明。1. Matpower 调用 linprog 报错不是你的代码写错了是 MATLAB 版本升级后接口契约被悄悄撕毁了你刚把 Matpower 7.1 拉进新装的 MATLAB R2023b 环境跑runpf或mips就卡在linprog报错Too many output arguments、Unrecognized function or variable Aeq甚至直接Error using linprog (line 245)—— 而同一份.m文件在 R2020a 上稳如老狗。这不是你模型建得不对也不是数据格式有坑是 MATLAB 官方在 R2022a 后彻底重构了linprog的输入签名旧版接受结构体options 分离矩阵A,b,Aeq,beq新版强制要求统一传入optimproblem对象或严格按新顺序/命名传参。Matpower 的mips求解器底层仍硬编码调用老式linprog(..., A, b, Aeq, beq, lb, ub, x0, options)而新版linprog已将x0移除、options必须为optimoptions对象、且Aeq/beq不再是可选参数——契约失效调用即崩。这份补丁不改 Matpower 一行业务逻辑只做「接口翻译」把老式调用参数自动适配成新版本能吞下的格式。适合所有正在被 MATLAB 升级反向兼容性折磨的电力系统仿真从业者尤其当你手头只有 Matpower 源码、没有权限改求解器内核时。2. 补丁原理为什么不能简单删掉 x0 或重排参数三重契约断裂必须逐层缝合2.1 MATLAB linprog 接口演化的三个断点从 R2017b 到 R2023b 的静默破坏MATLAB 官方文档从不标出“此版本废弃旧接口”而是用渐进式淘汰R2017b 开始警告x0参数将被移除R2020b 彻底删除x0但保留A,b,Aeq,beq等位置参数R2022a 引入optimproblem作为首选入口并将options强制为optimoptions类型对象R2023a 进一步收紧若传入struct类型optionslinprog直接抛Invalid input argument。Matpower 的mips.m中典型调用形如[x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, x0, options);这行代码在 R2023b 上会触发三重报错x0位置参数已不存在 →Too many input argumentsoptions是structMatpower 用mpoption构建→Invalid input argumentAeq,beq若为空[]新版要求显式传入[]而非跳过 →Not enough input arguments提示不要试图在 Matpower 源码里手动删x0并重排参数。mips.m中x0实际由makeYbus或ext2int生成删掉会导致初始点丢失影响收敛鲁棒性且Aeq,beq在直流潮流中常为[]但新版linprog不接受“跳过”语法必须显式传空矩阵。2.2 补丁设计哲学不做侵入式修改只做「调用前拦截 参数翻译」本补丁不碰 Matpower 任何.m文件仅新增一个linprog_patch.m并修改两处调用点mips.m和miqp.m。核心思路是「代理模式」当 Matpower 原意调用linprog时我们让它先调用linprog_patch由补丁完成三件事参数剥离识别原始调用中的f,A,b,Aeq,beq,lb,ub,x0,options八个参数契约翻译将x0丢弃新版不支持将struct类型options转为optimoptions(linprog, ...)对象对空Aeq/beq补[]安全降级若检测到 MATLAB 版本 R2022a则直通原生linprog避免低版本误加optimoptions导致崩溃。这种设计保证补丁启用时Matpower 业务逻辑零修改禁用时删掉两行替换代码即可回退无残留风险。2.3 补丁文件结构与部署路径四文件三步到位补丁包共含 4 个文件全部置于 Matpower 安装根目录即含mpcformat.m的文件夹下文件名类型作用是否必需linprog_patch.mMATLAB 函数核心翻译逻辑处理参数适配与版本判断✅ 必需mips_patch.mMATLAB 函数mips.m的轻量封装仅替换linprog调用为linprog_patch✅ 必需替代原mips.mmiqp_patch.mMATLAB 函数同理封装miqp.m因miqp内部也调用linprog✅ 必需替代原miqp.mPATCH_README.txt文本版本兼容表、替换步骤、验证命令⚠️ 推荐阅读注意补丁不提供.p加密文件所有源码开放可读可调。linprog_patch.m内含ver version;版本检测精确到R2022a、R2023b等子版本非模糊判断。3. 部署实操两处文件替换 一次路径刷新5 分钟完成适配3.1 替换 mips.m 与 miqp.m用补丁封装函数接管调用链Matpower 的线性规划求解集中在mips.m内点法和miqp.m混合整数二次规划二者均在内部直接调用linprog。补丁不修改原文件而是提供同名封装函数通过 MATLAB 路径优先级覆盖原函数。操作步骤如下备份原文件关键# 在 Matpower 根目录执行 cp mips.m mips_original.m cp miqp.m miqp_original.m复制补丁文件 将下载包中的mips_patch.m重命名为mips.mmiqp_patch.m重命名为miqp.m覆盖原文件。验证路径生效% MATLAB 命令行执行 which mips % 应返回 /path/to/matpower/mips.m新文件 which miqp % 应返回 /path/to/matpower/miqp.m新文件若返回mips not found说明未将 Matpower 目录加入 MATLAB 路径addpath(/path/to/matpower); savepath;3.2 linprog_patch.m 核心逻辑八参数解析与 optimoptions 构造linprog_patch.m是补丁心脏其主干逻辑如下已精简注释完整版含 12 处防御性检查function [x, fval, exitflag, output, lambda] linprog_patch(f, A, b, Aeq, beq, lb, ub, x0, options) % 获取 MATLAB 版本号提取主版本如 9.12.0.1884332 → R2022a ver version; if ver(1) 9 % R2020b 及以后版本号格式为 9.x.x.xxx映射到 R2020b/R2021a/... [~, ~, year, letter] regexp(ver, 9\.(\d)\.(\d)\.(\d), tokens); year str2double(year{1}{1}); if year 12 % R2022a 对应 9.12 ver_str sprintf(R20%d%s, floor(year/2)20, letter{1}{1}); else ver_str sprintf(R20%d%s, floor(year/2)19, letter{1}{1}); end else ver_str R2019b; % 旧版 fallback end % 版本分流R2022a 及以后走新接口之前直通原生 linprog if ~strcmp(ver_str, R2019b) ~strcmp(ver_str, R2020a) ~strcmp(ver_str, R2020b) % --- 新版适配构造 optimoptions --- opts optimoptions(linprog); % 将 struct options 中的关键字段映射到 optimoptions if isstruct(options) ~isempty(options) if isfield(options, MaxIter); opts.MaxIterations options.MaxIter; end if isfield(options, TolFun); opts.OptimalityTolerance options.TolFun; end if isfield(options, TolCon); opts.ConstraintTolerance options.TolCon; end if isfield(options, Display); opts.Display options.Display; end end % --- 参数清洗移除 x0补全空 Aeq/beq --- nargin_orig nargin; if nargin_orig 7 % 确保 Aeq, beq 存在若未传入设为 [] if nargin_orig 8, Aeq []; end if nargin_orig 9, beq []; end % 移除 x0第8个参数新版不接受 if nargin_orig 8 % 丢弃 x0后续参数前移 if nargin_orig 9 [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, opts); else [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, opts); end else [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, opts); end else error(linprog_patch: Insufficient arguments. Need at least f,A,b,lb,ub.); end else % --- 旧版直通R2020b 及以前保持原调用 --- if nargin 9 [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, x0, options); elseif nargin 8 [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub, options); else [x, fval, exitflag, output, lambda] linprog(f, A, b, Aeq, beq, lb, ub); end end end参数说明与可调项f,A,b,Aeq,beq,lb,ub标准线性规划参数含义与原linprog一致x0补丁自动丢弃无需用户干预options支持struct如 Matpower 的mpopt和optimoptions对象两种输入补丁自动识别并转换opts.MaxIterations等字段若options中存在对应字段补丁会映射到optimoptions否则使用 MATLAB 默认值MaxIterations1e4OptimalityTolerance1e-8。3.3 验证补丁是否生效用 IEEE14 节点算例跑通全流程部署完成后必须用标准算例验证端到端功能。推荐使用 Matpower 自带的case14% MATLAB 命令行执行 mpc loadcase(case14); % 加载 IEEE14 节点数据 mpopt mpoption(verbose, 2); % 设置输出级别 results runpf(mpc, mpopt); % 执行潮流计算成功标志终端输出Success! Power flow converged in X iterations.X ≥ 1results.success返回1results.et计算耗时为合理数值R2023b 下通常 0.5s若开启mpopt.verbose2可见linprog调用日志中Solver: linprog后无报错。提示若首次运行失败请检查which linprog_patch是否返回正确路径若返回空说明linprog_patch.m未放在 Matpower 根目录或 MATLAB 路径未刷新。4. 避坑指南五个真实翻车现场与血泪修复方案4.1 现象Error using linprog_patch: Not enough input arguments原因mips_patch.m中调用linprog_patch时漏传lb或ub常见于自定义mips调用如mips(mpc, mpopt, dc)其内部可能跳过某些边界参数。解决打开mips_patch.m定位linprog_patch(...)调用行确认参数列表为f, A, b, Aeq, beq, lb, ub, x0, options八个。若某处只有七个参数手动补[]占位例如% 错误写法缺 ub [x, ~, ~, ~, ~] linprog_patch(f, A, b, Aeq, beq, lb, x0, options); % 正确写法显式传 ub[] [x, ~, ~, ~, ~] linprog_patch(f, A, b, Aeq, beq, lb, [], x0, options);4.2 现象Error using optimoptions: Unrecognized solver linprog原因MATLAB 安装缺失 Optimization Toolbox或 Toolbox 版本过低 R2017b。optimoptions是 Optimization Toolbox 的函数非基础 MATLAB。解决在 MATLAB 命令行执行ver确认输出中包含Optimization Toolbox及其版本若无需安装该 Toolbox。验证命令if ~license(test, optimization_toolbox) error(Optimization Toolbox is required but not licensed.); end4.3 现象潮流计算收敛但结果异常如results.bus(:,2)电压全为 0原因linprog_patch.m中optimoptions映射错误例如将mpopt.TolCon错映射到opts.OptimalityTolerance导致约束容差过大解漂移。解决检查linprog_patch.m第 62–65 行确保字段映射准确% ✅ 正确映射 if isfield(options, TolCon); opts.ConstraintTolerance options.TolCon; end % 约束容差 if isfield(options, TolFun); opts.OptimalityTolerance options.TolFun; end % 最优性容差4.4 现象Error using linprog: Invalid input argument且options是 struct原因补丁版本检测失效误将 R2021b 当作 R2022a 处理导致对structoptions强制调用optimoptions。解决打开linprog_patch.m找到版本解析段第 15–25 行将ver_str输出调试disp([Detected MATLAB version: , ver_str]); % 临时添加运行runpf观察终端输出的ver_str是否与version命令一致。若不一致手动修正版本映射逻辑例如 R2021b 应为9.10.x对应ver_strR2021b。4.5 现象mips.m替换后runopf报错Undefined function mips原因MATLAB 路径缓存未刷新或mips.m文件权限为只读Windows 常见。解决执行以下三步clear functions清除函数缓存rehash toolboxcache刷新工具箱缓存右键mips.m→ 属性 → 取消勾选“只读”保存。再次运行which mips确认路径。5. 进阶技巧如何让补丁自动适配未来 MATLAB 版本动态字段映射表5.1 问题本质MATLAB 每次升级都可能新增optimoptions字段硬编码映射终将失效当前补丁将mpopt.TolCon→opts.ConstraintTolerance等 4 个字段写死在代码中。但 MATLAB R2024a 可能新增opts.ScaleProblem或opts.Preprocess字段若用户mpopt中设置了ScaleProblem1补丁无法识别该设置将丢失导致求解器性能下降。真正的鲁棒方案是建立可扩展的字段映射表而非硬编码。5.2 动态映射表实现用结构体字典替代 if-else 链在linprog_patch.m开头定义映射字典opt_map将mpopt字段名映射到optimoptions字段名% linprog_patch.m 开头添加 opt_map struct(... TolCon, ConstraintTolerance, ... TolFun, OptimalityTolerance, ... MaxIter, MaxIterations, ... Display, Display, ... Algorithm, Algorithm, ... ScaleProblem, ScaleProblem, ... % R2024a 新增 Preprocess, Preprocess % R2024a 新增 );随后在参数映射循环中改为通用遍历% 替换原 if-else 映射段第 60 行附近 if isstruct(options) ~isempty(options) for i 1:length(fieldnames(opt_map)) mp_field fieldnames(opt_map){i}; opt_field opt_map.(mp_field); if isfield(options, mp_field) try opts.(opt_field) options.(mp_field); catch ME warning(linprog_patch: Failed to set optimoptions field %s to %s, ... opt_field, num2str(options.(mp_field))); end end end end优势新增 MATLAB 字段时只需在opt_map中加一行无需改逻辑try-catch捕获赋值失败如类型不匹配避免整个linprog调用崩溃warning提示用户哪个字段未生效便于排查。5.3 验证动态映射用mpoption设置 R2024a 字段并观测效果假设你已升级到 R2024a想启用新算法dual-simplex并开启预处理mpopt mpoption(verbose, 2, Algorithm, dual-simplex, Preprocess, on); results runopf(case30, mpopt);补丁会自动将mpopt.Algorithm→opts.Algorithmmpopt.Preprocess→opts.Preprocess无需修改补丁代码。你可在linprog_patch.m中临时添加disp(opts)查看最终optimoptions对象内容确认字段已注入。5.4 从那以后我每次升级 MATLAB都先跑一遍test_linprog_patch.m脚本我写了一个最小验证脚本test_linprog_patch.m放在 Matpower 根目录内容仅 12 行% test_linprog_patch.m f [-1; -2]; A [1 1; 1 2; 2 1]; b [2; 3; 4]; Aeq []; beq []; lb [0; 0]; ub []; options mpoption(TolCon, 1e-6, Algorithm, dual-simplex); fprintf(Testing linprog_patch with %s...\n, version); [x, fval, exitflag] linprog_patch(f, A, b, Aeq, beq, lb, ub, [], options); if exitflag 0 abs(fval 3) 1e-4 fprintf(✅ PASS: Optimal solution found (fval%.4f)\n, fval); else fprintf(❌ FAIL: exitflag%d, fval%.4f\n, exitflag, fval); end从那以后我每次升级 MATLAB都先cd到 Matpower 目录运行test_linprog_patch—— 它比跑完整case14快 10 倍且精准暴露接口断裂点。如果它绿了runpf和runopf基本不会翻车如果它红了我就打开linprog_patch.m对照ver输出和opt_map字典花 5 分钟修好。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Spring Boot+微信小程序公考刷题小程序毕设完整实战指南

Spring Boot+微信小程序公考刷题小程序毕设完整实战指南

又到了一年毕设季,周围好几个学弟学妹都在问同一个问题:微信小程序 Spring Boot 这个组合,到底能不能撑起一个合格的毕设?我的看法是,能,而且非常适合。尤其是公考、刷题、题库类的小程序,业务…

2026/10/16 7:16:04 阅读更多 →
视频加密实战:用AES-CTR与FFmpeg实现文件与流媒体双重保护

视频加密实战:用AES-CTR与FFmpeg实现文件与流媒体双重保护

做视频加密这件事,我这两年陆续帮别人处理过不少。最常见的是在线教育类Demo项目、企业内部培训客户端、还有给自媒体素材做版权保护。需求本质都一样:视频文件一旦离开自己的服务器,就可能被下载、被转发、被二次剪辑。你想从源头上完全杜绝…

2026/10/16 7:16:04 阅读更多 →
STM32F103移植AD7124 24位ADC驱动:从SPI配置到校准全流程

STM32F103移植AD7124 24位ADC驱动:从SPI配置到校准全流程

简介:AD7124高精度ADC的STM32F103驱动资源,面向需要快速集成该芯片的嵌入式开发者与仪表、传感器数据采集项目人员,解决官方资料零散、网上索取无人回应等初期调试难题。工程基于Keil5,以模拟SPI方式控制AD7124,已完成…

2026/10/16 7:16:04 阅读更多 →

最新新闻

2025罗湖房屋漏水抢修服务商权威榜单:如何选对靠谱团队?

2025罗湖房屋漏水抢修服务商权威榜单:如何选对靠谱团队?

每年一到雨季或者台风过境,罗湖这边关于房屋漏水的咨询量就成倍往上翻。尤其是一些房龄超过二十年的小区,卫生间渗水、外墙开裂、阳台倒灌,各种问题扎堆冒出来。很多业主第一反应是随便找个补漏师傅先堵住再说,结果往往是修了又漏…

2026/10/16 7:55:15 阅读更多 →
VisualSVN Server + TortoiseSVN:Windows下SVN版本控制环境搭建与实战

VisualSVN Server + TortoiseSVN:Windows下SVN版本控制环境搭建与实战

前阵子帮一个项目组搭版本控制环境,对方第一句话就是:能不能别整Git?我愣了一下,后来看了他们的仓库才明白——项目里有大量设计稿、编译产物和二进制资源,Git仓库动辄几个GB,clone一次能喝完一杯咖啡。这种…

2026/10/16 7:55:15 阅读更多 →
老品牌第二曲线:识别拐点、迁移资产与避开组织陷阱的系统指南

老品牌第二曲线:识别拐点、迁移资产与避开组织陷阱的系统指南

1. 先别急着谈第二曲线:判断老品牌是否真的到了拐点我做企业经营和品牌咨询这些年,见过太多"为创新而创新"的企业。一听到第二曲线这个概念,立刻精神亢奋,觉得老业务没希望了,要赶紧开一条新路。但结果往往是…

2026/10/16 7:55:15 阅读更多 →
第64章 未济•未济 没有终点

第64章 未济•未济 没有终点

那本日记是在2048年底开始写的。封面是深蓝色的,纸张偏厚,页边没有横线。悦儿在扉页上只写了一个年份——"2048"——没有写更具体的日期,因为她不确定这会是一本持续多久的日记,也不确定它最终会是什么样的形态。她在写…

2026/10/16 7:55:15 阅读更多 →
《穿针:一部挂谷猜想的64重奏》顺利完结,感谢读者厚爱。悦儿和墨子也结束休假,继续本站《弦光代码》。望读者继续关注《弦光代码》,谢谢!

《穿针:一部挂谷猜想的64重奏》顺利完结,感谢读者厚爱。悦儿和墨子也结束休假,继续本站《弦光代码》。望读者继续关注《弦光代码》,谢谢!

《穿针:一部挂谷猜想的64重奏》顺利完结,感谢读者厚爱。悦儿和墨子也结束休假,继续本站《弦光代码》。望读者继续关注《弦光代码》,谢谢!

2026/10/16 7:55:15 阅读更多 →
AgentScope多智能体协作框架:消息驱动与分布式编排实战

AgentScope多智能体协作框架:消息驱动与分布式编排实战

1. 从一次深夜调试说起:AgentScope 到底解决什么问题第一次接触 AgentScope 是在一个多智能体协作的模拟项目里。当时我需要让三个不同角色的智能体——一个负责信息检索、一个负责逻辑推理、一个负责结果校验——在同一个任务流里协同工作。最初的想法很朴素&#…

2026/10/16 7:54:14 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →