Skip to content

Releases: helloworldtang/wechat-md

v0.5.0

Choose a tag to compare

@helloworldtang helloworldtang released this 04 Oct 14:36

变更

  • 修复开界侧粗体死角:水在流**(观察到的现象**) 这类写法(** 前紧贴文字、后紧跟标点)此前不做强调转换,字面 ** 直进 HTML;现在渲染前把开界后的标点串整串移出粗体(流**(X**) → 流(**X**))后正常转 strong。
  • 归一化实现从正则替换改为 CommonMark 分隔符配对算法;闭界侧死角(**X。**后文)行为与 0.4.0 一致。

为什么

CommonMark flanking 规则下,开界 ** 后紧跟标点且前非空白/标点时不是 left-flanking,markdown2(含 2.5.5)不做转换(2026-10-04 公众号草稿实测踩中;半角括号同样命中)。0.4.0 的正则规则在多粗体文本里还会把前一粗体的闭界误当开界锚点、跨粗体错位配对(**A**!**B**c 形态);配对算法先按 flanking 配对(原生可转换的绝不碰),只对落单的死角对搬标点。与 wechat-publish-service(Rust)的 render::bold_punct 算法保持同步。

验证:32 测试全绿(ruff / mypy strict 通过);干净 venv 安装构建产物后,线上草稿原句 4 处粗体全部转 strong、无字面 **。

升级命令

pip install -U wechat-md==0.5.0

消费方指引

  • 纯输出行为变更:仅受影响写法(死角形态)的渲染结果改变,合法写法逐字节不变;围栏代码块与行内代码内容不改。
  • 引 GitHub 源请锁 tag:.../archive/refs/tags/v0.5.0.tar.gz,不要引滚动的 main。

v0.4.0

Choose a tag to compare

@helloworldtang helloworldtang released this 23 Sep 06:01

变更

  • 修复:粗体尾部标点后紧跟文字(**X。**后缀)不再输出字面 **,正常渲染为 strong。段落与列表内行为一致。
  • 渲染前预归一化:命中失败面时把粗体尾部标点串整串移出粗体(**X。** → **X**。);后跟空白/标点/行尾的写法本来就能正常转换,一律不动。围栏代码块与行内代码内容不改。
  • 版本 0.3.0 → 0.4.0:受影响写法的渲染输出改变,按约定升 minor。

为什么

markdown2(含最新 2.5.5)对「粗体内部以标点结尾 + 关闭 ** 外侧紧跟汉字/字母」的写法不做强调转换,字面 ** 直接进 HTML;CommonMark 规范此处应为 strong,属实现不合规。线上踩中场景:公众号早报「1. **标签句。**说明」列表条目,成片字面 ** 读者可见。

验证证据:markdown2 裸库矩阵测试圈定精确失败面(12 用例,后跟标点/空白/行尾均正常);修复后全量 27 测试通过(新增 5 个回归用例覆盖复现写法、段落、标点串、不受影响面、代码保护),ruff + mypy strict 全绿;围栏/行内代码内的 ** 原样保留已由测试锁定。

已知代价:尾部标点串整串移出(如 **涨了3%。** → <strong>涨了3</strong>%。),% 不再粗体——只移末一个标点仍会踩 markdown2 死角,整串移出是转换成立的必要条件。

升级命令

pip install -U wechat-md==0.4.0

消费方指引

  • exomind(myExoMindManager):升级依赖并部署后,公众号投递的正文不再出现字面 **。
  • 直接消费 markdown_to_html 的调用方:仅「粗体尾部标点紧跟文字」类输入的输出发生变化(原先就是坏的),其余输入输出不变(含不传 theme 的逐字节回归护栏)。
  • 引用 GitHub 源请锁 refs/tags/v0.4.0.tar.gz,不要引滚动的 main。

v0.3.0

Choose a tag to compare

@helloworldtang helloworldtang released this 23 Sep 03:41

变更

  • 可选主题(配色覆盖):markdown_to_html(text, theme={...}) 按主题着色,键与 wechat-publish-service 的 ThemeConfig 对齐;不传 theme 时配色与历史版本一致(回归测试保障)。
  • 列表 → section 条目:ul/ol 逐条改为 <section>• 文本</section>(有序列表保留 N. 序号前缀);嵌套列表或 li 含块级元素时整段放弃改写、原样保留。
  • 外域链接内联成「文字,URL」:mp.weixin.qq.com 互链保持真锚点;链接文字含标签或已含 URL 时不冒险改写。

为什么

2026-09 线上实测(拉回公众号后台实际存储的 HTML 复核):

  • 公众号编辑器会把 li 内「内联元素+后续文本」拆成独立块——<strong>标签</strong> 与「:内容」断成两行,strong/span 一视同仁,列表标签在正文里不可用;
  • 外域锚点会被编辑器整个删除只留文字(连样式都不留),URL 信息彻底丢失。

两条规则与 wechat-publish-service 发布链路的优化层同构:经接口发布时幂等无害(双保险),直接粘贴编辑器场景自此受保护。验证方式:发布测试稿 → draft/get 拉回微信存储 HTML 比对,用户真机验收通过(2026-09-22/23)。

升级命令

pip install -U wechat-md==0.3.0

消费方指引

  • 经 wechat-publish-service(yyps)发布的内容无需升级也有同等保护(服务端优化层已上线),升级只是让本地直出 HTML 与发布产物一致;
  • 引用 GitHub 源请锁 tag:.../archive/refs/tags/v0.3.0.tar.gz,不要引滚动的 main;
  • 行为变更集中在列表与外链的输出结构,若下游对这两类 HTML 做了断言,升级前请同步期望值。

v0.2.1 — PyPI 首发

Choose a tag to compare

@helloworldtang helloworldtang released this 03 Sep 05:46

变更

  • PyPI 首发:pip install wechat-md==0.2.1 即可安装,project 页面 https://pypi.org/project/wechat-md/
  • README 专业化重写:面向「公众号排版」目标本身(排版规则一览表),移除内部实现史叙述
  • 发版元数据补全:classifiers(Python 3.9–3.13)/Project-URLs/作者
  • 版本单一来源:pyproject 经 hatch 动态读 __init__.py(根治 pyproject 与 __init__ 版本不同步)
  • CI(.github/workflows/publish.yml):tag 触发,质量门(ruff/mypy strict/pytest)作为发布前置,Trusted Publishing(OIDC)免 token 上传

为什么

此前仅经 GitHub tag tarball 分发,lock 文件里是长 URL 且不可走 PyPI 镜像。上 PyPI 后消费方以版本号显式锁定安装。渲染代码与 v0.2.0 完全一致——本版纯文档/元数据/CI 变更,零行为变更(测试 12/12 全绿,ruff+mypy strict 通过,CI 运行 33719538443)。

升级命令

pip install wechat-md==0.2.1

消费方指引

  • 引用一律锁版本号 wechat-md==X.Y.Z,升级 = 显式改版本号的决策动作
  • 原 GitHub tarball 引用(.../refs/tags/vX.Y.Z.tar.gz)可继续使用,建议迁移到 PyPI
  • 后续发版流程:commit → git tag -a vX.Y.Z → push tag,CI 自动过质量门并发布

v0.2.0 — 标题单层 border-left,根治微信编辑器复制多换行

Choose a tag to compare

@helloworldtang helloworldtang released this 03 Sep 04:09

变更

  • 标题竖条改单层 border-left(h1 4px / h2 3px),替换旧 3 层 flex 嵌套(section>flex容器>竖条section+p)
  • h3 拍扁多余 section 包裹层为单层 p
  • 新增单层结构断言测试(标题输出不得出现 display:flex),防回退

为什么(行为变更)

旧 3 层结构里竖条是独立 DOM 节点:在微信编辑器中可被单独选中,从草稿箱复制文字到聊天窗口时,每层块边界各贡献一个换行(标题前后多空行)。border-left 是 CSS 边框——非节点、不可选中、零换行贡献。

验证

  • 机器:无头 Chrome 复制序列化——旧 5 换行/标题前 1,新 3/0
  • 人工:丹心草稿箱 A/B 对照终审——旧版竖条可选中和产生换行,新版均无
  • 质量:12 测试全绿 + ruff (E,W,F,I,B,C4,UP,SIM) + mypy --strict 全清

升级

pip install https://github.com/helloworldtang/wechat-md/archive/refs/tags/v0.2.0.tar.gz

消费方(exomind 服务端、OpenClaw 本地链路)升级指引见各自 TODO。