PK POcE CODE_OF_CONDUCT.mdnu W+A # Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
PK Phf* * README.mdnu W+A # league/commonmark
[![Latest Version](https://img.shields.io/packagist/v/league/commonmark.svg?style=flat-square)](https://packagist.org/packages/league/commonmark)
[![Total Downloads](https://img.shields.io/packagist/dt/league/commonmark.svg?style=flat-square)](https://packagist.org/packages/league/commonmark)
[![Software License](https://img.shields.io/badge/License-BSD--3-brightgreen.svg?style=flat-square)](LICENSE)
[![Build Status](https://img.shields.io/travis/thephpleague/commonmark/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/commonmark)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/commonmark.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/commonmark/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/commonmark.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/commonmark)
[![SensioLabs Insight](https://img.shields.io/sensiolabs/i/9bf971c0-458f-4a19-9898-127728dbd65d.svg?style=flat-square)](https://insight.sensiolabs.com/projects/9bf971c0-458f-4a19-9898-127728dbd65d)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/126/badge)](https://bestpractices.coreinfrastructure.org/projects/126)
**league/commonmark** is a PHP-based Markdown parser created by [Colin O'Dell][@colinodell] which supports the full [CommonMark] spec. It is based on the [CommonMark JS reference implementation][commonmark.js] by [John MacFarlane] \([@jgm]\).
## Goals
* Fully support the CommonMark spec (100% compliance)
* Match the C and JavaScript implementations of CommonMark to make a logical and similar API
* Continuously improve performance without sacrificing quality or compliance
* Provide an extensible parser/renderer which users may customize as needed
## Installation
This project can be installed via [Composer]:
``` bash
$ composer require league/commonmark
```
**Note:** See [Versioning](#versioning) for important information on which version constraints you should use.
## Basic Usage
The `CommonMarkConverter` class provides a simple wrapper for converting CommonMark to HTML:
```php
use League\CommonMark\CommonMarkConverter;
$converter = new CommonMarkConverter();
echo $converter->convertToHtml('# Hello World!');
//
Hello World!
```
:warning: **Security warning:** If you will be parsing untrusted input from users, please consider setting the `html_input` and `allow_unsafe_links` options. See for more details.
If you also do choose to allow raw HTML input from untrusted users, considering using a library (like [HTML Purifier](https://github.com/ezyang/htmlpurifier)) to provide additional HTML filtering.
## Documentation
Full documentation on advanced usage, configuration, and customization can be found at [commonmark.thephpleague.com][docs].
## Upgrading
Information on how to upgrade to newer versions of this library can be found at .
## Related Packages
### Integrations
- [CakePHP 3](https://github.com/gourmet/common-mark)
- [Drupal 7 & 8](https://www.drupal.org/project/markdown)
- [Laravel 4 & 5](https://github.com/GrahamCampbell/Laravel-Markdown)
- [Sculpin](https://github.com/bcremer/sculpin-commonmark-bundle)
- [Symfony 2 & 3](https://github.com/webuni/commonmark-bundle)
- [Symfony 4](https://github.com/avensome/commonmark-bundle)
- [Twig Markdown extension](https://github.com/twigphp/markdown-extension)
- [Twig-based renderer](https://github.com/webuni/commonmark-twig-renderer)
- [Twig filter and tag](https://github.com/aptoma/twig-markdown)
### League Extensions
The PHP League offers useful extensions that add extra syntax and features:
- [`league/commonmark-extras`](https://github.com/thephpleague/commonmark-extras) - Bundles the extensions below into a single dependency for convenience
- [`league/commonmark-ext-autolink`](https://github.com/thephpleague/commonmark-ext-autolink) - Extension for league/commonmark which autolinks URLs, emails, and (optionally) @-mentions
- [`league/commonmark-ext-smartpunct`](https://github.com/thephpleague/commonmark-ext-smartpunct) - Intelligently converts ASCII quotes, dashes, and ellipses to their Unicode equivalents
- [`league/commonmark-ext-inlines-only`](https://github.com/thephpleague/commonmark-ext-inlines-only) - Renders inline text without paragraph tags or other block-level elements
You can add them to your project or use them as examples to [develop your own custom features](https://commonmark.thephpleague.com/customization/overview/).
### Community Extensions
Custom parsers/renderers can be bundled into extensions which extend CommonMark. Here are some that you may find interesting:
- [CommonMark Table Extension](https://github.com/webuni/commonmark-table-extension) - Adds the ability to create tables in CommonMark documents.
- [CommonMark Attributes Extension](https://github.com/webuni/commonmark-attributes-extension) - Adds a syntax to define attributes on the various HTML elements.
- [Alt Three Emoji](https://github.com/AltThree/Emoji) An emoji parser for CommonMark.
- [uafrica/commonmark-ext](https://github.com/uafrica/commonmark-ext) - Adds strikethrough support.
- [Sup Sub extensions](https://github.com/OWS/commonmark-sup-sub-extensions) - Adds support of superscript and subscript (`` and `` HTML tags)
If you build your own, feel free to submit a PR to add it to this list!
### Others
Check out the other cool things people are doing with `league/commonmark`:
## Compatibility with CommonMark ##
This project aims to fully support the entire [CommonMark spec]. Other flavors of Markdown may work but are not supported. Any/all changes made to the [spec][CommonMark spec] or [JS reference implementation][commonmark.js] should eventually find their way back into this codebase.
league/commonmark 0.19.0 and higher supports version 0.29 of the [CommonMark spec].
(This package is **not** part of CommonMark, but rather a compatible derivative.)
## Testing
``` bash
$ composer test
```
This will also test league/commonmark against the latest supported spec.
## Performance Benchmarks
You can compare the performance of **league/commonmark** to other popular parsers by running the included benchmark tool:
``` bash
$ ./tests/benchmark/benchmark.php
```
## Versioning
[SemVer](http://semver.org/) will be followed closely. 0.x.0 versions will introduce breaking changes to the codebase, so be careful which version constraints you use. **It's highly recommended that you use [Composer's caret operator](https://getcomposer.org/doc/articles/versions.md#caret) to ensure compatibility**; for example: `^0.18`. This is equivalent to `>=0.18.0 <0.19.0`.
0.x.y releases should not introduce breaking changes to the codebase; however, they might change the resulting AST or HTML output of parsed Markdown (due to bug fixes, minor spec changes, etc.) As a result, you might get slightly different HTML, but any custom code built onto this library will still function correctly.
If you're only using the `CommonMarkConverter` class or `ConverterInterface` to convert Markdown (no other class references, custom parsers, etc.), then it should be safe to use a broader constraint like `~0.18`, `>0.18`, etc. I personally promise to never break this specific class in any future 0.x release.
## Stability
While this package does work well, the underlying code should not be considered "stable" yet. The original spec and JS parser may undergo changes in the near future which will result in corresponding changes to this code. Any methods tagged with `@api` are not expected to change, but other methods/classes might.
Major release 1.0.0 will be reserved for when either the CommonMark spec or this project are considered stable (see [outstanding CommonMark spec issues](http://talk.commonmark.org/t/issues-to-resolve-before-1-0-release/1287)). 0.x.y will be used until that happens.
## Contributing
If you encounter a bug in the spec, please report it to the [CommonMark] project. Any resulting fix will eventually be implemented in this project as well.
For now, I'd like to maintain similar logic as the [JS reference implementation][commonmark.js] until everything is stable. I'll gladly accept any contributions which:
* Mirror fixes made to the [reference implementation][commonmark.js]
* Optimize existing methods or regular expressions
* Fix issues with adhering to the spec examples
Major refactoring should be avoided for now so that we can easily follow updates made to [the reference implementation][commonmark.js]. This restriction will likely be lifted once the CommonMark specs and implementations are considered stable.
Please see [CONTRIBUTING](https://github.com/thephpleague/commonmark/blob/master/CONTRIBUTING.md) for additional details.
## Security
If you discover any security related issues, please email your report privately to colinodell@gmail.com instead of using the issue tracker.
## Credits & Acknowledgements
- [Colin O'Dell][@colinodell]
- [John MacFarlane][@jgm]
- [All Contributors]
This code is a port of the [CommonMark JS reference implementation][commonmark.js] which is written, maintained and copyrighted by [John MacFarlane]. This project simply wouldn't exist without his work.
Also a huge thank you to [JetBrains](https://www.jetbrains.com/) for supporting the development of this project with complimentary [PhpStorm](https://www.jetbrains.com/phpstorm/) licenses.
## License ##
**league/commonmark** is licensed under the BSD-3 license. See the [`LICENSE`](LICENSE) file for more details.
## Governance
This project is primarily maintained by [Colin O'Dell][@colinodell]. Members of the [PHP League] Leadership Team may occasionally assist with some of these duties.
[CommonMark]: http://commonmark.org/
[CommonMark spec]: http://spec.commonmark.org/
[commonmark.js]: https://github.com/jgm/commonmark.js
[John MacFarlane]: http://johnmacfarlane.net
[docs]: https://commonmark.thephpleague.com/
[docs-examples]: https://commonmark.thephpleague.com/customization/overview/#examples
[docs-example-twitter]: https://commonmark.thephpleague.com/customization/inline-parsing#example-1---twitter-handles
[docs-example-smilies]: https://commonmark.thephpleague.com/customization/inline-parsing#example-2---emoticons
[All Contributors]: https://github.com/thephpleague/commonmark/contributors
[@colinodell]: https://www.twitter.com/colinodell
[@jgm]: https://github.com/jgm
[jgm/stmd]: https://github.com/jgm/stmd
[Composer]: https://getcomposer.org/
[PHP League]: https://thephpleague.com
PK P|
2\3 \3
UPGRADE.mdnu W+A # Upgrade Instructions
**Note:** This file has been deprecated. Future upgrade instructions can be found on our website:
## UNRELEASED
## 0.19
The `Environment` and extension framework underwent some major changes in this release.
### PHP support
This library no longer supports PHP 5.6 or 7.0. Feel free to remove support for those from your extensions as well.
### HTML attribute escaping
Previously, any attributes passed into an `HtmlElement` would need to be pre-escaped. This is now done for you so be sure to remove any references to `Xml::escape()` when applied to attributes.
This does not affect inner contents which may still need pre-escaping of untrusted user input.
### Removed classes and interface methods
The `getName()` method has been removed from several classes:
- `BlockParserInterface` and `AbstractBlockParser`
- `InlineParserInterface` and `AbstractInlineParser`
This method was originally intended for supporting XML rendering, which was never implemented, and will likely define names a bit differently if/when we do add support.
After doing this, the two abstract classes mentioned above had notthing left in them, so those were removed. Any parsers previously extending them should directly implement the corresponding interface instead.
`InlineContainer` was also removed.
`Xml::escape()` no longer accepts the deprecated `$preserveEntities` parameter.
### Removed deprecated `RegexHelper` methods
Several previously-deprecated methods inside of `RegexHelper` were finally removed. That functionality was made available with static methods and constants, so use those instead.
### Parameter and return types
Pretty much every method now uses parameter and return types, including several interfaces. Update your implementations accordingly.
### Environment interfaces
We have extracted two interfaces from the `Environment` class:
- `EnvironmentInterface` - contains all the getters; use this in your parsers, renderers, etc.
- `ConfigurableEnvironmentInterface` - contains all the `add` methods, as well as `setConfig()` and `mergeConfig`
As a result, `EnvironmentAwareInterface` now requires an `EnvironmentInterface` instead of an `Environment`, so update your parsers/processors/renderers accordingly.
### Block Elements
A few methods from `AbstractBlock` have been extracted into a new `AbstractStringContainerBlock` class and corresponding `StringContainerInterface` interface:
- `addLine(string $line)`
- `getStringContent()`
- `handleRemainingContents(ContextInterface $context, Cursor $cursor)`
These are used to represent a block which can contain strings of text inside (even if those strings do not contain "inline" elements but just plain text).
To determine how to best upgrade your existing block element classes, look at the value returned by the `acceptsLines()` method:
- If `acceptsLines()` returns `false`, simply remove the three methods from the bulleted list above, along with `acceptsLines()` and any calls to `parent::__construct()`.
- If `acceptsLines()` returns `true`, change your base class from `AbstractBlock` to `AbstractStringContainerBlock` and remove `acceptsLines()`.
Additionally, `StringContainerInterface` now extends this new `StringContainerInterface` interface. Just make sure you've implemented the change mentioned above and you should be fine.
### Extensions
Extensions work much differently now. In the past, you'd have functions returning an array of things that the `Environment` would register for you.
The `ExtensionInterface` was changed to have a single `register(ConfigurableEnvironmentInterface $environment)` method. You must now manually `add()` all your parsers, processors, and renderers yourself directly within the environment you are provided. See the changes made to `CommonMarkCoreExtension` for a good example.
The `Environment` will still automatically inject the `Environment` or `Configuration` for any parsers, processors, and renderers implementing the `EnvironmentAwareInterface` or `ConfigurationAwareInterface` - that behavior hasn't changed.
### Adding renderers with short names
`Environment::add___Renderer()` now requires the fully-qualified class name with namespace as its first argument. Providing just the class name without the namespace will no longer work.
### Prioritization of parsers, processors, and renderers
The execution order of these things no longer depends on the order you add them - you can now specific custom priorities when `add()`ing them to the `Environment`! The priority can be any integer you want. The default value is `0`. All CommonMark Core things will have a priority between -255 and 255. The higher the number, the earlier it will be executed.
### Multiple block/inline renderers per class
Thanks to the new prioritization system, we now support multiple renderers for the same block/inline class! The first renderer to return a non-null result will be considered the "winner" and no subsequent renderers will execute for that block/inline. No change should be required for most extensions unless you were using some weird workaround to support multiple renderers yourself.
### `RegexHelper::isEscapable()` no longer accepts `null` values
In cases where you may have previously passed a `null` value in, skip the call to this method. The previous behavior was to return `false` for `null` values, but `null` is never escapable so it's silly to make this call when we know what the result will be.
## 0.18.3
### Deprecated `Xml::escape()` argument
Starting in `0.19.0`, the `Xml::escape()` function will no longer accept the second `$preserveEntities` argument as this can lead to XSS issues. Remove this argument if your code uses it. See https://github.com/thephpleague/commonmark/issues/353 for further details.
## 0.18.0
No breaking changes were introduced, but we did add a new interface: `ConverterInface`. Consider depending on this interface in your code instead of the concrete implementation. (See #330)
## 0.17.0
## Minimum PHP version
The minimum PHP version has been increased to 5.6.5. Users on PHP 5.4 and 5.5 can still use previous versions of this library but will not receive future improvements or bug fixes.
## Removal of deprecated features
Pretty much everything marked as `@deprecated` in 0.16.0 has been removed.
## `RegexHelper`
We're now taking advantage of PHP 5.6's constant expression feature. This removes the need for `RegexHelper` to be a singleton where complex regular expressions are built and referenced using instance methods. **All regexes are now available as class constants.**
For example, instead of doing this:
```php
preg_match('/' . RegexHelper::getInstance()->getPartialRegex(RegexHelper::OPENTAG) . '/', $html);
```
You can now do this:
```php
preg_match('/' . RegexHelper::PARTIAL_OPENTAG . '/', $html);
```
(Basically, remove that function call and prefix the constant name with `PARTIAL_`).
Other instance functions like `getLinkTitleRegex()` which returned a regular expression have also been deprecated in favor of pre-defined constants like `PARTIAL_LINK_TITLE`.
The now-deprecated functionality still exists in 0.17.0 **but will be removed in the next major release.**
To summarize:
- All `REGEX_` constants are fully-formed regexes. Most are unchanged.
- All `PARTIAL_` constants need to be wrapped with a `/` on each side before use.
- All instance methods are deprecated - use a constant instead.
`RegexHelper` is also `final` now - it only contains constants and static methods and was never intended to be extended.
## Cursor state
`Cursor::saveState()` and `Cursor::restoreState()` provide the ability to rollback the state of a `Cursor`. For example:
```php
$oldState = $cursor->saveState();
// Made-up example of trying to parse something using calls
$cursor->advanceToNextNonSpaceOrTab();
$cursor->match('/foo(bar)?/');
$cursor->advanceToNextNonSpaceOrTab();
if ($someConditionThatWeDidntExpect) {
// Roll back and abort
$cursor->restoreState($oldState);
return;
}
```
This useful feature encapsulated the internal, `private` state of the `Cursor` inside of a `CursorState` object with public methods. **This was a design mistake** as it meant that any changes to the interal structure of a `Cursor` meant causing BC-breaks on the `CursorState`.
`CursorState` was also never intended for any other usage besides saving/restoring.
For those reasons, we've removed the `CursorState` class entirely and now store the state using an array. **Do not depend on the contents or structure of the array for any reason as it may change in any release without warning!** If you really need to reference information about the prior state of the cursor, either `clone` it or grab the info you need before manipulating it.
## `InlineContainer` interface
The `InlineContainer` interface was renamed to `InlineContainerInterface`. The old one still exists as a deprecated interface and will be removed in the next major release.
## 0.16.0
You may continue using the deprecated items listed below in version 0.16.x. **However, these deprecations will be removed in a future major release** (0.17.0+ or 1.0.0, whichever comes first) so consider updating your code now to prepare for that release.
## `Cursor` and `CursorState` methods
Basically, all methods in these two classes which contain `First` in their name have been deprecated. The original names were misleading as they always operated on the "first" non-space **after the current position**, which is not always the **first occurrence in the string**. You should instead use the `Next` versions instead:
- Deprecated `Cursor::advanceWhileMatches()`
- Use `Cursor::match()` instead.
- Deprecated `CursorState::getFirstNonSpaceCache()`
- Use `CursorState::getNextNonSpaceCache()` instead (identical behavior)
- Deprecated `Cursor::getFirstNonSpaceCharacter()`
- Use `Cursor::getNextNonSpaceCharacter()` instead (identical behavior)
- Deprecated `Cursor::getFirstNonSpacePosition()`
- Use `Cursor::getNextNonSpacePosition()` instead (identical behavior)
- Deprecated `Cursor::advanceToFirstNonSpace()`
- You'll probably want to use `advanceToNextNonSpaceOrTab()` if you're using this to parse blocks, but beware that it does not behave identically to the original method.
- If you need the exact functionality as the original, use `advanceToNextNonSpaceOrNewline()` instead. We're currently using this internally for parsing links and references.
The reason we now have two alternatives to the `advancedToFirstNonSpace()` function is because we accidentally assumed that a single approach would work in two different use cases. As you can see in [issue #279](https://github.com/thephpleague/commonmark/issues/279), this assumption was false. We have therefore split the two different parsing strategies into two different methods. Both will behave similarly for strings that only contain spaces, but they differ when newlines or tabs are involved.
More details about this change can be found here: https://github.com/thephpleague/commonmark/issues/280
### `RegexHelper`
`RegexHelper::REGEX_UNICODE_WHITESPACE` and `RegexHelper::getLinkDestinationRegex()` were no longer needed as of the 0.15.5 release and have therefore been deprecated and marked for removal.
### `HtmlRenderer::escape()`
`HtmlRenderer::escape()` was an instance method making it unusable as a general utility method. Its logic has been moved into a new static Xml::escape() method so use that instead - it takes the same exact methods and implements the same behavior.
### Final Utility Classes
The following utility classes were never meant to be extended and have therefore been marked `final`:
- `Html5Entities`
- `LinkParserHelper`
- `UrlEncoder`
## 0.15.0
### `CursorState` constructor
The `CursorState` constructor now requires an additional boolean parameter `$partiallyConsumedTab`.
No change should be needed in your application unless you are directly instantiating this object (unlikely).
### `DelimiterStack::findFirstMatchingOpener()` deprecated
You should use `DelimiterStack::findMatchingOpener()` instead.
The method signature is almost identical, except for the inclusion of a by-reference boolean `$oddMatch`.
The deprecated `findFirstMatchingOpener()` method was removed in the 0.16.0 release.
## 0.14.0
### `safe` option deprecated
The `safe` option has been deprecated and replaced with two new configuration options:
* `html_input` - How to handle HTML input. Set this option to one of the following values:
- `strip` - Strip all HTML (equivalent to `'safe' => true`)
- `allow` - Allow all HTML input as-is (equivalent to `'safe' => false)
- `escape` - Escape all HTML
* `allow_unsafe_links` - Whether to allow risky image URLs and links
- `true` - Allow (equivalent to `'safe' => false`)
- `false` - Remove all risky URLs (equivalent to `'safe' => true`)
Although `safe` will continue to work until 1.0.0 you should consider updating your configuration now if possible.
PK P| src/Converter.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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;
/**
* Converts CommonMark-compatible Markdown to HTML.
*/
class Converter implements ConverterInterface
{
/**
* The document parser instance.
*
* @var \League\CommonMark\DocParser
*/
protected $docParser;
/**
* The html renderer instance.
*
* @var \League\CommonMark\ElementRendererInterface
*/
protected $htmlRenderer;
/**
* Create a new commonmark converter instance.
*
* @param DocParser $docParser
* @param ElementRendererInterface $htmlRenderer
*/
public function __construct(DocParser $docParser, ElementRendererInterface $htmlRenderer)
{
$this->docParser = $docParser;
$this->htmlRenderer = $htmlRenderer;
}
/**
* Converts CommonMark to HTML.
*
* @param string $commonMark
*
* @return string
*
* @api
*/
public function convertToHtml(string $commonMark): string
{
$documentAST = $this->docParser->parse($commonMark);
return $this->htmlRenderer->renderBlock($documentAST);
}
/**
* Converts CommonMark to HTML.
*
* @see Converter::convertToHtml
*
* @param string $commonMark
*
* @return string
*/
public function __invoke(string $commonMark): string
{
return $this->convertToHtml($commonMark);
}
}
PK P
,= = src/CommonMarkConverter.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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;
/**
* Converts CommonMark-compatible Markdown to HTML.
*/
class CommonMarkConverter extends Converter
{
/**
* The currently-installed version.
*
* This might be a typical `x.y.z` version, or `x.y-dev`.
*
* @deprecated This will be removed in 1.0.0
*/
const VERSION = '0.19.0';
/**
* Create a new commonmark converter instance.
*
* @param array $config
* @param EnvironmentInterface|null $environment
*/
public function __construct(array $config = [], EnvironmentInterface $environment = null)
{
if ($environment === null) {
$environment = Environment::createCommonMarkEnvironment();
}
if ($environment instanceof ConfigurableEnvironmentInterface) {
$environment->mergeConfig($config);
}
parent::__construct(new DocParser($environment), new HtmlRenderer($environment));
}
}
PK PkL src/UnmatchedBlockCloser.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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;
use League\CommonMark\Block\Element\AbstractBlock;
class UnmatchedBlockCloser
{
/**
* @var ContextInterface
*/
private $context;
/**
* @var AbstractBlock
*/
private $oldTip;
/**
* @var AbstractBlock
*/
private $lastMatchedContainer;
/**
* @param ContextInterface $context
*/
public function __construct(ContextInterface $context)
{
$this->context = $context;
$this->resetTip();
}
/**
* @param AbstractBlock $block
*/
public function setLastMatchedContainer(AbstractBlock $block)
{
$this->lastMatchedContainer = $block;
}
public function closeUnmatchedBlocks()
{
$endLine = $this->context->getLineNumber() - 1;
while ($this->oldTip !== $this->lastMatchedContainer) {
/** @var AbstractBlock $oldTip */
$oldTip = $this->oldTip->parent();
$this->oldTip->finalize($this->context, $endLine);
$this->oldTip = $oldTip;
}
}
public function resetTip()
{
$this->oldTip = $this->context->getTip();
}
/**
* @return bool
*/
public function areAllClosed(): bool
{
return $this->context->getTip() === $this->lastMatchedContainer;
}
}
PK P ( src/ConfigurableEnvironmentInterface.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark;
use League\CommonMark\Block\Parser\BlockParserInterface;
use League\CommonMark\Block\Renderer\BlockRendererInterface;
use League\CommonMark\Inline\Parser\InlineParserInterface;
use League\CommonMark\Inline\Processor\InlineProcessorInterface;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
/**
* Interface for an Environment which can be configured with config settings, parsers, processors, and renderers
*/
interface ConfigurableEnvironmentInterface extends EnvironmentInterface
{
/**
* @param array $config
*/
public function mergeConfig(array $config = []);
/**
* @param array $config
*/
public function setConfig(array $config = []);
/**
* Registers the given block parser with the Environment
*
* @param BlockParserInterface $parser Block parser instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addBlockParser(BlockParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface;
/**
* Registers the given inline parser with the Environment
*
* @param InlineParserInterface $parser Inline parser instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addInlineParser(InlineParserInterface $parser, int $priority = 0): ConfigurableEnvironmentInterface;
/**
* Registers the given inline processor with the Environment
*
* @param InlineProcessorInterface $processor Inline processor instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addInlineProcessor(InlineProcessorInterface $processor, int $priority = 0): 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
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addBlockRenderer($blockClass, BlockRendererInterface $blockRenderer, int $priority = 0): ConfigurableEnvironmentInterface;
/**
* Registers the given inline renderer with the Environment
*
* @param string $inlineClass The fully-qualified inline element class name the renderer below should handle
* @param InlineRendererInterface $renderer The renderer responsible for rendering the type of element given above
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return self
*/
public function addInlineRenderer(string $inlineClass, InlineRendererInterface $renderer, int $priority = 0): ConfigurableEnvironmentInterface;
}
PK PPP P src/Block/Element/Heading.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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\Block\Element;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
class Heading extends AbstractStringContainerBlock implements InlineContainerInterface
{
/**
* @var int
*/
protected $level;
/**
* @param int $level
* @param string|string[] $contents
*/
public function __construct(int $level, $contents)
{
parent::__construct();
$this->level = $level;
if (!\is_array($contents)) {
$contents = [$contents];
}
foreach ($contents as $line) {
$this->addLine($line);
}
}
/**
* @return int
*/
public function getLevel(): int
{
return $this->level;
}
public function finalize(ContextInterface $context, int $endLineNumber)
{
parent::finalize($context, $endLineNumber);
$this->finalStringContents = \implode("\n", $this->strings->toArray());
}
/**
* Returns true if this block can contain the given block as a child node
*
* @param AbstractBlock $block
*
* @return bool
*/
public function canContain(AbstractBlock $block): bool
{
return false;
}
/**
* Whether this is a code block
*
* @return bool
*/
public function isCode(): bool
{
return false;
}
public function matchesNextLine(Cursor $cursor): bool
{
return false;
}
/**
* @param ContextInterface $context
* @param Cursor $cursor
*/
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
{
// nothing to do; contents were already added via the constructor.
}
}
PK P9 src/Block/Element/HtmlBlock.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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\Block\Element;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
use League\CommonMark\Util\RegexHelper;
class HtmlBlock extends AbstractStringContainerBlock
{
// Any changes to these constants should be reflected in .phpstorm.meta.php
const TYPE_1_CODE_CONTAINER = 1;
const TYPE_2_COMMENT = 2;
const TYPE_3 = 3;
const TYPE_4 = 4;
const TYPE_5_CDATA = 5;
const TYPE_6_BLOCK_ELEMENT = 6;
const TYPE_7_MISC_ELEMENT = 7;
/**
* @var int
*/
protected $type;
/**
* @param int $type
*/
public function __construct(int $type)
{
parent::__construct();
$this->type = $type;
}
/**
* @return int
*/
public function getType(): int
{
return $this->type;
}
/**
* @param int $type
*/
public function setType(int $type)
{
$this->type = $type;
}
/**
* Returns true if this block can contain the given block as a child node
*
* @param AbstractBlock $block
*
* @return bool
*/
public function canContain(AbstractBlock $block): bool
{
return false;
}
/**
* Whether this is a code block
*
* @return bool
*/
public function isCode(): bool
{
return true;
}
public function matchesNextLine(Cursor $cursor): bool
{
if ($cursor->isBlank() && ($this->type === self::TYPE_6_BLOCK_ELEMENT || $this->type === self::TYPE_7_MISC_ELEMENT)) {
return false;
}
return true;
}
public function finalize(ContextInterface $context, int $endLineNumber)
{
parent::finalize($context, $endLineNumber);
$this->finalStringContents = \implode("\n", $this->strings->toArray());
}
/**
* @param ContextInterface $context
* @param Cursor $cursor
*/
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
{
/** @var self $tip */
$tip = $context->getTip();
$tip->addLine($cursor->getRemainder());
// Check for end condition
if ($this->type >= self::TYPE_1_CODE_CONTAINER && $this->type <= self::TYPE_5_CDATA) {
if ($cursor->match(RegexHelper::getHtmlBlockCloseRegex($this->type)) !== null) {
$this->finalize($context, $context->getLineNumber());
}
}
}
}
PK PW?# # src/Block/Element/Paragraph.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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\Block\Element;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
class Paragraph extends AbstractStringContainerBlock implements InlineContainerInterface
{
/**
* Returns true if this block can contain the given block as a child node
*
* @param AbstractBlock $block
*
* @return bool
*/
public function canContain(AbstractBlock $block): bool
{
return false;
}
/**
* Whether this is a code block
*
* @return bool
*/
public function isCode(): bool
{
return false;
}
public function matchesNextLine(Cursor $cursor): bool
{
if ($cursor->isBlank()) {
$this->lastLineBlank = true;
return false;
}
return true;
}
public function finalize(ContextInterface $context, int $endLineNumber)
{
parent::finalize($context, $endLineNumber);
$this->finalStringContents = \preg_replace('/^ */m', '', \implode("\n", $this->getStrings()));
// Short-circuit
if ($this->finalStringContents === '' || $this->finalStringContents[0] !== '[') {
return;
}
$cursor = new Cursor($this->finalStringContents);
$referenceFound = $this->parseReferences($context, $cursor);
$this->finalStringContents = $cursor->getRemainder();
if ($referenceFound && $cursor->isAtEnd()) {
$this->detach();
}
}
/**
* @param ContextInterface $context
* @param Cursor $cursor
*
* @return bool
*/
protected function parseReferences(ContextInterface $context, Cursor $cursor)
{
$referenceFound = false;
while ($cursor->getCharacter() === '[' && $context->getReferenceParser()->parse($cursor)) {
$this->finalStringContents = $cursor->getRemainder();
$referenceFound = true;
}
return $referenceFound;
}
/**
* @param ContextInterface $context
* @param Cursor $cursor
*/
public function handleRemainingContents(ContextInterface $context, Cursor $cursor)
{
$cursor->advanceToNextNonSpaceOrTab();
/** @var self $tip */
$tip = $context->getTip();
$tip->addLine($cursor->getRemainder());
}
/**
* @return string[]
*/
public function getStrings(): array
{
return $this->strings->toArray();
}
}
PK PvHw # src/Block/Element/AbstractBlock.phpnu W+A
*
* Original code based on the CommonMark JS reference parser (https://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\Block\Element;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
use League\CommonMark\Node\Node;
/**
* Block-level element
*/
abstract class AbstractBlock extends Node
{
/**
* Used for storage of arbitrary data.
*
* @var array
*/
public $data = [];
/**
* @var bool
*/
protected $open = true;
/**
* @var bool
*/
protected $lastLineBlank = false;
/**
* @var int
*/
protected $startLine;
/**
* @var int
*/
protected $endLine;
/**
* @param Node|null $node
*/
protected function setParent(Node $node = null)
{
if ($node && !$node instanceof self) {
throw new \InvalidArgumentException('Parent of block must also be block (can not be inline)');
}
parent::setParent($node);
}
/**
* @return bool
*/
public function isContainer(): bool
{
return true;
}
/**
* @return bool
*/
public function hasChildren(): bool
{
return $this->firstChild !== null;
}
/**
* Returns true if this block can contain the given block as a child node
*
* @param AbstractBlock $block
*
* @return bool
*/
abstract public function canContain(AbstractBlock $block): bool;
/**
* Whether this is a code block
*
* @return bool
*/
abstract public function isCode(): bool;
/**
* @param Cursor $cursor
*
* @return bool
*/
abstract public function matchesNextLine(Cursor $cursor): bool;
/**
* @param int $startLine
*
* @return $this
*/
public function setStartLine(int $startLine)
{
$this->startLine = $startLine;
if (empty($this->endLine)) {
$this->endLine = $startLine;
}
return $this;
}
/**
* @return int
*/
public function getStartLine(): int
{
return $this->startLine;
}
/**
* @param int $endLine
*
* @return $this
*/
public function setEndLine(int $endLine)
{
$this->endLine = $endLine;
return $this;
}
/**
* @return int
*/
public function getEndLine(): int
{
return $this->endLine;
}
/**
* Whether the block ends with a blank line
*
* @return bool
*/
public function endsWithBlankLine(): bool
{
return $this->lastLineBlank;
}
/**
* @param bool $blank
*/
public function setLastLineBlank(bool $blank)
{
$this->lastLineBlank = $blank;
}
/**
* Determines whether the last line should be marked as blank
*
* @param Cursor $cursor
* @param int $currentLineNumber
*
* @return bool
*/
public function shouldLastLineBeBlank(Cursor $cursor, int $currentLineNumber): bool
{
return $cursor->isBlank();
}
/**
* Whether the block is open for modifications
*
* @return bool
*/
public function isOpen(): bool
{
return $this->open;
}
/**
* Finalize the block; mark it closed for modification
*
* @param ContextInterface $context
* @param int $endLineNumber
*/
public function finalize(ContextInterface $context, int $endLineNumber)
{
if (!$this->open) {
return;
}
$this->open = false;
$this->endLine = $endLineNumber;
$context->setTip($context->getTip()->parent());
}
/**
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function getData(string $key, $default = null)
{
return \array_key_exists($key, $this->data) ? $this->data[$key] : $default;
}
}
PK P