Primo Committ
This commit is contained in:
70
vendor/league/commonmark/src/Extension/SmartPunct/PunctuationParser.php
vendored
Normal file
70
vendor/league/commonmark/src/Extension/SmartPunct/PunctuationParser.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
|
||||
final class PunctuationParser implements InlineParserInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return ['-', '.'];
|
||||
}
|
||||
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$ch = $cursor->getCharacter();
|
||||
|
||||
// Ellipses
|
||||
if ($ch === '.' && $matched = $cursor->match('/^\\.( ?\\.)\\1/')) {
|
||||
$inlineContext->getContainer()->appendChild(new Text('…'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Em/En-dashes
|
||||
elseif ($ch === '-' && $matched = $cursor->match('/^(?<!-)(-{2,})/')) {
|
||||
$count = strlen($matched);
|
||||
$en_dash = '–';
|
||||
$en_count = 0;
|
||||
$em_dash = '—';
|
||||
$em_count = 0;
|
||||
if ($count % 3 === 0) { // If divisible by 3, use all em dashes
|
||||
$em_count = $count / 3;
|
||||
} elseif ($count % 2 === 0) { // If divisible by 2, use all en dashes
|
||||
$en_count = $count / 2;
|
||||
} elseif ($count % 3 === 2) { // If 2 extra dashes, use en dash for last 2; em dashes for rest
|
||||
$em_count = ($count - 2) / 3;
|
||||
$en_count = 1;
|
||||
} else { // Use en dashes for last 4 hyphens; em dashes for rest
|
||||
$em_count = ($count - 4) / 3;
|
||||
$en_count = 2;
|
||||
}
|
||||
$inlineContext->getContainer()->appendChild(new Text(
|
||||
str_repeat($em_dash, (int) $em_count) . str_repeat($en_dash, (int) $en_count)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
28
vendor/league/commonmark/src/Extension/SmartPunct/Quote.php
vendored
Normal file
28
vendor/league/commonmark/src/Extension/SmartPunct/Quote.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
final class Quote extends AbstractStringContainer
|
||||
{
|
||||
public const DOUBLE_QUOTE = '"';
|
||||
public const DOUBLE_QUOTE_OPENER = '“';
|
||||
public const DOUBLE_QUOTE_CLOSER = '”';
|
||||
|
||||
public const SINGLE_QUOTE = "'";
|
||||
public const SINGLE_QUOTE_OPENER = '‘';
|
||||
public const SINGLE_QUOTE_CLOSER = '’';
|
||||
}
|
||||
104
vendor/league/commonmark/src/Extension/SmartPunct/QuoteParser.php
vendored
Normal file
104
vendor/league/commonmark/src/Extension/SmartPunct/QuoteParser.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\Delimiter\Delimiter;
|
||||
use League\CommonMark\Inline\Parser\InlineParserInterface;
|
||||
use League\CommonMark\InlineParserContext;
|
||||
use League\CommonMark\Util\RegexHelper;
|
||||
|
||||
final class QuoteParser implements InlineParserInterface
|
||||
{
|
||||
public const DOUBLE_QUOTES = [Quote::DOUBLE_QUOTE, Quote::DOUBLE_QUOTE_OPENER, Quote::DOUBLE_QUOTE_CLOSER];
|
||||
public const SINGLE_QUOTES = [Quote::SINGLE_QUOTE, Quote::SINGLE_QUOTE_OPENER, Quote::SINGLE_QUOTE_CLOSER];
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCharacters(): array
|
||||
{
|
||||
return array_merge(self::DOUBLE_QUOTES, self::SINGLE_QUOTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes any quote characters found and manually adds them to the delimiter stack
|
||||
*/
|
||||
public function parse(InlineParserContext $inlineContext): bool
|
||||
{
|
||||
$cursor = $inlineContext->getCursor();
|
||||
$normalizedCharacter = $this->getNormalizedQuoteCharacter($cursor->getCharacter());
|
||||
|
||||
$charBefore = $cursor->peek(-1);
|
||||
if ($charBefore === null) {
|
||||
$charBefore = "\n";
|
||||
}
|
||||
|
||||
$cursor->advance();
|
||||
|
||||
$charAfter = $cursor->getCharacter();
|
||||
if ($charAfter === null) {
|
||||
$charAfter = "\n";
|
||||
}
|
||||
|
||||
[$leftFlanking, $rightFlanking] = $this->determineFlanking($charBefore, $charAfter);
|
||||
$canOpen = $leftFlanking && !$rightFlanking;
|
||||
$canClose = $rightFlanking;
|
||||
|
||||
$node = new Quote($normalizedCharacter, ['delim' => true]);
|
||||
$inlineContext->getContainer()->appendChild($node);
|
||||
|
||||
// Add entry to stack to this opener
|
||||
$inlineContext->getDelimiterStack()->push(new Delimiter($normalizedCharacter, 1, $node, $canOpen, $canClose));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getNormalizedQuoteCharacter(string $character): string
|
||||
{
|
||||
if (in_array($character, self::DOUBLE_QUOTES)) {
|
||||
return Quote::DOUBLE_QUOTE;
|
||||
} elseif (in_array($character, self::SINGLE_QUOTES)) {
|
||||
return Quote::SINGLE_QUOTE;
|
||||
}
|
||||
|
||||
return $character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $charBefore
|
||||
* @param string $charAfter
|
||||
*
|
||||
* @return bool[]
|
||||
*/
|
||||
private function determineFlanking(string $charBefore, string $charAfter)
|
||||
{
|
||||
$afterIsWhitespace = preg_match('/\pZ|\s/u', $charAfter);
|
||||
$afterIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
|
||||
$beforeIsWhitespace = preg_match('/\pZ|\s/u', $charBefore);
|
||||
$beforeIsPunctuation = preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
|
||||
|
||||
$leftFlanking = !$afterIsWhitespace &&
|
||||
!($afterIsPunctuation &&
|
||||
!$beforeIsWhitespace &&
|
||||
!$beforeIsPunctuation);
|
||||
|
||||
$rightFlanking = !$beforeIsWhitespace &&
|
||||
!($beforeIsPunctuation &&
|
||||
!$afterIsWhitespace &&
|
||||
!$afterIsPunctuation);
|
||||
|
||||
return [$leftFlanking, $rightFlanking];
|
||||
}
|
||||
}
|
||||
90
vendor/league/commonmark/src/Extension/SmartPunct/QuoteProcessor.php
vendored
Normal file
90
vendor/league/commonmark/src/Extension/SmartPunct/QuoteProcessor.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\Delimiter\DelimiterInterface;
|
||||
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
|
||||
use League\CommonMark\Inline\Element\AbstractStringContainer;
|
||||
|
||||
final class QuoteProcessor implements DelimiterProcessorInterface
|
||||
{
|
||||
/** @var string */
|
||||
private $normalizedCharacter;
|
||||
|
||||
/** @var string */
|
||||
private $openerCharacter;
|
||||
|
||||
/** @var string */
|
||||
private $closerCharacter;
|
||||
|
||||
private function __construct(string $char, string $opener, string $closer)
|
||||
{
|
||||
$this->normalizedCharacter = $char;
|
||||
$this->openerCharacter = $opener;
|
||||
$this->closerCharacter = $closer;
|
||||
}
|
||||
|
||||
public function getOpeningCharacter(): string
|
||||
{
|
||||
return $this->normalizedCharacter;
|
||||
}
|
||||
|
||||
public function getClosingCharacter(): string
|
||||
{
|
||||
return $this->normalizedCharacter;
|
||||
}
|
||||
|
||||
public function getMinLength(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse)
|
||||
{
|
||||
$opener->insertAfter(new Quote($this->openerCharacter));
|
||||
$closer->insertBefore(new Quote($this->closerCharacter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a double-quote processor
|
||||
*
|
||||
* @param string $opener
|
||||
* @param string $closer
|
||||
*
|
||||
* @return QuoteProcessor
|
||||
*/
|
||||
public static function createDoubleQuoteProcessor(string $opener = Quote::DOUBLE_QUOTE_OPENER, string $closer = Quote::DOUBLE_QUOTE_CLOSER): self
|
||||
{
|
||||
return new self(Quote::DOUBLE_QUOTE, $opener, $closer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single-quote processor
|
||||
*
|
||||
* @param string $opener
|
||||
* @param string $closer
|
||||
*
|
||||
* @return QuoteProcessor
|
||||
*/
|
||||
public static function createSingleQuoteProcessor(string $opener = Quote::SINGLE_QUOTE_OPENER, string $closer = Quote::SINGLE_QUOTE_CLOSER): self
|
||||
{
|
||||
return new self(Quote::SINGLE_QUOTE, $opener, $closer);
|
||||
}
|
||||
}
|
||||
47
vendor/league/commonmark/src/Extension/SmartPunct/QuoteRenderer.php
vendored
Normal file
47
vendor/league/commonmark/src/Extension/SmartPunct/QuoteRenderer.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Inline\Element\AbstractInline;
|
||||
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||
|
||||
final class QuoteRenderer implements InlineRendererInterface
|
||||
{
|
||||
/**
|
||||
* @param Quote $inline
|
||||
* @param ElementRendererInterface $htmlRenderer
|
||||
*
|
||||
* @return HtmlElement|string|null
|
||||
*/
|
||||
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||
{
|
||||
if (!$inline instanceof Quote) {
|
||||
throw new \InvalidArgumentException(sprintf('Expected an instance of "%s", got "%s" instead', Quote::class, get_class($inline)));
|
||||
}
|
||||
|
||||
// Handles unpaired quotes which remain after processing delimiters
|
||||
if ($inline->getContent() === Quote::SINGLE_QUOTE) {
|
||||
// Render as an apostrophe
|
||||
return Quote::SINGLE_QUOTE_CLOSER;
|
||||
} elseif ($inline->getContent() === Quote::DOUBLE_QUOTE) {
|
||||
// Render as an opening quote
|
||||
return Quote::DOUBLE_QUOTE_OPENER;
|
||||
}
|
||||
|
||||
return $inline->getContent();
|
||||
}
|
||||
}
|
||||
49
vendor/league/commonmark/src/Extension/SmartPunct/SmartPunctExtension.php
vendored
Normal file
49
vendor/league/commonmark/src/Extension/SmartPunct/SmartPunctExtension.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the league/commonmark package.
|
||||
*
|
||||
* (c) Colin O'Dell <colinodell@gmail.com>
|
||||
*
|
||||
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
|
||||
* - (c) John MacFarlane
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace League\CommonMark\Extension\SmartPunct;
|
||||
|
||||
use League\CommonMark\Block\Element\Document;
|
||||
use League\CommonMark\Block\Element\Paragraph;
|
||||
use League\CommonMark\Block\Renderer as CoreBlockRenderer;
|
||||
use League\CommonMark\ConfigurableEnvironmentInterface;
|
||||
use League\CommonMark\Extension\ExtensionInterface;
|
||||
use League\CommonMark\Inline\Element\Text;
|
||||
use League\CommonMark\Inline\Renderer as CoreInlineRenderer;
|
||||
|
||||
final class SmartPunctExtension implements ExtensionInterface
|
||||
{
|
||||
public function register(ConfigurableEnvironmentInterface $environment)
|
||||
{
|
||||
$environment
|
||||
->addInlineParser(new QuoteParser(), 10)
|
||||
->addInlineParser(new PunctuationParser(), 0)
|
||||
|
||||
->addDelimiterProcessor(QuoteProcessor::createDoubleQuoteProcessor(
|
||||
$environment->getConfig('smartpunct/double_quote_opener', Quote::DOUBLE_QUOTE_OPENER),
|
||||
$environment->getConfig('smartpunct/double_quote_closer', Quote::DOUBLE_QUOTE_CLOSER)
|
||||
))
|
||||
->addDelimiterProcessor(QuoteProcessor::createSingleQuoteProcessor(
|
||||
$environment->getConfig('smartpunct/single_quote_opener', Quote::SINGLE_QUOTE_OPENER),
|
||||
$environment->getConfig('smartpunct/single_quote_closer', Quote::SINGLE_QUOTE_CLOSER)
|
||||
))
|
||||
|
||||
->addBlockRenderer(Document::class, new CoreBlockRenderer\DocumentRenderer(), 0)
|
||||
->addBlockRenderer(Paragraph::class, new CoreBlockRenderer\ParagraphRenderer(), 0)
|
||||
|
||||
->addInlineRenderer(Quote::class, new QuoteRenderer(), 100)
|
||||
->addInlineRenderer(Text::class, new CoreInlineRenderer\TextRenderer(), 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user