1<?php 2 3/* 4 * This file is part of the league/commonmark package. 5 * 6 * (c) Colin O'Dell <colinodell@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace League\CommonMark\Input; 13 14use League\CommonMark\Exception\UnexpectedEncodingException; 15 16final class MarkdownInput implements MarkdownInputInterface 17{ 18 /** @var array<int, string>|null */ 19 private $lines; 20 21 /** @var string */ 22 private $content; 23 24 /** @var int|null */ 25 private $lineCount; 26 27 public function __construct(string $content) 28 { 29 if (!\mb_check_encoding($content, 'UTF-8')) { 30 throw new UnexpectedEncodingException('Unexpected encoding - UTF-8 or ASCII was expected'); 31 } 32 33 $this->content = $content; 34 } 35 36 public function getContent(): string 37 { 38 return $this->content; 39 } 40 41 /** 42 * @return \Traversable<int, string> 43 */ 44 public function getLines(): \Traversable 45 { 46 $this->splitLinesIfNeeded(); 47 48 foreach ($this->lines as $lineNumber => $line) { 49 yield $lineNumber => $line; 50 } 51 } 52 53 public function getLineCount(): int 54 { 55 $this->splitLinesIfNeeded(); 56 57 return $this->lineCount; 58 } 59 60 private function splitLinesIfNeeded(): void 61 { 62 if ($this->lines !== null) { 63 return; 64 } 65 66 $lines = \preg_split('/\r\n|\n|\r/', $this->content); 67 if ($lines === false) { 68 throw new UnexpectedEncodingException('Failed to split Markdown content by line'); 69 } 70 71 $this->lines = $lines; 72 73 // Remove any newline which appears at the very end of the string. 74 // We've already split the document by newlines, so we can simply drop 75 // any empty element which appears on the end. 76 if (\end($this->lines) === '') { 77 \array_pop($this->lines); 78 } 79 80 $this->lineCount = \count($this->lines); 81 } 82} 83