code = $line;
}
public function append( WP_Experimental_HTML_Renderer_Block $block ): void {
if ( $block instanceof WP_Experimental_HTML_Renderer_Block_Paragraph ) {
$this->code = $block->lines[0] ?? null;
} else {
$type = \strtr( \get_class( $block ), array( 'Block_' => '' ) );
throw new \Error( "Cannot add block of type '{$type}' to code block." );
}
}
public function infer_language( \WP_HTML_Processor $processor ): void {
if ( isset( $this->language ) ) {
return;
}
$language_map = array(
'c++' => 'cpp',
'eix' => 'elixir',
'erl' => 'erlang',
'golang' => 'go',
'md' => 'markdown',
'js' => 'javascript',
'patch' => 'diff',
'py' => 'python',
'python2' => 'python',
'python3' => 'python',
'rs' => 'rust',
'ts' => 'typescript',
);
$known_languages = array( 'asm', 'apl', 'bash', 'c', 'cpp', 'clojure', 'clojurescript', 'commonlisp', 'diff', 'elixir', 'erlang', 'go', 'html', 'javascript', 'lisp', 'php', 'python', 'rust', 'scheme', 'typescript' );
$known_rejects = array( 'nil', 'src' );
$try_slug = function ( $trial ) use ( $language_map, $known_languages, $known_rejects ) {
if ( \in_array( $trial, $known_rejects, true ) || \in_array( $this->language, $known_languages, true ) ) {
return;
}
$trial = $language_map[ $trial ] ?? $trial;
if ( \in_array( $trial, $known_languages, true ) ) {
$this->language = $trial;
return;
}
$this->language_fallback = $trial;
};
switch ( $processor->get_token_name() ) {
case 'PRE':
case 'CODE':
$class_list = $processor->class_list();
if ( ! isset( $class_list ) ) {
break;
}
foreach ( $processor->class_list() as $class ) {
if ( \str_starts_with( $class, 'language-' ) ) {
$try_slug( \substr( $class, 9 ) );
}
if ( \str_starts_with( $class, 'pre-' ) || \str_starts_with( $class, 'src-' ) ) {
$try_slug( \substr( $class, 4 ) );
return;
}
$try_slug( $class );
}
break;
}
}
public function flush( WP_Experimental_HTML_Renderer_Options $options ): string {
if ( ! isset( $this->code ) || $this->code->is_empty() ) {
return '';
}
$previous_indent = $options->indent;
$options->indent[] = ' ';
$slug = $this->language ?? $this->language_fallback ?? '';
$indent = \implode( '', $options->indent );
$indent_length = \mb_strwidth( $indent );
$soft_limit = $options->soft_line_wrap;
$options->soft_line_wrap = \max( 1, $soft_limit - $indent_length );
$prefix = "{$indent}```{$slug}\n";
$buffer = '';
foreach ( \explode( "\n", $this->code->raw_buffer() ) as $line ) {
$chunk = "{$indent}{$line}\n";
$is_all_whitespace = \strspn( $chunk, " \t\f\r\n" ) === \strlen( $chunk );
$buffer .= $is_all_whitespace ? "\n" : $chunk;
}
$buffer = \trim( $buffer, "\n" );
$suffix = "\n{$indent}```\n";
$options->soft_line_wrap = $soft_limit;
$options->indent = $previous_indent;
return "{$prefix}{$buffer}{$suffix}";
}
public function is_empty(): bool {
return null === $this->code || $this->code->is_empty();
}
}