in src/inlines/Emphasis.php [75:166]
private static function tokenize(
Context $context,
string $markdown,
int $initial_offset,
): ?vec<Stack\Node> {
$offset = $initial_offset;
if (!self::isStartOfRun($context, $markdown, $offset)) {
return null;
}
// This is tricky as until we find the closing marker, we don't know if
// `***` means:
// - `<strong><em>`
// - `<em><strong>`
// - `<em>**`
// - `<strong>*`
// - `***`
$start = self::consumeDelimiterRun($markdown, $offset);
list($start, $end_offset) = $start;
if (!self::isLeftFlankingDelimiterRun($markdown, $offset, $end_offset)) {
return null;
}
$stack = vec[
new Stack\DelimiterNode(
$start,
self::IS_START,
$offset,
$end_offset,
),
];
$offset = $end_offset;
$text = '';
// Tokenize into a stack of TextNodes, InlineNodes, and DelimiterNodes
$len = Str\length($markdown);
for (; $offset < $len; ++$offset) {
$inline = self::consumeHigherPrecedence($context, $markdown, $offset);
if ($inline !== null) {
list($inline, $end_offset) = $inline;
if ($text !== '') {
// Leading plain text - *not* what we just matched
$leading_end = $offset;
$leading_start = $leading_end - Str\length($text);
$stack[] = new Stack\TextNode($text, $leading_start, $leading_end);
$text = '';
}
$stack[] = new Stack\InlineNode($inline, $offset, $end_offset);
$offset = $end_offset - 1;
continue;
}
if (self::isStartOfRun($context, $markdown, $offset)) {
list($run, $end_offset) = self::consumeDelimiterRun($markdown, $offset);
$flags = 0;
if (self::isLeftFlankingDelimiterRun($markdown, $offset, $end_offset)) {
$flags |= self::IS_START;
}
if (
self::isRightFlankingDelimiterRun($markdown, $offset, $end_offset)
) {
$flags |= self::IS_END;
}
if ($flags !== 0) {
if ($text !== '') {
// Leading plain text again, before the delimiter
$leading_end = $offset;
$leading_start = $leading_end - Str\length($text);
$stack[] = new Stack\TextNode($text, $leading_start, $leading_end);
$text = '';
}
$stack[] =
new Stack\DelimiterNode($run, $flags, $offset, $end_offset);
$offset = $end_offset - 1;
continue;
}
}
$text .= $markdown[$offset];
}
if ($text !== '') {
$end_offset = $offset;
$start_offset = $end_offset - Str\length($text);
$stack[] = new Stack\TextNode($text, $start_offset, $end_offset);
}
return $stack;
}