2017-09-26 27 views
2

すべてのために複数の行を解析するために拡張機能を作成する方法に以下の行を移動し、開始タグを見つけるなる(私は信じて、AbstractBlockParserを拡張します)ブロックし、終了タグが見つかったときに停止します(最後の行で単独で)。、私は拡張機能を作成しようとしています</p> <p>をthephpleague/commonmark

提供された例を見ても、複数の行で構成されたブロックをどのように構築するかは非常に難しいです。コードフェンスを使用しており、このシナリオではドキュメントでは説明していません。

Listパーサーコードは、ListBlockにListItemsが追加されたことを示しているようですが、いつ停止するのかはどのようにわかりますか?

例値下げ

{{ Object ID 
Any markdown goes here. 
Some more 
    * List 1 
    * List 2 
}} 

、出力は次のようになります。

<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> 
+0

あなたは解析したいMarkdownの例と、結果のHTMLはどんなものになりますか? –

+0

@ ColinO'Dell - 完了! – Kurucu

答えて

1

トリックは、あなたのブロックは、常にreturn true;canContain()matchesNextLine()メソッドを持っていなければならないということである - これらを次の行を常に得ることが保証されます子ブロックとして追加されました。 (FencedCodeListBlockの実装を見てみましょう。)

はここで働いべきいくつかのコードです:

ObjectBlock.php:

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:

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; 
    } 
} 

Objec tRenderer:

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 
     ); 
    } 
} 

免責事項:私はこのライブラリの作者だが、特定のロジック(コンテナ、ヒント、およびブロック・クロージング)は、主にJS版からそのままでフォークれたと私はたったの約75の理解%of - それだけで十分な私のフォークを維持し、働くアプローチを理解してください:)

+0

これはうまくいきますが、適切な試行をする必要があります。次に、フィードバックを提供します。どうもありがとうございました。 – Kurucu

+0

うれしい私は助けることができました! –

関連する問題