You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CommonMark(MarkDown)中使用picture标签实现WEBP与JPG兼容?

在PHP的CommonMark中实现WEBP与JPG兼容的<picture>标签

下面提供几种可行的实现方案,按需选择:

方案1:直接启用原生HTML支持

CommonMark默认会转义HTML标签,只需在配置中开启允许原生HTML的选项,即可直接在Markdown内容里写入完整的<picture>代码块。

配置与使用示例:

use League\CommonMark\Environment\Environment;
use League\CommonMark\MarkdownConverter;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;

$config = [
    'html_input' => 'allow', // 核心配置:允许原生HTML解析
    'allow_unsafe_links' => false,
];

$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());

$converter = new MarkdownConverter($environment);

// 在Markdown中直接使用picture标签
$markdown = <<<MD
这是一张兼容多格式的图片:
<picture>
  <source type="image/webp" srcset="flower.webp">
  <source type="image/jpeg" srcset="flower.jpg">
  <img src="flower.jpg" alt="一朵花">
</picture>
MD;

echo $converter->convert($markdown);

方案2:自定义Markdown语法与扩展(更优雅的写法)

如果不想直接写冗长的HTML,可以自定义简洁的Markdown语法(比如![alt文本](webp路径|jpg路径)),通过自定义扩展将其自动解析为<picture>标签。

步骤1:创建自定义行内解析器

use League\CommonMark\Inline\Parser\InlineParserInterface;
use League\CommonMark\Parser\Inline\InlineParserMatch;
use League\CommonMark\Parser\InlineParserContext;
use League\CommonMark\Node\Inline\Image;

class PictureImageParser implements InlineParserInterface
{
    public function getMatchDefinition(): InlineParserMatch
    {
        // 匹配自定义语法:![alt](webp路径|jpg路径)
        return InlineParserMatch::regex('\!\[(.*?)\]\((.*?)\|(.*?)\)');
    }

    public function parse(InlineParserContext $context): bool
    {
        $matches = $context->getMatches();
        $altText = $matches[1];
        $webpSrc = $matches[2];
        $jpgSrc = $matches[3];

        // 创建图片节点并存储WEBP路径的额外数据
        $imageNode = new Image($jpgSrc, $altText);
        $imageNode->data->set('webp_src', $webpSrc);

        $context->getCursor()->advanceBy(\strlen($matches[0]));
        $context->getContainer()->appendChild($imageNode);

        return true;
    }
}

步骤2:创建自定义渲染器

use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlElement;
use League\CommonMark\Node\Inline\Image;

class PictureImageRenderer implements NodeRendererInterface
{
    public function render(Node $node, ChildNodeRendererInterface $childRenderer)
    {
        if (!($node instanceof Image)) {
            throw new \InvalidArgumentException('仅支持Image类型节点');
        }

        $webpSrc = $node->data->get('webp_src');
        // 如果没有WEBP源,渲染为普通img标签
        if (!$webpSrc) {
            return new HtmlElement('img', [
                'src' => $node->getUrl(),
                'alt' => $node->getAlt(),
            ]);
        }

        // 构建完整的picture标签结构
        $picture = new HtmlElement('picture', [], '');
        $picture->appendChild(new HtmlElement('source', [
            'type' => 'image/webp',
            'srcset' => $webpSrc,
        ]));
        $picture->appendChild(new HtmlElement('source', [
            'type' => 'image/jpeg',
            'srcset' => $node->getUrl(),
        ]));
        $picture->appendChild(new HtmlElement('img', [
            'src' => $node->getUrl(),
            'alt' => $node->getAlt(),
        ]));

        return $picture;
    }
}

步骤3:注册扩展并使用

use League\CommonMark\Environment\Environment;
use League\CommonMark\MarkdownConverter;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;

$config = [];
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());

// 注册自定义解析器与渲染器
$environment->addInlineParser(new PictureImageParser());
$environment->addRenderer(Image::class, new PictureImageRenderer());

$converter = new MarkdownConverter($environment);

// 使用自定义语法
$markdown = '![一朵花](flower.webp|flower.jpg)';
echo $converter->convert($markdown);

执行后会自动生成你需要的<picture>标签结构。


内容的提问来源于stack exchange,提问作者RSD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:10:39