Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View 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;
}
}

View 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 = '';
}

View 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];
}
}

View 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);
}
}

View 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();
}
}

View 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)
;
}
}