NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #90 most downloaded on Packagist
Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)
Last release 10 days ago
21 Sep 2026
Release timing varies
gaps range from 8 days to 4 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
147 releases · first in 2014
Fixed path to autoload.php within bin/commonmark
Added setUrl() method for Link and Image elements (#227, #244)
Added setUrl() method for Link and Image elements (#227, #244)
Added cebe/markdown to the benchmark tool (#245)
Added ability to invoke Converter as a function (#233, #239)
One column per quarter.
Added ability to invoke Converter as a function (#233, #239)
Added new advanceBySpaceOrTab convenience method to Cursor
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)
Refactored EmphasisParser::parse() to simplify it
Refactored EmphasisParser::parse() to simplify it (#223)
Updated dev dependencies (#218 & #220)
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
Added optional Environment parameter to CommonMarkConverter constructor
Added AST document processors (#210)
Added optional Environment parameter to CommonMarkConverter constructor
Renamed “header” things to “heading” for spec consistency
Header => Heading
ATXHeaderParser => ATXHeadingParser
SetExtHeaderParser => SetExtHeadingParser
HeaderRenderer => HeadingRenderer
Renamed “HorizontalRule” to “ThematicBreak” for spec consistency
HorizontalRule => ThematicBreak
HorizontalRuleParser => ThematicBreakParser
HorizontalRuleRenderer => ThematicBreakRenderer
HorizontalRuleRendererTest => ThematicBreakRendererTest
RegexHelper::getHRuleRegex() => RegexHelper::getThematicBreakRegex()
Renamed inline “Html” and “RawHtml” to “HtmlInline” for consistency
Html => HtmlInline
RawHtmlParser => HtmlInlineParser
RawHtmlRenderer => 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 Heading constructor now allows $contents to be a string (old behavior) or string[] (new)
Removed schema whitelist from autolink regex
Moved SmartPunct functionality into new league/commonmark-extras package
Added ability to configure characters and disable emphasis/strong
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 safe option to true
Added AppVeyor integration for automated unit/functional testing on Windows (#195)
AbstractBlock::finalize() now reqires a second parameter, $endLineNumber
RegexHelper::REGEX_ENTITY no longer includes the starting / or the ending /i (#194)
Node::setParent() now accepts null values (#203)
Fixed incorrect endLine positions (#187)
Fixed DocParser::preProcessInput dropping up to 2 ending newlines instead of just one
Fixed EntityParser not checking for ampersands at the start of the current position (#192, #194)
Removed protected function Context::addChild()
It was a duplicate of the Context::addBlock() method
Disabled STDIN reading on bin/commonmark for Windows due to PHP issues (#189, #195)
Nothing published for this version
Nothing published for this version
Tightened up some loose comparisons
Fixed missing “bin” directive in composer.json
Updated a docblock to match recent changes to method parameters
This release contains several major internal changes. It will likely break compatibility with custom elements, parsers, and renderers. Simple Markdown
This release contains several major internal changes. It will likely break compatibility with custom elements, parsers, and renderers. Simple Markdown parsing is unaffected.
Added new Node class, which both AbstractBlock and AbstractInline extend from (#169)
Added a NodeWalker and NodeWalkerEvent to traverse the AST without using recursion
Added new InlineContainer interface for blocks
Added new getContainer() and getReferenceMap() methods to InlineParserContext
Added iframe to whitelist of HTML block tags (as per spec)
Added ./bin/commonmark for converting Markdown at the command line
Bumped spec target version to 0.22
Revised AST to use a double-linked list (#169)
AbstractBlock and AbstractInline both extend from Node
Sub-classes must implement new isContainer() method
Other major changes to AbstractBlock :
getParent() is now parent()
setParent() now expects a Node instead of an AbstractBlock
getChildren() is now children()
getLastChild() is now lastChild()
addChild() is now appendChild()
InlineParserContext is constructed using the container AbstractBlock and the document’s RefereceMap
The constructor will automatically create the Cursor using the container’s string contents
InlineParserEngine::parse now requires the Node container and the document’s ReferenceMap instead of a ContextInterface and Cursor
Changed Delimiter to reference the actual inline Node instead of the position
The int $pos protected member and constructor arg is now Node $node
Use getInlineNode() and setInlineNode() instead of getPos() and setPos()
Changed DocParser::processInlines to use a NodeWalker to iterate through inlines
Walker passed as second argument instead of AbstractBlock
Uses a while loop instead of recursion to traverse the AST
Image and Link now only accept a string as their second argument
Refactored how CloseBracketParser::parse() works internally
CloseBracketParser::createInline no 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 new DocParser::setAndPropagateLastLineBlank() method
AbstractBlock::setLastLineBlank() is now a setter method for AbstractBlock::$lastLineBlank
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 logic error in calculation of offset (see jgm/commonmark.js@94053a8)
Fixed bug where DocParser checked the wrong method to determine remainder handling behavior
Fixed bug where HorizontalRuleParser failed to advance the cursor beyond the parsed horizontal rule characters
Fixed DocParser not ignoring the final newline of the input (like the reference parser does)
Removed Block\Element\AbstractInlineContainer
Extend AbstractBlock and implement InlineContainer instead
Use child methods instead of getInlines and setInlines
Removed AbstractBlock::replaceChild()
Call Node::replaceWith() directly the child node instead
Removed the getInlines() method from InlineParserContext
Add parsed inlines using $inlineContext->getContainer()->appendChild() instead of $inlineContext->getInlines()->add()
Removed the ContextInterface argument from AbstractInlineParser::parse() and InlineParserEngine::parseCharacter
Removed the first ArrayCollection $inlines argument from InlineProcessorInterface::processInlines()
Removed CloseBracketParser::nullify()
Removed pre from rule 6 of HTML blocks (see jgm/CommonMark#355)
Added parent references to inline elements
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)
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 HtmlRendererInterface with ElementRendererInterface (#141)
Removed the unnecessary trim() and string cast from ListItemRenderer
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)
Added public $data array to block elements
Added public $data array to block elements (#95)
Added isIndented helper method to Cursor
Added a new Converter base class which CommonMarkConverter extends from (#105)
Bumped spec target version to 0.20 (#112)
Renamed ListBlock::$data and ListItem::$data to $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_LEVEL to Cursor::INDENT_LEVEL
Changed arrays to short syntax (#116)
Improved efficiency of DelimiterStack iteration (jgm/commonmark.js#43)
Fixed open block tag followed by newline not being recognized (jgm/CommonMark#324)
Fixed indented lists sometimes being parsed incorrectly (jgm/commonmark.js#42)
Allow swapping built-in renderers without using their fully qualified names
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
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
Removed PHP 5.3 workaround (see commit 5747822)
Removed unused AbstractWebResource::setUrl() method
Removed unnecessary check for hrule when parsing lists (#85)
Bumped spec target version to 0.18
All references can now be obtained from the ReferenceMap via listReferences()
All references can now be obtained from the ReferenceMap via listReferences() (#73)
Test against PHP 7.0 (nightly) but allow failures
ListData::$start now defaults to null instead of 0 (#74)
Replace references to HtmlRenderer with new HtmlRendererInterface
Fixed 0-based ordered lists starting at 1 instead of 0 (#74)
Fixed errors parsing multi-byte characters (#78 and #79)
More unit tests to increase code coverage
Now with 50% more speed!
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 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
Bumped spec target version to 0.17
Bumped spec target version to 0.17
Updated emphasis parsing for underscores to prevent intra-word emphasis
Defered closing of fenced code blocks
Bulk registration of parsers/renderers via extensions
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
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
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 unused ReferenceDefinition* classes (#51)
Removed UnicodeCaseFolder in favor of mb_strtoupper
Fixed infinite loop and link-in-link-in-image parsing
Support for custom directives, parsers, and renderers
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
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →