如何在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语法(比如),通过自定义扩展将其自动解析为<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 { // 匹配自定义语法: 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 = ''; echo $converter->convert($markdown);
执行后会自动生成你需要的<picture>标签结构。
内容的提问来源于stack exchange,提问作者RSD
相关产品推荐
相关产品推荐

