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 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js) 9 * - (c) John MacFarlane 10 * 11 * Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java) 12 * - (c) Atlassian Pty Ltd 13 * 14 * For the full copyright and license information, please view the LICENSE 15 * file that was distributed with this source code. 16 */ 17 18namespace League\CommonMark\Delimiter\Processor; 19 20final class DelimiterProcessorCollection implements DelimiterProcessorCollectionInterface 21{ 22 /** @var array<string,DelimiterProcessorInterface>|DelimiterProcessorInterface[] */ 23 private $processorsByChar = []; 24 25 public function add(DelimiterProcessorInterface $processor) 26 { 27 $opening = $processor->getOpeningCharacter(); 28 $closing = $processor->getClosingCharacter(); 29 30 if ($opening === $closing) { 31 $old = $this->processorsByChar[$opening] ?? null; 32 if ($old !== null && $old->getOpeningCharacter() === $old->getClosingCharacter()) { 33 $this->addStaggeredDelimiterProcessorForChar($opening, $old, $processor); 34 } else { 35 $this->addDelimiterProcessorForChar($opening, $processor); 36 } 37 } else { 38 $this->addDelimiterProcessorForChar($opening, $processor); 39 $this->addDelimiterProcessorForChar($closing, $processor); 40 } 41 } 42 43 public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface 44 { 45 return $this->processorsByChar[$char] ?? null; 46 } 47 48 public function getDelimiterCharacters(): array 49 { 50 return \array_keys($this->processorsByChar); 51 } 52 53 private function addDelimiterProcessorForChar(string $delimiterChar, DelimiterProcessorInterface $processor): void 54 { 55 if (isset($this->processorsByChar[$delimiterChar])) { 56 throw new \InvalidArgumentException(\sprintf('Delim processor for character "%s" already exists', $processor->getOpeningCharacter())); 57 } 58 59 $this->processorsByChar[$delimiterChar] = $processor; 60 } 61 62 private function addStaggeredDelimiterProcessorForChar(string $opening, DelimiterProcessorInterface $old, DelimiterProcessorInterface $new): void 63 { 64 if ($old instanceof StaggeredDelimiterProcessor) { 65 $s = $old; 66 } else { 67 $s = new StaggeredDelimiterProcessor($opening, $old); 68 } 69 70 $s->add($new); 71 $this->processorsByChar[$opening] = $s; 72 } 73} 74