<?php /** * @copyright Copyright 2014 Carsten Brandt, 2024 Daniel Pimley * @license https://github.com/xenocrat/chyrp-markdown/blob/master/LICENSE * @link https://github.com/xenocrat/chyrp-markdown#readme */ namespace xenocrat\markdown\block; /** * Adds indented code blocks. */ trait CodeTrait { /** * Identify a line as the beginning of a code block. */ protected function identifyCode($line): bool { // Indentation >= 4 or one tab is code. return $line[0] === "\t" || str_starts_with($line, ' '); } /** * Consume lines for a code block element. */ protected function consumeCode($lines, $current): array { $content = []; // Consume until end of markers... for ($i = $current, $count = count($lines); $i < $count; $i++) { $line = $lines[$i]; if (isset($line[0]) && $line[0] === "\t") { // A line belongs to this code block if indented by a tab. $line = substr($line, 1); $content[] = $line; } elseif (str_starts_with($line, ' ')) { // A line belongs to this code block if indented by 4 spaces. $line = substr($line, 4); $content[] = $line; } elseif ( ($line === '' || ltrim($line) === '') && isset($lines[$i + 1]) ) { // ...Or if blank and the next is also blank // or the next is indented by 4 spaces or a tab. $next = $lines[$i + 1]; if ( $next === '' || ltrim($next) === '' || $next[0] === "\t" || str_starts_with($next, ' ') ) { $line = ''; $content[] = $line; } else { break; } } else { break; } } // Remove leading blank lines. while ( count($content) > 1 && ltrim(reset($content)) === '' ) { array_shift($content); } // Remove trailing blank lines. while ( count($content) > 1 && ltrim(end($content)) === '' ) { array_pop($content); } $block = [ 'code', 'content' => implode("\n", $content), ]; return [$block, --$i]; } /** * Renders a code block. */ protected function renderCode($block): string { $class = isset($block['language']) ? ' class="language-' . $block['language'] . '"' : ''; return "<pre><code$class>" . $this->escapeHtmlEntities( $block['content'], ENT_COMPAT | ENT_SUBSTITUTE ) . ($block['content'] === '' ? '' : "\n" ) . "</code></pre>\n"; } abstract protected function escapeHtmlEntities($text, $flags = 0); }