All notable changes to this project will be documented in this file. Updates should follow the Keep a CHANGELOG principles.
See https://commonmark.thephpleague.com/2.0/upgrading/ for detailed information on upgrading to version 2.0.
- Added new
FrontMatterExtension
(see documentation) - Added
Query
class to simplify Node traversal when looking to take action on certain Nodes - Added the ability to delegate event dispatching to PSR-14 compliant event dispatcher libraries
- Added the ability to configure disallowed raw HTML tags (#507)
- Added the ability for Mentions to use multiple characters for their symbol (#514, #550)
- Added
heading_permalink/min_heading_level
andheading_permalink/max_heading_level
options to control which headings get permalinks (#519) - Added
footnote/backref_symbol
option for customizing backreference link appearance (#522) - Added new
HtmlFilter
andStringContainerHelper
utility classes - Added new
AbstractBlockContinueParser
class to simplify the creation of custom block parsers - Added several new classes and interfaces:
BlockContinue
BlockContinueParserInterface
BlockStart
BlockStartParserInterface
ChildNodeRendererInterface
ConfigurableExtensionInterface
ConfigurationBuilderInterface
ConfigurationProviderInterface
CursorState
DashParser
(extracted fromPunctuationParser
)DelimiterParser
DocumentBlockParser
DocumentRenderedEvent
EllipsesParser
(extracted fromPunctuationParser
)ExpressionInterface
HtmlRendererInterface
InlineParserEngineInterface
InlineParserMatch
MarkdownParserState
MarkdownParserStateInterface
MutableConfigurationInterface
Query
ReadOnlyConfiguration
ReferenceableInterface
RenderedContent
RenderedContentInterface
- Added several new methods:
ConfigurationInterface::exists()
Environment::createDefaultConfiguration()
Environment::setEventDispatcher()
EnvironmentInterface::getExtensions()
EnvironmentInterface::getInlineParsers()
FencedCode::setInfo()
Heading::setLevel()
HtmlRenderer::renderDocument()
InlineParserContext::getFullMatch()
InlineParserContext::getFullMatchLength()
InlineParserContext::getMatches()
InlineParserContext::getSubMatches()
InvalidOptionException::forConfigOption()
InvalidOptionException::forParameter()
LinkParserHelper::parsePartialLinkLabel()
LinkParserHelper::parsePartialLinkTitle()
RegexHelper::isLetter()
StringContainerInterface::setLiteral()
TableCell::getType()
TableCell::setType()
TableCell::getAlign()
TableCell::setAlign()
- Added purity markers throughout the codebase (verified with Psalm)
CommonMarkConverter::convertToHtml()
now returns an instance ofRenderedContentInterface
. This can be cast to a string for backward compatibility with 1.x.- Changes to configuration options:
enable_em
has been renamed tocommonmark/enable_em
enable_strong
has been renamed tocommonmark/enable_strong
use_asterisk
has been renamed tocommonmark/use_asterisk
use_underscore
has been renamed tocommonmark/use_underscore
unordered_list_markers
has been renamed tocommonmark/unordered_list_markers
mentions/*/symbol
has been renamed tomentions/*/prefix
mentions/*/regex
has been renamed tomentions/*/pattern
and requires partial regular expressions (without delimiters or flags)max_nesting_level
now defaults toPHP_INT_MAX
and no longer supports floats
- Event dispatching is now fully PSR-14 compliant
- The
AbstractBlock::$data
andAbstractInline::$data
arrays were replaced with aData
array-like object on the baseNode
class - Moved and renamed several classes - see the full list here
- Implemented a new approach to block parsing. This was a massive change, so here are the highlights:
- Functionality previously found in block parsers and node elements has moved to block parser factories and block parsers, respectively (more details)
ConfigurableEnvironmentInterface::addBlockParser()
is nowEnvironmentBuilderInterface::addBlockParserFactory()
ReferenceParser
was re-implemented and works completely different than before- The paragraph parser no longer needs to be added manually to the environment
- Implemented a new approach to inline parsing where parsers can now specify longer strings or regular expressions they want to parse (instead of just single characters):
InlineParserInterface::getCharacters()
is nowgetMatchDefinition()
and returns an instance ofInlineParserMatch
InlineParserContext::__construct()
now requires the contents to be provided as aCursor
instead of astring
- Implemented delimiter parsing as a special type of inline parser (via the new
DelimiterParser
class) - Changed block and inline rendering to use common methods and interfaces
BlockRendererInterface
andInlineRendererInterface
were replaced byNodeRendererInterface
with slightly different parameters. All core renderers now implement this interface.ConfigurableEnvironmentInterface::addBlockRenderer()
andaddInlineRenderer()
were combined intoEnvironmentBuilderInterface::addRenderer()
EnvironmentInterface::getBlockRenderersForClass()
andgetInlineRenderersForClass()
are now justgetRenderersForClass()
- Completely refactored the Configuration implementation
Configuration
object must now be configured with a schema and all options must match that schema - arbitrary keys are no longer permittedConfiguration::__construct()
no longer accepts the default configuration values - useConfiguration::merge()
insteadConfigurationInterface
now only contains aget(string $key)
; this method no longer allows arbitrary default values to be returned if the option is missingConfigurableEnvironmentInterface
was renamed toEnvironmentBuilderInterface
ExtensionInterface::register()
now requires anEnvironmentBuilderInterface
param instead ofConfigurableEnvironmentInterface
- Re-implemented the GFM Autolink extension using the new inline parser approach instead of document processors
EmailAutolinkProcessor
is nowEmailAutolinkParser
UrlAutolinkProcessor
is nowUrlAutolinkParser
HtmlElement
can now properly handle array (i.e.class
) and boolean (i.e.checked
) attribute valuesHtmlElement
automatically flattens any attributes with array values into space-separated strings, removing duplicate entries- Combined separate classes/interfaces into one:
DisallowedRawHtmlRenderer
replacesDisallowedRawHtmlBlockRenderer
andDisallowedRawHtmlInlineRenderer
NodeRendererInterface
replacesBlockRendererInterface
andInlineRendererInterface
- Renamed the following methods:
Environment
andConfigurableEnvironmentInterface
:addBlockParser()
is nowaddBlockStartParser()
ReferenceMap
andReferenceMapInterface
:addReference()
is nowadd()
getReference()
is nowget()
listReferences()
is nowgetIterator()
- Various node (block/inline) classes:
getContent()
is nowgetLiteral()
setContent()
is nowsetLiteral()
- Moved and renamed the following constants:
EnvironmentInterface::HTML_INPUT_ALLOW
is nowHtmlFilter::ALLOW
EnvironmentInterface::HTML_INPUT_ESCAPE
is nowHtmlFilter::ESCAPE
EnvironmentInterface::HTML_INPUT_STRIP
is nowHtmlFilter::STRIP
- Changed the visibility of the following properties:
TableCell::$align
is nowprivate
TableCell::$type
is nowprivate
TableSection::$type
is nowprivate
- Added missing return types to virtually every class and interface method
- Several methods which previously returned
$this
now returnvoid
Delimiter::setPrevious()
Node::replaceChildren()
Context::setTip()
Context::setContainer()
Context::setBlocksParsed()
AbstractStringContainer::setContent()
AbstractWebResource::setUrl()
Heading
nodes no longer directly contain a copy of their inner textStringContainerInterface
can now be used for inlines, not just blocksArrayCollection
is now final and only supports integer keysCursor::saveState()
andCursor::restoreState()
now useCursorState
objects instead of arraysNodeWalker::next()
now enters, traverses any children, and leaves all elements which may have children (basically all blocks plus any inlines with children). Previously, it only did this for elements explicitly marked as "containers".InvalidOptionException
was renamed toInvalidConfigurationException
and now extends fromUnexpectedValueException
- Anything with a
getReference(): ReferenceInterface
method now implementsReferencableInterface
- Several changes made to the Footnote extension:
- Footnote identifiers can no longer contain spaces
- Anonymous footnotes can now span subsequent lines
- Footnotes can now contain multiple lines of content, including sub-blocks, by indenting them
- Footnote event listeners now have numbered priorities (but still execute in the same order)
- Footnotes must now be separated from previous content by a blank line
- The line numbers (keys) returned via
MarkdownInput::getLines()
now start at 1 instead of 0 DelimiterProcessorCollectionInterface
now extendsCountable
RegexHelper::PARTIAL_
constants must always be used in case-insensitive contextsHeadingPermalinkProcessor
no longer accepts text normalizers via the constructor - these must be provided via configuration instead
- Fixed parsing of footnotes without content
- Fixed rendering of orphaned footnotes and footnote refs
- Fixed some URL autolinks breaking too early (#492)
- Removed support for PHP 7.1
- Removed all previously-deprecated functionality:
- Removed the
Converter
class andConverterInterface
- Removed the
bin/commonmark
script - Removed the
Html5Entities
utility class - Removed the
InlineMentionParser
(useMentionParser
instead) - Removed
DefaultSlugGenerator
andSlugGeneratorInterface
from theExtension/HeadingPermalink/Slug
sub-namespace (use the new ones under./SlugGenerator
instead) - Removed the following
ArrayCollection
methods:add()
set()
get()
remove()
isEmpty()
contains()
indexOf()
containsKey()
replaceWith()
removeGaps()
- Removed the
ConfigurableEnvironmentInterface::setConfig()
method - Removed the
ListBlock::TYPE_UNORDERED
constant - Removed the
CommonMarkConverter::VERSION
constant - Removed the
HeadingPermalinkRenderer::DEFAULT_INNER_CONTENTS
constant - Removed the
heading_permalink/inner_contents
configuration option
- Removed the
- Removed now-unused classes:
AbstractStringContainerBlock
BlockRendererInterface
Context
ContextInterface
Converter
ConverterInterface
InlineRendererInterface
PunctuationParser
(was split into two classes:DashParser
andEllipsesParser
)UnmatchedBlockCloser
- Removed the following methods, properties, and constants:
AbstractBlock::$open
AbstractBlock::$lastLineBlank
AbstractBlock::isContainer()
AbstractBlock::canContain()
AbstractBlock::isCode()
AbstractBlock::matchesNextLine()
AbstractBlock::endsWithBlankLine()
AbstractBlock::setLastLineBlank()
AbstractBlock::shouldLastLineBeBlank()
AbstractBlock::isOpen()
AbstractBlock::finalize()
AbstractBlock::getData()
AbstractInline::getData()
ConfigurableEnvironmentInterface::addBlockParser()
ConfigurableEnvironmentInterface::mergeConfig()
ConfigurationInterface::merge()
(moved to newMutableConfigurationInterface
)ConfigurationInterface::replace()
ConfigurationInterface::set()
(moved to newMutableConfigurationInterface
)Delimiter::setCanClose()
EnvironmentInterface::getConfig()
EnvironmentInterface::getInlineParsersForCharacter()
EnvironmentInterface::getInlineParserCharacterRegex()
HtmlRenderer::renderBlock()
HtmlRenderer::renderBlocks()
HtmlRenderer::renderInline()
HtmlRenderer::renderInlines()
Node::isContainer()
RegexHelper::matchAll()
(use the newmatchFirst()
method instead)RegexHelper::REGEX_WHITESPACE
- Removed the second
$contents
argument from theHeading
constructor
The following things have been deprecated and will not be supported in v3.0:
Environment::mergeConfig()
(set configuration before instantiation instead)- Instantiating
CommonMarkConverter
orGithubFlavoredMarkdownConverter
with custom environments (useMarkdownConverter
instead) Environment::createCommonMarkEnvironment()
andEnvironment::createGFMEnvironment()
- Alternative 1: Use
CommonMarkConverter
orGithubFlavoredMarkdownConverter
if you don't need to customize the environment - Alternative 2: Instantiate a new
Environment
and add the necessary extensions yourself
- Alternative 1: Use