1<?php
2/**
3 * @copyright Copyright (c) 2014 Carsten Brandt
4 * @license https://github.com/cebe/markdown/blob/master/LICENSE
5 * @link https://github.com/cebe/markdown#readme
6 */
7
8namespace cebe\markdown\block;
9
10/**
11 * Adds the 4 space indented code blocks
12 */
13trait CodeTrait
14{
15	/**
16	 * identify a line as the beginning of a code block.
17	 */
18	protected function identifyCode($line)
19	{
20		// indentation >= 4 or one tab is code
21		return ($l = $line[0]) === ' ' && $line[1] === ' ' && $line[2] === ' ' && $line[3] === ' ' || $l === "\t";
22	}
23
24	/**
25	 * Consume lines for a code block element
26	 */
27	protected function consumeCode($lines, $current)
28	{
29		// consume until newline
30
31		$content = [];
32		for ($i = $current, $count = count($lines); $i < $count; $i++) {
33			$line = $lines[$i];
34
35			// a line is considered to belong to this code block as long as it is intended by 4 spaces or a tab
36			if (isset($line[0]) && ($line[0] === "\t" || strncmp($line, '    ', 4) === 0)) {
37				$line = $line[0] === "\t" ? substr($line, 1) : substr($line, 4);
38				$content[] = $line;
39			// but also if it is empty and the next line is intended by 4 spaces or a tab
40			} elseif (($line === '' || rtrim($line) === '') && isset($lines[$i + 1][0]) &&
41				      ($lines[$i + 1][0] === "\t" || strncmp($lines[$i + 1], '    ', 4) === 0)) {
42				if ($line !== '') {
43					$line = $line[0] === "\t" ? substr($line, 1) : substr($line, 4);
44				}
45				$content[] = $line;
46			} else {
47				break;
48			}
49		}
50
51		$block = [
52			'code',
53			'content' => implode("\n", $content),
54		];
55		return [$block, --$i];
56	}
57
58	/**
59	 * Renders a code block
60	 */
61	protected function renderCode($block)
62	{
63		$class = isset($block['language']) ? ' class="language-' . $block['language'] . '"' : '';
64		return "<pre><code$class>" . htmlspecialchars($block['content'] . "\n", ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8') . "</code></pre>\n";
65	}
66}
67