A CommonMark wrapper for Laravel

Overview

Laravel Markdown

Laravel Markdown was created by, and is maintained by Graham Campbell, and is a CommonMark wrapper for Laravel. It ships with integration with Laravel's view system too. Feel free to check out the change log, releases, security policy, license, code of conduct, and contribution guidelines.

Banner

Promo Banner

Build Status StyleCI Status Software License Packagist Downloads Latest Version

Installation

Laravel Markdown requires PHP 7.2-8.0. This particular version supports Laravel 6-8.

Markdown L5.1 L5.2 L5.3 L5.4 L5.5 L5.6 L5.7 L5.8 L6 L7 L8
5.3
6.1
7.1
8.1
9.0
10.3
11.2
12.0
13.1

To get the latest version, simply require the project using Composer:

$ composer require graham-campbell/markdown:^13.1

Once installed, if you are not using automatic package discovery, then you need to register the GrahamCampbell\Markdown\MarkdownServiceProvider service provider in your config/app.php.

You can also optionally alias our facade:

        'Markdown' => GrahamCampbell\Markdown\Facades\Markdown::class,

Configuration

Laravel Markdown supports optional configuration.

To get started, you'll need to publish all vendor assets:

$ php artisan vendor:publish

This will create a config/markdown.php file in your app that you can modify to set your configuration. Also, make sure you check for changes to the original config file in this package between releases.

There are several config options:

Enable View Integration

This option ('views') specifies if the view integration is enabled so you can write markdown views and have them rendered as html. The following extensions are currently supported: '.md', '.md.php', and '.md.blade.php'. Additionally, this will enable the @markdown Blade directive. You may disable this integration if it is conflicting with another package. The default value for this setting is true.

CommonMark Extensions

This option ('extensions') specifies what extensions will be automatically enabled. Simply provide your extension class names here, and they will be resolved from the service container, and registered with CommonMark. The default value for this setting is [].

Renderer Configuration

This option ('renderer') specifies an array of options for rendering HTML. The default value for this setting is ['block_separator' => "\n", 'inner_separator' => "\n", 'soft_break' => "\n"].

Enable Em Tag Parsing

This option ('enable_em') specifies if <em> parsing is enabled. The default value for this setting is true.

Enable Strong Tag Parsing

This option ('enable_strong') specifies if <strong> parsing is enabled. The default value for this setting is true.

Enable Asterisk Parsing

This option ('use_asterisk') specifies if * should be parsed for emphasis. The default value for this setting is true.

Enable Underscore Parsing

This option ('use_underscore') specifies if _ should be parsed for emphasis. The default value for this setting is true.

HTML Input

This option ('html_input') specifies how to handle untrusted HTML input. The default value for this setting is 'strip'.

Allow Unsafe Links

This option ('allow_unsafe_links') specifies whether to allow risky image URLs and links. The default value for this setting is true.

Maximum Nesting Level

This option ('max_nesting_level') specifies the maximum permitted block nesting level. The default value for this setting is INF.

Usage

Facades\Markdown

This facade will dynamically pass static method calls to the 'markdown' object in the ioc container which by default is an instance of League\CommonMark\MarkdownConverterInterface.

MarkdownServiceProvider

This class contains no public methods of interest. This class should be added to the providers array in config/app.php. This class will setup ioc bindings.

Real Examples

Here you can see an example of just how simple this package is to use.

use GrahamCampbell\Markdown\Facades\Markdown;

Markdown::convertToHtml('foo'); // <p>foo</p>

If you prefer to use dependency injection over facades like me, then you can easily inject the class like so:

use Illuminate\Support\Facades\App;
use League\CommonMark\MarkdownConverterInterface;

class Foo
{
    protected $converter;

    public function __construct(MarkdownConverterInterface $converter)
    {
        $this->converter = $converter;
    }

    public function bar()
    {
        return $this->converter->convertToHtml('foo');
    }
}

App::make('Foo')->bar();

And don't forget, that's just the basics. We also support extension through listening for the resolving event from the container, and we ship with integration with Laravel's view system. You can use both the @markdown blade directive, and also using the following file extensions will compile your views as markdown: '.md', '.md.php', and '.md.blade.php'.

For example, the following are all methods of rendering markdown:

foo.blade.php:

@markdown('# Foo')

bar.blade.php:

@markdown
# Bar
@endmarkdown

baz1.md:

# Baz 1

baz2.md.php:

# Baz 2

baz3.md.blade.php:

# Baz 3
Further Information

There are other classes in this package that are not documented here (such as the engine and compiler classes). This is because they are not intended for public use and are used internally by this package.

Extensions

As hinted in the configuration docs, CommonMark can be modified using extensions. There are some very good examples in the customization section of the CommonMark docs for how to create custom parsers and renders in the customization section: http://commonmark.thephpleague.com/.

The Smart Punctuation package also serves as a good example of how to implement the full deal: https://github.com/thephpleague/commonmark-ext-smartpunct. In particular, note the presence of the Extension class, and the fact that you can add it to the extensions array in your app/config/markdown.php file. If you don't see the file in your config folder, you would need to run php artisan vendor:publish.

Security

If you discover a security vulnerability within this package, please send an email to Graham Campbell at [email protected]. All security vulnerabilities will be promptly addressed. You may view our full security policy here.

License

Laravel Markdown is licensed under The MIT License (MIT).

For Enterprise

Available as part of the Tidelift Subscription

The maintainers of graham-campbell/markdown and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

Comments
  • Error when using dependency injection

    Error when using dependency injection

    Getting the following error:

    BindingResolutionException in Container.php line 745:
    Target [League\CommonMark\ElementRendererInterface] is not instantiable.
    
    opened by jblyberg 19
  • Request: Ability to add classes to images.

    Request: Ability to add classes to images.

    Not sure if it's already implemented, but I can't seem to find it.

    Basically, I would want to do something similar to the following

    ![Image](http://www.example.com/image.png class="img-responsive content-img")

    It's not something that needs to be overused, but a few images require 1 attribute (img-responsive) while a few others require that one as well as another.

    I know this isn't a true CommonMark implementation, but wondering if I can extend Laravel-Markdown to accomplish this, or perhaps I'm overlooking some easier way to accomplish this.

    Thank you for your time.

    opened by dancrodev 17
  • Not parsing to HTML

    Not parsing to HTML

    I did al the setup instructions: composer require graham-campbell/markdown php artisan vendor:publish Then added 'Mail' => Illuminate\Support\Facades\Mail::class, to the aliases in config/app.php

    That should be enough, so I do @markdown($page->body) in a blade.php file, and then it just outputs literally @markdown($page->body) When I change that to

    @markdown
      {{ $page->body }}
    @endmarkdown
    

    it just print the @markdown the content (in markdown) end the endmarkdown.

    I am using Laravel 7.0

    opened by noesnaterse 13
  • Markdown can't render this {{

    Markdown can't render this {{

    I don't why markdown can't render the blade syntax like.

    <meta name="description" content="{{ $article->teaser }}">
    

    The result of it be

    <meta name="description" content="">
    

    Anyone can answer what's really need to show that ?

    opened by ghost 12
  • Running the composer command throws an error

    Running the composer command throws an error

    PHP version: 8.0.13

    Description Running the composer command throws the following error:

    Problem 1 - graham-campbell/markdown[v13.1.0, ..., 13.2.x-dev] require league/commonmark ^1.5 -> found league/commonmark[1.5.0, ..., 1.6.x-dev] but the package is fixed to 2.1.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command. - Root composer.json requires graham-campbell/markdown ^13.1 -> satisfiable by graham-campbell/markdown[v13.1.0, ..., 13.2.x-dev].

    Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

    How to reproduce Run the composer command. composer require graham-campbell/markdown:^13.1

    Possible Solution Running with -W flag. Throws a bunch more errors.

    Additional context Laravel: ^8.65

    opened by dissto 11
  • Nested list hides content

    Nested list hides content

    Helle Graham

    I'm using version 2.1.0 for Laravel 4.2, and it looks that when I'm using a nested list in my markdown file, all the content below is lost. Do you have any idea?

    The weird thing is that I didn't had this problem before, I tried to reverse back to older versions, but that didn't helped either.

    E.g.

    * test
     * test 2
    * test
     * test 2
    
    hello
    

    The result is that the list is shown correctly, but the text hello is missing.

    opened by cedricve 11
  • Inline UserHandleParser

    Inline UserHandleParser

    So I extended this for a UserHandleParser below but it doesn't make the changes.

    <?php
    
    namespace App\Extensions\Markdown;
    
    use League\CommonMark\ContextInterface;
    use League\CommonMark\Inline\Element\Link;
    use League\CommonMark\Inline\Parser\AbstractInlineParser;
    use League\CommonMark\InlineParserContext;
    
    class UserHandleParser extends AbstractInlineParser
    {
        public function getCharacters() {
            return array('@');
        }
    
        public function parse(ContextInterface $context, InlineParserContext $inlineContext) {
            $cursor = $inlineContext->getCursor();
    
            // The @ symbol must not have any other characters immediately prior
            $previousChar = $cursor->peek(-1);
            if ($previousChar !== null && $previousChar !== ' ') {
                // peek() doesn't modify the cursor, so no need to restore state first
                return false;
            }
    
            // Save the cursor state in case we need to rewind and bail
            $previousState = $cursor->saveState();
    
            // Advance past the @ symbol to keep parsing simpler
            $cursor->advance();
    
            // Parse the handle
            $handle = $cursor->match('/^\w+\W\w+/');
            if (empty($handle)) {
                // Regex failed to match; this isn't a valid Twitter handle
                $cursor->restoreState($previousState);
    
                return false;
            }
    
            $profileUrl = url('members/' . $handle);
    
            $inlineContext->getInlines()->add(new Link($profileUrl, '@'.$handle));
    
            return true;
        }
    }
    

    I've bootstrapped the parser into Markdown with a ServiceProvider as seen below.

        $environment = Environment::createCommonMarkEnvironment();
        $environment->addInlineParser( new UserHandleParser() );
    

    But it doesn't parse my text case on render.

    Any ideas?

    opened by feenx 11
  • Laravel 8 installation problem

    Laravel 8 installation problem

    $ composer require graham-campbell/markdown:^13.1

    ./composer.json has been updated

    Running composer update graham-campbell/markdown Loading composer repositories with package information

    Updating dependencies Your requirements could not be resolved to an installable set of packages.

    Problem 1 - graham-campbell/markdown[v13.1.0, ..., 13.2.x-dev] require league/commonmark ^1.5 -> found league/commonmark[1.5.0, ..., 1.6.x-dev] but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command. - Root composer.json requires graham-campbell/markdown ^13.1 -> satisfiable by graham-campbell/markdown[v13.1.0, v13.1.1, 13.1.x-dev, 13.2.x-dev].

    Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

    Installation failed, reverting ./composer.json and ./composer.lock to their original content.

    opened by trianity 10
  • No method to escape user-inputted markdown

    No method to escape user-inputted markdown

    There's no satisfactory way to escape user-submitted Markdown as it uses the the angle bracket > for a block quote, which is escaped by Laravel into &gt; by default.

    Example:

    # Title 1
    
    <script src="example.com"></script>
    
    > Blockquote
    

    Escaped:

    # Title 1
    
    &lt;script src=&quot;example.com&quot;&gt;&lt;/script&gt;
    
    &gt; Blockquote
    

    The issue here is that the blockquote is no longer recognized as valid Markdown. One solution could be adding an escape function that ignores all right-angle brackets, which would instead convert it to:

    # Title 1
    
    &lt;script src=&quot;example.com&quot;>&lt;/script>
    
    > Blockquote
    

    ... which then would result in the expected Markdown, with the blockquote intact.

    opened by gytdau 10
  • first line is being output inside <pre> tags

    first line is being output inside
     tags
    	                                    
    	                                 

    As said in title. No matter what I do, when I save my markdown to database and render it out, the first line is output within PRE tags rendering any formatting useless. Any ideas?

    opened by Gigamick 9
  • Blade @\include not working with v13

    Blade @\include not working with v13

    I migrated a project to version 13 and a markdown template with a blade @\include directive stopped working.

    Steps to reproduce

    1. Create a fresh Laravel install laravel new markdown
    2. Require this package composer require graham-campbell/markdown:^13.1
    3. Delete welcome.blade.php view file
    4. Create welcome.md.blade.php view file with the following contents:
      @include('partial')
      
    5. Create partial.blade.php view file with some content, for example:
      Hello World
      
    6. Start project and visit it in the browser

    The error displayed is:

    ErrorException: Undefined variable: __env (View: /home/rodrigo/code/webmagic/markdown/resources/views/welcome.md.blade.php)

    As a workaround I reverted to version 12.

    I am out of time now to look further in the code and find a reason or solution, but I can give a try on fixing it.

    If you have any hint on where I should look, I appreciate.

    Thanks for the package.

    opened by rodrigopedra 7
  • Unexpected item 'commonmark'.

    Unexpected item 'commonmark'.

    I have update my project from laravel 8 to laravel 9. I also update graham-campbell/markdown version to 14.0 according to laravel 9 upgrade but after that i also getting this error. Please help me to solve this issue.

    image_2022_11_24T07_58_54_056Z

    opened by Pardeepjakhar 1
  • Livewire support?

    Livewire support?

    Not really an issue but wanted to ask whether this can be used with Livewire components? Been trying for days to get an EasyMDE editor into the Profile Information Form of a Laravel 9 App I'm building, but just can't get it to work - I tried toast-ui first without any luck either. My App uses Fortify/Livewire/Jetstream.

    opened by thelar 1
  • Adding extension in v14 / commonmark v2

    Adding extension in v14 / commonmark v2

    I got an error when try to make an extension I name my custom Extension ZoomImageExtension I tried to use use League\CommonMark\Environment\ConfigurableEnvironmentInterface; or use League\CommonMark\ConfigurableEnvironmentInterface; same error

    Could not check compatibility between App\Extensions\ZoomImageExtension::register(League\CommonMark\Environment\ConfigurableEnvironmentInterface $environment): void and League\CommonMark\Extension\ExtensionInterface::register(League\CommonMark\Environment\EnvironmentBuilderInterface $environment): void, because class League\CommonMark\Environment\ConfigurableEnvironmentInterface is not available

    <?php
    
    namespace App\Extensions;
    
    use League\CommonMark\Event\DocumentParsedEvent;
    use League\CommonMark\Environment\ConfigurableEnvironmentInterface;
    use League\CommonMark\Extension\ExtensionInterface;
    use League\CommonMark\Inline\Element\Image;
    
    class ZoomImageExtension implements ExtensionInterface
    {
        public function register(ConfigurableEnvironmentInterface $environment): void
        {
            $environment->addEventListener(DocumentParsedEvent::class, [$this, 'onDocumentParsed']);
        }
    
        public function onDocumentParsed(DocumentParsedEvent $event) 
        {
    
        }
    }
    
    opened by hilmanski 0
Releases(v14.0.0)
Owner
Graham Campbell
OSS Maintainer | Laravel | StyleCI
Graham Campbell
A Laravel Wrapper for the CoinDCX API. Now easily connect and consume the CoinDCX Public API in your Laravel apps without any hassle.

This package provides a Laravel Wrapper for the CoinDCX API and allows you to easily communicate with it. Important Note This package is in early deve

Moinuddin S. Khaja 2 Feb 16, 2022
Laravel wrapper package for the Aimon.it API

Laravel Aimon Package A laravel wrapper package for the Aimon.it API. For more information see Aimon Requirements Laravel 6 or later Installation Inst

Ruslan 3 Aug 7, 2022
PayuMoney Gateway wrapper for Laravel.

PayuMoney Integration with Laravel Easy to use integration for PayUMoney into Laravel apps. Video Tutorial Usage composer require infyomlabs/laravel-p

InfyOmLabs (InfyOm Technologies) 10 Nov 29, 2022
A Laravel wrapper for spatie/dns. Allows to query and validate DNS records.

A Laravel wrapper for spatie/dns. Allows to query and validate DNS records.

Astrotomic 22 Nov 17, 2022
Laravel API wrapper to interact fluently with your Janus Media Server

Laravel API wrapper to interact fluently with your Janus Media Server. Core server interactions, as well as the video room plugin included.

Richard  Tippin 11 Aug 21, 2022
A laravel wrapper for BnpParibas Mercanet payment gateway

Laravel Mercanet A laravel wrapper for BnpParibas Mercanet which provide a lightweight public api to process your online payments from your laravel ap

Mouad ZIANI 29 Nov 27, 2022
Open Food Facts API wrapper for Laravel

Laravel Open Food Facts API This package provides a convenient wrapper to the Open Food Facts API for Laravel applications (5.7+). Installation You ca

Open Food Facts 112 Jan 4, 2023
a Google API v3 wrapper for Laravel 4.x

A Google API v3 wrapper for Laravel 4 This package enables a Laravel flavoured way to manage Google services through its API interface (v3) Installati

null 4 Nov 29, 2022
27Laracurl Laravel wrapper package for PHP cURL class that provides OOP interface to cURL. [10/27/2015] View Details

Laracurl Laravel cURL Wrapper for Andreas Lutro's OOP cURL Class Installation To install the package, simply add the following to your Laravel install

zjango 8 Sep 9, 2018
Laravel wrapper for Sentry Official API

Laravel Sentry API Provides a simple laravel wrapper to some of the endpoints listed on (Official Sentry API)[https://docs.sentry.io/api/]. **Note: Th

Pedro Santiago 1 Nov 1, 2021
A wrapper package to run mysqldump from laravel console commands.

A wrapper package to run mysqldump from laravel console commands.

Yada Khov 24 Jun 24, 2022
Laravel wrapper for the Gmail API

Laravel Gmail Gmail Gmail API for Laravel 8 You need to create an application in the Google Console. Guidance here. if you need Laravel 5 compatibilit

Daniel Castro 244 Jan 3, 2023
Simple and ready to use API response wrapper for Laravel.

Laravel API Response Simple Laravel API response wrapper. Installation Install the package through composer: $ composer require obiefy/api-response Re

Obay Hamed 155 Dec 14, 2022
Laravel wrapper for zendesk/zendesk_api_client_php package.

Laravel Zendesk This package provides integration with the Zendesk API. It supports creating tickets, retrieving and updating tickets, deleting ticket

Huddle Digital 97 Dec 22, 2022
A DOMPDF Wrapper for Laravel

DOMPDF Wrapper for Laravel Laravel wrapper for Dompdf HTML to PDF Converter Require this package in your composer.json and update composer. This will

Barry vd. Heuvel 5.6k Dec 25, 2022
A Laravel wrapper for apex charts

Larapex Charts A Laravel wrapper for apex charts library Check the documentation on: Larapex Chart Docs. Installation Use composer. composer require a

ArielMejiaDev 189 Dec 26, 2022
Laravel SoapClient Wrapper

Laravel SoapClient Wrapper A SoapClient wrapper integration for Laravel. Makes it easy to use Soap in a Laravel application. Please report any bugs or

Michael v/d Rijt 618 Dec 12, 2022
A Laravel wrapper for healthchecks.io

Healthchecks.io is a service that monitors your cron jobs and alerts you when they are down. This package is a wrapper for the Healthchecks.io API.

Robin Martijn 4 Nov 7, 2022
A wrapper of voku/anti-xss for Laravel

Laravel Security Laravel Security was created by, and is maintained by Graham Campbell, and is a voku/anti-xss wrapper for Laravel, using graham-campb

Graham Campbell 170 Nov 20, 2022