首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建一个扩展来解析多行用于thephpleague/commonmark

如何创建一个扩展来解析多行用于thephpleague/commonmark
EN

Stack Overflow用户
提问于 2017-09-26 20:37:31
回答 1查看 230关注 0票数 2

全,

我正在尝试创建一个扩展(我相信是为了扩展AbstractBlockParser ),它将找到一个开始标记,将后面的行移动到一个块中,然后在找到结束标记时停止(在最后一行)。

在查看所提供的示例时,很难确定它们是如何构建由多行组成的块的,例如使用代码围栏,而文档没有涵盖此场景。

列表解析器代码似乎显示ListItems被添加到ListBlock中,但是它如何知道何时停止呢?

示例Markdown

代码语言:javascript
复制
{{ Object ID
Any markdown goes here.
Some more
  * List 1
  * List 2
}}

其产出可能是:

代码语言:javascript
复制
<div class="object">
    <span>Object ID</span>
    <p>Any markdown goes here.
    Some more</p>
    <ul>
        <li>List 1</li>
        <li>List 2</li>
    </ul>
</div>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-28 03:07:24

诀窍是,您的块应该有canContain()matchesNextLine()方法(总是return true; )--这将确保后续的行总是作为子块添加。(看看FencedCodeListBlock实现。)

下面是一些应该工作的代码:

ObjectBlock.php:

代码语言:javascript
复制
class ObjectBlock extends AbstractBlock
{
    private $objectId;

    public function __construct($objectId)
    {
        $this->objectId = $objectId;
    }

    public function getObjectId()
    {
        return $this->objectId;
    }

    public function canContain(AbstractBlock $block)
    {
        return true;
    }

    public function acceptsLines()
    {
        return false;
    }

    public function isCode()
    {
        return false;
    }

    public function matchesNextLine(Cursor $cursor)
    {
        return true;
    }
}

ObjectParser.php:

代码语言:javascript
复制
class ObjectParser extends AbstractBlockParser
{
    public function parse(ContextInterface $context, Cursor $cursor)
    {
        // Look for the starting syntax
        if ($cursor->match('/^{{ /')) {
            $id = $cursor->getRemainder();
            $cursor->advanceToEnd();

            $context->addBlock(new ObjectBlock($id));

            return true;
        // Look for the ending syntax
        } elseif ($cursor->match('/^}} +$/')) {
            // TODO: I don't know if this is the best approach, but it should work
            // Basically, we're going to locate a parent ObjectBlock in the AST...
            $container = $context->getContainer();
            while ($container) {
                if ($container instanceof ObjectBlock) {
                    $cursor->advanceToEnd();

                    // Found it!  Now we'll close everything up to (and including) it
                    $context->getBlockCloser()->setLastMatchedContainer($container->parent());
                    $context->getBlockCloser()->closeUnmatchedBlocks();
                    $context->setBlocksParsed(true);

                    return true;
                }

                $container = $container->parent();
            }
        }

        return false;
    }
}

ObjectRenderer:

代码语言:javascript
复制
class ObjectRenderer implements BlockRendererInterface
{
    public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = false)
    {
        $span = sprintf('<span>%s</span>', $block->getObjectId());
        $contents = $htmlRenderer->renderBlocks($block->children());

        return new HtmlElement('div', ['class' => 'object'],
            $span . $contents
        );
    }
}

免责声明:虽然我是这个库的作者,但特定的逻辑(容器、提示和块关闭)大多是分叉式的,我只了解其中大约75%的内容--足以让我的叉子正常工作,并找到可行的方法:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46435385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档