Skip to content

Commit

Permalink
Merge pull request #52 from thephpleague/extensions-delayed
Browse files Browse the repository at this point in the history
Delay extension initialization
  • Loading branch information
colinodell committed Jan 3, 2015
2 parents 7b14b5d + b6bdbfd commit 824243b
Show file tree
Hide file tree
Showing 3 changed files with 382 additions and 28 deletions.
202 changes: 174 additions & 28 deletions src/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@
use League\CommonMark\Block\Renderer\BlockRendererInterface;
use League\CommonMark\Extension\CommonMarkCoreExtension;
use League\CommonMark\Extension\ExtensionInterface;
use League\CommonMark\Extension\MiscExtension;
use League\CommonMark\Inline\Parser\InlineParserInterface;
use League\CommonMark\Inline\Processor\InlineProcessorInterface;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;

class Environment
{
/**
* @var ExtensionInterface[]
*/
protected $extensions = array();

/**
* @var MiscExtension
*/
protected $miscExtension;

/**
* @var bool
*/
protected $extensionsInitialized = false;

/**
* @var BlockParserInterface[]
*/
Expand Down Expand Up @@ -54,18 +70,23 @@ class Environment
*/
protected $inlineRenderersByClass = array();

public function __construct()
{
$this->miscExtension = new MiscExtension();
}

/**
* @param BlockParserInterface $parser
*
* @return $this
*/
public function addBlockParser(BlockParserInterface $parser)
{
if ($parser instanceof EnvironmentAwareInterface) {
$parser->setEnvironment($this);
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add block parser - extensions have already been initialized');
}

$this->blockParsers[$parser->getName()] = $parser;
$this->miscExtension->addBlockParser($parser);

return $this;
}
Expand All @@ -78,7 +99,11 @@ public function addBlockParser(BlockParserInterface $parser)
*/
public function addBlockRenderer($blockClass, BlockRendererInterface $blockRenderer)
{
$this->blockRenderersByClass[$blockClass] = $blockRenderer;
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add block renderer - extensions have already been initialized');
}

$this->miscExtension->addBlockRenderer($blockClass, $blockRenderer);

return $this;
}
Expand All @@ -90,15 +115,11 @@ public function addBlockRenderer($blockClass, BlockRendererInterface $blockRende
*/
public function addInlineParser(InlineParserInterface $parser)
{
if ($parser instanceof EnvironmentAwareInterface) {
$parser->setEnvironment($this);
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add inline parser - extensions have already been initialized');
}

$this->inlineParsers[$parser->getName()] = $parser;

foreach ($parser->getCharacters() as $character) {
$this->inlineParsersByCharacter[$character][] = $parser;
}
$this->miscExtension->addInlineParser($parser);

return $this;
}
Expand All @@ -110,7 +131,11 @@ public function addInlineParser(InlineParserInterface $parser)
*/
public function addInlineProcessor(InlineProcessorInterface $processor)
{
$this->inlineProcessors[] = $processor;
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add inline processor - extensions have already been initialized');
}

$this->miscExtension->addInlineProcessor($processor);

return $this;
}
Expand All @@ -123,7 +148,11 @@ public function addInlineProcessor(InlineProcessorInterface $processor)
*/
public function addInlineRenderer($inlineClass, InlineRendererInterface $renderer)
{
$this->inlineRenderersByClass[$inlineClass] = $renderer;
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add inline renderer - extensions have already been initialized');
}

$this->miscExtension->addInlineRenderer($inlineClass, $renderer);

return $this;
}
Expand All @@ -133,6 +162,10 @@ public function addInlineRenderer($inlineClass, InlineRendererInterface $rendere
*/
public function getBlockParsers()
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

return $this->blockParsers;
}

Expand All @@ -143,6 +176,10 @@ public function getBlockParsers()
*/
public function getBlockRendererForClass($blockClass)
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

if (!isset($this->blockRenderersByClass[$blockClass])) {
return null;
}
Expand All @@ -157,6 +194,10 @@ public function getBlockRendererForClass($blockClass)
*/
public function getInlineParser($name)
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

return $this->inlineParsers[$name];
}

Expand All @@ -165,6 +206,10 @@ public function getInlineParser($name)
*/
public function getInlineParsers()
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

return $this->inlineParsers;
}

Expand All @@ -175,6 +220,10 @@ public function getInlineParsers()
*/
public function getInlineParsersForCharacter($character)
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

if (!isset($this->inlineParsersByCharacter[$character])) {
return null;
}
Expand All @@ -187,6 +236,10 @@ public function getInlineParsersForCharacter($character)
*/
public function getInlineProcessors()
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

return $this->inlineProcessors;
}

Expand All @@ -197,6 +250,10 @@ public function getInlineProcessors()
*/
public function getInlineRendererForClass($inlineClass)
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

if (!isset($this->inlineRenderersByClass[$inlineClass])) {
return null;
}
Expand All @@ -206,9 +263,23 @@ public function getInlineRendererForClass($inlineClass)

public function createInlineParserEngine()
{
if (!$this->extensionsInitialized) {
$this->initializeExtensions();
}

return new InlineParserEngine($this);
}

/**
* Get all registered extensions
*
* @return ExtensionInterface[]
*/
public function getExtensions()
{
return $this->extensions;
}

/**
* Add a single extension
*
Expand All @@ -218,29 +289,104 @@ public function createInlineParserEngine()
*/
public function addExtension(ExtensionInterface $extension)
{
// Block parsers
foreach ($extension->getBlockParsers() as $blockParser) {
$this->addBlockParser($blockParser);
if ($this->extensionsInitialized) {
throw new \RuntimeException('Failed to add extension - extensions have already been initialized');
}

// Block renderers
foreach ($extension->getBlockRenderers() as $class => $blockRenderer) {
$this->addBlockRenderer($class, $blockRenderer);
$this->extensions[$extension->getName()] = $extension;

return $this;
}

protected function initializeExtensions()
{
// Only initialize them once
if ($this->extensionsInitialized) {
return;
}

$this->extensionsInitialized = true;

// Initialize all the registered extensions
foreach ($this->extensions as $extension) {
$this->initializeExtension($extension);
}

// Also initialize those one-off classes
$this->initializeExtension($this->miscExtension);
}

/**
* @param ExtensionInterface $extension
*/
protected function initializeExtension(ExtensionInterface $extension)
{
$this->initalizeBlockParsers($extension->getBlockParsers());
$this->initializeBlockRenderers($extension->getBlockRenderers());
$this->initializeInlineParsers($extension->getInlineParsers());
$this->initializeInlineProcessors($extension->getInlineProcessors());
$this->initializeInlineRenderers($extension->getInlineRenderers());
}

/**
* @param BlockParserInterface[] $blockParsers
*/
private function initalizeBlockParsers($blockParsers)
{
foreach ($blockParsers as $blockParser) {
if ($blockParser instanceof EnvironmentAwareInterface) {
$blockParser->setEnvironment($this);
}

$this->blockParsers[$blockParser->getName()] = $blockParser;
}
}

// Inline parsers
foreach ($extension->getInlineParsers() as $inlineParser) {
$this->addInlineParser($inlineParser);
/**
* @param BlockRendererInterface[] $blockRenderers
*/
private function initializeBlockRenderers($blockRenderers)
{
foreach ($blockRenderers as $class => $blockRenderer) {
$this->blockRenderersByClass[$class] = $blockRenderer;
}
}

/**
* @param InlineParserInterface[] $inlineParsers
*/
private function initializeInlineParsers($inlineParsers)
{
foreach ($inlineParsers as $inlineParser) {
if ($inlineParser instanceof EnvironmentAwareInterface) {
$inlineParser->setEnvironment($this);
}

$this->inlineParsers[$inlineParser->getName()] = $inlineParser;

// Inline processors
foreach ($extension->getInlineProcessors() as $inlineProcessor) {
$this->addInlineProcessor($inlineProcessor);
foreach ($inlineParser->getCharacters() as $character) {
$this->inlineParsersByCharacter[$character][] = $inlineParser;
}
}
}

/**
* @param InlineProcessorInterface[] $inlineProcessors
*/
private function initializeInlineProcessors($inlineProcessors)
{
foreach ($inlineProcessors as $inlineProcessor) {
$this->inlineProcessors[] = $inlineProcessor;
}
}

// Inline renderers
foreach ($extension->getInlineRenderers() as $class => $inlineRenderer) {
$this->addInlineRenderer($class, $inlineRenderer);
/**
* @param InlineRendererInterface[] $inlineRenderers
*/
private function initializeInlineRenderers($inlineRenderers)
{
foreach ($inlineRenderers as $class => $inlineRenderer) {
$this->inlineRenderersByClass[$class] = $inlineRenderer;
}
}

Expand Down
Loading

0 comments on commit 824243b

Please sign in to comment.