public function BlockParser::proceed in Gutenberg 8.2
Processes the next token from the input document.
This is the "next step" function that essentially takes a token as its input and decides what to do with that token before descending deeper into a nested block tree or continuing along the document or breaking out of a level of nesting.
@since 3.8.0 @internal
Return value
bool Whether to proceed eating more tokens.
1 call to BlockParser::proceed()
- BlockParser::parse in src/
Parser/ BlockParser.php - Parses a document and returns a list of block structures.
File
- src/
Parser/ BlockParser.php, line 119
Class
- BlockParser
- Class BlockParser.
Namespace
Drupal\gutenberg\ParserCode
public function proceed() {
$next_token = $this
->nextToken();
list($token_type, $block_name, $attrs, $start_offset, $token_length) = $next_token;
$stack_depth = count($this->stack);
// We may have some HTML soup before the next block.
$leading_html_start = $start_offset > $this->offset ? $this->offset : NULL;
switch ($token_type) {
case 'no-more-tokens':
// If not in a block then flush output.
if (0 === $stack_depth) {
$this
->addFreeform();
return FALSE;
}
/*
* Otherwise we have a problem
* This is an error
*
* we have options
* - treat it all as freeform text
* - assume an implicit closer (easiest when not nesting)
*/
// For the easy case we'll assume an implicit closer.
if (1 === $stack_depth) {
$this
->addBlockFromStack();
return FALSE;
}
/*
* for the nested case where it's more difficult we'll
* have to assume that multiple closers are missing
* and so we'll collapse the whole stack piecewise
*/
while (0 < count($this->stack)) {
$this
->addBlockFromStack();
}
return FALSE;
case 'void-block':
/*
* easy case is if we stumbled upon a void block
* in the top-level of the document
*/
if (0 === $stack_depth) {
if (isset($leading_html_start)) {
$this
->addToOutput((array) $this
->freeform(substr($this->document, $leading_html_start, $start_offset - $leading_html_start)));
}
$this
->addToOutput((array) new BlockParserBlock($block_name, $attrs, [], '', []));
$this->offset = $start_offset + $token_length;
return TRUE;
}
// Otherwise we found an inner block.
$this
->addInnerBlock(new BlockParserBlock($block_name, $attrs, [], '', []), $start_offset, $token_length);
$this->offset = $start_offset + $token_length;
return TRUE;
case 'block-opener':
// Track all newly-opened blocks on the stack.
$this->stack[] = new BlockParserFrame(new BlockParserBlock($block_name, $attrs, [], '', []), $start_offset, $token_length, $start_offset + $token_length, $leading_html_start);
$this->offset = $start_offset + $token_length;
return TRUE;
case 'block-closer':
/*
* if we're missing an opener we're in trouble
* This is an error
*/
if (0 === $stack_depth) {
/*
* we have options
* - assume an implicit opener
* - assume _this_ is the opener
* - give up and close out the document
*/
$this
->addFreeform();
return FALSE;
}
// If we're not nesting then this is easy - close the block.
if (1 === $stack_depth) {
$this
->addBlockFromStack($start_offset);
$this->offset = $start_offset + $token_length;
return TRUE;
}
/*
* otherwise we're nested and we have to close out the current
* block and add it as a new innerBlock to the parent
*/
$stack_top = array_pop($this->stack);
$html = substr($this->document, $stack_top->prevOffset, $start_offset - $stack_top->prevOffset);
$stack_top->block->innerHTML .= $html;
$stack_top->block->innerContent[] = $html;
$stack_top->prevOffset = $start_offset + $token_length;
$this
->addInnerBlock($stack_top->block, $stack_top->tokenStart, $stack_top->tokenLength, $start_offset + $token_length);
$this->offset = $start_offset + $token_length;
return TRUE;
default:
// This is an error.
$this
->addFreeform();
return FALSE;
}
}