Skip to content

Commit

Permalink
Replace document processors with an event
Browse files Browse the repository at this point in the history
  • Loading branch information
colinodell committed Jun 4, 2019
1 parent ad51a80 commit 3e918a5
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 234 deletions.
11 changes: 11 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

**Note:** This file has been deprecated. Future upgrade instructions can be found on our website: <https://commonmark.thephpleague.com/releases>

## UNRELEASED

### Document Processor Removed

Now that we have support for an event dispatcher, we can leverage generic event listeners to obtain and manipulate the `Document` once parsing is completed instead of having a special `DocumentParserInterface` for this purpose.

You'll need to make two changes:

- Instead of your processor implementing `DocumentProcessorInterface`, have a function which accepts a `DocumentParsedEvent` and obtains the `Document` from there.
- Change `$environment->addDocumentProcessor()` to `$environment->addEventListener(DocumentParsedEvent::class, /* your listener here */)` to register it with the environment

## 1.0.0-beta3

### More Delimiter Changes
Expand Down
108 changes: 0 additions & 108 deletions docs/1.0/customization/document-processing.md

This file was deleted.

96 changes: 96 additions & 0 deletions docs/1.0/customization/event-dispatcher.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
---
layout: default
title: Event Dispatcher
redirect_from:
- /0.20/customization/document-processing/
- /1.0/customization/document-processing/
---

Event Dispatcher
Expand Down Expand Up @@ -61,3 +64,96 @@ $environment->dispatch(new MyCustomEvent());
Listeners will be called in order of priority (higher priorities will be called first). If multiple listeners have the same priority, they'll be called in the order in which they were registered. If you'd like your listener to prevent other subsequent events from running, simply call `$event->stopPropagation()`.

Listeners may call any method on the event to get more information about the event, make changes to event data, etc.

## List of Available Events

This library supports the following default events which you can register listeners for:

### `DocumentParsedEvent`

This event is dispatched once all other processing is done. This offers extensions the opportunity to inspect and modify the [Abstract Syntax Tree](/1.0/customization/abstract-syntax-tree/) prior to rendering.

## Example

Here's an example of a listener which uses the `DocumentParsedEvent` to add an `external-link` class to external URLs:

~~~php
<?php

use League\CommonMark\EnvironmentInterface;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Inline\Element\Link;

class ExternalLinkProcessor
{
private $environment;

public function __construct(EnvironmentInterface $environment)
{
$this->environment = $environment;
}

public function onDocumentParsed(DocumentParsedEvent $event)
{
$document = $event->getDocument();
$walker = $document->walker();
while ($event = $walker->next()) {
$node = $event->getNode();

// Only stop at Link nodes when we first encounter them
if (!($node instanceof Link) || !$event->isEntering()) {
continue;
}

$url = $node->getUrl();
if ($this->isUrlExternal($url)) {
$node->data['attributes']['class'] = 'external-link';
}
}
}

private function isUrlExternal(string $url): bool
{
// Only look at http and https URLs
if (!preg_match('/^https?:\/\//', $url)) {
return false;
}

$host = parse_url($url, PHP_URL_HOST);

return $host != $this->environment->getConfig('host');
}
}
~~~

And here's how you'd use it:

~~~php
<?php

use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Event\DocumentParsedEvent;

$env = Environment::createCommonMarkEnvironment();

$listener = new ExternalLinkProcessor($env);
$env->addEventListener(DocumentParsedEvent::class, [$listener, 'onDocumentParsed']);

$converter = new CommonMarkConverter(['host' => 'commonmark.thephpleague.com'], $env);

$input = 'My two favorite sites are <https://google.com> and <https://commonmark.thephpleague.com>';

echo $converter->convertToHtml($input);
~~~

Output (formatted for readability):

~~~html
<p>
My two favorite sites are
<a class="external-link" href="https://google.com">https://google.com</a>
and
<a href="https://commonmark.thephpleague.com">https://commonmark.thephpleague.com</a>
</p>
~~~
37 changes: 37 additions & 0 deletions docs/1.0/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,43 @@ All previously-deprecated code has been removed. This includes:
- `DocParser::getEnvironment()` (you should obtain it some other way)
- `AbstractInlineContainer` (use `AbstractInline` instead and make `isContainer()` return `true`)

## Document Processors Removed

We no longer support Document Processors because we now have [event dispatching](/1.0/customization/event-dispatcher/) which can fill that same role! Simply remove the interface from your processor and register it as a listener; for example, instead of this:

```php
class MyDocumentProcessor implements DocumentProcessorInterface
{
public function processDocument(Document $document)
{
// TODO: Do things with the $document
}
}

// ...

$processor = new MyDocumentProcessor();
$environment->addDocumentProcessor($processor);
```

Simply do this:

```php
class MyDocumentProcessor
{
public function onDocumentParsed(DocumentParsedEvent $event)
{
$document = $event->getDocument();
// TODO: Do things with the $document
}
}

// ...

$processor = new MyDocumentProcessor();
$environment->addEventListener(DocumentParsedEvent::class, [$processor, 'onDocumentParsed']);
```

## Text Encoding

This library used to claim it supported ISO-8859-1 encoding but that never truly worked - everything assumed the text was encoded as UTF-8 or ASCII. We've therefore dropped support for ISO-8859-1 and any other unexpected encodings. If you were using some other encoding, you'll now need to convert your Markdown to UTF-8 prior to running it through this library.
Expand Down
1 change: 0 additions & 1 deletion docs/_data/menu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ version:
'Inline Parsing': '/1.0/customization/inline-parsing/'
'Delimiter Processing': '/1.0/customization/delimiter-processing/'
'Abstract Syntax Tree': '/1.0/customization/abstract-syntax-tree/'
'Document Processing': '/1.0/customization/document-processing/'
'Block Rendering': '/1.0/customization/block-rendering/'
'Inline Rendering': '/1.0/customization/inline-rendering/'
'0.19':
Expand Down
10 changes: 0 additions & 10 deletions src/ConfigurableEnvironmentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,6 @@ public function addInlineParser(InlineParserInterface $parser, int $priority = 0
*/
public function addDelimiterProcessor(DelimiterProcessorInterface $processor): ConfigurableEnvironmentInterface;

/**
* Registers the given document processor with the Environment
*
* @param DocumentProcessorInterface $processor Document processor instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addDocumentProcessor(DocumentProcessorInterface $processor, int $priority = 0): ConfigurableEnvironmentInterface;

/**
* @param string $blockClass The fully-qualified block element class name the renderer below should handle
* @param BlockRendererInterface $blockRenderer The renderer responsible for rendering the type of element given above
Expand Down
15 changes: 5 additions & 10 deletions src/DocParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use League\CommonMark\Block\Element\Document;
use League\CommonMark\Block\Element\Paragraph;
use League\CommonMark\Block\Element\StringContainerInterface;
use League\CommonMark\Event\DocumentParsedEvent;

final class DocParser implements DocParserInterface
{
Expand Down Expand Up @@ -73,7 +74,8 @@ private function preProcessInput(string $input): array
*/
public function parse(string $input): Document
{
$context = new Context(new Document(), $this->environment);
$document = new Document();
$context = new Context($document, $this->environment);

$lines = $this->preProcessInput($input);
foreach ($lines as $line) {
Expand All @@ -88,9 +90,9 @@ public function parse(string $input): Document

$this->processInlines($context);

$this->processDocument($context);
$this->environment->dispatch(new DocumentParsedEvent($document));

return $context->getDocument();
return $document;
}

private function incorporateLine(ContextInterface $context)
Expand Down Expand Up @@ -130,13 +132,6 @@ private function incorporateLine(ContextInterface $context)
}
}

private function processDocument(ContextInterface $context)
{
foreach ($this->environment->getDocumentProcessors() as $documentProcessor) {
$documentProcessor->processDocument($context->getDocument());
}
}

private function processInlines(ContextInterface $context)
{
$walker = $context->getDocument()->walker();
Expand Down
27 changes: 0 additions & 27 deletions src/DocumentProcessorInterface.php

This file was deleted.

Loading

0 comments on commit 3e918a5

Please sign in to comment.