All notable changes to this project will be documented in this file. Updates should follow the Keep a CHANGELOG principles.
Upgrading from 1.x? See https://commonmark.thephpleague.com/2.0/upgrading/ for additional information.
EmbedProcessor no longer calls updateEmbeds() when there are no embeds to update (#1081)benchmark.php CSV path validation for non-existent files (#1068, #1085)This is a security release to address a potential cross-site scripting (XSS) vulnerability when using the AttributesExtension with untrusted user input.
attributes/allow config option to specify which attributes users are allowed to set on elements (default allows virtually all attributes)AttributesExtension blocks all attributes starting with on unless explicitly allowed via the attributes/allow config optionallow_unsafe_links option is now respected by the AttributesExtension when users specify href and src attributesThis is a security release to address potential denial of service attacks when parsing specially crafted, malicious input from untrusted sources (like user input).
max_delimiters_per_line config option to prevent denial of service attacks when parsing malicious inputtable/max_autocompleted_cells config option to prevent denial of service attacks when parsing large tablesAttributesExtension now supports attributes without values (#985, #986)AutolinkExtension exposes two new configuration options to override the default behavior (#969, #987):
autolink/allowed_protocols - an array of protocols to allow autolinking forautolink/default_protocol - the default protocol to use when none is specifiedRegexHelper::isWhitespace() method to check if a given character is an ASCII whitespace characterCacheableDelimiterProcessorInterface to ensure linear complexity for dynamic delimiter processingBracket delimiter type to optimize bracket parsing[ and ] are no longer added as Delimiter objects on the stack; a new Bracket type with its own stack is used insteadUrlAutolinkParser no longer parses URLs with more than 127 subdomainsDelimiterInterface::getIndex()
DelimiterStack now accepts integer positions for any $stackBottom argumentsource, add search to list of recognized block tagstrue value (#1040)Table start line numbers (#1037)AttributesExtension now supports attributes without values (#985, #986)AutolinkExtension exposes two new configuration options to override the default behavior (#969, #987):
autolink/allowed_protocols - an array of protocols to allow autolinking forautolink/default_protocol - the default protocol to use when none is specifiedParagraphs only containing link reference definitions will be kept in the AST until the Document is finalized
Paragraph)UrlAutolinkParser incorrectly parsing text containing www anywhere before an autolink (#1025)FencedCodeRenderer: don't add language- to class if already prefixedDelimiterProcessorInterface::getDelimiterUse() is deprecated
CacheableDelimiterProcessorInterface to help the engine perform caching to avoid performance issues.null from DelimiterInterface::getIndex()) is deprecated and will not be supported in 3.0DelimiterInterface::isActive() and DelimiterInterface::setActive(), as these are no longer used by the engineDelimiterStack::removeEarlierMatches() and DelimiterStack::searchByCharacter(), as these are no longer used by the engineDelimiterInterface as the $stackBottom argument to DelimiterStack::processDelimiters() or ::removeAll() is deprecated and will not be supported in 3.0; pass the integer position instead.ExternalLinkProcessor not fully disabling the rel attribute when configured to do so (#992)CommonMarkException marker interface for all exceptions thrown by the libraryAlreadyInitializedExceptionInvalidArgumentExceptionIOExceptionLogicExceptionMissingDependencyExceptionNoMatchingRendererExceptionParserLogicExceptionheading_permalink/apply_id_to_heading - When true, the id attribute will be applied to the heading element itself instead of the <a> tagheading_permalink/heading_class - class to apply to the heading elementheading_permalink/insert - now accepts none to prevent the creation of the <a> linktable/alignment_attributes configuration option to control how table cell alignment is rendered (#959)RuntimeException to LogicException (or something extending it), including:
CallbackGenerators that fail to set a URL or return an expected valueMarkdownParser when deactivating the last block parser or attempting to get an active block parser when they've all been closedEnvironmentNode when no renderer has been registered for itHeadingPermalinkProcessor now throws InvalidConfigurationException instead of RuntimeException when invalid config values are given.HtmlElement::setAttribute() no longer requires the second parameter for boolean attributes@throws docblocks throughout the codebase, including ConverterInterface, MarkdownConverter, and MarkdownConverterInterface.
\RuntimeExceptions were thrown, which was inaccurate as \LogicExceptions were also possible.mb_internal_encoding() is set to something other than UTF-8 (#951)TaskListItemMarkerRenderer not including HTML attributes set on the node by other extensions (#947).) (#943)InlineParserEngine when no inline parsers are registered in the Environment (#908)EmbedStartParser to always capture embed-like lines in container blocks, regardless of parent block typeEmbedProcessor to also remove Embed blocks that aren't direct children of the DocumentEmbedProcessor to 1010EmbedExtension not parsing embeds following a list block (#898)EmbedExtension (#805)DocumentRendererInterface as a replacement for the now-deprecated MarkdownRendererInterfaceMarkdownRendererInterface; use DocumentRendererInterface insteadsymfony/deprecation-contracts constraintMarkdownConverterInterface to reduce noiseConverterInterfaceMarkdownToXmlConverter classHtmlDecorator class which can wrap existing renderers with additional HTML tagstable/wrap config to apply an optional wrapping/container element around a table (#780)HtmlElement contents can now consist of any Stringable, not just HtmlElement and stringMarkdownConverterInterface and its convertToHtml() method; use ConverterInterface and convert() insteadEnvironment::dispatch() to fix deprecation warning (#778)heading_permalink/aria_hidden config option (#741)No changes were introduced since the previous RC2 release. See all entries below for a list of changes between 1.x and 2.0.
No changes were introduced since the previous release.
getEnvironment() method of CommonMarkConverter and GithubFlavoredMarkdownConverter will always return the concrete, configurable Environment for upgrading convenienceFrontMatterExtension (see documentation)DescriptionListExtension (see documentation)DefaultAttributesExtension (see documentation)XmlRenderer to simplify AST debugging (see documentation) (#431)heading_permalink/min_heading_level and heading_permalink/max_heading_level options to control which headings get permalinks (#519)heading_permalink/fragment_prefix to allow customizing the URL fragment prefix (#602)footnote/backref_symbol option for customizing backreference link appearance (#522)slug_normalizer/max_length option to control the maximum length of generated URL slugsslug_normalizer/unique option to control whether unique slugs should be generated per-document or per-environmentQuery class to simplify Node traversal when looking to take action on certain NodesHtmlFilter and StringContainerHelper utility classesAbstractBlockContinueParser class to simplify the creation of custom block parsersBlockContinueBlockContinueParserInterfaceBlockContinueParserWithInlinesInterfaceBlockStartBlockStartParserInterfaceChildNodeRendererInterfaceConfigurableExtensionInterfaceCursorStateDashParser (extracted from PunctuationParser)DelimiterParserDocumentBlockParserDocumentPreRenderEventDocumentRenderedEventEllipsesParser (extracted from PunctuationParser)ExpressionInterfaceFallbackNodeXmlRendererInlineParserEngineInterfaceInlineParserMatchMarkdownParserStateMarkdownParserStateInterfaceMarkdownRendererInterfaceQueryRawMarkupContainerInterfaceReferenceableInterfaceRenderedContentRenderedContentInterfaceReplaceUnpairedQuotesListenerSpecReaderTableOfContentsRendererUniqueSlugNormalizerUniqueSlugNormalizerInterfaceXmlRendererXmlNodeRendererInterfaceCursor::getCurrentCharacter()Environment::createDefaultConfiguration()Environment::setEventDispatcher()EnvironmentInterface::getExtensions()EnvironmentInterface::getInlineParsers()EnvironmentInterface::getSlugNormalizer()FencedCode::setInfo()Heading::setLevel()HtmlRenderer::renderDocument()InlineParserContext::getFullMatch()InlineParserContext::getFullMatchLength()InlineParserContext::getMatches()InlineParserContext::getSubMatches()LinkParserHelper::parsePartialLinkLabel()LinkParserHelper::parsePartialLinkTitle()Node::assertInstanceOf()RegexHelper::isLetter()StringContainerInterface::setLiteral()TableCell::getType()TableCell::setType()TableCell::getAlign()TableCell::setAlign()CommonMarkConverter::convertToHtml() now returns an instance of RenderedContentInterface. This can be cast to a string for backward compatibility with 1.x.<p> tags (#613)name attributes (#602)content prefix by default (#602)enable_em has been renamed to commonmark/enable_emenable_strong has been renamed to commonmark/enable_stronguse_asterisk has been renamed to commonmark/use_asteriskuse_underscore has been renamed to commonmark/use_underscoreunordered_list_markers has been renamed to commonmark/unordered_list_markersmentions/*/symbol has been renamed to mentions/*/prefixmentions/*/regex has been renamed to mentions/*/pattern and requires partial regular expressions (without delimiters or flags)max_nesting_level now defaults to PHP_INT_MAX and no longer supports floatsheading_permalink/slug_normalizer has been renamed to slug_normalizer/instanceHeadingPermalinkExtension and FootnoteExtension were modified to ensure they never produce a slug which conflicts with slugs created by the other extensionSlugNormalizer::normalizer() now supports optional prefixes and max length options passed in via the $context argumentAbstractBlock::$data and AbstractInline::$data arrays were replaced with a Data array-like object on the base Node classConfigurableEnvironmentInterface::addBlockParser() is now EnvironmentBuilderInterface::addBlockParserFactory()ReferenceParser was re-implemented and works completely different than beforeInlineParserInterface::getCharacters() is now getMatchDefinition() and returns an instance of InlineParserMatchInlineParserContext::__construct() now requires the contents to be provided as a Cursor instead of a stringDelimiterParser class)BlockRendererInterface and InlineRendererInterface were replaced by NodeRendererInterface with slightly different parameters. All core renderers now implement this interface.ConfigurableEnvironmentInterface::addBlockRenderer() and addInlineRenderer() were combined into EnvironmentBuilderInterface::addRenderer()EnvironmentInterface::getBlockRenderersForClass() and getInlineRenderersForClass() are now just getRenderersForClass()league/config package with a new namespaceConfiguration objects 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 - use Configuration::merge() insteadConfigurationInterface now only contains a get(string $key); this method no longer allows arbitrary default values to be returned if the option is missingConfigurableEnvironmentInterface was renamed to EnvironmentBuilderInterfaceExtensionInterface::register() now requires an EnvironmentBuilderInterface param instead of ConfigurableEnvironmentInterfaceEmailAutolinkProcessor is now EmailAutolinkParserUrlAutolinkProcessor is now UrlAutolinkParserHtmlElement 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 entriesDisallowedRawHtmlRenderer replaces DisallowedRawHtmlBlockRenderer and DisallowedRawHtmlInlineRendererNodeRendererInterface replaces BlockRendererInterface and InlineRendererInterfaceEnvironment and ConfigurableEnvironmentInterface:
addBlockParser() is now addBlockStartParser()ReferenceMap and ReferenceMapInterface:
addReference() is now add()getReference() is now get()listReferences() is now getIterator()getContent() is now getLiteral()setContent() is now setLiteral()EnvironmentInterface::HTML_INPUT_ALLOW is now HtmlFilter::ALLOWEnvironmentInterface::HTML_INPUT_ESCAPE is now HtmlFilter::ESCAPEEnvironmentInterface::HTML_INPUT_STRIP is now HtmlFilter::STRIPTableCell::TYPE_HEAD is now TableCell::TYPE_HEADERTableCell::TYPE_BODY is now TableCell::TYPE_DATAAttributesInline::$attributes is now privateAttributesInline::$block is now privateTableCell::$align is now privateTableCell::$type is now privateTableSection::$type is now private$this now return void
Delimiter::setPrevious()Node::replaceChildren()Context::setTip()Context::setContainer()Context::setBlocksParsed()AbstractStringContainer::setContent()AbstractWebResource::setUrl()final:
ArrayCollectionEmphasisFencedCodeHeadingHtmlBlockHtmlElementHtmlInlineIndentedCodeNewlineStrikethroughStrongTextHeading nodes no longer directly contain a copy of their inner textStringContainerInterface can now be used for inlines, not just blocksArrayCollection only supports integer keysHtmlElement now implements StringableCursor::saveState() and Cursor::restoreState() now use CursorState 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 removedgetReference(): ReferenceInterface method now implements ReferencableInterfaceSmartPunct extension now replaces all unpaired Quote elements with Text elements towards the end of parsing, making the QuoteRenderer unnecessaryMarkdownInput::getLines() now start at 1 instead of 0DelimiterProcessorCollectionInterface now extends CountableRegexHelper::PARTIAL_ constants must always be used in case-insensitive contextsHeadingPermalinkProcessor no longer accepts text normalizers via the constructor - these must be provided via configuration insteadAnonymousFootnoteRefParser and HeadingPermalinkProcessor now implement EnvironmentAwareInterface instead of ConfigurationAwareInterfaceTextNormalizerInterface::normalize() must now be an arraytitle attribute for Link and Image nodes is now stored using a dedicated property instead of stashing it in $dataListData::$delimiter now returns either ListBlock::DELIM_PERIOD or ListBlock::DELIM_PAREN instead of the literal delimiterAbstractStringContainer not actually being abstractEnvironment instances into the CommonMarkConverter and GithubFlavoredMarkdownConverter constructorsConverter class and ConverterInterfacebin/commonmark scriptHtml5Entities utility classInlineMentionParser (use MentionParser instead)DefaultSlugGenerator and SlugGeneratorInterface from the Extension/HeadingPermalink/Slug sub-namespace (use the new ones under ./SlugGenerator instead)ArrayCollection methods:
add()set()get()remove()isEmpty()contains()indexOf()containsKey()replaceWith()removeGaps()ConfigurableEnvironmentInterface::setConfig() methodListBlock::TYPE_UNORDERED constantCommonMarkConverter::VERSION constantHeadingPermalinkRenderer::DEFAULT_INNER_CONTENTS constantheading_permalink/inner_contents configuration optionAbstractStringContainerBlockBlockRendererInterfaceContextContextInterfaceConverterConverterInterfaceInlineRendererInterfacePunctuationParser (was split into two classes: DashParser and EllipsesParser)QuoteRendererUnmatchedBlockCloserAbstractBlock::$openAbstractBlock::$lastLineBlankAbstractBlock::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()Delimiter::setCanClose()EnvironmentInterface::getConfig()EnvironmentInterface::getInlineParsersForCharacter()EnvironmentInterface::getInlineParserCharacterRegex()HtmlRenderer::renderBlock()HtmlRenderer::renderBlocks()HtmlRenderer::renderInline()HtmlRenderer::renderInlines()Node::isContainer()RegexHelper::matchAll() (use the new matchFirst() method instead)RegexHelper::REGEX_WHITESPACE$contents argument from the Heading constructorThe following things have been deprecated and will not be supported in v3.0:
Environment::mergeConfig() (set configuration before instantiation instead)Environment::createCommonMarkEnvironment() and Environment::createGFMEnvironment()
CommonMarkConverter or GithubFlavoredMarkdownConverter if you don't need to customize the environmentEnvironment and add the necessary extensions yourself