Release Notes
2.7.1 - 2025-07-20
Notable Changes
Changed
- Optimized several regular expressions in
RegexHelperto improve performance (#674, #1086)
Fixed
EmbedProcessorno longer callsupdateEmbeds()when there are no embeds to update (#1081)- Fixed missing
benchmark.phpCSV path validation for non-existent files (#1068, #1085)
New Contributors
- @driesvints made their first contribution in https://github.com/thephpleague/commonmark/pull/1077
- @adielcristo made their first contribution in https://github.com/thephpleague/commonmark/pull/1079
- @Copilot made their first contribution in https://github.com/thephpleague/commonmark/pull/1085
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.7.0…2.7.1
2.7.0 - 2025-05-05
This is a security release to address a potential cross-site scripting (XSS) vulnerability when using the AttributesExtension with untrusted user input.
Added
- Added
attributes/allowconfig option to specify which attributes users are allowed to set on elements (default allows virtually all attributes)
Changed
- The
AttributesExtensionblocks all attributes starting withonunless explicitly allowed via theattributes/allowconfig option - The
allow_unsafe_linksoption is now respected by theAttributesExtensionwhen users specifyhrefandsrcattributes
2.6.2 - 2025-04-18
Fixed
- Fixed Attributes extension parsing regression (#1071)
Other Changes
- fix incorrect interface in docs v2.6 by @CharrafiMed in https://github.com/thephpleague/commonmark/pull/1063
- docs/2.6/extensions/front-matter.md: add missing newline by @DanielEScherzer in https://github.com/thephpleague/commonmark/pull/1069
New Contributors
- @CharrafiMed made their first contribution in https://github.com/thephpleague/commonmark/pull/1063
- @DanielEScherzer made their first contribution in https://github.com/thephpleague/commonmark/pull/1069
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.6.1…2.6.2
2.6.1 - 2024-12-29
Fixed
- Rendered list items should only add newlines around block-level children (#1059, #1061)
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.6.0…2.6.1
2.6.0 - 2024-12-07
This is a security release to address potential denial of service attacks when parsing specially crafted, malicious input from untrusted sources (like user input). See https://github.com/thephpleague/commonmark/security/advisories/GHSA-c2pc-g5qf-rfrf for more details.
Added
- Added
max_delimiters_per_lineconfig option to prevent denial of service attacks when parsing malicious input - Added
table/max_autocompleted_cellsconfig option to prevent denial of service attacks when parsing large tables - The
AttributesExtensionnow supports attributes without values (#985, #986) - The
AutolinkExtensionexposes 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 specified
- Added
RegexHelper::isWhitespace()method to check if a given character is an ASCII whitespace character - Added
CacheableDelimiterProcessorInterfaceto ensure linear complexity for dynamic delimiter processing - Added
Bracketdelimiter type to optimize bracket parsing
Changed
[and]are no longer added asDelimiterobjects on the stack; a newBrackettype with its own stack is used insteadUrlAutolinkParserno longer parses URLs with more than 127 subdomains- Expanded reference links can no longer exceed 100kb, or the size of the input document (whichever is greater)
- Delimiters should always provide a non-null value via
DelimiterInterface::getIndex()- We’ll attempt to infer the index based on surrounding delimiters where possible
- The
DelimiterStacknow accepts integer positions for any$stackBottomargument - Several small performance optimizations
2.5.3 - 2024-08-16
Changed
- Made compatible with CommonMark spec 0.31.1, including:
- Remove
source, addsearchto list of recognized block tags
- Remove
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.5.2…2.5.3
2.5.2 - 2024-08-14
Changed
- Boolean attributes now require an explicit
truevalue (#1040)
Fixed
- Fixed regression where text could be misinterpreted as an attribute (#1040)
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.5.1…2.5.2
2.5.1 - 2024-07-24
Fixed
- Fixed attribute parsing incorrectly parsing mustache-like syntax (#1035)
- Fixed incorrect
Tablestart line numbers (#1037)
New Contributors
- @jasonvarga made their first contribution in https://github.com/thephpleague/commonmark/pull/1035
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.5.0…2.5.1
2.5.0 - 2024-07-22
Added
- The
AttributesExtensionnow supports attributes without values (#985, #986) - The
AutolinkExtensionexposes 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 specified
Changed
- Made compatible with CommonMark spec 0.31.0, including:
- Allow closing fence to be followed by tabs
- Remove restrictive limitation on inline comments
- Unicode symbols now treated like punctuation (for purposes of flankingness)
- Trailing tabs on the last line of indented code blocks will be excluded
- Improved HTML comment matching
Paragraphs only containing link reference definitions will be kept in the AST until theDocumentis finalized- (These were previously removed immediately after parsing the
Paragraph)
- (These were previously removed immediately after parsing the
Fixed
- Fixed list tightness not being determined properly in some edge cases
- Fixed incorrect ending line numbers for several block types in various scenarios
- Fixed lowercase inline HTML declarations not being accepted
New Contributors
- @svenluijten made their first contribution in https://github.com/thephpleague/commonmark/pull/986
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.4.4…2.5.0
2.4.4 - 2024-07-22
Fixed
- Fixed SmartPunct extension changing already-formatted quotation marks (#1030)
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.4.3…2.4.4
2.4.3 - 2024-07-22
Fixed
- Fixed the Attributes extension not supporting CSS level 3 selectors (#1013)
- Fixed
UrlAutolinkParserincorrectly parsing text containingwwwanywhere before an autolink (#1025)
New Contributors
- @nfreader made their first contribution in https://github.com/thephpleague/commonmark/pull/1016
- @macbookandrew made their first contribution in https://github.com/thephpleague/commonmark/pull/1025
- @xavierlacot made their first contribution in https://github.com/thephpleague/commonmark/pull/1013
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.4.2…2.4.3
2.4.2 - 2024-02-02
Fixed
- Fixed declaration parser being too strict
FencedCodeRenderer: don’t addlanguage-to class if already prefixed
New Contributors
- @sergiy-petrov made their first contribution in https://github.com/thephpleague/commonmark/pull/997
- @clustermin made their first contribution in https://github.com/thephpleague/commonmark/pull/988
- @peter279k made their first contribution in https://github.com/thephpleague/commonmark/pull/996
Full Changelog: https://github.com/thephpleague/commonmark/compare/2.4.1…2.4.2
2.4.1 - 2023-08-30
Fixed
- Fixed
ExternalLinkProcessornot fully disabling therelattribute when configured to do so (#992)
2.4.0 - 2023-03-24
See the upgrading guide for more information about the exception-related changes
Added
- Added generic
CommonMarkExceptionmarker interface for all exceptions thrown by the library - Added several new specific exception types implementing that marker interface:
AlreadyInitializedExceptionInvalidArgumentExceptionIOExceptionLogicExceptionMissingDependencyExceptionNoMatchingRendererExceptionParserLogicException
- Added more configuration options to the Heading Permalinks extension (#939):
heading_permalink/apply_id_to_heading- Whentrue, theidattribute 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 acceptsnoneto prevent the creation of the<a>link
- Added new
table/alignment_attributesconfiguration option to control how table cell alignment is rendered (#959)
Changed
- Change several thrown exceptions from
RuntimeExceptiontoLogicException(or something extending it), including:CallbackGenerators that fail to set a URL or return an expected valueMarkdownParserwhen deactivating the last block parser or attempting to get an active block parser when they’ve all been closed- Adding items to an already-initialized
Environment - Rendering a
Nodewhen no renderer has been registered for it
HeadingPermalinkProcessornow throwsInvalidConfigurationExceptioninstead ofRuntimeExceptionwhen invalid config values are given.HtmlElement::setAttribute()no longer requires the second parameter for boolean attributes- Several small micro-optimizations
- Changed Strikethrough to only allow 1 or 2 tildes per the updated GFM spec
Fixed
- Fixed inaccurate
@throwsdocblocks throughout the codebase, includingConverterInterface,MarkdownConverter, andMarkdownConverterInterface.- These previously suggested that only
\RuntimeExceptions were thrown, which was inaccurate as\LogicExceptions were also possible.
- These previously suggested that only
2.3.9 - 2023-02-15
Fixed
- Fixed autolink extension not detecting some URIs with underscores (#956)
2.3.8 - 2022-12-10
Fixed
- Fixed parsing issues when
mb_internal_encoding()is set to something other thanUTF-8(#951)
2.3.7 - 2022-11-17
Fixed
- Fixed
TaskListItemMarkerRenderernot including HTML attributes set on the node by other extensions (#947)
2.3.6 - 2022-10-30
Fixed
- Fixed unquoted attribute parsing when closing curly brace is followed by certain characters (like a
.) (#943)
2.3.5 - 2022-07-29
Fixed
- Fixed error using
InlineParserEnginewhen no inline parsers are registered in theEnvironment(#908)
2.3.4 - 2022-07-17
Changed
- Made a number of small tweaks to the embed extension’s parsing behavior to fix #898:
- Changed
EmbedStartParserto always capture embed-like lines in container blocks, regardless of parent block type - Changed
EmbedProcessorto also removeEmbedblocks that aren’t direct children of theDocument - Increased the priority of
EmbedProcessorto1010
- Changed
Fixed
- Fixed
EmbedExtensionnot parsing embeds following a list block (#898)
2.3.3 - 2022-06-07
Fixed
- Fixed
DomainFilteringAdapternot reindexing the embed list (#884, #885)
2.3.2 - 2022-06-03
Fixed
- Fixed FootnoteExtension stripping extra characters from tab-indented footnotes (#881)
2.2.5 - 2022-06-03
Fixed
- Fixed FootnoteExtension stripping extra characters from tab-indented footnotes (#881)
2.3.1 - 2022-05-14
Fixed
- Fixed AutolinkExtension not ignoring trailing strikethrough syntax (#867)
2.2.4 - 2022-05-14
Fixed
- Fixed AutolinkExtension not ignoring trailing strikethrough syntax (#867)
2.3.0 - 2022-04-07
Added
- Added new
EmbedExtension(#805) - Added
DocumentRendererInterfaceas a replacement for the now-deprecatedMarkdownRendererInterface
Deprecated
- Deprecated
MarkdownRendererInterface; useDocumentRendererInterfaceinstead
2.2.3 - 2022-02-26
Fixed
- Fixed front matter parsing with Windows line endings (#821)
2.1.3 - 2022-02-26
Fixed
- Fixed front matter parsing with Windows line endings (#821)
2.0.4 - 2022-02-26
Fixed
- Fixed front matter parsing with Windows line endings (#821)
2.2.2 - 2022-02-13
Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
2.1.2 - 2022-02-13
Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
2.0.3 - 2022-02-13
Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
2.2.1 - 2022-01-25
Fixed
- Fixed
symfony/deprecation-contractsconstraint
Removed
- Removed deprecation trigger from
MarkdownConverterInterfaceto reduce noise
2.2.0 - 2022-01-22
Added
- Added new
ConverterInterface - Added new
MarkdownToXmlConverterclass - Added new
HtmlDecoratorclass which can wrap existing renderers with additional HTML tags - Added new
table/wrapconfig to apply an optional wrapping/container element around a table (#780)
Changed
HtmlElementcontents can now consist of anyStringable, not justHtmlElementandstring
Deprecated
- Deprecated
MarkdownConverterInterfaceand itsconvertToHtml()method; useConverterInterfaceandconvert()instead
1.6.7 - 2022-01-13
Changed
- Added
ReturnTypeWillChangeattribute to prevent PHP 8.1 deprecation warnings (#785) - Coerced punctuation counts to integers to ensure floats are never used
2.1.1 - 2022-01-02
Added
- Added missing return type to
Environment::dispatch()to fix deprecation warning (#778)
2.1.0 - 2021-12-05
Added
- Added support for ext-yaml in FrontMatterExtension (#715)
- Added support for symfony/yaml v6.0 in FrontMatterExtension (#739)
- Added new
heading_permalink/aria_hiddenconfig option (#741)
Fixed
- Fixed PHP 8.1 deprecation warning (#759, #762)
2.0.2 - 2021-08-14
Changed
- Bumped minimum version of league/config to support PHP 8.1
Fixed
- Fixed ability to register block parsers that identify lines starting with letters (#706)
2.0.1 - 2021-07-31
Fixed
- Fixed nested autolinks (#689)
- Fixed description lists being parsed incorrectly (#692)
- Fixed Table of Contents not respecting Heading Permalink prefixes (#690)
2.0.0 - 2021-07-24
No changes were introduced since the previous 2.0.0-rc2 release.
Please refer to the full Changelog for a list of all changes between 1.x and 2.0. An upgrading guide is also available.
2.0.0-rc2 - 2021-07-17
Fixed
- Fixed Mentions inside of links creating nested links against the spec’s rules (#688)
1.6.6 - 2021-07-17
Fixed
- Fixed Mentions inside of links creating nested links against the spec’s rules (#688)
2.0.0-rc1 - 2021-07-10
No changes were introduced since the previous release.
2.0.0-beta3 - 2021-07-03
Changed
- Any leading UTF-8 BOM will be stripped from the input
- The
getEnvironment()method ofCommonMarkConverterandGithubFlavoredMarkdownConverterwill always return the concrete, configurableEnvironmentfor upgrading convenience - Optimized AST iteration
- Lots of small micro-optimizations
2.0.0-beta2 - 2021-06-27
See https://commonmark.thephpleague.com/2.0/upgrading/ for detailed information on upgrading to version 2.0.
Added
- Added new
Node::iterator()method andNodeIteratorclass for faster AST iteration (#683, #684)
Changed
- Made compatible with CommonMark spec 0.30.0
- Optimized link label parsing
- Optimized AST iteration for a 50% performance boost in some event listeners (#683, #684)
Fixed
- Fixed processing instructions with EOLs
- Fixed case-insensitive matching for HTML tag types
- Fixed type 7 HTML blocks incorrectly interrupting lazy paragraphs
- Fixed newlines in reference labels not collapsing into spaces
- Fixed link label normalization with escaped newlines
- Fixed unnecessary AST iteration when no default attributes are configured
1.6.5 - 2021-06-26
Changed
- Simplified checks for thematic breaks
Fixed
- Fixed ExternalLinkProcessor not handling autolinks by adjusting its priority to -50 (#681)
2.0.0-beta1 - 2021-06-20
See https://commonmark.thephpleague.com/2.0/upgrading/ for detailed information on upgrading to version 2.0.
Added
- Added three new extensions:
FrontMatterExtension(see documentation)DescriptionListExtension(see documentation)DefaultAttributesExtension(see documentation)
- Added new
XmlRendererto simplify AST debugging (see documentation) (#431) - 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 the ability to delegate event dispatching to PSR-14 compliant event dispatcher libraries
- Added new configuration options:
- Added
heading_permalink/min_heading_levelandheading_permalink/max_heading_leveloptions to control which headings get permalinks (#519) - Added
heading_permalink/fragment_prefixto allow customizing the URL fragment prefix (#602) - Added
footnote/backref_symboloption for customizing backreference link appearance (#522) - Added
slug_normalizer/max_lengthoption to control the maximum length of generated URL slugs - Added
slug_normalizer/uniqueoption to control whether unique slugs should be generated per-document or per-environment
- Added
- Added purity markers throughout the codebase (verified with Psalm)
- Added
Queryclass to simplify Node traversal when looking to take action on certain Nodes - Added new
HtmlFilterandStringContainerHelperutility classes - Added new
AbstractBlockContinueParserclass to simplify the creation of custom block parsers - Added several new classes and interfaces:
BlockContinueBlockContinueParserInterfaceBlockContinueParserWithInlinesInterfaceBlockStartBlockStartParserInterfaceChildNodeRendererInterfaceConfigurableExtensionInterfaceCursorStateDashParser(extracted fromPunctuationParser)DelimiterParserDocumentBlockParserDocumentPreRenderEventDocumentRenderedEventEllipsesParser(extracted fromPunctuationParser)ExpressionInterfaceFallbackNodeXmlRendererInlineParserEngineInterfaceInlineParserMatchMarkdownParserStateMarkdownParserStateInterfaceMarkdownRendererInterfaceQueryRawMarkupContainerInterfaceReferenceableInterfaceRenderedContentRenderedContentInterfaceReplaceUnpairedQuotesListenerSpecReaderTableOfContentsRendererUniqueSlugNormalizerUniqueSlugNormalizerInterfaceXmlRendererXmlNodeRendererInterface
- Added several new methods:
Cursor::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()
Changed
- Changed the converter return type
CommonMarkConverter::convertToHtml()now returns an instance ofRenderedContentInterface. This can be cast to a string for backward compatibility with 1.x.
- Table of Contents items are no longer wrapped with
<p>tags (#613) - Heading Permalinks now link to element IDs instead of using
nameattributes (#602) - Heading Permalink IDs and URL fragments now have a
contentprefix by default (#602) - Changes to configuration options:
enable_emhas been renamed tocommonmark/enable_emenable_stronghas been renamed tocommonmark/enable_stronguse_asteriskhas been renamed tocommonmark/use_asteriskuse_underscorehas been renamed tocommonmark/use_underscoreunordered_list_markershas been renamed tocommonmark/unordered_list_markersmentions/*/symbolhas been renamed tomentions/*/prefixmentions/*/regexhas been renamed tomentions/*/patternand requires partial regular expressions (without delimiters or flags)max_nesting_levelnow defaults toPHP_INT_MAXand no longer supports floatsheading_permalink/slug_normalizerhas been renamed toslug_normalizer/instance
- Event dispatching is now fully PSR-14 compliant
- Moved and renamed several classes - see the full list here
- The
HeadingPermalinkExtensionandFootnoteExtensionwere modified to ensure they never produce a slug which conflicts with slugs created by the other extension SlugNormalizer::normalizer()now supports optional prefixes and max length options passed in via the$contextargument- The
AbstractBlock::$dataandAbstractInline::$dataarrays were replaced with aDataarray-like object on the baseNodeclass - 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()ReferenceParserwas 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 ofInlineParserMatchInlineParserContext::__construct()now requires the contents to be provided as aCursorinstead of astring
- Implemented delimiter parsing as a special type of inline parser (via the new
DelimiterParserclass) - Changed block and inline rendering to use common methods and interfaces
BlockRendererInterfaceandInlineRendererInterfacewere replaced byNodeRendererInterfacewith 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
- All configuration-specific classes have been moved into a new
league/configpackage with a new namespace Configurationobjects 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()insteadConfigurationInterfacenow only contains aget(string $key); this method no longer allows arbitrary default values to be returned if the option is missingConfigurableEnvironmentInterfacewas renamed toEnvironmentBuilderInterfaceExtensionInterface::register()now requires anEnvironmentBuilderInterfaceparam instead ofConfigurableEnvironmentInterface
- All configuration-specific classes have been moved into a new
- Added missing return types to virtually every class and interface method
- Re-implemented the GFM Autolink extension using the new inline parser approach instead of document processors
EmailAutolinkProcessoris nowEmailAutolinkParserUrlAutolinkProcessoris nowUrlAutolinkParser
HtmlElementcan now properly handle array (i.e.class) and boolean (i.e.checked) attribute valuesHtmlElementautomatically flattens any attributes with array values into space-separated strings, removing duplicate entries- Combined separate classes/interfaces into one:
DisallowedRawHtmlRendererreplacesDisallowedRawHtmlBlockRendererandDisallowedRawHtmlInlineRendererNodeRendererInterfacereplacesBlockRendererInterfaceandInlineRendererInterface
- Renamed the following methods:
EnvironmentandConfigurableEnvironmentInterface:addBlockParser()is nowaddBlockStartParser()
ReferenceMapandReferenceMapInterface: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_ALLOWis nowHtmlFilter::ALLOWEnvironmentInterface::HTML_INPUT_ESCAPEis nowHtmlFilter::ESCAPEEnvironmentInterface::HTML_INPUT_STRIPis nowHtmlFilter::STRIPTableCell::TYPE_HEADis nowTableCell::TYPE_HEADERTableCell::TYPE_BODYis nowTableCell::TYPE_DATA
- Changed the visibility of the following properties:
AttributesInline::$attributesis nowprivateAttributesInline::$blockis nowprivateTableCell::$alignis nowprivateTableCell::$typeis nowprivateTableSection::$typeis nowprivate
- Several methods which previously returned
$thisnow returnvoidDelimiter::setPrevious()Node::replaceChildren()Context::setTip()Context::setContainer()Context::setBlocksParsed()AbstractStringContainer::setContent()AbstractWebResource::setUrl()
- Several classes are now marked
final:ArrayCollectionEmphasisFencedCodeHeadingHtmlBlockHtmlElementHtmlInlineIndentedCodeNewlineStrikethroughStrongText
Headingnodes no longer directly contain a copy of their inner textStringContainerInterfacecan now be used for inlines, not just blocksArrayCollectiononly supports integer keysHtmlElementnow implementsStringableCursor::saveState()andCursor::restoreState()now useCursorStateobjects 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”.InvalidOptionExceptionwas removed- Anything with a
getReference(): ReferenceInterfacemethod now implementsReferencableInterface - The
SmartPunctextension now replaces all unpairedQuoteelements withTextelements towards the end of parsing, making theQuoteRendererunnecessary - 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 DelimiterProcessorCollectionInterfacenow extendsCountableRegexHelper::PARTIAL_constants must always be used in case-insensitive contextsHeadingPermalinkProcessorno longer accepts text normalizers via the constructor - these must be provided via configuration instead- Blocks which can’t contain inlines will no longer be asked to render inlines
AnonymousFootnoteRefParserandHeadingPermalinkProcessornow implementEnvironmentAwareInterfaceinstead ofConfigurationAwareInterface- The second argument to
TextNormalizerInterface::normalize()must now be an array - The
titleattribute forLinkandImagenodes is now stored using a dedicated property instead of stashing it in$data ListData::$delimiternow returns eitherListBlock::DELIM_PERIODorListBlock::DELIM_PARENinstead of the literal delimiter
Fixed
- Fixed parsing of footnotes without content
- Fixed rendering of orphaned footnotes and footnote refs
- Fixed some URL autolinks breaking too early (#492)
- Fixed
AbstractStringContainernot actually beingabstract
Removed
- Removed support for PHP 7.1, 7.2, and 7.3 (#625, #671)
- Removed all previously-deprecated functionality:
- Removed the ability to pass custom
Environmentinstances into theCommonMarkConverterandGithubFlavoredMarkdownConverterconstructors - Removed the
Converterclass andConverterInterface - Removed the
bin/commonmarkscript - Removed the
Html5Entitiesutility class - Removed the
InlineMentionParser(useMentionParserinstead) - Removed
DefaultSlugGeneratorandSlugGeneratorInterfacefrom theExtension/HeadingPermalink/Slugsub-namespace (use the new ones under./SlugGeneratorinstead) - Removed the following
ArrayCollectionmethods:add()set()get()remove()isEmpty()contains()indexOf()containsKey()replaceWith()removeGaps()
- Removed the
ConfigurableEnvironmentInterface::setConfig()method - Removed the
ListBlock::TYPE_UNORDEREDconstant - Removed the
CommonMarkConverter::VERSIONconstant - Removed the
HeadingPermalinkRenderer::DEFAULT_INNER_CONTENTSconstant - Removed the
heading_permalink/inner_contentsconfiguration option
- Removed the ability to pass custom
- Removed now-unused classes:
AbstractStringContainerBlockBlockRendererInterfaceContextContextInterfaceConverterConverterInterfaceInlineRendererInterfacePunctuationParser(was split into two classes:DashParserandEllipsesParser)QuoteRendererUnmatchedBlockCloser
- Removed the following methods, properties, and constants:
AbstractBlock::$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 newmatchFirst()method instead)RegexHelper::REGEX_WHITESPACE
- Removed the second
$contentsargument from theHeadingconstructor
Deprecated
The following things have been deprecated and will not be supported in v3.0:
Environment::mergeConfig()(set configuration before instantiation instead)Environment::createCommonMarkEnvironment()andEnvironment::createGFMEnvironment()- Alternative 1: Use
CommonMarkConverterorGithubFlavoredMarkdownConverterif you don’t need to customize the environment - Alternative 2: Instantiate a new
Environmentand add the necessary extensions yourself
- Alternative 1: Use
1.6.4 - 2021-06-19
Changed
- Optimized attribute parsing to avoid inspecting every space character (30% performance boost)
1.6.3 - 2021-06-19
Fixed
- Fixed incorrect parsing of tilde-fenced code blocks with leading spaces (#676)
1.6.2 - 2021-05-12
Fixed
- Fixed incorrect error level for deprecation notices
1.6.1 - 2021-05-08
Fixed
- Fixed
HeadingPermalinkProcessorskipping text contents from certain nodes (#615)
1.6.0 - 2021-05-01
Please see https://commonmark.thephpleague.com/1.6/upgrading/ for important information about this release and the upcoming 2.0.0 version.
Added
- Added forward-compatibility for configuration options which will be changing in 2.0:
commonmark/enable_em(currentlyenable_emin 1.x)commonmark/enable_strong(currentlyenable_strongin 1.x)commonmark/use_asterisk(currentlyuse_asteriskin 1.x)commonmark/use_underscore(currentlyuse_underscorein 1.x)commonmark/unordered_list_markers(currentlyunordered_list_markersin 1.x)mentions/*/prefix(currentlymentions/*/symbolin 1.x)mentions/*/pattern(currentlymentions/*/regexin 1.x)max_nesting_level(currently supportsintandfloatvalues in 1.x; will only supportintin 2.0)
- Added new
MarkdownConverterclass for creating converters with custom environments; this replaces the previously-deprecatedConverterclass - Added new
RegexHelper::matchFirst()method - Added new
Configuration::exists()method
Changed
- The
max_nesting_leveloption now defaults toPHP_INT_MAXinstead ofINF
Deprecated
- Deprecated the configuration options shown above
- Deprecated the ability to pass a custom
Environmentinto the constructors ofCommonMarkConverterandGithubFlavoredMarkdownConverter; useMarkdownConverterinstead - Deprecated
ConfigurableEnvironmentInterface::setConfig(); usemergeConfig()instead - Deprecated calling
ConfigurableEnvironmentInterface::mergeConfig()without any parameters - Deprecated calling
Configuration::get()andEnvironmentInterface::getConfig()without any parameters - Deprecated calling
Configuration::set()without the second$valueparameter - Deprecated
RegexHelper::matchAll(); useRegexHelper::matchFirst()instead - Deprecated extending the
ArrayCollectionclass; will be markedfinalin 2.0
Fixed
- Fixed missing check for empty arrays being passed into the
unordered_list_markersconfiguration option
1.5.8 - 2021-03-28
Fixed
- Fixed Table of Contents not rendering heading inlines properly (#587, #588)
- Fixed parsing of tables within list items (#590)
1.5.7 - 2020-10-31
Fixed
- Fixed mentions not being parsed when appearing after non-word characters (#582)
1.5.6 - 2020-10-17
Changed
- Blocks added outside of the parsing context now have their start/end line numbers defaulted to 0 to avoid type errors (#579)
Fixed
- Fixed replacement blocks not inheriting the start line number of the container they’re replacing (#579)
- Fixed Table of Contents blocks not having correct start/end line numbers (#579)
1.5.5 - 2020-09-13
Changed
- Bumped CommonMark spec compliance to 0.28.2
Fixed
- Fixed
textareaelements not being treated as a type 1 HTML block (likescript,style, orpre) - Fixed autolink processor not handling other unmatched trailing parentheses
1.5.4 - 2020-08-18
Fixed
- Fixed footnote ID configuration not taking effect (#524, #530)
- Fixed heading permalink slugs not being unique (#531, #534)
1.5.3 - 2020-07-19
Fixed
- Fixed regression of multi-byte inline parser characters not being matched
1.5.2 - 2020-07-19
Changed
- Significantly improved performance of the inline parser regex
Fixed
- Fixed parent class lookups for non-existent classes on PHP 8 (#517)
1.5.1 - 2020-06-27
Fixed
- Fixed UTF-8 encoding not being checked in the
UrlEncoderutility (#509) or theCursor
1.5.0 - 2020-06-21
Added
- Added new
AttributesExtensionbased on https://github.com/webuni/commonmark-attributes-extension (#474) - Added new
FootnoteExtensionbased on https://github.com/rezozero/commonmark-ext-footnotes (#474) - Added new
MentionExtensionto replaceInlineMentionParserwith more flexibility and customization - Added the ability to render
TableOfContentsnodes anywhere in a document (given by a placeholder) - Added the ability to properly clone
Nodeobjects - Added options to customize the value of
relattributes set via theExternalLinkextension (#476) - Added a new
heading_permalink/slug_normalizerconfiguration option to allow custom slug generation (#460) - Added a new
heading_permalink/symbolconfiguration option to replace the now deprecatedheading_permalink/inner_contentsconfiguration option (#505) - Added
SlugNormalizerandTextNormalizerclasses to make normalization reusable by extensions (#485) - Added new classes:
TableOfContentsGeneratorTableOfContentsGeneratorInterfaceTableOfContentsPlaceholderTableOfContentsPlaceholderParserTableOfContentsPlaceholderRenderer
Changed
- “Moved” the
TableOfContentsclass into a newNodesub-namespace (with backward-compatibility) - Reference labels are now generated and stored in lower-case instead of upper-case
- Reference labels are no longer normalized inside the
Reference, only theReferenceMap
Fixed
- Fixed reference label case folding polyfill not being consistent between different PHP versions
Deprecated
- Deprecated the
CommonMarkConverter::VERSIONconstant (#496) - Deprecated
League\CommonMark\Extension\Autolink\InlineMentionParser(useLeague\CommonMark\Extension\Mention\MentionParserinstead) - Deprecated everything under
League\CommonMark\Extension\HeadingPermalink\Slug(use the classes underLeague\CommonMark\Normalizerinstead) - Deprecated
League\CommonMark\Extension\TableOfContents\TableOfContents(use the one in the newNodesub-namespace instead) - Deprecated the
STYLE_andNORMALIZE_constants inTableOfContentsBuilder(use the ones inTableOfContentsGeneratorinstead) - Deprecated the
\League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkRenderer::DEFAULT_INNER_CONTENTSconstant (#505) - Deprecated the
heading_permalink/inner_contentsconfiguration option in theHeadingPermalinkextension (use the newheading_permalink/symbolconfiguration option instead) (#505)
1.4.3 - 2020-05-04
Fixed
- Fixed certain Unicode letters, numbers, and marks not being preserved when generating URL slugs (#467)
1.4.2 - 2020-04-24
Fixed
- Fixed inline code blocks not be included within heading permalinks (#457)
1.4.1 - 2020-04-20
Fixed
- Fixed BC break caused by ConverterInterface alias not being used by some DI containers (#454)
1.4.0 - 2020-04-18
Added
- Added new Heading Permalink extension (#420)
- Added new Table of Contents extension (#441)
- Added new
MarkdownConverterInterfaceas a long-term replacement forConverterInterface(#439) - Added new
DocumentPreParsedEventevent (#427, #359, #399) - Added new
ListBlock::TYPE_BULLETconstant as a replacement forListBlock::TYPE_UNORDERED - Added new
MarkdownInputclass andMarkdownInputInterfaceto handle pre-parsing and allow listeners to replace Markdown contents
Changed
- Block & inline renderers will now render child classes automatically (#222, #209)
- The
ListBlockconstants now use fully-lowercased values instead of titlecased values - Significantly improved typing
Fixed
- Fixed loose comparison when checking for table alignment
- Fixed
StaggeredDelimiterProcessorreturning from avoidfunction
Deprecated
- The
Converterclass has been deprecated; useCommonMarkConverterinstead (#438, #439) - The
ConverterInterfacehas been deprecated; useMarkdownConverterInterfaceinstead (#438, #439) - The
bin/commonmarkscript has been deprecated - The following methods of
ArrayCollectionhave been deprecated:add()set()get()remove()isEmpty()contains()indexOf()containsKey()replaceWith()removeGaps()
- The
ListBlock::TYPE_UNORDEREDconstant has been deprecated, useListBlock::TYPE_BULLETinstead
1.3.4 - 2020-04-13
Fixed
- Fixed configuration/environment not being injected into event listeners when adding them via
[$instance, 'method']callable syntax (#440)
1.3.3 - 2020-04-05
Fixed
- Fixed event listeners not having the environment or configuration injected if they implemented the
EnvironmentAwareInterfaceorConfigurationAwareInterface(#423)
1.3.2 - 2020-03-25
Fixed
- Optimized URL normalization in cases where URLs don’t contain special characters (#417, #418)
1.3.1 - 2020-02-28
Fixed
- Fixed return types of
Environment::createCommonMarkEnvironment()andEnvironment::createGFMEnvironment()
1.3.0 - 2020-02-09
ℹ️ Do you use league/commonmark-ext* packages? Those features are now included directly in this library! See #409 for details on making the switch.
Added
- Added (optional) full GFM support! 🎉🎉🎉 (#409)
- Added check to ensure Markdown input is valid UTF-8 (#401, #405)
- Added new
unordered_list_markersconfiguration option (#408, #411)
Changed
- Introduced several micro-optimizations for a 5-10% performance boost
1.2.2 - 2020-01-16
This release contains the same changes as 1.1.3:
Fixed
- Fixed link parsing edge case (#403)
1.1.3 - 2020-01-16
Fixed
- Fixed link parsing edge case (#403)
1.2.1 - 2020-01-15
Changed
- Introduced several micro-optimizations, reducing the parse time by 8%
1.2.0 - 2020-01-09
Changed
- Removed URL decoding step before encoding (more performant and better matches the JS library)
- Removed redundant token from HTML tag regex
1.1.2 - 2019-12-10
Fixed
- Fixed URL normalization not handling non-UTF-8 sequences properly (#395, #396)
1.1.1 - 2019-11-11
Fixed
- Fixed handling of link destinations with unbalanced unescaped parens
- Fixed adding delimiters to stack which can neither open nor close a run
1.1.0 - 2019-10-31
Added
- Added a new
Html5EntityDecoderclass (#387)
Changed
- Improved performance by 10% (#389)
- Made entity decoding less memory-intensive (#386, #387)
Fixed
- Fixed PHP 7.4 compatibility issues
Deprecated
- Deprecated the
Html5Entitiesclass - useHtml5EntityDecoderinstead (#387)
1.0.0 - 2019-06-29
First stable release! 🎉
No code changes have been introduced since 1.0.0-rc1
1.0.0-rc1 - 2019-06-20
Added
- Extracted a
ReferenceMapInterfacefrom theReferenceMapclass - Added optional
ReferenceMapInterfaceparameter to theDocumentconstructor
Changed
- Replaced all references to
ReferenceMapwithReferenceMapInterface ReferenceMap::addReference()no longer returns$this
Fixed
- Fixed bug where elements with content of
"0"wouldn’t be rendered (#376)
0.19.3 - 2019-06-18
Fixed
- Fixed bug where elements with content of
"0"wouldn’t be rendered (#376)
1.0.0-beta4 - 2019-06-05
Added
- Added event dispatcher functionality (#359, #372)
Removed
- Removed
DocumentProcessorInterfacefunctionality in favor of event dispatching (#373)
1.0.0-beta3 - 2019-05-28
Changed
- Made the
Delimiterclass final and extracted a newDelimiterInterface- Modified most external usages to use this new interface
- Renamed three
Delimitermethods:getOrigDelims()renamed togetOriginalLength()getNumDelims()renamed togetLength()setNumDelims()renamed tosetLength()
- Made additional classes final:
DelimiterStackReferenceMapReferenceParser
- Moved
ReferenceParserinto theReferencesub-namespace
Removed
- Removed unused
Delimitermethods:setCanOpen()setCanClose()setChar()setIndex()setInlineNode()
- Removed fluent interface from
Delimiter(setter methods now have no return values)
1.0.0-beta2 - 2019-05-27
This beta release fixes a couple of items that were not addressed in the previous beta.
Changed
DelimiterProcessorInterface::process()will accept any type ofAbstractStringContainernow, not justTextnodes- The
Delimiterconstructor,getInlineNode(), andsetInlineNode()no longer accept genericNodeelements - onlyAbstractStringContainers
Removed
- Removed all deprecated functionality:
- The
safeoption (usehtml_inputandallow_unsafe_linksoptions instead) - All deprecated
RegexHelperconstants DocParser::getEnvironment()(you should obtain it some other way)AbstractInlineContainer(useAbstractInlineinstead and makeisContainer()returntrue)
- The
1.0.0-beta1 - 2019-05-26
See the upgrading guide for additional information.
Added
- Added proper support for delimiters, including custom delimiters
addDelimiterProcessor()added toConfigurableEnvironmentInterfaceandEnvironment
- Basic delimiters no longer need custom parsers - they’ll be parsed automatically
- Added new methods:
AdjacentTextMerger::mergeTextNodesBetweenExclusive()CommonMarkConveter::getEnvironment()Configuration::set()
- Extracted some new interfaces from base classes:
DocParserInterfacecreated fromDocParserConfigurationInterfacecreated fromConfigurationReferenceInterfacecreated fromReference
Changed
- Renamed several methods of the
Configurationclass:getConfig()renamed toget()mergeConfig()renamed tomerge()setConfig()renamed toreplace()
- Changed
ConfigurationAwareInterface::setConfiguration()to accept the newConfigurationInterfaceinstead of the concrete class - Renamed the
AdjoiningTextCollapserclass toAdjacentTextMerger- Replaced its
collapseTextNodes()method with the newmergeChildNodes()method
- Replaced its
- Made several classes
final:ConfigurationDocParserHtmlRendererInlineParserEngineNodeWalkerReference- All of the block/inline parsers and renderers
- Reduced visibility of several internal methods to
private:DelimiterStack::findEarliest()- All
protectedmethods inInlineParserEngine
- Marked some classes and methods as
@internal ElementRendererInterfacenow requires a publicrenderInline()method; added this toHtmlRenderer- Changed
InlineParserEngine::parse()to require anAbstractStringContainerBlockinstead of the genericNodeclass - Un-deprecated the
CommonmarkConverter::VERSIONconstant - The
Converterconstructor now requires an instance ofDocParserInterfaceinstead of the concreteDocParser - Changed
Emphasis,Strong, andAbstractWebResourceto directly extendAbstractInlineinstead of the (now-deprecated) intermediaryAbstractInlineContainerclass
Fixed
- Fixed null errors when inserting sibling
Nodes without parents - Fixed
NodeWalkerEventnot requiring aNodevia its constructor - Fixed
Reference::normalizeReference()improperly converting to uppercase instead of performing proper Unicode case-folding - Fixed strong emphasis delimiters not being preserved when
enable_strongis set tofalse(it now works identically toenable_em)
Deprecated
- Deprecated
DocParser::getEnvironment()(you should obtain it some other way) - Deprecated
AbstractInlineContainer(useAbstractInlineinstead and makeisContainer()returntrue)
Removed
- Removed inline processor functionality now that we have proper delimiter support:
- Removed
addInlineProcessor()fromConfigurableEnvironmentInterfaceandEnvironment - Removed
getInlineProcessors()fromEnvironmentInterfaceandEnvironment - Removed
EmphasisProcessor - Removed
InlineProcessorInterface
- Removed
- Removed
EmphasisParsernow that we have proper delimiter support - Removed support for non-UTF-8-compatible encodings
- Removed
getEncoding()fromContextInterface - Removed
getEncoding(),setEncoding(), and$encodingfromContext - Removed
getEncoding()and the second$encodingconstructor param fromCursor
- Removed
- Removed now-unused methods
- Removed
DelimiterStack::getTop()(no replacement) - Removed
DelimiterStack::iterateByCharacters()(use the newprocessDelimiters()method instead) - Removed the protected
DelimiterStack::findMatchingOpener()method
- Removed
0.19.2 - 2019-05-19
Fixed
- Fixed bug where default values for nested configuration paths were inadvertently cast to strings
0.19.1 - 2019-04-11
0.19.1 is an immediate follow-up to 0.19.0 which fixes issues with extensions that register other extensions.
(While this technically introduces a BC-break, it’s allowed under SemVer’s rules for 0.x releases and is necessary for 0.19.x code to work as expected.)
Added
- Added the missing
addExtension()method to the newConfigurableEnvironmentInterface
Fixed
- Fixed extensions not being able to register other extensions
0.19.0 - 2019-04-11
The 50th release of league/commonmark is here! :tada:
The Environment and extension framework underwent some major changes in this release. Be sure to read the upgrade notes if you maintain any community extensions or have written custom functionality on top of this library.
Added
- The priority of parsers, processors, and renderers can now be set when
add()ing them; you no longer need to rely on the order in which they are added - Added support for trying multiple parsers per block/inline
- Extracted two new base interfaces from
Environment:EnvironmentInterfaceConfigurableEnvironmentInterface
- Extracted a new
AbstractStringContainerBlockbase class and correspondingStringContainerInterfacefromAbstractBlock - Added
Cursor::getEncoding()method - Added
.phpstorm.meta.phpfile for better IDE code completion - Made some minor optimizations here and there
Changed
- Pretty much everything now has parameter and return types (#346)
- Attributes passed to
HtmlElementwill now be escaped by default Environmentis now afinalclassEnvironment::getBlockRendererForClass()was replaced withEnvironment::getBlockRenderersForClass()(note the addeds)Environment::getInlineRendererForClass()was replaced withEnvironment::getInlineRenderersForClass()(note the addeds)- The
Environment::get____()methods now return an iterator instead of an array Context::addBlock()no longer returns the same block instance you passed into the method, as this served no useful purposeRegexHelper::isEscapable()no longer acceptsnullvaluesNode::replaceChildren()now accepts any type ofiterable, not justarrays- Some block elements now extend
AbstractStringContainerBlockinstead ofAbstractBlockInlineContainerInterfacenow extends the newStringContainerInterface- The
handleRemainingContents()method (formerly onAbstractBlock, now onAbstractStringContainerBlock) is now an `abstract method - The
InlineParserContextconstructor now requires anAbstractStringContainerBlockinstead of anAbstractBlock
Removed
- Removed support for PHP 5.6 and 7.0 (#346)
- Removed support for
add()ing parsers with just the target block/inline class name - you need to include the full namespace now - Removed the following unused methods from
Environment:getInlineParser($name)getInlineParsers()createInlineParserEngine()
- Removed the unused
getName()methods:AbstractBlockParser::getName()AbstractInlineParser::getName()BlockParserInterface::getName()InlinerParserInterface::getName()
- Removed the now-useless classes:
AbstractBlockParserAbstractInlinerParserInlineContainer
- Removed the
AbstractBlock::acceptsLines()method - Removed the now-useless constructor from
AbstractBlock - Removed previously-deprecated functionality:
InlineContainerclassRegexHelper::$instanceRegexHelper::getInstance()RegexHelper::getPartialRegex()RegexHelper::getHtmlTagRegex()RegexHelper::getLinkTitleRegex()RegexHelper::getLinkDestinationBracesRegex()RegexHelper::getThematicBreakRegex()
- Removed the second
$preserveEntitiesparameter fromXml:escape()
0.18.5 - 2019-04-09
Fixed
- Fixed the adjoining
Textcollapser not handling the full tree (thephpleague/commonmark-ext-autolink#10)
0.18.4 - 2019-03-24
Changed
- Modified how URL normalization decodes certain characters in order to align with the JS library’s output
- Disallowed unescaped
(in parenthesized link title
Fixed
- Fixed two exponential backtracking issues
0.18.3 - 2019-03-21
This is a security update release.
Changed
- XML/HTML entities in attributes will no longer be preserved when rendering (#353)
Fixed
- Fix XSS vulnerability caused by improper preservation of entities when rendering (#353)
Deprecated
- Deprecated the
$preserveEntitesargument ofXml::escape()for removal in the next release (#353)
0.18.2 - 2019-03-17
Fixed
- Fixed adjoining
Textelements not being collapsed after delimiter processing
Deprecated
- Deprecated the
CommonmarkConverter::VERSIONconstant for removal in 1.0.0
0.18.1 - 2018-12-30
This release contains an important security update for CVE-2018-20583.
Fixed
- Fix XSS vulnerability caused by URL normalization not handling/encoding newlines properly (#337, CVE-2018-20583)
0.18.0 - 2018-09-18
No breaking changes were introduced, but we did add a new interface: ConverterInterface. Consider depending on this interface in your code instead of the concrete implementation. (See #330)
Added
- Added
ConverterInterfacetoConverterandCommonMarkConverter(#330) - Added
ListItem::getListData()method (#329)
Changed
- Links with
target="_blank"will also getrel="noopener noreferrer"by default (#331) - Implemented several performance optimizations (#324)
0.17.5 - 2018-03-29
Fixed
- Fixed incorrect version constant value (again)
- Fixed release checklist to prevent the above from happening
- Fixed incorrect dates in CHANGELOG
0.17.4 - 2018-03-29
Added
- Added
ListBlock::setTight()method
0.17.3 - 2018-03-26
Fixed
- Fixed incorrect version constant value (#322)
0.17.2 - 2018-03-26
Added
- Added new
RegexHelper::isEscapable()method
Fixed
- Fixed spec compliance bug where escaped spaces should not be allowed in link destinations
0.17.1 - 2018-03-18
Added
- Added a new constant containing the current version:
CommonMarkConverter::VERSION(#314)
0.17.0 - 2017-12-30
This release contains several breaking changes and a minimum PHP version bump - see UPGRADE.md for more details.
Added
- Added new
max_nesting_levelsetting (#243) - Added minor performance optimizations to
Cursor
Changed
- Minimum PHP version is now 5.6.5.
- All full and partial regular expressions in
RegexHelperare now defined as constants instead of being built on-the-fly. Cursor::saveState()now returns anarrayinstead of aCursorStateobject.Cursor::restoreState()now accepts anarrayparameter instead of aCursorStateobject.- Saving/restoring the Cursor state no longer tracks things that don’t change (like the text content).
RegexHelperis nowfinal.- References to
InlineContainerchanged to newInlineContainerInterfaceinterface. MiscExtension::addInlineParser()andMiscExtension::addBlockRenderer()now return$thisinstead of nothing.
Fixed
- Fixed
Reference::normalizeReference()not properly collapsing whitespace to a single space
Deprecated
RegexHelper::getInstance()and all instance (non-static) methods have been deprecated.- The
InlineContainerinterface has been deprecated. UseInlineContainerInterfaceinstead.
Removed
- Removed support for PHP 5.4 and 5.5.
- Removed
CursorStateclass - Removed all previous deprecations:
Cursor::getFirstNonSpacePosition()Cursor::getFirstNonSpaceCharacter()Cursor::advanceWhileMatches()Cursor::advanceToFirstNonSpace()ElementRendererInterface::escape()HtmlRenderer::escape()RegexHelper::REGEX_UNICODE_WHITESPACERegexHelper::getLinkDestinationRegex()
0.16.0 - 2017-10-31
This release contains breaking changes, several performance improvements, and two deprecations:
Added
- Added new
Xmlutility class; moved HTML/XML escaping logic into there (see deprecations below)
Changed
Environment::getInlineParsersForCharacter()now returns an empty array (instead ofnull) when no matching parsers are found- Three utility classes are now marked
final:Html5EntitiesLinkParserHelperUrlEncoder
Fixed
- Improved performance of several methods (for a 10% overall performance boost - #292)
Deprecated
The following methods were deprecated and are scheduled for removal in 0.17.0 or 1.0.0 (whichever comes first). See UPGRADE.md for more information.
Cursor::advanceWhileMatches()deprecated; useCursor::match()instead.HtmlRenderer::escape()deprecated; useXml::escape()instead.
Removed
- Removed
DelimiterStack::findFirstMatchingOpener()which was previously deprecated in 0.15.0
0.15.7 - 2017-10-26
Fixed
- Improved performance of
Cursor::advanceBy()(for a 16% performance boost!) :tada:
0.15.6 - 2017-08-08
Fixed
- Fixed URI normalization not properly encoding/decoding special characters in certain cases (#287)
0.15.5 - 2017-08-05
This release bumps spec compliance to 0.28 without breaking changes to the API.
Added
- Project is now tested against PHP 7.2
Changed
- Bumped CommonMark spec target to 0.28
- Changed internal implementation of
LinkParserHelper::parseLinkDestination()to allow nested parens - Changed precedence of strong/emph when both nestings are possible (rule 14)
- Allow tabs before and after ATX closing header
Fixed
- Fixed HTML type 6 block regex matching against
<pre>(it shouldn’t) and not matching<iframe>(it should) - Fixed reference parser incorrectly handling escaped
]characters - Fixed “multiple of 3” delimiter run calculations
Deprecated
An unused constant and static method were deprecated and will be removed in a future release. See
- Deprecated
RegexHelper::REGEX_UNICODE_WHITESPACE(no longer used) - Deprecated
RegexHelper::getLinkDestinationRegex()(no longer used)
0.15.4 - 2017-05-09
Added
- Added new methods to
Cursor(#280):advanceToNextNonSpaceOrNewline()- Identical replacement for the (now-deprecated)advanceToFirstNonSpace()methodadvanceToNextNonSpaceOrTab()- Similar replacement foradvanceToFirstNonSpace()but with proper tab handlinggetNextNonSpaceCharacter()- Identical replacement for the (now-deprecated)getFirstNonSpaceCharacter()methodgetNextNonSpacePosition()- Identical replacement for the (now-deprecated)getFirstNonSpacePosition()method
- Added new method to
CursorState(#280):getNextNonSpaceCache()- Identical replacement for the (now-deprecated)getFirstNonSpaceCache()method
Fixed
- Fixed duplicate characters in non-intended lines containing tabs (#279)
Deprecated
All deprecations listed here will be removed in a future 0.x release. See UPGRADE.md for instructions on preparing your code for the eventual removal of these methods.
- Deprecated
Cursor::advanceToFirstNonSpace()(#280)- Use
advanceToNextNonSpaceOrTab()oradvanceToNextNonSpaceOrNewline()instead, depending on your requirements
- Use
- Deprecated
Cursor::getFirstNonSpaceCharacter()(#280)- Use
Cursor::getNextNonSpaceCharacter()instead
- Use
- Deprecated
Cursor::getFirstNonSpacePosition()(#280)- Use
Cursor::getNextNonSpacePosition()instead
- Use
- Deprecated
CursorState::getFirstNonSpaceCache()(#280)- Use
CursorState::getNextNonSpaceCache()instead
- Use
0.15.3 - 2016-12-19
Fixed
- Allow inline parsers matching regex delimiter to be created (#271, #272)
0.15.2 - 2016-11-22
Changed
- Bumped spec target version to 0.27 (#268)
- H2-H6 elements are now parsed as HTML block elements instead of HTML inlines
Fixed
- Fixed incomplete punctuation regex
- Fixed shortcut links not being allowed before a
( - Fixed distinction between Unicode whitespace and regular whitespace
0.15.1 - 2016-11-08
Fixed
- Fixed setext heading underlines not allowing trailing tabs (#266)
0.15.0 - 2016-09-14
Added
- Added preliminary support for PHP 7.1 (#259)
- Added more regression tests (#258, #260)
Changed
- Bumped spec target version to 0.26 (#260)
- The
CursorStateconstructor requires an additional parameter (#258) - Ordered lists cannot interupt a paragraph unless they start with
1(#260) - Blank list items cannot interupt a paragraph (#260)
Deprecated
- Deprecated
DelimiterStack::findFirstMatchingOpener()- usefindMatchingOpener()instead (#260)
Fixed
- Fixed tabs in ATX headers and thematic breaks (#260)
- Fixed issue where cursor state was not being restored properly (#258, #260)
- This fixed the lists-with-tabs regression reported in #258
Removed
- Removed an unnecessary check in
Cursor::advanceBy()(#260) - Removed the two-blanks-break-out-of-lists feature (#260)
0.14.0 - 2016-07-02
Added
- The
safeoption is deprecated and replaced by 2 new options (#253, #255):html_input(strip,alloworescape): how to handle untrusted HTML input (the default isstripfor BC reasons)allow_unsafe_links(trueorfalse): whether to allow risky image URLs and links (the default istruefor BC reasons)
Deprecated
- The
safeoption is now deprecated and will be removed in the 1.0.0 release.
0.13.4 - 2016-06-14
Fixed
- Fixed path to
autoload.phpwithin bin/commonmark (#250)
0.13.3 - 2016-05-21
Added
- Added
setUrl()method forLinkandImageelements (#227, #244) - Added cebe/markdown to the benchmark tool (#245)
0.13.2 - 2016-03-27
Added
- Added ability to invoke
Converteras a function (#233, #239) - Added new
advanceBySpaceOrTabconvenience method toCursor
Changed
- Bumped spec target version to 0.25
- Adjusted how tabs are handled by the
Cursor(#234) - Made a couple small micro-optimizations to heavily used functions (#240)
- Updated URLs in docblocks to use HTTPS where possible (#238)
0.13.1 - 2016-03-09
Changed
- Refactored
EmphasisParser::parse()to simplify it (#223) - Updated dev dependencies (#218 & #220)
Fixed
- Fixed invalid regex generated when no inline parsers are defined (#224)
- Fixed logic bug with blank line after empty list item (#230)
- Fixed some incorrect code comments
Removed
- Removed unused variables (#223)
0.13.0 - 2016-01-14
Added
- Added AST document processors (#210)
- Added optional
Environmentparameter toCommonMarkConverterconstructor
Changed
- Renamed “header” things to “heading” for spec consistency
Header=>HeadingATXHeaderParser=>ATXHeadingParserSetExtHeaderParser=>SetExtHeadingParserHeaderRenderer=>HeadingRenderer
- Renamed “HorizontalRule” to “ThematicBreak” for spec consistency
HorizontalRule=>ThematicBreakHorizontalRuleParser=>ThematicBreakParserHorizontalRuleRenderer=>ThematicBreakRendererHorizontalRuleRendererTest=>ThematicBreakRendererTestRegexHelper::getHRuleRegex()=>RegexHelper::getThematicBreakRegex()
- Renamed inline “Html” and “RawHtml” to “HtmlInline” for consistency
Html=>HtmlInlineRawHtmlParser=>HtmlInlineParserRawHtmlRenderer=>HtmlInlineRenderer
- Don’t allow whitespace between link text and link label of a reference link (spec change)
- Don’t allow spaces in link destinations, even in
<> - Allow multiline setext header content
- The
Headingconstructor now allows$contentsto be astring(old behavior) orstring[](new)
- The
Fixed
- Fixed several list issues and regressions (jgm/commonmark.js#59)
Removed
- Removed schema whitelist from autolink regex
- Moved SmartPunct functionality into new league/commonmark-extras package
0.12.0 - 2015-11-04
Added
- Added ability to configure characters and disable emphasis/strong (#135)
- Added new ConfigurationAwareInterface support for all parsers, processors, and renderers (#201)
- Added HTML safe mode to handle untrusted input (#200, #201)
- Safe mode is disabled by default for backwards-compatibility
- To enable it, set the
safeoption totrue
- Added AppVeyor integration for automated unit/functional testing on Windows (#195)
Changed
AbstractBlock::finalize()now reqires a second parameter,$endLineNumberRegexHelper::REGEX_ENTITYno longer includes the starting/or the ending/i(#194)Node::setParent()now accepts null values (#203)
Fixed
- Fixed incorrect
endLinepositions (#187) - Fixed
DocParser::preProcessInputdropping up to 2 ending newlines instead of just one - Fixed
EntityParsernot checking for ampersands at the start of the current position (#192, #194)
Removed
- Removed protected function Context::addChild()
- It was a duplicate of the Context::addBlock() method
- Disabled STDIN reading on
bin/commonmarkfor Windows due to PHP issues (#189, #195)
0.11.3 - 2015-09-25
Fixed
- Reset container after closing containing lists (#183; jgm/commonmark.js#67)
- The temporary fix from 0.11.2 was reverted
0.11.2 - 2015-09-23
Fixed
- Fixed parser checking acceptsLines on the wrong element (#183)
0.11.1 - 2015-09-22
Changed
- Tightened up some loose comparisons
Fixed
- Fixed missing “bin” directive in composer.json
- Updated a docblock to match recent changes to method parameters
Removed
- Removed unused variable from within QuoteProcessor’s closure
0.11.0 - 2015-09-19
This release contains several major internal changes. It will likely break compatibility with custom elements, parsers, and renderers. Simple Markdown parsing is unaffected.
Added
- Added new
Nodeclass, which bothAbstractBlockandAbstractInlineextend from (#169) - Added a
NodeWalkerandNodeWalkerEventto traverse the AST without using recursion - Added new
InlineContainerinterface for blocks - Added new
getContainer()andgetReferenceMap()methods toInlineParserContext - Added
iframeto whitelist of HTML block tags (as per spec) - Added
./bin/commonmarkfor converting Markdown at the command line
Changed
- Bumped spec target version to 0.22
- Revised AST to use a double-linked list (#169)
AbstractBlockandAbstractInlineboth extend fromNode- Sub-classes must implement new
isContainer()method
- Sub-classes must implement new
- Other major changes to
AbstractBlock:getParent()is nowparent()setParent()now expects aNodeinstead of anAbstractBlockgetChildren()is nowchildren()getLastChild()is nowlastChild()addChild()is nowappendChild()
InlineParserContextis constructed using the containerAbstractBlockand the document’sRefereceMap- The constructor will automatically create the
Cursorusing the container’s string contents
- The constructor will automatically create the
InlineParserEngine::parsenow requires theNodecontainer and the document’sReferenceMapinstead of aContextInterfaceandCursor- Changed
Delimiterto reference the actual inlineNodeinstead of the position- The
int $posprotected member and constructor arg is nowNode $node - Use
getInlineNode()andsetInlineNode()instead ofgetPos()andsetPos()
- The
- Changed
DocParser::processInlinesto use aNodeWalkerto iterate through inlines- Walker passed as second argument instead of
AbstractBlock - Uses a
whileloop instead of recursion to traverse the AST
- Walker passed as second argument instead of
ImageandLinknow only accept a string as their second argument- Refactored how
CloseBracketParser::parse()works internally CloseBracketParser::createInlineno longer accepts label inlines- Disallow list item starting with multiple blank lines (see jgm/CommonMark#332)
- Modified
AbstractBlock::setLastLineBlank()- Functionality moved to
AbstractBlock::shouldLastLineBeBlank()and newDocParser::setAndPropagateLastLineBlank()method AbstractBlock::setLastLineBlank()is now a setter method forAbstractBlock::$lastLineBlank
- Functionality moved to
AbstractBlock::handleRemainingContents()is no longer abstract- A default implementation is provided
- Removed duplicate code from sub-classes which used the default implementation - they’ll just use the parent method from now on
Fixed
- Fixed logic error in calculation of offset (see jgm/commonmark.js@94053a8)
- Fixed bug where
DocParserchecked the wrong method to determine remainder handling behavior - Fixed bug where
HorizontalRuleParserfailed to advance the cursor beyond the parsed horizontal rule characters - Fixed
DocParsernot ignoring the final newline of the input (like the reference parser does)
Removed
- Removed
Block\Element\AbstractInlineContainer- Extend
AbstractBlockand implementInlineContainerinstead - Use child methods instead of
getInlinesandsetInlines
- Extend
- Removed
AbstractBlock::replaceChild()- Call
Node::replaceWith()directly the child node instead
- Call
- Removed the
getInlines()method fromInlineParserContext- Add parsed inlines using
$inlineContext->getContainer()->appendChild()instead of$inlineContext->getInlines()->add()
- Add parsed inlines using
- Removed the
ContextInterfaceargument fromAbstractInlineParser::parse()andInlineParserEngine::parseCharacter - Removed the first
ArrayCollection $inlinesargument fromInlineProcessorInterface::processInlines() - Removed
CloseBracketParser::nullify() - Removed
prefrom rule 6 of HTML blocks (see jgm/CommonMark#355)
0.10.0 - 2015-07-25
Added
- Added parent references to inline elements (#124)
- Added smart punctuation extension (#134)
- Added HTML block types
- Added indentation caching to the cursor
- Added automated code style checks (#133)
- Added support for tag attributes in renderers (#101, #165)
Changed
- Bumped spec target version to 0.21
- Revised HTML block parsing to conform to new spec (jgm/commonmark.js@99bd473)
- Imposed 9-digit limit on ordered list markers, per spec
- Allow non-initial hyphens in html tag names (jgm/CommonMark#239)
- Updated list of block tag names
- Changed tab/indentation handling to meet the new spec behavior
- Modified spec tests to show spaces and tabs in test results
- Replaced
HtmlRendererInterfacewithElementRendererInterface(#141) - Removed the unnecessary
trim()and string cast fromListItemRenderer
Fixed
- Fixed link reference definition edge case (#120)
- Allow literal (non-escaping) backslashes in link destinations (#118)
- Allow backslash-escaped backslashes in link labels (#119)
- Allow link labels up to 999 characters (per the spec)
- Properly split on whitespace when determining code block class (jgm/commonmark.js#54)
- Fixed code style issues (#132, #133, #151, #152)
- Fixed wording for invalid inline exception (#136)
Removed
- Removed the advance-by-one optimization due to added cursor complexity
0.9.0 - 2015-06-19
Added
- Added public $data array to block elements (#95)
- Added
isIndentedhelper method toCursor - Added a new
Converterbase class whichCommonMarkConverterextends from (#105)
Changed
- Bumped spec target version to 0.20 (#112)
- Renamed
ListBlock::$dataandListItem::$datato$listData - Require link labels to contain non-whitespace (jgm/CommonMark#322)
- Use U+FFFD for entities resolving to 0 (jgm/CommonMark#323)
- Moved
IndentedCodeParser::CODE_INDENT_LEVELtoCursor::INDENT_LEVEL - Changed arrays to short syntax (#116)
- Improved efficiency of DelimiterStack iteration (jgm/commonmark.js#43)
Fixed
- Fixed open block tag followed by newline not being recognized (jgm/CommonMark#324)
- Fixed indented lists sometimes being parsed incorrectly (jgm/commonmark.js#42)
0.8.0 - 2015-04-29
Added
- Allow swapping built-in renderers without using their fully qualified names (#84)
- Lots of unit tests (for existing code)
- Ability to include arbitrary functional tests in addition to spec-based tests
Changed
- Dropped support for PHP 5.3 (#64 and #76)
- Bumped spec target version to 0.19
- Made the AbstractInlineContainer be abstract
- Moved environment config. logic into separate class
Fixed
- Fixed underscore emphasis to conform to spec changes (jgm/CommonMark#317)
Removed
- Removed PHP 5.3 workaround (see commit 5747822)
- Removed unused AbstractWebResource::setUrl() method
- Removed unnecessary check for hrule when parsing lists (#85)
0.7.2 - 2015-03-08
Changed
- Bumped spec target version to 0.18
Fixed
- Fixed broken parsing of emphasized text ending with a ‘0’ character (#81)
0.7.1 - 2015-03-01
Added
- All references can now be obtained from the
ReferenceMapvialistReferences()(#73) - Test against PHP 7.0 (nightly) but allow failures
Changed
- ListData::$start now defaults to null instead of 0 (#74)
- Replace references to HtmlRenderer with new HtmlRendererInterface
Fixed
- Fixed 0-based ordered lists starting at 1 instead of 0 (#74)
- Fixed errors parsing multi-byte characters (#78 and #79)
0.7.0 - 2015-02-17
Now with 50% more speed!
Added
- More unit tests to increase code coverage
Changed
- Enabled the InlineParserEngine to parse several non-special characters at once (performance boost)
- NewlineParser no longer attempts to parse spaces; look-behind is used instead (major performance boost)
- Moved closeUnmatchedBlocks into its own class
- Image and link elements now extend AbstractInlineContainer; label data is stored via $inlineContents instead
- Renamed AbstractInlineContainer::$inlineContents and its getter/setter
Removed
- Removed the InlineCollection class
- Removed the unused ArrayCollection::splice() method
- Removed impossible-to-reach code in Cursor::advanceToFirstNonSpace
- Removed unnecessary test from the InlineParserEngine
- Removed unnecessary/unused RegexHelper::getMainRegex() method
0.6.1 - 2015-01-25
Changed
- Bumped spec target version to 0.17
- Updated emphasis parsing for underscores to prevent intra-word emphasis
- Defered closing of fenced code blocks
0.6.0 - 2015-01-09
Added
- Bulk registration of parsers/renderers via extensions (#45)
- Proper UTF-8 support, especially in the Cursor; mbstring extension is now required (#49)
- Environment is now configurable; options can be accessed in its parsers/renderers (#56)
- Added some unit tests
Changed
- Bumped spec target version to 0.15 (#50)
- Parsers/renderers are now lazy-initialized (#52)
- Some private elements are now protected for easier extending, especially on Element classes (#53)
- Renderer option names changed from underscore_case to camelCase (#56)
- Moved CommonMark parser/render definitions into CommonMarkCoreExtension
Fixed
- Improved parsing of emphasis around punctuation
- Improved regexes for CDATA and HTML comments
- Fixed issue with HTML content that is considered false in loose comparisons, like
'0'(#55) - Fixed DocParser trying to add empty strings to closed containers (#58)
- Fixed incorrect use of a null parameter value in the HtmlElementTest
Removed
- Removed unused ReferenceDefinition* classes (#51)
- Removed UnicodeCaseFolder in favor of mb_strtoupper
0.5.1 - 2014-12-27
Fixed
- Fixed infinite loop and link-in-link-in-image parsing (#37)
Removed
- Removed hard dependency on mbstring extension; workaround used if not installed (#38)
0.5.0 - 2014-12-24
Added
- Support for custom directives, parsers, and renderers
Changed
- Major refactoring to de-couple directives from the parser, support custom directive functionality, and reduce complexity
- Updated references to stmd.js in README and docblocks
- Modified CHANGELOG formatting
- Improved travis configuration
- Put tests in autoload-dev
Fixed
- Fixed CommonMarkConverter re-creating object each time new text is converted (#26)
Removed
- Removed dependency on symfony/options-resolver (fixes #20)
- 2014-12-16
- Changed namespace to League\CommonMark
- Made compatible with spec version 0.13
- Moved delimiter stack functionality into seperate class
- Fixed regex which caused HHVM tests to fail
- Added some missing copyright info