Pandoc 2.x图片替代文本渲染存可访问性问题,求解决方案
问题原因分析
Pandoc 2.x版本对图片(尤其是带说明的figure)的HTML渲染逻辑做了大幅调整,主要是为了对齐CommonMark规范,同时区分“图片替代文本(alt)”和“图片标题(caption)”的作用:
- 对于无alt文本的装饰图(
):1.19版本会默认用<p class="figure">包裹,但2.x版本简化了结构,直接用普通<p>包裹,并且因为没有提供alt文本,所以不会生成alt=""属性(这其实符合基础HTML规范,但确实影响了屏幕阅读器对装饰图的识别——按照无障碍标准,装饰图应该设置alt=""来告知屏幕阅读器忽略它)。 - 对于带alt文本的图片(
):2.x版本将alt文本直接作为figure的caption,同时清空了img的alt属性。Pandoc的默认逻辑认为“caption是给视觉用户看的说明,alt是给屏幕阅读器的替代文本”,但这里的处理完全割裂了两者,导致屏幕阅读器无法获取图片的核心描述。
可行的调整方案
不用依赖后置JS,有两种更优雅的原生解决方式:
1. 自定义HTML模板
创建一个自定义的HTML模板,修改figure和图片的渲染逻辑,完全按照你需要的结构输出:
首先,创建一个名为figure-template.html的文件,核心部分如下:
<!DOCTYPE html> <html>$for(head)$ $head$$endfor$ <body>$for(body)$ $body$$endfor$ $if(figure)$ <div class="figure"> <img src="$figure.src$" alt="$figure.alt$"$if(figure.width)$ width="$figure.width"$endif$>$if(figure.caption)$ <p class="caption" aria-hidden="true">$figure.caption$</p>$endif$ </div> $endif$ </body> </html>
然后转换时指定模板:
pandoc input.md --template=figure-template.html -o output.html
2. 使用Lua过滤器(更灵活)
如果不想修改完整模板,可以写一个轻量的Lua过滤器,动态调整图片的输出结构:
创建fix-image-figures.lua脚本:
-- 处理图片元素,调整HTML输出结构 function Image(img) -- 情况1:无alt文本的装饰图,添加figure类和空alt属性 if #img.caption == 0 then img.attr.attributes.alt = "" local p_tag = pandoc.Para({img}) p_tag.attr.class:insert("figure") return p_tag -- 情况2:有alt文本的图片,生成符合无障碍标准的figure结构 else local figure_div = pandoc.Div({}, "figure") -- 保留图片的alt文本 local img_with_alt = pandoc.Image(img.caption, img.src, img.title, img.attr) -- 创建带aria-hidden的caption,避免屏幕阅读器重复读取 local caption_para = pandoc.Para(img.caption) caption_para.attr.class:insert("caption") caption_para.attr.attributes["aria-hidden"] = "true" -- 组装最终的figure结构 figure_div.content:extend({img_with_alt, caption_para}) return figure_div end end
转换时加载过滤器:
pandoc input.md --lua-filter=fix-image-figures.lua -o output.html
这两种方式都能完美实现你需要的HTML结构,避免了后置JS的繁琐。
内容的提问来源于stack exchange,提问作者Joshua Muheim
相关产品推荐
相关产品推荐

